more javascript shit

This commit is contained in:
Empire 2023-12-22 17:26:00 +01:00
parent 58801f870e
commit 2541c83ebe
6 changed files with 125 additions and 41 deletions

View File

@ -73,7 +73,7 @@ embedded-hal = "0.2.7"
one-wire-bus = "0.1.1" one-wire-bus = "0.1.1"
anyhow = { version = "1.0.75", features = ["std", "backtrace"] } anyhow = { version = "1.0.75", features = ["std", "backtrace"] }
schemars = "0.8.16" schemars = "0.8.16"
heapless = { version = "0.8.0", features = ["serde"] } heapless = { version = "0.7", features = ["serde"] }
serde_json = "1.0.108" serde_json = "1.0.108"
#?bq34z100 required #?bq34z100 required

View File

@ -130,7 +130,7 @@ fn main() -> Result<()> {
board.wifi_ap().unwrap(); board.wifi_ap().unwrap();
//config upload will trigger reboot! //config upload will trigger reboot!
drop(board); drop(board);
let _webserver = httpd_initial(board_access.clone()); let _webserver = httpd_initial(&board_access);
wait_infinity(board_access.clone(), WaitType::InitialConfig); wait_infinity(board_access.clone(), WaitType::InitialConfig);
}, },
}; };

View File

