diff --git a/homeassistant/components/mqtt/sensor.py b/homeassistant/components/mqtt/sensor.py index 9de442926a0..d63c41964bb 100644 --- a/homeassistant/components/mqtt/sensor.py +++ b/homeassistant/components/mqtt/sensor.py @@ -53,7 +53,7 @@ from .models import ( ReceiveMessage, ReceivePayloadType, ) -from .util import get_mqtt_data, valid_subscribe_topic +from .util import get_mqtt_data _LOGGER = logging.getLogger(__name__) @@ -73,36 +73,11 @@ DEFAULT_NAME = "MQTT Sensor" DEFAULT_FORCE_UPDATE = False -def validate_options(conf: ConfigType) -> ConfigType: - """Validate options. - - If last reset topic is present it must be same as the state topic. - """ - if ( - CONF_LAST_RESET_TOPIC in conf - and CONF_STATE_TOPIC in conf - and conf[CONF_LAST_RESET_TOPIC] != conf[CONF_STATE_TOPIC] - ): - _LOGGER.warning( - "'%s' must be same as '%s'", CONF_LAST_RESET_TOPIC, CONF_STATE_TOPIC - ) - - if CONF_LAST_RESET_TOPIC in conf and CONF_LAST_RESET_VALUE_TEMPLATE not in conf: - _LOGGER.warning( - "'%s' must be set if '%s' is set", - CONF_LAST_RESET_VALUE_TEMPLATE, - CONF_LAST_RESET_TOPIC, - ) - - return conf - - _PLATFORM_SCHEMA_BASE = MQTT_RO_SCHEMA.extend( { vol.Optional(CONF_DEVICE_CLASS): vol.Any(DEVICE_CLASSES_SCHEMA, None), vol.Optional(CONF_EXPIRE_AFTER): cv.positive_int, vol.Optional(CONF_FORCE_UPDATE, default=DEFAULT_FORCE_UPDATE): cv.boolean, - vol.Optional(CONF_LAST_RESET_TOPIC): valid_subscribe_topic, vol.Optional(CONF_LAST_RESET_VALUE_TEMPLATE): cv.template, vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_SUGGESTED_DISPLAY_PRECISION): cv.positive_int, @@ -112,8 +87,10 @@ _PLATFORM_SCHEMA_BASE = MQTT_RO_SCHEMA.extend( ).extend(MQTT_ENTITY_COMMON_SCHEMA.schema) PLATFORM_SCHEMA_MODERN = vol.All( + # Deprecated in HA Core 2021.11.0 https://github.com/home-assistant/core/pull/54840 + # Removed in HA Core 2023.6.0 + cv.removed(CONF_LAST_RESET_TOPIC), _PLATFORM_SCHEMA_BASE, - validate_options, ) # Configuring MQTT Sensors under the sensor platform key was deprecated in @@ -123,9 +100,10 @@ PLATFORM_SCHEMA = vol.All( ) DISCOVERY_SCHEMA = vol.All( - cv.deprecated(CONF_LAST_RESET_TOPIC), + # Deprecated in HA Core 2021.11.0 https://github.com/home-assistant/core/pull/54840 + # Removed in HA Core 2023.6.0 + cv.removed(CONF_LAST_RESET_TOPIC), _PLATFORM_SCHEMA_BASE.extend({}, extra=vol.REMOVE_EXTRA), - validate_options, ) @@ -319,10 +297,7 @@ class MqttSensor(MqttEntity, RestoreSensor): def message_received(msg: ReceiveMessage) -> None: """Handle new MQTT messages.""" _update_state(msg) - if CONF_LAST_RESET_VALUE_TEMPLATE in self._config and ( - CONF_LAST_RESET_TOPIC not in self._config - or self._config[CONF_LAST_RESET_TOPIC] == self._config[CONF_STATE_TOPIC] - ): + if CONF_LAST_RESET_VALUE_TEMPLATE in self._config: _update_last_reset(msg) get_mqtt_data(self.hass).state_write_requests.write_state_request(self) @@ -333,24 +308,6 @@ class MqttSensor(MqttEntity, RestoreSensor): "encoding": self._config[CONF_ENCODING] or None, } - @callback - @log_messages(self.hass, self.entity_id) - def last_reset_message_received(msg: ReceiveMessage) -> None: - """Handle new last_reset messages.""" - _update_last_reset(msg) - get_mqtt_data(self.hass).state_write_requests.write_state_request(self) - - if ( - CONF_LAST_RESET_TOPIC in self._config - and self._config[CONF_LAST_RESET_TOPIC] != self._config[CONF_STATE_TOPIC] - ): - topics["last_reset_topic"] = { - "topic": self._config[CONF_LAST_RESET_TOPIC], - "msg_callback": last_reset_message_received, - "qos": self._config[CONF_QOS], - "encoding": self._config[CONF_ENCODING] or None, - } - self._sub_state = subscription.async_prepare_subscribe_topics( self.hass, self._sub_state, topics ) diff --git a/tests/components/mqtt/test_sensor.py b/tests/components/mqtt/test_sensor.py index 64499f11140..16697939f50 100644 --- a/tests/components/mqtt/test_sensor.py +++ b/tests/components/mqtt/test_sensor.py @@ -480,117 +480,44 @@ async def test_setting_sensor_value_via_mqtt_json_message_and_default_current_st "state_class": "total", "state_topic": "test-topic", "unit_of_measurement": "fav unit", - "last_reset_topic": "last-reset-topic", - } - } - } - ], -) -async def test_setting_sensor_last_reset_via_mqtt_message( - hass: HomeAssistant, - mqtt_mock_entry: MqttMockHAClientGenerator, - caplog: pytest.LogCaptureFixture, -) -> None: - """Test the setting of the last_reset property via MQTT.""" - await mqtt_mock_entry() - - async_fire_mqtt_message(hass, "last-reset-topic", "2020-01-02 08:11:00") - state = hass.states.get("sensor.test") - assert state.attributes.get("last_reset") == "2020-01-02T08:11:00" - assert "'last_reset_topic' must be same as 'state_topic'" in caplog.text - assert ( - "'last_reset_value_template' must be set if 'last_reset_topic' is set" - in caplog.text - ) - - -@pytest.mark.parametrize( - "hass_config", - [ - { - mqtt.DOMAIN: { - sensor.DOMAIN: { - "name": "test", - "state_class": "total", - "state_topic": "test-topic", - "unit_of_measurement": "fav unit", - "last_reset_topic": "last-reset-topic", - } - } - } - ], -) -@pytest.mark.parametrize("datestring", ["2020-21-02 08:11:00", "Hello there!"]) -async def test_setting_sensor_bad_last_reset_via_mqtt_message( - hass: HomeAssistant, - caplog: pytest.LogCaptureFixture, - datestring, - mqtt_mock_entry: MqttMockHAClientGenerator, -) -> None: - """Test the setting of the last_reset property via MQTT.""" - await mqtt_mock_entry() - - async_fire_mqtt_message(hass, "last-reset-topic", datestring) - state = hass.states.get("sensor.test") - assert state.attributes.get("last_reset") is None - assert "Invalid last_reset message" in caplog.text - - -@pytest.mark.parametrize( - "hass_config", - [ - { - mqtt.DOMAIN: { - sensor.DOMAIN: { - "name": "test", - "state_class": "total", - "state_topic": "test-topic", - "unit_of_measurement": "fav unit", - "last_reset_topic": "last-reset-topic", - } - } - } - ], -) -async def test_setting_sensor_empty_last_reset_via_mqtt_message( - hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator -) -> None: - """Test the setting of the last_reset property via MQTT.""" - await mqtt_mock_entry() - - async_fire_mqtt_message(hass, "last-reset-topic", "") - state = hass.states.get("sensor.test") - assert state.attributes.get("last_reset") is None - - -@pytest.mark.parametrize( - "hass_config", - [ - { - mqtt.DOMAIN: { - sensor.DOMAIN: { - "name": "test", - "state_class": "total", - "state_topic": "test-topic", - "unit_of_measurement": "fav unit", - "last_reset_topic": "last-reset-topic", "last_reset_value_template": "{{ value_json.last_reset }}", + "value_template": "{{ value_json.state }}", } } } ], ) +@pytest.mark.parametrize( + ("message", "last_reset", "state"), + [ + ( + '{ "last_reset": "2020-01-02 08:11:00" }', + "2020-01-02T08:11:00", + STATE_UNKNOWN, + ), + ( + '{ "last_reset": "2020-01-02 08:11:03", "state": 10.0 }', + "2020-01-02T08:11:03", + "10.0", + ), + ('{ "last_reset": null, "state": 10.1 }', None, "10.1"), + ('{ "last_reset": "", "state": 10.1 }', None, "10.1"), + ], +) async def test_setting_sensor_last_reset_via_mqtt_json_message( - hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator + hass: HomeAssistant, + mqtt_mock_entry: MqttMockHAClientGenerator, + message: str, + last_reset: str, + state: str, ) -> None: """Test the setting of the value via MQTT with JSON payload.""" await mqtt_mock_entry() - async_fire_mqtt_message( - hass, "last-reset-topic", '{ "last_reset": "2020-01-02 08:11:00" }' - ) - state = hass.states.get("sensor.test") - assert state.attributes.get("last_reset") == "2020-01-02T08:11:00" + async_fire_mqtt_message(hass, "test-topic", message) + sensor_state = hass.states.get("sensor.test") + assert sensor_state.attributes.get("last_reset") == last_reset + assert sensor_state.state == state @pytest.mark.parametrize( @@ -608,19 +535,6 @@ async def test_setting_sensor_last_reset_via_mqtt_json_message( }, } }, - { - mqtt.DOMAIN: { - sensor.DOMAIN: { - "name": "test", - "state_class": "total", - "state_topic": "test-topic", - "unit_of_measurement": "kWh", - "value_template": "{{ value_json.value | float / 60000 }}", - "last_reset_value_template": "{{ utcnow().fromtimestamp(value_json.time / 1000, tz=utcnow().tzinfo) }}", - "last_reset_topic": "test-topic", - }, - } - }, ], ) async def test_setting_sensor_last_reset_via_mqtt_json_message_2( @@ -640,11 +554,6 @@ async def test_setting_sensor_last_reset_via_mqtt_json_message_2( state = hass.states.get("sensor.test") assert float(state.state) == pytest.approx(0.015796176944444445) assert state.attributes.get("last_reset") == "2021-08-19T15:05:00+00:00" - assert "'last_reset_topic' must be same as 'state_topic'" not in caplog.text - assert ( - "'last_reset_value_template' must be set if 'last_reset_topic' is set" - not in caplog.text - ) @pytest.mark.parametrize(