Skip to content

Commit 0b283d1

Browse files
committed
Fix state for zigbee light #711
1 parent 00fa5d2 commit 0b283d1

File tree

7 files changed

+82
-13
lines changed

7 files changed

+82
-13
lines changed

custom_components/yandex_station/button.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from homeassistant.components.button import ButtonEntity
22

3-
from .core.entity import YandexCustomEntity, YandexEntity
3+
from .core.entity import YandexCustomEntity, YandexEntity, extract_instance
44
from .core.yandex_quasar import YandexQuasar
55
from .hass import hass_utils
66

@@ -27,7 +27,7 @@ async def async_setup_entry(hass, entry, async_add_entities):
2727
for instance in device["capabilities"]:
2828
if instance["type"] not in INCLUDE_CAPABILITIES:
2929
continue
30-
if instance["parameters"].get("instance", "on") in instances:
30+
if extract_instance(instance) in instances:
3131
entities.append(YandexCustomButton(quasar, device, instance))
3232

3333
async_add_entities(entities)

custom_components/yandex_station/core/entity.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,24 @@
99
_LOGGER = logging.getLogger(__name__)
1010

1111

12+
def extract_instance(item: dict) -> str:
13+
if item["type"] == "devices.capabilities.on_off":
14+
return "on"
15+
return item["parameters"].get("instance")
16+
17+
1218
def extract_parameters(items: list[dict]) -> dict:
1319
result = {}
1420
for item in items:
15-
instance = item["parameters"].get("instance", "on")
21+
instance = extract_instance(item)
1622
result[instance] = {"retrievable": item["retrievable"], **item["parameters"]}
1723
return result
1824

1925

2026
def extract_state(items: list[dict]) -> dict:
2127
result = {}
2228
for item in items:
23-
instance = item["parameters"].get("instance", "on")
29+
instance = extract_instance(item)
2430
value = item["state"]["value"] if item["state"] else None
2531
result[instance] = value
2632
return result
@@ -32,7 +38,8 @@ def __init__(self, quasar: YandexQuasar, device: dict, config: dict = None):
3238
self.device = device
3339
self.config = config
3440

35-
self._attr_available = device["state"] in ("online", "unknown")
41+
# "online", "unknown" or key not exist
42+
self._attr_available = device.get("state") != "offline"
3643
self._attr_name = device["name"]
3744
self._attr_should_poll = False
3845
self._attr_unique_id = device["id"].replace("-", "")
@@ -104,7 +111,7 @@ async def device_actions(self, **kwargs):
104111

105112
class YandexCustomEntity(YandexEntity):
106113
def __init__(self, quasar: YandexQuasar, device: dict, config: dict):
107-
self.instance = config["parameters"].get("instance", "on")
114+
self.instance = extract_instance(config)
108115
super().__init__(quasar, device)
109116
if name := config["parameters"].get("name"):
110117
self._attr_name += " " + name

custom_components/yandex_station/hass/hass_utils.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
from ..climate import INCLUDE_TYPES as CLIMATE
99
from ..core.const import DATA_CONFIG, DOMAIN
10+
from ..core.entity import extract_instance
1011
from ..core.yandex_quasar import YandexQuasar
1112
from ..cover import INCLUDE_TYPES as COVER
1213
from ..humidifier import INCLUDE_TYPES as HUMIDIFIER
@@ -85,7 +86,7 @@ def build_include_config(device: dict) -> dict:
8586
else:
8687
return {}
8788

88-
caps = [i["parameters"].get("instance", "on") for i in device["capabilities"]]
89+
caps = [extract_instance(i) for i in device["capabilities"]]
8990
props = [i["parameters"]["instance"] for i in device["properties"]]
9091

