Fix myUplink select platform failing on decimal enum values (#182602)

This commit is contained in:
Franck Nijhof
2026-09-29 16:59:34 +01:00
committed by GitHub
parent a94a4f83da
commit 1c1dcfd950
3 changed files with 255 additions and 7 deletions
+8 -6
View File
@@ -66,26 +66,28 @@ class MyUplinkSelect(MyUplinkEntity, SelectEntity):
self._attr_name = device_point.parameter_name
self._attr_options = [x["text"].capitalize() for x in device_point.enum_values]
# enum values are numeric strings, with decimals on some devices ("0.3"),
# so match them as numbers and keep the raw string to write back
self.options_map = {
str(int(x["value"])): x["text"].capitalize()
for x in device_point.enum_values
float(x["value"]): x["text"].capitalize() for x in device_point.enum_values
}
self.options_rev = {
x["text"].capitalize(): x["value"] for x in device_point.enum_values
}
self.options_rev = {value: key for key, value in self.options_map.items()}
@property
@override
def current_option(self) -> str | None:
"""Retrieve currently selected option."""
device_point = self.coordinator.data.points[self.device_id][self.point_id]
value = int(cast(int, device_point.value_t))
return self.options_map.get(str(value))
return self.options_map.get(float(cast(float, device_point.value_t)))
@override
async def async_select_option(self, option: str) -> None:
"""Set the current option."""
try:
await self.coordinator.api.async_set_device_points(
self.device_id, data={self.point_id: str(self.options_rev[option])}
self.device_id, data={self.point_id: self.options_rev[option]}
)
except ClientError as err:
raise HomeAssistantError(
@@ -0,0 +1,208 @@
[
{
"category": "Add. heat",
"parameterId": "61590",
"parameterName": "Lower Immersion heater / heating kW",
"parameterUnit": "",
"writable": true,
"timestamp": "2026-09-17T17:53:27+00:00",
"value": 3.0,
"strVal": "3",
"smartHomeCategories": [],
"minValue": null,
"maxValue": null,
"stepValue": 1.0,
"enumValues": [
{
"value": "0.0",
"text": "0.0",
"icon": ""
},
{
"value": "3.0",
"text": "3.0",
"icon": ""
}
],
"scaleValue": "0.1",
"zoneId": null
},
{
"category": "Add. heat",
"parameterId": "61591",
"parameterName": "Upper Immersion heater / DHW kW",
"parameterUnit": "",
"writable": true,
"timestamp": "2026-09-17T17:53:27+00:00",
"value": 8.7,
"strVal": "8.7",
"smartHomeCategories": [],
"minValue": null,
"maxValue": null,
"stepValue": 1.0,
"enumValues": [
{
"value": "0.0",
"text": "0.0",
"icon": ""
},
{
"value": "0.3",
"text": "0.3",
"icon": ""
},
{
"value": "0.6",
"text": "0.6",
"icon": ""
},
{
"value": "0.9",
"text": "0.9",
"icon": ""
},
{
"value": "1.2",
"text": "1.2",
"icon": ""
},
{
"value": "1.5",
"text": "1.5",
"icon": ""
},
{
"value": "1.8",
"text": "1.8",
"icon": ""
},
{
"value": "2.1",
"text": "2.1",
"icon": ""
},
{
"value": "2.3",
"text": "2.3",
"icon": ""
},
{
"value": "2.6",
"text": "2.6",
"icon": ""
},
{
"value": "2.9",
"text": "2.9",
"icon": ""
},
{
"value": "3.2",
"text": "3.2",
"icon": ""
},
{
"value": "3.5",
"text": "3.5",
"icon": ""
},
{
"value": "3.8",
"text": "3.8",
"icon": ""
},
{
"value": "4.1",
"text": "4.1",
"icon": ""
},
{
"value": "4.4",
"text": "4.4",
"icon": ""
},
{
"value": "4.6",
"text": "4.6",
"icon": ""
},
{
"value": "4.9",
"text": "4.9",
"icon": ""
},
{
"value": "5.2",
"text": "5.2",
"icon": ""
},
{
"value": "5.5",
"text": "5.5",
"icon": ""
},
{
"value": "5.8",
"text": "5.8",
"icon": ""
},
{
"value": "6.1",
"text": "6.1",
"icon": ""
},
{
"value": "6.4",
"text": "6.4",
"icon": ""
},
{
"value": "6.7",
"text": "6.7",
"icon": ""
},
{
"value": "6.9",
"text": "6.9",
"icon": ""
},
{
"value": "7.2",
"text": "7.2",
"icon": ""
},
{
"value": "7.5",
"text": "7.5",
"icon": ""
},
{
"value": "7.8",
"text": "7.8",
"icon": ""
},
{
"value": "8.1",
"text": "8.1",
"icon": ""
},
{
"value": "8.4",
"text": "8.4",
"icon": ""
},
{
"value": "8.7",
"text": "8.7",
"icon": ""
},
{
"value": "9.0",
"text": "9.0",
"icon": ""
}
],
"scaleValue": "0.1",
"zoneId": null
}
]
+39 -1
View File
@@ -6,7 +6,8 @@ from aiohttp import ClientError
import pytest
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.select import DOMAIN as SELECT_DOMAIN
from homeassistant.components.myuplink.const import DOMAIN
from homeassistant.components.select import ATTR_OPTIONS, DOMAIN as SELECT_DOMAIN
from homeassistant.const import (
ATTR_ENTITY_ID,
ATTR_OPTION,
@@ -24,6 +25,7 @@ pytestmark = pytest.mark.parametrize("platforms", [(Platform.SELECT,)])
ENTITY_ID = "select.gotham_city_comfort_mode"
ENTITY_FRIENDLY_NAME = "Gotham City comfort mode"
ENTITY_UID = "robin-r-1234-20240201-123456-aa-bb-cc-dd-ee-ff-47041"
DEVICE_ID = "robin-r-1234-20240201-123456-aa-bb-cc-dd-ee-ff"
async def test_selecting(
@@ -71,6 +73,42 @@ async def test_entity_registry_smo20(
assert entry.unique_id == "robin-r-1234-20240201-123456-aa-bb-cc-dd-ee-ff-47660"
@pytest.mark.parametrize(
"load_device_points_file",
["device_points_ctc_i555.json"],
)
async def test_decimal_enum_values(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
mock_myuplink_client: MagicMock,
setup_platform: None,
) -> None:
"""Test select entities for enum values with decimals, as a CTC i555 reports."""
lower_heater = entity_registry.async_get_entity_id(
SELECT_DOMAIN, DOMAIN, f"{DEVICE_ID}-61590"
)
upper_heater = entity_registry.async_get_entity_id(
SELECT_DOMAIN, DOMAIN, f"{DEVICE_ID}-61591"
)
assert lower_heater is not None
assert upper_heater is not None
lower_state = hass.states.get(lower_heater)
assert lower_state.state == "3.0"
assert lower_state.attributes[ATTR_OPTIONS] == ["0.0", "3.0"]
assert hass.states.get(upper_heater).state == "8.7"
await hass.services.async_call(
SELECT_DOMAIN,
SERVICE_SELECT_OPTION,
{ATTR_ENTITY_ID: upper_heater, ATTR_OPTION: "0.3"},
blocking=True,
)
mock_myuplink_client.async_set_device_points.assert_called_once_with(
DEVICE_ID, data={"61591": "0.3"}
)
async def test_select_states(
hass: HomeAssistant,
mock_myuplink_client: MagicMock,