webui shutoff voltage + better start/stop requests
All checks were successful
Build .deb on release / Build-Deb (push) Successful in 1m53s
All checks were successful
Build .deb on release / Build-Deb (push) Successful in 1m53s
This commit is contained in:
parent
4ebd386c05
commit
7f4a880720
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -2633,7 +2633,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tesla-charge-controller"
|
name = "tesla-charge-controller"
|
||||||
version = "1.0.29"
|
version = "1.0.30"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap 4.4.11",
|
"clap 4.4.11",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "tesla-charge-controller"
|
name = "tesla-charge-controller"
|
||||||
version = "1.0.29"
|
version = "1.0.30"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MITNFA"
|
license = "MITNFA"
|
||||||
description = "Controls Tesla charge rate based on solar charge data"
|
description = "Controls Tesla charge rate based on solar charge data"
|
||||||
|
|
|
@ -62,6 +62,9 @@ fn rocket(state: ServerState) -> rocket::Rocket<rocket::Build> {
|
||||||
flash,
|
flash,
|
||||||
disable_control,
|
disable_control,
|
||||||
enable_control,
|
enable_control,
|
||||||
|
set_shutoff,
|
||||||
|
set_shutoff_time,
|
||||||
|
shutoff_status,
|
||||||
set_max,
|
set_max,
|
||||||
set_min,
|
set_min,
|
||||||
set_proportional_gain,
|
set_proportional_gain,
|
||||||
|
@ -125,27 +128,50 @@ async fn flash(state: &State<ServerState>, remote_addr: std::net::IpAddr) {
|
||||||
#[post("/disable-control")]
|
#[post("/disable-control")]
|
||||||
async fn disable_control(state: &State<ServerState>, remote_addr: std::net::IpAddr) {
|
async fn disable_control(state: &State<ServerState>, remote_addr: std::net::IpAddr) {
|
||||||
log::warn!("disabling control: {remote_addr:?}");
|
log::warn!("disabling control: {remote_addr:?}");
|
||||||
match state
|
match state.tcrc_state.write() {
|
||||||
.tcrc_requests
|
Ok(mut handle) => handle.control_enable = false,
|
||||||
.send(TcrcRequest::DisableAutomaticControl)
|
Err(e) => log::error!("Error disabling control: {e:?}"),
|
||||||
{
|
|
||||||
Ok(_) => {}
|
|
||||||
Err(e) => log::error!("Error sending stop control request: {e:?}"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/enable-control")]
|
#[post("/enable-control")]
|
||||||
async fn enable_control(state: &State<ServerState>, remote_addr: std::net::IpAddr) {
|
async fn enable_control(state: &State<ServerState>, remote_addr: std::net::IpAddr) {
|
||||||
log::warn!("enabling control: {remote_addr:?}");
|
log::warn!("enabling control: {remote_addr:?}");
|
||||||
match state
|
match state.tcrc_state.write() {
|
||||||
.tcrc_requests
|
Ok(mut handle) => handle.control_enable = true,
|
||||||
.send(TcrcRequest::EnableAutomaticControl)
|
Err(e) => log::error!("Error enabling control: {e:?}"),
|
||||||
{
|
|
||||||
Ok(_) => {}
|
|
||||||
Err(e) => log::error!("Error sending stop control request: {e:?}"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[post("/shutoff/voltage/<voltage>")]
|
||||||
|
async fn set_shutoff(voltage: f64, remote_addr: std::net::IpAddr) {
|
||||||
|
log::warn!("setting shutoff voltage: {remote_addr:?}");
|
||||||
|
let voltage = voltage.clamp(40., 60.);
|
||||||
|
write_to_config().shutoff_voltage = voltage;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[post("/shutoff/time/<time>")]
|
||||||
|
async fn set_shutoff_time(time: u64, remote_addr: std::net::IpAddr) {
|
||||||
|
log::warn!("setting shutoff time: {remote_addr:?}");
|
||||||
|
let time = time.clamp(5, 120);
|
||||||
|
write_to_config().shutoff_voltage_time_seconds = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Serialize, Deserialize, Debug)]
|
||||||
|
struct ShutoffStatus {
|
||||||
|
voltage: f64,
|
||||||
|
time: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("/shutoff/status")]
|
||||||
|
async fn shutoff_status() -> Json<ShutoffStatus> {
|
||||||
|
let config = access_config();
|
||||||
|
Json(ShutoffStatus {
|
||||||
|
voltage: config.shutoff_voltage,
|
||||||
|
time: config.shutoff_voltage_time_seconds,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
#[post("/set-max/<limit>")]
|
#[post("/set-max/<limit>")]
|
||||||
async fn set_max(limit: i64, remote_addr: std::net::IpAddr) {
|
async fn set_max(limit: i64, remote_addr: std::net::IpAddr) {
|
||||||
log::warn!("setting max: {remote_addr:?}");
|
log::warn!("setting max: {remote_addr:?}");
|
||||||
|
|
|
@ -20,6 +20,7 @@ pub struct TeslaChargeRateController {
|
||||||
control_enable_gauge: Gauge,
|
control_enable_gauge: Gauge,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub enum TcrcRequest {
|
pub enum TcrcRequest {
|
||||||
DisableAutomaticControl,
|
DisableAutomaticControl,
|
||||||
EnableAutomaticControl,
|
EnableAutomaticControl,
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
<a class="outlink" href="/grafana">Grafana→</a>
|
<a class="outlink" href="/grafana">Grafana→</a>
|
||||||
<a class="outlink" href="/info">Car state info→</a>
|
<a class="outlink" href="/info">Car state info→</a>
|
||||||
<a class="outlink" href="/pid">PID control variables→</a>
|
<a class="outlink" href="/pid">PID control variables→</a>
|
||||||
|
<a class="outlink" href="/shutoff">Shutoff voltage control→</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -40,6 +40,15 @@ function init_pid() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function init_shutoff() {
|
||||||
|
refresh_shutoff();
|
||||||
|
document.addEventListener("visibilitychange", () => {
|
||||||
|
if (!document.hidden) {
|
||||||
|
refresh_shutoff();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function init_info() {
|
function init_info() {
|
||||||
refresh_interval = register(refresh_info);
|
refresh_interval = register(refresh_info);
|
||||||
|
|
||||||
|
@ -138,6 +147,34 @@ function set_derivative() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function set_shutoff_voltage() {
|
||||||
|
var set_button = document.getElementById("set-shutoff-voltage");
|
||||||
|
var number_input = document.getElementById("shutoff-voltage");
|
||||||
|
if (!isNaN(number_input.value)) {
|
||||||
|
set_button.disabled = true;
|
||||||
|
number_input.disabled = true;
|
||||||
|
fetch(api_url + "/shutoff/voltage/" + number_input.value, { method: "POST" })
|
||||||
|
.then(async (response) => {
|
||||||
|
let delayres = await delay(100);
|
||||||
|
refresh_shutoff();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function set_shutoff_time() {
|
||||||
|
var set_button = document.getElementById("set-shutoff-time");
|
||||||
|
var number_input = document.getElementById("shutoff-time");
|
||||||
|
if (!isNaN(number_input.value)) {
|
||||||
|
set_button.disabled = true;
|
||||||
|
number_input.disabled = true;
|
||||||
|
fetch(api_url + "/shutoff/time/" + number_input.value, { method: "POST" })
|
||||||
|
.then(async (response) => {
|
||||||
|
let delayres = await delay(100);
|
||||||
|
refresh_shutoff();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function set_load_divisor() {
|
function set_load_divisor() {
|
||||||
var set_button = document.getElementById("set-load-divisor");
|
var set_button = document.getElementById("set-load-divisor");
|
||||||
var number_input = document.getElementById("load-divisor");
|
var number_input = document.getElementById("load-divisor");
|
||||||
|
@ -159,7 +196,7 @@ function disable_automatic_control() {
|
||||||
|
|
||||||
fetch(api_url + "/disable-control", { method: "POST" })
|
fetch(api_url + "/disable-control", { method: "POST" })
|
||||||
.then(async (response) => {
|
.then(async (response) => {
|
||||||
let delayres = await delay(1000);
|
let delayres = await delay(100);
|
||||||
refresh_buttons();
|
refresh_buttons();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -171,7 +208,7 @@ function enable_automatic_control() {
|
||||||
document.body.classList.add("loading");
|
document.body.classList.add("loading");
|
||||||
fetch(api_url + "/enable-control", { method: "POST" })
|
fetch(api_url + "/enable-control", { method: "POST" })
|
||||||
.then(async (response) => {
|
.then(async (response) => {
|
||||||
let delayres = await delay(1000);
|
let delayres = await delay(100);
|
||||||
refresh_buttons();
|
refresh_buttons();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -242,6 +279,25 @@ function update_gains(data) {
|
||||||
load_divisor_input.value = data.load_divisor;
|
load_divisor_input.value = data.load_divisor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function refresh_shutoff() {
|
||||||
|
fetch(api_url + "/shutoff/status")
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then((json) => update_shutoff(json));
|
||||||
|
}
|
||||||
|
|
||||||
|
function update_shutoff(data) {
|
||||||
|
var voltage_set_button = document.getElementById("set-shutoff-voltage");
|
||||||
|
var voltage_number_input = document.getElementById("shutoff-voltage");
|
||||||
|
voltage_set_button.disabled = false;
|
||||||
|
voltage_number_input.disabled = false;
|
||||||
|
voltage_number_input.value = data.voltage;
|
||||||
|
var time_set_button = document.getElementById("set-shutoff-time");
|
||||||
|
var time_number_input = document.getElementById("shutoff-time");
|
||||||
|
time_set_button.disabled = false;
|
||||||
|
time_number_input.disabled = false;
|
||||||
|
time_number_input.value = data.time;
|
||||||
|
}
|
||||||
|
|
||||||
function refresh_buttons() {
|
function refresh_buttons() {
|
||||||
fetch(api_url + "/control-state")
|
fetch(api_url + "/control-state")
|
||||||
.then((response) => response.json())
|
.then((response) => response.json())
|
||||||
|
|
29
webapp/shutoff/index.html
Normal file
29
webapp/shutoff/index.html
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>Tesla Charge Control</title>
|
||||||
|
<link id="favicon" rel="icon"
|
||||||
|
href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🎚️</text></svg>">
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
<script src="script.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body onload="init_shutoff()">
|
||||||
|
<div class="container">
|
||||||
|
<p id="pid-control">
|
||||||
|
<h3>Shutoff voltage:</h3>
|
||||||
|
<input type="number" id="shutoff-voltage" step="1" min="40" max="60" autocomplete="off" />
|
||||||
|
<button id="set-shutoff-voltage" onclick="set_shutoff_voltage()">Set shutoff voltage</button>
|
||||||
|
<br><br>
|
||||||
|
<input type="number" id="shutoff-time" step="1" autocomplete="off" />
|
||||||
|
<button id="set-shutoff-time" onclick="set_shutoff_time()">Set shutoff time</button>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a class="outlink" href="/">←Home</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
Loading…
Reference in a new issue