Skip to content

Commit edb06c5

Browse files
authored
Add unique_identifier property to miot properties, actions, and events (#1984)
This allows descriptors to have device-unique identifiers, the format is '<normalized_name>_<siid>_<id>'. This also changes 'id' of the descriptors to use this identifier in-place of a plain name from the description.
1 parent 62427d2 commit edb06c5

File tree

2 files changed

+41
-6
lines changed

2 files changed

+41
-6
lines changed

miio/miot_models.py

+25-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import logging
2+
from abc import abstractmethod
23
from datetime import timedelta
34
from enum import Enum
45
from typing import Any, Optional
@@ -150,6 +151,11 @@ def normalized_name(self) -> str:
150151
"""
151152
return self.name.replace(":", "_").replace("-", "_")
152153

154+
@property
155+
@abstractmethod
156+
def unique_identifier(self) -> str:
157+
"""Return unique identifier."""
158+
153159

154160
class MiotAction(MiotBaseModel):
155161
"""Action presentation for miot."""
@@ -176,8 +182,6 @@ def fill_from_parent(self, service: "MiotService"):
176182

177183
def get_descriptor(self):
178184
"""Create a descriptor based on the property information."""
179-
id_ = self.name
180-
181185
extras = self.extras
182186
extras["urn"] = self.urn
183187
extras["siid"] = self.siid
@@ -190,12 +194,17 @@ def get_descriptor(self):
190194
inputs = [prop.get_descriptor() for prop in self.inputs]
191195

192196
return ActionDescriptor(
193-
id=id_,
197+
id=self.unique_identifier,
194198
name=self.description,
195199
inputs=inputs,
196200
extras=extras,
197201
)
198202

203+
@property
204+
def unique_identifier(self) -> str:
205+
"""Return unique identifier."""
206+
return f"{self.normalized_name}_{self.siid}_{self.aiid}"
207+
199208
class Config:
200209
extra = "forbid"
201210

@@ -327,7 +336,7 @@ def _create_enum_descriptor(self) -> EnumDescriptor:
327336
raise
328337

329338
desc = EnumDescriptor(
330-
id=self.name,
339+
id=self.unique_identifier,
331340
name=self.description,
332341
status_attribute=self.normalized_name,
333342
unit=self.unit,
@@ -346,7 +355,7 @@ def _create_range_descriptor(
346355
if self.range is None:
347356
raise ValueError("Range is None")
348357
desc = RangeDescriptor(
349-
id=self.name,
358+
id=self.unique_identifier,
350359
name=self.description,
351360
status_attribute=self.normalized_name,
352361
min_value=self.range[0],
@@ -363,14 +372,19 @@ def _create_range_descriptor(
363372
def _create_regular_descriptor(self) -> PropertyDescriptor:
364373
"""Create boolean setting descriptor."""
365374
return PropertyDescriptor(
366-
id=self.name,
375+
id=self.unique_identifier,
367376
name=self.description,
368377
status_attribute=self.normalized_name,
369378
type=self.format,
370379
extras=self.extras,
371380
access=self._miot_access_list_to_access(self.access),
372381
)
373382

383+
@property
384+
def unique_identifier(self) -> str:
385+
"""Return unique identifier."""
386+
return f"{self.normalized_name}_{self.siid}_{self.piid}"
387+
374388
class Config:
375389
extra = "forbid"
376390

@@ -381,6 +395,11 @@ class MiotEvent(MiotBaseModel):
381395
eiid: int = Field(alias="iid")
382396
arguments: Any
383397

398+
@property
399+
def unique_identifier(self) -> str:
400+
"""Return unique identifier."""
401+
return f"{self.normalized_name}_{self.siid}_{self.eiid}"
402+
384403
class Config:
385404
extra = "forbid"
386405

miio/tests/test_miot_models.py

+16
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
URN,
2222
MiotAccess,
2323
MiotAction,
24+
MiotBaseModel,
2425
MiotEnumValue,
2526
MiotEvent,
2627
MiotFormat,
@@ -349,3 +350,18 @@ def test_get_descriptor_enum_property(read_only, expected):
349350
def test_property_pretty_value():
350351
"""Test the pretty value conversions."""
351352
raise NotImplementedError()
353+
354+
355+
@pytest.mark.parametrize(
356+
("collection", "id_var"),
357+
[("actions", "aiid"), ("properties", "piid"), ("events", "eiid")],
358+
)
359+
def test_unique_identifier(collection, id_var):
360+
"""Test unique identifier for properties, actions, and events."""
361+
serv = MiotService.parse_raw(DUMMY_SERVICE)
362+
elem: MiotBaseModel = getattr(serv, collection)
363+
first = elem[0]
364+
assert (
365+
first.unique_identifier
366+
== f"{first.normalized_name}_{serv.siid}_{getattr(first, id_var)}"
367+
)

0 commit comments

Comments
 (0)