Source code for aioafero.v1.models.features

"""Feature Schemas used by various Afero resources."""

from dataclasses import dataclass, field
from enum import Enum

from aioafero.util import percentage_to_ordered_list_item


[docs] @dataclass class ColorModeFeature: """Represent the current mode (ie white, color) Feature object.""" mode: str @property def api_value(self): """Value to send to Afero API.""" return self.mode
[docs] @dataclass class ColorFeature: """Represent `RGB` Feature object.""" red: int green: int blue: int @property def api_value(self): """Value to send to Afero API.""" return { "value": { "color-rgb": { "r": self.red, "g": self.green, "b": self.blue, } } }
[docs] @dataclass class ColorTemperatureFeature: """Represent Current temperature Feature.""" temperature: int supported: list[int] prefix: str | None = None @property def api_value(self): """Value to send to Afero API.""" return f"{self.temperature}{self.prefix}"
[docs] class CurrentPositionEnum(Enum): """Enum with available current position modes.""" LOCKED = "locked" LOCKING = "locking" UNKNOWN = "unknown" UNLOCKED = "unlocked" UNLOCKING = "unlocking" @classmethod def _missing_(cls, value): return cls.UNKNOWN
[docs] @dataclass class CurrentPositionFeature: """Represents the current position of the lock.""" position: CurrentPositionEnum @property def api_value(self): """Value to send to Afero API.""" return self.position.value
[docs] @dataclass class CurrentTemperatureFeature: """Represents the current temperature.""" temperature: float function_class: str function_instance: str | None @property def api_value(self): """Value to send to Afero API.""" return { "functionClass": self.function_class, "functionInstance": self.function_instance, "value": round(self.temperature, 1), }
[docs] @dataclass class DimmingFeature: """Represent Current temperature Feature.""" brightness: int supported: list[int] func_instance: str | None = field(default=None) @property def api_value(self): """Value to send to Afero API.""" return self.brightness
[docs] @dataclass class DirectionFeature: """Represent Current Fan direction Feature.""" forward: bool @property def api_value(self): """Value to send to Afero API.""" return "forward" if self.forward else "reverse"
[docs] @dataclass class EffectFeature: """Represent the current effect.""" effect: str effects: dict[str, set[str]] @property def api_value(self): """States to send to Afero API.""" states = [] seq_key = None for effect_group, effects in self.effects.items(): if self.effect not in effects: continue seq_key = effect_group break if seq_key is None: return [] preset_val = self.effect if self.effect in self.effects["preset"] else seq_key states.append( { "functionClass": "color-sequence", "functionInstance": "preset", "value": preset_val, } ) if seq_key != "preset": states.append( { "functionClass": "color-sequence", "functionInstance": seq_key, "value": self.effect, } ) return states
[docs] def is_preset(self, effect): """Determine if the current state is a preset effect.""" try: return effect in self.effects["preset"] except KeyError: return False
[docs] @dataclass class HVACModeFeature: """Represent HVAC Mode Feature.""" mode: str | None previous_mode: str | None supported_modes: set[str] modes: set[str] @property def api_value(self): """Value to send to Afero API.""" return self.mode
[docs] @dataclass class ModeFeature: """Represent Current Fan mode Feature.""" mode: str | None modes: set[str] @property def api_value(self): """Value to send to Afero API.""" return self.mode
[docs] @dataclass class NumbersFeature: """Represents a numeric value.""" value: float min: float max: float step: float name: str | None unit: str | None @property def api_value(self): """Value to send to Afero API.""" return self.value
[docs] @dataclass class OnFeature: """Represent `On` Feature object as used by various Afero resources.""" on: bool func_class: str | None = field(default="power") func_instance: str | None = field(default=None) @property def api_value(self): """Value to send to Afero API.""" state = { "value": "on" if self.on else "off", "functionClass": self.func_class, } if self.func_instance: state["functionInstance"] = self.func_instance return state
[docs] @dataclass class OpenFeature: """Represent `Open` Feature object.""" open: bool func_class: str | None = field(default="toggle") func_instance: str | None = field(default=None) @property def api_value(self): """Value to send to Afero API.""" state = { "value": "on" if self.open else "off", "functionClass": self.func_class, } if self.func_instance: state["functionInstance"] = self.func_instance return state
[docs] @dataclass class PresetFeature: """Represent the current preset.""" enabled: bool func_instance: str func_class: str @property def api_value(self): """Value to send to Afero API.""" return { "functionClass": self.func_class, "functionInstance": self.func_instance, "value": "enabled" if self.enabled else "disabled", }
[docs] @dataclass class SecuritySensorConfigFeature: """Represent the current security sensor configuration.""" sensor_id: int chirpMode: int # noqa: N815 triggerType: int # noqa: N815 bypassType: int # noqa: N815 key_name: str @property def api_value(self): """Value to send to Afero API.""" return { "functionClass": "sensor-config", "value": { self.key_name: { "chirpMode": self.chirpMode, "triggerType": self.triggerType, "bypassType": self.bypassType, } }, "functionInstance": f"sensor-{self.sensor_id}", }
[docs] @dataclass class SelectFeature: """Represent available options and currently selected.""" selected: str selects: set[str] name: str @property def api_value(self): """Value to send to Afero API.""" return self.selected
[docs] @dataclass class SecuritySystemDisarmPin: """Represent the disarm pin feature.""" pin: int @property def api_value(self): """Value to send to Afero API.""" return { "functionClass": "disarm", "functionInstance": None, "value": str(self.pin), }
[docs] @dataclass class SecuritySensorSirenFeature: """Represent the current state of the siren.""" result_code: int | None command: int | None @property def api_value(self): """Value to send to Afero API.""" if self.result_code is None and self.command is None: return { "functionClass": "siren-action", "value": None, "functionInstance": None, } return { "functionClass": "siren-action", "value": { "security-siren-action": { "resultCode": self.result_code, "command": self.command, } }, "functionInstance": None, }
[docs] @dataclass class SpeedFeature: """Represent Current Fan speed Feature.""" speed: int speeds: list[str] @property def api_value(self): """Value to send to Afero API.""" return percentage_to_ordered_list_item(self.speeds, self.speed)
[docs] @dataclass class TargetTemperatureFeature: """Represents the target temperature for auto.""" value: float min: float max: float step: float instance: str @property def api_value(self): """Value to send to Afero API.""" return { "functionClass": "temperature", "functionInstance": self.instance, "value": self.value, }
AferoFeatures: list = [ ColorModeFeature, ColorFeature, ColorTemperatureFeature, CurrentPositionEnum, CurrentPositionFeature, DimmingFeature, DirectionFeature, EffectFeature, HVACModeFeature, ModeFeature, NumbersFeature, OnFeature, OpenFeature, PresetFeature, SelectFeature, SpeedFeature, TargetTemperatureFeature, ]