"""Models for LaMetric.""" from __future__ import annotations from dataclasses import dataclass, field from datetime import datetime from ipaddress import IPv4Address from awesomeversion import AwesomeVersion from mashumaro import field_options from mashumaro.config import BaseConfig from mashumaro.mixins.orjson import DataClassORJSONMixin from .const import ( AlarmSound, BrightnessMode, DeviceMode, DeviceState, DisplayType, NotificationIconType, NotificationPriority, NotificationSound, NotificationSoundCategory, NotificationType, WifiMode, ) @dataclass(kw_only=True) class Range(DataClassORJSONMixin): """Object holding an integer range.""" range_max: int = field(metadata=field_options(alias="max")) range_min: int = field(metadata=field_options(alias="min")) @dataclass(kw_only=True) class Audio(DataClassORJSONMixin): """Object holding the audio state of an LaMetric device.""" available: bool = True volume: int | None volume_limit: Range | None volume_range: Range | None @dataclass(kw_only=True) class Bluetooth(DataClassORJSONMixin): """Object holding the Bluetooth state of an LaMetric device.""" active: bool address: str available: bool discoverable: bool name: str pairable: bool @dataclass(kw_only=True) class DisplayScreensaver(DataClassORJSONMixin): """Object holding the screensaver data of an LaMetric device.""" enabled: bool @dataclass(kw_only=True) class Display(DataClassORJSONMixin): """Object holding the display state of an LaMetric device.""" brightness: int brightness_mode: BrightnessMode brightness_range: Range | None = None brightness_limit: Range | None = None display_type: DisplayType | None = field( default=None, metadata=field_options(alias="type") ) height: int on: bool | None = None screensaver: DisplayScreensaver | None = None width: int @dataclass(kw_only=True) class Wifi(DataClassORJSONMixin): """Object holding the Wi-Fi state of an LaMetric device.""" active: bool available: bool encryption: str | None = None ip: IPv4Address mac: str mode: WifiMode netmask: str rssi: int | None = None ssid: str @dataclass(kw_only=True) class Device(DataClassORJSONMixin): """Object holding the state of an LaMetric device.""" audio: Audio | None = None bluetooth: Bluetooth | None = None device_id: str = field(metadata=field_options(alias="id")) display: Display mode: DeviceMode model: str name: str os_version: AwesomeVersion serial_number: str update: Update | None = field( metadata=field_options(alias="update_available"), default=None ) wifi: Wifi @dataclass(kw_only=True) class Update(DataClassORJSONMixin): """Object holding the update state of an LaMetric device.""" version: AwesomeVersion @dataclass(kw_only=True) class Chart(DataClassORJSONMixin): """Object holding the chart frame of an LaMetric notification.""" data: list[int] = field(metadata=field_options(alias="chartData")) class Config(BaseConfig): """Chart model configuration.""" serialize_by_alias = True allow_deserialization_not_by_alias = True @dataclass(kw_only=True) class Simple(DataClassORJSONMixin): """Object holding the simple frame of an LaMetric notification.""" icon: int | str | None = None text: str @dataclass(kw_only=True) class GoalData(DataClassORJSONMixin): """Object holding the goal data of an LaMetric notification.""" current: int end: int start: int unit: str | None = None @dataclass(kw_only=True) class Goal(DataClassORJSONMixin): """Object holding the goal frame of an LaMetric notification.""" data: GoalData = field(metadata=field_options(alias="goalData")) icon: int | str | None = None class Config(BaseConfig): """Goal model configuration.""" serialize_by_alias = True allow_deserialization_not_by_alias = True @dataclass(kw_only=True) class Sound(DataClassORJSONMixin): """Object holding the notification sound state of an LaMetric device.""" category: NotificationSoundCategory | None = None repeat: int = 1 sound: AlarmSound | NotificationSound = field(metadata=field_options(alias="id")) def __post_init__(self) -> None: """Infer the category of the sound.""" if self.category is not None: return if self.sound in AlarmSound: self.category = NotificationSoundCategory.ALARMS if self.sound in NotificationSound: self.category = NotificationSoundCategory.NOTIFICATIONS class Config(BaseConfig): """Sound model configuration.""" serialize_by_alias = True allow_deserialization_not_by_alias = True @dataclass(kw_only=True) class SoundURL(DataClassORJSONMixin): """Sound URL model configuration.""" url: str type: str = "mp3" fallback: Sound | None = None @dataclass(kw_only=True) class Model(DataClassORJSONMixin): """Object holding the notification model of an LaMetric device.""" cycles: int = 1 frames: list[Chart | Goal | Simple] sound: SoundURL | Sound | None = None class Config(BaseConfig): """Model configuration.""" omit_none = True @dataclass(kw_only=True) class Notification(DataClassORJSONMixin): """Object holding a LaMetric notification.""" created: datetime | None = None expiration_date: datetime | None = None icon_type: NotificationIconType | None = None life_time: float | None = None model: Model notification_id: int | None = field( default=None, metadata=field_options(alias="id"), ) notification_type: NotificationType | None = field( default=None, metadata=field_options(alias="type"), ) priority: NotificationPriority | None = None class Config(BaseConfig): """Notification model configuration.""" serialize_by_alias = True omit_none = True @dataclass(kw_only=True) class User(DataClassORJSONMixin): """Object holding LaMetric User information.""" apps_count: int email: str name: str private_apps_count: int private_device_count: int user_id: int = field(metadata=field_options(alias="id")) @dataclass(kw_only=True) class CloudDevice(DataClassORJSONMixin): """Object holding the state of an LaMetric device from the Cloud.""" api_key: str created_at: datetime device_id: int = field(metadata=field_options(alias="id")) ip: IPv4Address = field(metadata=field_options(alias="ipv4_internal")) mac: str name: str serial_number: str ssid: str = field(metadata=field_options(alias="wifi_ssid")) state: DeviceState updated_at: datetime