MYCSS

2021-12-17

Перший код в LUA. Скрипт для роутера з OpenWRT. MQTT та Telegram статус підключених WiFi clients.

З метою оптимізації мого попереднього коду (Нотатки : Простий скрипт для wifi device tracker в OpenWRT : відсилання повідомлень до MQTT ) в SHELL script так як його можливості дещо обмежені. Перевів код на LUA -  швидка і компактна скриптова мова програмування.

Мета коду - зробити автоматизацію вдома на основі присутності людей. Один з варіантів визначення присутності це за тим чи підключений мобільний телефон особи до домашньої Wi-Fi мережі.

Результати роботи визначення статусу в телеграм групі
Так як мобільний телефон при підключенні до мережі Wi-Fi використовує унікальні MAC адреси, то за активністю MAC адрес можна припустити по наявність особи вдома.

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.

Немає коментарів:

Коли забув ти рідну мову, біднієш духом ти щодня...
When you forgot your native language you would become a poor at spirit every day ...

Д.Білоус / D.Bilous
Рабів до раю не пускають. Будь вільним!

ipv6 ready