Обработка спецсимволов для упрощения работы с OpenHAB.
[openhab-process.git] / mqtt-bt / scan-beacons
index 747c295c2e473145fd69bb2f4b4fc3fc9ec32220..b73d6747abdad876a4937f85eecf9e5c7790ea5f 100644 (file)
@@ -1,4 +1,68 @@
-#!/usr/bin/env lua
+#!/usr/bin/lua
+
+function getConfig(configname)
+
+  local uci=require("uci")
+  local cur=uci.cursor()
+  local config
+  if configname then
+    config=configname
+  else
+    config="beacon"
+  end
+
+  logging = cur.get(config,"logging","enabled") 
+
+  mqtt_host = cur.get(config,"mqtt","host")
+  mqtt_port = cur.get(config,"mqtt","port")
+  mqtt_id = cur.get(config,"mqtt","id")
+  mqtt_topic = cur.get(config,"mqtt","topic")
+
+  mqtt_user = cur.get(config,"mqtt","user")
+  mqtt_passwd = cur.get(config,"mqtt","password")
+
+  if mqtt_host and not mqtt_id then
+    mqtt_id="beaconmon"
+  end
+
+  if mqtt_host and not mqtt_port then
+    mqtt_port = 1883
+  end
+
+  if mqtt_host and not mqtt_topic then
+    mqtt_topic = 'beaconmon/{type}/{details}'
+  end
+
+end
+
+function capture(cmd, raw)
+  local f = assert(io.popen(cmd, 'r'))
+  local s = assert(f:read('*a'))
+  f:close()
+  if raw then return s end
+  s = string.gsub(s, '^%s+', '')
+  s = string.gsub(s, '%s+$', '')
+  s = string.gsub(s, '[\n\r]+', ' ')
+  return s
+end
+
+function mqtt_encode(str)
+  if (str) then
+    str = string.gsub (str, "\n", "")
+    str = string.gsub (str, ":", "-")
+    str = string.gsub (str, "/", "-")
+    str = string.gsub (str, " ", "_")
+  end
+  return str   
+end
+
+function printLog(str)
+  if logging=="on" then
+    capture("logger -t beaconmon "..str)
+  else 
+    print(str)  
+  end 
+end
 
 function run_command(cmd)
 
 
 function run_command(cmd)
 
@@ -10,11 +74,12 @@ end
 
 function open_dump()
 
 
 function open_dump()
 
-  f = assert(io.popen ("hcidump --raw"))
-  run_command("kill `pgrep hcitool`")
-  run_command("hciconfig hci0 down")
-  run_command("hciconfig hci0 up")
-  f_null = assert(io.popen ("hcitool lescan --duplicates"))
+  run_command("/bin/kill `/usr/bin/pgrep hcidump`")
+  run_command("/bin/kill `/usr/bin/pgrep hcitool`")
+  f = assert(io.popen ("/usr/bin/hcidump --raw"))
+  run_command("/usr/bin/hciconfig hci0 down")
+  run_command("/usr/bin/hciconfig hci0 up")
+  f_null = assert(io.popen ("/usr/bin/hcitool lescan --duplicates"))
 
   return f
 
 
   return f
 
@@ -25,8 +90,8 @@ function dump(o)
       local s = '{ '
       for k,v in pairs(o) do
          if type(k) ~= 'number' then k = '"'..k..'"' end
       local s = '{ '
       for k,v in pairs(o) do
          if type(k) ~= 'number' then k = '"'..k..'"' end
---         s = s .. '['..k..'] = ' .. dump(v) .. ','
-         s = s .. dump(v) .. ','
+         s = s .. '['..k..'] = ' .. dump(v) .. ','
+--         s = s .. dump(v) .. ','
       end
       return s .. '} '
    else
       end
       return s .. '} '
    else
@@ -38,10 +103,26 @@ function trim(s)
   return (s:gsub("^%s*(.-)%s*$", "%1"))
 end
 
   return (s:gsub("^%s*(.-)%s*$", "%1"))
 end
 
+function mqtt_pub(path,value)
+  printLog("Pub "..path.." "..value)
+  return mqtt_client:publish(path,value)
+end
+
 function process_packet(packet)
 
 function process_packet(packet)
 
-  bytes={}
-  idx=1
+  local bytes={}
+  local idx=1
+  local len
+  local mac
+  local flags
+  local power
+  local tx
+  local type
+  local paysublen
+  local uuid
+  local major
+  local minor
+  local details
 
   if packet:len()>1 then
 
 
   if packet:len()>1 then
 
