logging and pcb adjustment

This commit is contained in:
2025-02-14 23:50:19 +01:00
parent 1741bb0b53
commit aad1dbd458
15 changed files with 389 additions and 119 deletions

View File

@@ -28,7 +28,9 @@ command = [
"save-image",
"--chip",
"esp32c6",
"image.bin"
"image.bin",
"--partition-table",
"partitions.csv"
]
@@ -66,7 +68,7 @@ once_cell = "1.19.0"
anyhow = { version = "1.0.75", features = ["std", "backtrace"] }
average = { version = "0.14.1" , features = ["std"] }
bit_field = "0.10.2"
strum = { version = "0.26.1", features = ["derive"] }
strum = { version = "0.27.0", features = ["derive"] }
measurements = "0.11.0"
schemars = "0.8.16"
@@ -82,6 +84,8 @@ url = "2.5.3"
crc = "3.2.1"
bincode = "1.3.3"
ringbuffer = "0.15.0"
text-template = "0.1.0"
strum_macros = "0.27.0"
[patch.crates-io]

143
rust/src/log/mod.rs Normal file
View File

@@ -0,0 +1,143 @@
use std::{collections::HashMap, sync::Mutex};
use strum_macros::IntoStaticStr;
use esp_idf_svc::systime::EspSystemTime;
use once_cell::sync::Lazy;
use ringbuffer::{ConstGenericRingBuffer, RingBuffer};
use text_template::Template;
const TXT_SHORT_LENGTH:usize = 8;
const TXT_LONG_LENGTH:usize = 32;
const BUFFER_SIZE:usize = 210;
#[link_section = ".rtc.data"]
static mut BUFFER:ConstGenericRingBuffer::<LogEntry, BUFFER_SIZE> = ConstGenericRingBuffer::<LogEntry, BUFFER_SIZE>::new();
static BUFFER_ACCESS: Lazy<Mutex<&mut ConstGenericRingBuffer::<LogEntry, BUFFER_SIZE>>> = Lazy::new(|| unsafe { Mutex::new(&mut BUFFER) });
pub struct LogEntry {
pub timestamp: u64,
pub message_id: u32,
pub a: u32,
pub b: u32,
pub txt_short: heapless::String<TXT_SHORT_LENGTH>,
pub txt_long: heapless::String<TXT_LONG_LENGTH>
}
pub fn init(){
unsafe {
BUFFER = ConstGenericRingBuffer::<LogEntry, BUFFER_SIZE>::new();
};
let mut access = BUFFER_ACCESS.lock().unwrap();
access.drain().for_each(|_| {});
}
fn limit_length <const LIMIT:usize> (input: &str, target: &mut heapless::String<LIMIT>){
for char in input.chars() {
match target.push(char) {
Ok(_) => {}, //continue adding chars
Err(_) => {
//clear space for two asci chars
while target.len()+2 >= LIMIT {
target.pop().unwrap();
}
//add .. to shortened strings
target.push('.').unwrap();
target.push('.').unwrap();
return;
},
}
}
}
pub fn log(message_key: LogMessage, number_a: u32, number_b: u32, txt_short:&str, txt_long:&str){
let mut txt_short_stack:heapless::String<TXT_SHORT_LENGTH> = heapless::String::new();
let mut txt_long_stack:heapless::String<TXT_LONG_LENGTH> = heapless::String::new();
limit_length(txt_short, &mut txt_short_stack);
limit_length(txt_long, &mut txt_long_stack);
let time = EspSystemTime {}.now().as_millis() as u64;
let template_string:&str = message_key.into();
let mut values: HashMap<&str, &str> = HashMap::new();
let number_a_str = number_a.to_string();
let number_b_str = number_b.to_string();
values.insert("number_a", &number_a_str);
values.insert("number_b", &number_b_str);
values.insert("txt_short", txt_short);
values.insert("txt_long", txt_long);
let template = Template::from(template_string);
let serial_entry = template.fill_in(&values);
println!("{serial_entry}");
let entry = LogEntry{
timestamp: time,
message_id: 1,
a: number_a,
b: number_b,
txt_short: txt_short_stack,
txt_long: txt_long_stack,
};
let mut buffer = BUFFER_ACCESS.lock().unwrap();
buffer.push(entry);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn within_limit() {
let test = "12345678";
let mut txt_short_stack:heapless::String<TXT_SHORT_LENGTH> = heapless::String::new();
let mut txt_long_stack:heapless::String<TXT_LONG_LENGTH> = heapless::String::new();
limit_length(test, &mut txt_short_stack);
limit_length(test, &mut txt_long_stack);
assert_eq!(txt_short_stack.as_str(), test);
assert_eq!(txt_long_stack.as_str(), test);
}
}
#[derive(IntoStaticStr)]
pub enum LogMessage {
#[strum(serialize = "Reset due to {{txt_long}} requires rtc clear {{a}} and force config mode {{b}}")]
reset_reason,
#[strum(serialize = "Current restart to conf mode {{a}}")]
restart_to_config,
#[strum(serialize = "Current low voltage detection is {{a}}")]
low_voltage,
#[strum(serialize = "Error communicating with battery!! {{txt_long}}")]
battery_communication_error,
#[strum(serialize = "Tank sensor raw {{a}} percent {{b}}")]
sensor_tank_raw,
#[strum(serialize = "raw measure unscaled {{a}} hz {{b}}, plant {{txt_short}} sensor {{txt_long}}")]
raw_measure,
#[strum(serialize = "IP info: {{txt_long}}")]
wifi_info,
#[strum(serialize = "Plant:{{txt_short}} a:{{a}} b:{{b}}")]
test_sensor,
#[strum(serialize = "Stay alive topic is {{txt_long}}")]
stay_alive,
#[strum(serialize = "Connecting mqtt {{txt_short}} with id {{txt_long}}")]
mqtt_info,
#[strum(serialize = "Received stay alive with value {{txt_short}}")]
mqtt_stay_alive_rec,
#[strum(serialize = "Unknown topic recieved {{txt_long}}")]
unknown_topic,
}

