Fix no temperature unit in SmartThings (#140363)

This commit is contained in:
Joost Lekkerkerker 2025-03-11 14:03:15 +01:00 committed by GitHub
parent daaa1486fc
commit bc6d342919
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 372 additions and 4 deletions

View File

@ -321,10 +321,14 @@ class SmartThingsThermostat(SmartThingsEntity, ClimateEntity):
@property @property
def temperature_unit(self) -> str: def temperature_unit(self) -> str:
"""Return the unit of measurement.""" """Return the unit of measurement."""
unit = self._internal_state[Capability.TEMPERATURE_MEASUREMENT][ # Offline third party thermostats may not have a unit
Attribute.TEMPERATURE # Since climate always requires a unit, default to Celsius
].unit if (
assert unit unit := self._internal_state[Capability.TEMPERATURE_MEASUREMENT][
Attribute.TEMPERATURE
].unit
) is None:
return UnitOfTemperature.CELSIUS
return UNIT_MAP[unit] return UNIT_MAP[unit]

View File

@ -120,6 +120,7 @@ def mock_smartthings() -> Generator[AsyncMock]:
"sensibo_airconditioner_1", "sensibo_airconditioner_1",
"ecobee_sensor", "ecobee_sensor",
"ecobee_thermostat", "ecobee_thermostat",
"ecobee_thermostat_offline",
"fake_fan", "fake_fan",
"generic_fan_3_speed", "generic_fan_3_speed",
"heatit_ztrm3_thermostat", "heatit_ztrm3_thermostat",

View File

@ -0,0 +1,81 @@
{
"components": {
"main": {
"relativeHumidityMeasurement": {
"humidity": {
"value": null
}
},
"thermostatOperatingState": {
"thermostatOperatingState": {
"value": null
}
},
"healthCheck": {
"checkInterval": {
"value": 60,
"unit": "s",
"data": {
"deviceScheme": "UNTRACKED",
"protocol": "cloud"
},
"timestamp": "2025-03-10T00:57:26.866Z"
},
"healthStatus": {
"value": null
},
"DeviceWatch-Enroll": {
"value": null
},
"DeviceWatch-DeviceStatus": {
"value": "offline",
"data": {
"reason": "DEVICE-OFFLINE"
},
"timestamp": "2025-03-11T10:22:17.013Z"
}
},
"temperatureMeasurement": {
"temperatureRange": {
"value": null
},
"temperature": {
"value": null
}
},
"thermostatHeatingSetpoint": {
"heatingSetpoint": {
"value": null
},
"heatingSetpointRange": {
"value": null
}
},
"thermostatFanMode": {
"thermostatFanMode": {
"value": null
},
"supportedThermostatFanModes": {
"value": null
}
},
"refresh": {},
"thermostatMode": {
"thermostatMode": {
"value": null
},
"supportedThermostatModes": {
"value": null
}
},
"thermostatCoolingSetpoint": {
"coolingSetpointRange": {
"value": null
},
"coolingSetpoint": {
"value": null
}
}
}
}
}

View File

@ -0,0 +1,82 @@
{
"items": [
{
"deviceId": "1888b38f-6246-4f1e-911b-bfcfb66999db",
"name": "v4 - ecobee Thermostat - Heat and Cool (F)",
"label": "Downstairs",
"manufacturerName": "0A0b",
"presentationId": "ST_5334da38-8076-4b40-9f6c-ac3fccaa5d24",
"deviceManufacturerCode": "ecobee",
"locationId": "1030449a-22c1-4a80-9781-0bd4ab7f0f2f",
"ownerId": "e7dbb793-4351-4cdc-b037-e6e0b4f9df67",
"roomId": "d22e6f98-78fe-4a76-b904-6cad8628da59",
"components": [
{
"id": "main",
"label": "main",
"capabilities": [
{
"id": "temperatureMeasurement",
"version": 1
},
{
"id": "relativeHumidityMeasurement",
"version": 1
},
{
"id": "thermostatHeatingSetpoint",
"version": 1
},
{
"id": "thermostatCoolingSetpoint",
"version": 1
},
{
"id": "thermostatOperatingState",
"version": 1
},
{
"id": "thermostatMode",
"version": 1
},
{
"id": "thermostatFanMode",
"version": 1
},
{
"id": "refresh",
"version": 1
},
{
"id": "healthCheck",
"version": 1
}
],
"categories": [
{
"name": "Thermostat",
"categoryType": "manufacturer"
}
]
}
],
"createTime": "2025-03-10T00:57:26.760Z",
"profile": {
"id": "234d537d-d388-497f-b0f4-2e25025119ba"
},
"viper": {
"manufacturerName": "ecobee",
"modelName": "nikeSmart-thermostat",
"swVersion": "250308073247",
"hwVersion": "250308073247",
"endpointAppId": "viper_92ccdcc0-4184-11eb-b9c5-036180216747"
},
"type": "VIPER",
"restrictionTier": 0,
"allowed": null,
"executionContext": "CLOUD",
"relationships": []
}
],
"_links": {}
}

View File

@ -432,6 +432,70 @@
'state': 'heat', 'state': 'heat',
}) })
# --- # ---
# name: test_all_entities[ecobee_thermostat_offline][climate.downstairs-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'fan_modes': None,
'hvac_modes': list([
]),
'max_temp': 35,
'min_temp': 7,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'climate',
'entity_category': None,
'entity_id': 'climate.downstairs',
'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': None,
'platform': 'smartthings',
'previous_unique_id': None,
'supported_features': <ClimateEntityFeature: 395>,
'translation_key': None,
'unique_id': '1888b38f-6246-4f1e-911b-bfcfb66999db',
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[ecobee_thermostat_offline][climate.downstairs-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'current_temperature': None,
'fan_mode': None,
'fan_modes': None,
'friendly_name': 'Downstairs',
'hvac_modes': list([
]),
'max_temp': 35,
'min_temp': 7,
'supported_features': <ClimateEntityFeature: 395>,
'target_temp_high': None,
'target_temp_low': None,
'temperature': None,
}),
'context': <ANY>,
'entity_id': 'climate.downstairs',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_all_entities[generic_ef00_v1][climate.thermostat_kuche-entry] # name: test_all_entities[generic_ef00_v1][climate.thermostat_kuche-entry]
EntityRegistryEntrySnapshot({ EntityRegistryEntrySnapshot({
'aliases': set({ 'aliases': set({

View File

@ -662,6 +662,39 @@
'via_device_id': None, 'via_device_id': None,
}) })
# --- # ---
# name: test_devices[ecobee_thermostat_offline]
DeviceRegistryEntrySnapshot({
'area_id': None,
'config_entries': <ANY>,
'config_entries_subentries': <ANY>,
'configuration_url': 'https://account.smartthings.com',
'connections': set({
}),
'disabled_by': None,
'entry_type': None,
'hw_version': '250308073247',
'id': <ANY>,
'identifiers': set({
tuple(
'smartthings',
'1888b38f-6246-4f1e-911b-bfcfb66999db',
),
}),
'is_new': False,
'labels': set({
}),
'manufacturer': 'ecobee',
'model': 'nikeSmart-thermostat',
'model_id': None,
'name': 'Downstairs',
'name_by_user': None,
'primary_config_entry': <ANY>,
'serial_number': None,
'suggested_area': None,
'sw_version': '250308073247',
'via_device_id': None,
})
# ---
# name: test_devices[fake_fan] # name: test_devices[fake_fan]
DeviceRegistryEntrySnapshot({ DeviceRegistryEntrySnapshot({
'area_id': 'theater', 'area_id': 'theater',

View File

@ -5093,6 +5093,109 @@
'state': '22', 'state': '22',
}) })
# --- # ---
# name: test_all_entities[ecobee_thermostat_offline][sensor.downstairs_humidity-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.downstairs_humidity',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.HUMIDITY: 'humidity'>,
'original_icon': None,
'original_name': 'Humidity',
'platform': 'smartthings',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': '1888b38f-6246-4f1e-911b-bfcfb66999db.humidity',
'unit_of_measurement': '%',
})
# ---
# name: test_all_entities[ecobee_thermostat_offline][sensor.downstairs_humidity-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'humidity',
'friendly_name': 'Downstairs Humidity',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': '%',
}),
'context': <ANY>,
'entity_id': 'sensor.downstairs_humidity',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_all_entities[ecobee_thermostat_offline][sensor.downstairs_temperature-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.downstairs_temperature',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.TEMPERATURE: 'temperature'>,
'original_icon': None,
'original_name': 'Temperature',
'platform': 'smartthings',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': '1888b38f-6246-4f1e-911b-bfcfb66999db.temperature',
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[ecobee_thermostat_offline][sensor.downstairs_temperature-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'temperature',
'friendly_name': 'Downstairs Temperature',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'context': <ANY>,
'entity_id': 'sensor.downstairs_temperature',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_all_entities[generic_ef00_v1][sensor.thermostat_kuche_link_quality-entry] # name: test_all_entities[generic_ef00_v1][sensor.thermostat_kuche_link_quality-entry]
EntityRegistryEntrySnapshot({ EntityRegistryEntrySnapshot({
'aliases': set({ 'aliases': set({