{"id":1230,"date":"2025-03-26T11:29:47","date_gmt":"2025-03-26T11:29:47","guid":{"rendered":"https:\/\/www.bleuio.com\/blog\/?p=1230"},"modified":"2025-03-26T12:39:58","modified_gmt":"2025-03-26T12:39:58","slug":"lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio","status":"publish","type":"post","link":"https:\/\/www.bleuio.com\/blog\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\/","title":{"rendered":"LUA parser for Apple Homekit using BleuIO"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">This project demonstrates how to turn a <strong>BLE advertisement-based air quality sensor<\/strong>\u2014in this case, the <strong><a href=\"https:\/\/www.hibouair.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">HibouAir<\/a><\/strong>\u2014into a fully integrated <strong>Apple Home accessory<\/strong>. By combining the flexibility of the BleuIO USB BLE dongle and the simplicity of <strong><a href=\"https:\/\/www.lua.org\/\" target=\"_blank\" rel=\"noreferrer noopener\">Lua scripting<\/a><\/strong>, we\u2019ve created a bridge that reads raw BLE advertisement packets, decodes the environmental data, and makes it available to the <strong><a href=\"https:\/\/www.apple.com\/home-app\/\" target=\"_blank\" rel=\"noreferrer noopener\">Apple Home app<\/a><\/strong> through <strong><a href=\"https:\/\/homebridge.io\/\" target=\"_blank\" rel=\"noreferrer noopener\">Homebridge<\/a><\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Unlike most HomeKit integrations that rely on cloud APIs or native HomeKit devices, this setup is completely offline and works on any platform. The use of BleuIO allows BLE communication to be handled reliably across macOS, Linux, or Windows\u2014something most native BLE libraries struggle to achieve consistently across platforms. Lua adds a lightweight, embeddable scripting engine perfect for decoding raw advertisement data in real time. Together, they make a fast, minimalist, and cross-platform solution for BLE-to-HomeKit integration.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>What This Project Does<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">At a high level, the system continuously scans BLE advertisements from the HibouAir sensor using BleuIO. The data is decoded using Lua, which extracts temperature and humidity values. These values are then served via a local HTTP server, and finally read by Homebridge using the <code>homebridge-http-temperature-humidity<\/code> plugin. This enables you to view real-time air quality data directly in the Apple Home app on your iPhone, iPad, or Mac.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Project Components and Tools Used<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.bleuio.com\/\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>BleuIO<\/strong> USB BLE dongle for cross-platform BLE scanning<\/a><\/li>\n\n\n\n<li><strong>Python 3<\/strong> to interface with BleuIO and run scan commands<\/li>\n\n\n\n<li><strong>Lua<\/strong> for lightweight and efficient BLE advertisement parsing<\/li>\n\n\n\n<li><strong>Homebridge<\/strong> to expose non-HomeKit devices to the Apple Home ecosystem<\/li>\n\n\n\n<li><strong>homebridge-config-ui-x<\/strong> for a convenient web-based Homebridge interface<\/li>\n\n\n\n<li><strong>homebridge-http-temperature-humidity<\/strong> plugin to read HTTP values as HomeKit accessories<\/li>\n\n\n\n<li><a href=\"https:\/\/www.hibouair.com\/\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>HibouAir<\/strong> Air quality monitoring device<\/a><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Step-by-Step Setup<\/strong><\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">1. Connect and Configure BleuIO<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Start by plugging in your BleuIO USB dongle. On macOS or Linux, find its serial port using:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>ls \/dev\/tty.usb*<br><\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Once you\u2019ve identified the port (e.g., <code>\/dev\/tty.usbmodemXXXXXX<\/code>), update the Python script accordingly.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">2. Create <code>bleuio_scan.py<\/code><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">This script will initiate a BLE scan using BleuIO\u2019s AT command interface and capture the raw advertisement data from the HibouAir sensor. It filters for packets containing a specific manufacturer ID and writes the first match to a file.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import serial\nimport time\nimport re\n\n# Update this with your actual port\nport = \"\/dev\/tty.usbmodem4048FDE52DAF1\"\n\nser = serial.Serial(port, 9600, timeout=1)\nser.write(b\"AT+FINDSCANDATA=5B07050=2\\r\\n\")\ntime.sleep(4)\n\ndata = ser.read_all().decode()\nser.close()\n\nprint(\"RAW OUTPUT:\\n\", data)\n\n# Extract first adv line\nmatches = re.findall(r\"Device Data \\&#91;ADV\\]: (&#91;0-9A-F]+)\", data)\nif matches:\n    with open(\"adv_data.txt\", \"w\") as f:\n        f.write(matches&#91;0])\n    print(\"\u2705 Wrote ADV data:\", matches&#91;0])\nelse:\n    print(\"\u274c No HibouAir data found.\")\n<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">3. Parse the BLE Data Using Lua<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Lua is ideal for embedded processing due to its speed and small footprint. We use it here to decode the hex-formatted BLE advertisement string into readable sensor values.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Create a file named <code>parse_ble_adv.lua<\/code> with the following:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>local http = require(\"socket.http\")\nlocal ltn12 = require(\"ltn12\")\nlocal json = require(\"dkjson\")\n\n-- Reverse byte order (e.g., \"1234\" -> \"3412\")\nlocal function reverse_bytes(hexstr)\n    local bytes = {}\n    for i = 1, #hexstr, 2 do\n        table.insert(bytes, 1, hexstr:sub(i, i+1))\n    end\n    return table.concat(bytes)\nend\n\n-- Parse HibouAir BLE advertisement data\nlocal function parse_adv_data(adv)\n    local pos = string.find(adv, \"5B070504\")\n    if not pos then return nil end\n    pos = pos - 1 -- Lua is 1-indexed\n\n    local function read_val(start, len, divide_by, signed)\n        local hex = reverse_bytes(adv:sub(start, start+len-1))\n        local val = tonumber(hex, 16)\n        if signed and val > 0x7FFF then\n            val = val - 0x10000\n        end\n        return divide_by and val \/ divide_by or val\n    end\n\n    return {\n        temp = read_val(pos+23, 4, 10, true),\n        hum = read_val(pos+27, 4, 10),\n        pressure = read_val(pos+19, 4, 10), \n        voc = read_val(pos+31, 4),\n        pm1 = read_val(pos+35, 4, 10),\n        pm25 = read_val(pos+39, 4, 10),\n        pm10 = read_val(pos+43, 4, 10),\n        co2 = tonumber(adv:sub(pos+47, pos+50), 16),\n        vocType = tonumber(adv:sub(pos+51, pos+52), 16),\n        ts = os.date(\"%Y-%m-%d %H:%M:%S\")\n    }\nend\n\n-- Example BLE advertisement data (replace with real data from BleuIO scan)\n-- local adv_data = \"0201061BFF5B070504220069130010273A0160017E0000000000000001B703\"\nlocal file = io.open(\"adv_data.txt\", \"r\")\nlocal adv_data = file:read(\"*a\")\nfile:close()\n\nlocal data = parse_adv_data(adv_data)\n-- Write latest data to file\nprint(\"DEBUG: Writing this to latest_data.json\")\nprint(\"Temperature:\", data.temp)\nprint(\"Humidity:\", data.hum)\n\nlocal file = io.open(\"latest_data.json\", \"w\")\nfile:write(json.encode({\n    temperature = data.temp,\n    humidity = data.hum,\n}))\n\nfile:close()\n\n\n\nif not data then\n    print(\"Failed to parse advertisement data\")\n    return\nend\n\nprint(\"Parsed BLE Data:\")\nfor k, v in pairs(data) do\n    print(k, v)\nend\n<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">4. Automate Scanning and Parsing<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">To keep your data fresh, use a simple shell script to run both the scanner and parser every 10 seconds.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Create <code>run_everything.sh<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/bin\/bash\nwhile true; do\n  echo \"Scanning and updating Homebridge...\"\n  python3 bleuio_scan.py &amp;&amp; lua parse_ble_adv.lua\n  sleep 10\ndone\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Make it executable with:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>chmod +x run_everything.sh<br><\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Run it in the background or with <code>tmux<\/code> to keep it alive.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">5. Create the HTTP Server in Lua<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">This server reads from the JSON file and exposes it via an HTTP endpoint (<code>\/temp<\/code>) that Homebridge can read.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>local copas = require(\"copas\")\nlocal socket = require(\"socket\")\nlocal json = require(\"dkjson\")\n\n-- Start TCP server on port 8081\nlocal server = socket.bind(\"*\", 8081)\ncopas.addserver(server, function(c)\n    c = copas.wrap(c)\n    local request = c:receive(\"*l\")\n\n    if request and request:match(\"GET \/temp\") then\n        -- Read latest temp\/hum from file\n        local file = io.open(\"latest_data.json\", \"r\")\n        local temp_hum = { temperature = 0, humidity = 0 }\n\n        if file then\n            local contents = file:read(\"*a\")\n            file:close()\n            local decoded, _, err = json.decode(contents)\n            if decoded then\n                temp_hum = decoded\n            end\n        end\n\n        local body = json.encode(temp_hum)\n\n        local response = {\n            \"HTTP\/1.1 200 OK\",\n            \"Content-Type: application\/json\",\n            \"Content-Length: \" .. #body,\n            \"\",\n            body\n        }\n        c:send(table.concat(response, \"\\r\\n\"))\n    else\n        c:send(\"HTTP\/1.1 404 Not Found\\r\\n\\r\\n\")\n    end\nend)\n\nprint(\"Lua HTTP server running on http:\/\/localhost:8081\")\ncopas.loop()\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You\u2019ll need LuaSocket and dkjson:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>luarocks install luasocket<br>luarocks install dkjson<br>luarocks install copas<br><\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Run the server:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>lua server.lua<br><\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">It will listen on <code>http:\/\/localhost:8081\/temp<\/code> and serve the current temperature and humidity.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Setting Up Homebridge and Home App Integration<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Install Homebridge globally:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>sudo npm install -g homebridge<br><\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Install the UI plugin for web-based setup:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>sudo npm install -g homebridge-config-ui-x<br><\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then install the required accessory plugin:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>sudo npm install -g homebridge-http-temperature-humidity<br><\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Create or update your Homebridge <code>config.json<\/code> (usually located in <code>~\/.homebridge\/<\/code>):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"bridge\": {\n    \"name\": \"Homebridge\",\n    \"username\": \"0E:4E:20:2F:2E:BC\",\n    \"port\": 51826,\n    \"pin\": \"031-45-154\"\n  },\n  \"description\": \"Homebridge setup\",\n  \"accessories\": &#91;\n    {\n      \"accessory\": \"HttpTemphum\",\n      \"name\": \"HibouAir Sensor\",\n      \"url\": \"http:\/\/localhost:8081\/temp\",\n      \"http_method\": \"GET\",\n      \"sendimmediately\": \"\",\n      \"timeout\": 3000\n    }\n  ],\n  \"platforms\": &#91;\n    {\n      \"platform\": \"config\",\n      \"name\": \"Config\"\n    }\n  ]\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Start Homebridge with:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>homebridge -I<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Use the Homebridge UI (usually on <a>http:\/\/localhost:8081<\/a>) to add the bridge to your Apple Home app by scanning the QR code. Once added, you\u2019ll see <strong>temperature and humidity<\/strong> from your HibouAir sensor as real HomeKit accessories.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"665\" src=\"https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/image-5-1024x665.png\" alt=\"\" class=\"wp-image-1232\" srcset=\"https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/image-5-1024x665.png 1024w, https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/image-5-300x195.png 300w, https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/image-5-768x499.png 768w, https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/image-5-1536x998.png 1536w, https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/image-5-2048x1330.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Output<\/h2>\n\n\n\n<figure class=\"wp-block-gallery alignwide has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"473\" height=\"1024\" data-id=\"1233\" src=\"https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/IMG_4537-473x1024.png\" alt=\"\" class=\"wp-image-1233\" srcset=\"https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/IMG_4537-473x1024.png 473w, https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/IMG_4537-139x300.png 139w, https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/IMG_4537-768x1662.png 768w, https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/IMG_4537-710x1536.png 710w, https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/IMG_4537-946x2048.png 946w, https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/IMG_4537.png 1170w\" sizes=\"auto, (max-width: 473px) 100vw, 473px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"473\" height=\"1024\" data-id=\"1234\" src=\"https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/IMG_4536-473x1024.png\" alt=\"\" class=\"wp-image-1234\" srcset=\"https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/IMG_4536-473x1024.png 473w, https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/IMG_4536-139x300.png 139w, https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/IMG_4536-768x1662.png 768w, https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/IMG_4536-710x1536.png 710w, https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/IMG_4536-946x2048.png 946w, https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/IMG_4536.png 1170w\" sizes=\"auto, (max-width: 473px) 100vw, 473px\" \/><\/figure>\n<\/figure>\n\n\n\n<figure class=\"wp-block-gallery alignwide has-nested-images columns-default is-cropped wp-block-gallery-2 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"473\" height=\"1024\" data-id=\"1235\" src=\"https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/IMG_4538-473x1024.png\" alt=\"\" class=\"wp-image-1235\" srcset=\"https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/IMG_4538-473x1024.png 473w, https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/IMG_4538-139x300.png 139w, https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/IMG_4538-768x1662.png 768w, https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/IMG_4538-710x1536.png 710w, https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/IMG_4538-946x2048.png 946w, https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/IMG_4538.png 1170w\" sizes=\"auto, (max-width: 473px) 100vw, 473px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"473\" height=\"1024\" data-id=\"1236\" src=\"https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/IMG_4539-473x1024.png\" alt=\"\" class=\"wp-image-1236\" srcset=\"https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/IMG_4539-473x1024.png 473w, https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/IMG_4539-139x300.png 139w, https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/IMG_4539-768x1662.png 768w, https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/IMG_4539-710x1536.png 710w, https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/IMG_4539-946x2048.png 946w, https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/IMG_4539.png 1170w\" sizes=\"auto, (max-width: 473px) 100vw, 473px\" \/><\/figure>\n<\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">This project showcases how BleuIO and Lua can be used to create a fast, simple, and platform-independent BLE integration with Apple Home. Unlike heavyweight setups or cloud-connected devices, this approach is minimal, local-first, and highly customizable. With BleuIO&#8217;s cross-platform compatibility and Lua&#8217;s tiny footprint, you can integrate BLE advertisement data into almost any platform\u2014from macOS to Raspberry Pi to embedded Linux. This is just the beginning. You can extend this setup to support more metrics like VOC, CO\u2082, pressure, light.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This project demonstrates how to turn a BLE advertisement-based air quality sensor\u2014in this case, the HibouAir\u2014into a fully integrated Apple Home accessory. By combining the flexibility of the BleuIO USB BLE dongle and the simplicity of Lua scripting, we\u2019ve created a bridge that reads raw BLE advertisement packets, decodes the environmental data, and makes it [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1243,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1,2],"tags":[],"class_list":["post-1230","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-bleuio","category-bleuio-tutorial"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>LUA parser for Apple Homekit using BleuIO - BleuIO - Create Bluetooth Low Energy application<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.bleuio.com\/blog\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"LUA parser for Apple Homekit using BleuIO - BleuIO - Create Bluetooth Low Energy application\" \/>\n<meta property=\"og:description\" content=\"This project demonstrates how to turn a BLE advertisement-based air quality sensor\u2014in this case, the HibouAir\u2014into a fully integrated Apple Home accessory. By combining the flexibility of the BleuIO USB BLE dongle and the simplicity of Lua scripting, we\u2019ve created a bridge that reads raw BLE advertisement packets, decodes the environmental data, and makes it [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.bleuio.com\/blog\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\/\" \/>\n<meta property=\"og:site_name\" content=\"BleuIO - Create Bluetooth Low Energy application\" \/>\n<meta property=\"article:published_time\" content=\"2025-03-26T11:29:47+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-03-26T12:39:58+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/apple-home-lua.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"800\" \/>\n\t<meta property=\"og:image:height\" content=\"450\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"BleuIO\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.bleuio.com\\\/blog\\\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.bleuio.com\\\/blog\\\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\\\/\"},\"author\":{\"name\":\"BleuIO\",\"@id\":\"https:\\\/\\\/www.bleuio.com\\\/blog\\\/#\\\/schema\\\/person\\\/89bc581382d5964043f96efc54b75b80\"},\"headline\":\"LUA parser for Apple Homekit using BleuIO\",\"datePublished\":\"2025-03-26T11:29:47+00:00\",\"dateModified\":\"2025-03-26T12:39:58+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.bleuio.com\\\/blog\\\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\\\/\"},\"wordCount\":640,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/www.bleuio.com\\\/blog\\\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.bleuio.com\\\/blog\\\/wp-content\\\/uploads\\\/2025\\\/03\\\/apple-home-lua.jpg\",\"articleSection\":[\"BleuIO\",\"BleuIO tutorial\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.bleuio.com\\\/blog\\\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.bleuio.com\\\/blog\\\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\\\/\",\"url\":\"https:\\\/\\\/www.bleuio.com\\\/blog\\\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\\\/\",\"name\":\"LUA parser for Apple Homekit using BleuIO - BleuIO - Create Bluetooth Low Energy application\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.bleuio.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.bleuio.com\\\/blog\\\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.bleuio.com\\\/blog\\\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.bleuio.com\\\/blog\\\/wp-content\\\/uploads\\\/2025\\\/03\\\/apple-home-lua.jpg\",\"datePublished\":\"2025-03-26T11:29:47+00:00\",\"dateModified\":\"2025-03-26T12:39:58+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.bleuio.com\\\/blog\\\/#\\\/schema\\\/person\\\/89bc581382d5964043f96efc54b75b80\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.bleuio.com\\\/blog\\\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.bleuio.com\\\/blog\\\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.bleuio.com\\\/blog\\\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.bleuio.com\\\/blog\\\/wp-content\\\/uploads\\\/2025\\\/03\\\/apple-home-lua.jpg\",\"contentUrl\":\"https:\\\/\\\/www.bleuio.com\\\/blog\\\/wp-content\\\/uploads\\\/2025\\\/03\\\/apple-home-lua.jpg\",\"width\":800,\"height\":450,\"caption\":\"apple home lua\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.bleuio.com\\\/blog\\\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.bleuio.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"LUA parser for Apple Homekit using BleuIO\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.bleuio.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.bleuio.com\\\/blog\\\/\",\"name\":\"BleuIO - Create Bluetooth Low Energy application\",\"description\":\"Learn Bluetooth Low Energy programming and build Bluetooth Low Energy Application\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.bleuio.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.bleuio.com\\\/blog\\\/#\\\/schema\\\/person\\\/89bc581382d5964043f96efc54b75b80\",\"name\":\"BleuIO\",\"sameAs\":[\"https:\\\/\\\/www.bleuio.com\\\/blog\"],\"url\":\"https:\\\/\\\/www.bleuio.com\\\/blog\\\/author\\\/biadmin\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"LUA parser for Apple Homekit using BleuIO - BleuIO - Create Bluetooth Low Energy application","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.bleuio.com\/blog\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\/","og_locale":"en_US","og_type":"article","og_title":"LUA parser for Apple Homekit using BleuIO - BleuIO - Create Bluetooth Low Energy application","og_description":"This project demonstrates how to turn a BLE advertisement-based air quality sensor\u2014in this case, the HibouAir\u2014into a fully integrated Apple Home accessory. By combining the flexibility of the BleuIO USB BLE dongle and the simplicity of Lua scripting, we\u2019ve created a bridge that reads raw BLE advertisement packets, decodes the environmental data, and makes it [&hellip;]","og_url":"https:\/\/www.bleuio.com\/blog\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\/","og_site_name":"BleuIO - Create Bluetooth Low Energy application","article_published_time":"2025-03-26T11:29:47+00:00","article_modified_time":"2025-03-26T12:39:58+00:00","og_image":[{"width":800,"height":450,"url":"https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/apple-home-lua.jpg","type":"image\/jpeg"}],"author":"BleuIO","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.bleuio.com\/blog\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\/#article","isPartOf":{"@id":"https:\/\/www.bleuio.com\/blog\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\/"},"author":{"name":"BleuIO","@id":"https:\/\/www.bleuio.com\/blog\/#\/schema\/person\/89bc581382d5964043f96efc54b75b80"},"headline":"LUA parser for Apple Homekit using BleuIO","datePublished":"2025-03-26T11:29:47+00:00","dateModified":"2025-03-26T12:39:58+00:00","mainEntityOfPage":{"@id":"https:\/\/www.bleuio.com\/blog\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\/"},"wordCount":640,"commentCount":0,"image":{"@id":"https:\/\/www.bleuio.com\/blog\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\/#primaryimage"},"thumbnailUrl":"https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/apple-home-lua.jpg","articleSection":["BleuIO","BleuIO tutorial"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.bleuio.com\/blog\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.bleuio.com\/blog\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\/","url":"https:\/\/www.bleuio.com\/blog\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\/","name":"LUA parser for Apple Homekit using BleuIO - BleuIO - Create Bluetooth Low Energy application","isPartOf":{"@id":"https:\/\/www.bleuio.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.bleuio.com\/blog\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\/#primaryimage"},"image":{"@id":"https:\/\/www.bleuio.com\/blog\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\/#primaryimage"},"thumbnailUrl":"https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/apple-home-lua.jpg","datePublished":"2025-03-26T11:29:47+00:00","dateModified":"2025-03-26T12:39:58+00:00","author":{"@id":"https:\/\/www.bleuio.com\/blog\/#\/schema\/person\/89bc581382d5964043f96efc54b75b80"},"breadcrumb":{"@id":"https:\/\/www.bleuio.com\/blog\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.bleuio.com\/blog\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.bleuio.com\/blog\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\/#primaryimage","url":"https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/apple-home-lua.jpg","contentUrl":"https:\/\/www.bleuio.com\/blog\/wp-content\/uploads\/2025\/03\/apple-home-lua.jpg","width":800,"height":450,"caption":"apple home lua"},{"@type":"BreadcrumbList","@id":"https:\/\/www.bleuio.com\/blog\/lightweight-ble-advertisement-parser-for-homekit-using-lua-and-bleuio\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.bleuio.com\/blog\/"},{"@type":"ListItem","position":2,"name":"LUA parser for Apple Homekit using BleuIO"}]},{"@type":"WebSite","@id":"https:\/\/www.bleuio.com\/blog\/#website","url":"https:\/\/www.bleuio.com\/blog\/","name":"BleuIO - Create Bluetooth Low Energy application","description":"Learn Bluetooth Low Energy programming and build Bluetooth Low Energy Application","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.bleuio.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.bleuio.com\/blog\/#\/schema\/person\/89bc581382d5964043f96efc54b75b80","name":"BleuIO","sameAs":["https:\/\/www.bleuio.com\/blog"],"url":"https:\/\/www.bleuio.com\/blog\/author\/biadmin\/"}]}},"_links":{"self":[{"href":"https:\/\/www.bleuio.com\/blog\/wp-json\/wp\/v2\/posts\/1230","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.bleuio.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.bleuio.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.bleuio.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.bleuio.com\/blog\/wp-json\/wp\/v2\/comments?post=1230"}],"version-history":[{"count":3,"href":"https:\/\/www.bleuio.com\/blog\/wp-json\/wp\/v2\/posts\/1230\/revisions"}],"predecessor-version":[{"id":1242,"href":"https:\/\/www.bleuio.com\/blog\/wp-json\/wp\/v2\/posts\/1230\/revisions\/1242"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.bleuio.com\/blog\/wp-json\/wp\/v2\/media\/1243"}],"wp:attachment":[{"href":"https:\/\/www.bleuio.com\/blog\/wp-json\/wp\/v2\/media?parent=1230"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.bleuio.com\/blog\/wp-json\/wp\/v2\/categories?post=1230"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.bleuio.com\/blog\/wp-json\/wp\/v2\/tags?post=1230"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}