diff --git a/README.md b/README.md index c32fd43..f51d806 100644 --- a/README.md +++ b/README.md @@ -15,22 +15,22 @@ Internet-detector is an application for checking the availability of the Interne ## Installation notes (OpenWrt >= 21.02) opkg update - wget --no-check-certificate -O /tmp/internet-detector_1.4.0-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/internet-detector_1.4.0-r1_all.ipk - opkg install /tmp/internet-detector_1.4.0-r1_all.ipk - rm /tmp/internet-detector_1.4.0-r1_all.ipk + wget --no-check-certificate -O /tmp/internet-detector_1.4.1-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/internet-detector_1.4.1-r1_all.ipk + opkg install /tmp/internet-detector_1.4.1-r1_all.ipk + rm /tmp/internet-detector_1.4.1-r1_all.ipk /etc/init.d/internet-detector start /etc/init.d/internet-detector enable - wget --no-check-certificate -O /tmp/luci-app-internet-detector_1.4.0-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/luci-app-internet-detector_1.4.0-r1_all.ipk - opkg install /tmp/luci-app-internet-detector_1.4.0-r1_all.ipk - rm /tmp/luci-app-internet-detector_1.4.0-r1_all.ipk + wget --no-check-certificate -O /tmp/luci-app-internet-detector_1.4.1-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/luci-app-internet-detector_1.4.1-r1_all.ipk + opkg install /tmp/luci-app-internet-detector_1.4.1-r1_all.ipk + rm /tmp/luci-app-internet-detector_1.4.1-r1_all.ipk /etc/init.d/rpcd restart i18n-ru: - wget --no-check-certificate -O /tmp/luci-i18n-internet-detector-ru_1.4.0-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/luci-i18n-internet-detector-ru_1.4.0-r1_all.ipk - opkg install /tmp/luci-i18n-internet-detector-ru_1.4.0-r1_all.ipk - rm /tmp/luci-i18n-internet-detector-ru_1.4.0-r1_all.ipk + wget --no-check-certificate -O /tmp/luci-i18n-internet-detector-ru_1.4.1-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/luci-i18n-internet-detector-ru_1.4.1-r1_all.ipk + opkg install /tmp/luci-i18n-internet-detector-ru_1.4.1-r1_all.ipk + rm /tmp/luci-i18n-internet-detector-ru_1.4.1-r1_all.ipk ## Screenshots: @@ -42,9 +42,9 @@ i18n-ru: **Dependences:** modemmanager. - wget --no-check-certificate -O /tmp/internet-detector-mod-modem-restart_1.4.0-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/internet-detector-mod-modem-restart_1.4.0-r1_all.ipk - opkg install /tmp/internet-detector-mod-modem-restart_1.4.0-r1_all.ipk - rm /tmp/internet-detector-mod-modem-restart_1.4.0-r1_all.ipk + wget --no-check-certificate -O /tmp/internet-detector-mod-modem-restart_1.4.1-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/internet-detector-mod-modem-restart_1.4.1-r1_all.ipk + opkg install /tmp/internet-detector-mod-modem-restart_1.4.1-r1_all.ipk + rm /tmp/internet-detector-mod-modem-restart_1.4.1-r1_all.ipk /etc/init.d/internet-detector restart ![](https://github.com/gSpotx2f/luci-app-internet-detector/blob/master/screenshots/04.jpg) @@ -53,9 +53,9 @@ i18n-ru: **Dependences:** mailsend. - wget --no-check-certificate -O /tmp/internet-detector-mod-email_1.4.0-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/internet-detector-mod-email_1.4.0-r1_all.ipk - opkg install /tmp/internet-detector-mod-email_1.4.0-r1_all.ipk - rm /tmp/internet-detector-mod-email_1.4.0-r1_all.ipk + wget --no-check-certificate -O /tmp/internet-detector-mod-email_1.4.1-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/internet-detector-mod-email_1.4.1-r1_all.ipk + opkg install /tmp/internet-detector-mod-email_1.4.1-r1_all.ipk + rm /tmp/internet-detector-mod-email_1.4.1-r1_all.ipk /etc/init.d/internet-detector restart ![](https://github.com/gSpotx2f/luci-app-internet-detector/blob/master/screenshots/05.jpg) diff --git a/internet-detector-mod-email/Makefile b/internet-detector-mod-email/Makefile index f34d82c..6b06a59 100644 --- a/internet-detector-mod-email/Makefile +++ b/internet-detector-mod-email/Makefile @@ -5,7 +5,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=internet-detector-mod-email -PKG_VERSION:=1.4.0 +PKG_VERSION:=1.4.1 PKG_RELEASE:=1 PKG_MAINTAINER:=gSpot diff --git a/internet-detector-mod-modem-restart/Makefile b/internet-detector-mod-modem-restart/Makefile index 1f9981a..37907f0 100644 --- a/internet-detector-mod-modem-restart/Makefile +++ b/internet-detector-mod-modem-restart/Makefile @@ -5,7 +5,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=internet-detector-mod-modem-restart -PKG_VERSION:=1.4.0 +PKG_VERSION:=1.4.1 PKG_RELEASE:=1 PKG_MAINTAINER:=gSpot diff --git a/internet-detector/Makefile b/internet-detector/Makefile index b08bc50..c81bc23 100644 --- a/internet-detector/Makefile +++ b/internet-detector/Makefile @@ -5,7 +5,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=internet-detector -PKG_VERSION:=1.4.0 +PKG_VERSION:=1.4.1 PKG_RELEASE:=1 PKG_MAINTAINER:=gSpot diff --git a/internet-detector/files/etc/config/internet-detector b/internet-detector/files/etc/config/internet-detector index 18a81f7..720aa58 100644 --- a/internet-detector/files/etc/config/internet-detector +++ b/internet-detector/files/etc/config/internet-detector @@ -13,6 +13,7 @@ config instance 'internet' option interval_down '5' option connection_attempts '2' option connection_timeout '2' + option mod_led_control_enabled '0' option mod_reboot_enabled '0' option mod_reboot_dead_period '3600' option mod_reboot_force_reboot_delay '300' diff --git a/internet-detector/files/usr/lib/lua/internet-detector/mod_led_control.lua b/internet-detector/files/usr/lib/lua/internet-detector/mod_led_control.lua index 07a2523..d4578c8 100644 --- a/internet-detector/files/usr/lib/lua/internet-detector/mod_led_control.lua +++ b/internet-detector/files/usr/lib/lua/internet-detector/mod_led_control.lua @@ -3,25 +3,21 @@ local unistd = require("posix.unistd") local dirent = require("posix.dirent") local Module = { - name = "mod_led_control", - runPrio = 10, - config = {}, - syslog = function(level, msg) return true end, - writeValue = function(filePath, str) return false end, - readValue = function(filePath) return nil end, - runInterval = 5, - sysLedsDir = "/sys/class/leds", - ledName = nil, - ledAction1 = 2, -- 1: off, 2: on, 3: blink - ledAction2 = 1, -- 1: off, 2: on, 3: blink - status = nil, - _enabled = false, - _ledDir = nil, - _ledMaxBrightnessFile = nil, - _ledBrightnessFile = nil, - _ledMaxBrightness = nil, - _ledTriggerFile = nil, - _counter = 0, + name = "mod_led_control", + runPrio = 10, + config = {}, + syslog = function(level, msg) return true end, + writeValue = function(filePath, str) return false end, + readValue = function(filePath) return nil end, + runInterval = 5, + sysLedsDir = "/sys/class/leds", + ledsPerInstance = 3, + ledAction1Default = 1, -- 1: off, 2: on, 3: blink + ledAction2Default = 1, + status = nil, + _enabled = false, + _leds = {}, + _counter = 0, } function Module:resetLeds() @@ -37,101 +33,121 @@ function Module:resetLeds() end end -function Module:init(t) - if not t.led_name then - return - else - self.ledName = t.led_name - end - if t.led_action_1 ~= nil then - self.ledAction1 = tonumber(t.led_action_1) - end - if t.led_action_2 ~= nil then - self.ledAction2 = tonumber(t.led_action_2) - end - self._ledDir = string.format("%s/%s", self.sysLedsDir, self.ledName) - self._ledMaxBrightnessFile = string.format("%s/max_brightness", self._ledDir) - self._ledBrightnessFile = string.format("%s/brightness", self._ledDir) - self._ledMaxBrightness = self.readValue(self._ledMaxBrightnessFile) or 1 - self._ledTriggerFile = string.format("%s/trigger", self._ledDir) +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.ledTriggerFile = string.format("%s/trigger", t.ledDir) +end - if (not unistd.access(self._ledDir, "r") or - not unistd.access(self._ledBrightnessFile, "rw") or - not unistd.access(self._ledTriggerFile, "rw")) then - self._enabled = false - self.syslog("warning", string.format( - "%s: LED '%s' is not available", self.name, self.ledName)) - else +function Module:checkLed(t) + return (unistd.access(t.ledDir, "r") and + unistd.access(t.ledBrightnessFile, "rw") and + unistd.access(t.ledTriggerFile, "rw")) +end + +function Module:init(t) + for i = 1, self.ledsPerInstance do + self._leds[i] = {} + end + if t.led1_name then self._enabled = true -- Reset all LEDs --self:resetLeds() + else + 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 + self:setLedAttrs(l) + l.enabled = true + else + l.enabled = false + end + if l.enabled and not self:checkLed(l) then + self._enabled = false + self.syslog("err", string.format( + "%s: module disabled. LED '%s' is not available", self.name, l.ledName)) + end end end -function Module:SetTriggerTimer() - self.writeValue(self._ledTriggerFile, "timer") +function Module:SetTriggerTimer(t) + self.writeValue(t.ledTriggerFile, "timer") end -function Module:SetTriggerNone() - self.writeValue(self._ledTriggerFile, "none") +function Module:SetTriggerNone(t) + self.writeValue(t.ledTriggerFile, "none") end -function Module:getCurrentTrigger() - local trigger = self.readValue(self._ledTriggerFile) +function Module:getCurrentTrigger(t) + local trigger = self.readValue(t.ledTriggerFile) if trigger and trigger:match("%[timer%]") then - return 1 + return true end end -function Module:on() - self:SetTriggerNone() - self.writeValue(self._ledBrightnessFile, self._ledMaxBrightness) +function Module:on(t) + self:SetTriggerNone(t) + self.writeValue(t.ledBrightnessFile, t.ledMaxBrightness) end -function Module:off() - self:SetTriggerNone() - self.writeValue(self._ledBrightnessFile, 0) +function Module:off(t) + self:SetTriggerNone(t) + self.writeValue(t.ledBrightnessFile, 0) end -function Module:getCurrentState() - local state = self.readValue(self._ledBrightnessFile) +function Module:getCurrentState(t) + local state = self.readValue(t.ledBrightnessFile) if state and tonumber(state) > 0 then return tonumber(state) end end +function Module:ledRunFunc(t, currentStatus) + if currentStatus == 0 then + if t.ledAction1 == 1 then + if self:getCurrentState(t) or self:getCurrentTrigger(t) then + self:off(t) + end + elseif t.ledAction1 == 2 then + if not self:getCurrentState(t) or self:getCurrentTrigger(t) then + self:on(t) + end + elseif t.ledAction1 == 3 then + if not self:getCurrentTrigger(t) then + self:SetTriggerTimer(t) + end + end + else + if t.ledAction2 == 1 then + if self:getCurrentState(t) or self:getCurrentTrigger(t) then + self:off(t) + end + elseif t.ledAction2 == 2 then + if not self:getCurrentState(t) or self:getCurrentTrigger(t) then + self:on(t) + end + elseif t.ledAction2 == 3 then + if not self:getCurrentTrigger(t) then + self:SetTriggerTimer(t) + end + end + end +end + function Module:run(currentStatus, lastStatus, timeDiff, timeNow) if not self._enabled then return end if self._counter == 0 or self._counter >= self.runInterval or currentStatus ~= lastStatus then - if currentStatus == 0 then - if self.ledAction1 == 1 then - if self:getCurrentState() or self:getCurrentTrigger() then - self:off() - end - elseif self.ledAction1 == 2 then - if not self:getCurrentState() or self:getCurrentTrigger() then - self:on() - end - elseif self.ledAction1 == 3 then - if not self:getCurrentTrigger() then - self:SetTriggerTimer() - end - end - else - if self.ledAction2 == 1 then - if self:getCurrentState() or self:getCurrentTrigger() then - self:off() - end - elseif self.ledAction2 == 2 then - if not self:getCurrentState() or self:getCurrentTrigger() then - self:on() - end - elseif self.ledAction2 == 3 then - if not self:getCurrentTrigger() then - self:SetTriggerTimer() - end + for _, t in ipairs(self._leds) do + if t.enabled then + self:ledRunFunc(t, currentStatus) end end self._counter = 0 diff --git a/internet-detector/files/usr/lib/lua/internet-detector/mod_public_ip.lua b/internet-detector/files/usr/lib/lua/internet-detector/mod_public_ip.lua index af8b77c..9d408bb 100644 --- a/internet-detector/files/usr/lib/lua/internet-detector/mod_public_ip.lua +++ b/internet-detector/files/usr/lib/lua/internet-detector/mod_public_ip.lua @@ -324,7 +324,7 @@ function Module:resolveIP() res = table.concat(retTable, ", ") end else - self.syslog("err", string.format( + self.syslog("warning", string.format( "%s: DNS error when requesting an IP address", self.name)) end diff --git a/internet-detector/files/usr/lib/lua/internet-detector/mod_regular_script.lua b/internet-detector/files/usr/lib/lua/internet-detector/mod_regular_script.lua index af68fe2..f06d658 100644 --- a/internet-detector/files/usr/lib/lua/internet-detector/mod_regular_script.lua +++ b/internet-detector/files/usr/lib/lua/internet-detector/mod_regular_script.lua @@ -3,17 +3,17 @@ local stdlib = require("posix.stdlib") local unistd = require("posix.unistd") local Module = { - name = "mod_regular_script", - runPrio = 90, - config = {}, - syslog = function(level, msg) return true end, - writeValue = function(filePath, str) return false end, - readValue = function(filePath) return nil end, - inetState = 2, -- 0: connected, 1: disconnected, 2: both - interval = 3600, - script = "", - status = nil, - _nextTime = nil, + name = "mod_regular_script", + runPrio = 90, + config = {}, + syslog = function(level, msg) return true end, + writeValue = function(filePath, str) return false end, + readValue = function(filePath) return nil end, + inetState = 2, -- 0: connected, 1: disconnected, 2: both + runInterval = 3600, + script = "", + status = nil, + _nextTime = nil, } function Module:runExternalScript(scriptPath, currentStatus) @@ -28,7 +28,7 @@ function Module:init(t) self.inetState = tonumber(t.inet_state) end if t.interval ~= nil then - self.interval = tonumber(t.interval) + self.runInterval = tonumber(t.interval) end if self.config.configDir then self.script = string.format( @@ -38,17 +38,17 @@ end function Module:run(currentStatus, lastStatus, timeDiff, timeNow) if not self._nextTime then - if timeNow < self.interval then - self._nextTime = self.interval + if timeNow < self.runInterval then + self._nextTime = self.runInterval else - self._nextTime = timeNow - (timeNow % self.interval) + self.interval + self._nextTime = timeNow - (timeNow % self.runInterval) + self.runInterval end end if timeNow >= self._nextTime then if self.inetState == 2 or (self.inetState == 0 and currentStatus == 0) or (self.inetState == 1 and currentStatus == 1) then self:runExternalScript(self.script, currentStatus) end - self._nextTime = self._nextTime + self.interval + self._nextTime = self._nextTime + self.runInterval end end diff --git a/luci-app-internet-detector/Makefile b/luci-app-internet-detector/Makefile index 3b558f4..dc0ce2f 100644 --- a/luci-app-internet-detector/Makefile +++ b/luci-app-internet-detector/Makefile @@ -5,7 +5,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-internet-detector -PKG_VERSION:=1.4.0 +PKG_VERSION:=1.4.1 PKG_RELEASE:=1 LUCI_TITLE:=LuCI support for internet-detector LUCI_DEPENDS:=+internet-detector diff --git a/luci-app-internet-detector/htdocs/luci-static/resources/view/internet-detector.js b/luci-app-internet-detector/htdocs/luci-static/resources/view/internet-detector.js index 5dcce66..f4a1d6e 100644 --- a/luci-app-internet-detector/htdocs/luci-static/resources/view/internet-detector.js +++ b/luci-app-internet-detector/htdocs/luci-static/resources/view/internet-detector.js @@ -134,23 +134,24 @@ var Timefield = ui.Textfield.extend({ }); return view.extend({ - appName : 'internet-detector', - configDir : '/etc/internet-detector', - ledsPath : '/sys/class/leds', - pollInterval : L.env.pollinterval, - appStatus : 'stoped', - initStatus : null, - inetStatus : null, - inetStatusArea : E('div', { 'class': 'cbi-value-field', 'id': 'inetStatusArea' }), - serviceStatusLabel : E('em', { 'id': 'serviceStatusLabel' }), - initButton : null, - currentAppMode : '0', - defaultHosts : [ '8.8.8.8', '1.1.1.1' ], - leds : [], - mm : false, - mmInit : false, - email : false, - emailExec : false, + appName : 'internet-detector', + configDir : '/etc/internet-detector', + pollInterval : L.env.pollinterval, + appStatus : 'stoped', + initStatus : null, + inetStatus : null, + inetStatusArea : E('div', { 'class': 'cbi-value-field', 'id': 'inetStatusArea' }), + serviceStatusLabel : E('em', { 'id': 'serviceStatusLabel' }), + initButton : null, + currentAppMode : '0', + defaultHosts : [ '8.8.8.8', '1.1.1.1' ], + ledsPath : '/sys/class/leds', + ledsPerInstance : 3, + leds : [], + mm : false, + mmInit : false, + email : false, + emailExec : false, callInitStatus: rpc.declare({ object: 'luci', @@ -511,9 +512,9 @@ return view.extend({ if(!data) { return; }; - this.appStatus = (data[0].code === 0) ? data[0].stdout.trim() : null; - this.initStatus = data[1]; - this.leds = data[2]; + this.appStatus = (data[0].code === 0) ? data[0].stdout.trim() : null; + this.initStatus = data[1]; + this.leds = data[2]; if(data[3]) { if(data[3].mm_mod) { this.mm = true; @@ -566,7 +567,6 @@ return view.extend({ /* Main settings */ // mode - let mode = s.option(form.ListValue, 'mode', _('Internet detector mode')); mode.value('0', _('Disabled')); @@ -579,6 +579,7 @@ return view.extend({ ); mode.default = '0'; + /* Service instances configuration */ if(this.currentAppMode !== '2') { @@ -767,32 +768,45 @@ return view.extend({ o.rmempty = false; o.modalonly = true; - // led_name - o = s.taboption('led_control', form.ListValue, 'mod_led_control_led_name', - _('LED Name')); + o = s.taboption('led_control', form.SectionValue, s.section, form.NamedSection, + s.section); o.depends({ mod_led_control_enabled: '1' }); - o.modalonly = true; - this.leds.forEach(e => o.value(e.name)); + ss = o.subsection; - // led_action_1 - o = s.taboption('led_control', form.ListValue, 'mod_led_control_led_action_1', - _('Action when connected')); - o.depends({ mod_led_control_enabled: '1' }); - o.modalonly = true; - o.value(1, _('Off')); - o.value(2, _('On')); - o.value(3, _('Blink')); - o.default = '2'; + for(let i = 1; i <= this.ledsPerInstance; i++) { + ss.tab('led' + i + '_tab', _('LED') + ' ' + i); - // led_action_2 - o = s.taboption('led_control', form.ListValue, 'mod_led_control_led_action_2', - _('Action when disconnected')); - o.depends({ mod_led_control_enabled: '1' }); - o.modalonly = true; - o.value(1, _('Off')); - o.value(2, _('On')); - o.value(3, _('Blink')); - o.default = '1'; + // led_name + o = ss.taboption('led' + i + '_tab', form.ListValue, 'mod_led_control_led' + i + '_name', + _('LED Name')); + o.depends({ mod_led_control_enabled: '1' }); + o.modalonly = true; + if(i > 1) { + o.rmempty = true; + o.optional = true; + }; + 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.depends({ ['mod_led_control_led' + i + '_name']: /.+/ }); + o.modalonly = true; + o.value(1, _('Off')); + o.value(2, _('On')); + o.value(3, _('Blink')); + o.default = '2'; + + // led_action_2 + o = ss.taboption('led' + i + '_tab', form.ListValue, 'mod_led_control_led' + i + '_action_2', + _('Action when disconnected')); + o.depends({ ['mod_led_control_led' + i + '_name']: /.+/ }); + o.modalonly = true; + o.value(1, _('Off')); + o.value(2, _('On')); + o.value(3, _('Blink')); + o.default = '1'; + }; } else { o = s.taboption('led_control', form.DummyValue, '_dummy'); o.rawhtml = true;