Issue #27: the flex-zone/cooler-drawer select vanished after a device stopped including supportedOptions on an update for /mode/vs/0. ObserveManager.apply() handed reps straight to StateCache.apply_rep, which fully replaces the cached rep -- so a partial update (missing a field the select's exists_fn/options_field gate on) silently erased data a fuller update had previously supplied. apply() now merges incoming reps onto whatever's already cached instead. Also give ice-maker entities (and any future pattern-cap instance) a device-given display name instead of the href-derived "Icemaker One"/"Icemaker Two": Capability.name_field lets a pattern capability read and normalize an instance name (e.g. iceMaker.name's "CUBED_ICE") for use as the entity name prefix, independent of the stable key/unique_id.
27 lines
1.3 KiB
Python
27 lines
1.3 KiB
Python
"""A Capability binds one OCF resource href 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:
|
|
href: Optional[str] = None
|
|
entities: tuple[SamsungEntityDescription, ...] = ()
|
|
poll_tier: str = 'cold' # 'hot' | 'warm' | 'cold'
|
|
rt_filter: Optional[str] = None # bind only if rt_filter in rep.get('rt', ())
|
|
href_prefix: Optional[str] = None # pattern caps only: bind only if href starts with this
|
|
strip_prefix_in_key: bool = False # strip href_prefix segs before building key_override
|
|
# Rep field holding this instance's device-given name (e.g. an ice
|
|
# maker's "CUBED_ICE"/"ICE_BITES"), normalized and used as the display
|
|
# name prefix in place of the href-derived instance label. Does not
|
|
# affect key_override/unique_id -- only what's shown in the UI.
|
|
name_field: Optional[str] = None
|
|
match_fn: Optional[Callable[[dict, dict], bool]] = None # match_fn(rep, resources) -> bool
|
|
# Rare optional hook — only operational-state-style resources use this.
|
|
on_observation: Optional[Callable[[dict, dict], None]] = None
|
|
project: Optional[Callable[[dict, dict], dict]] = None
|