Files
ClimatController/schedule/models.py
T

119 lines
2.5 KiB
Python

from dataclasses import dataclass, field, fields
from datetime import datetime, time
from enum import StrEnum
from typing import Any
class ScheduleActionType(StrEnum):
SET = "set"
AUTO = "auto"
@dataclass(frozen=True, slots=True)
class ScheduledSettings:
power: bool | None = None
speed: int | None = None
heater: bool | None = None
target_temp: int | None = None
mode: str | None = None
sound: bool | None = None
light: bool | None = None
def merged(self, newer: "ScheduledSettings") -> "ScheduledSettings":
"""
Наложить более новые настройки поверх старых.
None означает:
параметр в данной точке расписания не менялся.
"""
values: dict[str, Any] = {}
for item in fields(self):
old_value = getattr(self, item.name)
new_value = getattr(newer, item.name)
values[item.name] = (
old_value
if new_value is None
else new_value
)
return ScheduledSettings(**values)
@property
def empty(self) -> bool:
return all(
getattr(self, item.name) is None
for item in fields(self)
)
def to_dict(
self,
*,
skip_none: bool = True,
) -> dict:
result = {}
for item in fields(self):
value = getattr(self, item.name)
if skip_none and value is None:
continue
result[item.name] = value
return result
@dataclass(frozen=True, slots=True)
class ScheduleAction:
type: ScheduleActionType
settings: ScheduledSettings = field(
default_factory=ScheduledSettings
)
@dataclass(frozen=True, slots=True)
class SchedulePoint:
at: time
action: ScheduleAction
@dataclass(frozen=True, slots=True)
class ScheduleConfig:
version: int
enabled: bool
timezone: str
templates: dict[
str,
tuple[SchedulePoint, ...]
]
days: dict[str, str]
@dataclass(frozen=True, slots=True)
class ScheduleOccurrence:
"""
Конкретная точка расписания уже с датой.
"""
when: datetime
weekday: str
template: str
point: SchedulePoint
@dataclass(frozen=True, slots=True)
class ScheduleResolution:
enabled: bool
current: ScheduleOccurrence | None
next: ScheduleOccurrence | None
scheduled_settings: ScheduledSettings
auto_active: bool