diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 7c679f4..dc400e4 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -73,7 +73,7 @@ embedded-hal = "0.2.7" one-wire-bus = "0.1.1" anyhow = { version = "1.0.75", features = ["std", "backtrace"] } schemars = "0.8.16" -heapless = { version = "0.8.0", features = ["serde"] } +heapless = { version = "0.7", features = ["serde"] } serde_json = "1.0.108" #?bq34z100 required diff --git a/rust/src/main.rs b/rust/src/main.rs index bd3919d..da11c61 100644 --- a/rust/src/main.rs +++ b/rust/src/main.rs @@ -130,7 +130,7 @@ fn main() -> Result<()> { board.wifi_ap().unwrap(); //config upload will trigger reboot! drop(board); - let _webserver = httpd_initial(board_access.clone()); + let _webserver = httpd_initial(&board_access); wait_infinity(board_access.clone(), WaitType::InitialConfig); }, }; diff --git a/rust/src/plant_hal.rs b/rust/src/plant_hal.rs index b209394..94f9a87 100644 --- a/rust/src/plant_hal.rs +++ b/rust/src/plant_hal.rs @@ -1,20 +1,19 @@ //mod config; -use embedded_hal::blocking::delay::DelayMs; use embedded_svc::wifi::{ - AccessPointConfiguration, AuthMethod, ClientConfiguration, Configuration, Wifi, AccessPointInfo, + AccessPointConfiguration, AuthMethod, ClientConfiguration, Configuration, AccessPointInfo, }; use esp_idf_svc::eventloop::EspSystemEventLoop; use esp_idf_svc::nvs::EspDefaultNvsPartition; use esp_idf_svc::wifi::config::{ScanConfig, ScanType}; -use esp_idf_svc::wifi::{EspWifi, NonBlocking}; +use esp_idf_svc::wifi::EspWifi; use plant_ctrl2::sipo::ShiftRegister40; use anyhow::anyhow; -use anyhow::{bail, Context, Ok, Result}; +use anyhow::{bail, Ok, Result}; use std::ffi::CString; use std::fs::File; -use std::io::{BufReader, Read}; +use std::io::Read; use std::path::Path; use std::str::from_utf8; use std::sync::{Mutex, Arc}; @@ -26,7 +25,7 @@ use embedded_hal::digital::v1_compat::OldOutputPin; use embedded_hal::digital::v2::OutputPin; use esp_idf_hal::adc::config::Config; use esp_idf_hal::adc::{attenuation, AdcChannelDriver, AdcDriver}; -use esp_idf_hal::delay::{Delay, FreeRtos}; +use esp_idf_hal::delay::Delay; use esp_idf_hal::gpio::{AnyInputPin, Gpio39, Gpio4, Level, PinDriver}; use esp_idf_hal::pcnt::{ PcntChannel, PcntChannelConfig, PcntControlMode, PcntCountMode, PcntDriver, PinIndex, @@ -35,9 +34,8 @@ 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::{vTaskDelay, EspError}; +use esp_idf_sys::EspError; use one_wire_bus::OneWire; -use serde::{Deserialize, Serialize}; use crate::config::{self, WifiConfig}; @@ -604,6 +602,7 @@ impl PlantCtrlBoardInteraction for PlantCtrlBoard<'_> { } fn wifi_scan(&mut self) -> Result> { + //remove this parts for i in 1..11 { println!("Scanning channel {}", i); self.wifi_driver.start_scan(&ScanConfig{ @@ -618,6 +617,11 @@ impl PlantCtrlBoardInteraction for PlantCtrlBoard<'_> { } } - return bail!("dummy"); + self.wifi_driver.start_scan(&ScanConfig{ + scan_type : ScanType::Passive(Duration::from_secs(1)), + show_hidden: false, + ..Default::default() + }, true)?; + return Ok(self.wifi_driver.get_scan_result()?); } } diff --git a/rust/src/webserver/initial_config.html b/rust/src/webserver/initial_config.html index cf164fe..735205d 100644 --- a/rust/src/webserver/initial_config.html +++ b/rust/src/webserver/initial_config.html @@ -17,14 +17,18 @@

WIFI

