2024-12-15 19:27:27 +01:00

105 lines
3.6 KiB
Rust

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<EspSubscription<'static, System>>,
ip_sub: Option<EspSubscription<'static, System>>,
}
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<NvsDefault>) -> 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::<WifiEvent, _>( 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::<IpEvent, _>(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);
}
}