diff --git a/samsung_appliance/registry/capability.py b/samsung_appliance/registry/capability.py new file mode 100644 index 0000000..87c941e --- /dev/null +++ b/samsung_appliance/registry/capability.py @@ -0,0 +1,19 @@ +"""A Capability binds one OCF resource type (rt) to the entities it produces.""" +from __future__ import annotations + +from dataclasses import dataclass +from typing import Callable, Optional + +from .entities import SamsungEntityDescription + + +@dataclass(frozen=True, kw_only=True) +class Capability: + rt: str + entities: tuple[SamsungEntityDescription, ...] + poll_tier: str = 'warm' # 'hot' | 'warm' | 'cold' + observe: bool = True + # Rare optional hooks — only operational-state-style resources use these. + active_when: Optional[Callable[[dict], bool]] = None + on_observation: Optional[Callable[[dict, dict], None]] = None + project: Optional[Callable[[dict, dict], dict]] = None diff --git a/tests/test_capability.py b/tests/test_capability.py new file mode 100644 index 0000000..9cc5b3c --- /dev/null +++ b/tests/test_capability.py @@ -0,0 +1,20 @@ +from samsung_appliance.registry.capability import Capability +from samsung_appliance.registry.entities import BinarySensorDesc + + +def test_capability_defaults(): + c = Capability(rt='x.com.samsung.da.kidsLock', + entities=(BinarySensorDesc(key='child_lock', field='x.com.samsung.da.kidsLock'),)) + assert c.poll_tier == 'warm' + assert c.observe is True + assert c.active_when is None + assert len(c.entities) == 1 + + +def test_capability_is_frozen(): + c = Capability(rt='x', entities=()) + try: + c.rt = 'y' + except Exception: + return + raise AssertionError("expected frozen dataclass")