Set stateclass on unknown numeric Tasmota sensors (#120650)
This commit is contained in:
parent
4e34d02d2d
commit
ec069f9084
3 changed files with 332 additions and 0 deletions
|
@ -302,6 +302,15 @@ class TasmotaSensor(TasmotaAvailability, TasmotaDiscoveryUpdate, SensorEntity):
|
|||
self._attr_native_unit_of_measurement = SENSOR_UNIT_MAP.get(
|
||||
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:
|
||||
"""Subscribe to MQTT events."""
|
||||
|
|
|
@ -1712,3 +1712,301 @@
|
|||
'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
|
||||
# Home Assistant maps this to one sensor for each list item
|
||||
LIST_SENSOR_CONFIG = {
|
||||
|
@ -281,6 +292,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(
|
||||
|
|
Loading…
Add table
Reference in a new issue