From: Roman Bazalevskiy <rvb@rvb.name> Date: Sun, 19 Mar 2017 19:53:22 +0000 (+0300) Subject: BLE Beacon scan - initial support fro iBeacons X-Git-Url: https://git.rvb.name/openhab-process.git/commitdiff_plain/e06b837b3b3ec837665eb7c0539636c7b000664a?hp=-c BLE Beacon scan - initial support fro iBeacons --- e06b837b3b3ec837665eb7c0539636c7b000664a diff --git a/mqtt-bt/scan-beacons b/mqtt-bt/scan-beacons index 747c295..98c3993 100644 --- a/mqtt-bt/scan-beacons +++ b/mqtt-bt/scan-beacons @@ -1,5 +1,67 @@ #!/usr/bin/env 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, "/", "-") + 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) local file = assert(io.popen(cmd, 'r')) @@ -40,8 +102,19 @@ end 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 @@ -59,17 +132,17 @@ function process_packet(packet) 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" - 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] @@ -77,10 +150,26 @@ function process_packet(packet) 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 - print(dump(bytes)) + type='unknown' + details=dump(bytes) + printLog(details) end + if mqtt_client 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) + mqtt_client:publish(mqtt_path,tx) + end end end @@ -118,6 +207,16 @@ function read_loop() end -inp = open_dump() +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()