diff --git a/homeassistant/components/mqtt/light/schema_basic.py b/homeassistant/components/mqtt/light/schema_basic.py index d2f8a5ac03e..ab5d28d8a68 100644 --- a/homeassistant/components/mqtt/light/schema_basic.py +++ b/homeassistant/components/mqtt/light/schema_basic.py @@ -623,7 +623,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity): self._attr_hs_color = cast(tuple[float, float], hs_color) get_mqtt_data(self.hass).state_write_requests.write_state_request(self) except ValueError: - _LOGGER.debug("Failed to parse hs state update: '%s'", payload) + _LOGGER.warning("Failed to parse hs state update: '%s'", payload) add_topic(CONF_HS_STATE_TOPIC, hs_received) diff --git a/tests/components/mqtt/conftest.py b/tests/components/mqtt/conftest.py index 80c339d6342..c88988fa675 100644 --- a/tests/components/mqtt/conftest.py +++ b/tests/components/mqtt/conftest.py @@ -1,7 +1,3 @@ """Test fixtures for mqtt component.""" -import logging - from tests.components.blueprint.conftest import stub_blueprint_populate # noqa: F401 from tests.components.light.conftest import mock_light_profiles # noqa: F401 - -logging.basicConfig(level=logging.DEBUG) diff --git a/tests/components/mqtt/test_binary_sensor.py b/tests/components/mqtt/test_binary_sensor.py index 91607de9343..ca8e5c441f9 100644 --- a/tests/components/mqtt/test_binary_sensor.py +++ b/tests/components/mqtt/test_binary_sensor.py @@ -455,7 +455,7 @@ async def test_setting_sensor_value_via_mqtt_message_and_template_and_raw_state_ async def test_setting_sensor_value_via_mqtt_message_empty_template( - hass, mqtt_mock_entry_with_yaml_config, caplog + hass, mqtt_mock_entry_with_yaml_config ): """Test the setting of the value via MQTT.""" assert await async_setup_component( @@ -482,7 +482,6 @@ async def test_setting_sensor_value_via_mqtt_message_empty_template( async_fire_mqtt_message(hass, "test-topic", "DEF") state = hass.states.get("binary_sensor.test") assert state.state == STATE_UNKNOWN - assert "Empty template output" in caplog.text async_fire_mqtt_message(hass, "test-topic", "ABC") state = hass.states.get("binary_sensor.test") @@ -1060,13 +1059,6 @@ async def test_cleanup_triggers_and_restoring_state( await help_test_reload_with_config( hass, caplog, tmp_path, {mqtt.DOMAIN: {domain: [config1, config2]}} ) - assert "Clean up expire after trigger for binary_sensor.test1" in caplog.text - assert "Clean up expire after trigger for binary_sensor.test2" not in caplog.text - assert ( - "State recovered after reload for binary_sensor.test1, remaining time before expiring" - in caplog.text - ) - assert "State recovered after reload for binary_sensor.test2" not in caplog.text state = hass.states.get("binary_sensor.test1") assert state.state == state1 @@ -1084,7 +1076,7 @@ async def test_cleanup_triggers_and_restoring_state( async def test_skip_restoring_state_with_over_due_expire_trigger( - hass, mqtt_mock_entry_with_yaml_config, caplog, freezer + hass, mqtt_mock_entry_with_yaml_config, freezer ): """Test restoring a state with over due expire timer.""" @@ -1107,7 +1099,8 @@ async def test_skip_restoring_state_with_over_due_expire_trigger( ) await hass.async_block_till_done() await mqtt_mock_entry_with_yaml_config() - assert "Skip state recovery after reload for binary_sensor.test3" in caplog.text + state = hass.states.get("binary_sensor.test3") + assert state.state == STATE_UNAVAILABLE async def test_setup_manual_entity_from_yaml(hass): diff --git a/tests/components/mqtt/test_climate.py b/tests/components/mqtt/test_climate.py index dd86c41dcc7..16872c0c49d 100644 --- a/tests/components/mqtt/test_climate.py +++ b/tests/components/mqtt/test_climate.py @@ -807,7 +807,6 @@ async def test_get_with_templates(hass, mqtt_mock_entry_with_yaml_config, caplog hass, "current-preset-mode", '{"other_attribute": "some_value"}' ) state = hass.states.get(ENTITY_CLIMATE) - assert "Ignoring empty preset_mode from 'current-preset-mode'" assert state.attributes.get("preset_mode") == "eco" # Aux mode @@ -835,10 +834,6 @@ async def test_get_with_templates(hass, mqtt_mock_entry_with_yaml_config, caplog async_fire_mqtt_message(hass, "action", "null") state = hass.states.get(ENTITY_CLIMATE) assert state.attributes.get("hvac_action") == "cooling" - assert ( - "Invalid ['cooling', 'drying', 'fan', 'heating', 'idle', 'off'] action: None, ignoring" - in caplog.text - ) async def test_set_and_templates(hass, mqtt_mock_entry_with_yaml_config, caplog): diff --git a/tests/components/mqtt/test_common.py b/tests/components/mqtt/test_common.py index e5880b981a2..82e94c1e65e 100644 --- a/tests/components/mqtt/test_common.py +++ b/tests/components/mqtt/test_common.py @@ -1672,8 +1672,6 @@ async def help_test_reload_with_config(hass, caplog, tmp_path, config): ) await hass.async_block_till_done() - assert "" in caplog.text - async def help_test_entry_reload_with_new_config(hass, tmp_path, new_config): """Test reloading with supplied config.""" diff --git a/tests/components/mqtt/test_config_flow.py b/tests/components/mqtt/test_config_flow.py index 818cdcf33a6..5cccb341218 100644 --- a/tests/components/mqtt/test_config_flow.py +++ b/tests/components/mqtt/test_config_flow.py @@ -454,93 +454,90 @@ async def test_hassio_cannot_connect( assert len(mock_finish_setup.mock_calls) == 0 -@patch( - "homeassistant.config.async_hass_config_yaml", - AsyncMock(return_value={}), -) async def test_option_flow( hass, mqtt_mock_entry_no_yaml_config, mock_try_connection, - caplog, ): """Test config flow options.""" - mqtt_mock = await mqtt_mock_entry_no_yaml_config() - mock_try_connection.return_value = True - config_entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0] - config_entry.data = { - mqtt.CONF_BROKER: "test-broker", - mqtt.CONF_PORT: 1234, - } + with patch( + "homeassistant.config.async_hass_config_yaml", AsyncMock(return_value={}) + ) as yaml_mock: + mqtt_mock = await mqtt_mock_entry_no_yaml_config() + mock_try_connection.return_value = True + config_entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0] + config_entry.data = { + mqtt.CONF_BROKER: "test-broker", + mqtt.CONF_PORT: 1234, + } - mqtt_mock.async_connect.reset_mock() + mqtt_mock.async_connect.reset_mock() - result = await hass.config_entries.options.async_init(config_entry.entry_id) - assert result["type"] == data_entry_flow.FlowResultType.FORM - assert result["step_id"] == "broker" + result = await hass.config_entries.options.async_init(config_entry.entry_id) + assert result["type"] == data_entry_flow.FlowResultType.FORM + assert result["step_id"] == "broker" - result = await hass.config_entries.options.async_configure( - result["flow_id"], - user_input={ + result = await hass.config_entries.options.async_configure( + result["flow_id"], + user_input={ + mqtt.CONF_BROKER: "another-broker", + mqtt.CONF_PORT: 2345, + mqtt.CONF_USERNAME: "user", + mqtt.CONF_PASSWORD: "pass", + }, + ) + assert result["type"] == data_entry_flow.FlowResultType.FORM + assert result["step_id"] == "options" + + await hass.async_block_till_done() + assert mqtt_mock.async_connect.call_count == 0 + + yaml_mock.reset_mock() + + result = await hass.config_entries.options.async_configure( + result["flow_id"], + user_input={ + mqtt.CONF_DISCOVERY: True, + "discovery_prefix": "homeassistant", + "birth_enable": True, + "birth_topic": "ha_state/online", + "birth_payload": "online", + "birth_qos": 1, + "birth_retain": True, + "will_enable": True, + "will_topic": "ha_state/offline", + "will_payload": "offline", + "will_qos": 2, + "will_retain": True, + }, + ) + assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY + assert result["data"] == {} + assert config_entry.data == { mqtt.CONF_BROKER: "another-broker", mqtt.CONF_PORT: 2345, mqtt.CONF_USERNAME: "user", mqtt.CONF_PASSWORD: "pass", - }, - ) - assert result["type"] == data_entry_flow.FlowResultType.FORM - assert result["step_id"] == "options" - - await hass.async_block_till_done() - assert mqtt_mock.async_connect.call_count == 0 - - result = await hass.config_entries.options.async_configure( - result["flow_id"], - user_input={ mqtt.CONF_DISCOVERY: True, - "discovery_prefix": "homeassistant", - "birth_enable": True, - "birth_topic": "ha_state/online", - "birth_payload": "online", - "birth_qos": 1, - "birth_retain": True, - "will_enable": True, - "will_topic": "ha_state/offline", - "will_payload": "offline", - "will_qos": 2, - "will_retain": True, - }, - ) - assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY - assert result["data"] == {} - assert config_entry.data == { - mqtt.CONF_BROKER: "another-broker", - mqtt.CONF_PORT: 2345, - mqtt.CONF_USERNAME: "user", - mqtt.CONF_PASSWORD: "pass", - mqtt.CONF_DISCOVERY: True, - mqtt.CONF_DISCOVERY_PREFIX: "homeassistant", - mqtt.CONF_BIRTH_MESSAGE: { - mqtt.ATTR_TOPIC: "ha_state/online", - mqtt.ATTR_PAYLOAD: "online", - mqtt.ATTR_QOS: 1, - mqtt.ATTR_RETAIN: True, - }, - mqtt.CONF_WILL_MESSAGE: { - mqtt.ATTR_TOPIC: "ha_state/offline", - mqtt.ATTR_PAYLOAD: "offline", - mqtt.ATTR_QOS: 2, - mqtt.ATTR_RETAIN: True, - }, - } + mqtt.CONF_DISCOVERY_PREFIX: "homeassistant", + mqtt.CONF_BIRTH_MESSAGE: { + mqtt.ATTR_TOPIC: "ha_state/online", + mqtt.ATTR_PAYLOAD: "online", + mqtt.ATTR_QOS: 1, + mqtt.ATTR_RETAIN: True, + }, + mqtt.CONF_WILL_MESSAGE: { + mqtt.ATTR_TOPIC: "ha_state/offline", + mqtt.ATTR_PAYLOAD: "offline", + mqtt.ATTR_QOS: 2, + mqtt.ATTR_RETAIN: True, + }, + } - await hass.async_block_till_done() - assert config_entry.title == "another-broker" + await hass.async_block_till_done() + assert config_entry.title == "another-broker" # assert that the entry was reloaded with the new config - assert ( - "" - in caplog.text - ) + assert yaml_mock.await_count @pytest.mark.parametrize( diff --git a/tests/components/mqtt/test_fan.py b/tests/components/mqtt/test_fan.py index f4e89aa1ceb..d0ffc87141c 100644 --- a/tests/components/mqtt/test_fan.py +++ b/tests/components/mqtt/test_fan.py @@ -415,7 +415,7 @@ async def test_controlling_state_via_topic_and_json_message( assert state.attributes.get(fan.ATTR_PERCENTAGE) is None async_fire_mqtt_message(hass, "percentage-state-topic", '{"otherval": 100}') - assert "Ignoring empty speed from" in caplog.text + assert state.attributes.get(fan.ATTR_PERCENTAGE) is None caplog.clear() async_fire_mqtt_message(hass, "preset-mode-state-topic", '{"val": "low"}') @@ -439,8 +439,7 @@ async def test_controlling_state_via_topic_and_json_message( assert state.attributes.get("preset_mode") is None async_fire_mqtt_message(hass, "preset-mode-state-topic", '{"otherval": 100}') - assert "Ignoring empty preset_mode from" in caplog.text - caplog.clear() + assert state.attributes.get("preset_mode") is None async def test_controlling_state_via_topic_and_json_message_shared_topic( @@ -528,9 +527,6 @@ async def test_controlling_state_via_topic_and_json_message_shared_topic( state = hass.states.get("fan.test") assert state.attributes.get(fan.ATTR_PERCENTAGE) == 100 assert state.attributes.get("preset_mode") == "auto" - assert "Ignoring empty preset_mode from" in caplog.text - assert "Ignoring empty state from" in caplog.text - assert "Ignoring empty oscillation from" in caplog.text caplog.clear() diff --git a/tests/components/mqtt/test_humidifier.py b/tests/components/mqtt/test_humidifier.py index 1b8eac397cf..c5ffdc0df8f 100644 --- a/tests/components/mqtt/test_humidifier.py +++ b/tests/components/mqtt/test_humidifier.py @@ -301,7 +301,7 @@ async def test_controlling_state_via_topic_and_json_message( assert state.attributes.get(humidifier.ATTR_HUMIDITY) is None async_fire_mqtt_message(hass, "humidity-state-topic", '{"otherval": 100}') - assert "Ignoring empty target humidity from" in caplog.text + assert state.attributes.get(humidifier.ATTR_HUMIDITY) is None caplog.clear() async_fire_mqtt_message(hass, "mode-state-topic", '{"val": "low"}') @@ -325,7 +325,7 @@ async def test_controlling_state_via_topic_and_json_message( assert state.attributes.get(humidifier.ATTR_MODE) is None async_fire_mqtt_message(hass, "mode-state-topic", '{"otherval": 100}') - assert "Ignoring empty mode from" in caplog.text + assert state.attributes.get(humidifier.ATTR_MODE) is None caplog.clear() async_fire_mqtt_message(hass, "state-topic", '{"val": null}') @@ -407,8 +407,6 @@ async def test_controlling_state_via_topic_and_json_message_shared_topic( state = hass.states.get("humidifier.test") assert state.attributes.get(humidifier.ATTR_HUMIDITY) == 100 assert state.attributes.get(humidifier.ATTR_MODE) == "auto" - assert "Ignoring empty mode from" in caplog.text - assert "Ignoring empty state from" in caplog.text caplog.clear() diff --git a/tests/components/mqtt/test_init.py b/tests/components/mqtt/test_init.py index 38849167959..df26f1c489b 100644 --- a/tests/components/mqtt/test_init.py +++ b/tests/components/mqtt/test_init.py @@ -1383,12 +1383,8 @@ async def test_handle_mqtt_on_callback( await hass.async_block_till_done() # Now call publish without call back, this will call _wait_for_mid(msg_info.mid) await mqtt.async_publish(hass, "no_callback/test-topic", "test-payload") - # Since the mid event was already set, we should not see any timeout + # Since the mid event was already set, we should not see any timeout warning in the log await hass.async_block_till_done() - assert ( - "Transmitting message on no_callback/test-topic: 'test-payload', mid: 1" - in caplog.text - ) assert "No ACK from MQTT server" not in caplog.text @@ -1425,18 +1421,26 @@ async def test_subscribe_error( async def test_handle_message_callback( - hass, caplog, mqtt_mock_entry_no_yaml_config, mqtt_client_mock + hass, mqtt_mock_entry_no_yaml_config, mqtt_client_mock ): """Test for handling an incoming message callback.""" + callbacks = [] + + def _callback(args): + callbacks.append(args) + await mqtt_mock_entry_no_yaml_config() msg = ReceiveMessage("some-topic", b"test-payload", 1, False) mqtt_client_mock.on_connect(mqtt_client_mock, None, None, 0) - await mqtt.async_subscribe(hass, "some-topic", lambda *args: 0) + await mqtt.async_subscribe(hass, "some-topic", _callback) mqtt_client_mock.on_message(mock_mqtt, None, msg) await hass.async_block_till_done() await hass.async_block_till_done() - assert "Received message on some-topic (qos=1): b'test-payload'" in caplog.text + assert len(callbacks) == 1 + assert callbacks[0].topic == "some-topic" + assert callbacks[0].qos == 1 + assert callbacks[0].payload == "test-payload" async def test_setup_override_configuration(hass, caplog, tmp_path): diff --git a/tests/components/mqtt/test_light.py b/tests/components/mqtt/test_light.py index 2404d8a0f1f..7a654825596 100644 --- a/tests/components/mqtt/test_light.py +++ b/tests/components/mqtt/test_light.py @@ -493,32 +493,26 @@ async def test_invalid_state_via_topic(hass, mqtt_mock_entry_with_yaml_config, c assert state.attributes.get("color_mode") == "rgb" async_fire_mqtt_message(hass, "test_light_rgb/status", "") - assert "Ignoring empty state message" in caplog.text light_state = hass.states.get("light.test") assert state.state == STATE_ON async_fire_mqtt_message(hass, "test_light_rgb/brightness/status", "") - assert "Ignoring empty brightness message" in caplog.text light_state = hass.states.get("light.test") assert light_state.attributes["brightness"] == 255 async_fire_mqtt_message(hass, "test_light_rgb/color_mode/status", "") - assert "Ignoring empty color mode message" in caplog.text light_state = hass.states.get("light.test") - assert light_state.attributes["effect"] == "none" + assert state.attributes.get("color_mode") == "rgb" async_fire_mqtt_message(hass, "test_light_rgb/effect/status", "") - assert "Ignoring empty effect message" in caplog.text light_state = hass.states.get("light.test") assert light_state.attributes["effect"] == "none" async_fire_mqtt_message(hass, "test_light_rgb/rgb/status", "") - assert "Ignoring empty rgb message" in caplog.text light_state = hass.states.get("light.test") assert light_state.attributes.get("rgb_color") == (255, 255, 255) async_fire_mqtt_message(hass, "test_light_rgb/hs/status", "") - assert "Ignoring empty hs message" in caplog.text light_state = hass.states.get("light.test") assert light_state.attributes.get("hs_color") == (0, 0) @@ -528,21 +522,18 @@ async def test_invalid_state_via_topic(hass, mqtt_mock_entry_with_yaml_config, c assert light_state.attributes.get("hs_color") == (0, 0) async_fire_mqtt_message(hass, "test_light_rgb/xy/status", "") - assert "Ignoring empty xy-color message" in caplog.text light_state = hass.states.get("light.test") assert light_state.attributes.get("xy_color") == (0.323, 0.329) async_fire_mqtt_message(hass, "test_light_rgb/rgbw/status", "255,255,255,1") async_fire_mqtt_message(hass, "test_light_rgb/color_mode/status", "rgbw") async_fire_mqtt_message(hass, "test_light_rgb/rgbw/status", "") - assert "Ignoring empty rgbw message" in caplog.text light_state = hass.states.get("light.test") assert light_state.attributes.get("rgbw_color") == (255, 255, 255, 1) async_fire_mqtt_message(hass, "test_light_rgb/rgbww/status", "255,255,255,1,2") async_fire_mqtt_message(hass, "test_light_rgb/color_mode/status", "rgbww") async_fire_mqtt_message(hass, "test_light_rgb/rgbww/status", "") - assert "Ignoring empty rgbww message" in caplog.text light_state = hass.states.get("light.test") assert light_state.attributes.get("rgbww_color") == (255, 255, 255, 1, 2) @@ -559,7 +550,6 @@ async def test_invalid_state_via_topic(hass, mqtt_mock_entry_with_yaml_config, c assert state.attributes.get("xy_color") == (0.326, 0.333) async_fire_mqtt_message(hass, "test_light_rgb/color_temp/status", "") - assert "Ignoring empty color temp message" in caplog.text light_state = hass.states.get("light.test") assert light_state.attributes["color_temp"] == 153 diff --git a/tests/components/mqtt/test_sensor.py b/tests/components/mqtt/test_sensor.py index 750a6d79edd..6fdc1beedf7 100644 --- a/tests/components/mqtt/test_sensor.py +++ b/tests/components/mqtt/test_sensor.py @@ -410,7 +410,7 @@ async def test_setting_sensor_bad_last_reset_via_mqtt_message( async def test_setting_sensor_empty_last_reset_via_mqtt_message( - hass, caplog, mqtt_mock_entry_with_yaml_config + hass, mqtt_mock_entry_with_yaml_config ): """Test the setting of the last_reset property via MQTT.""" assert await async_setup_component( @@ -434,7 +434,6 @@ async def test_setting_sensor_empty_last_reset_via_mqtt_message( async_fire_mqtt_message(hass, "last-reset-topic", "") state = hass.states.get("sensor.test") assert state.attributes.get("last_reset") is None - assert "Ignoring empty last_reset message" in caplog.text async def test_setting_sensor_last_reset_via_mqtt_json_message( @@ -1147,14 +1146,6 @@ async def test_cleanup_triggers_and_restoring_state( ) await hass.async_block_till_done() - assert "Clean up expire after trigger for sensor.test1" in caplog.text - assert "Clean up expire after trigger for sensor.test2" not in caplog.text - assert ( - "State recovered after reload for sensor.test1, remaining time before expiring" - in caplog.text - ) - assert "State recovered after reload for sensor.test2" not in caplog.text - state = hass.states.get("sensor.test1") assert state.state == "38" # 100 °F -> 38 °C @@ -1171,7 +1162,7 @@ async def test_cleanup_triggers_and_restoring_state( async def test_skip_restoring_state_with_over_due_expire_trigger( - hass, mqtt_mock_entry_with_yaml_config, caplog, freezer + hass, mqtt_mock_entry_with_yaml_config, freezer ): """Test restoring a state with over due expire timer.""" @@ -1195,7 +1186,8 @@ async def test_skip_restoring_state_with_over_due_expire_trigger( ) await hass.async_block_till_done() await mqtt_mock_entry_with_yaml_config() - assert "Skip state recovery after reload for sensor.test3" in caplog.text + state = hass.states.get("sensor.test3") + assert state.state == STATE_UNAVAILABLE @pytest.mark.parametrize( diff --git a/tests/components/mqtt/test_siren.py b/tests/components/mqtt/test_siren.py index 361a043ed4b..02af2d7ac1c 100644 --- a/tests/components/mqtt/test_siren.py +++ b/tests/components/mqtt/test_siren.py @@ -276,10 +276,6 @@ async def test_controlling_state_and_attributes_with_json_message_without_templa assert state.attributes.get(siren.ATTR_TONE) == "bell" assert state.attributes.get(siren.ATTR_DURATION) == 5 assert state.attributes.get(siren.ATTR_VOLUME_LEVEL) == 0.6 - assert ( - "Ignoring empty payload '{}' after rendering for topic state-topic" - in caplog.text - ) async def test_filtering_not_supported_attributes_optimistic(