mirror of
https://github.com/home-assistant/core.git
synced 2025-04-28 03:07:50 +00:00
Set stateclass on unknown numeric Tasmota sensors (#120650)
This commit is contained in:
parent
9b5d0f72dc
commit
f28cbf1909
@ -298,6 +298,15 @@ class TasmotaSensor(TasmotaAvailability, TasmotaDiscoveryUpdate, SensorEntity):
|
|||||||
self._attr_native_unit_of_measurement = SENSOR_UNIT_MAP.get(
|
self._attr_native_unit_of_measurement = SENSOR_UNIT_MAP.get(
|
||||||
self._tasmota_entity.unit, self._tasmota_entity.unit
|
self._tasmota_entity.unit, self._tasmota_entity.unit
|
||||||
)
|
)
|
||||||
|
if (
|
||||||
|
self._attr_device_class is None
|
||||||
|
and self._attr_state_class is None
|
||||||
|
and self._attr_native_unit_of_measurement is None
|
||||||
|
):
|
||||||
|
# If the sensor has a numeric value, but we couldn't detect what it is,
|
||||||
|
# set state class to measurement.
|
||||||
|
if self._tasmota_entity.discovered_as_numeric:
|
||||||
|
self._attr_state_class = SensorStateClass.MEASUREMENT
|
||||||
|
|
||||||
async def async_added_to_hass(self) -> None:
|
async def async_added_to_hass(self) -> None:
|
||||||
"""Subscribe to MQTT events."""
|
"""Subscribe to MQTT events."""
|
||||||
|
@ -1546,3 +1546,301 @@
|
|||||||
'state': '2300',
|
'state': '2300',
|
||||||
})
|
})
|
||||||
# ---
|
# ---
|
||||||
|
# name: test_controlling_state_via_mqtt[sensor_config9-entity_ids9-messages9]
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'friendly_name': 'Tasmota SENSOR1 Unknown',
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'sensor.tasmota_sensor1_unknown',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': 'unavailable',
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_controlling_state_via_mqtt[sensor_config9-entity_ids9-messages9].1
|
||||||
|
EntityRegistryEntrySnapshot({
|
||||||
|
'aliases': set({
|
||||||
|
}),
|
||||||
|
'area_id': None,
|
||||||
|
'capabilities': None,
|
||||||
|
'config_entry_id': <ANY>,
|
||||||
|
'device_class': None,
|
||||||
|
'device_id': <ANY>,
|
||||||
|
'disabled_by': None,
|
||||||
|
'domain': 'sensor',
|
||||||
|
'entity_category': None,
|
||||||
|
'entity_id': 'sensor.tasmota_sensor1_unknown',
|
||||||
|
'has_entity_name': True,
|
||||||
|
'hidden_by': None,
|
||||||
|
'icon': None,
|
||||||
|
'id': <ANY>,
|
||||||
|
'labels': set({
|
||||||
|
}),
|
||||||
|
'name': None,
|
||||||
|
'options': dict({
|
||||||
|
}),
|
||||||
|
'original_device_class': None,
|
||||||
|
'original_icon': None,
|
||||||
|
'original_name': 'SENSOR1 Unknown',
|
||||||
|
'platform': 'tasmota',
|
||||||
|
'previous_unique_id': None,
|
||||||
|
'supported_features': 0,
|
||||||
|
'translation_key': None,
|
||||||
|
'unique_id': '00000049A3BC_sensor_sensor_SENSOR1_Unknown',
|
||||||
|
'unit_of_measurement': None,
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_controlling_state_via_mqtt[sensor_config9-entity_ids9-messages9].10
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'friendly_name': 'Tasmota SENSOR3 Unknown',
|
||||||
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'sensor.tasmota_sensor3_unknown',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': '20.5',
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_controlling_state_via_mqtt[sensor_config9-entity_ids9-messages9].11
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'friendly_name': 'Tasmota SENSOR4 Unknown',
|
||||||
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'sensor.tasmota_sensor4_unknown',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': '20.5',
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_controlling_state_via_mqtt[sensor_config9-entity_ids9-messages9].12
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'friendly_name': 'Tasmota SENSOR1 Unknown',
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'sensor.tasmota_sensor1_unknown',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': '20',
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_controlling_state_via_mqtt[sensor_config9-entity_ids9-messages9].13
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'friendly_name': 'Tasmota SENSOR2 Unknown',
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'sensor.tasmota_sensor2_unknown',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': '20',
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_controlling_state_via_mqtt[sensor_config9-entity_ids9-messages9].14
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'friendly_name': 'Tasmota SENSOR3 Unknown',
|
||||||
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'sensor.tasmota_sensor3_unknown',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': '20',
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_controlling_state_via_mqtt[sensor_config9-entity_ids9-messages9].15
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'friendly_name': 'Tasmota SENSOR4 Unknown',
|
||||||
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'sensor.tasmota_sensor4_unknown',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': '20',
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_controlling_state_via_mqtt[sensor_config9-entity_ids9-messages9].2
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'friendly_name': 'Tasmota SENSOR2 Unknown',
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'sensor.tasmota_sensor2_unknown',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': 'unavailable',
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_controlling_state_via_mqtt[sensor_config9-entity_ids9-messages9].3
|
||||||
|
EntityRegistryEntrySnapshot({
|
||||||
|
'aliases': set({
|
||||||
|
}),
|
||||||
|
'area_id': None,
|
||||||
|
'capabilities': None,
|
||||||
|
'config_entry_id': <ANY>,
|
||||||
|
'device_class': None,
|
||||||
|
'device_id': <ANY>,
|
||||||
|
'disabled_by': None,
|
||||||
|
'domain': 'sensor',
|
||||||
|
'entity_category': None,
|
||||||
|
'entity_id': 'sensor.tasmota_sensor2_unknown',
|
||||||
|
'has_entity_name': True,
|
||||||
|
'hidden_by': None,
|
||||||
|
'icon': None,
|
||||||
|
'id': <ANY>,
|
||||||
|
'labels': set({
|
||||||
|
}),
|
||||||
|
'name': None,
|
||||||
|
'options': dict({
|
||||||
|
}),
|
||||||
|
'original_device_class': None,
|
||||||
|
'original_icon': None,
|
||||||
|
'original_name': 'SENSOR2 Unknown',
|
||||||
|
'platform': 'tasmota',
|
||||||
|
'previous_unique_id': None,
|
||||||
|
'supported_features': 0,
|
||||||
|
'translation_key': None,
|
||||||
|
'unique_id': '00000049A3BC_sensor_sensor_SENSOR2_Unknown',
|
||||||
|
'unit_of_measurement': None,
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_controlling_state_via_mqtt[sensor_config9-entity_ids9-messages9].4
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'friendly_name': 'Tasmota SENSOR3 Unknown',
|
||||||
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'sensor.tasmota_sensor3_unknown',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': 'unavailable',
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_controlling_state_via_mqtt[sensor_config9-entity_ids9-messages9].5
|
||||||
|
EntityRegistryEntrySnapshot({
|
||||||
|
'aliases': set({
|
||||||
|
}),
|
||||||
|
'area_id': None,
|
||||||
|
'capabilities': dict({
|
||||||
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
|
}),
|
||||||
|
'config_entry_id': <ANY>,
|
||||||
|
'device_class': None,
|
||||||
|
'device_id': <ANY>,
|
||||||
|
'disabled_by': None,
|
||||||
|
'domain': 'sensor',
|
||||||
|
'entity_category': None,
|
||||||
|
'entity_id': 'sensor.tasmota_sensor3_unknown',
|
||||||
|
'has_entity_name': True,
|
||||||
|
'hidden_by': None,
|
||||||
|
'icon': None,
|
||||||
|
'id': <ANY>,
|
||||||
|
'labels': set({
|
||||||
|
}),
|
||||||
|
'name': None,
|
||||||
|
'options': dict({
|
||||||
|
}),
|
||||||
|
'original_device_class': None,
|
||||||
|
'original_icon': None,
|
||||||
|
'original_name': 'SENSOR3 Unknown',
|
||||||
|
'platform': 'tasmota',
|
||||||
|
'previous_unique_id': None,
|
||||||
|
'supported_features': 0,
|
||||||
|
'translation_key': None,
|
||||||
|
'unique_id': '00000049A3BC_sensor_sensor_SENSOR3_Unknown',
|
||||||
|
'unit_of_measurement': None,
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_controlling_state_via_mqtt[sensor_config9-entity_ids9-messages9].6
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'friendly_name': 'Tasmota SENSOR4 Unknown',
|
||||||
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'sensor.tasmota_sensor4_unknown',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': 'unavailable',
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_controlling_state_via_mqtt[sensor_config9-entity_ids9-messages9].7
|
||||||
|
EntityRegistryEntrySnapshot({
|
||||||
|
'aliases': set({
|
||||||
|
}),
|
||||||
|
'area_id': None,
|
||||||
|
'capabilities': dict({
|
||||||
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
|
}),
|
||||||
|
'config_entry_id': <ANY>,
|
||||||
|
'device_class': None,
|
||||||
|
'device_id': <ANY>,
|
||||||
|
'disabled_by': None,
|
||||||
|
'domain': 'sensor',
|
||||||
|
'entity_category': None,
|
||||||
|
'entity_id': 'sensor.tasmota_sensor4_unknown',
|
||||||
|
'has_entity_name': True,
|
||||||
|
'hidden_by': None,
|
||||||
|
'icon': None,
|
||||||
|
'id': <ANY>,
|
||||||
|
'labels': set({
|
||||||
|
}),
|
||||||
|
'name': None,
|
||||||
|
'options': dict({
|
||||||
|
}),
|
||||||
|
'original_device_class': None,
|
||||||
|
'original_icon': None,
|
||||||
|
'original_name': 'SENSOR4 Unknown',
|
||||||
|
'platform': 'tasmota',
|
||||||
|
'previous_unique_id': None,
|
||||||
|
'supported_features': 0,
|
||||||
|
'translation_key': None,
|
||||||
|
'unique_id': '00000049A3BC_sensor_sensor_SENSOR4_Unknown',
|
||||||
|
'unit_of_measurement': None,
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_controlling_state_via_mqtt[sensor_config9-entity_ids9-messages9].8
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'friendly_name': 'Tasmota SENSOR1 Unknown',
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'sensor.tasmota_sensor1_unknown',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': '20.5',
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_controlling_state_via_mqtt[sensor_config9-entity_ids9-messages9].9
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'friendly_name': 'Tasmota SENSOR2 Unknown',
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'sensor.tasmota_sensor2_unknown',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': '20.5',
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
@ -50,6 +50,17 @@ BAD_LIST_SENSOR_CONFIG_3 = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# This configuration has sensors which type we can't guess
|
||||||
|
DEFAULT_SENSOR_CONFIG_UNKNOWN = {
|
||||||
|
"sn": {
|
||||||
|
"Time": "2020-09-25T12:47:15",
|
||||||
|
"SENSOR1": {"Unknown": None},
|
||||||
|
"SENSOR2": {"Unknown": "123"},
|
||||||
|
"SENSOR3": {"Unknown": 123},
|
||||||
|
"SENSOR4": {"Unknown": 123.0},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# This configuration has some sensors where values are lists
|
# This configuration has some sensors where values are lists
|
||||||
# Home Assistant maps this to one sensor for each list item
|
# Home Assistant maps this to one sensor for each list item
|
||||||
LIST_SENSOR_CONFIG = {
|
LIST_SENSOR_CONFIG = {
|
||||||
@ -279,6 +290,20 @@ TEMPERATURE_SENSOR_CONFIG = {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
# Test we automatically set state class to measurement on unknown numerical sensors
|
||||||
|
(
|
||||||
|
DEFAULT_SENSOR_CONFIG_UNKNOWN,
|
||||||
|
[
|
||||||
|
"sensor.tasmota_sensor1_unknown",
|
||||||
|
"sensor.tasmota_sensor2_unknown",
|
||||||
|
"sensor.tasmota_sensor3_unknown",
|
||||||
|
"sensor.tasmota_sensor4_unknown",
|
||||||
|
],
|
||||||
|
(
|
||||||
|
'{"SENSOR1":{"Unknown":20.5},"SENSOR2":{"Unknown":20.5},"SENSOR3":{"Unknown":20.5},"SENSOR4":{"Unknown":20.5}}',
|
||||||
|
'{"StatusSNS":{"SENSOR1":{"Unknown":20},"SENSOR2":{"Unknown":20},"SENSOR3":{"Unknown":20},"SENSOR4":{"Unknown":20}}}',
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_controlling_state_via_mqtt(
|
async def test_controlling_state_via_mqtt(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user