9192
return {

custom_components/yandex_station/number.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from homeassistant.components.number import NumberEntity
44
from homeassistant.const import UnitOfTemperature
55

6-
from .core.entity import YandexCustomEntity
6+
from .core.entity import YandexCustomEntity, extract_instance
77
from .hass import hass_utils
88

99
_LOGGER = logging.getLogger(__name__)
@@ -21,7 +21,7 @@ async def async_setup_entry(hass, entry, async_add_entities):
2121
for instance in device["capabilities"]:
2222
if instance["type"] not in INCLUDE_CAPABILITIES:
2323
continue
24-
if instance["parameters"].get("instance", "on") in instances:
24+
if extract_instance(instance) in instances:
2525
entities.append(YandexCustomNumber(quasar, device, instance))
2626

2727
async_add_entities(entities)

custom_components/yandex_station/select.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from homeassistant.helpers.entity import DeviceInfo
55

66
from .core.const import DOMAIN
7-
from .core.entity import YandexCustomEntity
7+
from .core.entity import YandexCustomEntity, extract_instance
88
from .core.yandex_quasar import YandexQuasar
99
from .hass import hass_utils
1010

@@ -66,7 +66,7 @@ async def async_setup_entry(hass, entry, async_add_entities):
6666
for instance in device["capabilities"]:
6767
if instance["type"] not in INCLUDE_CAPABILITIES:
6868
continue
69-
if instance["parameters"].get("instance", "on") in instances:
69+
if extract_instance(instance) in instances:
7070
entities.append(YandexCustomSelect(quasar, device, instance))
7171

7272
async_add_entities(entities)

custom_components/yandex_station/switch.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from homeassistant.components.switch import SwitchEntity
44

5-
from .core.entity import YandexCustomEntity, YandexEntity
5+
from .core.entity import YandexCustomEntity, YandexEntity, extract_instance
66
from .core.yandex_quasar import YandexQuasar
77
from .hass import hass_utils
88

@@ -28,7 +28,7 @@ async def async_setup_entry(hass, entry, async_add_entities):
2828
for instance in device["capabilities"]:
2929
if instance["type"] not in INCLUDE_CAPABILITIES:
3030
continue
31-
if instance["parameters"].get("instance", "on") in instances:
31+
if extract_instance(instance) in instances:
3232
entities.append(YandexCustomSwitch(quasar, device, instance))
3333

3434
async_add_entities(entities)

tests/test_light.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,3 +544,64 @@ def test_issue465():
544544
"supported_features": LightEntityFeature.EFFECT,
545545
# "xy_color": (0.496, 0.383),
546546
}
547+
548+
549+
def test_issue711():
550+
device = {
551+
"id": "xxx",
552+
"name": "Свет на крыльце",
553+
"type": "devices.types.light",
554+
"icon_url": "https://avatars.mds.yandex.net/get-iot/icons-devices-devices.types.light.svg/orig",
555+
"capabilities": [
556+
{
557+
"reportable": true,
558+
"retrievable": true,
559+
"type": "devices.capabilities.on_off",
560+
"state_changed_at": 1761939645.3040287,
561+
"last_updated": 1761977954.1980345,
562+
"parameters": {"split": false},
563+
"state": {"instance": "on", "value": false},
564+
},
565+
{
566+
"reportable": true,
567+
"retrievable": false,
568+
"type": "devices.capabilities.zigbee_node",
569+
"state_changed_at": 1761978012.2432792,
570+
"last_updated": 1761978012.2432792,
571+
"parameters": {"type": "router"},
572+
"state": {
573+
"value": {
574+
"signal_quality": {"status": "ok", "lqi": 75, "rssi": -74}
575+
}
576+
},
577+
},
578+
],
579+
"properties": [
580+
{
581+
"type": "devices.properties.float",
582+
"retrievable": false,
583+
"reportable": true,
584+
"parameters": {
585+
"instance": "power",
586+
"name": "потребляемая мощность",
587+
"unit": "unit.watt",
588+
"range": {"min": 0, "max": 3500, "precision": 0.1},
589+
},
590+
"state": {"percent": null, "status": null, "value": 0},
591+
"state_changed_at": "2025-10-31T19:40:46Z",
592+
"last_updated": "2025-11-01T05:38:23Z",
593+
}
594+
],
595+
"skill_id": "YANDEX_IO",
596+
"item_type": "device",
597+
"groups": [],
598+
}
599+
600+
state = update_ha_state(YandexLight, device)
601+
assert state.state == "off"
602+
assert state.attributes == {
603+
"color_mode": None,
604+
"friendly_name": "Свет на крыльце",
605+
"supported_color_modes": [ColorMode.ONOFF],
606+
"supported_features": 0,
607+
}

0 commit comments

Comments
 (0)