| """控制面板:主动性调节 + 场景免打扰""" |
|
|
| from enum import Enum |
| from dataclasses import dataclass, field |
| from typing import List |
| import time |
|
|
|
|
| class ThermostatMode(Enum): |
| """主动性温度计""" |
| SILENT = 0 |
| MINIMAL = 25 |
| BALANCED = 50 |
| INSPIRING = 75 |
| FULL = 100 |
|
|
|
|
| class SceneMode(Enum): |
| """场景模式""" |
| NORMAL = "normal" |
| WORK = "work" |
| MEETING = "meeting" |
| SLEEP = "sleep" |
| DRIVING = "driving" |
| CUSTOM = "custom" |
|
|
|
|
| @dataclass |
| class SceneConfig: |
| """场景配置""" |
| thermostat: int = 50 |
| allowed_topics: List[str] = field(default_factory=list) |
| blocked_topics: List[str] = field(default_factory=list) |
| max_per_hour: int = 3 |
| quiet_hours_start: int = 23 |
| quiet_hours_end: int = 7 |
| geofence: List[str] = field(default_factory=list) |
|
|
|
|
| SCENE_PRESETS = { |
| SceneMode.NORMAL: SceneConfig(thermostat=50, max_per_hour=3), |
| SceneMode.WORK: SceneConfig(thermostat=25, max_per_hour=1, |
| allowed_topics=["work", "reminder"], |
| blocked_topics=["social", "entertainment"]), |
| SceneMode.MEETING: SceneConfig(thermostat=0, max_per_hour=0, |
| allowed_topics=["emergency"]), |
| SceneMode.SLEEP: SceneConfig(thermostat=5, max_per_hour=0, |
| allowed_topics=["emergency"], |
| quiet_hours_start=0, quiet_hours_end=24), |
| SceneMode.DRIVING: SceneConfig(thermostat=10, max_per_hour=0, |
| allowed_topics=["urgent_call"]), |
| } |
|
|
|
|
| class ControlPanel: |
| """ |
| 用户控制面板 |
| """ |
|
|
| def __init__(self): |
| self._current_mode: SceneMode = SceneMode.NORMAL |
| self._custom_config: SceneConfig = SceneConfig() |
| self._thermostat: int = 50 |
| self._manual_overrides: dict = {} |
| self._dnd_schedule: list = [] |
| self._device_geofence: str = "" |
|
|
| @property |
| def config(self) -> SceneConfig: |
| if self._current_mode == SceneMode.CUSTOM: |
| return self._custom_config |
| return SCENE_PRESETS.get(self._current_mode, SCENE_PRESETS[SceneMode.NORMAL]) |
|
|
| def set_scene(self, mode: SceneMode): |
| self._current_mode = mode |
| self._thermostat = self.config.thermostat |
|
|
| def set_thermostat(self, value: int): |
| self._thermostat = max(0, min(100, value)) |
|
|
| def get_decision_threshold(self) -> float: |
| """根据温度计值计算决策阈值""" |
| |
| |
| |
| return 0.95 - (self._thermostat / 100) * 0.45 |
|
|
| def can_act_on_topic(self, topic: str) -> bool: |
| """基于主题和场景判断是否允许""" |
| cfg = self.config |
| |
| if topic in self._manual_overrides: |
| return self._manual_overrides[topic] == "allow" |
| if topic in cfg.blocked_topics: |
| return False |
| if cfg.allowed_topics and topic not in cfg.allowed_topics: |
| return False |
| return True |
|
|