v0.5.0
This commit is contained in:
+159
@@ -26,6 +26,10 @@ fn default_cool_away() -> f64 { 27.0 }
|
||||
fn default_heat_comfort() -> f64 { 21.0 }
|
||||
fn default_heat_sleep() -> f64 { 19.0 }
|
||||
fn default_heat_away() -> f64 { 17.0 }
|
||||
fn default_history_retention_days() -> u32 { 30 }
|
||||
fn default_influx_version() -> String { "2".into() }
|
||||
fn default_influx_database() -> String { "gree_controller".into() }
|
||||
fn default_influx_threshold_days() -> u32 { 30 }
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Device {
|
||||
@@ -148,6 +152,27 @@ pub struct DeviceCommand {
|
||||
}
|
||||
|
||||
impl DeviceCommand {
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.power.is_none() && self.mode.is_none() && self.target_temperature.is_none()
|
||||
&& self.fan_speed.is_none() && self.swing_vertical.is_none() && self.swing_horizontal.is_none()
|
||||
&& self.quiet.is_none() && self.turbo.is_none() && self.light.is_none()
|
||||
}
|
||||
|
||||
/// Return only fields that differ from the last known device state.
|
||||
pub fn changed_from(&self, device: &Device) -> Self {
|
||||
Self {
|
||||
power: self.power.filter(|value| *value != device.power),
|
||||
mode: self.mode.as_ref().filter(|value| value.as_str() != device.mode.as_str()).cloned(),
|
||||
target_temperature: self.target_temperature.filter(|value| value.clamp(8.0, 30.0).round() != device.target_temperature.clamp(8.0, 30.0).round()),
|
||||
fan_speed: self.fan_speed.filter(|value| (*value).min(5) != device.fan_speed),
|
||||
swing_vertical: self.swing_vertical.filter(|value| *value != device.swing_vertical),
|
||||
swing_horizontal: self.swing_horizontal.filter(|value| *value != device.swing_horizontal),
|
||||
quiet: self.quiet.filter(|value| *value != device.quiet),
|
||||
turbo: self.turbo.filter(|value| *value != device.turbo),
|
||||
light: self.light.filter(|value| *value != device.light),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn apply(&self, device: &mut Device) {
|
||||
if let Some(v) = self.power { device.power = v; }
|
||||
if let Some(v) = &self.mode { device.mode = v.clone(); }
|
||||
@@ -386,6 +411,128 @@ pub struct HomeAssistantSettings {
|
||||
pub allow_invalid_tls: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct InfluxDbSettings {
|
||||
#[serde(default)]
|
||||
pub enabled: bool,
|
||||
/// InfluxDB API generation: `1` or `2`.
|
||||
#[serde(default = "default_influx_version")]
|
||||
pub version: String,
|
||||
#[serde(default)]
|
||||
pub url: String,
|
||||
/// InfluxDB 1.x database name.
|
||||
#[serde(default = "default_influx_database")]
|
||||
pub database: String,
|
||||
#[serde(default)]
|
||||
pub username: String,
|
||||
#[serde(default)]
|
||||
pub password: String,
|
||||
/// InfluxDB 2.x organization.
|
||||
#[serde(default)]
|
||||
pub org: String,
|
||||
/// InfluxDB 2.x bucket.
|
||||
#[serde(default = "default_influx_database")]
|
||||
pub bucket: String,
|
||||
#[serde(default)]
|
||||
pub token: String,
|
||||
/// Queries older than this age are read from InfluxDB when it is enabled.
|
||||
#[serde(default = "default_influx_threshold_days")]
|
||||
pub history_threshold_days: u32,
|
||||
}
|
||||
|
||||
impl Default for InfluxDbSettings {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
enabled: false,
|
||||
version: default_influx_version(),
|
||||
url: String::new(),
|
||||
database: default_influx_database(),
|
||||
username: String::new(),
|
||||
password: String::new(),
|
||||
org: String::new(),
|
||||
bucket: default_influx_database(),
|
||||
token: String::new(),
|
||||
history_threshold_days: default_influx_threshold_days(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
pub struct DebugSettings {
|
||||
#[serde(default)]
|
||||
pub overlay_enabled: bool,
|
||||
#[serde(default)]
|
||||
pub gree_frames: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ConfigurationExport {
|
||||
pub format_version: u32,
|
||||
pub exported_at: DateTime<Utc>,
|
||||
pub settings: RuntimeSettings,
|
||||
pub devices: Vec<Device>,
|
||||
pub zones: Vec<Zone>,
|
||||
pub schedules: Vec<Schedule>,
|
||||
pub automations: Vec<Automation>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ControlPlanEvent {
|
||||
pub at: DateTime<Utc>,
|
||||
pub kind: String,
|
||||
pub label: String,
|
||||
pub preset: Option<String>,
|
||||
pub target_temperature: Option<f64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ZoneControlPlan {
|
||||
pub zone_id: String,
|
||||
pub zone_name: String,
|
||||
pub device_id: String,
|
||||
pub device_name: String,
|
||||
pub enabled: bool,
|
||||
pub mode: String,
|
||||
pub preset: String,
|
||||
pub current_temperature: Option<f64>,
|
||||
pub target_temperature: Option<f64>,
|
||||
pub device_setpoint: Option<f64>,
|
||||
pub demand: bool,
|
||||
pub control_source: String,
|
||||
pub manual_override_until: Option<DateTime<Utc>>,
|
||||
pub current_schedule_id: Option<String>,
|
||||
pub current_schedule_name: Option<String>,
|
||||
pub next_events: Vec<ControlPlanEvent>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct AutomationPlanRule {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub enabled: bool,
|
||||
pub trigger_kind: String,
|
||||
pub trigger_device_id: Option<String>,
|
||||
pub trigger_device_name: Option<String>,
|
||||
pub threshold: Option<f64>,
|
||||
pub at_time: Option<String>,
|
||||
pub action_device_id: String,
|
||||
pub action_device_name: String,
|
||||
pub action: DeviceCommand,
|
||||
pub last_fired_at: Option<DateTime<Utc>>,
|
||||
pub next_ready_at: Option<DateTime<Utc>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ControlPlan {
|
||||
pub generated_at: DateTime<Utc>,
|
||||
pub house_mode: String,
|
||||
pub outdoor_temperature: Option<f64>,
|
||||
pub control_strategy: String,
|
||||
pub next_events: Vec<ControlPlanEvent>,
|
||||
pub zones: Vec<ZoneControlPlan>,
|
||||
pub rules: Vec<AutomationPlanRule>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct RuntimeSettings {
|
||||
pub controller_id: String,
|
||||
@@ -402,6 +549,18 @@ pub struct RuntimeSettings {
|
||||
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,
|
||||
/// Add protocol-specific buzzer suppression fields to command frames.
|
||||
#[serde(default)]
|
||||
pub suppress_device_beep: bool,
|
||||
#[serde(default)]
|
||||
pub influxdb: InfluxDbSettings,
|
||||
#[serde(default)]
|
||||
pub debug: DebugSettings,
|
||||
pub home_assistant: HomeAssistantSettings,
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user