@ -1,20 +1,19 @@
//mod config; //mod config;
use embedded_hal::blocking::delay::DelayMs;
use embedded_svc::wifi::{ 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::eventloop::EspSystemEventLoop;
use esp_idf_svc::nvs::EspDefaultNvsPartition; use esp_idf_svc::nvs::EspDefaultNvsPartition;
use esp_idf_svc::wifi::config::{ScanConfig, ScanType}; 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 plant_ctrl2::sipo::ShiftRegister40;
use anyhow::anyhow; use anyhow::anyhow;
use anyhow::{bail, Context, Ok, Result}; use anyhow::{bail, Ok, Result};
use std::ffi::CString; use std::ffi::CString;
use std::fs::File; use std::fs::File;
use std::io::{BufReader, Read}; use std::io::Read;
use std::path::Path; use std::path::Path;
use std::str::from_utf8; use std::str::from_utf8;
use std::sync::{Mutex, Arc}; use std::sync::{Mutex, Arc};
@ -26,7 +25,7 @@ use embedded_hal::digital::v1_compat::OldOutputPin;
use embedded_hal::digital::v2::OutputPin; use embedded_hal::digital::v2::OutputPin;
use esp_idf_hal::adc::config::Config; use esp_idf_hal::adc::config::Config;
use esp_idf_hal::adc::{attenuation, AdcChannelDriver, AdcDriver}; 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::gpio::{AnyInputPin, Gpio39, Gpio4, Level, PinDriver};
use esp_idf_hal::pcnt::{ use esp_idf_hal::pcnt::{
PcntChannel, PcntChannelConfig, PcntControlMode, PcntCountMode, PcntDriver, PinIndex, 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_hal::reset::ResetReason;
use esp_idf_svc::sntp::{self, SyncStatus}; use esp_idf_svc::sntp::{self, SyncStatus};
use esp_idf_svc::systime::EspSystemTime; use esp_idf_svc::systime::EspSystemTime;
use esp_idf_sys::{vTaskDelay, EspError}; use esp_idf_sys::EspError;
use one_wire_bus::OneWire; use one_wire_bus::OneWire;
use serde::{Deserialize, Serialize};
use crate::config::{self, WifiConfig}; use crate::config::{self, WifiConfig};
@ -604,6 +602,7 @@ impl PlantCtrlBoardInteraction for PlantCtrlBoard<'_> {
} }
fn wifi_scan(&mut self) -> Result<Vec<AccessPointInfo>> { fn wifi_scan(&mut self) -> Result<Vec<AccessPointInfo>> {
//remove this parts
for i in 1..11 { for i in 1..11 {
println!("Scanning channel {}", i); println!("Scanning channel {}", i);
self.wifi_driver.start_scan(&ScanConfig{ 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()?);
} }
} }

View File

@ -17,14 +17,18 @@
<div> <div>
<h2>WIFI</h2> <h2>WIFI</h2>
<input type="button" id="scan" onchange="scanWifi()" value="Scan"> <input type="button" id="scan" onclick="scanWifi()" value="Scan">
<br> <br>
<label for="ssid">SSID:</label> <label for="ssid">SSID:</label>
<input type="text" id="ssid" list="cityname"> <input type="text" id="ssid" list="ssidlist">
<datalist id="cityname"> <datalist id="ssidlist">
<option value="Boston"> <option value="Not scanned yet">
<option value="Cambridge">
</datalist> </datalist>
<label for="ssid">Password:</label>
<input type="text" id="password" list="ssidlist">
<input type="button" id="save" onclick="saveWifi()" value="Save & Restart">
<div id="wifistatus"></div>
<br>
</div> </div>
</body> </body>
</html> </html>

View File

@ -1,22 +1,36 @@
//offer ota and config mode //offer ota and config mode
use std::{vec, sync::{Mutex, Arc}}; use std::sync::{Mutex, Arc};
use embedded_svc::http::Method; use embedded_svc::http::Method;
use esp_idf_svc::http::server::EspHttpServer; use esp_idf_svc::http::server::EspHttpServer;
use esp_ota::OtaUpdate; 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<Mutex<PlantCtrlBoard<'static>>>) -> Box<EspHttpServer<'static>> { #[derive(Serialize)]
#[derive(Debug)]
struct SSIDList<'a> {
ssids: Vec<&'a String<32>>
}
pub fn httpd_initial(board_access:&Arc<Mutex<PlantCtrlBoard<'static>>>) -> Box<EspHttpServer<'static>> {
let mut server = shared(); let mut server = shared();
server.fn_handler("/",Method::Get, move |request| { server.fn_handler("/",Method::Get, move |request| {
let mut response = request.into_ok_response()?; let mut response = request.into_ok_response()?;
response.write(include_bytes!("initial_config.html"))?; response.write(include_bytes!("initial_config.html"))?;
return Ok(()) return Ok(())
}).unwrap(); }).unwrap();
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::Get, move |request| { server.fn_handler("/wifiscan",Method::Post, move |request| {
let mut response = request.into_ok_response()?; let mut response = request.into_ok_response()?;
let mut board = board_access.lock().unwrap(); let mut board = board_access.lock().unwrap();
match board.wifi_scan() { match board.wifi_scan() {
@ -24,21 +38,41 @@ pub fn httpd_initial(board_access:Arc<Mutex<PlantCtrlBoard<'static>>>) -> Box<Es
response.write(format!("Error scanning wifi: {}", error).as_bytes())?; response.write(format!("Error scanning wifi: {}", error).as_bytes())?;
}, },
Ok(scan_result) => { Ok(scan_result) => {
println!("Scan result is {:?}", scan_result); let mut ssids: Vec<&String<32>> = Vec::new();
response.write("{ ssids:[".as_bytes())?; scan_result.iter().for_each(|s|
let mut first = true; ssids.push(&s.ssid)
for ap in scan_result.iter(){ );
if !first { response.write( serde_json::to_string(
response.write(",".as_bytes())?; &SSIDList{ssids}
} )?.as_bytes())?;
response.write(ap.ssid.as_bytes())?;
first = false;
}
response.write("]".as_bytes())?;
}, },
} }
return Ok(()) return Ok(())
}).unwrap(); }).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<WifiConfig, serde_json::Error> = 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 return server
} }

View File

@ -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(){ function scanWifi(){
const req = new XMLHttpRequest(); document.getElementById("scan").disabled = true;
req.addEventListener("progress", updateProgress);
req.addEventListener("load", wifiTransferComplete); var ajax = new XMLHttpRequest();
req.addEventListener("error", transferFailed); ajax.upload.addEventListener("progress", progressHandler, false);
req.addEventListener("abort", transferCanceled); ajax.responseType = 'json';
req.open("GET", "/wifiscan"); ajax.onreadystatechange = () => {
req.send(); 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) { function callback(data){
console.log("The transfer is complete."); 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);
}
} }