mod_led_control: added netdev trigger, more options for timer trigger.

This commit is contained in:
gSpot
2025-08-09 18:37:11 +03:00
parent 9067d3d3ab
commit 1c02ace538
11 changed files with 466 additions and 115 deletions

View File

@@ -8,6 +8,7 @@ Internet-detector is an application for checking the availability of the Interne
![](https://github.com/gSpotx2f/luci-app-internet-detector/blob/master/screenshots/internet-led.jpg)
- Performing actions when connecting and disconnecting the Internet: rebooting device, restarting network or modem (internet-detector-mod-modem-restart), executing custom shell scripts.
- Sending email notification when Internet access is restored (internet-detector-mod-email).
- Sending telegtam notification when Internet access is restored (internet-detector-mod-telegram).
- The daemon is written entirely in Lua using the luaposix library.
**OpenWrt >= 21.02.**
@@ -19,22 +20,22 @@ Internet-detector is an application for checking the availability of the Interne
## Installation notes:
opkg update
wget --no-check-certificate -O /tmp/internet-detector_1.6.1-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/internet-detector_1.6.1-r1_all.ipk
opkg install /tmp/internet-detector_1.6.1-r1_all.ipk
rm /tmp/internet-detector_1.6.1-r1_all.ipk
wget --no-check-certificate -O /tmp/internet-detector_1.6.2-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/internet-detector_1.6.2-r1_all.ipk
opkg install /tmp/internet-detector_1.6.2-r1_all.ipk
rm /tmp/internet-detector_1.6.2-r1_all.ipk
service internet-detector start
service internet-detector enable
wget --no-check-certificate -O /tmp/luci-app-internet-detector_1.6.1-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/luci-app-internet-detector_1.6.1-r1_all.ipk
opkg install /tmp/luci-app-internet-detector_1.6.1-r1_all.ipk
rm /tmp/luci-app-internet-detector_1.6.1-r1_all.ipk
wget --no-check-certificate -O /tmp/luci-app-internet-detector_1.6.2-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/luci-app-internet-detector_1.6.2-r1_all.ipk
opkg install /tmp/luci-app-internet-detector_1.6.2-r1_all.ipk
rm /tmp/luci-app-internet-detector_1.6.2-r1_all.ipk
service rpcd restart
i18n-ru:
wget --no-check-certificate -O /tmp/luci-i18n-internet-detector-ru_1.6.1-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/luci-i18n-internet-detector-ru_1.6.1-r1_all.ipk
opkg install /tmp/luci-i18n-internet-detector-ru_1.6.1-r1_all.ipk
rm /tmp/luci-i18n-internet-detector-ru_1.6.1-r1_all.ipk
wget --no-check-certificate -O /tmp/luci-i18n-internet-detector-ru_1.6.2-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/luci-i18n-internet-detector-ru_1.6.2-r1_all.ipk
opkg install /tmp/luci-i18n-internet-detector-ru_1.6.2-r1_all.ipk
rm /tmp/luci-i18n-internet-detector-ru_1.6.2-r1_all.ipk
## Screenshots:
@@ -46,9 +47,9 @@ i18n-ru:
**Dependences:** modemmanager.
wget --no-check-certificate -O /tmp/internet-detector-mod-modem-restart_1.6.1-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/internet-detector-mod-modem-restart_1.6.1-r1_all.ipk
opkg install /tmp/internet-detector-mod-modem-restart_1.6.1-r1_all.ipk
rm /tmp/internet-detector-mod-modem-restart_1.6.1-r1_all.ipk
wget --no-check-certificate -O /tmp/internet-detector-mod-modem-restart_1.6.2-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/internet-detector-mod-modem-restart_1.6.2-r1_all.ipk
opkg install /tmp/internet-detector-mod-modem-restart_1.6.2-r1_all.ipk
rm /tmp/internet-detector-mod-modem-restart_1.6.2-r1_all.ipk
service internet-detector restart
![](https://github.com/gSpotx2f/luci-app-internet-detector/blob/master/screenshots/04.jpg)
@@ -57,9 +58,9 @@ i18n-ru:
**Dependences:** mailsend.
wget --no-check-certificate -O /tmp/internet-detector-mod-email_1.6.1-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/internet-detector-mod-email_1.6.1-r1_all.ipk
opkg install /tmp/internet-detector-mod-email_1.6.1-r1_all.ipk
rm /tmp/internet-detector-mod-email_1.6.1-r1_all.ipk
wget --no-check-certificate -O /tmp/internet-detector-mod-email_1.6.2-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/internet-detector-mod-email_1.6.2-r1_all.ipk
opkg install /tmp/internet-detector-mod-email_1.6.2-r1_all.ipk
rm /tmp/internet-detector-mod-email_1.6.2-r1_all.ipk
service internet-detector restart
![](https://github.com/gSpotx2f/luci-app-internet-detector/blob/master/screenshots/05.jpg)
@@ -68,9 +69,9 @@ i18n-ru:
**Dependences:** curl.
wget --no-check-certificate -O /tmp/internet-detector-mod-telegram_1.6.1-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/internet-detector-mod-telegram_1.6.1-r1_all.ipk
opkg install /tmp/internet-detector-mod-telegram_1.6.1-r1_all.ipk
rm /tmp/internet-detector-mod-telegram_1.6.1-r1_all.ipk
wget --no-check-certificate -O /tmp/internet-detector-mod-telegram_1.6.2-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/internet-detector-mod-telegram_1.6.2-r1_all.ipk
opkg install /tmp/internet-detector-mod-telegram_1.6.2-r1_all.ipk
rm /tmp/internet-detector-mod-telegram_1.6.2-r1_all.ipk
service internet-detector restart
![](https://github.com/gSpotx2f/luci-app-internet-detector/blob/master/screenshots/06.jpg)

View File

@@ -5,7 +5,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=internet-detector-mod-email
PKG_VERSION:=1.6.1
PKG_VERSION:=1.6.2
PKG_RELEASE:=1
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/luci-app-internet-detector>

View File

@@ -5,7 +5,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=internet-detector-mod-modem-restart
PKG_VERSION:=1.6.1
PKG_VERSION:=1.6.2
PKG_RELEASE:=1
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/luci-app-internet-detector>

View File

@@ -5,7 +5,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=internet-detector-mod-telegram
PKG_VERSION:=1.6.1
PKG_VERSION:=1.6.2
PKG_RELEASE:=1
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/luci-app-internet-detector>

View File

@@ -5,7 +5,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=internet-detector
PKG_VERSION:=1.6.1
PKG_VERSION:=1.6.2
PKG_RELEASE:=1
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/luci-app-internet-detector>

View File

@@ -1,6 +1,7 @@
local unistd = require("posix.unistd")
local dirent = require("posix.dirent")
local time = require("posix.time")
local unistd = require("posix.unistd")
local Module = {
name = "mod_led_control",
@@ -13,39 +14,40 @@ local Module = {
runInterval = 5,
sysLedsDir = "/sys/class/leds",
ledsPerInstance = 3,
ledAction1Default = 1, -- 1: off, 2: on, 3: blink
ledAction1Default = 1, -- 1: off, 2: on, 3: blinking, 4: netdev
ledAction2Default = 1,
ledBlinkDelayDefault = 500,
ledNetlinkDeviceDefault = nil,
ledNetdevModeLinkDefault = "1",
ledNetdevModeRxDefault = "0",
ledNetdevModeTxDefault = "0",
status = nil,
_enabled = false,
_leds = {},
_counter = 0,
}
function Module:resetLeds()
local ok, dir = pcall(dirent.files, self.sysLedsDir)
if not ok then
return
end
for led in dir do
local brightness = string.format("%s/%s/brightness", self.sysLedsDir, led)
if unistd.access(brightness, "w") then
self.writeValue(brightness, 0)
end
end
end
function Module:setLedAttrs(t)
t.ledDir = string.format("%s/%s", self.sysLedsDir, t.ledName)
t.ledMaxBrightnessFile = string.format("%s/max_brightness", t.ledDir)
t.ledBrightnessFile = string.format("%s/brightness", t.ledDir)
t.ledMaxBrightness = self.readValue(t.ledMaxBrightnessFile) or 1
t.ledMaxBrightness = self.readValue(t.ledMaxBrightnessFile) or "1"
t.ledTriggerFile = string.format("%s/trigger", t.ledDir)
t.ledDelayOnFile = string.format("%s/delay_on", t.ledDir)
t.ledDelayOffFile = string.format("%s/delay_off", t.ledDir)
t.ledDeviceNameFile = string.format("%s/device_name", t.ledDir)
t.ledLinkFile = string.format("%s/link", t.ledDir)
t.ledRxFile = string.format("%s/rx", t.ledDir)
t.ledTxFile = string.format("%s/tx", t.ledDir)
t.ledPrevState = {
brightness = self.readValue(t.ledBrightnessFile),
trigger = self.readValue(t.ledTriggerFile),
}
if t.ledPrevState.trigger then
t.ledPrevState.trigger = t.ledPrevState.trigger:match("%[[%w%-_]+%]"):gsub("[%]%[]", "")
local val = t.ledPrevState.trigger:match("%[[%w%-_]+%]")
if val then
t.ledPrevState.trigger = val:gsub("[%]%[]", "")
end
end
end
@@ -65,10 +67,43 @@ function Module:init(t)
return
end
for i, l in ipairs(self._leds) do
if t["led" .. i .. "_name"] ~= nil then
l.ledName = t["led" .. i .. "_name"]
l.ledAction1 = tonumber(t["led" .. i .. "_action_1"]) or self.ledAction1Default
l.ledAction2 = tonumber(t["led" .. i .. "_action_2"]) or self.ledAction2Default
local led = "led" .. i
if t[led .. "_name"] ~= nil then
l.ledName = t[led .. "_name"]
l.ledAction1 = tonumber(t[led .. "_action_1"]) or self.ledAction1Default
l.ledAction2 = tonumber(t[led .. "_action_2"]) or self.ledAction2Default
l.ledBlinkOnDelay1 = tonumber(t[led .. "_blink_on_delay_1"]) or self.ledBlinkDelayDefault
l.ledBlinkOffDelay1 = tonumber(t[led .. "_blink_off_delay_1"]) or self.ledBlinkDelayDefault
l.ledBlinkOnDelay2 = tonumber(t[led .. "_blink_on_delay_2"]) or self.ledBlinkDelayDefault
l.ledBlinkOffDelay2 = tonumber(t[led .. "_blink_off_delay_2"]) or self.ledBlinkDelayDefault
l.ledNetlinkDevice1 = t[led .. "_netdev_device_1"] or self.ledNetlinkDeviceDefault
l.ledNetlinkDevice2 = t[led .. "_netdev_device_2"] or self.ledNetlinkDeviceDefault
l.ledNetdevModeLink1 = self.ledNetdevModeLinkDefault
l.ledNetdevModeTx1 = self.ledNetdevModeTxDefault
l.ledNetdevModeRx1 = self.ledNetdevModeRxDefault
l.ledNetdevModeLink2 = self.ledNetdevModeLinkDefault
l.ledNetdevModeTx2 = self.ledNetdevModeTxDefault
l.ledNetdevModeRx2 = self.ledNetdevModeRxDefault
local ndm1 = t[led .. "_netdev_mode_1"]
if ndm1 ~= nil and type(ndm1) == "table" then
local enabledFlags = {}
for _, v in ipairs(ndm1) do
enabledFlags[v] = "1"
end
l.ledNetdevModeLink1 = enabledFlags.link or "0"
l.ledNetdevModeTx1 = enabledFlags.tx or "0"
l.ledNetdevModeRx1 = enabledFlags.rx or "0"
end
local ndm2 = t[led .. "_netdev_mode_2"]
if ndm2 ~= nil and type(ndm2) == "table" then
local enabledFlags = {}
for _, v in ipairs(ndm2) do
enabledFlags[v] = "1"
end
l.ledNetdevModeLink2 = enabledFlags.link or "0"
l.ledNetdevModeTx2 = enabledFlags.tx or "0"
l.ledNetdevModeRx2 = enabledFlags.rx or "0"
end
self:setLedAttrs(l)
l.enabled = true
else
@@ -82,29 +117,119 @@ function Module:init(t)
end
end
function Module:setTriggerTimer(t)
self.writeValue(t.ledTriggerFile, "timer")
function Module:checkLedTimer(t)
return (unistd.access(t.ledDelayOnFile, "rw") and unistd.access(t.ledDelayOffFile, "rw"))
end
function Module:checkLedNetdev(t)
return (unistd.access(t.ledDeviceNameFile, "rw") and
unistd.access(t.ledLinkFile, "rw") and
unistd.access(t.ledRxFile, "rw") and
unistd.access(t.ledTxFile, "rw"))
end
function Module:setTriggerNone(t)
self.writeValue(t.ledTriggerFile, "none")
self.debugOutput(string.format(
"%s: LED TRIGGER SET: none, %s", self.name, t.ledTriggerFile))
end
function Module:setTriggerTimer(t, delayOn, delayOff)
if not delayOn then
delayOn = self.ledBlinkDelayDefault
end
if not delayOff then
delayOff = self.ledBlinkDelayDefault
end
self.writeValue(t.ledTriggerFile, "timer")
for i = 0, 10 do
if self:checkLedTimer(t) then
self.writeValue(t.ledDelayOnFile, delayOn)
self.writeValue(t.ledDelayOffFile, delayOff)
break
else
time.nanosleep({ tv_sec = 0, tv_nsec = 500000 })
end
end
self.debugOutput(string.format(
"%s: LED TRIGGER SET: timer, %s; delayOn = %s, delayOff = %s",
self.name, t.ledTriggerFile, tostring(delayOn), tostring(delayOff))
)
end
function Module:setTriggerNetdev(t, device, link, tx, rx)
if not device then
return
end
self.writeValue(t.ledTriggerFile, "netdev")
for i = 0, 10 do
if self:checkLedNetdev(t) then
self.writeValue(t.ledDeviceNameFile, device)
self.writeValue(t.ledLinkFile, link)
self.writeValue(t.ledTxFile, tx)
self.writeValue(t.ledRxFile, rx)
break
else
time.nanosleep({ tv_sec = 0, tv_nsec = 500000 })
end
end
self.debugOutput(string.format(
"%s: LED TRIGGER SET: netdev, %s; device = %s, link = %s, rx = %s, tx = %s",
self.name, t.ledTriggerFile, tostring(device), tostring(link), tostring(rx), tostring(tx))
)
end
function Module:getCurrentTrigger(t)
local trigger = self.readValue(t.ledTriggerFile)
if trigger and trigger:match("%[timer%]") then
return true
if trigger then
if trigger:match("%[timer%]") then
return "timer"
elseif trigger:match("%[netdev%]") then
return "netdev"
end
end
end
function Module:getTriggerValues(t, trigger)
local currentTrigger = self:getCurrentTrigger(t)
if trigger == currentTrigger then
if trigger == "timer" then
return {
trigger = currentTrigger,
delayOn = tonumber(self.readValue(t.ledDelayOnFile)),
delayOff = tonumber(self.readValue(t.ledDelayOffFile)),
}
elseif trigger == "netdev" then
return {
trigger = currentTrigger,
device = self.readValue(t.ledDeviceNameFile),
link = self.readValue(t.ledLinkFile),
tx = self.readValue(t.ledTxFile),
rx = self.readValue(t.ledRxFile),
}
end
end
return {}
end
function Module:on(t)
self:setTriggerNone(t)
self.writeValue(t.ledBrightnessFile, t.ledMaxBrightness)
self.debugOutput(string.format("%s: LED ON: %s", self.name, t.ledBrightnessFile))
end
function Module:off(t)
self:setTriggerNone(t)
self.writeValue(t.ledBrightnessFile, 0)
self.writeValue(t.ledBrightnessFile, "0")
self.debugOutput(string.format("%s: LED OFF: %s", self.name, t.ledBrightnessFile))
end
function Module:getCurrentState(t)
@@ -125,8 +250,21 @@ function Module:ledRunFunc(t, currentStatus)
self:on(t)
end
elseif t.ledAction1 == 3 then
if not self:getCurrentTrigger(t) then
self:setTriggerTimer(t)
local triggerValues = self:getTriggerValues(t, "timer")
if (not next(triggerValues)) or (triggerValues.delayOn ~= t.ledBlinkOnDelay1 or
triggerValues.delayOff ~= t.ledBlinkOffDelay1) then
self:setTriggerTimer(t, t.ledBlinkOnDelay1, t.ledBlinkOffDelay1)
end
elseif t.ledAction1 == 4 then
local triggerValues = self:getTriggerValues(t, "netdev")
if (not next(triggerValues)) or (triggerValues.device ~= t.ledNetlinkDevice1 or
triggerValues.link ~= t.ledNetdevModeLink1 or
triggerValues.tx ~= t.ledNetdevModeTx1 or
triggerValues.rx ~= t.ledNetdevModeRx1) then
self:setTriggerNetdev(t,
t.ledNetlinkDevice1, t.ledNetdevModeLink1,
t.ledNetdevModeTx1, t.ledNetdevModeRx1
)
end
end
else
@@ -139,8 +277,21 @@ function Module:ledRunFunc(t, currentStatus)
self:on(t)
end
elseif t.ledAction2 == 3 then
if not self:getCurrentTrigger(t) then
self:setTriggerTimer(t)
local triggerValues = self:getTriggerValues(t, "timer")
if (not next(triggerValues)) or (triggerValues.delayOn ~= t.ledBlinkOnDelay2 or
triggerValues.delayOff ~= t.ledBlinkOffDelay2) then
self:setTriggerTimer(t, t.ledBlinkOnDelay2, t.ledBlinkOffDelay2)
end
elseif t.ledAction2 == 4 then
local triggerValues = self:getTriggerValues(t, "netdev")
if (not next(triggerValues)) or (triggerValues.device ~= t.ledNetlinkDevice2 or
triggerValues.link ~= t.ledNetdevModeLink2 or
triggerValues.tx ~= t.ledNetdevModeTx2 or
triggerValues.rx ~= t.ledNetdevModeRx2) then
self:setTriggerNetdev(t,
t.ledNetlinkDevice2, t.ledNetdevModeLink2,
t.ledNetdevModeTx2, t.ledNetdevModeRx2
)
end
end
end

View File

@@ -350,12 +350,15 @@ end
function Module:httpRequest(url)
local retCode = 1, data
local iface = ""
if self.config.serviceConfig.iface then
iface = " --interface " .. self.config.serviceConfig.iface
end
local fh = io.popen(string.format(
'%s%s --connect-timeout %s %s "%s"; printf "\n$?";', self.curlExec, iface, self.timeout, self.curlParams, url), "r")
local curl = string.format(
'%s%s --connect-timeout %s %s "%s"; printf "\n$?";',
self.curlExec,
self.config.serviceConfig.iface and (" --interface " .. self.config.serviceConfig.iface) or "",
self.timeout,
self.curlParams,
url
)
local fh = io.popen(curl, "r")
if fh then
data = fh:read("*a")
fh:close()

View File

@@ -5,7 +5,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-internet-detector
PKG_VERSION:=1.6.1
PKG_VERSION:=1.6.2
PKG_RELEASE:=1
LUCI_TITLE:=LuCI support for internet-detector
LUCI_DEPENDS:=+internet-detector

View File

@@ -624,7 +624,8 @@ return view.extend({
this.getInit(),
uci.load(this.appName),
]).catch(e => {
ui.addNotification(null, E('p', _('An error has occurred') + ': %s'.format(e.message)));
ui.addNotification(
null, E('p', _('An error has occurred') + ': %s'.format(e.message)));
});
},
@@ -749,6 +750,18 @@ return view.extend({
list.value(600, '10 ' + _('min'));
}
function makeTimerDelayOptions(list) {
list.value(25, '25 ' + _('msec'));
list.value(50, '50 ' + _('msec'));
list.value(100, '100 ' + _('msec'));
list.value(250, '250 ' + _('msec'));
list.value(500, '500 ' + _('msec'));
list.value(750, '750 ' + _('msec'));
list.value(1000, '1 ' + _('sec'));
list.value(1500, '1.5 ' + _('sec'));
list.value(2000, '2 ' + _('sec'));
}
// enabled
o = s.taboption('main', form.Flag, 'enabled',
_('Enabled'),
@@ -898,13 +911,14 @@ return view.extend({
this.leds.sort((a, b) => a.name > b.name);
// enabled
o = s.taboption('led_control', form.Flag, 'mod_led_control_enabled',
o = s.taboption('led_control', form.Flag,
'mod_led_control_enabled',
_('Enabled'));
o.rmempty = false;
o.modalonly = true;
o = s.taboption('led_control', form.SectionValue, s.section, form.NamedSection,
s.section);
o = s.taboption('led_control', form.SectionValue,
s.section, form.NamedSection, s.section);
o.depends({ mod_led_control_enabled: '1' });
ss = o.subsection;
@@ -912,7 +926,8 @@ return view.extend({
ss.tab('led' + i + '_tab', _('LED') + ' ' + i);
// led_name
o = ss.taboption('led' + i + '_tab', form.ListValue, 'mod_led_control_led' + i + '_name',
o = ss.taboption('led' + i + '_tab', form.ListValue,
'mod_led_control_led' + i + '_name',
_('<abbr title="Light Emitting Diode">LED</abbr> Name'));
o.modalonly = true;
if(i > 1) {
@@ -922,24 +937,117 @@ return view.extend({
this.leds.forEach(e => o.value(e.name));
// led_action_1
o = ss.taboption('led' + i + '_tab', form.ListValue, 'mod_led_control_led' + i + '_action_1',
_('Action when connected'));
o = ss.taboption('led' + i + '_tab', form.ListValue,
'mod_led_control_led' + i + '_action_1',
_('After connection'));
o.depends({ ['mod_led_control_led' + i + '_name']: /.+/ });
o.modalonly = true;
o.value(1, _('Off'));
o.value(2, _('On'));
o.value(3, _('Blink'));
o.value(3, _('Blinking (kernel: timer)'));
o.value(4, _('Network device activity (kernel: netdev)'));
o.default = '2';
// blink_on_delay_1
o = ss.taboption('led' + i + '_tab', form.ListValue,
'mod_led_control_led' + i + '_blink_on_delay_1',
_('On-state delay'),
_('On-state delay for blinking option.'));
makeTimerDelayOptions(o);
o.depends({ ['mod_led_control_led' + i + '_action_1']: '3' });
o.modalonly = true;
o.default = '500';
// blink_off_delay_1
o = ss.taboption('led' + i + '_tab', form.ListValue,
'mod_led_control_led' + i + '_blink_off_delay_1',
_('Off-state delay'),
_('Off-state delay for blinking option.'));
makeTimerDelayOptions(o);
o.depends({ ['mod_led_control_led' + i + '_action_1']: '3' });
o.modalonly = true;
o.default = '500';
// netdev_device_1
o = ss.taboption('led' + i + '_tab', widgets.DeviceSelect,
'mod_led_control_led' + i + '_netdev_device_1',
_('Device'),
_('<abbr title="Light Emitting Diode">LED</abbr> will display the link activity of this network device.')
);
o.depends({ ['mod_led_control_led' + i + '_action_1']: '4' });
o.modalonly = true;
o.rmempty = false;
o.noaliases = true;
// netdev_mode_1
o = ss.taboption('led' + i + '_tab', form.MultiValue,
'mod_led_control_led' + i + '_netdev_mode_1',
_('<abbr title="Light Emitting Diode">LED</abbr> mode')
);
o.depends({ ['mod_led_control_led' + i + '_action_1']: '4' });
o.modalonly = true;
o.value('link', _('Link On'));
o.value('tx', _('Tramsmit'));
o.value('rx', _('Receive'));
o.default = 'link';
o.rmempty = false;
// led_action_2
o = ss.taboption('led' + i + '_tab', form.ListValue, 'mod_led_control_led' + i + '_action_2',
_('Action when disconnected'));
o = ss.taboption('led' + i + '_tab', form.ListValue,
'mod_led_control_led' + i + '_action_2',
_('After disconnection'));
o.depends({ ['mod_led_control_led' + i + '_name']: /.+/ });
o.modalonly = true;
o.value(1, _('Off'));
o.value(2, _('On'));
o.value(3, _('Blink'));
o.value(3, _('Blinking (kernel: timer)'));
o.value(4, _('Network device activity (kernel: netdev)'));
o.default = '1';
// blink_on_delay_2
o = ss.taboption('led' + i + '_tab', form.ListValue,
'mod_led_control_led' + i + '_blink_on_delay_2',
_('On-state delay'),
_('On-state delay for blinking option.'));
makeTimerDelayOptions(o);
o.depends({ ['mod_led_control_led' + i + '_action_2']: '3' });
o.modalonly = true;
o.default = '500';
// blink_off_delay_2
o = ss.taboption('led' + i + '_tab', form.ListValue,
'mod_led_control_led' + i + '_blink_off_delay_2',
_('Off-state delay'),
_('Off-state delay for blinking option.'));
makeTimerDelayOptions(o);
o.depends({ ['mod_led_control_led' + i + '_action_2']: '3' });
o.modalonly = true;
o.default = '500';
// netdev_device_2
o = ss.taboption('led' + i + '_tab', widgets.DeviceSelect,
'mod_led_control_led' + i + '_netdev_device_2',
_('Device'),
_('<abbr title="Light Emitting Diode">LED</abbr> will display the link activity of this network device.')
);
o.depends({ ['mod_led_control_led' + i + '_action_2']: '4' });
o.modalonly = true;
o.rmempty = false;
o.noaliases = true;
// netdev_mode_2
o = ss.taboption('led' + i + '_tab', form.MultiValue,
'mod_led_control_led' + i + '_netdev_mode_2',
_('<abbr title="Light Emitting Diode">LED</abbr> mode')
);
o.depends({ ['mod_led_control_led' + i + '_action_2']: '4' });
o.modalonly = true;
o.value('link', _('Link On'));
o.value('tx', _('Tramsmit'));
o.value('rx', _('Receive'));
o.default = 'link';
o.rmempty = false;
};
} else {
o = s.taboption('led_control', form.DummyValue, '_dummy');
@@ -990,7 +1098,8 @@ return view.extend({
o.default = '300';
// disconnected_at_startup
o = s.taboption('reboot_device', form.Flag, 'mod_reboot_disconnected_at_startup',
o = s.taboption('reboot_device', form.Flag,
'mod_reboot_disconnected_at_startup',
_('On startup'),
_('Reboot device if the Internet is disconnected at service startup.')
);
@@ -1007,7 +1116,8 @@ return view.extend({
o.modalonly = true;
// enabled
o = s.taboption('restart_network', form.Flag, 'mod_network_restart_enabled',
o = s.taboption('restart_network', form.Flag,
'mod_network_restart_enabled',
_('Enabled'));
o.rmempty = false;
o.modalonly = true;
@@ -1022,7 +1132,8 @@ return view.extend({
o.modalonly = true;
// ifaces
o = s.taboption('restart_network', widgets.DeviceSelect, 'mod_network_restart_ifaces',
o = s.taboption('restart_network', widgets.DeviceSelect,
'mod_network_restart_ifaces',
_('Device'),
_('Network device or interface to restart. If not specified, then the network service is restarted.')
);
@@ -1073,7 +1184,8 @@ return view.extend({
o.default = '0';
// disconnected_at_startup
o = s.taboption('restart_network', form.Flag, 'mod_network_restart_disconnected_at_startup',
o = s.taboption('restart_network', form.Flag,
'mod_network_restart_disconnected_at_startup',
_('On startup'),
_('Restart network if the Internet is disconnected at service startup.')
);
@@ -1092,7 +1204,8 @@ return view.extend({
o.modalonly = true;
// enabled
o = s.taboption('restart_modem', form.Flag, 'mod_modem_restart_enabled',
o = s.taboption('restart_modem', form.Flag,
'mod_modem_restart_enabled',
_('Enabled'),
);
o.rmempty = false;
@@ -1140,7 +1253,8 @@ return view.extend({
o.modalonly = true;
// iface
o = s.taboption('restart_modem', widgets.NetworkSelect, 'mod_modem_restart_iface',
o = s.taboption('restart_modem', widgets.NetworkSelect,
'mod_modem_restart_iface',
_('Interface'),
_('ModemManger interface. If specified, it will be restarted after restarting ModemManager.')
);
@@ -1168,7 +1282,8 @@ return view.extend({
o.default = '0';
// disconnected_at_startup
o = s.taboption('restart_modem', form.Flag, 'mod_modem_restart_disconnected_at_startup',
o = s.taboption('restart_modem', form.Flag,
'mod_modem_restart_disconnected_at_startup',
_('On startup'),
_('Restart modem if the Internet is disconnected at service startup.')
);
@@ -1292,7 +1407,8 @@ return view.extend({
if(this.currentAppMode !== '2') {
// enable_ip_script
o = s.taboption('public_ip', form.Flag, 'mod_public_ip_enable_ip_script',
o = s.taboption('public_ip', form.Flag,
'mod_public_ip_enable_ip_script',
_('Enable public-ip-script'));
o.rmempty = false;
o.modalonly = true;
@@ -1356,7 +1472,8 @@ return view.extend({
o.default = '0';
// host_alias
o = s.taboption('email', form.Value, 'mod_email_host_alias',
o = s.taboption('email', form.Value,
'mod_email_host_alias',
_('Host alias'),
_('Host identifier in messages. If not specified, hostname will be used.'));
o.modalonly = true;
@@ -1412,7 +1529,8 @@ return view.extend({
o.modalonly = true;
// message_at_startup
o = s.taboption('email', form.Flag, 'mod_email_message_at_startup',
o = s.taboption('email', form.Flag,
'mod_email_message_at_startup',
_('On startup'),
_('Send message on service startup.')
);
@@ -1443,7 +1561,8 @@ return view.extend({
o.modalonly = true;
// enabled
o = s.taboption('telegram', form.Flag, 'mod_telegram_enabled',
o = s.taboption('telegram', form.Flag,
'mod_telegram_enabled',
_('Enable'));
o.rmempty = false;
o.modalonly = true;
@@ -1481,7 +1600,8 @@ return view.extend({
o.default = '0';
// host_alias
o = s.taboption('telegram', form.Value, 'mod_telegram_host_alias',
o = s.taboption('telegram', form.Value,
'mod_telegram_host_alias',
_('Host alias'),
_('Host identifier in messages. If not specified, hostname will be used.'));
o.modalonly = true;
@@ -1509,7 +1629,8 @@ return view.extend({
o.depends({ 'mod_telegram_api_token': /.+/ });
// message_at_startup
o = s.taboption('telegram', form.Flag, 'mod_telegram_message_at_startup',
o = s.taboption('telegram', form.Flag,
'mod_telegram_message_at_startup',
_('On startup'),
_('Send message on service startup.')
);
@@ -1540,8 +1661,8 @@ return view.extend({
o.rmempty = false;
o.modalonly = true;
o = s.taboption('user_scripts', form.SectionValue, 'user_scripts_section', form.NamedSection,
s.section);
o = s.taboption('user_scripts', form.SectionValue,
'user_scripts_section', form.NamedSection, s.section);
ss = o.subsection;
// up-script tab
@@ -1588,7 +1709,8 @@ return view.extend({
// up_script_attempt_interval
o = ss.taboption('user_scripts_up_script', this.CBITimeInput,
'mod_user_scripts_up_script_attempt_interval', _('Attempt interval'),
'mod_user_scripts_up_script_attempt_interval',
_('Attempt interval'),
_('Interval between up-script runs.')
);
o.default = '60';
@@ -1596,7 +1718,8 @@ return view.extend({
o.modalonly = true;
// connected_at_startup
o = ss.taboption('user_scripts_up_script', form.Flag, 'mod_user_scripts_connected_at_startup',
o = ss.taboption('user_scripts_up_script', form.Flag,
'mod_user_scripts_connected_at_startup',
_('On startup'),
_('Run up-script if the Internet is connected at service startup.')
);
@@ -1647,7 +1770,8 @@ return view.extend({
// down_script_attempt_interval
o = ss.taboption('user_scripts_down_script', this.CBITimeInput,
'mod_user_scripts_down_script_attempt_interval', _('Attempt interval'),
'mod_user_scripts_down_script_attempt_interval',
_('Attempt interval'),
_('Interval between down-script runs.')
);
o.default = '60';
@@ -1655,7 +1779,8 @@ return view.extend({
o.modalonly = true;
// disconnected_at_startup
o = ss.taboption('user_scripts_down_script', form.Flag, 'mod_user_scripts_disconnected_at_startup',
o = ss.taboption('user_scripts_down_script', form.Flag,
'mod_user_scripts_disconnected_at_startup',
_('On startup'),
_('Run down-script if the Internet is disconnected at service startup.')
);
@@ -1672,13 +1797,15 @@ return view.extend({
o.modalonly = true;
// enabled
o = s.taboption('regular_script', form.Flag, 'mod_regular_script_enabled',
o = s.taboption('regular_script', form.Flag,
'mod_regular_script_enabled',
_('Enabled'));
o.rmempty = false;
o.modalonly = true;
// next run
o = s.taboption('regular_script', form.DummyValue, '_dummy', _('Next run'));
o = s.taboption('regular_script', form.DummyValue,
'_dummy', _('Next run'));
o.rawhtml = true;
o.default = '<span id="id_next_run_' + s.section + '">' + (this.modRegularScriptNextRun[s.section] || _('Not scheduled')) + '</span>';
o.modalonly = true;

View File

@@ -23,15 +23,23 @@ msgid ""
"<abbr title=\"Light Emitting Diode\">LED</abbr> indicates the Internet status."
msgstr "<abbr title=\"Светодиод\">LED</abbr> отображает статус Интернет."
msgid "Action when connected"
msgstr "Действие при подключении"
msgid "<abbr title=\"Light Emitting Diode\">LED</abbr> mode"
msgstr "Режим <abbr title=\"Светодиод\">LED</abbr>"
msgid "Action when disconnected"
msgstr "Действие при отключении"
msgid ""
"<abbr title=\"Light Emitting Diode\">LED</abbr> will display the link activity of this network device."
msgstr ""
"<abbr title=\"Светодиод\">LED</abbr> будет отображать активность линка этого сетевого устройства."
msgid "Add instance"
msgstr "Добавить экземпляр"
msgid "After connection"
msgstr "После подключения"
msgid "After disconnection"
msgstr "После отключения"
msgid "Alive interval"
msgstr "Интервал при подключении"
@@ -53,8 +61,8 @@ msgstr "Попытки"
msgid "Big: 248 bytes"
msgstr "Большой: 248 байт"
msgid "Blink"
msgstr "Мигание"
msgid "Blinking (kernel: timer)"
msgstr "Мигание (kernel: timer)"
msgid "Bot API token is missing!"
msgstr "Отсутствует API токен бота!"
@@ -267,6 +275,9 @@ msgstr "Гигантский: 9000 байт"
msgid "LED control"
msgstr "Управление LED"
msgid "Link On"
msgstr "Подключение"
msgid "Loading"
msgstr "Загрузка"
@@ -326,6 +337,9 @@ msgstr ""
"Сетевое устройство для доступа в Интернет. Если не указано, используется "
"устройство по умолчанию."
msgid "Network device activity (kernel: netdev)"
msgstr "Активность сетевого устройства (kernel: netdev)"
msgid ""
"Network device or interface to restart. If not specified, then the network service is restarted."
msgstr ""
@@ -356,12 +370,24 @@ msgstr "Количество попыток запроса IP адреса"
msgid "Off"
msgstr "Выключить"
msgid "Off-state delay"
msgstr "Задержка выключенного состояния"
msgid "Off-state delay for blinking option."
msgstr "Задержка выключенного состояния для опции мигания."
msgid "On"
msgstr "Включить"
msgid "On startup"
msgstr "При запуске"
msgid "On-state delay"
msgstr "Задержка включённого состояния"
msgid "On-state delay for blinking option."
msgstr "Задержка включённого состояния для опции мигания."
msgid "One of the following:"
msgstr "Одно из следующих значений:"
@@ -421,6 +447,9 @@ msgstr "Перезагрузка устройства"
msgid "Reboot device if the Internet is disconnected at service startup."
msgstr "Перезагрузка устройства если Интренет отключен при запуске службы."
msgid "Receive"
msgstr "Приём"
msgid "Recipient"
msgstr "Получатель"
@@ -565,6 +594,9 @@ msgstr "Таймаут между остановкой и запуском ин
msgid "To support HTTP services you need to install curl."
msgstr "Для поддержки HTTP сервисов необходимо установить curl."
msgid "Tramsmit"
msgstr "Передача"
msgid "Type a time string"
msgstr "Введите строку времени"
@@ -658,6 +690,9 @@ msgstr "мин"
msgid "minutes"
msgstr "минуты"
msgid "msec"
msgstr "мсек"
msgid "sec"
msgstr "сек"

View File

@@ -11,15 +11,22 @@ msgid ""
"<abbr title=\"Light Emitting Diode\">LED</abbr> indicates the Internet status."
msgstr ""
msgid "Action when connected"
msgid "<abbr title=\"Light Emitting Diode\">LED</abbr> mode"
msgstr ""
msgid "Action when disconnected"
msgid ""
"<abbr title=\"Light Emitting Diode\">LED</abbr> will display the link activity of this network device."
msgstr ""
msgid "Add instance"
msgstr ""
msgid "After connection"
msgstr ""
msgid "After disconnection"
msgstr ""
msgid "Alive interval"
msgstr ""
@@ -41,7 +48,7 @@ msgstr ""
msgid "Big: 248 bytes"
msgstr ""
msgid "Blink"
msgid "Blinking (kernel: timer)"
msgstr ""
msgid "Bot API token is missing!"
@@ -253,6 +260,9 @@ msgstr ""
msgid "LED control"
msgstr ""
msgid "Link On"
msgstr ""
msgid "Loading"
msgstr ""
@@ -303,6 +313,9 @@ msgid ""
"interface is used."
msgstr ""
msgid "Network device activity (kernel: netdev)"
msgstr ""
msgid ""
"Network device or interface to restart. If not specified, then the network service is restarted."
msgstr ""
@@ -331,12 +344,24 @@ msgstr ""
msgid "Off"
msgstr ""
msgid "Off-state delay"
msgstr ""
msgid "Off-state delay for blinking option."
msgstr ""
msgid "On"
msgstr ""
msgid "On startup"
msgstr ""
msgid "On-state delay"
msgstr ""
msgid "On-state delay for blinking option."
msgstr ""
msgid "One of the following:"
msgstr ""
@@ -393,6 +418,9 @@ msgstr ""
msgid "Reboot device if the Internet is disconnected at service startup."
msgstr ""
msgid "Receive"
msgstr ""
msgid "Recipient"
msgstr ""
@@ -537,6 +565,9 @@ msgstr ""
msgid "To support HTTP services you need to install curl."
msgstr ""
msgid "Tramsmit"
msgstr ""
msgid "Type a time string"
msgstr ""
@@ -622,6 +653,9 @@ msgstr ""
msgid "minutes"
msgstr ""
msgid "msec"
msgstr ""
msgid "sec"
msgstr ""