1786267721
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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(())
|
||||
|
||||
@@ -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) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 { }
|
||||
|
||||
Reference in New Issue
Block a user