151 lines
4.5 KiB
HTML
151 lines
4.5 KiB
HTML
<!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>">
|
|
|
|
<script type="text/javascript">
|
|
const api_url = window.location.protocol + "//" + window.location.hostname + ":" + window.location.port;
|
|
|
|
refresh_interval = register();
|
|
|
|
refresh();
|
|
document.addEventListener("visibilitychange", () => {
|
|
if (document.hidden) {
|
|
clearInterval(refresh_interval);
|
|
} else {
|
|
refresh();
|
|
refresh_interval = register();
|
|
}
|
|
});
|
|
|
|
function register() {
|
|
return setInterval(refresh, 10000);
|
|
}
|
|
|
|
function flash() {
|
|
fetch(api_url + "/flash", { method: "POST" });
|
|
}
|
|
|
|
function disable_automatic_control() {
|
|
fetch(api_url + "/disable-control", { method: "POST" })
|
|
.then((response) => {
|
|
refresh_buttons();
|
|
});
|
|
}
|
|
|
|
function enable_automatic_control() {
|
|
fetch(api_url + "/enable-control", { method: "POST" })
|
|
.then((response) => {
|
|
refresh_buttons();
|
|
});
|
|
}
|
|
|
|
function update_control_buttons(data) {
|
|
var button_container = document.getElementById("buttons");
|
|
while (button_container.childElementCount > 0) { button_container.removeChild(button_container.firstChild) }
|
|
if (data.control_enable) {
|
|
// control enabled, so show disable button
|
|
var button = document.createElement('button');
|
|
button.textContent = 'Disable automatic control';
|
|
button.addEventListener('click', disable_automatic_control);
|
|
button_container.appendChild(button);
|
|
} else {
|
|
// control disabled, so show enable button
|
|
var button = document.createElement('button');
|
|
button.textContent = 'Enable automatic control';
|
|
button.addEventListener('click', enable_automatic_control);
|
|
button_container.appendChild(button);
|
|
}
|
|
}
|
|
|
|
function refresh_buttons() {
|
|
fetch(api_url + "/control-state")
|
|
.then((response) => response.json())
|
|
.then((json) => update_control_buttons(json));
|
|
}
|
|
|
|
function refresh() {
|
|
let favicon = document.getElementById("favicon");
|
|
|
|
favicon.setAttribute("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>");
|
|
fetch(api_url + "/car-state")
|
|
.then((response) => response.json())
|
|
.then((json) => update_state(json));
|
|
|
|
refresh_buttons();
|
|
}
|
|
|
|
function update_state(state) {
|
|
let favicon = document.getElementById("favicon");
|
|
|
|
favicon.setAttribute("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>" + get_emoji(state.charge_state) + "</text></svg>");
|
|
|
|
|
|
var info_div = document.getElementById("info");
|
|
while (info_div.childElementCount > 0) { info_div.removeChild(info_div.firstChild) }
|
|
|
|
var arr = ["Battery " + state.charge_state.battery_level + "%", "Range: " + (state.charge_state.battery_range * 1.60934).toFixed(1) + "km", "Charging at " + state.charge_state.charge_rate.toFixed(1) + " amps", "Charging until battery at " + state.charge_state.charge_limit_soc + "%",
|
|
];
|
|
for (line in arr) {
|
|
el = document.createElement('p');
|
|
el.appendChild(document.createTextNode(arr[line]));
|
|
info_div.appendChild(el)
|
|
}
|
|
|
|
|
|
home = document.createElement('p');
|
|
if (state.location_data.home) {
|
|
home.appendChild(document.createTextNode("At home"));
|
|
} else {
|
|
home.appendChild(document.createTextNode("Not home"));
|
|
}
|
|
|
|
info_div.appendChild(home);
|
|
|
|
|
|
el = document.createElement('p');
|
|
el.appendChild(document.createTextNode("Full charge state:"));
|
|
|
|
state_json = document.createElement('pre');
|
|
state_json.appendChild(document.createTextNode(JSON.stringify(state.charge_state, null, '\t')));
|
|
el.appendChild(state_json);
|
|
info_div.appendChild(el);
|
|
|
|
el = document.createElement('p');
|
|
el.appendChild(document.createTextNode("Full climate state:"));
|
|
|
|
state_json = document.createElement('pre');
|
|
state_json.appendChild(document.createTextNode(JSON.stringify(state.climate_state, null, '\t')));
|
|
el.appendChild(state_json);
|
|
info_div.appendChild(el);
|
|
|
|
|
|
}
|
|
|
|
function get_emoji(charge_state) {
|
|
if (charge_state.charge_rate > 0) {
|
|
return "🔌";
|
|
} else if (charge_state.battery_level < 60) {
|
|
return "🪫"
|
|
} else return "🔋";
|
|
}
|
|
</script>
|
|
</head>
|
|
|
|
<body></body>
|
|
<div>
|
|
<h2>
|
|
<a href="/grafana">Grafana</a>
|
|
</h2>
|
|
</div>
|
|
<button onclick="flash()">flash</button>
|
|
|
|
<p id="buttons"></p>
|
|
|
|
<div id="info"></div>
|
|
|
|
</html> |