Fix incorrect spawn function call and update dependencies

- Corrected usage of `spawner.spawn` by fixing misplaced error propagation.
- Updated `Cargo.lock` with new and upgraded dependencies, including `base64`, `darling`, and `smoltcp` upgrades.
This commit is contained in:
2026-04-26 19:46:46 +02:00
parent b8f01f0de9
commit cc92c82ac9
7 changed files with 696 additions and 455 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -46,42 +46,34 @@ canapi = { path = "../../Shared/canapi" }
# Platform and ESP-specific runtime/boot/runtime utilities
log = "0.4.28"
esp-bootloader-esp-idf = { version = "0.4.0", features = ["esp32c6", "log-04"] }
esp-hal = { version = "1.0.0", features = ["esp32c6", "log-04"] }
esp-rtos = { version = "0.2.0", features = ["esp32c6", "embassy", "esp-radio"] }
esp-backtrace = { version = "0.18.1", features = ["esp32c6", "panic-handler", "println", "colors", "custom-halt"] }
esp-println = { version = "0.16.1", features = ["esp32c6", "log-04", "auto"] }
esp-storage = { version = "0.8.1", features = ["esp32c6"] }
esp-radio = { version = "0.17.0", features = ["esp32c6", "log-04", "wifi", "unstable"] }
esp-alloc = { version = "0.9.0", features = ["esp32c6", "internal-heap-stats"] }
esp-bootloader-esp-idf = { version = "0.5.0", features = ["esp32c6", "log-04"] }
esp-hal = { version = "1.1.0", features = ["esp32c6", "log-04"] }
esp-rtos = { version = "0.3.0", features = ["esp32c6", "embassy", "esp-radio"] }
esp-backtrace = { version = "0.19.0", features = ["esp32c6", "panic-handler", "println", "colors", "custom-halt"] }
esp-println = { version = "0.17.0", features = ["esp32c6", "log-04", "auto"] }
esp-storage = { version = "0.9.0", features = ["esp32c6"] }
esp-radio = { version = "0.18.0", features = ["esp32c6", "log-04", "wifi", "unstable"] }
esp-alloc = { version = "0.10.0", features = ["esp32c6", "internal-heap-stats"] }
# Async runtime (Embassy core)
embassy-executor = { version = "0.9.1", features = ["log", "nightly"] }
embassy-time = { version = "0.5.0", features = ["log"], default-features = false }
embassy-sync = { version = "0.7.2", features = ["log"] }
embassy-executor = { version = "0.10.0", features = ["log", "nightly"] }
embassy-time = { version = "0.5.1", features = ["log"], default-features = false }
embassy-sync = { version = "0.8.0", features = ["log"] }
# Networking and protocol stacks
embassy-net = { version = "0.7.1", features = [
"dhcpv4",
"log",
"medium-ethernet",
"tcp",
"udp",
"proto-ipv4",
"dns"
] }
embassy-net = { version = "0.8.0", features = ["dhcpv4", "log", "medium-ethernet", "tcp", "udp", "proto-ipv4", "dns", "proto-ipv6"] }
sntpc = { version = "0.6.1", default-features = false, features = ["log", "embassy-socket", "embassy-socket-ipv6"] }
edge-dhcp = "0.6.0"
edge-nal = "0.5.0"
edge-nal-embassy = "0.6.0"
edge-http = { version = "0.6.1", features = ["log"] }
edge-dhcp = "0.7.0"
edge-nal = "0.6.0"
edge-nal-embassy = "0.8.1"
edge-http = { version = "0.7.0", features = ["log"] }
esp32c6 = { version = "0.22.0" }
esp32c6 = { version = "0.23.2" }
# Hardware abstraction traits and HAL adapters
embedded-hal = "1.0.0"
embedded-storage = "0.3.1"
embassy-embedded-hal = "0.5.0"
embassy-embedded-hal = "0.6.0"
embedded-can = "0.4.1"
nb = "1.1.0"
@@ -118,12 +110,6 @@ async-trait = "0.1.89"
option-lock = { version = "0.3.1", default-features = false }
measurements = "0.11.1"
# Project-specific
mcutie = { version = "0.3.0", default-features = false, features = ["log", "homeassistant"] }
no-panic = "0.1.36"
[patch.crates-io]
mcutie = { git = 'https://github.com/empirephoenix/mcutie.git' }
#bq34z100 = { path = "../../bq34z100_rust" }
[build-dependencies]