View File

@@ -3,7 +3,7 @@ use std::{
sync::{atomic::AtomicBool, Arc, Mutex},
};
use anyhow::Result;
use anyhow::{bail, Result};
use chrono::{DateTime, Datelike, TimeDelta, Timelike, Utc};
use chrono_tz::{Europe::Berlin, Tz};
@@ -22,7 +22,6 @@ use esp_idf_sys::{
esp_ota_img_states_t_ESP_OTA_IMG_VALID,
vTaskDelay
};
use log::error;
use once_cell::sync::Lazy;
use plant_hal::{PlantCtrlBoard, PlantHal, PLANT_COUNT};
use serde::{Deserialize, Serialize};
@@ -32,10 +31,12 @@ use crate::{
espota::{mark_app_valid, rollback_and_reboot},
webserver::webserver::httpd,
};
mod log;
mod config;
pub mod espota;
pub mod plant_hal;
const TIME_ZONE: Tz = Berlin;
const MOIST_SENSOR_MAX_FREQUENCY: u32 = 250000; // 60kHz (500Hz margin)
@@ -72,9 +73,9 @@ struct LightState {
#[derive(Debug, PartialEq, Default)]
struct PlantState {
a: Option<u8>,
a_raw: Option<i32>,
a_raw: Option<u32>,
b: Option<u8>,
b_raw: Option<i32>,
b_raw: Option<u32>,
consecutive_pump_count: u32,
after_p: Option<u8>,
do_water: bool,
@@ -142,14 +143,14 @@ fn safe_main() -> anyhow::Result<()> {
esp_idf_svc::log::EspLogger::initialize_default();
if esp_idf_sys::CONFIG_MAIN_TASK_STACK_SIZE < 25000 {
error!(
bail!(
"stack too small: {} bail!",
esp_idf_sys::CONFIG_MAIN_TASK_STACK_SIZE
);
return Ok(());
}
log::info!("Startup Rust");
println!("Startup Rust");
let mut to_config = false;
@@ -186,6 +187,7 @@ fn safe_main() -> anyhow::Result<()> {
};
println!("{}", ota_state_string);
println!("Board hal init");
let mut board: std::sync::MutexGuard<'_, PlantCtrlBoard<'_>> = BOARD_ACCESS.lock().unwrap();
board.general_fault(false);
@@ -207,7 +209,7 @@ fn safe_main() -> anyhow::Result<()> {
match time {
Ok(cur) => cur,
Err(err) => {
log::error!("time error {}", err);
bail!("time error {}", err);
DateTime::from_timestamp_millis(0).unwrap()
}
}
@@ -284,7 +286,7 @@ fn safe_main() -> anyhow::Result<()> {
ip_address = Some(ip_info.ip.to_string());
wifi = true;
match board.sntp(1000 * 5) {
match board.sntp(1000 * 10) {
Ok(new_time) => {
println!("Using time from sntp");
let _ = board.set_rtc_time(&new_time);

View File

@@ -2,6 +2,7 @@ use bq34z100::{Bq34Z100Error, Bq34z100g1, Bq34z100g1Driver};
use chrono_tz::Tz;
use ds323x::{DateTimeAccess, Ds323x};
use crate::log::{init, LogMessage};
use eeprom24x::{Eeprom24x, Eeprom24xTrait, SlaveAddr};
use embedded_hal_bus::i2c::MutexDevice;
@@ -22,6 +23,7 @@ use esp_idf_svc::mqtt::client::{EspMqttClient, LwtConfiguration, MqttClientConfi
use esp_idf_svc::nvs::EspDefaultNvsPartition;
use esp_idf_svc::wifi::config::{ScanConfig, ScanType};
use esp_idf_svc::wifi::EspWifi;
use log::logger;
use measurements::Temperature;
use once_cell::sync::Lazy;
use plant_ctrl2::sipo::ShiftRegister40;
@@ -46,7 +48,7 @@ use std::time::Duration;
use embedded_hal::digital::OutputPin;
use esp_idf_hal::delay::Delay;
use esp_idf_hal::gpio::{AnyInputPin, Gpio18, Gpio5, Gpio7, Gpio8, IOPin, InputOutput, Level, PinDriver, Pull};
use esp_idf_hal::gpio::{AnyInputPin, Gpio18, Gpio5, IOPin, InputOutput, Level, PinDriver, Pull};
use esp_idf_hal::pcnt::{
PcntChannel, PcntChannelConfig, PcntControlMode, PcntCountMode, PcntDriver, PinIndex,
};
@@ -54,11 +56,12 @@ use esp_idf_hal::prelude::Peripherals;
use esp_idf_hal::reset::ResetReason;
use esp_idf_svc::sntp::{self, SyncStatus};
use esp_idf_svc::systime::EspSystemTime;
use esp_idf_sys::{esp, esp_spiffs_check, gpio_hold_dis, gpio_hold_en, vTaskDelay, EspError};
use esp_idf_sys::{gpio_hold_dis, gpio_hold_en, vTaskDelay, EspError};
use one_wire_bus::OneWire;
use crate::config::{self, PlantControllerConfig};
use crate::espota::mark_app_valid;
use crate::log::log;
use crate::{plant_hal, to_string, STAY_ALIVE};
//Only support for 8 right now!
@@ -80,14 +83,15 @@ const PUMP5_BIT: usize = 5;
const PUMP6_BIT: usize = 6;
const PUMP7_BIT: usize = 7;
const MS_0: usize = 8;
const MS_4: usize = 9;
const MS_2: usize = 10;
const MS_3: usize = 11;
const SENSOR_ON: usize = 12;
const MS_1: usize = 13;
//unused 14
//unused 15
const CHARGING: usize = 14;
const AWAKE: usize = 15;
const FAULT_3: usize = 16;
const FAULT_8: usize = 17;
@@ -128,10 +132,6 @@ static mut LOW_VOLTAGE_DETECTED: bool = false;
#[link_section = ".rtc.data"]
static mut RESTART_TO_CONF: bool = false;
const BUFFER_SIZE:usize = 120;
const ENTRY_SIZE:usize = 120;
#[link_section = ".rtc.data"]
static mut BUFFER:ConstGenericRingBuffer::<heapless::String<ENTRY_SIZE>, BUFFER_SIZE> = ConstGenericRingBuffer::<heapless::String<ENTRY_SIZE>, BUFFER_SIZE>::new();
pub struct FileSystemSizeInfo {
@@ -266,9 +266,7 @@ impl PlantCtrlBoard<'_> {
OkStd(_) => {},
Err(err) => bail!("Error reading eeprom header {:?}", err),
};
println!("Raw header is {:?} with size {}", header_page_buffer , store);
let header:BackupHeader = bincode::deserialize(&header_page_buffer)?;
println!("Reading eeprom header {header:?}");
let data_start_address = 1*self.eeprom.page_size() as u32;
let mut data_buffer = vec![0_u8; header.size];
@@ -282,19 +280,6 @@ impl PlantCtrlBoard<'_> {
bail!("Invalid checksum, got {} but expected {}", checksum, header.crc16 );
}
unsafe {
let value = heapless::String::try_from("dummy").unwrap();
BUFFER.push(value);
}
unsafe {
for entry in BUFFER.iter() {
let test = entry.as_bytes().to_owned();
for p in test {
data_buffer.push(p);
}
}
}
Ok(data_buffer)
}
@@ -317,9 +302,7 @@ impl PlantCtrlBoard<'_> {
bail!("Size limit reached header is {}, but firest page is only {}",encoded.len(), page_size)
}
let as_u8:&[u8] = &encoded;
println!("Raw header is {:?} with size {}", as_u8 , as_u8.len());
match self.eeprom.write_page(0, as_u8) {
OkStd(_) => {},
Err(err) => bail!("Error writing eeprom {:?}", err),
@@ -375,13 +358,11 @@ impl PlantCtrlBoard<'_> {
let mut iter_error = None;
let mut result = Vec::new();
println!("Filename {filename}");
let filepath = Path::new(BASE_PATH);
let read_dir = fs::read_dir(filepath);
match read_dir {
OkStd(read_dir) => {
for item in read_dir {
println!("start loop");
match item {
OkStd(file) => {
let f = FileInfo {
@@ -392,7 +373,6 @@ impl PlantCtrlBoard<'_> {
.unwrap_or_default()
as usize,
};
println!("fileinfo {f:?}");
result.push(f);
}
Err(err) => {
@@ -503,8 +483,8 @@ impl PlantCtrlBoard<'_> {
let r2 = median * 50.0 / (3.3 - median);
let mut percent = r2 / 190_f32 * 100_f32;
percent = percent.clamp(0.0, 100.0);
log(LogMessage::sensor_tank_raw, median as u32, percent as u32, "","");
println!("Tank sensor raw {} percent {}", median, percent);
return Ok(percent as u16);
}
@@ -620,7 +600,7 @@ impl PlantCtrlBoard<'_> {
self.time()
}
pub fn measure_moisture_hz(&mut self, plant: usize, sensor: Sensor) -> Result<i32> {
pub fn measure_moisture_hz(&mut self, plant: usize, sensor: Sensor) -> Result<u32> {
let sensor_channel = match sensor {
Sensor::A => match plant {
0 => SENSOR_A_1,
@@ -646,7 +626,7 @@ impl PlantCtrlBoard<'_> {
},
};
let mut results = [0; REPEAT_MOIST_MEASURE];
let mut results = [0_u32; REPEAT_MOIST_MEASURE];
for repeat in 0..REPEAT_MOIST_MEASURE {
self.signal_counter.counter_pause()?;
self.signal_counter.counter_clear()?;
@@ -675,13 +655,9 @@ impl PlantCtrlBoard<'_> {
.unwrap();
delay.delay_ms(10);
let unscaled = self.signal_counter.get_counter_value()? as i32;
let hz = (unscaled as f32 * factor) as i32;
println!(
"raw measure unscaled {} hz {}, plant {} sensor {:?}",
unscaled, hz, plant, sensor
);
let hz = (unscaled as f32 * factor) as u32;
log(LogMessage::raw_measure, unscaled as u32, hz as u32, &plant.to_string(), &format!("{sensor:?}"));
results[repeat] = hz;
//println!("Measuring {:?} @ {} with {}", sensor, plant, hz);
}
results.sort();
@@ -745,7 +721,6 @@ impl PlantCtrlBoard<'_> {
let delay = Delay::new_default();
let mut counter = 0_u32;
while !self.wifi_driver.is_connected()? {
println!("Waiting for station connection");
delay.delay_ms(250);
counter += 250;
if counter > max_wait {
@@ -758,7 +733,6 @@ impl PlantCtrlBoard<'_> {
println!("Should be connected now");
while !self.wifi_driver.is_up()? {
println!("Waiting for network being up");
delay.delay_ms(250);
counter += 250;
if counter > max_wait {
@@ -770,7 +744,7 @@ impl PlantCtrlBoard<'_> {
}
//update freertos registers ;)
let address = self.wifi_driver.sta_netif().get_ip_info()?;
println!("IP info: {:?}", address);
log(LogMessage::wifi_info, 0 ,0,"", &format!("{address:?}"));
Ok(address)
}
@@ -908,9 +882,16 @@ impl PlantCtrlBoard<'_> {
for plant in 0..PLANT_COUNT {
let a = self.measure_moisture_hz(plant, plant_hal::Sensor::A);
let b = self.measure_moisture_hz(plant, plant_hal::Sensor::B);
print!("P:{} a:{:?} b:{:?}", plant, a, b)
let aa = match a {
OkStd(a) => a as u32,
Err(_) => u32::MAX
};
let bb = match b {
OkStd(b) => b as u32,
Err(_) => u32::MAX
};
log(LogMessage::test_sensor, aa ,bb,&plant.to_string(), "");
}
println!();
Delay::new_default().delay_ms(10);
Ok(())
}
@@ -958,18 +939,15 @@ impl PlantCtrlBoard<'_> {
let round_trip_ok = Arc::new(AtomicBool::new(false));
let round_trip_topic = format!("{}/internal/roundtrip", base_topic);
let stay_alive_topic = format!("{}/stay_alive", base_topic);
println!("Stay alive topic is {}", stay_alive_topic);
log(LogMessage::stay_alive, 0 ,0,"", &stay_alive_topic);
let mqtt_connected_event_received_copy = mqtt_connected_event_received.clone();
let mqtt_connected_event_ok_copy = mqtt_connected_event_ok.clone();
let stay_alive_topic_copy = stay_alive_topic.clone();
let round_trip_topic_copy = round_trip_topic.clone();
let round_trip_ok_copy = round_trip_ok.clone();
println!(
"Connecting mqtt {} with id {}",
mqtt_url,
mqtt_client_config.client_id.unwrap_or("not set")
);
let client_id = mqtt_client_config.client_id.unwrap_or("not set");
log(LogMessage::mqtt_info, 0 ,0,client_id, &mqtt_url);
let mut client = EspMqttClient::new_cb(&mqtt_url, &mqtt_client_config, move |event| {
let payload = event.payload();
match payload {
@@ -987,10 +965,10 @@ impl PlantCtrlBoard<'_> {
} else if topic.eq(stay_alive_topic_copy.as_str()) {
let value =
data.eq_ignore_ascii_case("true") || data.eq_ignore_ascii_case("1");
println!("Received stay alive with value {}", value);
log(LogMessage::mqtt_stay_alive_rec, 0 ,0,&data, "");
STAY_ALIVE.store(value, std::sync::atomic::Ordering::Relaxed);
} else {
println!("Unknown topic recieved {}", topic);
log(LogMessage::unknown_topic, 0 ,0,"", &topic);
}
}
}
@@ -1327,6 +1305,38 @@ impl PlantHal {
pub fn create() -> Result<Mutex<PlantCtrlBoard<'static>>> {
let peripherals = Peripherals::take()?;
let mut clock = PinDriver::input_output(peripherals.pins.gpio15.downgrade())?;
clock.set_pull(Pull::Floating).unwrap();
let mut latch = PinDriver::input_output(peripherals.pins.gpio3.downgrade())?;
latch.set_pull(Pull::Floating).unwrap();
let mut data = PinDriver::input_output(peripherals.pins.gpio23.downgrade())?;
data.set_pull(Pull::Floating).unwrap();
let shift_register = ShiftRegister40::new(clock.into(), latch.into(), data.into());
//disable all
for mut pin in shift_register.decompose() {
pin.set_low().unwrap();
}
let awake = &mut shift_register.decompose()[AWAKE];
awake.set_high()?;
let charging = &mut shift_register.decompose()[CHARGING];
charging.set_high()?;
let ms0 = &mut shift_register.decompose()[MS_0];
ms0.set_low()?;
let ms1 = &mut shift_register.decompose()[MS_1];
ms1.set_low()?;
let ms2 = &mut shift_register.decompose()[MS_2];
ms2.set_low()?;
let ms3 = &mut shift_register.decompose()[MS_3];
ms3.set_low()?;
let ms4 = &mut shift_register.decompose()[MS_4];
ms4.set_high()?;
println!("Init battery driver");
let mut battery_driver = Bq34z100g1Driver {
i2c: MutexDevice::new(&I2C_DRIVER),
@@ -1345,6 +1355,10 @@ impl PlantHal {
)
};
let mut one_wire_pin = PinDriver::input_output_od(peripherals.pins.gpio18)?;
one_wire_pin.set_pull(Pull::Floating).unwrap();
let rtc_time = rtc.datetime();
match rtc_time {
OkStd(tt) => {
@@ -1363,33 +1377,6 @@ impl PlantHal {
}
}
let mut clock = PinDriver::input_output(peripherals.pins.gpio15.downgrade())?;
clock.set_pull(Pull::Floating).unwrap();
let mut latch = PinDriver::input_output(peripherals.pins.gpio3.downgrade())?;
latch.set_pull(Pull::Floating).unwrap();
let mut data = PinDriver::input_output(peripherals.pins.gpio23.downgrade())?;
data.set_pull(Pull::Floating).unwrap();
let shift_register = ShiftRegister40::new(clock.into(), latch.into(), data.into());
for mut pin in shift_register.decompose() {
pin.set_low().unwrap();
}
let mut one_wire_pin = PinDriver::input_output_od(peripherals.pins.gpio18)?;
one_wire_pin.set_pull(Pull::Floating).unwrap();
//disable all
let ms0 = &mut shift_register.decompose()[MS_0];
ms0.set_low()?;
let ms1 = &mut shift_register.decompose()[MS_1];
ms1.set_low()?;
let ms2 = &mut shift_register.decompose()[MS_2];
ms2.set_low()?;
let ms3 = &mut shift_register.decompose()[MS_3];
ms3.set_low()?;
let ms4 = &mut shift_register.decompose()[MS_4];
ms4.set_high()?;
//init,reset rtc memory depending on cause
let mut init_rtc_store: bool = false;
let mut to_config_mode: bool = false;
@@ -1430,13 +1417,13 @@ impl PlantHal {
init_rtc_store = true
},
};
println!("Reset due to {:?} requires rtc clear {} and force config mode {}", reasons, init_rtc_store, to_config_mode);
log(LogMessage::reset_reason, init_rtc_store as u32, to_config_mode as u32, "",&format!("{reasons:?}"));
if init_rtc_store {
unsafe {
LAST_WATERING_TIMESTAMP = [0; PLANT_COUNT];
CONSECUTIVE_WATERING_PLANT = [0; PLANT_COUNT];
LOW_VOLTAGE_DETECTED = false;
BUFFER = ConstGenericRingBuffer::<heapless::String<ENTRY_SIZE>, BUFFER_SIZE>::new();
crate::log::init();
RESTART_TO_CONF = to_config_mode;
};
} else {
@@ -1444,12 +1431,8 @@ impl PlantHal {
if to_config_mode{
RESTART_TO_CONF = true;
}
println!("Current restart to conf mode{:?}", RESTART_TO_CONF);
println!(
"Current low voltage detection is {:?}",
LOW_VOLTAGE_DETECTED
);
log(LogMessage::restart_to_config, RESTART_TO_CONF as u32, 0, "","");
log(LogMessage::low_voltage, LOW_VOLTAGE_DETECTED as u32, 0, "","");
for i in 0..PLANT_COUNT {
println!(
"LAST_WATERING_TIMESTAMP[{}] = UTC {}",
@@ -1473,8 +1456,6 @@ impl PlantHal {
Option::<AnyInputPin>::None,
)?;
println!("Channel config start");
counter_unit1.channel_config(
PcntChannel::Channel0,
PinIndex::Pin0,
@@ -1489,8 +1470,6 @@ impl PlantHal {
},
)?;
println!("Wifi start");
let sys_loop = EspSystemEventLoop::take()?;
let nvs = EspDefaultNvsPartition::take()?;
let wifi_driver = EspWifi::new(peripherals.modem, sys_loop, Some(nvs))?;
@@ -1525,15 +1504,15 @@ impl PlantHal {
let one_wire_bus = OneWire::new(one_wire_pin)
.map_err(|err| -> anyhow::Error { anyhow!("Missing attribute: {:?}", err) })?;
println!("After stuff");
let status = print_battery(&mut battery_driver);
if status.is_err() {
println!("Error communicating with battery!! {:?}", status.err());
} else {
println!("Managed to comunnicate with battery");
match status {
OkStd(_) => {
},
Err(err) => {
log(LogMessage::battery_communication_error, 0 as u32, 0, "",&format!("{err:?})"));
},
}
let shift_register_enable_invert = PinDriver::output(peripherals.pins.gpio21.downgrade())?;
let rv = Mutex::new(PlantCtrlBoard {

View File

@@ -9,6 +9,7 @@ use crate::{
};
use anyhow::bail;
use chrono::DateTime;
use esp_idf_sys::{esp_set_time_from_rtc, settimeofday, timeval, vTaskDelay};
use core::result::Result::Ok;
use embedded_svc::http::Method;
use esp_idf_hal::delay::Delay;
@@ -24,11 +25,6 @@ struct SSIDList<'a> {
ssids: Vec<&'a String<32>>,
}
#[derive(Serialize, Debug)]
struct FileList {
file: Vec<FileInfo>,
}
#[derive(Serialize, Debug)]
struct LoadData<'a> {
rtc: &'a str,
@@ -64,6 +60,12 @@ fn write_time(
let time: SetTime = serde_json::from_slice(&actual_data)?;
let parsed = DateTime::parse_from_rfc3339(time.time).map_err(|err| anyhow::anyhow!(err))?;
let mut board = BOARD_ACCESS.lock().unwrap();
let now = timeval {
tv_sec: parsed.to_utc().timestamp(),
tv_usec: 0
};
unsafe { settimeofday(&now, core::ptr::null_mut()) };
board.set_rtc_time(&parsed.to_utc())?;
anyhow::Ok(None)
}
@@ -440,6 +442,8 @@ pub fn httpd(reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
})
.unwrap();
unsafe { vTaskDelay(1) };
let reboot_now_for_exit = reboot_now.clone();
server
.fn_handler("/exit", Method::Post, move |_| {
@@ -462,19 +466,16 @@ pub fn httpd(reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
let mut buffer: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE];
let mut total_read: usize = 0;
loop {
unsafe { vTaskDelay(1) };
let read = std::io::Read::read(&mut file_handle, &mut buffer)?;
total_read += read;
println!(
"sending {read} bytes of {total_read} for file {}",
&filename
);
let to_write = &buffer[0..read];
response.write(to_write)?;
println!("wrote {read} bytes of {total_read} for file {filename}");
if read == 0 {
break;
}
}
println!("wrote {total_read} for file {filename}");
drop(file_handle);
response.flush()?;
}
@@ -588,6 +589,7 @@ pub fn httpd(reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
anyhow::Ok(())
})
.unwrap();
unsafe { vTaskDelay(1) };
server
.fn_handler("/", Method::Get, move |request| {
let mut response = request.into_ok_response()?;