Merge branch 'develop' of ssh://git.mannheim.ccc.de:1337/C3MA/PlantCtrl into develop

This commit is contained in:
2026-03-18 01:25:29 +01:00
10 changed files with 225 additions and 129 deletions

View File

@@ -18,7 +18,7 @@ pub trait BatteryInteraction {
async fn reset(&mut self) -> FatResult<()>;
}
#[derive(Debug, Serialize)]
#[derive(Debug, Serialize, Copy, Clone)]
pub struct BatteryInfo {
pub voltage_milli_volt: u32,
pub average_current_milli_ampere: i32,

View File

@@ -320,16 +320,16 @@ impl Esp<'_> {
let ntp_addrs = stack
.dns_query(NTP_SERVER, DnsQueryType::A)
.await
.expect("Failed to resolve DNS");
if ntp_addrs.is_empty() {
.await;
if ntp_addrs.is_err() {
bail!("Failed to resolve DNS");
}
info!("NTP server: {ntp_addrs:?}");
let ntp = ntp_addrs.unwrap()[0];
info!("NTP server: {ntp:?}");
let mut counter = 0;
loop {
let addr: IpAddr = ntp_addrs[0].into();
let addr: IpAddr = ntp.into();
let timeout = get_time(SocketAddr::from((addr, 123)), &socket, context)
.with_timeout(Duration::from_millis((_max_wait_ms / 10) as u64))
.await;

View File

@@ -357,6 +357,7 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
}
async fn measure_moisture_hz(&mut self) -> FatResult<Moistures> {
self.can_power.set_high();
Timer::after_millis(500).await;
let config = self.twai_config.take().expect("twai config not set");
let mut twai = config.into_async().start();
@@ -364,7 +365,7 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
let mut moistures = Moistures::default();
let _ = wait_for_can_measurements(&mut twai, &mut moistures)
.with_timeout(Duration::from_millis(5000))
.with_timeout(Duration::from_millis(1000))
.await;
let config = twai.stop().into_blocking();
@@ -374,6 +375,74 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
Ok(moistures)
}
async fn detect_sensors(&mut self, request: Detection) -> FatResult<Detection> {
self.can_power.set_high();
Timer::after_millis(500).await;
let config = self.twai_config.take().expect("twai config not set");
let mut twai = config.into_async().start();
Timer::after_millis(1000).await;
info!("Sending info messages now");
// Send a few test messages per potential sensor node
for plant in 0..PLANT_COUNT {
for sensor in [Sensor::A, Sensor::B] {
let detect = if sensor == Sensor::A {
request.plant[plant].sensor_a
} else {
request.plant[plant].sensor_b
};
if !detect {
continue;
}
let target = StandardId::new(plant_id(
IDENTIFY_CMD_OFFSET,
sensor.into(),
(plant + 1) as u16,
))
.context(">> Could not create address for sensor! (plant: {}) <<")?;
let can_buffer = [0_u8; 0];
info!(
"Sending test message to plant {} sensor {sensor:?} with id {}",
plant + 1,
target.as_raw()
);
if let Some(frame) = EspTwaiFrame::new(target, &can_buffer) {
// Try a few times; we intentionally ignore rx here and rely on stub logic
let resu = twai
.transmit_async(&frame)
.with_timeout(Duration::from_millis(500))
.await;
match resu {
Ok(_) => {}
Err(err) => {
info!(
"Error sending test message to plant {} sensor {sensor:?}: {err:?}",
plant + 1
);
}
}
} else {
info!("Error building CAN frame");
}
}
}
let mut moistures = Moistures::default();
let _ = wait_for_can_measurements(&mut twai, &mut moistures)
.with_timeout(Duration::from_millis(3000))
.await;
let config = twai.stop().into_blocking();
self.twai_config.replace(config);
self.can_power.set_low();
let result = moistures.into();
info!("Autodetection result: {result:?}");
Ok(result)
}
async fn general_fault(&mut self, enable: bool) {
hold_disable(23);
self.general_fault.set_level(enable.into());
@@ -443,73 +512,6 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
}
Ok(())
}
async fn detect_sensors(&mut self, request: Detection) -> FatResult<Detection> {
self.can_power.set_high();
let config = self.twai_config.take().expect("twai config not set");
let mut twai = config.into_async().start();
Timer::after_millis(1000).await;
info!("Sending info messages now");
// Send a few test messages per potential sensor node
for plant in 0..PLANT_COUNT {
for sensor in [Sensor::A, Sensor::B] {
let detect = if sensor == Sensor::A {
request.plant[plant].sensor_a
} else {
request.plant[plant].sensor_b
};
if !detect {
continue;
}
let target = StandardId::new(plant_id(
IDENTIFY_CMD_OFFSET,
sensor.into(),
(plant + 1) as u16,
))
.context(">> Could not create address for sensor! (plant: {}) <<")?;
let can_buffer = [0_u8; 0];
info!(
"Sending test message to plant {} sensor {sensor:?} with id {}",
plant + 1,
target.as_raw()
);
if let Some(frame) = EspTwaiFrame::new(target, &can_buffer) {
// Try a few times; we intentionally ignore rx here and rely on stub logic
let resu = twai
.transmit_async(&frame)
.with_timeout(Duration::from_millis(3000))
.await;
match resu {
Ok(_) => {}
Err(err) => {
info!(
"Error sending test message to plant {} sensor {sensor:?}: {err:?}",
plant + 1
);
}
}
} else {
info!("Error building CAN frame");
}
}
}
let mut moistures = Moistures::default();
let _ = wait_for_can_measurements(&mut twai, &mut moistures)
.with_timeout(Duration::from_millis(3000))
.await;
let config = twai.stop().into_blocking();
self.twai_config.replace(config);
self.can_power.set_low();
let result = moistures.into();
info!("Autodetection result: {result:?}");
Ok(result)
}
}
async fn wait_for_can_measurements(