summaryrefslogtreecommitdiff
path: root/web
diff options
context:
space:
mode:
Diffstat (limited to 'web')
-rw-r--r--web/kvm/index.html38
-rw-r--r--web/kvm/navbar-health.pug13
-rw-r--r--web/kvm/window-about.pug2
-rw-r--r--web/share/js/kvm/session.js133
4 files changed, 148 insertions, 38 deletions
diff --git a/web/kvm/index.html b/web/kvm/index.html
index 1000ddaa..1007bb99 100644
--- a/web/kvm/index.html
+++ b/web/kvm/index.html
@@ -106,6 +106,38 @@
</div>
</li>
</div>
+ <div class="hidden" id="fan-health-dropdown">
+ <li class="left"><a class="menu-button" href="#"><img class="hidden" data-dont-hide-menu id="fan-health-led" src="/share/svg/led-fan.svg"></a>
+ <div class="menu" data-dont-hide-menu>
+ <div class="text">
+ <table>
+ <tr>
+ <td rowspan="2"><img class="sign " src="/share/svg/warning.svg"></td>
+ <td style="line-height:1.5"><b>Raspberry Pi's health is at risk</b></td>
+ </tr>
+ <tr>
+ <td><sup style="line-height:1">This is not a drill! A red icon indicates a current issue,<br>
+ a yellow one that was observed in the past</sup></td>
+ </tr>
+ </table>
+ </div>
+ <div id="fan-health-message-fail">
+ <hr>
+ <div class="text">
+ <table>
+ <tr>
+ <td rowspan="2"><img class="sign led-gray" src="/share/svg/led-fan.svg"></td>
+ <td style="line-height:1.5"><b>Fan failed</b></td>
+ </tr>
+ <tr>
+ <td><sup style="line-height:1">A fan error occured, please check the log</sup></td>
+ </tr>
+ </table>
+ </div>
+ </div>
+ </div>
+ </li>
+ </div>
<li class="right"><a class="menu-button" href="#"><img class="led-gray" data-dont-hide-menu id="link-led" src="/share/svg/led-link.svg"><img class="led-gray" data-dont-hide-menu id="stream-led" src="/share/svg/led-stream.svg"><img class="led-gray" data-dont-hide-menu id="hid-keyboard-led" src="/share/svg/led-hid-keyboard.svg"><img class="led-gray" data-dont-hide-menu id="hid-mouse-led" src="/share/svg/led-hid-mouse.svg">System</a>
<div class="menu" data-dont-hide-menu>
<table class="kv" style="width: calc(100% - 20px)">
@@ -1539,10 +1571,10 @@
<div class="code" id="about-meta"><span class="code-comment">No data</span>
</div>
</div>
- <input type="radio" name="about-tab-button" id="about-tab-hw-button">
- <label for="about-tab-hw-button">Hardware</label>
+ <input type="radio" name="about-tab-button" id="about-tab-hardware-button">
+ <label for="about-tab-hardware-button">Hardware</label>
<div class="tab">
- <div class="code" id="about-hw"><span class="code-comment">No data</span>
+ <div class="code" id="about-hardware"><span class="code-comment">No data</span>
</div>
</div>
<input type="radio" name="about-tab-button" id="about-tab-version-button">
diff --git a/web/kvm/navbar-health.pug b/web/kvm/navbar-health.pug
index 91003bab..455f0339 100644
--- a/web/kvm/navbar-health.pug
+++ b/web/kvm/navbar-health.pug
@@ -17,3 +17,16 @@ div(id="hw-health-dropdown" class="hidden")
+menu_message("led-overheating", "Overheating detected", "led-gray")
| Frequency capping due to overheating,#[br]
| improve cooling of the Raspberry Pi
+
+div(id="fan-health-dropdown" class="hidden")
+ li(class="left")
+ a(class="menu-button" href="#")
+ +navbar_led("fan-health-led", "led-fan", "hidden")
+ div(data-dont-hide-menu class="menu")
+ +menu_message("warning", "Raspberry Pi's health is at risk")
+ | This is not a drill! A red icon indicates a current issue,#[br]
+ | a yellow one that was observed in the past
+ div(id="fan-health-message-fail")
+ hr
+ +menu_message("led-fan", "Fan failed", "led-gray")
+ | A fan error occured, please check the log
diff --git a/web/kvm/window-about.pug b/web/kvm/window-about.pug
index 830ddb10..18b5f23c 100644
--- a/web/kvm/window-about.pug
+++ b/web/kvm/window-about.pug
@@ -28,7 +28,7 @@ div(id="about-window" class="window")
br
div(class="tabs-box")
+about_tab("meta", "Meta", true)
- +about_tab("hw", "Hardware")
+ +about_tab("hardware", "Hardware")
+about_tab("version", "Version")
+about_tab("thanks", "Thanks")
diff --git a/web/share/js/kvm/session.js b/web/share/js/kvm/session.js
index 68320655..72d75ab6 100644
--- a/web/share/js/kvm/session.js
+++ b/web/share/js/kvm/session.js
@@ -53,6 +53,9 @@ export function Session() {
var __gpio = new Gpio(__recorder);
var __ocr = new Ocr(__streamer.getGeometry);
+ var __info_hw_state = null;
+ var __info_fan_state = null;
+
var __init__ = function() {
__startSession();
};
@@ -86,16 +89,6 @@ export function Session() {
};
var __setAboutInfoHw = function(state) {
- $("about-hw").innerHTML = `
- Platform base: <span class="code-comment">${state.platform.base}</span><br>
- <hr>
- Temperature:
- ${__formatTemp(state.health.temp)}
- <hr>
- Throttling:
- ${__formatThrottling(state.health.throttling)}
- `;
-
if (state.health.throttling !== null) {
let flags = state.health.throttling.parsed_flags;
let undervoltage = (flags.undervoltage.now || flags.undervoltage.past);
@@ -107,31 +100,74 @@ export function Session() {
tools.hidden.setVisible($("hw-health-message-undervoltage"), undervoltage);
tools.hidden.setVisible($("hw-health-message-overheating"), freq_capped);
}
+ __info_hw_state = state;
+ __renderAboutInfoHardware();
};
- var __setExtras = function(state) {
- let show_hook = null;
- let close_hook = null;
- let has_webterm = (state.webterm && (state.webterm.enabled || state.webterm.started));
- if (has_webterm) {
- let path = "/" + state.webterm.path;
- show_hook = function() {
- tools.info("Terminal opened: ", path);
- $("webterm-iframe").src = path;
- };
- close_hook = function() {
- tools.info("Terminal closed");
- $("webterm-iframe").src = "";
- };
+ var __setAboutInfoFan = function(state) {
+ let failed = false;
+ let failed_past = false;
+ if (state.monitored) {
+ if (state.state === null) {
+ failed = true;
+ } else {
+ if (!state.state.fan.ok) {
+ failed = true;
+ } else if (state.state.fan.last_fail_ts >= 0) {
+ failed = true;
+ failed_past = true;
+ }
+ }
}
- tools.feature.setEnabled($("webterm"), has_webterm);
- $("webterm-window").show_hook = show_hook;
- $("webterm-window").close_hook = close_hook;
+ tools.hidden.setVisible($("fan-health-dropdown"), failed);
+ $("fan-health-led").className = (failed ? (failed_past ? "led-yellow" : "led-red") : "hidden");
- __streamer.setJanusEnabled(
- (state.janus && (state.janus.enabled || state.janus.started))
- || (state.janus_static && (state.janus_static.enabled || state.janus_static.started))
- );
+ __info_fan_state = state;
+ __renderAboutInfoHardware();
+ };
+
+ var __renderAboutInfoHardware = function() {
+ let html = "";
+ if (__info_hw_state !== null) {
+ html += `
+ Platform base: <span class="code-comment">${__info_hw_state.platform.base}</span><br>
+ <hr>
+ Temperature:
+ ${__formatTemp(__info_hw_state.health.temp)}
+ <hr>
+ Throttling:
+ ${__formatThrottling(__info_hw_state.health.throttling)}
+ `;
+ }
+ if (__info_fan_state !== null) {
+ if (html.length > 0) {
+ html += "<hr>";
+ }
+ html += `
+ Fan:
+ ${__formatFan(__info_fan_state)}
+ `;
+ }
+ $("about-hardware").innerHTML = html;
+ };
+
+ var __formatFan = function(state) {
+ if (!state.monitored) {
+ return __formatUl([["Status", "Not monitored"]]);
+ } else if (state.state === null) {
+ return __formatUl([["Status", __colored("red", "Not available")]]);
+ } else {
+ state = state.state;
+ let pairs = [
+ ["Status", (state.fan.ok ? __colored("green", "Ok") : __colored("red", "Failed"))],
+ ["Desired speed", `${state.fan.speed}%`],
+ ["PWM", `${state.fan.pwm}`],
+ ];
+ if (state.hall.available) {
+ pairs.push(["RPM", __colored((state.fan.ok ? "green" : "red"), state.hall.rpm)]);
+ }
+ return __formatUl(pairs);
+ }
};
var __formatTemp = function(temp) {
@@ -158,13 +194,16 @@ export function Session() {
};
var __formatThrottleError = function(flags) {
- let colored = ((color, text) => `<font color="${color}">${text}</font>`);
return `
- ${flags["now"] ? colored("red", "RIGHT NOW") : colored("green", "No")};
- ${flags["past"] ? colored("red", "In the past") : colored("green", "Never")}
+ ${flags["now"] ? __colored("red", "RIGHT NOW") : __colored("green", "No")};
+ ${flags["past"] ? __colored("red", "In the past") : __colored("green", "Never")}
`;
};
+ var __colored = function(color, text) {
+ return `<font color="${color}">${text}</font>`;
+ };
+
var __setAboutInfoSystem = function(state) {
$("about-version").innerHTML = `
KVMD: <span class="code-comment">${state.kvmd.version}</span><br>
@@ -203,6 +242,31 @@ export function Session() {
return text + "</ul>";
};
+ var __setExtras = function(state) {
+ let show_hook = null;
+ let close_hook = null;
+ let has_webterm = (state.webterm && (state.webterm.enabled || state.webterm.started));
+ if (has_webterm) {
+ let path = "/" + state.webterm.path;
+ show_hook = function() {
+ tools.info("Terminal opened: ", path);
+ $("webterm-iframe").src = path;
+ };
+ close_hook = function() {
+ tools.info("Terminal closed");
+ $("webterm-iframe").src = "";
+ };
+ }
+ tools.feature.setEnabled($("webterm"), has_webterm);
+ $("webterm-window").show_hook = show_hook;
+ $("webterm-window").close_hook = close_hook;
+
+ __streamer.setJanusEnabled(
+ (state.janus && (state.janus.enabled || state.janus.started))
+ || (state.janus_static && (state.janus_static.enabled || state.janus_static.started))
+ );
+ };
+
var __startSession = function() {
$("link-led").className = "led-yellow";
$("link-led").title = "Connecting...";
@@ -244,6 +308,7 @@ export function Session() {
case "pong": __missed_heartbeats = 0; break;
case "info_meta_state": __setAboutInfoMeta(data.event); break;
case "info_hw_state": __setAboutInfoHw(data.event); break;
+ case "info_fan_state": __setAboutInfoFan(data.event); break;
case "info_system_state": __setAboutInfoSystem(data.event); break;
case "info_extras_state": __setExtras(data.event); break;
case "gpio_model_state": __gpio.setModel(data.event); break;