1786267721

This commit is contained in:
2026-08-09 11:28:41 +02:00
parent 81f46f6f54
commit 0c1acdd822
4 changed files with 75 additions and 3 deletions

View File

@@ -83,6 +83,8 @@ impl From<&HassEntity> for DateTimeData {
impl From<&HassEntity> for ThermostatData {
fn from(value: &HassEntity) -> Self {
let id = value.entity_id.to_shared_string();
let available = value.available();
let current = value
@@ -95,13 +97,15 @@ impl From<&HassEntity> for ThermostatData {
.attributes
.get("temperature")
.and_then(|x| x.as_f64())
.unwrap_or_default();
.unwrap_or_default() as f32;
let (target, remainder) = split_number(temperature, 1);
Self {
id,
available,
current,
temperature,
name: value.friendly_name().to_shared_string(),
state: value.state.to_uppercase().to_shared_string(),
unit: "°C".into(),
@@ -272,10 +276,10 @@ pub fn pretty_label(value: &str) -> String {
.join(" ")
}
fn split_number(x: f64, decimals: u32) -> (i32, i32) {
fn split_number(x: f32, decimals: u32) -> (i32, i32) {
let factor = 10_i32.pow(decimals);
let main = x.trunc() as i32;
let remainder = ((x.fract() * factor as f64).round()) as i32;
let remainder = ((x.fract() * factor as f32).round()) as i32;
(main, remainder)
}

View File

@@ -92,6 +92,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
app.on_toggle_light({
let state = state.clone();
let c2s_tx = c2s_tx.clone();
move |entity_id| {
let id = entity_id.to_string();
@@ -116,6 +117,51 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
}
});
app.on_set_temperature({
let c2s_tx = c2s_tx.clone();
move |entity_id, value| {
let payload = Some(json!({
"entity_id": entity_id.to_string(),
"temperature": value
}));
c2s_tx
.send(C2sMessage::CallService(
"climate".into(),
"set_temperature".into(),
payload.clone(),
))
.ok();
}
});
app.on_toggle_thermostat({
let state = state.clone();
let c2s_tx = c2s_tx.clone();
move |entity_id| {
let id = entity_id.to_string();
let payload = Some(json!({
"entity_id": id
}));
if let Some(entity) = state.get(&id) {
let action = if entity.state == "heat" {
"turn_off"
} else {
"turn_on"
};
c2s_tx
.send(C2sMessage::CallService(
"climate".into(),
action.into(),
payload.clone(),
))
.ok();
}
}
});
app.run()?;
Ok(())

View File

@@ -5,6 +5,7 @@ import {
ElevatedButton,
SegmentedButton,
MaterialPalette,
FilledButton,
} from "material/material.slint";
import { Icons } from "material/ui/icons/icons.slint";
export struct WeatherData {
@@ -29,8 +30,10 @@ export struct WeatherData {
}
export struct ThermostatData {
id: string,
name: string,
current: float,
temperature: float,
unit: string,
target: int,
remainder: int,
@@ -45,6 +48,9 @@ export component Climate inherits Rectangle {
property <int> icon-index: weather.icon-index == 1 && is-night ? 2 : weather.icon-index;
callback set_temperature(string, float);
callback toggle_thermostat(string);
property <[image]> icons: [
@image-url("icons/sun.svg"),
@image-url("icons/cloud-sun.svg"),
@@ -96,6 +102,7 @@ export component Climate inherits Rectangle {
ElevatedButton {
icon: Icons.remove;
clicked => { root.set_temperature(thermostat.id, thermostat.temperature - 0.5) }
}
Rectangle {
@@ -149,6 +156,17 @@ export component Climate inherits Rectangle {
ElevatedButton {
icon: Icons.add;
clicked => { root.set_temperature(thermostat.id, thermostat.temperature + 0.5) }
}
if thermostat.state == "OFF": ElevatedButton {
icon: Icons.mode_heat_off;
clicked => { root.toggle_thermostat(thermostat.id) }
}
if thermostat.state == "HEAT": FilledButton {
icon: Icons.mode_heat;
clicked => { root.toggle_thermostat(thermostat.id) }
}
}

View File

@@ -127,6 +127,8 @@ export component AppWindow inherits Window {
in property <[ThermostatData]> thermostats;
in property <WeatherData> weather;
in property <bool> is-night;
callback set_temperature(string, float);
callback toggle_thermostat(string);
in property <[ThermometerData]> thermometers;
@@ -170,6 +172,8 @@ export component AppWindow inherits Window {
thermostats: thermostats;
is-night: is-night;
weather: weather;
set_temperature(entity_id, value) => { root.set_temperature(entity_id, value); }
toggle_thermostat(entity_id) => { toggle_thermostat(entity_id) }
}
if tab-bar.current-index == 1: Calendar { }
if tab-bar.current-index == 2: Energy { }