1786267721
This commit is contained in:
@@ -83,6 +83,8 @@ impl From<&HassEntity> for DateTimeData {
|
|||||||
|
|
||||||
impl From<&HassEntity> for ThermostatData {
|
impl From<&HassEntity> for ThermostatData {
|
||||||
fn from(value: &HassEntity) -> Self {
|
fn from(value: &HassEntity) -> Self {
|
||||||
|
let id = value.entity_id.to_shared_string();
|
||||||
|
|
||||||
let available = value.available();
|
let available = value.available();
|
||||||
|
|
||||||
let current = value
|
let current = value
|
||||||
@@ -95,13 +97,15 @@ impl From<&HassEntity> for ThermostatData {
|
|||||||
.attributes
|
.attributes
|
||||||
.get("temperature")
|
.get("temperature")
|
||||||
.and_then(|x| x.as_f64())
|
.and_then(|x| x.as_f64())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default() as f32;
|
||||||
|
|
||||||
let (target, remainder) = split_number(temperature, 1);
|
let (target, remainder) = split_number(temperature, 1);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
id,
|
||||||
available,
|
available,
|
||||||
current,
|
current,
|
||||||
|
temperature,
|
||||||
name: value.friendly_name().to_shared_string(),
|
name: value.friendly_name().to_shared_string(),
|
||||||
state: value.state.to_uppercase().to_shared_string(),
|
state: value.state.to_uppercase().to_shared_string(),
|
||||||
unit: "°C".into(),
|
unit: "°C".into(),
|
||||||
@@ -272,10 +276,10 @@ pub fn pretty_label(value: &str) -> String {
|
|||||||
.join(" ")
|
.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 factor = 10_i32.pow(decimals);
|
||||||
let main = x.trunc() as i32;
|
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)
|
(main, remainder)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
|
|
||||||
app.on_toggle_light({
|
app.on_toggle_light({
|
||||||
let state = state.clone();
|
let state = state.clone();
|
||||||
|
let c2s_tx = c2s_tx.clone();
|
||||||
move |entity_id| {
|
move |entity_id| {
|
||||||
let id = entity_id.to_string();
|
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()?;
|
app.run()?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
ElevatedButton,
|
ElevatedButton,
|
||||||
SegmentedButton,
|
SegmentedButton,
|
||||||
MaterialPalette,
|
MaterialPalette,
|
||||||
|
FilledButton,
|
||||||
} from "material/material.slint";
|
} from "material/material.slint";
|
||||||
import { Icons } from "material/ui/icons/icons.slint";
|
import { Icons } from "material/ui/icons/icons.slint";
|
||||||
export struct WeatherData {
|
export struct WeatherData {
|
||||||
@@ -29,8 +30,10 @@ export struct WeatherData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export struct ThermostatData {
|
export struct ThermostatData {
|
||||||
|
id: string,
|
||||||
name: string,
|
name: string,
|
||||||
current: float,
|
current: float,
|
||||||
|
temperature: float,
|
||||||
unit: string,
|
unit: string,
|
||||||
target: int,
|
target: int,
|
||||||
remainder: 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;
|
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: [
|
property <[image]> icons: [
|
||||||
@image-url("icons/sun.svg"),
|
@image-url("icons/sun.svg"),
|
||||||
@image-url("icons/cloud-sun.svg"),
|
@image-url("icons/cloud-sun.svg"),
|
||||||
@@ -96,6 +102,7 @@ export component Climate inherits Rectangle {
|
|||||||
|
|
||||||
ElevatedButton {
|
ElevatedButton {
|
||||||
icon: Icons.remove;
|
icon: Icons.remove;
|
||||||
|
clicked => { root.set_temperature(thermostat.id, thermostat.temperature - 0.5) }
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@@ -149,6 +156,17 @@ export component Climate inherits Rectangle {
|
|||||||
|
|
||||||
ElevatedButton {
|
ElevatedButton {
|
||||||
icon: Icons.add;
|
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 <[ThermostatData]> thermostats;
|
||||||
in property <WeatherData> weather;
|
in property <WeatherData> weather;
|
||||||
in property <bool> is-night;
|
in property <bool> is-night;
|
||||||
|
callback set_temperature(string, float);
|
||||||
|
callback toggle_thermostat(string);
|
||||||
|
|
||||||
in property <[ThermometerData]> thermometers;
|
in property <[ThermometerData]> thermometers;
|
||||||
|
|
||||||
@@ -170,6 +172,8 @@ export component AppWindow inherits Window {
|
|||||||
thermostats: thermostats;
|
thermostats: thermostats;
|
||||||
is-night: is-night;
|
is-night: is-night;
|
||||||
weather: weather;
|
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 == 1: Calendar { }
|
||||||
if tab-bar.current-index == 2: Energy { }
|
if tab-bar.current-index == 2: Energy { }
|
||||||
|
|||||||
Reference in New Issue
Block a user