Continue GPIO Tinkering

OutputPin objects aren't Copy- or Clone-able, which is causing problems.
Starting rewrite, passing around u8 OutputPin *addresses* instead,
hopefully that will work properly.
This commit is contained in:
Blizzard Finnegan 2023-05-09 16:30:15 -04:00
parent 605ea16b3a
commit 0b73b71dfc
Signed by: blizzardfinnegan
GPG key ID: 61C1E13067E0018E
5 changed files with 137 additions and 34 deletions

View file

@ -1,9 +1,14 @@
use std::{fs::{self, File}, path::Path, io::{BufReader, BufRead}, thread, time::Duration};
use std::{fs::{self, File}, path::Path, io::{BufReader, BufRead, BufWriter, Write}, thread, time::Duration};
use crate::{tty, gpio_facade::Relay};
const BOOT_TIME:Duration = Duration::new(60, 0);
const BP_START:Duration = Duration::new(60, 0);
const BP_RUN:Duration = Duration::new(60, 0);
const REBOOTS_SECTION: &str = "Reboots: ";
const BP_SECTION: &str = "Successful BP tests: ";
const TEMP_SECTION: &str = "Successful temp tests: ";
const OUTPUT_FOLDER: &str = "output/";
const UNINITIALISED_SERIAL: &str = "uninitialised";
#[derive(PartialEq)]
pub enum State{
LoginPrompt,
@ -15,7 +20,7 @@ pub enum State{
pub struct Device{
usb_tty: tty::TTY,
output_file: Option<File>,
pin: Option<Relay>,
pin: Option<&'static mut Relay>,
serial: String,
current_state: State,
reboots: u64,
@ -25,11 +30,10 @@ pub struct Device{
impl Device{
fn load_values(&mut self) -> &mut Self {
let mut output_path:String = "output/".to_string();
if ! Path::new(&output_path).is_dir(){
_ = fs::create_dir(&output_path);
if ! Path::new(&OUTPUT_FOLDER).is_dir(){
_ = fs::create_dir(&OUTPUT_FOLDER);
};
output_path.push_str(&self.serial.to_string());
let output_path = OUTPUT_FOLDER.to_owned() + &self.serial.to_string();
if ! Path::new(&output_path).exists(){
self.output_file = Some(fs::File::create(&output_path).unwrap());
}
@ -42,13 +46,13 @@ impl Device{
let section: &str = &*split_sections.next().unwrap().to_lowercase();
let value = split_sections.next().unwrap().parse::<u64>().unwrap();
match section {
"Reboots: " => {
REBOOTS_SECTION => {
self.reboots = value;
},
"Successful BP cycles:" => {
BP_SECTION => {
self.bps = value;
},
"Successful temp cycles:" => {
TEMP_SECTION => {
self.temps = value;
},
_ => ()
@ -63,7 +67,7 @@ impl Device{
usb_tty: usb_port,
pin: None,
output_file: None,
serial: "uninitialised".to_string(),
serial: UNINITIALISED_SERIAL.to_string(),
current_state: State::LoginPrompt,
reboots: 0,
temps: 0,
@ -110,6 +114,7 @@ impl Device{
};
return self;
}
#[allow(dead_code)]
fn go_to_debug_menu(&mut self) -> &mut Self{
while !(self.current_state == State::DebugMenu){
match self.current_state {
@ -154,13 +159,29 @@ impl Device{
};
return self;
}
fn save_values(&mut self) -> &mut Self{
if let Some(file_name) = &self.output_file{
let mut file_writer = BufWriter::new(file_name);
let mut output_data = REBOOTS_SECTION.to_string();
output_data.push_str(&self.reboots.to_string());
output_data.push_str("\n");
output_data.push_str(BP_SECTION);
output_data.push_str(&self.bps.to_string());
output_data.push_str("\n");
output_data.push_str(TEMP_SECTION);
output_data.push_str(&self.temps.to_string());
file_writer.write_all(output_data.as_bytes()).expect("Unable to write to bufwriter");
file_writer.flush().expect("Unable to write to file");
}
return self;
}
pub fn set_serial(&mut self, serial:&str) -> &mut Self{
self.serial = serial.to_string();
self.load_values();
return self;
}
pub fn set_gpio(&mut self, gpio_pin: Relay) -> &mut Self{
self.pin = Some(gpio_pin);
pub fn set_gpio(&mut self, gpio_pin:Relay) -> &mut Self{
self.pin = Some(&mut gpio_pin);
return self;
}
pub fn start_temp(&mut self) -> &mut Self {
@ -224,7 +245,7 @@ impl Device{
else{
self.go_to_login_prompt();
self.reboots +=1;
//Write values to file
self.save_values();
return true;
}
}
@ -245,7 +266,7 @@ impl Device{
let _bp_end = self.is_bp_running();
if _bp_start != _bp_end {
self.bps +=1;
//Write values to file
self.save_values();
}
}
for temp_count in 1..=local_temp_cycles{
@ -254,12 +275,12 @@ impl Device{
let _temp_end = self.stop_temp().is_temp_running();
if _temp_start != _temp_end {
self.temps +=1;
//Write values to file
self.save_values();
}
}
log::info!("Rebooting {}",self.serial);
self.reboot();
self.reboots += 1;
//Write values to file
self.save_values();
}
}

View file

@ -5,7 +5,7 @@ const GPIO:Lazy<rppal::gpio::Gpio> = Lazy::new(|| Gpio::new().unwrap());
const RELAY_ADDRESSES: [u8;10] = [4,5,6,12,13,17,18,19,20,26];
pub struct GpioFacade{
unassigned_relays:Vec<Box<Relay>>
unassigned_addresses:Vec<u8>
}
pub struct Relay{
@ -31,24 +31,29 @@ impl Relay{
impl GpioFacade{
pub fn new() -> Self {
let mut output = Self { unassigned_relays:Vec::new() };
let mut output = Self { unassigned_addresses:Vec::new() };
for pin in RELAY_ADDRESSES.iter(){
output.unassigned_relays.push(Box::new(Relay::new(GPIO.get(*pin).unwrap().into_output())));
output.unassigned_addresses.push(*pin);
//output.unassigned_addresses.push(Box::new(Relay::new(GPIO.get(*pin).unwrap().into_output())));
}
return output;
}
pub fn remove_pin(&mut self, address:u8) -> Option<&mut Box<Relay>>{
for relay in self.unassigned_relays.iter_mut() {
if &relay.address() == &address{
return Some(relay);
pub fn remove_pin(&mut self, address:u8) -> Option<Relay>{
let mut removed_address:u8 = 0;
for unassigned_address in self.unassigned_addresses.iter_mut() {
if address == *unassigned_address{
removed_address = address;
}
}
if removed_address > 0{
self.unassigned_addresses.retain(|&assigned_address| assigned_address != removed_address );
return Some(Relay::new(GPIO.get(removed_address).unwrap().into_output()));
}
return None;
}
pub fn get_unassigned_relays(&mut self) -> &Vec<Box<Relay>>{
return &self.unassigned_relays;
pub fn get_unassigned_addresses(&mut self) -> &mut Vec<u8>{
return &mut self.unassigned_addresses;
}
}

View file

@ -1,9 +1,86 @@
use log::error;
pub mod log_facade;
pub mod tty;
pub mod gpio_facade;
#[allow(unused_imports)]
use log::{warn,error,debug,info,trace};
use serialport;
use crate::serialport::SerialPortInfo;
use seymour_poc_rust::{device, tty,log_facade,gpio_facade::{Relay, self, GpioFacade}, tty::TTY};
use std::io::{stdin,stdout,Write};
#[allow(unused_imports)]
use std::{thread, time::Duration};
fn int_input_filtering(prompt:Option<&str>) -> i64{
let internal_prompt = prompt.unwrap_or(">>>");
let mut user_input:String = String::new();
print!("{}",internal_prompt);
_ = stdout().flush();
stdin().read_line(&mut user_input).expect("Did not input a valid number.");
if let Some('\n')=user_input.chars().next_back() {
user_input.pop();
}
if let Some('\r')=user_input.chars().next_back() {
user_input.pop();
}
return user_input.parse().unwrap_or(-1);
}
fn input_filtering(prompt:Option<&str>) -> String{
let internal_prompt = prompt.unwrap_or(">>>");
let mut user_input:String = String::new();
print!("{}",internal_prompt);
_ = stdout().flush();
stdin().read_line(&mut user_input).expect("Did not enter a correct string");
if let Some('\n')=user_input.chars().next_back() {
user_input.pop();
}
if let Some('\r')=user_input.chars().next_back() {
user_input.pop();
}
return user_input;
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
log_facade::setup_logs()?;
error!("Test log creation");
log_facade::setup_logs().unwrap();
let mut gpio = GpioFacade::new();
let available_ttys:Vec<SerialPortInfo> = tty::AVAILABLE_TTYS.clone();
let mut possible_devices:Vec<Option<device::Device>> = Vec::new();
for possible_tty in available_ttys.to_vec(){
possible_devices.push(thread::spawn(move ||{
let mut possible_port = TTY::new(possible_tty.port_name.to_string());
println!("Testing port {}. This may take a moment...",possible_tty.port_name);
possible_port.write_to_device(tty::Command::Newline);
let response = possible_port.read_from_device(Some(""));
if response != tty::Response::Other{
Some(device::Device::new(possible_port))
}
else{
None
}
}).join().unwrap());
}
let mut devices:Vec<device::Device> = Vec::new();
for possible_device in possible_devices.into_iter(){
if let Some(device) = possible_device{
devices.push(device);
}
}
println!("Dimming all screens...");
for device in devices.iter_mut(){
device.darken_screen();
}
for device in devices.iter_mut(){
device.brighten_screen()
.set_serial(&input_filtering(Some("Enter the serial of the device with the bright screen: ")).to_string())
.darken_screen();
let unassigned_relays:&Vec<Box<Relay>> = gpio.get_unassigned_relays();
for relay in unassigned_relays.into_iter(){
_ = &relay.high();
if device.is_temp_running(){
device.set_gpio(**relay);
}
}
}
Ok(())
}

View file

View file

@ -3,9 +3,9 @@ use once_cell::sync::Lazy;
use serialport::{SerialPortInfo, SerialPort};
use derivative::Derivative;
const BAUD_RATE:u32 = 115200;
pub const BAUD_RATE:u32 = 115200;
const AVAILABLE_TTYS: Lazy<Vec<SerialPortInfo>> = Lazy::new(||serialport::available_ports().unwrap());
pub const AVAILABLE_TTYS: Lazy<Vec<SerialPortInfo>> = Lazy::new(||serialport::available_ports().unwrap());
#[derive(Eq,Derivative)]
#[derivative(PartialEq, Hash)]