diff --git a/MQTT.md b/MQTT.md deleted file mode 100644 index 1bebd37..0000000 --- a/MQTT.md +++ /dev/null @@ -1,51 +0,0 @@ - # MQTT Configuration - - This project can publish weather and public transport data to an MQTT broker. - To enable MQTT, follow these steps: - - ## 1. Install dependencies - Ensure you have Rust and Cargo installed. The MQTT support uses the Paho MQTT client crate. - Run: - ```bash - cargo update - ``` - - ## 2. Set the MQTT_BROKER environment variable - Before running the client, define `MQTT_BROKER` to your broker address. - - Without URI scheme (defaults to TCP): - ```bash - export MQTT_BROKER=localhost:1883 - ``` - - With URI scheme: - ```bash - export MQTT_BROKER=tcp://broker.example.com:1883 - ``` - - ## 3. Run the LED board client - Pass the LED board IP address as the only argument: - ```bash - export MQTT_BROKER=localhost:1883 - cargo run --bin ledboard_client -- 192.168.1.50 - ``` - - ## Topics and Payloads - The client publishes two topics: - - ### weather - JSON payload with fields: - - `dt`: timestamp (Unix seconds) - - `temp`: temperature in °C - - `weather`: object with `main`, `description`, `icon` - - `rain`: rain volume in last 3h (optional) - - `pop`: probability of precipitation - - `wind`: object with `speed`, `deg`, `gust` - - ### straba - JSON payload with fields: - - `outbound_station`: name of outbound station - - `outbound_diff`: seconds until outbound departure - - `inbound_station`: name of inbound station - - `inbound_diff`: seconds until inbound departure - - ## Customization - You can adjust MQTT topics, QoS, and message formats in `client/bin/src/main.rs` under the `publish_to_mqtt` function. \ No newline at end of file diff --git a/client/bin/src/main.rs b/client/bin/src/main.rs index bb80194..c01bd6a 100644 --- a/client/bin/src/main.rs +++ b/client/bin/src/main.rs @@ -23,6 +23,7 @@ use std::process::ExitCode; use openweathermap::forecast::Forecast; use straba::NextDeparture; +use paho_mqtt::{Client, CreateOptionsBuilder, ConnectOptionsBuilder, Message}; // This declaration will look for a file named `straba.rs` and will // insert its contents inside a module named `straba` under this scope mod straba; @@ -347,6 +348,28 @@ fn check_connection(ipaddress: String) -> bool { } return device_online; } +/// Publishes weather and transit data to MQTT broker +fn publish_to_mqtt(client: &Client, data: &Option>, straba_res: &NextDeparture) { + let payload = if let Some(Ok(forecast)) = data { + if let Some(f) = forecast.list.first() { + let temp = f.main.temp; + let weather = f.weather.get(0).map(|w| w.main.clone()).unwrap_or_default(); + format!("temp:{:.1}C,weather:{},out:{}min,in:{}min", + temp, + weather, + straba_res.outbound_diff / 60, + straba_res.inbound_diff / 60) + } else { + "no_forecast".to_string() + } + } else { + "no_data".to_string() + }; + let msg = Message::new("ledboard/data", payload, 1); + if let Err(e) = client.publish(msg) { + eprintln!("Error publishing MQTT message: {}", e); + } +} fn main() -> ExitCode { let args: Vec = env::args().collect(); @@ -380,6 +403,45 @@ fn main() -> ExitCode { let mut straba_res = straba::fetch_data(Some(true)); println!("{:?} {:?}s", straba_res.outbound_station, straba_res.outbound_diff); println!("{:?} {:?}s", straba_res.inbound_station , straba_res.inbound_diff); + + // Initialize MQTT client from MQTT_BROKER env var (else disabled) + let mqtt_client: Option = { + // Read broker URL from environment + let broker = match std::env::var("MQTT_BROKER") { + Ok(val) if !val.is_empty() => val, + _ => { + eprintln!("Environment variable MQTT_BROKER not set or empty, MQTT disabled"); + String::new() + } + }; + if broker.is_empty() { + None + } else { + let create_opts = CreateOptionsBuilder::new() + .server_uri(&broker) + .client_id("ledboard_client") + .finalize(); + match Client::new(create_opts) { + Ok(cli) => { + let conn_opts = ConnectOptionsBuilder::new() + .keep_alive_interval(Duration::from_secs(20)) + .clean_session(true) + .finalize(); + match cli.connect(conn_opts) { + Ok(_) => Some(cli), + Err(e) => { + eprintln!("Failed to connect to MQTT broker '{}': {}", broker, e); + None + } + } + } + Err(e) => { + eprintln!("Failed to create MQTT client for '{}': {}", broker, e); + None + } + } + } + }; // Render start send_package(ip.to_string(), &last_data, &straba_res);