regulator state set button
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
1cde09ff58
commit
ccd46b657c
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -2538,7 +2538,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tesla-charge-controller"
|
||||
version = "1.1.4"
|
||||
version = "1.2.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"clap 4.4.11",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "tesla-charge-controller"
|
||||
version = "1.1.4"
|
||||
version = "1.2.0"
|
||||
edition = "2021"
|
||||
license = "MITNFA"
|
||||
description = "Controls Tesla charge rate based on solar charge data"
|
||||
|
|
|
@ -50,6 +50,17 @@ impl From<u8> for RegulatorState {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<RegulatorState> for u8 {
|
||||
fn from(value: RegulatorState) -> Self {
|
||||
match value {
|
||||
RegulatorState::Boost => 0b00,
|
||||
RegulatorState::Equalise => 0b01,
|
||||
RegulatorState::Absorption => 0b10,
|
||||
RegulatorState::Float => 0b11,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for RegulatorState {
|
||||
fn default() -> Self {
|
||||
Self::Absorption
|
||||
|
@ -95,6 +106,7 @@ pub enum PliRequest {
|
|||
ReadRam(u8),
|
||||
ReadEeprom(u8),
|
||||
SyncTime,
|
||||
SetRegulatorState(RegulatorState),
|
||||
}
|
||||
|
||||
impl Pli {
|
||||
|
@ -182,6 +194,11 @@ impl Pli {
|
|||
"Set time: {now} corresponds to {timestamp} + minutes {min} + seconds {sec}"
|
||||
);
|
||||
}
|
||||
PliRequest::SetRegulatorState(state) => {
|
||||
log::warn!("Setting regulator state to {state:?}");
|
||||
self.write_ram(PlRamAddress::Rstate, state.into())
|
||||
.some_or_print_with("setting regulator state");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,8 @@ pub enum ServerError {
|
|||
#[error("no data")]
|
||||
// 503
|
||||
NoData,
|
||||
#[error("invalid parameters")]
|
||||
InvalidParameters,
|
||||
#[error("prometheus")]
|
||||
Prometheus(#[from] prometheus::Error),
|
||||
}
|
||||
|
@ -49,6 +51,7 @@ impl<'a> Responder<'a, 'a> for ServerError {
|
|||
Err(match self {
|
||||
ServerError::Lock => rocket::http::Status::InternalServerError,
|
||||
ServerError::NoData => rocket::http::Status::ServiceUnavailable,
|
||||
Self::InvalidParameters => rocket::http::Status::BadRequest,
|
||||
ServerError::Prometheus(_) => rocket::http::Status::InternalServerError,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ use std::sync::{Arc, RwLock};
|
|||
use rocket::{
|
||||
fairing::{Fairing, Info, Kind},
|
||||
http::Header,
|
||||
request::FromParam,
|
||||
serde::json::Json,
|
||||
Request, Response, State,
|
||||
};
|
||||
|
@ -11,9 +12,9 @@ use tokio::sync::mpsc::UnboundedSender;
|
|||
|
||||
use crate::{
|
||||
api_interface::InterfaceRequest,
|
||||
charge_controllers::pl::{PlState, PliRequest},
|
||||
charge_controllers::pl::{PlState, PliRequest, RegulatorState},
|
||||
config::{access_config, write_to_config},
|
||||
errors::ServerError,
|
||||
errors::{PrintErrors, ServerError},
|
||||
tesla_charge_rate::{TcrcRequest, TcrcState},
|
||||
types::CarState,
|
||||
};
|
||||
|
@ -75,7 +76,8 @@ fn rocket(state: ServerState) -> rocket::Rocket<rocket::Build> {
|
|||
metrics,
|
||||
sync_time,
|
||||
read_ram,
|
||||
read_eeprom
|
||||
read_eeprom,
|
||||
set_regulator_state
|
||||
],
|
||||
)
|
||||
}
|
||||
|
@ -250,6 +252,37 @@ async fn regulator_state(state: &State<ServerState>) -> Result<Json<PlState>, Se
|
|||
.and_then(|v| Ok(Json(*(v.read()?))))
|
||||
}
|
||||
|
||||
#[post("/set-regulator-state/<regulator_state>")]
|
||||
async fn set_regulator_state(
|
||||
state: &State<ServerState>,
|
||||
regulator_state: Option<RegulatorState>,
|
||||
) -> Result<(), ServerError> {
|
||||
if let Some(regulator_state) = regulator_state {
|
||||
log::info!("Requesting regulator state set to {regulator_state:?}");
|
||||
state
|
||||
.pli_requests
|
||||
.send(PliRequest::SetRegulatorState(regulator_state))
|
||||
.some_or_print_with("requesting new pl regulator state");
|
||||
Ok(())
|
||||
} else {
|
||||
Err(ServerError::InvalidParameters)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromParam<'_> for RegulatorState {
|
||||
type Error = ();
|
||||
|
||||
fn from_param(param: &'_ str) -> Result<Self, Self::Error> {
|
||||
match param.to_lowercase().as_str() {
|
||||
"boost" => Ok(Self::Boost),
|
||||
"equalise" => Ok(Self::Equalise),
|
||||
"absorption" => Ok(Self::Absorption),
|
||||
"float" => Ok(Self::Float),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Cors;
|
||||
|
||||
#[rocket::async_trait]
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
<p>
|
||||
<a class="outlink" href="/grafana">Grafana→</a>
|
||||
<a class="outlink" href="/info">Car state info→</a>
|
||||
<a class="outlink" href="/regulator">Regulator control→</a>
|
||||
<a class="outlink" href="/pid">PID control variables→</a>
|
||||
<a class="outlink" href="/shutoff">Shutoff voltage control→</a>
|
||||
</p>
|
||||
|
|
33
webapp/regulator/index.html
Normal file
33
webapp/regulator/index.html
Normal file
|
@ -0,0 +1,33 @@
|
|||
<!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_regulator()">
|
||||
<div class="container">
|
||||
<p id="pid-control">
|
||||
<h3>Regulator state:</h3>
|
||||
<div id="current-state"></div>
|
||||
<br>
|
||||
<select name="regstate" id="regstate">
|
||||
<option value="boost">Boost</option>
|
||||
<option value="equalise">Equalise</option>
|
||||
<option value="absorption">Absorption</option>
|
||||
<option value="float">Float</option>
|
||||
</select>
|
||||
<button id="set-regulator-state" onclick="set_regulator_state()">Set regulator state</button>
|
||||
</p>
|
||||
<p>
|
||||
<a class="outlink" href="/">←Home</a>
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -63,6 +63,21 @@ function init_info() {
|
|||
});
|
||||
}
|
||||
|
||||
function init_regulator() {
|
||||
|
||||
refresh_interval = register(refresh_regulator_state);
|
||||
|
||||
refresh_regulator_state();
|
||||
document.addEventListener("visibilitychange", () => {
|
||||
if (document.hidden) {
|
||||
clearInterval(refresh_interval);
|
||||
} else {
|
||||
refresh_regulator_state();
|
||||
refresh_interval = register(refresh_regulator_state);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function register(func) {
|
||||
return setInterval(func, 5000);
|
||||
}
|
||||
|
@ -175,6 +190,21 @@ function set_shutoff_time() {
|
|||
}
|
||||
}
|
||||
|
||||
function set_regulator_state() {
|
||||
var set_button = document.getElementById("set-regulator-state");
|
||||
var state_input = document.getElementById("regstate");
|
||||
|
||||
set_button.disabled = true;
|
||||
state_input.disabled = true;
|
||||
|
||||
fetch(api_url + "/set-regulator-state/" + state_input.value, { method: "POST" })
|
||||
.then(async (response) => {
|
||||
let delayres = await delay(300);
|
||||
refresh_regulator_state();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function set_load_divisor() {
|
||||
var set_button = document.getElementById("set-load-divisor");
|
||||
var number_input = document.getElementById("load-divisor");
|
||||
|
@ -285,6 +315,18 @@ function refresh_shutoff() {
|
|||
.then((json) => update_shutoff(json));
|
||||
}
|
||||
|
||||
function refresh_regulator_state() {
|
||||
var set_button = document.getElementById("set-regulator-state");
|
||||
var state_input = document.getElementById("regstate");
|
||||
|
||||
set_button.disabled = false;
|
||||
state_input.disabled = false;
|
||||
|
||||
fetch(api_url + "/regulator-state")
|
||||
.then((response) => { response.json() })
|
||||
.then((json) => update_regulator_state(json));
|
||||
}
|
||||
|
||||
function update_shutoff(data) {
|
||||
var voltage_set_button = document.getElementById("set-shutoff-voltage");
|
||||
var voltage_number_input = document.getElementById("shutoff-voltage");
|
||||
|
@ -298,6 +340,14 @@ function update_shutoff(data) {
|
|||
time_number_input.value = data.time;
|
||||
}
|
||||
|
||||
function update_regulator_state(state) {
|
||||
console.log(state);
|
||||
if (state == null) { var cur = "Unknown" } else { var cur = state.regulator_state }
|
||||
|
||||
var current_state = document.getElementById("current-state");
|
||||
current_state.textContent = "Current state: " + cur;
|
||||
}
|
||||
|
||||
function refresh_buttons() {
|
||||
fetch(api_url + "/control-state")
|
||||
.then((response) => response.json())
|
||||
|
|
Loading…
Reference in a new issue