initial config changes

This commit is contained in:
2023-12-22 01:35:08 +01:00
parent 066b3ec24f
commit 58801f870e
11 changed files with 653 additions and 253 deletions

View File

@@ -1,72 +1,57 @@
<html>
<meta>
<script src="ota.js"></script>
<script src="jsoneditor.js"></script>
<script src="form.js"></script>
</meta>
<body>
<h2>firmeware OTA v3</h2>
<form id="upload_form" method="post">
<input type="file" name="file1" id="file1" onchange="uploadFile()"><br>
<progress id="progressBar" value="0" max="100" style="width:300px;"></progress>
<h3 id="status"></h3>
<h3 id="answer"></h3>
<p id="loaded_n_total"></p>
</form>
<h2>firmeware OTA v3</h2>
<form id="upload_form" method="post">
<input type="file" name="file1" id="file1" onchange="uploadFile()"><br>
<progress id="progressBar" value="0" max="100" style="width:300px;"></progress>
<h3 id="status"></h3>
<h3 id="answer"></h3>
<p id="loaded_n_total"></p>
</form>
<h2>config</h2>
<div id="editor_holder" data-theme="html" class="je-ready">
<h2>config</h2>
<button id="submit" onclick="createForm()">Create</button>
<div id="configform">
<h3>Tank:</h3>
<div>
<input type="checkbox" id="tank_sensor_enabled" onchange="submitForm()">
Enable Tank Sensor
</div>
<button id="submit">Submit (console.log)</button>
<script>
// Initialize the editor with a JSON schema
var editor = new JSONEditor(document.getElementById('editor_holder'),{
schema: {
type: "object",
title: "Car",
properties: {
make: {
type: "string",
enum: [
"Toyota",
"BMW",
"Honda",
"Ford",
"Chevy",
"VW"
]
},
model: {
type: "string"
},
year: {
type: "integer",
enum: [
1995,1996,1997,1998,1999,
2000,2001,2002,2003,2004,
2005,2006,2007,2008,2009,
2010,2011,2012,2013,2014
],
default: 2008
},
safety: {
type: "integer",
format: "rating",
maximum: "5",
exclusiveMaximum: false,
readonly: false
}
}
}
});
// Hook up the submit button to log to the console
document.getElementById('submit').addEventListener('click',function() {
// Get the value from the editor
console.log(editor.getValue());
});
</script>
<div>
<input type="number" min="2" max="500000" id="tank_full_ml" onchange="submitForm()">
Tank Size mL
</div>
<div>
<input type="number" min="1" max="500000" id="tank_warn_percent" onchange="submitForm()">
Tank Warn below mL
</div>
<h3>Light:</h3>
<div>
Start
<input type="time" id="night_lamp_time_start" onchange="submitForm()">
Stop
<input type="time" id="night_lamp_time_end" onchange="submitForm()">
</div>
<div>
<input type="checkbox" id="night_lamp_only_when_dark" onchange="submitForm()">
Light only when dark
</div>
<h3>Plants:</h3>
<div id="plants"></div>
</div>
<button id="submit" onclick="submitForm()">Submit</button>
<br>
<textarea id="json" cols=50 rows=10></textarea>
</body>
</html>

109
rust/src/webserver/form.js Normal file
View File

