Skip to content

Commit

Permalink
Add unique_identifier property to miot properties, actions, and events (
Browse files Browse the repository at this point in the history
#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.
  • Loading branch information
rytilahti authored Nov 9, 2024
1 parent 62427d2 commit edb06c5
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 6 deletions.
31 changes: 25 additions & 6 deletions miio/miot_models.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
from abc import abstractmethod
from datetime import timedelta
from enum import Enum
from typing import Any, Optional
Expand Down Expand Up @@ -150,6 +151,11 @@ def normalized_name(self) -> str:
"""
return self.name.replace(":", "_").replace("-", "_")

@property
@abstractmethod
def unique_identifier(self) -> str:
"""Return unique identifier."""


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

def get_descriptor(self):
"""Create a descriptor based on the property information."""
id_ = self.name

extras = self.extras
extras["urn"] = self.urn
extras["siid"] = self.siid
Expand All @@ -190,12 +194,17 @@ def get_descriptor(self):
inputs = [prop.get_descriptor() for prop in self.inputs]

return ActionDescriptor(
id=id_,
id=self.unique_identifier,
name=self.description,
inputs=inputs,
extras=extras,
)

@property
def unique_identifier(self) -> str:
"""Return unique identifier."""
return f"{self.normalized_name}_{self.siid}_{self.aiid}"

class Config:
extra = "forbid"

Expand Down Expand Up @@ -327,7 +336,7 @@ def _create_enum_descriptor(self) -> EnumDescriptor:
raise

desc = EnumDescriptor(
id=self.name,
id=self.unique_identifier,
name=self.description,
status_attribute=self.normalized_name,
unit=self.unit,
Expand All @@ -346,7 +355,7 @@ def _create_range_descriptor(
if self.range is None:
raise ValueError("Range is None")
desc = RangeDescriptor(
id=self.name,
id=self.unique_identifier,
name=self.description,
status_attribute=self.normalized_name,
min_value=self.range[0],
Expand All @@ -363,14 +372,19 @@ def _create_range_descriptor(
def _create_regular_descriptor(self) -> PropertyDescriptor:
"""Create boolean setting descriptor."""
return PropertyDescriptor(
id=self.name,
id=self.unique_identifier,
name=self.description,
status_attribute=self.normalized_name,
type=self.format,
extras=self.extras,
access=self._miot_access_list_to_access(self.access),
)

@property
def unique_identifier(self) -> str:
"""Return unique identifier."""
return f"{self.normalized_name}_{self.siid}_{self.piid}"

class Config:
extra = "forbid"

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

@property
def unique_identifier(self) -> str:
"""Return unique identifier."""
return f"{self.normalized_name}_{self.siid}_{self.eiid}"

class Config:
extra = "forbid"

Expand Down
16 changes: 16 additions & 0 deletions miio/tests/test_miot_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
URN,
MiotAccess,
MiotAction,
MiotBaseModel,
MiotEnumValue,
MiotEvent,
MiotFormat,
Expand Down Expand Up @@ -349,3 +350,18 @@ def test_get_descriptor_enum_property(read_only, expected):
def test_property_pretty_value():
"""Test the pretty value conversions."""
raise NotImplementedError()


@pytest.mark.parametrize(
("collection", "id_var"),
[("actions", "aiid"), ("properties", "piid"), ("events", "eiid")],
)
def test_unique_identifier(collection, id_var):
"""Test unique identifier for properties, actions, and events."""
serv = MiotService.parse_raw(DUMMY_SERVICE)
elem: MiotBaseModel = getattr(serv, collection)
first = elem[0]
assert (
first.unique_identifier
== f"{first.normalized_name}_{serv.siid}_{getattr(first, id_var)}"
)

0 comments on commit edb06c5

Please # to comment.