- +
- - -
\ No newline at end of file diff --git a/rust/src/webserver/webserver.rs b/rust/src/webserver/webserver.rs index c42208e..014ad56 100644 --- a/rust/src/webserver/webserver.rs +++ b/rust/src/webserver/webserver.rs @@ -1,22 +1,36 @@ //offer ota and config mode -use std::{vec, sync::{Mutex, Arc}}; +use std::sync::{Mutex, Arc}; use embedded_svc::http::Method; use esp_idf_svc::http::server::EspHttpServer; use esp_ota::OtaUpdate; +use heapless::String; +use serde::Serialize; -use crate::plant_hal::{PlantCtrlBoard, PlantCtrlBoardInteraction}; +use crate::{plant_hal::{PlantCtrlBoard, PlantCtrlBoardInteraction}, config::WifiConfig}; -pub fn httpd_initial(board_access:Arc>>) -> Box> { +#[derive(Serialize)] +#[derive(Debug)] +struct SSIDList<'a> { + ssids: Vec<&'a String<32>> +} + +pub fn httpd_initial(board_access:&Arc>>) -> Box> { let mut server = shared(); server.fn_handler("/",Method::Get, move |request| { let mut response = request.into_ok_response()?; response.write(include_bytes!("initial_config.html"))?; return Ok(()) }).unwrap(); - - server.fn_handler("/wifiscan",Method::Get, move |request| { + server + .fn_handler("/wifi.js",Method::Get, |request| { + let mut response = request.into_ok_response()?; + response.write(include_bytes!("wifi.js"))?; + return Ok(()) + }).unwrap(); + + server.fn_handler("/wifiscan",Method::Post, move |request| { let mut response = request.into_ok_response()?; let mut board = board_access.lock().unwrap(); match board.wifi_scan() { @@ -24,21 +38,41 @@ pub fn httpd_initial(board_access:Arc>>) -> Box { - println!("Scan result is {:?}", scan_result); - response.write("{ ssids:[".as_bytes())?; - let mut first = true; - for ap in scan_result.iter(){ - if !first { - response.write(",".as_bytes())?; - } - response.write(ap.ssid.as_bytes())?; - first = false; - } - response.write("]".as_bytes())?; + let mut ssids: Vec<&String<32>> = Vec::new(); + scan_result.iter().for_each(|s| + ssids.push(&s.ssid) + ); + response.write( serde_json::to_string( + &SSIDList{ssids} + )?.as_bytes())?; }, } return Ok(()) }).unwrap(); + + server.fn_handler("/wifisave",Method::Post, move |mut request| { + let mut buf = [0_u8;2048]; + let read = request.read(&mut buf); + if read.is_err(){ + let error_text = read.unwrap_err().to_string(); + request.into_status_response(500)?.write(error_text.as_bytes())?; + return Ok(()); + } + let actual_data = &buf[0..read.unwrap()]; + let wifi_config: Result = serde_json::from_slice(actual_data); + if wifi_config.is_err(){ + let error_text = wifi_config.unwrap_err().to_string(); + request.into_status_response(500)?.write(error_text.as_bytes())?; + return Ok(()); + } + let mut board = board_access.lock().unwrap(); + board.set_wifi(&wifi_config.unwrap()); + let mut response = request.into_status_response(202)?; + response.write("saved".as_bytes()); + return Ok(()) + }).unwrap(); + + return server } diff --git a/rust/src/webserver/wifi.js b/rust/src/webserver/wifi.js index 2c75c4a..7a17e7b 100644 --- a/rust/src/webserver/wifi.js +++ b/rust/src/webserver/wifi.js @@ -1,14 +1,56 @@ +function saveWifi(){ + document.getElementById("save").disabled = true; + var wificonfig = {} + wificonfig.ssid = document.getElementById("ssid").value + wificonfig.password = document.getElementById("password").value + var pretty = JSON.stringify(wificonfig, undefined, 4); + console.log("Sending config " + pretty) + + var ajax = new XMLHttpRequest(); + ajax.upload.addEventListener("progress", progressHandler, false); + ajax.onreadystatechange = () => { + _("wifistatus").innerText = ajax.responseText + }; + ajax.onerror = (evt) => { + console.log(evt) + _("wifistatus").innerText = ajax.responseText + document.getElementById("save").disabled = false; + alert("Failed to save config see console") + } + ajax.open("POST", "/wifisave"); + ajax.send(); +} + function scanWifi(){ - const req = new XMLHttpRequest(); - req.addEventListener("progress", updateProgress); - req.addEventListener("load", wifiTransferComplete); - req.addEventListener("error", transferFailed); - req.addEventListener("abort", transferCanceled); - req.open("GET", "/wifiscan"); - req.send(); + document.getElementById("scan").disabled = true; + + var ajax = new XMLHttpRequest(); + ajax.upload.addEventListener("progress", progressHandler, false); + ajax.responseType = 'json'; + ajax.onreadystatechange = () => { + if (ajax.readyState === 4) { + callback(ajax.response); + } + }; + ajax.onerror = (evt) => { + console.log(evt) + document.getElementById("scan").disabled = false; + alert("Failed to start see console") + } + ajax.open("POST", "/wifiscan"); + ajax.send(); } -function wifiTransferComplete(evt) { - console.log("The transfer is complete."); +function callback(data){ + document.getElementById("scan").disabled = false; + + var ssidlist = document.getElementById("ssidlist") + ssidlist.innerHTML = '' + + for (ssid of data.ssids) { + var wi = document.createElement("option"); + wi.value = ssid; + ssidlist.appendChild(wi); + } }