"""控制面板:主动性调节 + 场景免打扰""" 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 = {} # {"topic": "block"/"allow"} self._dnd_schedule: list = [] # [(day_of_week, start_h, end_h)] 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: """根据温度计值计算决策阈值""" # 0°C → 阈值 0.95(极难触发) # 50°C → 阈值 0.75 # 100°C → 阈值 0.5(容易触发) 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