This commit is contained in:
Mateusz Gruszczyński
2026-09-01 22:20:10 +02:00
parent 1cb62c8d0b
commit 16e0d94564
47 changed files with 2565 additions and 117 deletions
+37
View File
@@ -107,3 +107,40 @@ mod tests {
assert_eq!(resolve_entity_id(&settings, None).as_deref(), Some("sensor.salon_temperature"));
}
}
/// Read a complete Home Assistant entity document for Flow conditions. Keeping this helper
/// centralized means state and attribute blocks share the same URL validation, TLS and auth path.
pub async fn read_entity(
default_client: &reqwest::Client,
settings: &HomeAssistantSettings,
entity_override: Option<&str>,
) -> Result<Value> {
if settings.url.trim().is_empty() { bail!("Home Assistant URL is not configured") }
if settings.token.trim().is_empty() { bail!("Home Assistant token is not configured") }
let entity = resolve_entity_id(settings, entity_override)
.ok_or_else(|| anyhow!("Home Assistant entity_id is not configured"))?;
let mut base = Url::parse(settings.url.trim()).context("invalid Home Assistant URL")?;
if !matches!(base.scheme(), "http" | "https") { bail!("Home Assistant URL must use http or https") }
base = base.join(&format!("api/states/{}", entity.trim_start_matches('/'))).context("cannot build Home Assistant API URL")?;
let client = request_client(default_client, settings)?;
let response = client.get(base).bearer_auth(settings.token.trim()).header("Accept", "application/json")
.send().await.context("Home Assistant request failed")?;
if !response.status().is_success() {
let status = response.status();
let body = response.text().await.unwrap_or_default();
bail!("Home Assistant returned {status}: {}", body.chars().take(200).collect::<String>())
}
response.json().await.context("invalid Home Assistant JSON")
}
/// Read the raw Home Assistant state for Flow conditions. Unlike `read_temperature`, this
/// intentionally keeps the state as text so binary_sensor, switch, input_boolean and custom
/// entities can participate in visual automations.
pub async fn read_state(
default_client: &reqwest::Client,
settings: &HomeAssistantSettings,
entity_override: Option<&str>,
) -> Result<String> {
let payload = read_entity(default_client, settings, entity_override).await?;
payload.get("state").and_then(Value::as_str).map(str::to_string).ok_or_else(|| anyhow!("Home Assistant state is missing"))
}