З метою оптимізації мого попереднього коду (Нотатки : Простий скрипт для wifi device tracker в OpenWRT : відсилання повідомлень до MQTT ) в SHELL script так як його можливості дещо обмежені. Перевів код на LUA - швидка і компактна скриптова мова програмування.
Мета коду - зробити автоматизацію вдома на основі присутності людей. Один з варіантів визначення присутності це за тим чи підключений мобільний телефон особи до домашньої Wi-Fi мережі.
Результати роботи визначення статусу в телеграм групі |
iwinfo
Прилад роботи команди в роутері: iwinfo
$ iwinfo wlan0 assoclist AA:AA:AA:AA:AA:E6 -47 dBm / -93 dBm (SNR 46) 1860 ms ago RX: 6.0 MBit/s 47653 Pkts. TX: 72.2 MBit/s, MCS 7, 20MHz 877 Pkts. expected throughput: 34.9 MBit/s AA:AA:AA:AA:D3:12 -66 dBm / -93 dBm (SNR 27) 3224 ms ago RX: 6.0 MBit/s 7281 Pkts. TX: 120.0 MBit/s, MCS 5, 40MHz 1461 Pkts. expected throughput: 39.1 MBit/s AA:AA:AA:AA:58:39 -68 dBm / -93 dBm (SNR 25) 25836 ms ago RX: 24.0 MBit/s 8812 Pkts. TX: 65.0 MBit/s, MCS 6, 20MHz 3922 Pkts. expected throughput: 27.9 MBit/s AA:AA:AA:AA:34:77 -43 dBm / -93 dBm (SNR 50) 9316 ms ago RX: 6.0 MBit/s 3420 Pkts. TX: 72.2 MBit/s, MCS 7, 20MHz 1050 Pkts. expected throughput: 34.9 MBit/s
В результаті вибираємо тарі параметри як "MAC" адреса, так час останньої активності "AGO".
За допомогою awk дещо фільтруємо результат виведення MAC, наприклад якщо активність була менша за останні 50 сек.
iwinfo wlan0 assoclist|awk '{if (($11) && ($9<50000)) print $1}'
AA:AA:AA:AA:AA:E6
AA:AA:AA:AA:D3:12
AA:AA:AA:AA:58:39
AA:AA:AA:AA:34:77
Тепер до скрипту в LUA - device-tracker.lua:
#!/usr/bin/lua
local os=require("os")
users = { ["user1"] = 'AA:AA:AA:AA:34:77', ["user2"] = 'AA:AA:AA:AA:58:39' } ustate = {} next = false local function sleep(n) os.execute("sleep " .. tonumber(n)) end local function publish (topic, mess) os.execute("mosquitto_pub -t '" .. topic .. "' -m '" .. mess .. "' -r -q 2" ) end -- main code sleep(120) -- initialize previos users state tabe for u,m in pairs(users) do ustate[u] = 0 end while true do -- get list of active wifi mac addresess local us=io.popen( "iwinfo wlan0 assoclist|awk '{if (($11) && ($9<50000)) print $1}'" ) maclist = {} for line in us:lines() do maclist[line]=true; end us:close() for u,m in pairs(users) do result = maclist[m] and 1 or 0 if ustate[u] ~= result then ustate[u]=result if next then -- print( "state user :" .. u .. " changed" ) publish("tele/wifi_" .. u .. "/LWT",result) end end end next=true sleep(5) end
libiwinfo-lua
Якщо встановити пакунок OpenWRT - libiwinfo-lua : opkg install libiwinfo-lua, то необхідність запуску зовнішніх програм для визначення активних wifi клієнтів відпадає.
#!/usr/bin/lua
local os=require("os")
-- opkg install libiwinfo-lua local iwinfo=require("iwinfo") -- MAC DataBase of users local users = { ["user1"] = 'AA:AA:AA:AA:34:77', ["user2"] = 'AA:AA:AA:AA:58:39' } -- LIST of WiFi APs, 2.4GHz, 5GHz local ifaces = {"wlan0"} -- FUNCTIONS local function sleep(n) os.execute("sleep " .. tonumber(n)) end local function publish (topic, mess) os.execute("mosquitto_pub -t '" .. topic .. "' -m '" .. mess .. "' -r -q 2" ) end -- MAIN CODE local ustate = {} local next = false -- initialize previos users state tabe for u,m in pairs(users) do ustate[u] = 0 end -- list of wifi clients local maxInactive = 70000 while true do -- get list of active wifi mac addresess local maclist = {} for _,iface in pairs(ifaces) do local ifacet = iwinfo.type(iface) local clients = iwinfo[ifacet].assoclist(iface) for mac,v in pairs(clients) do if v.inactive < maxInactive then -- print(iface, mac, v.inactive) maclist[mac]=true end end end for u,m in pairs(users) do local result = maclist[m] and 1 or 0 if ustate[u] ~= result then ustate[u]=result if next then -- print( "state user: " .. u .. " changed: " .. result ) publish("tele/wifi_" .. u .. "/LWT",result) end end end next=true sleep(5) end
autorun
Скрипт автоматично завантажується при запуску системи.
Автоматичний запуск скрипту device-tracker.lua в OpenWRT |
mqtt
Результат роботи є запуск команди: mosquitto_pub, яка публікує повідомлення до MQTT брокера.
В даному випадку mqtt брокер mosquitto встановлений в цьому роутері.
Скрипт який відсилає повідомлення то Telegam було описано мною раніше: "Нотатки : Простий скрипт для MQTT в OpenWRT : відсилання Telegram повідомлень з Emoji. Tasmota. "
lua-mosquitto
Якщо встановити пакунок OpenWRT - lua-mosquitto : opkg install lua-mosquitto, функцію publish можна переписати так:
-- opkg install lua-mosquitto local mqtt = require("mosquitto") local function publish(t,m) client = mqtt.new() client.ON_CONNECT = function() client:publish(t,m,2,true) end client.ON_PUBLISH = function() client:disconnect() end client:connect() client:loop_forever() end
Але розмір використаної оперативної пам'яті збільшиться в 2.4 рази, тому, я вважаю що недоцільно використовувати lua-mosquitto для одноразового використання, краще запустити зовнішню програму mosquitto_pub.
Оптимізація sleep
-- opkg install luasocket local socket = require 'socket' local function sleep(n) socket.sleep(tonumber(n)) -- os.execute("sleep " .. tonumber(n)) end
Розмір став 1916, але не має процесу sleep котрий займає 1250.
Немає коментарів:
Дописати коментар