async def test_no_change(hass, mqtt_mock_entry_no_yaml_config, caplog): """Test subscription to topics without change.""" mqtt_mock = await mqtt_mock_entry_no_yaml_config() calls = [] @callback def record_calls(*args): """Record calls.""" calls.append(args) sub_state = None sub_state = async_prepare_subscribe_topics( hass, sub_state, { "test_topic1": { "topic": "test-topic1", "msg_callback": record_calls } }, ) await async_subscribe_topics(hass, sub_state) subscribe_call_count = mqtt_mock.async_subscribe.call_count async_fire_mqtt_message(hass, "test-topic1", "test-payload") assert len(calls) == 1 sub_state = async_prepare_subscribe_topics( hass, sub_state, { "test_topic1": { "topic": "test-topic1", "msg_callback": record_calls } }, ) await async_subscribe_topics(hass, sub_state) assert subscribe_call_count == mqtt_mock.async_subscribe.call_count async_fire_mqtt_message(hass, "test-topic1", "test-payload") assert len(calls) == 2 async_unsubscribe_topics(hass, sub_state) async_fire_mqtt_message(hass, "test-topic1", "test-payload") assert len(calls) == 2
async def test_qos_encoding_custom(hass, mqtt_mock_entry_no_yaml_config, caplog): """Test custom qos and encoding.""" mqtt_mock = await mqtt_mock_entry_no_yaml_config() @callback def msg_callback(*args): """Do nothing.""" pass sub_state = None sub_state = async_prepare_subscribe_topics( hass, sub_state, { "test_topic1": { "topic": "test-topic1", "msg_callback": msg_callback, "qos": 1, "encoding": "utf-16", } }, ) await async_subscribe_topics(hass, sub_state) mqtt_mock.async_subscribe.assert_called_with("test-topic1", ANY, 1, "utf-16")
async def _subscribe_topics(sub_state: dict | None, topics: dict) -> dict: # Optionally mark message handlers as callback for topic in topics.values(): if "msg_callback" in topic and "event_loop_safe" in topic: topic["msg_callback"] = callback(topic["msg_callback"]) sub_state = async_prepare_subscribe_topics(hass, sub_state, topics) await async_subscribe_topics(hass, sub_state) return sub_state
async def subscribe_topics( hass: HomeAssistant, state: dict[str, EntitySubscription] | None, topics: dict[str, Any], ) -> Any: # pragma: no cover """Subscribe to MQTT topic.""" state = async_prepare_subscribe_topics(hass, state, topics) # pylint: disable=no-value-for-parameter return await async_subscribe_topics(hass, state)
async def test_subscribe_topics(hass, mqtt_mock_entry_no_yaml_config, caplog): """Test subscription to topics.""" await mqtt_mock_entry_no_yaml_config() calls1 = [] @callback def record_calls1(*args): """Record calls.""" calls1.append(args) calls2 = [] @callback def record_calls2(*args): """Record calls.""" calls2.append(args) sub_state = None sub_state = async_prepare_subscribe_topics( hass, sub_state, { "test_topic1": { "topic": "test-topic1", "msg_callback": record_calls1 }, "test_topic2": { "topic": "test-topic2", "msg_callback": record_calls2 }, }, ) await async_subscribe_topics(hass, sub_state) async_fire_mqtt_message(hass, "test-topic1", "test-payload1") assert len(calls1) == 1 assert calls1[0][0].topic == "test-topic1" assert calls1[0][0].payload == "test-payload1" assert len(calls2) == 0 async_fire_mqtt_message(hass, "test-topic2", "test-payload2") assert len(calls1) == 1 assert len(calls2) == 1 assert calls2[0][0].topic == "test-topic2" assert calls2[0][0].payload == "test-payload2" async_unsubscribe_topics(hass, sub_state) async_fire_mqtt_message(hass, "test-topic1", "test-payload") async_fire_mqtt_message(hass, "test-topic2", "test-payload") assert len(calls1) == 1 assert len(calls2) == 1
async def _subscribe_topics(self): """(Re)Subscribe to topics.""" topics = {} def add_subscription(topics, topic, msg_callback): if topic is not None: topics[topic] = { 'topic': topic, 'msg_callback': msg_callback, 'qos': self._qos } def message_received(msg): """A new MQTT message has been received.""" topic = msg.topic payload = msg.payload parsed = json.loads(payload) if topic == self._state_topic: self._target_temperature = float(parsed['heat_target']) self._fan_mode = str(parsed['speed']) self._hvac_mode = parsed['mode'] self._current_power = bool(parsed['on']) self._current_status = bool(parsed['heating']) self._switch_active = bool(parsed['switch_active']) self._attrs.update(parsed) if parsed['mode'] == "OFF": self._state = False else: self._state = True elif topic == self._temp_state_topic: self._current_temperature = float(parsed['temp_incoming']) self._attrs.update(parsed) else: print("unknown topic") # TODO: Log as error async_dispatcher_send(self._hass, SIGNAL_STATE_UPDATED) for topic in [self._state_topic, self._temp_state_topic]: add_subscription(topics, topic, message_received) self._sub_state = async_prepare_subscribe_topics( self._hass, self._sub_state, topics) await subscription.async_subscribe_topics(self._hass, self._sub_state)
async def test_qos_encoding_default(hass, mqtt_mock, caplog): """Test default qos and encoding.""" @callback def msg_callback(*args): """Do nothing.""" pass sub_state = None sub_state = async_prepare_subscribe_topics( hass, sub_state, { "test_topic1": { "topic": "test-topic1", "msg_callback": msg_callback } }, ) await async_subscribe_topics(hass, sub_state) mqtt_mock.async_subscribe.assert_called_once_with("test-topic1", ANY, 0, "utf-8")
async def test_modify_topics(hass, mqtt_mock, caplog): """Test modification of topics.""" calls1 = [] @callback def record_calls1(*args): """Record calls.""" calls1.append(args) calls2 = [] @callback def record_calls2(*args): """Record calls.""" calls2.append(args) sub_state = None sub_state = async_prepare_subscribe_topics( hass, sub_state, { "test_topic1": { "topic": "test-topic1", "msg_callback": record_calls1 }, "test_topic2": { "topic": "test-topic2", "msg_callback": record_calls2 }, }, ) await async_subscribe_topics(hass, sub_state) async_fire_mqtt_message(hass, "test-topic1", "test-payload") assert len(calls1) == 1 assert len(calls2) == 0 async_fire_mqtt_message(hass, "test-topic2", "test-payload") assert len(calls1) == 1 assert len(calls2) == 1 sub_state = async_prepare_subscribe_topics( hass, sub_state, { "test_topic1": { "topic": "test-topic1_1", "msg_callback": record_calls1 } }, ) await async_subscribe_topics(hass, sub_state) async_fire_mqtt_message(hass, "test-topic1", "test-payload") async_fire_mqtt_message(hass, "test-topic2", "test-payload") assert len(calls1) == 1 assert len(calls2) == 1 async_fire_mqtt_message(hass, "test-topic1_1", "test-payload") assert len(calls1) == 2 assert calls1[1][0].topic == "test-topic1_1" assert calls1[1][0].payload == "test-payload" assert len(calls2) == 1 async_unsubscribe_topics(hass, sub_state) async_fire_mqtt_message(hass, "test-topic1_1", "test-payload") async_fire_mqtt_message(hass, "test-topic2", "test-payload") assert len(calls1) == 2 assert len(calls2) == 1