use esp_idf_svc::{eventloop::{EspSubscription, EspSystemEventLoop, System}, hal::modem::Modem, netif::IpEvent, nvs::{EspNvsPartition, NvsDefault}, sntp::{EspSntp, SyncStatus}, wifi::{AuthMethod, ClientConfiguration, Configuration, EspWifi, WifiEvent}}; use crate::{events::{EventBus, System as SystemNS}, properties::Variant, task::Task, time::Periodically}; use std::fmt::Debug; pub struct WifiTask { wifi: EspWifi<'static>, ntp: EspSntp<'static>, connection_check: Periodically, sys_loop: EspSystemEventLoop, wifi_sub: Option>, ip_sub: Option>, } impl Debug for WifiTask { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("WifiTask").finish() } } impl WifiTask { pub fn new(modem: Modem, sys_loop: EspSystemEventLoop, nvs: &EspNvsPartition) -> Self { log::info!("Installing wifi driver"); let wifi = EspWifi::new( modem, sys_loop.clone(), Some(nvs.clone()) ).unwrap(); WifiTask { wifi, ntp: EspSntp::new_default().unwrap(), connection_check: Periodically::new_every_n_seconds(1), sys_loop, wifi_sub: None, ip_sub: None, } } fn connect(&mut self) { log::info!("Connecting wifi"); let wifi_config = Configuration::Client(ClientConfiguration { ssid: "The Frequency".try_into().unwrap(), bssid: None, auth_method: AuthMethod::WPA2Personal, password: "thepasswordkenneth".try_into().unwrap(), channel: None, ..Default::default() }); self.wifi.set_configuration(&wifi_config).unwrap(); self.wifi.start().unwrap(); self.wifi.connect().unwrap(); } fn disconnect(&mut self) { log::info!("Disconnecting wifi"); self.wifi.disconnect().unwrap(); self.wifi.stop().unwrap(); } } impl Task for WifiTask { fn start(&mut self, bus: &mut EventBus) { log::info!("Starting wifi!"); let mut wifi_bus = bus.clone(); self.wifi_sub = Some(self.sys_loop.subscribe::( move |evt| { log::debug!("wifi event {:?}", evt); wifi_bus.set_property(SystemNS::NetworkOnline,false); }).unwrap()); let mut ip_bus = bus.clone(); self.ip_sub = Some(self.sys_loop.subscribe::(move |evt| { log::debug!("ip event {:?}", evt); match evt { IpEvent::DhcpIpAssigned(addr) => { ip_bus.set_property(SystemNS::IP, addr.ip().to_string()); ip_bus.set_property(SystemNS::Gateway, addr.gateway().to_string()); ip_bus.set_property(SystemNS::NetworkOnline, true); }, _ => () } }).unwrap()); self.connect(); } fn on_tick(&mut self, bus: &mut EventBus) { if self.connection_check.tick() { if bus.properties().get(SystemNS::NetworkOnline).unwrap() == Variant::Boolean(true) { match self.ntp.get_sync_status() { SyncStatus::Completed => bus.set_property(SystemNS::TimeSync, true), _ => bus.set_property(SystemNS::TimeSync, false) } } } } fn stop(&mut self, bus: &mut EventBus) { log::info!("Stopping wifi"); self.wifi_sub.take().unwrap(); self.ip_sub.take().unwrap(); self.disconnect(); bus.set_property(SystemNS::NetworkOnline, false); } }