v0.12.0
This commit is contained in:
+53
-18
@@ -61,50 +61,85 @@ fn shared_input_comparison_kind(kind: &str) -> bool {
|
||||
)
|
||||
}
|
||||
|
||||
fn validate_shared_input_source(kind: &str, config: &Value, state: &AppState) -> Result<(), AppError> {
|
||||
match kind {
|
||||
"outdoor_temperature" | "house_mode" | "night_mode" => {}
|
||||
enum SharedInputResourceReference {
|
||||
Device(String),
|
||||
Zone(String),
|
||||
Group(String),
|
||||
}
|
||||
|
||||
fn shared_input_resource_reference(kind: &str, config: &Value) -> Result<Option<SharedInputResourceReference>, AppError> {
|
||||
let reference = match kind {
|
||||
"outdoor_temperature" | "house_mode" | "night_mode" => None,
|
||||
"device_temperature" => {
|
||||
let id = flow_string(config, "device_id").ok_or_else(|| AppError::BadRequest("shared device temperature input needs device".into()))?;
|
||||
if state.db.get_device(&id)?.is_none() { return Err(AppError::BadRequest("shared Flow input references a missing device".into())); }
|
||||
let id = flow_string(config, "device_id")
|
||||
.ok_or_else(|| AppError::BadRequest("shared device temperature input needs device".into()))?;
|
||||
Some(SharedInputResourceReference::Device(id))
|
||||
}
|
||||
"zone_temperature" => {
|
||||
let id = flow_string(config, "zone_id").ok_or_else(|| AppError::BadRequest("shared zone temperature input needs zone".into()))?;
|
||||
if state.db.get_zone(&id)?.is_none() { return Err(AppError::BadRequest("shared Flow input references a missing zone".into())); }
|
||||
let id = flow_string(config, "zone_id")
|
||||
.ok_or_else(|| AppError::BadRequest("shared zone temperature input needs zone".into()))?;
|
||||
Some(SharedInputResourceReference::Zone(id))
|
||||
}
|
||||
"ha_state" | "ha_numeric" | "ha_available" => {
|
||||
if flow_string(config, "entity_id").is_none() { return Err(AppError::BadRequest("shared Home Assistant input needs entity_id".into())); }
|
||||
if flow_string(config, "entity_id").is_none() {
|
||||
return Err(AppError::BadRequest("shared Home Assistant input needs entity_id".into()));
|
||||
}
|
||||
None
|
||||
}
|
||||
"ha_attribute" => {
|
||||
if flow_string(config, "entity_id").is_none() || flow_string(config, "attribute").is_none() {
|
||||
return Err(AppError::BadRequest("shared Home Assistant attribute input needs entity_id and attribute".into()));
|
||||
}
|
||||
None
|
||||
}
|
||||
"device_state" => {
|
||||
let id = flow_string(config, "device_id").ok_or_else(|| AppError::BadRequest("shared device state input needs device".into()))?;
|
||||
if state.db.get_device(&id)?.is_none() { return Err(AppError::BadRequest("shared Flow input references a missing device".into())); }
|
||||
let field = flow_string(config, "field").ok_or_else(|| AppError::BadRequest("shared device state input needs a field".into()))?;
|
||||
let id = flow_string(config, "device_id")
|
||||
.ok_or_else(|| AppError::BadRequest("shared device state input needs device".into()))?;
|
||||
let field = flow_string(config, "field")
|
||||
.ok_or_else(|| AppError::BadRequest("shared device state input needs a field".into()))?;
|
||||
if !matches!(field.as_str(), "enabled" | "online" | "power" | "mode" | "fan_speed" | "swing_vertical" | "swing_horizontal" | "quiet" | "turbo" | "light" | "air" | "xfan" | "health" | "sleep") {
|
||||
return Err(AppError::BadRequest("unsupported shared device state field".into()));
|
||||
}
|
||||
Some(SharedInputResourceReference::Device(id))
|
||||
}
|
||||
"zone_state" => {
|
||||
let id = flow_string(config, "zone_id").ok_or_else(|| AppError::BadRequest("shared zone state input needs zone".into()))?;
|
||||
if state.db.get_zone(&id)?.is_none() { return Err(AppError::BadRequest("shared Flow input references a missing zone".into())); }
|
||||
let field = flow_string(config, "field").ok_or_else(|| AppError::BadRequest("shared zone state input needs a field".into()))?;
|
||||
let id = flow_string(config, "zone_id")
|
||||
.ok_or_else(|| AppError::BadRequest("shared zone state input needs zone".into()))?;
|
||||
let field = flow_string(config, "field")
|
||||
.ok_or_else(|| AppError::BadRequest("shared zone state input needs a field".into()))?;
|
||||
if !matches!(field.as_str(), "enabled" | "mode" | "active_preset" | "demand" | "control_owner" | "device_manual_override" | "local_thermostat_power") {
|
||||
return Err(AppError::BadRequest("unsupported shared zone state field".into()));
|
||||
}
|
||||
Some(SharedInputResourceReference::Zone(id))
|
||||
}
|
||||
"group_state" => {
|
||||
let id = flow_string(config, "group_id").ok_or_else(|| AppError::BadRequest("shared group state input needs group".into()))?;
|
||||
if state.db.get_group(&id)?.is_none() { return Err(AppError::BadRequest("shared Flow input references a missing group".into())); }
|
||||
if flow_string(config, "field").as_deref() != Some("power_enabled") { return Err(AppError::BadRequest("unsupported shared group state field".into())); }
|
||||
let id = flow_string(config, "group_id")
|
||||
.ok_or_else(|| AppError::BadRequest("shared group state input needs group".into()))?;
|
||||
if flow_string(config, "field").as_deref() != Some("power_enabled") {
|
||||
return Err(AppError::BadRequest("unsupported shared group state field".into()));
|
||||
}
|
||||
Some(SharedInputResourceReference::Group(id))
|
||||
}
|
||||
"constant" => {
|
||||
if config.get("value").and_then(Value::as_bool).is_none() { return Err(AppError::BadRequest("shared constant input needs a boolean value".into())); }
|
||||
if config.get("value").and_then(Value::as_bool).is_none() {
|
||||
return Err(AppError::BadRequest("shared constant input needs a boolean value".into()));
|
||||
}
|
||||
None
|
||||
}
|
||||
_ => return Err(AppError::BadRequest(format!("unsupported shared Flow input kind: {kind}"))),
|
||||
};
|
||||
Ok(reference)
|
||||
}
|
||||
|
||||
fn validate_shared_input_source(kind: &str, config: &Value, state: &AppState) -> Result<(), AppError> {
|
||||
let Some(reference) = shared_input_resource_reference(kind, config)? else { return Ok(()); };
|
||||
let exists = match reference {
|
||||
SharedInputResourceReference::Device(id) => state.db.get_device(&id)?.is_some(),
|
||||
SharedInputResourceReference::Zone(id) => state.db.get_zone(&id)?.is_some(),
|
||||
SharedInputResourceReference::Group(id) => state.db.get_group(&id)?.is_some(),
|
||||
};
|
||||
if !exists {
|
||||
return Err(AppError::BadRequest("shared Flow input references a missing resource".into()));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user