#!/opt/lnxall_app/bin/lua local uci = require("uci") local invoker = require("invoker") local CHECK_LOG = "/tmp/sysdaemon.log" local DEFAULT_SSID = "my_ssid" local DEFAULT_PASSWORD = "my_password" local WIRELESS_CONFIG = "/etc/config" local error_dis = 0 local elec_mode = "none" local passcnt = 0 -- consecutive checks CPU > 40% local failcnt = 0 -- consecutive checks CPU < 20% local function log(msg) local timestamp = os.date("%Y-%m-%d %H:%M:%S") local line = string.format("[%s] %s", timestamp, msg) local f = io.open(CHECK_LOG, "a") if f then f:write(line .. "\n") f:close() end print(line) end local function check_type() local devtype = "invalid" local output = invoker.readfile("/proc/device-tree/model", nil, 1024) if not output then return devtype end if string.find(output,"3568") then devtype = "rk3568" elseif string.find(output,"2004") then devtype = "wl2004" end log(string.format("Info, devtype: %s", devtype)) return devtype end local function load_wificfg(xuci, iface) local dis = xuci:get("wireless", iface, "disabled") if dis ~= "1" and dis ~= 1 and dis ~= "0" and dis ~= 0 then return nil end local mode = xuci:get("wireless", iface, "mode") if mode ~= "ap" and mode ~= "sta" then return nil end local ssid = xuci:get("wireless", iface, "ssid") if type(ssid) ~= "string" or #ssid == 0 then return nil end local key = xuci:get("wireless", iface, "key") return { ssid = ssid, key = key, mode = mode, dis = dis } end local function parse_wireless_config() local result = { ap = {}, -- { ssid, key, dis } sta = {} -- { ssid, key, dis } } local xuci = uci.cursor(WIRELESS_CONFIG) local ifaces = {'radio0', 'radio1'} for _, iface in ipairs(ifaces) do local cfg = load_wificfg(xuci, iface) if cfg then if cfg.mode == "ap" then result.ap.ssid = cfg.ssid result.ap.key = cfg.key result.ap.dis = cfg.dis elseif cfg.mode == "sta" then result.sta.ssid = cfg.ssid result.sta.key = cfg.key result.sta.dis = cfg.dis end end end xuci:close() xuci = nil return result end -- check if wifiwan is UP (STA mode) local function check_wifiwan_up() local okay, output = invoker.invoke(invoker.OUTPUT + invoker.NOSTDIO, "bash", "-c", "nmcli con show --active 2>/dev/null") if okay and type(output) == "string" and string.find(output,"wifiwan") then return true else log("Error, wifiwan(sta) is DOWN") return false end end -- check if wlan0 is UP (AP mode) local function check_wlan0_up() local okay, output = invoker.invoke(invoker.OUTPUT + invoker.NOSTDIO, "bash", "-c", "ip link show wlan0 2>/dev/null") if okay and type(output) == "string" and string.find(output,"state UP") then return true else log("Error, wlan0(ap) is DOWN") return false end end -- bring up wifiwan (STA mode) local function bring_up_wifiwan() log("ACTION: attempting to bring up wifiwan(sta) connection...") invoker.invoke(invoker.NOSTDIO, "nmcli", "-w", "6", "con", "up", "wifiwan") invoker.waitsec(60) end -- bring up wlan0 (AP mode) local function bring_up_wlan0() log("ACTION: attempting to bring up wlan0(ap) interface...") invoker.invoke(invoker.NOSTDIO, "ip", "link", "set", "up", "wlan0") invoker.waitsec(60) end local function wifi_check() local config = parse_wireless_config() local ssid_default = config.sta.ssid == DEFAULT_SSID local pass_default = config.sta.key == DEFAULT_PASSWORD local ap_enable = config.ap.ssid and (config.ap.dis ~= "1" and config.ap.dis ~= 1) local sta_enable = config.sta.ssid and (config.sta.dis ~= "1" and config.sta.dis ~= 1) if (ap_enable and sta_enable) or (not ap_enable and not sta_enable) then if error_dis == 0 then error_dis = 1 log("Error, sta and ap all enable/disable.") end return false else error_dis = 0 end if not sta_enable or (ssid_default and pass_default) then if error_dis == 0 then error_dis = 1 log("Info, sta not enabled or ssid and pass is default,skip") end return false else error_dis = 0 local is_up = check_wifiwan_up() if not is_up then bring_up_wifiwan() end end return true end local function restart(service) log(string.format("ACTION: attempting to restart %s...",service)) invoker.invoke(0, 'systemctl', 'restart', service) invoker.waitsec(120) end local function electron_check() local _, output = invoker.invoke(invoker.OUTPUT + invoker.NOSTDIO, "/bin/bash", "-c", "ps aux | grep electron | grep -v grep") if type(output) ~= "string" or #output == 0 then log("Error, electron not running.") return "low" end local mid = false for line in string.gmatch(output,"([^\r\n]+)") do local str = line:match("%S+%s+%S+%s+([%d%.]+)%S+%s+") if str then local cpu = tonumber(str) if cpu then if cpu > 40 then return "high" end if cpu > 20 then mid = true end end end end if mid then return "mid" end return "low" end local function main() local devtype = check_type() while true do if invoker.uptime() < 1800 then log("Info, uptime is less than 30 minutes, skip") invoker.waitsec(600) else if devtype == "rk3568" then local status = electron_check() if status == "high" then passcnt = passcnt + 1 failcnt = 0 elseif status == "mid" then passcnt = 0 failcnt = 0 if elec_mode ~= "none" then log("Info, entering none mode (20% < CPU < 40% )") elec_mode = "none" end else failcnt = failcnt + 1 passcnt = 0 end if passcnt >= 5 then if elec_mode ~= "normal" then log("Info, entering NORMAL mode (CPU > 40% for 5 minutes)") elec_mode = "normal" end passcnt = 0 end if failcnt >= 10 then if elec_mode ~= "abnormal" then log("Info, entering ABNORMAL mode (CPU < 20% for 10 minutes)") elec_mode = "abnormal" restart("lightdm") end failcnt = 0 end invoker.waitsec(60) elseif devtype == "wl2004" then wifi_check() invoker.waitsec(300) else log("Error, invalid devtype.") return false end end end end main() os.exit(0)