12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- ## RaydonEye uses BLE LED Button Service (LBS) UUID 00001523-1212-EFDE-1523-785FEABCD123
- ## [!] ble only supports a single connection, if RadonEye App is running this will fail
- import BLE_GATT
- import time
- from gi.repository import GLib
- import struct
- import subprocess
- dev = None
- # [!] To get this to work bluetoothctl needs to connect to the device before using BLE_GATT.connect
- def ble_ctl(addr:str):
- """
- use bluetoothctl interactively: scan on, ... wait ..., scan off, connect CF:CD:27:79:55:6B, exit
- subprocess has a relevant bug in line-buffering, see issue 21471
- """
- ctl = subprocess.Popen(['bluetoothctl'], stdin = subprocess.PIPE)
- def writeHelper(proc, str, delay = 1):
- proc.stdin.write(str.encode('utf-8'))
- proc.stdin.flush()
- time.sleep(delay)
- # send bluetoothctl commands interactively
- writeHelper(ctl, "scan on\n", 4)
- writeHelper(ctl, "scan off\n")
- writeHelper(ctl, "connect " + addr + "\n", 3)
- writeHelper(ctl, "exit\n")
- # wait for child subprocess to terminate
- while True:
- if None != ctl.poll():
- break
- time.sleep(.1)
- def radonEye_toFloat(res):
- """
- pulls a IEEE754 float representing the most recent radon sample in picocuries per
- liter from the LBS Read Characteristic, the sample is updated 30 times an hour
- RadonEye stores in 4 bytes, big-endian starting at offset 3 of LBS "response"
- """
- return struct.unpack('<f', bytes(res[2:6]))
- # LED Button Service - Write 00001524-1212-EFDE-1523-785FEABCD123
- def push_button():
- print("timeout, pushing LBS button")
- dev.char_write('00001524-1212-EFDE-1523-785FEABCD123', b'\x50')
- return True
- def notify_handler(value):
- print(" ".join(hex(x) for x in value))
- print(radonEye_toFloat(value), " picocuries per liter")
- while True:
- radonEyeMac = 'CF:CD:27:79:55:6B'
- try:
- # Use Central Role BlueZ D-Bus API (BLE-GATT) to connect to peripheral (RadonEye)
- dev = BLE_GATT.Central(radonEyeMac)
- break
- except:
- print("device not found, retrying...\n")
- # using OS time take a break for a tenth of a second, then try bluetoothctl commands
- time.sleep(.1)
- ble_ctl(radonEyeMac)
- continue
- # Open connection, do not disconnect, BLE only supports a single open connection
- dev.connect()
- # LED Button Service - Notify/Read 00001525-1212-EFDE-1523-785FEABCD123
- dev.on_value_change('00001525-1212-EFDE-1523-785FEABCD123', notify_handler)
- GLib.timeout_add_seconds(12, push_button)
- dev.wait_for_notifications()
|