tracing and changes

This commit is contained in:
2026-09-13 16:25:47 +01:00
parent 74f59be3f8
commit 57201bc0ff
17 changed files with 306 additions and 47 deletions
+53 -5
View File
@@ -1,6 +1,10 @@
use std::error::Error;
use common::{BarModule, Endpoint, ModuleEffect, Service, WeatherKind, WeatherMsg, Wire};
use chrono::Timelike;
use common::{
BarModule, ClockKind, ClockPayload, Endpoint, Hourly, ModuleEffect, Service, WeatherKind,
WeatherMsg, WeatherPayload, WeatherResponse, Wire,
};
use iced::{
widget::{container, mouse_area, text},
Element, Task,
@@ -8,11 +12,37 @@ use iced::{
pub struct WeatherModule {
text: String,
/// Cached hourly forecast from the last weather update.
hourly: Option<Hourly>,
/// Current hour, mirrored from the datetime service's clock ticks.
hour: Option<u32>,
}
impl WeatherModule {
/// Shows the forecast temperature for the tracked current hour.
fn refresh(&mut self) {
let (Some(hourly), Some(hour)) = (&self.hourly, self.hour) else {
return;
};
if let Some(i) = hourly.time.iter().position(|t| t.hour() == hour) {
if let Some(&temp) = hourly.temperature_2m.get(i) {
let value = format!("{}°", temp as i32);
if self.text != value {
self.text = value;
tracing::info!(hour, temp, "weather: current hour");
}
}
}
}
}
impl Default for WeatherModule {
fn default() -> Self {
Self { text: "hi".into() }
Self {
text: "waiting ".into(),
hourly: None,
hour: None,
}
}
}
@@ -32,18 +62,36 @@ impl BarModule for WeatherModule {
}
fn update(&mut self, msg: Wire) -> Task<ModuleEffect> {
// Weather state: cache the hourly forecast, then show the current hour.
if let Some(env) = msg.downcast::<WeatherPayload>() {
match env.kind {
WeatherMsg::State => match env.payload.downcast_ref::<WeatherResponse>() {
Some(resp) => {
self.hourly = Some(resp.hourly.clone());
self.refresh();
}
None => tracing::warn!("weather payload was not a WeatherResponse"),
},
}
}
// Clock tick from the datetime service: track the current hour.
if let Some(payload) = msg.downcast::<ClockPayload>() {
self.hour = payload.value.split(':').next().and_then(|h| h.parse().ok());
self.refresh();
}
match msg.downcast::<WeatherKind>() {
Some(WeatherKind::Poke) => {
tracing::debug!("weather poked");
self.text = "poked".into();
Task::none()
}
None => Task::none(),
None => (),
}
Task::none()
}
/// Route keys this module subscribes to.
fn services(&self) -> Vec<Service> {
vec![WeatherMsg::State.key()]
vec![WeatherMsg::State.key(), ClockKind::Seconds.key()]
}
/// Optional: read `module.weather` from the config table.