mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2025-12-12 09:10:30 +08:00
gpio ui
This commit is contained in:
parent
5307765399
commit
68ab7ce33c
@ -187,6 +187,7 @@ def _patch_dynamic( # pylint: disable=too-many-locals
|
|||||||
}
|
}
|
||||||
if mode == "output":
|
if mode == "output":
|
||||||
ch_scheme.update({
|
ch_scheme.update({
|
||||||
|
"busy_delay": Option(0.2, type=valid_float_f01),
|
||||||
"initial": Option(False, type=valid_bool),
|
"initial": Option(False, type=valid_bool),
|
||||||
"switch": Option(True, type=valid_bool),
|
"switch": Option(True, type=valid_bool),
|
||||||
"pulse": {
|
"pulse": {
|
||||||
@ -328,8 +329,7 @@ def _get_config_scheme() -> Dict:
|
|||||||
"scheme": {}, # Dymanic content
|
"scheme": {}, # Dymanic content
|
||||||
"view": {
|
"view": {
|
||||||
"header": {
|
"header": {
|
||||||
"title": Option("Switches"),
|
"title": Option("GPIO"),
|
||||||
"leds": Option([], type=valid_string_list),
|
|
||||||
},
|
},
|
||||||
"table": Option([], type=valid_ugpio_view_table),
|
"table": Option([], type=valid_ugpio_view_table),
|
||||||
},
|
},
|
||||||
|
|||||||
@ -44,8 +44,7 @@ class UserGpioApi:
|
|||||||
@exposed_http("GET", "/gpio")
|
@exposed_http("GET", "/gpio")
|
||||||
async def __state_handler(self, _: Request) -> Response:
|
async def __state_handler(self, _: Request) -> Response:
|
||||||
return make_json_response({
|
return make_json_response({
|
||||||
"scheme": (await self.__user_gpio.get_scheme()),
|
"model": (await self.__user_gpio.get_model()),
|
||||||
"view": (await self.__user_gpio.get_view()),
|
|
||||||
"state": (await self.__user_gpio.get_state()),
|
"state": (await self.__user_gpio.get_state()),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -243,8 +243,7 @@ class KvmdServer(HttpServer): # pylint: disable=too-many-arguments,too-many-ins
|
|||||||
await client.ws.prepare(request)
|
await client.ws.prepare(request)
|
||||||
await self.__register_ws_client(client)
|
await self.__register_ws_client(client)
|
||||||
try:
|
try:
|
||||||
await self.__broadcast_event("gpio_scheme_state", await self.__user_gpio.get_scheme())
|
await self.__broadcast_event("gpio_model_state", await self.__user_gpio.get_model())
|
||||||
await self.__broadcast_event("gpio_view_state", await self.__user_gpio.get_view())
|
|
||||||
await asyncio.gather(*[
|
await asyncio.gather(*[
|
||||||
self.__broadcast_event(component.event_type, await component.get_state())
|
self.__broadcast_event(component.event_type, await component.get_state())
|
||||||
for component in self.__components
|
for component in self.__components
|
||||||
|
|||||||
@ -23,6 +23,7 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import operator
|
import operator
|
||||||
|
|
||||||
|
from typing import List
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
from typing import AsyncGenerator
|
from typing import AsyncGenerator
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
@ -88,6 +89,7 @@ class _GpioOutput: # pylint: disable=too-many-instance-attributes
|
|||||||
self.__pulse_delay: float = config.pulse.delay
|
self.__pulse_delay: float = config.pulse.delay
|
||||||
self.__min_pulse_delay: float = config.pulse.min_delay
|
self.__min_pulse_delay: float = config.pulse.min_delay
|
||||||
self.__max_pulse_delay: float = config.pulse.max_delay
|
self.__max_pulse_delay: float = config.pulse.max_delay
|
||||||
|
self.__busy_delay: float = config.busy_delay
|
||||||
|
|
||||||
self.__state = config.initial
|
self.__state = config.initial
|
||||||
self.__region = aiotools.AioExclusiveRegion(GpioChannelIsBusyError, notifier)
|
self.__region = aiotools.AioExclusiveRegion(GpioChannelIsBusyError, notifier)
|
||||||
@ -97,8 +99,8 @@ class _GpioOutput: # pylint: disable=too-many-instance-attributes
|
|||||||
"switch": self.__switch,
|
"switch": self.__switch,
|
||||||
"pulse": {
|
"pulse": {
|
||||||
"delay": self.__pulse_delay,
|
"delay": self.__pulse_delay,
|
||||||
"min_delay": self.__min_pulse_delay,
|
"min_delay": (self.__min_pulse_delay if self.__pulse_delay else 0),
|
||||||
"max_delay": self.__max_pulse_delay,
|
"max_delay": (self.__max_pulse_delay if self.__pulse_delay else 0),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,8 +127,10 @@ class _GpioOutput: # pylint: disable=too-many-instance-attributes
|
|||||||
self.__write(state)
|
self.__write(state)
|
||||||
self.__state = state
|
self.__state = state
|
||||||
get_logger(0).info("Switched GPIO %s to %d", self, state)
|
get_logger(0).info("Switched GPIO %s to %d", self, state)
|
||||||
|
await asyncio.sleep(self.__busy_delay)
|
||||||
return True
|
return True
|
||||||
self.__state = real_state
|
self.__state = real_state
|
||||||
|
await asyncio.sleep(self.__busy_delay)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@aiotools.atomic
|
@aiotools.atomic
|
||||||
@ -146,7 +150,7 @@ class _GpioOutput: # pylint: disable=too-many-instance-attributes
|
|||||||
await asyncio.sleep(delay)
|
await asyncio.sleep(delay)
|
||||||
finally:
|
finally:
|
||||||
self.__write(False)
|
self.__write(False)
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(self.__busy_delay)
|
||||||
get_logger(0).info("Pulsed GPIO %s", self)
|
get_logger(0).info("Pulsed GPIO %s", self)
|
||||||
|
|
||||||
def __read(self) -> bool:
|
def __read(self) -> bool:
|
||||||
@ -185,15 +189,15 @@ class UserGpio:
|
|||||||
else: # output:
|
else: # output:
|
||||||
self.__outputs[channel] = _GpioOutput(channel, ch_config, self.__state_notifier)
|
self.__outputs[channel] = _GpioOutput(channel, ch_config, self.__state_notifier)
|
||||||
|
|
||||||
async def get_scheme(self) -> Dict:
|
async def get_model(self) -> Dict:
|
||||||
return {
|
return {
|
||||||
"inputs": {channel: gin.get_scheme() for (channel, gin) in self.__inputs.items()},
|
"scheme": {
|
||||||
"outputs": {channel: gout.get_scheme() for (channel, gout) in self.__outputs.items()},
|
"inputs": {channel: gin.get_scheme() for (channel, gin) in self.__inputs.items()},
|
||||||
|
"outputs": {channel: gout.get_scheme() for (channel, gout) in self.__outputs.items()},
|
||||||
|
},
|
||||||
|
"view": self.__make_view(),
|
||||||
}
|
}
|
||||||
|
|
||||||
async def get_view(self) -> Dict:
|
|
||||||
return self.__view
|
|
||||||
|
|
||||||
async def get_state(self) -> Dict:
|
async def get_state(self) -> Dict:
|
||||||
return {
|
return {
|
||||||
"inputs": {channel: gin.get_state() for (channel, gin) in self.__inputs.items()},
|
"inputs": {channel: gin.get_state() for (channel, gin) in self.__inputs.items()},
|
||||||
@ -240,3 +244,37 @@ class UserGpio:
|
|||||||
if gout is None:
|
if gout is None:
|
||||||
raise GpioChannelNotFoundError()
|
raise GpioChannelNotFoundError()
|
||||||
await gout.pulse(delay)
|
await gout.pulse(delay)
|
||||||
|
|
||||||
|
# =====
|
||||||
|
|
||||||
|
def __make_view(self) -> Dict:
|
||||||
|
table: List[Optional[List[Dict]]] = []
|
||||||
|
for row in self.__view["table"]:
|
||||||
|
if len(row) == 0:
|
||||||
|
table.append(None)
|
||||||
|
continue
|
||||||
|
|
||||||
|
items: List[Dict] = []
|
||||||
|
for item in map(str.strip, row):
|
||||||
|
if item.startswith("#") or len(item) == 0:
|
||||||
|
items.append({
|
||||||
|
"type": "label",
|
||||||
|
"text": item[1:].strip(),
|
||||||
|
})
|
||||||
|
elif (parts := list(map(str.strip, item.split(",", 1)))):
|
||||||
|
if parts[0] in self.__inputs:
|
||||||
|
items.append({
|
||||||
|
"type": "input",
|
||||||
|
"channel": parts[0],
|
||||||
|
})
|
||||||
|
elif parts[0] in self.__outputs:
|
||||||
|
items.append({
|
||||||
|
"type": "output",
|
||||||
|
"channel": parts[0],
|
||||||
|
"text": (parts[1] if len(parts) > 1 else "Click"),
|
||||||
|
})
|
||||||
|
table.append(items)
|
||||||
|
return {
|
||||||
|
"header": self.__view["header"],
|
||||||
|
"table": table,
|
||||||
|
}
|
||||||
|
|||||||
@ -37,6 +37,77 @@ kvmd:
|
|||||||
- "--notify-parent"
|
- "--notify-parent"
|
||||||
- "--no-log-colors"
|
- "--no-log-colors"
|
||||||
|
|
||||||
|
gpio:
|
||||||
|
scheme:
|
||||||
|
host1: # any name like foo_bar_baz
|
||||||
|
pin: 1
|
||||||
|
mode: input
|
||||||
|
host2:
|
||||||
|
pin: 2
|
||||||
|
mode: input
|
||||||
|
host3:
|
||||||
|
pin: 3
|
||||||
|
mode: input
|
||||||
|
host4:
|
||||||
|
pin: 4
|
||||||
|
mode: input
|
||||||
|
change_host:
|
||||||
|
pin: 5
|
||||||
|
mode: output
|
||||||
|
switch: false
|
||||||
|
|
||||||
|
host1_pwr:
|
||||||
|
pin: 11
|
||||||
|
mode: input
|
||||||
|
host2_pwr:
|
||||||
|
pin: 12
|
||||||
|
mode: input
|
||||||
|
host3_pwr:
|
||||||
|
pin: 13
|
||||||
|
mode: input
|
||||||
|
host4_pwr:
|
||||||
|
pin: 14
|
||||||
|
mode: input
|
||||||
|
|
||||||
|
host1_pwr_btn:
|
||||||
|
pin: 21
|
||||||
|
mode: output
|
||||||
|
switch: false
|
||||||
|
host2_pwr_btn:
|
||||||
|
pin: 22
|
||||||
|
mode: output
|
||||||
|
switch: false
|
||||||
|
host3_pwr_btn:
|
||||||
|
pin: 23
|
||||||
|
mode: output
|
||||||
|
switch: false
|
||||||
|
host4_pwr_btn:
|
||||||
|
pin: 24
|
||||||
|
mode: output
|
||||||
|
switch: false
|
||||||
|
|
||||||
|
lamp:
|
||||||
|
pin: 50
|
||||||
|
mode: output
|
||||||
|
pulse:
|
||||||
|
delay: 0
|
||||||
|
|
||||||
|
view:
|
||||||
|
header:
|
||||||
|
title: Switch
|
||||||
|
table:
|
||||||
|
- ["#Multihost controller"]
|
||||||
|
- []
|
||||||
|
- ["", "#Current", "#Power"]
|
||||||
|
- ["#host1.localdomain:", host1, host1_pwr, "host1_pwr_btn,Pwr"]
|
||||||
|
- ["#host2.localdomain:", host2, host2_pwr, "host2_pwr_btn,Pwr"]
|
||||||
|
- ["#host3.localdomain:", host3, host3_pwr, "host3_pwr_btn,Pwr"]
|
||||||
|
- ["#host4.localdomain:", host4, host4_pwr, "host4_pwr_btn,Pwr"]
|
||||||
|
- []
|
||||||
|
- ["change_host,Change host"]
|
||||||
|
- []
|
||||||
|
- ["#Lamp in the rack", lamp]
|
||||||
|
|
||||||
vnc:
|
vnc:
|
||||||
keymap: /usr/share/kvmd/keymaps/ru
|
keymap: /usr/share/kvmd/keymaps/ru
|
||||||
|
|
||||||
|
|||||||
@ -328,6 +328,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</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>
|
<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="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>
|
<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>
|
||||||
|
|||||||
4
web/kvm/navbar-gpio.pug
Normal file
4
web/kvm/navbar-gpio.pug
Normal file
@ -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")
|
||||||
@ -23,5 +23,6 @@ ul(id="navbar")
|
|||||||
include navbar-system.pug
|
include navbar-system.pug
|
||||||
include navbar-atx.pug
|
include navbar-atx.pug
|
||||||
include navbar-msd.pug
|
include navbar-msd.pug
|
||||||
|
include navbar-gpio.pug
|
||||||
include navbar-macro.pug
|
include navbar-macro.pug
|
||||||
include navbar-shortcuts.pug
|
include navbar-shortcuts.pug
|
||||||
|
|||||||
@ -94,6 +94,13 @@ img.inline-lamp {
|
|||||||
margin-right: 2px;
|
margin-right: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
img.inline-lamp-big {
|
||||||
|
vertical-align: middle;
|
||||||
|
height: 16px;
|
||||||
|
margin-left: 2px;
|
||||||
|
margin-right: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
button,
|
button,
|
||||||
select {
|
select {
|
||||||
border: none;
|
border: none;
|
||||||
|
|||||||
163
web/share/js/kvm/gpio.js
Normal file
163
web/share/js/kvm/gpio.js
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
# #
|
||||||
|
# KVMD - The main Pi-KVM daemon. #
|
||||||
|
# #
|
||||||
|
# Copyright (C) 2018 Maxim Devaev <mdevaev@gmail.com> #
|
||||||
|
# #
|
||||||
|
# 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -31,6 +31,7 @@ import {Atx} from "./atx.js";
|
|||||||
import {Msd} from "./msd.js";
|
import {Msd} from "./msd.js";
|
||||||
import {Streamer} from "./stream.js";
|
import {Streamer} from "./stream.js";
|
||||||
import {WakeOnLan} from "./wol.js";
|
import {WakeOnLan} from "./wol.js";
|
||||||
|
import {Gpio} from "./gpio.js";
|
||||||
|
|
||||||
|
|
||||||
export function Session() {
|
export function Session() {
|
||||||
@ -48,6 +49,7 @@ export function Session() {
|
|||||||
var __msd = new Msd();
|
var __msd = new Msd();
|
||||||
var __streamer = new Streamer();
|
var __streamer = new Streamer();
|
||||||
var __wol = new WakeOnLan();
|
var __wol = new WakeOnLan();
|
||||||
|
var __gpio = new Gpio();
|
||||||
|
|
||||||
var __init__ = function() {
|
var __init__ = function() {
|
||||||
__startSession();
|
__startSession();
|
||||||
@ -211,6 +213,8 @@ export function Session() {
|
|||||||
case "info_hw_state": __setAboutInfoHw(data.event); break;
|
case "info_hw_state": __setAboutInfoHw(data.event); break;
|
||||||
case "info_system_state": __setAboutInfoSystem(data.event); break;
|
case "info_system_state": __setAboutInfoSystem(data.event); break;
|
||||||
case "wol_state": __wol.setState(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 "hid_state": __hid.setState(data.event); break;
|
||||||
case "atx_state": __atx.setState(data.event); break;
|
case "atx_state": __atx.setState(data.event); break;
|
||||||
case "msd_state": __msd.setState(data.event); break;
|
case "msd_state": __msd.setState(data.event); break;
|
||||||
@ -237,6 +241,7 @@ export function Session() {
|
|||||||
__ping_timer = null;
|
__ping_timer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__gpio.setState(null);
|
||||||
__hid.setSocket(null);
|
__hid.setSocket(null);
|
||||||
__atx.setState(null);
|
__atx.setState(null);
|
||||||
__msd.setState(null);
|
__msd.setState(null);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user