const api_url = window.location.protocol + "//" + window.location.hostname + ":" + window.location.port; Object.prototype.disable = function () { var that = this; for (var i = 0, len = that.length; i < len; i++) { that[i].disabled = true; } return that; }; Object.prototype.enable = function () { var that = this; for (var i = 0, len = that.length; i < len; i++) { that[i].disabled = false; } return that; }; function init_main() { refresh_interval = register(refresh); refresh(); document.addEventListener("visibilitychange", () => { if (document.hidden) { clearInterval(refresh_interval); } else { refresh(); refresh_interval = register(refresh); } }); } function init_pid() { refresh_gains(); document.addEventListener("visibilitychange", () => { if (!document.hidden) { refresh_gains(); } }); } function init_shutoff() { refresh_shutoff(); document.addEventListener("visibilitychange", () => { if (!document.hidden) { refresh_shutoff(); } }); } function init_info() { refresh_interval = register(refresh_info); refresh_info(); document.addEventListener("visibilitychange", () => { if (document.hidden) { clearInterval(refresh_interval); } else { refresh_info(); refresh_interval = register(refresh_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); } function flash() { fetch(api_url + "/flash", { method: "POST" }); } var is_automatic_control; var current_min_rate; var current_max_rate; const delay = (time) => { return new Promise(resolve => setTimeout(resolve, time)); }; function set_minimum() { var set_button = document.getElementById("set-minimum"); var number_input = document.getElementById("min-rate"); if (!isNaN(number_input.value)) { set_button.disabled = true; number_input.disabled = true; fetch(api_url + "/set-min/" + number_input.value, { method: "POST" }) .then(async (response) => { let delayres = await delay(100); refresh_buttons(); }); } } function change_min() { var set_button = document.getElementById("set-minimum"); var number_input = document.getElementById("min-rate"); set_button.disabled = (number_input.value == current_min_rate); } function set_maximum() { var set_button = document.getElementById("set-maximum"); var number_input = document.getElementById("max-rate"); if (!isNaN(number_input.value)) { set_button.disabled = true; number_input.disabled = true; fetch(api_url + "/set-max/" + number_input.value, { method: "POST" }) .then(async (response) => { let delayres = await delay(100); refresh_buttons(); }); } } function change_max() { var set_button = document.getElementById("set-maximum"); var number_input = document.getElementById("max-rate"); set_button.disabled = (number_input.value == current_max_rate); } function set_proportional() { var set_button = document.getElementById("set-proportional"); var number_input = document.getElementById("proportional-gain"); if (!isNaN(number_input.value)) { set_button.disabled = true; number_input.disabled = true; fetch(api_url + "/pid-settings/proportional/" + number_input.value, { method: "POST" }) .then(async (response) => { let delayres = await delay(100); refresh_gains(); }); } } function set_derivative() { var set_button = document.getElementById("set-derivative"); var number_input = document.getElementById("derivative-gain"); if (!isNaN(number_input.value)) { set_button.disabled = true; number_input.disabled = true; fetch(api_url + "/pid-settings/derivative/" + number_input.value, { method: "POST" }) .then(async (response) => { let delayres = await delay(100); refresh_gains(); }); } } 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_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"); if (!isNaN(number_input.value)) { set_button.disabled = true; number_input.disabled = true; fetch(api_url + "/pid-settings/load_divisor/" + number_input.value, { method: "POST" }) .then(async (response) => { let delayres = await delay(100); refresh_gains(); }); } } function disable_automatic_control() { if (is_automatic_control) { document.getElementById('control-disabled').checked = true; document.body.classList.add("loading"); fetch(api_url + "/disable-control", { method: "POST" }) .then(async (response) => { let delayres = await delay(100); refresh_buttons(); }); } } function enable_automatic_control() { if (!is_automatic_control) { document.getElementById('control-enabled').checked = true; document.body.classList.add("loading"); fetch(api_url + "/enable-control", { method: "POST" }) .then(async (response) => { let delayres = await delay(100); refresh_buttons(); }); } } function update_control_buttons(data) { current_max_rate = data.max_rate; current_min_rate = data.min_rate; var number_input_min = document.getElementById("min-rate"); if (number_input_min.disabled || number_input_min.value == "") { number_input_min.value = data.min_rate; number_input_min.disabled = false; } document.getElementById("set-minimum").disabled = (number_input_min.value == current_min_rate); var number_input_max = document.getElementById("max-rate"); if (number_input_max.disabled || number_input_max.value == "") { number_input_max.value = data.max_rate; number_input_max.disabled = false; } document.getElementById("set-maximum").disabled = (number_input_max.value == current_max_rate); document.body.classList.remove("loading"); is_automatic_control = data.control_enable; if (data.control_enable) { document.getElementById('control-enabled').checked = true; } else { document.getElementById('control-disabled').checked = true; } var control_selector = document.getElementById("control-selector"); if (data.is_charging_at_home) { if (control_selector.classList.contains('disabled')) { control_selector.classList.remove('disabled'); } document.getElementsByName('control').enable(); } else { if (!control_selector.classList.contains('disabled')) { control_selector.classList.add('disabled'); } document.getElementsByName('control').disable(); } } function refresh_gains() { fetch(api_url + "/pid-settings/status") .then((response) => response.json()) .then((json) => update_gains(json)); } function update_gains(data) { var proportional_set_button = document.getElementById("set-proportional"); var proportional_number_input = document.getElementById("proportional-gain"); proportional_set_button.disabled = false; proportional_number_input.disabled = false; proportional_number_input.value = data.proportional_gain; var derivative_set_button = document.getElementById("set-derivative"); var derivative_number_input = document.getElementById("derivative-gain"); derivative_set_button.disabled = false; derivative_number_input.disabled = false; derivative_number_input.value = data.derivative_gain; var load_divisor_button = document.getElementById("set-load-divisor"); var load_divisor_input = document.getElementById("load-divisor"); load_divisor_button.disabled = false; load_divisor_input.disabled = false; 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 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()) .catch(() => null) .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"); 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 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()) .then((json) => update_control_buttons(json)); } function refresh() { set_favicon(null); refresh_buttons(); fetch(api_url + "/car-state") .then((response) => response.json()) .then((json) => update_state(json)); } function refresh_info() { set_favicon(null); fetch(api_url + "/car-state") .then((response) => response.json()) .then((json) => update_info(json)); } function update_info(state) { set_favicon(state.charge_state); var info_div = document.getElementById("info"); while (info_div.childElementCount > 0) { info_div.removeChild(info_div.firstChild) } el = document.createElement('p'); state_json = document.createElement('pre'); state_json.appendChild(document.createTextNode(JSON.stringify(state, null, '\t'))); el.appendChild(state_json); info_div.appendChild(el); } function update_state(state) { set_favicon(state.charge_state); var info_div = document.getElementById("info"); while (info_div.childElementCount > 0) { info_div.removeChild(info_div.firstChild) } el = document.createElement('p'); var charging_state_info = ""; switch (state.charge_state.charging_state) { case "Charging": charging_state_info = "charging at " + state.charge_state.charge_rate + "A"; break; case "Stopped": charging_state_info = "charge stopped"; break; case "Disconnected": charging_state_info = "disconnected" break; } if (state.location_data.home) { if (state.charge_state.charging_state == "Charging") { charging_state_info = "set at " + state.charge_state.charge_current_request + "A, " + charging_state_info; } charging_state_info = "At home; " + charging_state_info; } else { charging_state_info = "Not home; " + charging_state_info; } el.appendChild(document.createTextNode(charging_state_info)); info_div.appendChild(el); } function set_favicon(charge_state) { let favicon = document.getElementById("favicon"); favicon.setAttribute("href", "data:image/svg+xml," + get_emoji(charge_state) + ""); } function get_emoji(charge_state) { if (charge_state == null) { return "âŗ"; } else if (charge_state.charge_rate > 0) { return "🔌"; } else if (charge_state.battery_level < 60) { return "đŸĒĢ" } else return "🔋"; }