diff options
author | Devaev Maxim <[email protected]> | 2020-09-03 06:51:02 +0300 |
---|---|---|
committer | Devaev Maxim <[email protected]> | 2020-09-03 06:51:11 +0300 |
commit | 68ab7ce33c5cfd5a8ae7c6682029191ccbfd49c3 (patch) | |
tree | 625d9513cae7301063e2f8191f5073945e9a7d07 /web | |
parent | 5307765399c1a3280eeb33380047195a118eb935 (diff) |
gpio ui
Diffstat (limited to 'web')
-rw-r--r-- | web/kvm/index.html | 3 | ||||
-rw-r--r-- | web/kvm/navbar-gpio.pug | 4 | ||||
-rw-r--r-- | web/kvm/navbar.pug | 1 | ||||
-rw-r--r-- | web/share/css/main.css | 7 | ||||
-rw-r--r-- | web/share/js/kvm/gpio.js | 163 | ||||
-rw-r--r-- | web/share/js/kvm/session.js | 5 |
6 files changed, 183 insertions, 0 deletions
diff --git a/web/kvm/index.html b/web/kvm/index.html index 727888ae..0c0b3ff0 100644 --- a/web/kvm/index.html +++ b/web/kvm/index.html @@ -328,6 +328,9 @@ </div> </div> </li> + <li class="right feature-disabled" id="gpio-dropdown"><a class="menu-button" id="gpio-menu-button" href="#">GPIO ↴</a> + <div class="menu" data-dont-hide-menu id="gpio-menu"></div> + </li> <li class="right"><a class="menu-button" href="#"><img class="led-gray" data-dont-hide-menu id="hid-recorder-led" src="/share/svg/led-gear.svg">Macro ↴</a> <div class="menu" data-dont-hide-menu> <div class="text"><b>Record and play keyboard & mouse actions<br></b><sub>For security reasons, the record will not saved on Pi-KVM</sub></div> diff --git a/web/kvm/navbar-gpio.pug b/web/kvm/navbar-gpio.pug new file mode 100644 index 00000000..280ba3fd --- /dev/null +++ b/web/kvm/navbar-gpio.pug @@ -0,0 +1,4 @@ +li(id="gpio-dropdown" class="right feature-disabled") + a(class="menu-button" id="gpio-menu-button" href="#") + | GPIO ↴ + div(data-dont-hide-menu id="gpio-menu" class="menu") diff --git a/web/kvm/navbar.pug b/web/kvm/navbar.pug index d7743160..422cf236 100644 --- a/web/kvm/navbar.pug +++ b/web/kvm/navbar.pug @@ -23,5 +23,6 @@ ul(id="navbar") include navbar-system.pug include navbar-atx.pug include navbar-msd.pug + include navbar-gpio.pug include navbar-macro.pug include navbar-shortcuts.pug diff --git a/web/share/css/main.css b/web/share/css/main.css index 443b637a..cfba1c11 100644 --- a/web/share/css/main.css +++ b/web/share/css/main.css @@ -94,6 +94,13 @@ img.inline-lamp { margin-right: 2px; } +img.inline-lamp-big { + vertical-align: middle; + height: 16px; + margin-left: 2px; + margin-right: 2px; +} + button, select { border: none; diff --git a/web/share/js/kvm/gpio.js b/web/share/js/kvm/gpio.js new file mode 100644 index 00000000..53644038 --- /dev/null +++ b/web/share/js/kvm/gpio.js @@ -0,0 +1,163 @@ +/***************************************************************************** +# # +# KVMD - The main Pi-KVM daemon. # +# # +# Copyright (C) 2018 Maxim Devaev <[email protected]> # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <https://www.gnu.org/licenses/>. # +# # +*****************************************************************************/ + + +"use strict"; + + +import {tools, $, $$$} from "../tools.js"; +import {wm} from "../wm.js"; + + +export function Gpio() { + var self = this; + + /************************************************************************/ + + var __state = null; + + /************************************************************************/ + + self.setState = function(state) { + if (state) { + for (let channel in state.inputs) { + let el = $(`gpio-led-${channel}`); + if (el) { + __setLedState(el, state.inputs[channel].state); + } + } + for (let channel in state.outputs) { + for (let type of ["switch", "button"]) { + let el = $(`gpio-${type}-${channel}`); + if (el) { + wm.switchEnabled(el, !state.outputs[channel].busy); + } + } + } + } else { + for (let el of $$$(".gpio-led")) { + __setLedState(el, false); + } + for (let selector of [".gpio-switch", ".gpio-button"]) { + for (let el of $$$(selector)) { + wm.switchEnabled(el, false); + } + } + } + __state = state; + }; + + self.setModel = function(model) { + tools.featureSetEnabled($("gpio-dropdown"), model.view.table.length); + if (model.view.table.length) { + $("gpio-menu-button").innerHTML = `${model.view.header.title} ↴`; + } + + let switches = []; + let buttons = []; + let content = "<table class=\"kv\">"; + for (let row of model.view.table) { + if (row === null) { + content += "</table><hr><table class=\"kv\">"; + } else { + content += "<tr>"; + for (let item of row) { + if (item.type === "output") { + item.scheme = model.scheme.outputs[item.channel]; + } + content += `<td>${__createItem(item, switches, buttons)}</td>`; + } + content += "</tr>"; + } + } + content += "</table>"; + $("gpio-menu").innerHTML = content; + + for (let channel of switches) { + tools.setOnClick($(`gpio-switch-${channel}`), () => __switchChannel(channel)); + } + for (let channel of buttons) { + tools.setOnClick($(`gpio-button-${channel}`), () => __pulseChannel(channel)); + } + + self.setState(__state); + }; + + var __createItem = function(item, switches, buttons) { + if (item.type === "label") { + return item.text; + } else if (item.type === "input") { + return `<img id="gpio-led-${item.channel}" class="gpio-led inline-lamp-big led-gray" src="/share/svg/led-square.svg" />`; + } else if (item.type === "output") { + let controls = []; + if (item.scheme["switch"]) { + switches.push(item.channel); + controls.push(` + <td><div class="switch-box"> + <input disabled type="checkbox" id="gpio-switch-${item.channel}" class="gpio-switch" /> + <label for="gpio-switch-${item.channel}"> + <span class="switch-inner"></span> + <span class="switch"></span> + </label> + </div></td> + `); + } + if (item.scheme.pulse.delay) { + buttons.push(item.channel); + controls.push(`<td><button disabled id="gpio-button-${item.channel}" class="gpio-button">${item.text}</button></td>`); + } + return `<table><tr>${controls.join("<td> </td>")}</tr></table>`; + } else { + return ""; + } + }; + + var __setLedState = function(el, state) { + if (state) { + el.classList.add("led-green"); + el.classList.remove("led-gray"); + } else { + el.classList.add("led-gray"); + el.classList.remove("led-green"); + } + }; + + var __switchChannel = function(channel) { + let to = ($(`gpio-switch-${channel}`).checked ? "1" : "0"); + __sendPost(`/api/gpio/switch?channel=${channel}&state=${to}`); + }; + + var __pulseChannel = function(channel) { + __sendPost(`/api/gpio/pulse?channel=${channel}`); + }; + + var __sendPost = function(url) { + let http = tools.makeRequest("POST", url, function() { + if (http.readyState === 4) { + if (http.status === 409) { + wm.error("Performing another operation for this GPIO channel.<br>Please try again later"); + } else if (http.status !== 200) { + wm.error("GPIO error:<br>", http.responseText); + } + } + }); + }; +} diff --git a/web/share/js/kvm/session.js b/web/share/js/kvm/session.js index 06ffcd95..7112d51c 100644 --- a/web/share/js/kvm/session.js +++ b/web/share/js/kvm/session.js @@ -31,6 +31,7 @@ import {Atx} from "./atx.js"; import {Msd} from "./msd.js"; import {Streamer} from "./stream.js"; import {WakeOnLan} from "./wol.js"; +import {Gpio} from "./gpio.js"; export function Session() { @@ -48,6 +49,7 @@ export function Session() { var __msd = new Msd(); var __streamer = new Streamer(); var __wol = new WakeOnLan(); + var __gpio = new Gpio(); var __init__ = function() { __startSession(); @@ -211,6 +213,8 @@ export function Session() { case "info_hw_state": __setAboutInfoHw(data.event); break; case "info_system_state": __setAboutInfoSystem(data.event); break; case "wol_state": __wol.setState(data.event); break; + case "gpio_model_state": __gpio.setModel(data.event); break; + case "gpio_state": __gpio.setState(data.event); break; case "hid_state": __hid.setState(data.event); break; case "atx_state": __atx.setState(data.event); break; case "msd_state": __msd.setState(data.event); break; @@ -237,6 +241,7 @@ export function Session() { __ping_timer = null; } + __gpio.setState(null); __hid.setSocket(null); __atx.setState(null); __msd.setState(null); |