request station_id via new integrated function

This commit is contained in:
Ollo
2026-02-28 21:26:43 +01:00
parent fc3fc65d64
commit cd5c0f8dd1
2 changed files with 87 additions and 4 deletions

View File

@@ -31,10 +31,14 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let (client, mut eventloop) = AsyncClient::new(mqttoptions, 100); let (client, mut eventloop) = AsyncClient::new(mqttoptions, 100);
//FIXME Set last_request initially to 1 hour before now
let mut last_request = Instant::now(); let mut last_request = Instant::now() - Duration::from_secs(3600);
let interval = Duration::from_secs(args.interval as u64); let interval = Duration::from_secs(args.interval as u64);
let mut departure_data = tokio::task::spawn_blocking(|| straba::fetch_data(2494, Some(true))) let station_id = tokio::task::spawn_blocking(|| straba::lookup_station_id("Lettestr"))
.await
.unwrap()
.expect("Failed to lookup station ID");
let mut departure_data = tokio::task::spawn_blocking(move || straba::fetch_data(station_id, Some(true)))
.await .await
.unwrap(); .unwrap();
let mut data_published = false; let mut data_published = false;
@@ -44,7 +48,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
if now.duration_since(last_request) > interval { if now.duration_since(last_request) > interval {
data_published = false; data_published = false;
last_request = Instant::now(); last_request = Instant::now();
departure_data = tokio::task::spawn_blocking(|| straba::fetch_data(2494, Some(false))) departure_data = tokio::task::spawn_blocking(move || straba::fetch_data(station_id, Some(false)))
.await .await
.unwrap(); .unwrap();
if departure_data.failure { if departure_data.failure {
@@ -68,6 +72,26 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
Ok(Event::Incoming(Packet::Publish(_))) => {} Ok(Event::Incoming(Packet::Publish(_))) => {}
Ok(Event::Incoming(Packet::ConnAck(_))) => { Ok(Event::Incoming(Packet::ConnAck(_))) => {
println!("Connected to MQTT broker"); println!("Connected to MQTT broker");
if data_published == false
{
client
.publish("departure/station", QoS::AtLeastOnce, false, departure_data.station_name.as_bytes())
.await?;
client
.publish("departure/outbound/station", QoS::AtLeastOnce, false, departure_data.outbound_station.as_bytes())
.await?;
client
.publish("departure/outbound/diff", QoS::AtLeastOnce, false, format!("{}", departure_data.outbound_diff))
.await?;
client
.publish("departure/inbound/station", QoS::AtLeastOnce, false, departure_data.inbound_station.as_bytes())
.await?;
client
.publish("departure/inbound/diff", QoS::AtLeastOnce, false, format!("{}", departure_data.inbound_diff))
.await?;
data_published = true;
}
} }
Ok(_) => { Ok(_) => {
if data_published == false if data_published == false

View File

@@ -8,6 +8,10 @@ const LOOKUP_STATION_URL: &str = "https://www.rnv-online.de/rest/stop?name=";
const STATION_URL: &str = "https://www.rnv-online.de/rest/departure/"; const STATION_URL: &str = "https://www.rnv-online.de/rest/departure/";
/* ******************** JSON Description ****************************** */ /* ******************** JSON Description ****************************** */
/********************************************************
* Used to decode Timetable response
********************************************************/
#[derive(Default, Debug, Clone, PartialEq, Deserialize)] #[derive(Default, Debug, Clone, PartialEq, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Station { pub struct Station {
@@ -81,6 +85,61 @@ pub struct NextDeparture {
pub failure: bool, pub failure: bool,
} }
/********************************************************
* Used to decode Station Lookup
********************************************************/
#[derive(Default, Debug, Clone, PartialEq, Deserialize)]
pub struct StationLookupResponse {
pub results: Vec<StationLookupRegion>,
}
#[derive(Default, Debug, Clone, PartialEq, Deserialize)]
pub struct StationLookupRegion {
pub children: Vec<StationLookupItem>,
}
#[derive(Default, Debug, Clone, PartialEq, Deserialize)]
pub struct StationLookupItem {
pub id: String,
}
/********************************************************
* Global Functions
********************************************************/
pub fn lookup_station_id(station_name: &str) -> Option<u64> {
let url = format!("{}{}", LOOKUP_STATION_URL, station_name);
let result = reqwest::blocking::get(&url).ok()?;
let text = result.text().ok()?;
let body: StationLookupResponse = serde_json::from_str(&text).ok()?;
/** Example https://www.rnv-online.de/rest/stop?name=Lettestr
{
"results": [
{
"text": "Mannheim",
"children": [
{
"id": "2494",
"triasId": "de:08222:2494",
"text": "Mannheim, Lettestraße",
"value": "https://www.rnv-online.de/rest/station/2494"
}
]
}
],
"cached": false,
"lifetime": 3600
}
*/
body.results
.iter()
.flat_map(|r| r.children.iter())
.next()
.and_then(|s| s.id.parse().ok())
}
pub fn fetch_data(station_id: u64, debug_print: Option<bool>) -> NextDeparture { pub fn fetch_data(station_id: u64, debug_print: Option<bool>) -> NextDeparture {
let st_now = SystemTime::now(); let st_now = SystemTime::now();
let seconds = st_now.duration_since(UNIX_EPOCH).unwrap().as_secs(); let seconds = st_now.duration_since(UNIX_EPOCH).unwrap().as_secs();