#[derive(Debug, Clone, Serialize, Deserialize)] pub struct RuntimeSettings { pub controller_id: String, pub simulator_enabled: bool, pub poll_interval_seconds: u64, pub zone_interval_seconds: u64, pub discovery_timeout_ms: u64, pub discovery_broadcast: String, /// Global seasonal mode. Zones follow this by default. Values: cool/heat/off; off pauses house-level thermostat control. #[serde(default = "default_house_mode")] pub house_mode: String, /// Whole-house master power. False is authoritative and suppresses zone/automation restarts. #[serde(default = "default_true")] pub house_power_enabled: bool, /// `setpoint` keeps units powered and modulates compressor demand by changing target temperature. #[serde(default = "default_control_strategy")] pub control_strategy: String, #[serde(default = "default_true")] pub outdoor_assist_enabled: bool, /// Keep recent metrics locally; older history may live in InfluxDB. #[serde(default = "default_history_retention_days")] pub history_retention_days: u32, #[serde(default = "default_true")] pub history_compaction_enabled: bool, /// Retention window for controller event/debug log rows. #[serde(default = "default_event_log_retention_days")] pub event_log_retention_days: u32, /// Add protocol-specific buzzer suppression fields to command frames. #[serde(default)] pub suppress_device_beep: bool, /// Global thermostat compressor protection. When enabled, automatic starts and /// Heat/Cool reversals are delayed instead of being sent during the protection window. #[serde(default = "default_true")] pub compressor_protection_enabled: bool, /// Global compressor protection window in seconds. The UI exposes this as minutes. #[serde(default = "default_compressor_protection_seconds")] pub compressor_protection_seconds: u64, #[serde(default)] pub influxdb: InfluxDbSettings, #[serde(default)] pub debug: DebugSettings, #[serde(default)] pub night_mode: NightModeSettings, #[serde(default)] pub notifications: NotificationSettings, pub home_assistant: HomeAssistantSettings, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct DiscoveryRequest { #[serde(default)] pub timeout_ms: Option, #[serde(default)] pub broadcast: Option, /// 0 = auto (accept both), 1 = AES-ECB only, 2 = AES-GCM only. #[serde(default)] pub protocol_version: Option, /// Number of scan broadcasts sent during one discovery operation. #[serde(default)] pub passes: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ManualDeviceRequest { pub name: String, pub mac: String, pub ip: String, #[serde(default = "default_port")] pub port: u16, #[serde(default = "default_protocol")] pub protocol_version: u8, #[serde(default)] pub key: Option, #[serde(default)] pub simulated: bool, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ApiTokenInfo { pub id: String, pub name: String, pub token_prefix: String, pub created_at: DateTime, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ApiEvent { pub event: String, pub timestamp: DateTime, pub data: Value, }