View File

@@ -15,7 +15,7 @@ use core::sync::atomic::Ordering;
use embassy_executor::Spawner;
use embassy_net::dns::DnsQueryType;
use embassy_net::udp::{PacketMetadata, UdpSocket};
use embassy_net::{DhcpConfig, Ipv4Cidr, Runner, Stack, StackResources, StaticConfigV4};
use embassy_net::{DhcpConfig, IpAddress, Ipv4Cidr, Runner, Stack, StackResources, StaticConfigV4};
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::mutex::Mutex;
use embassy_sync::once_lock::OnceLock;
@@ -34,17 +34,17 @@ use esp_hal::system::software_reset;
use esp_hal::uart::Uart;
use esp_hal::Blocking;
use esp_println::println;
use esp_radio::wifi::{
AccessPointConfig, AccessPointInfo, AuthMethod, ClientConfig, ModeConfig, ScanConfig,
ScanTypeConfig, WifiController, WifiDevice, WifiStaState,
};
use esp_radio::wifi::ap::{AccessPointConfig, AccessPointInfo};
use esp_radio::wifi::scan::{ScanConfig, ScanTypeConfig};
use esp_radio::wifi::sta::StationConfig;
use esp_radio::wifi::{AuthenticationMethod, Config, Interface, WifiController};
use log::{error, info, warn};
use mcutie::{
Error, McutieBuilder, McutieReceiver, McutieTask, MqttMessage, PublishDisplay, Publishable,
QoS, Topic,
};
// pub use mcutie::{
// Error, McutieBuilder, McutieReceiver, McutieTask, MqttMessage, PublishDisplay, Publishable,
// QoS, Topic,
// };
use portable_atomic::AtomicBool;
use sntpc::{get_time, NtpContext, NtpTimestampGenerator};
use sntpc::{get_time, NtpContext, NtpTimestampGenerator, NtpUdpSocket};
#[esp_hal::ram(unstable(rtc_fast), unstable(persistent))]
static mut LAST_WATERING_TIMESTAMP: [i64; PLANT_COUNT] = [0; PLANT_COUNT];
@@ -69,6 +69,39 @@ struct Timestamp {
stamp: DateTime<Utc>,
}
struct EmbassyNtpSocket<'a, 'b> {
socket: &'a UdpSocket<'b>,
}
impl<'a, 'b> EmbassyNtpSocket<'a, 'b> {
fn new(socket: &'a UdpSocket<'b>) -> Self {
Self { socket }
}
}
impl NtpUdpSocket for EmbassyNtpSocket<'_, '_> {
async fn send_to(&self, buf: &[u8], addr: SocketAddr) -> sntpc::Result<usize> {
self.socket
.send_to(buf, addr)
.await
.map_err(|_| sntpc::Error::Network)?;
Ok(buf.len())
}
async fn recv_from(&self, buf: &mut [u8]) -> sntpc::Result<(usize, SocketAddr)> {
let (len, metadata) = self
.socket
.recv_from(buf)
.await
.map_err(|_| sntpc::Error::Network)?;
let addr = match metadata.endpoint.addr {
IpAddress::Ipv4(ip) => IpAddr::V4(ip),
IpAddress::Ipv6(ip) => IpAddr::V6(ip),
};
Ok((len, SocketAddr::new(addr, metadata.endpoint.port)))
}
}
// Minimal esp-idf equivalent for gpio_hold on esp32c6 via ROM functions
extern "C" {
fn gpio_pad_hold(gpio_num: u32);
@@ -103,8 +136,8 @@ pub struct Esp<'a> {
pub savegame: SavegameManager,
pub rng: Rng,
//first starter (ap or sta will take these)
pub interface_sta: Option<WifiDevice<'static>>,
pub interface_ap: Option<WifiDevice<'static>>,
pub interface_sta: Option<Interface<'static>>,
pub interface_ap: Option<Interface<'static>>,
pub controller: Arc<Mutex<CriticalSectionRawMutex, WifiController<'static>>>,
pub boot_button: Input<'a>,
@@ -248,6 +281,7 @@ impl Esp<'_> {
socket.bind(123).context("Could not bind UDP socket")?;
let context = NtpContext::new(Timestamp::default());
let ntp_socket = EmbassyNtpSocket::new(&socket);
let ntp_addrs = stack
.dns_query(NTP_SERVER, DnsQueryType::A)
@@ -263,7 +297,7 @@ impl Esp<'_> {
let mut counter = 0;
loop {
let addr: IpAddr = ntp.into();
let timeout = get_time(SocketAddr::from((addr, 123)), &socket, context)
let timeout = get_time(SocketAddr::from((addr, 123)), &ntp_socket, context)
.with_timeout(Duration::from_millis((_max_wait_ms / 10) as u64))
.await;
@@ -291,10 +325,10 @@ impl Esp<'_> {
let mut lock = self.controller.try_lock()?;
info!("start wifi scan lock");
let scan_config = ScanConfig::default().with_scan_type(ScanTypeConfig::Active {
min: Default::default(),
max: Default::default(),
min: esp_hal::time::Duration::from_millis(0),
max: esp_hal::time::Duration::from_millis(0),
});
let rv = lock.scan_with_config_async(scan_config).await?;
let rv = lock.scan_async(&scan_config).await?;
info!("end wifi scan lock");
Ok(rv)
}
@@ -382,15 +416,13 @@ impl Esp<'_> {
let stack = mk_static!(Stack, stack);
let client_config =
ModeConfig::AccessPoint(AccessPointConfig::default().with_ssid(ssid.clone()));
Config::AccessPoint(AccessPointConfig::default().with_ssid(ssid.clone()));
self.controller.lock().await.set_config(&client_config)?;
println!("start new");
self.controller.lock().await.start()?;
println!("start net task");
spawner.spawn(net_task(runner)).ok();
spawner.spawn(net_task(runner)?);
println!("run dhcp");
spawner.spawn(run_dhcp(*stack, gw_ip_addr)).ok();
spawner.spawn(run_dhcp(*stack, gw_ip_addr)?);
loop {
if stack.is_link_up() {
@@ -450,52 +482,28 @@ impl Esp<'_> {
);
let stack = mk_static!(Stack, stack);
let client_config = ClientConfig::default()
let auth_method = if password.is_empty() {
AuthenticationMethod::None
} else {
AuthenticationMethod::Wpa2Personal
};
let client_config = StationConfig::default()
.with_ssid(ssid)
.with_auth_method(AuthMethod::Wpa2Personal)
.with_auth_method(auth_method)
.with_password(password);
self.controller
.lock()
.await
.set_config(&ModeConfig::Client(client_config))?;
spawner.spawn(net_task(runner)).ok();
self.controller.lock().await.start_async().await?;
let res = async {
loop {
let state = esp_radio::wifi::sta_state();
if state == WifiStaState::Started {
self.controller.lock().await.connect()?;
break;
}
Timer::after(Duration::from_millis(500)).await;
}
Ok::<(), FatError>(())
}
.with_timeout(Duration::from_millis(max_wait as u64 * 1000))
.await;
if res.is_err() {
bail!("Timeout waiting for wifi sta ready")
}
let res = async {
loop {
let state = esp_radio::wifi::sta_state();
if state == WifiStaState::Connected {
break;
}
Timer::after(Duration::from_millis(500)).await;
}
Ok::<(), FatError>(())
}
.with_timeout(Duration::from_millis(max_wait as u64 * 1000))
.await;
if res.is_err() {
bail!("Timeout waiting for wifi sta connected")
}
.set_config(&Config::Station(client_config))?;
spawner.spawn(net_task(runner)?);
self.controller
.lock()
.await
.connect_async()
.with_timeout(Duration::from_millis(max_wait as u64 * 1000))
.await
.context("Timeout waiting for wifi sta connected")??;
let res = async {
while !stack.is_link_up() {
@@ -670,62 +678,62 @@ impl Esp<'_> {
let round_trip_topic = format!("{base_topic}/internal/roundtrip");
let stay_alive_topic = format!("{base_topic}/stay_alive");
let mut builder: McutieBuilder<'_, String, PublishDisplay<String, &str>, 0> =
McutieBuilder::new(stack, "plant ctrl", mqtt_url);
if let (Some(mqtt_user), Some(mqtt_password)) = (
network_config.mqtt_user.as_ref(),
network_config.mqtt_password.as_ref(),
) {
builder = builder.with_authentication(mqtt_user, mqtt_password);
info!("With authentification");
}
let lwt = Topic::General(last_will_topic);
let lwt = mk_static!(Topic<String>, lwt);
let lwt = lwt.with_display("lost").retain(true).qos(QoS::AtLeastOnce);
builder = builder.with_last_will(lwt);
//TODO make configurable
builder = builder.with_device_id("plantctrl");
let builder: McutieBuilder<'_, String, PublishDisplay<String, &str>, 2> = builder
.with_subscriptions([
Topic::General(round_trip_topic.clone()),
Topic::General(stay_alive_topic.clone()),
]);
let keep_alive = Duration::from_secs(60 * 60 * 2).as_secs() as u16;
let (receiver, task) = builder.build(keep_alive);
spawner.spawn(mqtt_incoming_task(
receiver,
round_trip_topic.clone(),
stay_alive_topic.clone(),
))?;
spawner.spawn(mqtt_runner(task))?;
log(LogMessage::StayAlive, 0, 0, "", &stay_alive_topic);
log(LogMessage::MqttInfo, 0, 0, "", mqtt_url);
// let mut builder: McutieBuilder<'_, String, PublishDisplay<String, &str>, 0> =
// McutieBuilder::new(stack, "plant ctrl", mqtt_url);
// if let (Some(mqtt_user), Some(mqtt_password)) = (
// network_config.mqtt_user.as_ref(),
// network_config.mqtt_password.as_ref(),
// ) {
// builder = builder.with_authentication(mqtt_user, mqtt_password);
// info!("With authentification");
// }
//
// let lwt = Topic::General(last_will_topic);
// let lwt = mk_static!(Topic<String>, lwt);
// let lwt = lwt.with_display("lost").retain(true).qos(QoS::AtLeastOnce);
// builder = builder.with_last_will(lwt);
// //TODO make configurable
// builder = builder.with_device_id("plantctrl");
//
// let builder: McutieBuilder<'_, String, PublishDisplay<String, &str>, 2> = builder
// .with_subscriptions([
// Topic::General(round_trip_topic.clone()),
// Topic::General(stay_alive_topic.clone()),
// ]);
//
// let keep_alive = Duration::from_secs(60 * 60 * 2).as_secs() as u16;
// let (receiver, task) = builder.build(keep_alive);
//
// spawner.spawn(mqtt_incoming_task(
// receiver,
// round_trip_topic.clone(),
// stay_alive_topic.clone(),
// )?);
// spawner.spawn(mqtt_runner(task)?);
//
// log(LogMessage::StayAlive, 0, 0, "", &stay_alive_topic);
//
// log(LogMessage::MqttInfo, 0, 0, "", mqtt_url);
//
let mqtt_timeout = 15000;
let res = async {
while !MQTT_CONNECTED_EVENT_RECEIVED.load(Ordering::Relaxed) {
crate::hal::PlantHal::feed_watchdog();
Timer::after(Duration::from_millis(100)).await;
}
Ok::<(), FatError>(())
}
.with_timeout(Duration::from_millis(mqtt_timeout as u64))
.await;
if res.is_err() {
bail!("Timeout waiting MQTT connect event")
}
let _ = Topic::General(round_trip_topic.clone())
.with_display("online_text")
.publish()
.await;
// let res = async {
// while !MQTT_CONNECTED_EVENT_RECEIVED.load(Ordering::Relaxed) {
// crate::hal::PlantHal::feed_watchdog();
// Timer::after(Duration::from_millis(100)).await;
// }
// Ok::<(), FatError>(())
// }
// .with_timeout(Duration::from_millis(mqtt_timeout as u64))
// .await;
//
// if res.is_err() {
// bail!("Timeout waiting MQTT connect event")
// }
//
// let _ = Topic::General(round_trip_topic.clone())
// .with_display("online_text")
// .publish()
// .await;
let res = async {
while !MQTT_ROUND_TRIP_RECEIVED.load(Ordering::Relaxed) {
@@ -759,36 +767,36 @@ impl Esp<'_> {
let full_topic = format!("{base_topic}{subtopic}");
loop {
let result = Topic::General(full_topic.as_str())
.with_display(message)
.retain(true)
.publish()
.await;
match result {
Ok(()) => return Ok(()),
Err(err) => {
let retry = match err {
Error::IOError => false,
Error::TimedOut => true,
Error::TooLarge => false,
Error::PacketError => false,
Error::Invalid => false,
};
if !retry {
bail!(
"Error during mqtt send on topic {} with message {:#?} error is {:?}",
&full_topic,
message,
err
);
}
info!(
"Retransmit for {} with message {:#?} error is {:?} retrying {}",
&full_topic, message, err, retry
);
Timer::after(Duration::from_millis(100)).await;
}
}
// let result = Topic::General(full_topic.as_str())
// .with_display(message)
// .retain(true)
// .publish()
// .await;
// match result {
// Ok(()) => return Ok(()),
// Err(err) => {
// let retry = match err {
// Error::IOError => false,
// Error::TimedOut => true,
// Error::TooLarge => false,
// Error::PacketError => false,
// Error::Invalid => false,
// };
// if !retry {
// bail!(
// "Error during mqtt send on topic {} with message {:#?} error is {:?}",
// &full_topic,
// message,
// err
// );
// }
// info!(
// "Retransmit for {} with message {:#?} error is {:?} retrying {}",
// &full_topic, message, err, retry
// );
// Timer::after(Duration::from_millis(100)).await;
// }
// }
}
}
pub(crate) async fn mqtt_publish(&mut self, subtopic: &str, message: &str) {
@@ -813,60 +821,59 @@ impl Esp<'_> {
}
#[embassy_executor::task]
async fn mqtt_runner(
task: McutieTask<'static, String, PublishDisplay<'static, String, &'static str>, 2>,
async fn mqtt_runner(//task: McutieTask<'static, String, PublishDisplay<'static, String, &'static str>, 2>,
) {
task.run().await;
//task.run().await;
}
#[embassy_executor::task]
async fn mqtt_incoming_task(
receiver: McutieReceiver,
//receiver: McutieReceiver,
round_trip_topic: String,
stay_alive_topic: String,
) {
loop {
let message = receiver.receive().await;
match message {
MqttMessage::Connected => {
info!("Mqtt connected");
MQTT_CONNECTED_EVENT_RECEIVED.store(true, Ordering::Relaxed);
}
MqttMessage::Publish(topic, payload) => match topic {
Topic::DeviceType(_type_topic) => {}
Topic::Device(_device_topic) => {}
Topic::General(topic) => {
let subtopic = topic.as_str();
if subtopic.eq(round_trip_topic.as_str()) {
MQTT_ROUND_TRIP_RECEIVED.store(true, Ordering::Relaxed);
} else if subtopic.eq(stay_alive_topic.as_str()) {
let value = payload.eq_ignore_ascii_case("true".as_ref())
|| payload.eq_ignore_ascii_case("1".as_ref());
let a = match value {
true => 1,
false => 0,
};
log(LogMessage::MqttStayAliveRec, a, 0, "", "");
MQTT_STAY_ALIVE.store(value, Ordering::Relaxed);
} else {
log(LogMessage::UnknownTopic, 0, 0, "", &topic);
}
}
},
MqttMessage::Disconnected => {
MQTT_CONNECTED_EVENT_RECEIVED.store(false, Ordering::Relaxed);
info!("Mqtt disconnected");
}
MqttMessage::HomeAssistantOnline => {
info!("Home assistant is online");
}
}
//let message = receiver.receive().await;
// match message {
// MqttMessage::Connected => {
// info!("Mqtt connected");
// MQTT_CONNECTED_EVENT_RECEIVED.store(true, Ordering::Relaxed);
// }
// MqttMessage::Publish(topic, payload) => match topic {
// Topic::DeviceType(_type_topic) => {}
// Topic::Device(_device_topic) => {}
// Topic::General(topic) => {
// let subtopic = topic.as_str();
//
// if subtopic.eq(round_trip_topic.as_str()) {
// MQTT_ROUND_TRIP_RECEIVED.store(true, Ordering::Relaxed);
// } else if subtopic.eq(stay_alive_topic.as_str()) {
// let value = payload.eq_ignore_ascii_case("true".as_ref())
// || payload.eq_ignore_ascii_case("1".as_ref());
// let a = match value {
// true => 1,
// false => 0,
// };
// log(LogMessage::MqttStayAliveRec, a, 0, "", "");
// MQTT_STAY_ALIVE.store(value, Ordering::Relaxed);
// } else {
// log(LogMessage::UnknownTopic, 0, 0, "", &topic);
// }
// }
// },
// MqttMessage::Disconnected => {
// MQTT_CONNECTED_EVENT_RECEIVED.store(false, Ordering::Relaxed);
// info!("Mqtt disconnected");
// }
// MqttMessage::HomeAssistantOnline => {
// info!("Home assistant is online");
// }
// }
}
}
#[embassy_executor::task(pool_size = 2)]
async fn net_task(mut runner: Runner<'static, WifiDevice<'static>>) {
async fn net_task(mut runner: Runner<'static, Interface<'static>>) {
runner.run().await;
}

View File

@@ -95,7 +95,6 @@ use esp_hal::system::reset_reason;
use esp_hal::timer::timg::{MwdtStage, TimerGroup, Wdt};
use esp_hal::uart::Uart;
use esp_hal::Blocking;
use esp_radio::{init, Controller};
use esp_storage::FlashStorage;
use log::{info, warn};
use portable_atomic::AtomicBool;
@@ -280,19 +279,11 @@ impl PlantHal {
let wake_gpio1 = peripherals.GPIO1;
let rng = Rng::new();
let esp_wifi_ctrl = &*mk_static!(
Controller<'static>,
init().map_err(|e| FatError::String {
error: format!("Could not init wifi controller: {:?}", e)
})?
);
let (controller, interfaces) =
esp_radio::wifi::new(esp_wifi_ctrl, peripherals.WIFI, Default::default()).map_err(
|e| FatError::String {
error: format!("Could not init wifi: {:?}", e),
},
)?;
let (controller, interfaces) = esp_radio::wifi::new(peripherals.WIFI, Default::default())
.map_err(|e| FatError::String {
error: format!("Could not init wifi: {:?}", e),
})?;
let pcnt_module = Pcnt::new(peripherals.PCNT);
@@ -349,16 +340,13 @@ impl PlantHal {
.context("No OTA data partition found")?
);
let ota_data = mk_static!(
FlashRegion<RmwNorFlashStorage<&mut MutexFlashStorage>>,
ota_data.as_embedded_storage(mk_static!(
RmwNorFlashStorage<&mut MutexFlashStorage>,
RmwNorFlashStorage::new(flash_storage_2, mk_static!([u8; 4096], [0_u8; 4096]))
))
);
let mut ota_data = ota_data.as_embedded_storage(mk_static!(
RmwNorFlashStorage<&mut MutexFlashStorage>,
RmwNorFlashStorage::new(flash_storage_2, mk_static!([u8; 4096], [0_u8; 4096]))
));
let state_0 = ota_state(AppPartitionSubType::Ota0, ota_data);
let state_1 = ota_state(AppPartitionSubType::Ota1, ota_data);
let state_0 = ota_state(AppPartitionSubType::Ota0, &mut ota_data);
let state_1 = ota_state(AppPartitionSubType::Ota1, &mut ota_data);
let mut ota = Ota::new(ota_data, 2)?;
let running = get_current_slot(&pt, &mut ota)?;
let target = next_partition(running)?;
@@ -411,8 +399,8 @@ impl PlantHal {
error: "Uart creation failed".to_string(),
})?;
let ap = interfaces.ap;
let sta = interfaces.sta;
let ap = interfaces.access_point;
let sta = interfaces.station;
let mut esp = Esp {
savegame,
rng,

View File

@@ -317,7 +317,7 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> {
let reboot_now = Arc::new(AtomicBool::new(false));
let stack_val = stack.take();
if let Some(s) = stack_val {
spawner.spawn(http_server(reboot_now.clone(), s))?;
spawner.spawn(http_server(reboot_now.clone(), s)?);
} else {
bail!("Network stack missing, hard abort")
}
@@ -673,7 +673,7 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> {
if stay_alive {
let reboot_now = Arc::new(AtomicBool::new(false));
if let Some(s) = stack.take() {
spawner.spawn(http_server(reboot_now.clone(), s))?;
spawner.spawn(http_server(reboot_now.clone(), s)?);
wait_infinity(board, WaitType::MqttConfig, reboot_now.clone(), timezone).await;
} else {
bail!("Network Stack missing, hard abort");
@@ -690,7 +690,7 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> {
Timer::after_millis(5000).await;
board.board_hal.get_esp().set_restart_to_conf(false);
let _ = board
board
.board_hal
.deep_sleep(1000 * 1000 * 60 * deep_sleep_duration_minutes as u64)
.await;
@@ -1282,7 +1282,7 @@ use embassy_time::WithTimeout;
async fn main(spawner: Spawner) -> ! {
// intialize embassy
crate::log::INTERCEPTOR.init();
spawner.must_spawn(crate::log::log_task());
spawner.spawn(log::log_task().unwrap());
//force init here!
match BOARD_ACCESS.init(
PlantHal::create()

View File

@@ -3,11 +3,13 @@ use crate::fat_error::FatResult;
use crate::hal::Detection;
use crate::webserver::read_up_to_bytes_from_request;
use crate::{do_secure_pump, BOARD_ACCESS};
use alloc::borrow::ToOwned;
use alloc::string::{String, ToString};
use alloc::vec::Vec;
use chrono::DateTime;
use edge_http::io::server::Connection;
use edge_nal::io::{Read, Write};
use esp_radio::wifi::ap::AccessPointInfo;
use log::info;
use serde::{Deserialize, Serialize};
@@ -40,10 +42,10 @@ pub(crate) async fn wifi_scan<T, const N: usize>(
let mut board = BOARD_ACCESS.get().await.lock().await;
info!("start wifi scan");
let mut ssids: Vec<String> = Vec::new();
let scan_result = board.board_hal.get_esp().wifi_scan().await?;
let scan_result: Vec<AccessPointInfo> = board.board_hal.get_esp().wifi_scan().await?;
scan_result
.iter()
.for_each(|s| ssids.push(s.ssid.to_string()));
.for_each(|s| ssids.push(s.ssid.as_str().to_owned()));
let ssid_json = serde_json::to_string(&SSIDList { ssids })?;
info!("Sending ssid list {}", &ssid_json);
Ok(Some(ssid_json))