@@ -0,0 +1,109 @@
var plantcount = 1;
function createForm(){
var current = {}
current.tank_sensor_enabled = true;
current.tank_full_ml = 400;
current.tank_warn_percent = 200;
current.night_lamp_time_start = "18:00";
current.night_lamp_time_end = "02:00";
current.night_lamp_only_when_dark = true;
current.plants = [
{
target_moisture: 40,
pump_time_s:60
}
]
current.plantcount = 1;
plantcount = current.plantcount;
for(i=0;i<plantcount;i++){
var plant = document.createElement("div");
plants.appendChild(plant);
var header = document.createElement("h4");
header.textContent = "Plant " + (i+1);
plant.appendChild(header);
{
var holder = document.createElement("div");
plant.appendChild(holder);
var inputf = document.createElement("input");
inputf.id = "plant_"+i+"_target_moisture";
inputf.onchange = function() {submitForm()};
inputf.type = "number";
inputf.min = 0;
inputf.max = 100;
holder.appendChild(inputf)
var text = document.createElement("span");
holder.appendChild(text)
text.innerHTML += "Target Moisture"
}
{
var holder = document.createElement("div");
plant.appendChild(holder);
var input = document.createElement("input");
input.id = "plant_"+i+"_pump_time_s";
input.onchange = function() {submitForm()};
input.type = "number";
input.min = 0;
input.max = 600;
holder.appendChild(input)
var text = document.createElement("span");
holder.appendChild(text)
text.innerHTML += "Pump Time (s)"
}
}
sync(current);
}
function sync(current){
document.getElementById("tank_full_ml").disabled = !current.tank_sensor_enabled;
document.getElementById("tank_warn_percent").disabled = !current.tank_sensor_enabled;
document.getElementById("tank_sensor_enabled").checked = current.tank_sensor_enabled;
document.getElementById("tank_full_ml").value = current.tank_full_ml;
document.getElementById("tank_warn_percent").value = current.tank_warn_percent;
document.getElementById("night_lamp_time_start").value = current.night_lamp_time_start;
document.getElementById("night_lamp_time_end").value = current.night_lamp_time_end;
document.getElementById("tank_warn_percent").value = current.tank_warn_percent;
for(i=0;i<plantcount;i++){
document.getElementById("plant_"+i+"_target_moisture").value = current.plants[i].target_moisture;
document.getElementById("plant_"+i+"_pump_time_s").value = current.plants[i].pump_time_s;
}
}
function submitForm() {
var current = {}
current.plantcount = plantcount;
current.tank_sensor_enabled = document.getElementById("tank_sensor_enabled").checked;
current.tank_full_ml = document.getElementById("tank_full_ml").value;
current.tank_warn_percent = document.getElementById("tank_warn_percent").value;
current.night_lamp_time_start = document.getElementById("night_lamp_time_start").value;
current.night_lamp_time_end = document.getElementById("night_lamp_time_end").value;
current.night_lamp_only_when_dark = document.getElementById("night_lamp_only_when_dark").checked;
current.plants = []
for(i=0;i<plantcount;i++){
console.log("Adding plant " + i)
current.plants[i] = {}
current.plants[i].target_moisture = document.getElementById("plant_"+i+"_target_moisture").value;
current.plants[i].pump_time_s = document.getElementById("plant_"+i+"_pump_time_s").value;
}
sync(current);
console.log(current);
var pretty = JSON.stringify(current, undefined, 4);
document.getElementById('json').value = pretty;
}

View File

@@ -1,6 +1,7 @@
<html>
<meta>
<script src="ota.js"></script>
<script src="wifi.js"></script>
</meta>
<body>
<div>
@@ -13,5 +14,17 @@
<p id="loaded_n_total"></p>
</form>
</div>
<div>
<h2>WIFI</h2>
<input type="button" id="scan" onchange="scanWifi()" value="Scan">
<br>
<label for="ssid">SSID:</label>
<input type="text" id="ssid" list="cityname">
<datalist id="cityname">
<option value="Boston">
<option value="Cambridge">
</datalist>
</div>
</body>
</html>

View File

@@ -1,23 +1,64 @@
//offer ota and config mode
use std::{vec, sync::{Mutex, Arc}};
use embedded_svc::http::Method;
use esp_idf_svc::http::server::EspHttpServer;
use esp_ota::OtaUpdate;
#[allow(unused_variables)]
pub fn httpd(initial_config:bool) -> EspHttpServer<'static> {
use crate::plant_hal::{PlantCtrlBoard, PlantCtrlBoardInteraction};
let mut server = EspHttpServer::new(&Default::default()).unwrap();
pub fn httpd_initial(board_access:Arc<Mutex<PlantCtrlBoard<'static>>>) -> Box<EspHttpServer<'static>> {
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| {
let mut response = request.into_ok_response()?;
let mut board = board_access.lock().unwrap();
match board.wifi_scan() {
Err(error) => {
response.write(format!("Error scanning wifi: {}", error).as_bytes())?;
},
Ok(scan_result) => {
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())?;
},
}
return Ok(())
}).unwrap();
return server
}
pub fn httpd(board:&mut Box<PlantCtrlBoard<'static>>) -> Box<EspHttpServer<'static>> {
let mut server = shared();
server
.fn_handler("/",Method::Get, move |request| {
let mut response = request.into_ok_response()?;
match initial_config {
true => response.write(include_bytes!("initial_config.html"))?,
false => response.write(include_bytes!("config.html"))?
};
return Ok(())
}).unwrap();
.fn_handler("/",Method::Get, move |request| {
let mut response = request.into_ok_response()?;
response.write(include_bytes!("config.html"))?;
return Ok(())
}).unwrap();
return server;
}
pub fn shared() -> Box<EspHttpServer<'static>> {
let mut server = Box::new(EspHttpServer::new(&Default::default()).unwrap());
server
.fn_handler("/version",Method::Get, |request| {
let mut response = request.into_ok_response()?;
@@ -78,9 +119,6 @@ pub fn httpd(initial_config:bool) -> EspHttpServer<'static> {
println!("changing boot partition");
finalizer.set_as_boot_partition().unwrap();
finalizer.restart();
//return Ok(())
}).unwrap();
return server;
}

View File

@@ -0,0 +1,14 @@
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();
}
function wifiTransferComplete(evt) {
console.log("The transfer is complete.");
}