From 3cd136ce9484e7a72dc18ae7bde3bd5fef0b9425 Mon Sep 17 00:00:00 2001 From: Rory Coffey Date: Tue, 17 Aug 2021 21:15:30 -0400 Subject: [PATCH 1/5] Adding await to trains --- Cargo.toml | 1 + src/main.rs | 38 +++++++++++++++++++++++++++++++++----- src/train_time.rs | 38 ++++++++++++++++++++------------------ 3 files changed, 54 insertions(+), 23 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 531d13a..3fc3210 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,3 +21,4 @@ scraper = "0.12.0" rayon = "1.5.1" termion = "1.5.6" tokio = { version = "1", features = ["full"] } +futures = {version = "0.3.15", features = ["executor"]} diff --git a/src/main.rs b/src/main.rs index 92633bd..2b55187 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,12 @@ use clap::{App, Arg}; +use futures::executor::block_on; use mbta_countdown; -use std; +use rppal::gpio; use std::{ collections::HashMap, + error, io::{stdout, Read, Write}, + process::{exit, Command}, sync::{Arc, Mutex}, time::Duration, }; @@ -42,7 +45,22 @@ async fn main() { // set quit to false to have a clean quit let quit = Arc::new(Mutex::new(false)); + let shutdown = Arc::new(Mutex::new(false)); + let gpio = gpio::Gpio::new().unwrap_or_else(|err| panic!("ERROR - gpio - {}", err)); + let mut shutdown_pin = gpio + .get(21) + .unwrap_or_else(|err| panic!("ERROR - pin - {}", err)) + .into_input(); + + let quit_clone = Arc::clone(&quit); + let shutdown_clone = Arc::clone(&shutdown); + shutdown_pin + .set_async_interrupt(gpio::Trigger::FallingEdge, move |_| { + *quit_clone.lock().unwrap() = true; + *shutdown_clone.lock().unwrap() = true; + }) + .unwrap(); let address; if clock_type == "TM1637".to_string() { @@ -55,6 +73,7 @@ async fn main() { .unwrap_or_else(|err| panic!("ERROR - clock - {}", err)); let train_times = Arc::new(Mutex::new( mbta_countdown::train_time::train_times(&dir_code, &station, &vehicle_code) + .await .unwrap_or_else(|err| panic!("ERROR - train_times - {}", err)), )); let train_times_clone = Arc::clone(&train_times); @@ -89,7 +108,7 @@ async fn main() { }; } if let Ok(new_train_times) = - mbta_countdown::train_time::train_times(&dir_code, &station, &vehicle_code) + mbta_countdown::train_time::train_times(&dir_code, &station, &vehicle_code).await { let mut train_times_unlocked = train_times_clone.lock().unwrap(); *train_times_unlocked = new_train_times; @@ -151,7 +170,9 @@ async fn main() { }; }; } - screen_train_thread.await.unwrap_or_else(|err| panic!("ERROR - train thread - {}", err)); + screen_train_thread + .await + .unwrap_or_else(|err| panic!("ERROR - train thread - {}", err)); write!( stdout_main, "{}{}Finished", @@ -165,10 +186,17 @@ async fn main() { clock .clear_display() .unwrap_or_else(|err| panic!("ERROR - clear_display - {}", err)); + if *shutdown.lock().unwrap() { + Command::new("shutdown") + .arg("-h") + .arg("now") + .output() + .unwrap(); + } } /// Gets the command line arguments -pub fn arguments() -> Result<(String, String, u8, String, String), Box> { +pub fn arguments() -> Result<(String, String, u8, String, String), Box> { // get station and vehicle conversions for the MBTA API let (vehicle_info, station_info) = mbta_countdown::mbta_info::all_mbta_info(false)?; // get a list of stations to limit the station argument input @@ -273,7 +301,7 @@ pub fn arguments() -> Result<(String, String, u8, String, String), Box Result>>, Box> { // get prediction times - let prediction_times = get_prediction_times(station, dir_code, route_code)?; + let prediction_times_task = get_prediction_times(station, dir_code, route_code); // get schuduled times, if None, create empty hashmap - let mut scheduled_times = - get_scheduled_times(station, dir_code, route_code)?.unwrap_or(HashMap::new()); + let scheduled_times_task = + get_scheduled_times(station, dir_code, route_code); + let prediction_times = prediction_times_task.await?; + let mut scheduled_times = scheduled_times_task.await?.unwrap_or(HashMap::new()); + // let (prediction_times, scheduled_times_start) = try_join!(prediction_times_task, scheduled_times_task)?; + // let mut scheduled_times = scheduled_times_start.unwrap_or(HashMap::new()); // if there are predicted times, replace the scheduled times with the more accurate predicted // tiem if let Some(pred_times) = prediction_times { @@ -51,34 +53,34 @@ pub fn train_times( } /// Retreived MBTA predicted times with their API -fn get_prediction_times( +async fn get_prediction_times( station: &str, dir_code: &str, route_code: &str, ) -> Result>>, Box> { // MBTA API for predicted times let address = format!("https://api-v3.mbta.com/predictions?filter[stop]={}&filter[direction_id]={}&include=stop&filter[route]={}", station, dir_code, route_code); - return get_route_times(address); + return get_route_times(address).await; } /// Retreived MBTA scheduled times with their API -fn get_scheduled_times( +async fn get_scheduled_times( station: &str, dir_code: &str, route_code: &str, ) -> Result>>, Box> { - let now = chrono::Local::now(); + let now = Local::now(); // MBTA API for scheduled times let address = format!("https://api-v3.mbta.com/schedules?include=route,trip,stop&filter[min_time]={}%3A{}&filter[stop]={}&filter[route]={}&filter[direction_id]={}",now.hour(), now.minute(), station, route_code, dir_code); - return get_route_times(address); + return get_route_times(address).await; } /// Retreives the JSON from MBTA API and parses it into a hasmap -fn get_route_times( +async fn get_route_times( address: String, ) -> Result>>, Box> { // retrieve the routes with the MBTA API returning a converted JSON format - let routes_json: Value = reqwest::blocking::get(&address)?.json()?; + let routes_json: Value = reqwest::get(&address).await?.json().await?; // only interested in the "data" field let data_option = routes_json.get("data"); // if there is a "data" field, proceed @@ -86,7 +88,7 @@ fn get_route_times( // if the "data" field is an array, proceed if let Some(data_array) = data.as_array() { // create a new HashMap to put int trip_id and departure time - let mut commuter_rail_dep_time: HashMap> = + let mut commuter_rail_dep_time: HashMap> = HashMap::new(); // for each train in the data array, insert the trip_id and departure time for train in data_array { From fbe0aef4eadbdda5d6809abda8ce2016f8a226aa Mon Sep 17 00:00:00 2001 From: Rory Date: Wed, 1 Sep 2021 19:31:56 -0400 Subject: [PATCH 2/5] upgraded reqwest to get to tokio v1 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 3fc3210..1ab114a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ edition = "2018" chrono = "0.4" ht16k33 = "0.4" lazy_static = "1.4" -reqwest = {version = "0.10.0-alpha.2", features = ["blocking", "json"]} +reqwest = {version = "0.11", features = ["blocking", "json"]} rppal = {version = "0.11", features = ["hal-unproven"]} serde_json = "1.0" ssd1306 = "0.4" From 3b0eced057df8675ef25477fdde2755467f11259 Mon Sep 17 00:00:00 2001 From: Rory Date: Wed, 1 Sep 2021 19:32:36 -0400 Subject: [PATCH 3/5] added awaits --- src/main.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index f29844b..0849b7c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,6 @@ use chrono::prelude::*; use chrono::Local; use clap::{App, Arg}; -use futures::executor::block_on; use mbta_countdown; use rppal::gpio; use std; @@ -119,7 +118,7 @@ async fn main() { // get the first and last train for the day to know when to pause the displays and not // continually update when there are no trains arriving let last_first = - mbta_countdown::train_time::max_min_times(&dir_code, &station, &vehicle_code) + mbta_countdown::train_time::max_min_times(&dir_code, &station, &vehicle_code).await .unwrap_or_else(|err| panic!("Error - max min times - {}", err)); let mut last_time; let mut first_time; @@ -153,7 +152,7 @@ async fn main() { // after 3 am get the first and last vehicle times let last_first_thread = - mbta_countdown::train_time::max_min_times(&dir_code, &station, &vehicle_code) + mbta_countdown::train_time::max_min_times(&dir_code, &station, &vehicle_code).await .unwrap_or_else(|err| panic!("Error - max min times - {}", err)); if let Some([last, first]) = last_first_thread { last_time = last; From 2f97618eab58d7799ec8d5a46dcf3b3262f6ff8b Mon Sep 17 00:00:00 2001 From: Rory Date: Wed, 1 Sep 2021 19:33:28 -0400 Subject: [PATCH 4/5] added time filtering and an await --- src/train_time.rs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/train_time.rs b/src/train_time.rs index a8922c5..87089b2 100644 --- a/src/train_time.rs +++ b/src/train_time.rs @@ -2,7 +2,6 @@ use reqwest; use std; use chrono::prelude::*; use chrono::{DateTime, Local, TimeZone}; -use futures::try_join; use serde_json::Value; use std::{collections::HashMap, error::Error}; @@ -16,7 +15,7 @@ pub async fn train_times( let prediction_times_task = get_prediction_times(station, dir_code, route_code); // get schuduled times, if None, create empty hashmap let scheduled_times_task = - get_scheduled_times(station, dir_code, route_code); + get_scheduled_times(station, dir_code, route_code, true); let prediction_times = prediction_times_task.await?; let mut scheduled_times = scheduled_times_task.await?.unwrap_or(HashMap::new()); // let (prediction_times, scheduled_times_start) = try_join!(prediction_times_task, scheduled_times_task)?; @@ -52,12 +51,12 @@ pub async fn train_times( return Ok(Some(all_times)); } -pub fn max_min_times( +pub async fn max_min_times( dir_code: &str, station: &str, route_code: &str, ) -> Result; 2]>, Box> { - if let Some(scheduled_times) = get_scheduled_times(station, dir_code, route_code, false)? { + if let Some(scheduled_times) = get_scheduled_times(station, dir_code, route_code, false).await? { let mut all_times = scheduled_times .values() .map(|date| date.clone()) @@ -89,10 +88,16 @@ async fn get_scheduled_times( station: &str, dir_code: &str, route_code: &str, + filter_time: bool, ) -> Result>>, Box> { - let now = Local::now(); - // MBTA API for scheduled times - let address = format!("https://api-v3.mbta.com/schedules?include=route,trip,stop&filter[min_time]={}%3A{}&filter[stop]={}&filter[route]={}&filter[direction_id]={}",now.hour(), now.minute(), station, route_code, dir_code); + let address; + if filter_time { + let now = chrono::Local::now(); + // MBTA API for scheduled times + address = format!("https://api-v3.mbta.com/schedules?include=route,trip,stop&filter[min_time]={}%3A{}&filter[stop]={}&filter[route]={}&filter[direction_id]={}",now.hour(), now.minute(), station, route_code, dir_code); + } else { + address = format!("https://api-v3.mbta.com/schedules?include=route,trip,stop&filter[stop]={}&filter[route]={}&filter[direction_id]={}", station, route_code, dir_code); + } return get_route_times(address).await; } From 5e1b606f818e2cc81af7ca6052e1645e0dbf815b Mon Sep 17 00:00:00 2001 From: Rory Date: Wed, 1 Sep 2021 19:38:41 -0400 Subject: [PATCH 5/5] updated to version 0.5 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 1ab114a..1f72aee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mbta_countdown" -version = "0.4.0" +version = "0.5.0" authors = ["Rory Coffey "] edition = "2018"