v0.4. Daemon modules, LED control

This commit is contained in:
gSpot
2021-12-08 20:58:14 +03:00
parent 54f13984a3
commit 29eb4e8a71
14 changed files with 451 additions and 249 deletions

View File

@@ -1,30 +1,38 @@
# Internet detector for OpenWrt.
Checking Internet availability.
Internet-detector is an application for checking the availability of the Internet. Performs periodic connections to a known public host (8.8.8.8, 1.1.1.1) and determines the actual Internet availability.
OpenWrt >= 19.07.
**OpenWrt** >= 19.07.
Dependences: lua, luci-lib-nixio, libuci-lua
**Dependences:** lua, luci-lib-nixio, libuci-lua.
**Features:**
- It can run continuously as a system service or only in an open web interface.
- Checking the availability of a host using ping or by connecting via TCP to a specified port.
- Execution of custom shell scripts when connecting and disconnecting the Internet.
- LED indication of Internet availability.
![](https://github.com/gSpotx2f/luci-app-internet-detector/blob/master/screenshots/internet-led.jpg)
- The daemon is written entirely in Lua using the nixio library.
## Installation notes
**OpenWrt >= 21.02:**
wget --no-check-certificate -O /tmp/internet-detector_0.3.0-2_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/internet-detector_0.3.0-2_all.ipk
opkg install /tmp/internet-detector_0.3.0-2_all.ipk
rm /tmp/internet-detector_0.3.0-2_all.ipk
wget --no-check-certificate -O /tmp/internet-detector_0.4-1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/internet-detector_0.4-1_all.ipk
opkg install /tmp/internet-detector_0.4-1_all.ipk
rm /tmp/internet-detector_0.4-1_all.ipk
/etc/init.d/internet-detector start
/etc/init.d/internet-detector enable
wget --no-check-certificate -O /tmp/luci-app-internet-detector_0.3.0-3_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/luci-app-internet-detector_0.3.0-3_all.ipk
opkg install /tmp/luci-app-internet-detector_0.3.0-3_all.ipk
rm /tmp/luci-app-internet-detector_0.3.0-3_all.ipk
wget --no-check-certificate -O /tmp/luci-app-internet-detector_0.4-1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/luci-app-internet-detector_0.4-1_all.ipk
opkg install /tmp/luci-app-internet-detector_0.4-1_all.ipk
rm /tmp/luci-app-internet-detector_0.4-1_all.ipk
/etc/init.d/rpcd restart
i18n-ru:
wget --no-check-certificate -O /tmp/luci-i18n-internet-detector-ru_0.3.0-3_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/luci-i18n-internet-detector-ru_0.3.0-3_all.ipk
opkg install /tmp/luci-i18n-internet-detector-ru_0.3.0-3_all.ipk
rm /tmp/luci-i18n-internet-detector-ru_0.3.0-3_all.ipk
wget --no-check-certificate -O /tmp/luci-i18n-internet-detector-ru_0.4-1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/luci-i18n-internet-detector-ru_0.4-1_all.ipk
opkg install /tmp/luci-i18n-internet-detector-ru_0.4-1_all.ipk
rm /tmp/luci-i18n-internet-detector-ru_0.4-1_all.ipk
**OpenWrt 19.07:**
@@ -45,20 +53,6 @@ i18n-ru:
opkg install /tmp/luci-i18n-internet-detector-ru_0.3.0-2_all.ipk
rm /tmp/luci-i18n-internet-detector-ru_0.3.0-2_all.ipk
## Script for LED control:
![](https://github.com/gSpotx2f/luci-app-internet-detector/blob/master/screenshots/internet-led.jpg)
LED is on when Internet is available. A specific LED can be set in `/etc/internet-detector/run-script` (`LEDN`), either by number or by name from /sys/class/leds/*****. The list of available LEDs can be obtained using the command: `/usr/bin/internet-detector-led.sh list`.
wget --no-check-certificate -O /usr/bin/internet-detector-led.sh https://github.com/gSpotx2f/luci-app-internet-detector/raw/master/led/usr/bin/internet-detector-led.sh
chmod +x /usr/bin/internet-detector-led.sh
wget --no-check-certificate -O /etc/internet-detector/run-script https://github.com/gSpotx2f/luci-app-internet-detector/raw/master/led/etc/internet-detector/run-script
chmod +x /etc/internet-detector/run-script
uci set internet-detector.config.enable_run_script='1'
uci commit
/etc/init.d/internet-detector restart
## Screenshots:
![](https://github.com/gSpotx2f/luci-app-internet-detector/blob/master/screenshots/01.jpg)

View File

@@ -5,8 +5,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=internet-detector
PKG_VERSION:=0.3.0
PKG_RELEASE:=2
PKG_VERSION:=0.4
PKG_RELEASE:=1
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/luci-app-internet-detector>
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
@@ -39,6 +39,8 @@ endef
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/usr/bin/internet-detector $(1)/usr/bin/internet-detector
$(INSTALL_DIR) $(1)/usr/lib/internet-detector
$(INSTALL_DATA) $(PKG_BUILD_DIR)/files/usr/lib/internet-detector/mod_led_control.lua $(1)/usr/lib/internet-detector/mod_led_control.lua
$(INSTALL_DIR) $(1)/etc/internet-detector
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/etc/internet-detector/down-script $(1)/etc/internet-detector/down-script
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/etc/internet-detector/run-script $(1)/etc/internet-detector/run-script

View File

@@ -1,18 +1,25 @@
config main 'config'
option mode '2'
list hosts '8.8.8.8'
list hosts '1.1.1.1'
option check_type '0'
option tcp_port '53'
config main 'ui_config'
option interval_up '6'
option interval_down '1'
option connection_attempts '1'
option connection_timeout '1'
config main 'service_config'
option interval_up '30'
option interval_down '5'
option connection_attempts '2'
option connection_timeout '2'
option enable_logger '1'
option enable_up_script '0'
option enable_down_script '0'
option enable_run_script '0'
option interval_up '30'
option interval_down '5'
option ui_interval_up '6'
option ui_interval_down '1'
list hosts '8.8.8.8'
list hosts '1.1.1.1'
option check_type '0'
option connection_attempts '2'
option connection_timeout '2'
option ui_connection_attempts '1'
option ui_connection_timeout '1'
option tcp_port '53'
config module 'mod_led_control'
option enabled '0'

View File

@@ -35,11 +35,13 @@ local Config = {
["connectionTimeout"] = 3,
["UIConnectionTimeout"] = 1,
["tcpPort"] = 53,
["checkType"] = 0, -- 0: ping, 1: TCP
["checkType"] = 0, -- 0: TCP, 1: ping
["loggerLevel"] = "info",
--["loggerCmd"] = "logger",
["modules"] = {},
}
Config.configDir = "/etc/" .. Config.appName
Config.modulesDir = "/usr/lib/" .. Config.appName
Config.upScript = Config.configDir .. "/" .. "up-script"
Config.downScript = Config.configDir .. "/" .. "down-script"
Config.runScript = Config.configDir .. "/" .. "run-script"
@@ -59,30 +61,28 @@ if not nixio then
end
local uci = prequire("uci")
if uci then
-- Load settings from UCI
local cursor = uci.cursor()
Config.mode = cursor:get(Config.appName, "config", "mode")
Config.enableLogger = cursor:get(Config.appName, "config", "enable_logger")
Config.enableUpScript = cursor:get(Config.appName, "config", "enable_up_script")
Config.enableDownScript = cursor:get(Config.appName, "config", "enable_down_script")
Config.enableRunScript = cursor:get(Config.appName, "config", "enable_run_script")
Config.intervalUp = tonumber(cursor:get(Config.appName, "config", "interval_up"))
Config.intervalDown = tonumber(cursor:get(Config.appName, "config", "interval_down"))
Config.hosts = cursor:get(Config.appName, "config", "hosts")
Config.checkType = tonumber(cursor:get(Config.appName, "config", "check_type"))
Config.connectionAttempts = tonumber(cursor:get(Config.appName, "config", "connection_attempts"))
Config.connectionTimeout = tonumber(cursor:get(Config.appName, "config", "connection_timeout"))
Config.UIConnectionAttempts = tonumber(cursor:get(Config.appName, "config", "ui_connection_attempts"))
Config.UIConnectionTimeout = tonumber(cursor:get(Config.appName, "config", "ui_connection_timeout"))
Config.tcpPort = tonumber(cursor:get(Config.appName, "config", "tcp_port"))
else
io.stderr:write("libuci-lua does not exists! The default settings will be used...\n")
if not uci then
error("You need to install libuci-lua...")
end
-- Load settings from UCI
local uciCursor = uci.cursor()
Config.mode = uciCursor:get(Config.appName, "config", "mode")
Config.hosts = uciCursor:get(Config.appName, "config", "hosts")
Config.checkType = tonumber(uciCursor:get(Config.appName, "config", "check_type"))
Config.tcpPort = tonumber(uciCursor:get(Config.appName, "config", "tcp_port"))
Config.UIConnectionAttempts = tonumber(uciCursor:get(Config.appName, "ui_config", "connection_attempts"))
Config.UIConnectionTimeout = tonumber(uciCursor:get(Config.appName, "ui_config", "connection_timeout"))
Config.enableLogger = uciCursor:get(Config.appName, "service_config", "enable_logger")
Config.enableUpScript = uciCursor:get(Config.appName, "service_config", "enable_up_script")
Config.enableDownScript = uciCursor:get(Config.appName, "service_config", "enable_down_script")
Config.enableRunScript = uciCursor:get(Config.appName, "service_config", "enable_run_script")
Config.intervalUp = tonumber(uciCursor:get(Config.appName, "service_config", "interval_up"))
Config.intervalDown = tonumber(uciCursor:get(Config.appName, "service_config", "interval_down"))
Config.connectionAttempts = tonumber(uciCursor:get(Config.appName, "service_config", "connection_attempts"))
Config.connectionTimeout = tonumber(uciCursor:get(Config.appName, "service_config", "connection_timeout"))
local function writeValueToFile(filePath, str)
local retValue = false
local fh = io.open(filePath, "w")
@@ -114,6 +114,28 @@ local function writeLogMessage(level, msg)
end
end
local function loadModules()
package.path = string.format("%s;%s/?.lua", package.path, Config.modulesDir)
Config.modules = {}
uciCursor:foreach(
Config.appName,
"module",
function(s)
local mod_name = s[".name"]
if mod_name and s.enabled == "1" then
local m = prequire(mod_name)
if m then
m.syslog = writeLogMessage
m.writeValue = writeValueToFile
m.readValue = readValueFromFile
m:init(s)
Config.modules[#Config.modules + 1] = m
end
end
end
)
end
local function runExternalScript(scriptPath, inetStat)
if inetStat == nil then
inetStat = ""
@@ -164,7 +186,7 @@ local function tcpConnectToHost(host, port)
end
local function checkHosts()
local checkFunc = (Config.checkType == 1) and tcpConnectToHost or pingHost
local checkFunc = (Config.checkType == 1) and pingHost or tcpConnectToHost
local retCode = 1
for k, v in ipairs(Config.parsedHosts) do
for i = 1, Config.connectionAttempts do
@@ -181,20 +203,20 @@ local function checkHosts()
end
local function main()
local last_status
local current_status
local lastStatus
local currentStatus
local interval = Config.intervalUp
while true do
current_status = checkHosts()
currentStatus = checkHosts()
if not nixio.fs.access(Config.statusFile, "r") then
writeValueToFile(Config.statusFile, current_status)
writeValueToFile(Config.statusFile, currentStatus)
end
if current_status == 0 then
if currentStatus == 0 then
interval = Config.intervalUp
if last_status ~= nil and current_status ~= last_status then
writeValueToFile(Config.statusFile, current_status)
if lastStatus ~= nil and currentStatus ~= lastStatus then
writeValueToFile(Config.statusFile, currentStatus)
writeLogMessage("notice", "internet connected")
if Config.enableUpScript == "1" then
runExternalScript(Config.upScript)
@@ -202,8 +224,8 @@ local function main()
end
else
interval = Config.intervalDown
if last_status ~= nil and current_status ~= last_status then
writeValueToFile(Config.statusFile, current_status)
if lastStatus ~= nil and currentStatus ~= lastStatus then
writeValueToFile(Config.statusFile, currentStatus)
writeLogMessage("notice", "internet disconnected")
if Config.enableDownScript == "1" then
runExternalScript(Config.downScript)
@@ -211,11 +233,15 @@ local function main()
end
end
if Config.enableRunScript == "1" then
runExternalScript(Config.runScript, current_status)
for _, e in ipairs(Config.modules) do
e:run(currentStatus, lastStatus)
end
last_status = current_status
if Config.enableRunScript == "1" then
runExternalScript(Config.runScript, currentStatus)
end
lastStatus = currentStatus
nixio.nanosleep(interval)
end
end
@@ -312,6 +338,19 @@ local function run()
local pidValue = nixio.getpid()
writeValueToFile(Config.pidFile, pidValue)
writeLogMessage("info", "started")
loadModules()
-- Loaded modules
local modules = {}
for _, v in ipairs(Config.modules) do
modules[#modules + 1] = string.format("%s", v.name)
end
if #modules > 0 then
writeLogMessage(
"info", string.format("Loaded modules: %s", table.concat(modules, ", "))
)
end
main()
end

View File

@@ -0,0 +1,81 @@
local nixio = require("nixio")
local Module = {
name = "mod_led_control",
sysLedsDir = "/sys/class/leds",
syslog = function(level, msg) return true end,
writeValue = function(filePath, str) return false end,
readValue = function(filePath) return nil end,
ledName = nil,
_enabled = false,
_ledDir = nil,
_ledMaxBrightnessFile = nil,
_ledBrightnessFile = nil,
_ledMaxBrightness = nil,
}
function Module:resetLeds()
local dir = nixio.fs.dir(self.sysLedsDir)
if not dir then
return
end
for led in dir do
local brightness = string.format("%s/%s/brightness", self.sysLedsDir, led)
if nixio.fs.access(brightness, "w") then
self.writeValue(brightness, 0)
end
end
end
function Module:init(t)
self.ledName = t.led_name
if not self.ledName then
return
end
self._ledDir = string.format("%s/%s", self.sysLedsDir, self.ledName)
self._ledMaxBrightnessFile = self._ledDir .. "/max_brightness"
self._ledBrightnessFile = self._ledDir .. "/brightness"
self._ledMaxBrightness = self.readValue(self._ledMaxBrightnessFile) or 1
if (not nixio.fs.access(self._ledDir, "r") or
not nixio.fs.access(self._ledBrightnessFile, "r", "w")) then
self._enabled = false
self.syslog("warning", string.format('%s: "%s" is not available', self.name, self.ledName))
else
self._enabled = true
-- Reset all LEDs
--self:resetLeds()
end
end
function Module:getCurrentState()
local state = self.readValue(self._ledBrightnessFile)
if state and tonumber(state) > 0 then
return tonumber(state)
end
end
function Module:on()
self.writeValue(self._ledBrightnessFile, self._ledMaxBrightness)
end
function Module:off()
self.writeValue(self._ledBrightnessFile, 0)
end
function Module:run(currentStatus, lastStatus)
if not self._enabled then
return
end
if currentStatus == 0 then
if not self:getCurrentState() then
self:on()
end
else
if self:getCurrentState() then
self:off()
end
end
end
return Module

View File

@@ -1,14 +0,0 @@
# Shell commands that are executed every time the Internet is checked for availability
#
# $1 : (0|1) - internet status: 0 is up, 1 is down
#
LEDN=1
LED_CMD="/usr/bin/internet-detector-led.sh"
LED_STATE=`$LED_CMD state $LEDN`
if [ $LED_STATE -eq 0 -a $1 -eq 0 ]; then
$LED_CMD on $LEDN
elif [ $LED_STATE -ne 0 -a $1 -eq 1 ]; then
$LED_CMD off $LEDN
fi

View File

@@ -1,63 +0,0 @@
#/bin/sh
#
# Usage: internet-detector-led.sh on|off|state|list [<LED number>|<LED sysfs-name>]
#
# Examples:
# internet-detector-led.sh list # list of available LEDs
# internet-detector-led.sh on 2 # turn on LED 2
# internet-detector-led.sh off 2 # turn off LED 2
# internet-detector-led.sh on "nbg6817:white:internet" # turn on LED by sysfs-name (/sys/class/leds/nbg6817:white:internet)
# internet-detector-led.sh off "nbg6817:white:internet" # turn off --"--
# internet-detector-led.sh on # same as "internet-detector-led.sh on 1" (default <LED number> is 1)
# internet-detector-led.sh off # turn off --"--
# internet-detector-led.sh state 2 # current state (brightness) of LED 2
# ...
#
if [ -n $2 ]; then
LEDN=$2
else
LEDN=1
fi
SYSFS_LEDS="/sys/class/leds/"
LED="`ls -1 $SYSFS_LEDS | awk -v LEDN=$LEDN '{
LEDN = (length(LEDN) == 0) ? 1 : LEDN;
if($0 == LEDN || NR == LEDN) {
print $0;
exit;
}
}'`" 2> /dev/null
LED_BR_PATH="${SYSFS_LEDS}/${LED}/brightness"
[ -w $LED_BR_PATH ] || exit 1
MAX_BRIGHTNESS=`cat ${SYSFS_LEDS}/${LED}/max_brightness` 2> /dev/null
if [ -z $MAX_BRIGHTNESS ]; then
MAX_BRIGHTNESS=1
fi
case $1 in
on)
printf $MAX_BRIGHTNESS > $LED_BR_PATH
;;
off)
printf 0 > $LED_BR_PATH
;;
state)
cat $LED_BR_PATH 2> /dev/null
;;
list)
ls -1 $SYSFS_LEDS | awk '{print NR ": " $0}'
;;
*)
echo "Usage: `basename $0` on|off|state|list [<LED number>|<LED sysfs-name>]" >&2
exit 1
;;
esac
exit 0;

View File

@@ -4,7 +4,7 @@
include $(TOPDIR)/rules.mk
PKG_VERSION:=0.3.0-3
PKG_VERSION:=0.4-1
LUCI_TITLE:=LuCI support for internet-detector
LUCI_DEPENDS:=+internet-detector
LUCI_PKGARCH:=all

View File

@@ -17,6 +17,7 @@ return view.extend({
upScriptPath : '/etc/internet-detector/up-script',
downScriptPath : '/etc/internet-detector/down-script',
runScriptPath : '/etc/internet-detector/run-script',
ledsPath : '/sys/class/leds',
pollInterval : L.env.pollinterval,
appStatus : 'stoped',
initStatus : null,
@@ -31,6 +32,7 @@ return view.extend({
uiCheckIntervalUp : null,
uiCheckIntervalDown : null,
currentAppMode : '0',
leds : null,
callInitStatus: rpc.declare({
object: 'luci',
@@ -202,6 +204,20 @@ return view.extend({
};
},
CBIBlockTitle: form.DummyValue.extend({
string: null,
renderWidget: function(section_id, option_index, cfgvalue) {
this.title = this.description = null;
return E([
E('label', { 'class': 'cbi-value-title' }),
E('div', { 'class': 'cbi-value-field' },
E('b', {}, this.string)
),
]);
},
}),
CBIBlockService: form.DummyValue.extend({
ctx: null,
@@ -339,6 +355,7 @@ return view.extend({
return Promise.all([
fs.exec(this.execPath, [ 'status' ]),
this.getInitStatus(),
fs.list(this.ledsPath),
uci.load('internet-detector'),
]).catch(e => {
ui.addNotification(null, E('p', _('An error has occurred') + ': %s'.format(e.message)));
@@ -351,9 +368,10 @@ return view.extend({
};
this.appStatus = (data[0].code === 0) ? data[0].stdout.trim() : null;
this.initStatus = data[1];
this.leds = data[2];
this.currentAppMode = uci.get('internet-detector', 'config', 'mode');
this.uiCheckIntervalUp = Number(uci.get('internet-detector', 'config', 'ui_interval_up'));
this.uiCheckIntervalDown = Number(uci.get('internet-detector', 'config', 'ui_interval_down'));
this.uiCheckIntervalUp = Number(uci.get('internet-detector', 'ui_config', 'interval_up'));
this.uiCheckIntervalDown = Number(uci.get('internet-detector', 'ui_config', 'interval_down'));
let upScriptEditDialog = new this.fileEditDialog(
this.upScriptPath,
@@ -371,54 +389,57 @@ return view.extend({
_("Shell commands that are executed every time the Internet is checked for availability"),
);
let m, s, o;
m = new form.Map('internet-detector', _('Internet detector'),
_('Checking Internet availability.'));
/* UCI sections */
s = m.section(form.NamedSection, 'config');
s.anonymous = true;
s.addremove = false;
let s, o;
s.tab('main_settings', _('Main settings'));
//// Main configuration
// service section
o = s.taboption('main_settings', this.CBIBlockService, '_dummy_service');
let mMain = new form.Map('internet-detector');
s = mMain.section(form.NamedSection, 'config');
// service widget
o = s.option(this.CBIBlockService, '_dummy_service');
o.ctx = this;
// mode
o = s.taboption('main_settings', form.ListValue,
o = s.option(form.ListValue,
'mode', _('Internet detector mode'));
o.value('0', _('Disabled'));
o.value('1', _('Web UI only'));
o.value('2', _('Service'));
o.description = '%s;<br>%s;<br>%s;'.format(
o.description = '%s;<br />%s;<br />%s;'.format(
_('Disabled: detector is completely off'),
_('Web UI only: detector works only when the Web UI is open (UI detector)'),
_('Service: detector always runs as a system service')
);
// hosts
o = s.taboption('main_settings', form.DynamicList,
o = s.option(form.DynamicList,
'hosts', _('Hosts'));
o.description = _('Hosts to check Internet availability. Hosts are polled (in list order) until at least one of them responds');
o.datatype = 'or(host,hostport)';
o.datatype = 'or(host,hostport)';
// check_type
o = s.taboption('main_settings', form.ListValue,
o = s.option(form.ListValue,
'check_type', _('Check type'));
o.description = _('Host availability check type');
o.value(0, _('Ping host'));
o.value(1, _('TCP port connection'));
o.value(0, _('TCP port connection'));
o.value(1, _('Ping host'));
// tcp_port
o = s.taboption('main_settings', form.Value,
o = s.option(form.Value,
'tcp_port', _('TCP port'));
o.description = _('Default port value for TCP connections');
o.rmempty = false;
o.datatype = "port";
o.rmempty = false;
o.datatype = "port";
s.tab('ui_detector_configuration', _('UI detector configuration'));
//// UI detector configuration
let mUi = new form.Map('internet-detector');
s = mUi.section(form.NamedSection, 'ui_config');
let makeUIIntervalOptions = L.bind(function(list) {
list.value(1, '%d %s'.format(this.pollInterval, _('sec')));
@@ -429,80 +450,39 @@ return view.extend({
list.value(6, '%d %s'.format(this.pollInterval * 6, _('sec')));
}, this);
// ui_interval_up
o = s.taboption('ui_detector_configuration', form.ListValue,
'ui_interval_up', _('Alive interval'));
// interval_up
o = s.option(form.ListValue,
'interval_up', _('Alive interval'));
o.description = _('Hosts polling interval when the Internet is up');
makeUIIntervalOptions(o);
// ui_interval_down
o = s.taboption('ui_detector_configuration', form.ListValue,
'ui_interval_down', _('Dead interval'));
// interval_down
o = s.option(form.ListValue,
'interval_down', _('Dead interval'));
o.description = _('Hosts polling interval when the Internet is down');
makeUIIntervalOptions(o);
// ui_connection_attempts
o = s.taboption('ui_detector_configuration', form.ListValue,
'ui_connection_attempts', _('Connection attempts'));
// connection_attempts
o = s.option(form.ListValue,
'connection_attempts', _('Connection attempts'));
o.description = _('Maximum number of attempts to connect to each host');
o.value(1);
o.value(2);
o.value(3);
// ui_connection_timeout
o = s.taboption('ui_detector_configuration', form.ListValue,
'ui_connection_timeout', _('Connection timeout'));
// connection_timeout
o = s.option(form.ListValue,
'connection_timeout', _('Connection timeout'));
o.description = _('Maximum timeout for waiting for a response from the host');
o.value(1, "1 " + _('sec'));
o.value(2, "2 " + _('sec'));
o.value(3, "3 " + _('sec'));
s.tab('service_configuration', _('Service configuration'));
// enable_logger
o = s.taboption('service_configuration', form.Flag,
'enable_logger', _('Enable logging'));
o.description = _('Write messages to the system log');
o.rmempty = false;
//// Service configuration
// enable_up_script
o = s.taboption('service_configuration', form.Flag,
'enable_up_script', _('Enable up-script'));
o.description = _('Execute commands when the Internet is connected');
o.rmempty = false;
// up_script edit dialog
o = s.taboption('service_configuration', form.Button,
'_up_script_btn', _('Edit up-script'));
o.onclick = () => upScriptEditDialog.show();
o.inputtitle = _('Edit');
o.inputstyle = 'edit btn';
// enable_down_script
o = s.taboption('service_configuration', form.Flag,
'enable_down_script', _('Enable down-script'));
o.description = _('Execute commands when the Internet is disconnected');
o.rmempty = false;
// down_script edit dialog
o = s.taboption('service_configuration', form.Button,
'_down_script_btn', _('Edit down-script'));
o.onclick = () => downScriptEditDialog.show();
o.inputtitle = _('Edit');
o.inputstyle = 'edit btn';
// enable_run_script
o = s.taboption('service_configuration', form.Flag,
'enable_run_script', _('Enable run-script'));
o.description = _('Execute commands every time the Internet is checked for availability');
o.rmempty = false;
// run_script edit dialog
o = s.taboption('service_configuration', form.Button,
'_run_script_btn', _('Edit run-script'));
o.onclick = () => runScriptEditDialog.show();
o.inputtitle = _('Edit');
o.inputstyle = 'edit btn';
let mService = new form.Map('internet-detector');
s = mService.section(form.NamedSection, 'service_config');
function makeIntervalOptions(list) {
list.value(2, '2 ' + _('sec'));
@@ -519,19 +499,19 @@ return view.extend({
}
// interval_up
o = s.taboption('service_configuration', form.ListValue,
o = s.option(form.ListValue,
'interval_up', _('Alive interval'));
o.description = _('Hosts polling interval when the Internet is up');
makeIntervalOptions(o);
// interval_down
o = s.taboption('service_configuration', form.ListValue,
o = s.option(form.ListValue,
'interval_down', _('Dead interval'));
o.description = _('Hosts polling interval when the Internet is down');
makeIntervalOptions(o);
// connection_attempts
o = s.taboption('service_configuration', form.ListValue,
o = s.option(form.ListValue,
'connection_attempts', _('Connection attempts'));
o.description = _('Maximum number of attempts to connect to each host');
o.value(1);
@@ -541,7 +521,7 @@ return view.extend({
o.value(5);
// connection_timeout
o = s.taboption('service_configuration', form.ListValue,
o = s.option( form.ListValue,
'connection_timeout', _('Connection timeout'));
o.description = _('Maximum timeout for waiting for a response from the host');
o.value(1, "1 " + _('sec'));
@@ -555,20 +535,153 @@ return view.extend({
o.value(9, "9 " + _('sec'));
o.value(10, "10 " + _('sec'));
if(this.currentAppMode !== '0') {
poll.add(
L.bind((this.currentAppMode === '2') ? this.servicePoll : this.uiPoll, this),
this.pollInterval
);
// enable_logger
o = s.option(form.Flag,
'enable_logger', _('Enable logging'));
o.description = _('Write messages to the system log');
o.rmempty = false;
// enable_up_script
o = s.option(form.Flag,
'enable_up_script', _('Enable up-script'));
o.description = _('Execute commands when the Internet is connected');
o.rmempty = false;
// up_script edit dialog
o = s.option(form.Button,
'_up_script_btn', _('Edit up-script'));
o.onclick = () => upScriptEditDialog.show();
o.inputtitle = _('Edit');
o.inputstyle = 'edit btn';
// enable_down_script
o = s.option(form.Flag,
'enable_down_script', _('Enable down-script'));
o.description = _('Execute commands when the Internet is disconnected');
o.rmempty = false;
// down_script edit dialog
o = s.option(form.Button,
'_down_script_btn', _('Edit down-script'));
o.onclick = () => downScriptEditDialog.show();
o.inputtitle = _('Edit');
o.inputstyle = 'edit btn';
// enable_run_script
o = s.option(form.Flag,
'enable_run_script', _('Enable run-script'));
o.description = _('Execute commands every time the Internet is checked for availability');
o.rmempty = false;
// run_script edit dialog
o = s.option(form.Button,
'_run_script_btn', _('Edit run-script'));
o.onclick = () => runScriptEditDialog.show();
o.inputtitle = _('Edit');
o.inputstyle = 'edit btn';
/* Modules */
//// LED control
let mLed = new form.Map('internet-detector');
s = mLed.section(form.NamedSection, 'mod_led_control');
o = s.option(this.CBIBlockTitle, '_dummy');
o.string = _('<abbr title="Light Emitting Diode">LED</abbr> control') + ':';
if(this.leds && this.leds.length > 0) {
// enabled
o = s.option(form.Flag, 'enabled',
_('Enable <abbr title="Light Emitting Diode">LED</abbr> control'));
o.rmempty = false;
o.description = _('<abbr title="Light Emitting Diode">LED</abbr> is on when Internet is available.');
// led_name
o = s.option(form.ListValue, 'led_name',
_('<abbr title="Light Emitting Diode">LED</abbr> Name'));
o.depends('enabled', '1');
this.leds.sort((a, b) => a.name > b.name);
this.leds.forEach(e => o.value(e.name));
} else {
o = s.option(form.DummyValue, '_dummy');
o.rawhtml = true;
o.default = '<label class="cbi-value-title"></label><div class="cbi-value-field"><em>' +
_('No <abbr title="Light Emitting Diode">LED</abbr>s available...') +
'</em></div>';
};
let mapPromise = m.render();
mapPromise.then(node => node.classList.add('fade-in'));
return mapPromise;
/* Rendering */
let settingsNode = E('div', { 'class': 'cbi-section fade-in' },
E('div', { 'class': 'cbi-section-node' },
E('div', { 'class': 'cbi-value' },
E('em', { 'class': 'spinning' }, _('Collecting data...'))
)
)
);
let promises = [ mMain.render(), mUi.render(), mService.render() ];
if(mLed) {
promises.push(mLed.render());
};
Promise.all(promises).then(maps => {
let settingsTabs = E('div', { 'class': 'cbi-section fade-in' });
let tabsContainer = E('div', { 'class': 'cbi-section-node cbi-section-node-tabbed' });
settingsTabs.append(tabsContainer);
// Main settings tab
let mainTab = E('div', {
'data-tab' : 0,
'data-tab-title': _('Main settings'),
}, maps[0]);
tabsContainer.append(mainTab);
// UI detector configuration tab
let uiTab = E('div', {
'data-tab' : 1,
'data-tab-title': _('UI detector configuration'),
}, maps[1]);
tabsContainer.append(uiTab);
// Service configuration tab
let serviceTab = E('div', {
'data-tab' : 2,
'data-tab-title': _('Service configuration'),
}, maps[2]);
// LED control
if(maps[3]) {
serviceTab.append(maps[3]);
};
tabsContainer.append(serviceTab);
ui.tabs.initTabGroup(tabsContainer.children);
settingsNode.replaceWith(settingsTabs);
if(this.currentAppMode !== '0') {
poll.add(
L.bind((this.currentAppMode === '2') ? this.servicePoll : this.uiPoll, this),
this.pollInterval
);
};
}).catch(e => ui.addNotification(null, E('p', {}, e.message)));
return E([
E('h2', { 'class': 'fade-in' }, _('Internet detector')),
E('div', { 'class': 'cbi-section-descr fade-in' },
_('Checking Internet availability.')),
settingsNode,
]);
},
handleSaveApply: function(ev, mode) {
return this.handleSave(ev).then(() => {
return this.handleSave(ev).then(() => {
ui.changes.apply(mode == '0');
window.setTimeout(() => this.serviceRestart(), 3000);
});

View File

@@ -15,8 +15,8 @@ return baseclass.extend({
'currentAppMode' in window
)) {
await uci.load('internet-detector').then(data => {
window.uiCheckIntervalUp = Number(uci.get('internet-detector', 'config', 'ui_interval_up'));
window.uiCheckIntervalDown = Number(uci.get('internet-detector', 'config', 'ui_interval_down'));
window.uiCheckIntervalUp = Number(uci.get('internet-detector', 'ui_config', 'interval_up'));
window.uiCheckIntervalDown = Number(uci.get('internet-detector', 'ui_config', 'interval_down'));
window.currentAppMode = uci.get('internet-detector', 'config', 'mode');
}).catch(e => {});
};

View File

@@ -24,12 +24,18 @@ msgstr "Тип проверки"
msgid "Checking Internet availability."
msgstr "Проверка доступности Интернет."
msgid "Collecting data..."
msgstr "Сбор данных..."
msgid "Command failed"
msgstr "Команда не выполнена"
msgid "Connected"
msgstr "Подключен"
msgid "Connection attempts"
msgstr "Попытки подключения"
msgid "Connection timeout"
msgstr "Таймаут соединения"
@@ -55,7 +61,7 @@ msgid "Disconnected"
msgstr "Отключен"
msgid "Dismiss"
msgstr "Отмена"
msgstr "Закрыть"
msgid "Edit"
msgstr "Изменить"
@@ -73,7 +79,7 @@ msgid "Enable down-script"
msgstr "Включить down-script"
msgid "Enable logging"
msgstr "Включить логирование"
msgstr "Включить запись событий в лог"
msgid "Enable run-script"
msgstr "Включить run-script"
@@ -218,3 +224,18 @@ msgstr "сек"
msgid "up-script"
msgstr ""
msgid "<abbr title=\"Light Emitting Diode\">LED</abbr> control"
msgstr "Управление <abbr title=\"Светодиод\">LED</abbr>"
msgid "<abbr title=\"Light Emitting Diode\">LED</abbr> is on when Internet is available."
msgstr "<abbr title=\"Светодиод\">LED</abbr> включен если Интернет доступен."
msgid "<abbr title=\"Light Emitting Diode\">LED</abbr> Name"
msgstr "Имя <abbr title=\"Светодиод\">LED</abbr>"
msgid "Enable <abbr title=\"Light Emitting Diode\">LED</abbr> control"
msgstr "Включить управление <abbr title=\"Светодиод\">LED</abbr>"
msgid "No <abbr title=\"Light Emitting Diode\">LED</abbr>s available..."
msgstr "Нет доступных <abbr title=\"Светодиод\">LED</abbr>..."

View File

@@ -13,12 +13,18 @@ msgstr ""
msgid "Checking Internet availability."
msgstr ""
msgid "Collecting data..."
msgstr ""
msgid "Command failed"
msgstr ""
msgid "Connected"
msgstr ""
msgid "Connection attempts"
msgstr ""
msgid "Connection timeout"
msgstr ""
@@ -204,3 +210,18 @@ msgstr ""
msgid "up-script"
msgstr ""
msgid "<abbr title=\"Light Emitting Diode\">LED</abbr> control"
msgstr ""
msgid "<abbr title=\"Light Emitting Diode\">LED</abbr> is on when Internet is available."
msgstr ""
msgid "<abbr title=\"Light Emitting Diode\">LED</abbr> Name"
msgstr ""
msgid "Enable <abbr title=\"Light Emitting Diode\">LED</abbr> control"
msgstr ""
msgid "No <abbr title=\"Light Emitting Diode\">LED</abbr>s available..."
msgstr ""

View File

@@ -3,6 +3,7 @@
"description": "Grant access to internet-detector procedures",
"read": {
"file": {
"/sys/class/leds": [ "list" ],
"/etc/internet-detector/up-script": [ "read" ],
"/etc/internet-detector/down-script": [ "read" ],
"/etc/internet-detector/run-script": [ "read" ],

Binary file not shown.

Before

Width:  |  Height:  |  Size: 199 KiB

After

Width:  |  Height:  |  Size: 155 KiB