@@ -59,17 +140,17 @@ function process_packet(packet)
       flags=bytes[14]
       power=tonumber("0x"..bytes[len-1])-256
       tx=tonumber("0x"..bytes[len])-256
       flags=bytes[14]
       power=tonumber("0x"..bytes[len-1])-256
       tx=tonumber("0x"..bytes[len])-256
-      j = 15
+      local j = 15
       while j<len-2 do
         paysublen=tonumber('0x'..bytes[j])
        if bytes[j+1]=="FF" and bytes[j+2]=="4C" and bytes[j+3]=="00" and bytes[j+4]=="02" and bytes[j+5]=="15" then
          -- Standard UUID iBeacon
           type="ibeacon"
       while j<len-2 do
         paysublen=tonumber('0x'..bytes[j])
        if bytes[j+1]=="FF" and bytes[j+2]=="4C" and bytes[j+3]=="00" and bytes[j+4]=="02" and bytes[j+5]=="15" then
          -- Standard UUID iBeacon
           type="ibeacon"
-         uuid1=bytes[j+6]..bytes[j+7]..bytes[j+8]..bytes[j+9]
-         uuid2=bytes[j+10]..bytes[j+11]
-         uuid3=bytes[j+12]..bytes[j+13]
-         uuid4=bytes[j+14]..bytes[j+15]
-         uuid5=bytes[j+16]..bytes[j+17]..bytes[j+18]..bytes[j+19]..bytes[j+20]..bytes[j+21]
+         local uuid1=bytes[j+6]..bytes[j+7]..bytes[j+8]..bytes[j+9]
+         local uuid2=bytes[j+10]..bytes[j+11]
+         local uuid3=bytes[j+12]..bytes[j+13]
+         local uuid4=bytes[j+14]..bytes[j+15]
+         local uuid5=bytes[j+16]..bytes[j+17]..bytes[j+18]..bytes[j+19]..bytes[j+20]..bytes[j+21]
          uuid=string.lower(uuid1..'-'..uuid2..'-'..uuid3..'-'..uuid4..'-'..uuid5)
           major=bytes[j+23]..bytes[j+22]
           minor=bytes[j+25]..bytes[j+24]
          uuid=string.lower(uuid1..'-'..uuid2..'-'..uuid3..'-'..uuid4..'-'..uuid5)
           major=bytes[j+23]..bytes[j+22]
           minor=bytes[j+25]..bytes[j+24]
@@ -77,10 +158,31 @@ function process_packet(packet)
         j=j+1+paysublen
       end
       if type=="ibeacon" then
         j=j+1+paysublen
       end
       if type=="ibeacon" then
-        print(string.format("{type:'ibeacon',mac:'%s',uuid:'%s',major:'%s',minor:'%s',power:%d,tx:%d}",mac,uuid,major,minor,power,tx))
+        printLog(string.format("{type:'ibeacon',mac:'%s',uuid:'%s',major:'%s',minor:'%s',power:%d,tx:%d}",mac,uuid,major,minor,power,tx))
+        details=uuid..'/'..major..'/'..minor
       else
       else
-        print(dump(bytes))
+        type='unknown'
+        details=dump(bytes)
+--        printLog(details)
       end
       end
+      if not (type=="unknown") then
+        mqtt_path=string.gsub(mqtt_topic,"{(.-)}", 
+          function (name) 
+            if name=="type" then
+              return mqtt_encode(type)
+            elseif name=="details" then
+              return mqtt_encode(details)
+            else
+              return '{'..name..'}'
+            end      
+          end)
+        
+        if not pcall(mqtt_pub,mqtt_path,tx) then
+          printLog('Reconnecting MQTT...')
+          mqtt_client:connect(mqtt_id)
+        end
+
+      end        
     end
   end
 
     end
   end
 
@@ -118,6 +220,17 @@ function read_loop()
 
 end
 
 
 end
 
+getConfig(arg[1])
+
+if mqtt_host then
+  MQTT = require "paho.mqtt"
+  mqtt_client = MQTT.client.create(mqtt_host, mqtt_port)
+  if mqtt_user then
+    mqtt_client:auth(mqtt_user, mqtt_passwd)
+  end
+  mqtt_client:connect(mqtt_id)
+end
+
 inp = open_dump()
 
 read_loop()
 inp = open_dump()
 
 read_loop()