From 883827e2775b5ff52823914e98a8c9ea0172f76f Mon Sep 17 00:00:00 2001 From: etoten Date: Tue, 5 Jul 2022 00:42:15 +0100 Subject: [PATCH 01/21] Added debuging and changed this to work with python3 --- radon_reader.py | 84 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 57 insertions(+), 27 deletions(-) diff --git a/radon_reader.py b/radon_reader.py index 64f2a0a..9f7449e 100644 --- a/radon_reader.py +++ b/radon_reader.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 """ radon_reader.py: RadonEye RD200 (Bluetooth/BLE) Reader """ @@ -10,11 +10,20 @@ import argparse, struct, time, re, json import paho.mqtt.client as mqtt - +import logging +import sys from bluepy import btle from time import sleep from random import randint +logger = logging.getLogger() + +handler = logging.StreamHandler(sys.stdout) +handler.setLevel(logging.DEBUG) +formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') +handler.setFormatter(formatter) +logger.addHandler(handler) + parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter,description=__progname__) parser.add_argument('-a',dest='address',help='Bluetooth Address (AA:BB:CC:DD:EE:FF format)',required=True) parser.add_argument('-b','--becquerel',action='store_true',help='Display radon value in Becquerel (Bq/m^3) unit', required=False) @@ -36,27 +45,49 @@ def GetRadonValue(): if args.verbose and not args.silent: - print ("Connecting...") - DevBT = btle.Peripheral(args.address, "random") - RadonEye = btle.UUID("00001523-1212-efde-1523-785feabcd123") - RadonEyeService = DevBT.getServiceByUUID(RadonEye) + logger.setLevel(logging.DEBUG) + else: + logger.setLevel(logging.ERROR) + + try: + DevBT = btle.Peripheral() + DevBT.connect(args.address, 'public') + services = DevBT.getServices() + for service in list(services): + logger.debug(service) + + RadonEye = btle.UUID("00001523-0000-1000-8000-00805f9b34fb") + RadonEyeService = DevBT.getServiceByUUID(RadonEye) + logger.debug('Reading: {}'.format(RadonEye)) + logger.debug('RadonEyeService from UUID: {}'.format(RadonEyeService)) + + # Write 0x50 to 00001524-1212-efde-1523-785feabcd123 + uuidWrite = btle.UUID("00001524-0000-1000-8000-00805f9b34fb") + logger.debug('Writing UUID: {}'.format(uuidWrite)) + RadonEyeWrite = RadonEyeService.getCharacteristics(uuidWrite)[0] + logger.debug('Service Characteristics: {}'.format(RadonEyeWrite)) + bGETValues = bytes("\x50", "ascii") + logger.debug('Writing Bytes: {}'.format(bGETValues)) + RadonEyeWrite.write(bGETValues,True) + #RadonEyeWrite.write(bytes("P",'ascii'),True) + while DevBT.waitForNotifications(1): pass + # while self.delegate.data_length < min_bytes: pass + # received = self.delegate.data + # if unpack_string: received = struct.unpack(unpack_string,received) + # Read from 3rd to 6th byte of 00001525-1212-efde-1523-785feabcd123 + uuidRead = btle.UUID("00001525-0000-1000-8000-00805f9b34fb") + logger.debug('Reading: {}'.format(uuidRead)) + RadonEyeValue = RadonEyeService.getCharacteristics(uuidRead)[0] + RadonValue = RadonEyeValue.read() + logger.debug('Radon Value: {}'.format(RadonValue)) + RadonValue = struct.unpack(' Date: Tue, 5 Jul 2022 00:42:59 +0100 Subject: [PATCH 02/21] deleted files added debug new rd200 --- radon_reader_old_v1.py | 68 -------------------------------------- radon_reader_old_v2.py | 75 ------------------------------------------ 2 files changed, 143 deletions(-) delete mode 100644 radon_reader_old_v1.py delete mode 100644 radon_reader_old_v2.py diff --git a/radon_reader_old_v1.py b/radon_reader_old_v1.py deleted file mode 100644 index 0eafd80..0000000 --- a/radon_reader_old_v1.py +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/python -# -# RadonEye RD200 Reader (Bluetooth/BLE) -# -# Author: Carlos Andre -# -import struct -import time - -from bluepy import btle -from time import sleep - -# Put here your RadonEye Bluetooth Address -RadonEyeBTAddress = "E4:34:1D:xx:xx:xx" - -# Choose Unit of Measurement - pCi/L (True) or Bq/m^3 (False) -picoCurie = True - -# Verbose - Enable (True) or Disable (False) -Verbose = False - -# Output - Only Radon Value or Full (timestamp and Unit) -OnlyValue = False - -def GetRadonValue(): - if Verbose: - print ("Connecting...") - DevBT = btle.Peripheral(RadonEyeBTAddress, "random") - RadonEye = btle.UUID("00001523-1212-efde-1523-785feabcd123") - RadonEyeService = DevBT.getServiceByUUID(RadonEye) - - # Write 0x50 to 00001524-1212-efde-1523-785feabcd123 - if Verbose: - print ("Writing...") - uuidWrite = btle.UUID("00001524-1212-efde-1523-785feabcd123") - RadonEyeWrite = RadonEyeService.getCharacteristics(uuidWrite)[0] - RadonEyeWrite.write(bytes("\x50")) - - # Read from 3rd to 6th byte of 00001525-1212-efde-1523-785feabcd123 - if Verbose: - print ("Reading...") - uuidRead = btle.UUID("00001525-1212-efde-1523-785feabcd123") - RadonEyeValue = RadonEyeService.getCharacteristics(uuidRead)[0] - RadonValue = RadonEyeValue.read() - RadonValue = struct.unpack(' Date: Tue, 5 Jul 2022 01:53:48 +0100 Subject: [PATCH 03/21] working example with new RD200 --- radon_reader_by_handle.py | 44 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 radon_reader_by_handle.py diff --git a/radon_reader_by_handle.py b/radon_reader_by_handle.py new file mode 100644 index 0000000..7be57c8 --- /dev/null +++ b/radon_reader_by_handle.py @@ -0,0 +1,44 @@ +import bluepy.btle as btle +import struct +import logging +import sys + +logger = logging.getLogger() +handler = logging.StreamHandler(sys.stdout) +handler.setLevel(logging.DEBUG) +formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') +handler.setFormatter(formatter) +logger.addHandler(handler) +logger.setLevel(logging.DEBUG) + + +##50 0a 02 00 05 00 00 00 00 00 00 00 +##02 05 00 00 05 00 00 00 00' +##b'P\n\x02\x00\x05\x00\x00\x00\x00\x00\x00\x00' + + + +class ReadDelegate(btle.DefaultDelegate): + def handleNotification(self, cHandle, data): + RadonValue = struct.unpack(' Date: Tue, 5 Jul 2022 08:05:10 +0100 Subject: [PATCH 04/21] made it work with old and new device added auto scan --- radon_reader.py | 8 +++- radon_reader_by_handle.py | 83 +++++++++++++++++++++++++++++---------- read_script.sh | 42 ++++++++++++++++++++ 3 files changed, 112 insertions(+), 21 deletions(-) create mode 100755 read_script.sh diff --git a/radon_reader.py b/radon_reader.py index 9f7449e..b7df32a 100644 --- a/radon_reader.py +++ b/radon_reader.py @@ -52,10 +52,14 @@ def GetRadonValue(): try: DevBT = btle.Peripheral() DevBT.connect(args.address, 'public') + DevBT.setMTU(507) services = DevBT.getServices() for service in list(services): logger.debug(service) + #send -- "char-write-cmd 0x002a 50\r" + + RadonEye = btle.UUID("00001523-0000-1000-8000-00805f9b34fb") RadonEyeService = DevBT.getServiceByUUID(RadonEye) logger.debug('Reading: {}'.format(RadonEye)) @@ -66,7 +70,9 @@ def GetRadonValue(): logger.debug('Writing UUID: {}'.format(uuidWrite)) RadonEyeWrite = RadonEyeService.getCharacteristics(uuidWrite)[0] logger.debug('Service Characteristics: {}'.format(RadonEyeWrite)) - bGETValues = bytes("\x50", "ascii") + # bGETValues = bytes("\x50", "ascii") +# bGETValues = bytes([0x50]) + bGETValues = b"\x50" logger.debug('Writing Bytes: {}'.format(bGETValues)) RadonEyeWrite.write(bGETValues,True) #RadonEyeWrite.write(bytes("P",'ascii'),True) diff --git a/radon_reader_by_handle.py b/radon_reader_by_handle.py index 7be57c8..3b91780 100644 --- a/radon_reader_by_handle.py +++ b/radon_reader_by_handle.py @@ -1,4 +1,5 @@ import bluepy.btle as btle +from bluepy.btle import Scanner, DefaultDelegate, BTLEException import struct import logging import sys @@ -11,34 +12,76 @@ logger.addHandler(handler) logger.setLevel(logging.DEBUG) +class ScanDelegate(DefaultDelegate): + def __init__(self): + DefaultDelegate.__init__(self) + + def handleDiscovery(self, dev, isNewDev, isNewData): + pass + +def radeon_device_finder(): + logger.debug('Scanning for devices') + scanner = Scanner().withDelegate(ScanDelegate()) + try: + devices = scanner.scan(10.0) + for device in devices: + name = '' + if device.getValueText(9): + name = device.getValueText(9) + elif device.getValueText(8): + name = device.getValueText(8) + logger.debug('Device name: ' + name) + if 'FR:RU' in name: + logger.info('Found RD200 - x>=2022 revision with address: ' + device.addr) + return device.addr, 1 + elif 'FR:R2' in name: + logger.info('Found RD200 - x<2002 revision with address: ' + device.addr) + return device.addr, 0 + logger.info('Finished scanning for devices, no devices found') + return "", -1 + except BTLEException as e: + scanner.stop() + logger.error('Recieved scan exception ' + e.message) -##50 0a 02 00 05 00 00 00 00 00 00 00 -##02 05 00 00 05 00 00 00 00' -##b'P\n\x02\x00\x05\x00\x00\x00\x00\x00\x00\x00' - class ReadDelegate(btle.DefaultDelegate): - def handleNotification(self, cHandle, data): - RadonValue = struct.unpack('= 0: + p = btle.Peripheral(rdDeviceAddress) + p.withDelegate(ReadDelegate()) -while True: - while p.waitForNotifications(1): - pass -p.disconnect() + #send -- "char-write-cmd 0x002a 50\r" + intHandle = int.from_bytes(b'\x00\x2a', "big") + bGETValues = b"\x50" + logger.debug('Sending payload (byte): %s To handle (int): %s', bGETValues, intHandle) + p.writeCharacteristic(intHandle, bGETValues, True); + while p.waitForNotifications(1): + pass + p.disconnect() +elif rdDeviceType == -1: + logger.error("Device not found, no data to return.") diff --git a/read_script.sh b/read_script.sh new file mode 100755 index 0000000..f789835 --- /dev/null +++ b/read_script.sh @@ -0,0 +1,42 @@ +#!/usr/bin/expect -f +# +## remove output from STDOUT, except for puts +log_user 0 +# +set timeout 4 +# +spawn gatttool -b 94:3c:c6:dd:42:ce -I +# +match_max 100000 +# +expect "> " +# +while (1) { + send -- "connect\r" + expect "Connection successful" break + sleep 1 +# puts "next attempt\n" +} +# +send -- "mtu 507\r" +expect "MTU was exchanged successfully" { + + sleep 1 + send -- "char-write-cmd 0x002a 50\r" + + set systemTime [clock seconds] + puts "Time [clock format $systemTime -format %Y-%m-%dT%H:%M:%S]" + set message1 "" + + expect { + -re "Notification handle = 0x002c value: (.+\n)" { + set message1 ${message1}$expect_out(1,string) + exp_continue + } + } + puts "$message1" + } + +send -- "exit\r" +# +expect eof From 64655d0276ae5670d3c3fb0815a973ab994c86d6 Mon Sep 17 00:00:00 2001 From: etoten Date: Tue, 5 Jul 2022 09:57:53 +0100 Subject: [PATCH 05/21] fixed radon_reader.py to work with radon_reader_by_handle --- README.md | 15 ++- .../radon_reader_by_handle.cpython-37.pyc | Bin 0 -> 3467 bytes radon_reader.py | 90 ++++++------------ radon_reader_by_handle.py | 80 ++++++++++------ 4 files changed, 95 insertions(+), 90 deletions(-) create mode 100644 __pycache__/radon_reader_by_handle.cpython-37.pyc diff --git a/README.md b/README.md index c5e5ce1..2e22a7f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,14 @@ -# RadonReader +# RadonReader 2022 RD200 v2 (=>2022) + + +EtoTen 07/05/2022 +- Forked Project +- Changed compatability to Python3 +- Added support for new RD200 models made in 2022 +- Added auto-scan ability + + +------------ This project provides a tool which allows users collect current radon data from FTLab Radon Eye RD200 (Bluetooth only version). @@ -10,7 +20,7 @@ This project provides a tool which allows users collect current radon data from # Software Requeriments -- Python 2.7.x +- Python 3.7 - bluepy Python library @@ -27,6 +37,7 @@ RadonEye RD200 (Bluetooth/BLE) Reader optional arguments: -h, --help show this help message and exit -a ADDRESS Bluetooth Address (AA:BB:CC:DD:EE:FF format) + -t TYPE 0 for original RD200, 1 for RD200 v2 (=>2022) -b, --becquerel Display radon value in Becquerel (Bq/m^3) unit -v, --verbose Verbose mode -s, --silent Only output radon value (without unit and timestamp) diff --git a/__pycache__/radon_reader_by_handle.cpython-37.pyc b/__pycache__/radon_reader_by_handle.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..57bd509ff48e43a9bd22e02430c148668729b7e8 GIT binary patch literal 3467 zcmZ`*&u<&K6(;AGMzSO;wv#yBq&q;9u9YTskQUt{$S$&p;{-)uq_%gH9c(L%McSTN zno&5T#L`N=IKAz;XZcc~|3okSFL*6bz&-TROHnM^evcD5j?<1H&LjCae0=YH-{bvS zt-|mue*fofRcGuk)R{gGgnRgBe@7#j;2qZGA?GApkgd?_+M(TbLdT5pjvKm0&kH^C zE`=q$?T+6qhh@&BH>n)4a0c(HEWM~5@vtuIlUeD#XdL0Y7(XW*jLurGpiHrr8>NTp|20;ME~AkwKQdLu#J`qT_R_9g>BTE55^17jB%~_j zR?%r~4_bRsB06%pH&7)kn#VsQ>lq)OKW*6ZbeA?|6+QGOD~*NJd25&1yy++(L)sSd zmGX8FEH(z3Gw*C?u_xuC!X+ zRP;L}S6i)@{m2BX)iS3egcQy>v%T^#F-Kd{L45ApW~7add0ez)ra9}sAy6~~r)cEX zA)DB_bBNfC+29W&HgSaonIC*N;;Zb}Z^o9e$M(pYc!Ul0cq)zUWWmTTM!%U#W7~Y& z8`&3&XqQIzzNfy!D9|#pUiig0Nus=CZ2~t&CayAC`hnHbBkd4!@$&8pCIWMZkF3%8E0iEAE&)L^3v7Q%EZmbU%46Nd0H`qy4 zfH22xne7^Hv8(qqJEj~wrX(2F5PHl86r(%A&|TZOv+?Ed=33fMM6j`X`_?U>?BMgy zZr{3nJ5bQg0LS2UobLsZ5DEyp6C6{j6-#dqZ=6|r7oYgQE0tNfvIdZ3dr|}$(ZLzJ zZv;s?Jp;}IyMQjrhvWa?87^+fb`0Pbivu~OjG$T5UMJn%1-rOHZufT;VMkZV_9>)I zCIOk)R#$gr{#DfJ%Po13YbQ>2Qti+g73Ce2^0cR2sZ^?TX-X}wE*YDp0vi{820a@= zJLFT%<(Yie^9J&*LaVhCCxHGXY?0kS!+3?)xrMgE9sH|Cs&k(=AW>U4GY!b?e5xu?>d^-lWT*NX(Yqf{$>qfb*ngg$bSvJ0S*0c-uDYYLPcGHgdACxm! zFv)tF$2)O5q8jiEe9}+=vl@K(@oD>)Kh$1_C9`BngPL>H{Dd0H{8J4Phx##^Pw_XL z2DeiG#3hDwFkoB~LJ)jxA3Pn|Bfihn)}Rh}!Yu~8fHT0$0p6z^fF%N&prlNkk^R8>jd+9yLA5eA>7I$5p#|~S=A8p8+xf&1>+9?Vo3SOFIL6qmR+sgsD zZ^xgkp+5Pox6>v^-??6Wg3l<5WYY=l9330Cauv%=m)=4*EMb!tX3ls-`^kf1 z+t2WcjM9jiY^1z&kb#tabCz1hc-vGY2vnkos*R(l`izh{`>y&c<KN8GUDlxDk8# z` zVs_FPp#o5FO}~M@SM*2j$Rqy7_s(JG?=gQ)m|K;Y2k+B8U}4?x+cCwVsF&BZy&dlw z$UYq|Z^}eahHt0w58Bmhe?0!Wx49NbM5t$Uew-KOJok+;EGiL7*ewo&MI&k z)w3^(+7wo&16zY0xVRUVVOc>uVP*T#!!5&JSy(k5GM)Rs3Ty9rPani*!SOzS7q_)v zV*iZbz<>-NtX;LL1}SyO4)-meFB<+{#B75%EE=hBbq_1_1w};q!M(5f!*FIB^{6*k zCV#7+L)X+WbGIxIPx#a&DsxCAZD)f_J9IfV*ws#z$g@a?d&ain%7 1000 ) or ( RadonValue < 0 ): + if ( mRadonValueBQ > 1000 ) or ( mRadonValueBQ < 0 ): raise Exception("Very strange radon value. Debugging needed.") if args.becquerel: Unit="Bq/m^3" -# RadonValue = ( RadonValue * 37 ) + RadonValue = mRadonValueBQ else: Unit="pCi/L" - RadonValue = ( RadonValue / 37 ) + RadonValue = mRadonValuePCi + if args.silent: print ("%0.2f" % (RadonValue)) - else: - print ("%s - %s - Radon Value: %0.2f %s" % (time.strftime("%Y-%m-%d [%H:%M:%S]"),args.address,RadonValue,Unit)) - + else: + print ("%s - %s - Radon Value: %0.2f %s" % (time.strftime("%Y-%m-%d [%H:%M:%S]"),mRdDeviceAddress,RadonValue,Unit)) + if args.mqtt: if args.verbose and not args.silent: print ("Sending to MQTT...") @@ -147,7 +115,7 @@ def GetRadonValue(): except Exception as e: if args.verbose and not args.silent: print (e) - + for i in range(1,4): try: logger.debug("Failed, trying again (%s)..." % i) diff --git a/radon_reader_by_handle.py b/radon_reader_by_handle.py index 3b91780..5373dbb 100644 --- a/radon_reader_by_handle.py +++ b/radon_reader_by_handle.py @@ -1,17 +1,20 @@ +#!/usr/bin/python3 import bluepy.btle as btle from bluepy.btle import Scanner, DefaultDelegate, BTLEException import struct import logging import sys +from time import sleep + logger = logging.getLogger() handler = logging.StreamHandler(sys.stdout) handler.setLevel(logging.DEBUG) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) -logger.addHandler(handler) logger.setLevel(logging.DEBUG) + class ScanDelegate(DefaultDelegate): def __init__(self): DefaultDelegate.__init__(self) @@ -19,7 +22,7 @@ def __init__(self): def handleDiscovery(self, dev, isNewDev, isNewData): pass -def radeon_device_finder(): +def radon_device_finder(): logger.debug('Scanning for devices') scanner = Scanner().withDelegate(ScanDelegate()) try: @@ -43,45 +46,68 @@ def radeon_device_finder(): scanner.stop() logger.error('Recieved scan exception ' + e.message) +#raw data for .05 pCi/L: +##50 0a 02 00 05 00 00 00 00 00 00 00 +##02 05 00 00 05 00 00 00 00' +##b'P\n\x02\x00\x05\x00\x00\x00\x00\x00\x00\x00' - +radonDataRAW = b"\x00" class ReadDelegate(btle.DefaultDelegate): def handleNotification(self, cHandle, data): + global radonDataRAW + logger.debug('Radon Value Raw: {}'.format(data)) + radonDataRAW=data + +def nConnect(per, num_retries, address): + try_num = 1 + while (try_num < num_retries): + try: + per._connect(address) + return True + except BTLEException: + logger.debug("Re-trying connections attempts: {}'".format(try_num)) + try_num += 1 + sleep(1) + # if we fell through the while loop, it failed to connect + return False + +def radon_device_reader(rdDeviceAddress,rdDeviceType): + if rdDeviceType >= 0: + p = btle.Peripheral() + nConnect(p, 5, rdDeviceAddress); + p.withDelegate(ReadDelegate()) + #send -- "char-write-cmd 0x002a 50\r" ./temp_expect.sh (https://community.home-assistant.io/t/radoneye-ble-interface/94962/115) + intHandle = int.from_bytes(b'\x00\x2a', "big") + bGETValues = b"\x50" + logger.debug('Sending payload (byte): %s To handle (int): %s', bGETValues, intHandle) + p.writeCharacteristic(intHandle, bGETValues, True); + while p.waitForNotifications(1): + pass + p.disconnect() + if rdDeviceType == 1: #new RD200 sends back short int (2-bytes) with Bq/m^3 - RadonValueBQ = struct.unpack('= 0: - p = btle.Peripheral(rdDeviceAddress) - p.withDelegate(ReadDelegate()) +if ('radon_reader_by_handle' not in sys.modules): #if I was not imported - #send -- "char-write-cmd 0x002a 50\r" - intHandle = int.from_bytes(b'\x00\x2a', "big") - bGETValues = b"\x50" - logger.debug('Sending payload (byte): %s To handle (int): %s', bGETValues, intHandle) - p.writeCharacteristic(intHandle, bGETValues, True); + logger.addHandler(handler) # add handler for standard out - while p.waitForNotifications(1): - pass - p.disconnect() + mRdDeviceAddress, mRdDeviceType = radon_device_finder() #auto find the device + radon_device_reader (mRdDeviceAddress , mRdDeviceType) #get data from the device -elif rdDeviceType == -1: - logger.error("Device not found, no data to return.") From 4c31344836c5541515cb03eee7e020774454fd49 Mon Sep 17 00:00:00 2001 From: Nickolai Golubev Date: Tue, 5 Jul 2022 02:03:51 -0700 Subject: [PATCH 06/21] Update README.md --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2e22a7f..035c6c1 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,19 @@ # RadonReader 2022 RD200 v2 (=>2022) -EtoTen 07/05/2022 +EtoTen v0.4 - 07/05/2022 - Forked Project - Changed compatability to Python3 - Added support for new RD200 models made in 2022 - Added auto-scan ability +Note: if specifying an -a MAC address, you now also have to specify a device type (either 0 for original RD200 or 1 for RD200 v2) + +Example usage: + +python3 radon_reader.py -a 94:3c:c6:dd:42:ce -t 1 -v +python3 radon_reader.py -v + ------------ From c418295dc9faf90ce412ac52ba099dcff3a49675 Mon Sep 17 00:00:00 2001 From: Nickolai Golubev Date: Tue, 5 Jul 2022 02:04:00 -0700 Subject: [PATCH 07/21] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 035c6c1..45b6952 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ Note: if specifying an -a MAC address, you now also have to specify a device typ Example usage: python3 radon_reader.py -a 94:3c:c6:dd:42:ce -t 1 -v + python3 radon_reader.py -v From 965e2ce7c07ebce7b03ba2dd9cc141702b2cf689 Mon Sep 17 00:00:00 2001 From: Nickolai Golubev Date: Tue, 5 Jul 2022 02:04:48 -0700 Subject: [PATCH 08/21] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 45b6952..68d2de2 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ EtoTen v0.4 - 07/05/2022 - Changed compatability to Python3 - Added support for new RD200 models made in 2022 - Added auto-scan ability +- Change the read function to call the handler directly, instead of interacting with the UUIDs Note: if specifying an -a MAC address, you now also have to specify a device type (either 0 for original RD200 or 1 for RD200 v2) From 5ff14427046c9d1ca2a475d11e5b9fc5ab6e33d3 Mon Sep 17 00:00:00 2001 From: Nickolai Golubev Date: Tue, 5 Jul 2022 02:30:50 -0700 Subject: [PATCH 09/21] Update README.md --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 68d2de2..5a9f1a1 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,19 @@ python3 radon_reader.py -a 94:3c:c6:dd:42:ce -t 1 -v python3 radon_reader.py -v +Pre-req install steps: + +sudo apt install libglib2.0-dev + +pip3 install bluepy + +pip3 install paho-mqtt + +setcap cap_net_raw+e /home/pi/.local/lib/python3.7/site-packages/bluepy/bluepy-helper + +setcap cap_net_admin+eip /home/pi/.local/lib/python3.7/site-packages/bluepy/bluepy-helper + + ------------ This project provides a tool which allows users collect current radon data from FTLab Radon Eye RD200 (Bluetooth only version). From dadf70439902bd019193695d80db3f0ea09740f7 Mon Sep 17 00:00:00 2001 From: Nickolai Golubev Date: Tue, 5 Jul 2022 02:33:10 -0700 Subject: [PATCH 10/21] Update README.md --- README.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 5a9f1a1..efc403d 100644 --- a/README.md +++ b/README.md @@ -10,24 +10,21 @@ EtoTen v0.4 - 07/05/2022 Note: if specifying an -a MAC address, you now also have to specify a device type (either 0 for original RD200 or 1 for RD200 v2) -Example usage: +#Example usage: python3 radon_reader.py -a 94:3c:c6:dd:42:ce -t 1 -v python3 radon_reader.py -v -Pre-req install steps: - +#Pre-req install steps: +

 sudo apt install libglib2.0-dev
-
 pip3 install bluepy
-
 pip3 install paho-mqtt
-
-setcap cap_net_raw+e /home/pi/.local/lib/python3.7/site-packages/bluepy/bluepy-helper
-
-setcap cap_net_admin+eip /home/pi/.local/lib/python3.7/site-packages/bluepy/bluepy-helper
+sudo setcap cap_net_raw+e /home/pi/.local/lib/python3.7/site-packages/bluepy/bluepy-helper
+sudo setcap cap_net_admin+eip /home/pi/.local/lib/python3.7/site-packages/bluepy/bluepy-helper
+
------------ @@ -47,6 +44,7 @@ This project provides a tool which allows users collect current radon data from # History +- 0.4 - Forked - 0.3 - Added MQTT support From 88a2db042eb45772cb7689e457a3f460a3f8a16b Mon Sep 17 00:00:00 2001 From: Nickolai Golubev Date: Tue, 5 Jul 2022 02:35:30 -0700 Subject: [PATCH 11/21] Update README.md --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index efc403d..c960f49 100644 --- a/README.md +++ b/README.md @@ -10,14 +10,9 @@ EtoTen v0.4 - 07/05/2022 Note: if specifying an -a MAC address, you now also have to specify a device type (either 0 for original RD200 or 1 for RD200 v2) -#Example usage: -python3 radon_reader.py -a 94:3c:c6:dd:42:ce -t 1 -v - -python3 radon_reader.py -v +# Pre-req install steps: - -#Pre-req install steps:

 sudo apt install libglib2.0-dev
 pip3 install bluepy
@@ -32,16 +27,15 @@ sudo setcap cap_net_admin+eip /home/pi/.local/lib/python3.7/site-packages/bluepy
 This project provides a tool which allows users collect current radon data from FTLab Radon Eye RD200 (Bluetooth only version).
 
 
-# Hardware Requeriments
+# Hardware Requirements
 - FTLabs RadonEye RD200 
-- Raspberry Pi 
-- Bluetooth LE (Low Energy) support
+- Raspberry Pi w/Bluetooth LE (Low Energy) support
 
 
 # Software Requeriments
 - Python 3.7
 - bluepy Python library
-
+- paho-mqtt Python library
 
 # History
 - 0.4 - Forked
@@ -49,7 +43,7 @@ This project provides a tool which allows users collect current radon data from
 
 
 # Usage
-
usage: radon_reader.py [-h] -a ADDRESS [-b] [-v] [-s] [-m] [-ms MQTT_SRV]
+
usage: radon_reader.py [-h] [-a] ADDRESS [-t] DEVICE_TYPE [-b] [-v] [-s] [-m] [-ms MQTT_SRV]
                        [-mp MQTT_PORT] [-mu MQTT_USER] [-mw MQTT_PW] [-ma]
 
 RadonEye RD200 (Bluetooth/BLE) Reader
@@ -67,3 +61,9 @@ optional arguments:
   -mu MQTT_USER    MQTT server username
   -mw MQTT_PW      MQTT server password
   -ma              Enable Home Assistant MQTT output (Default: EmonCMS)
+ +# Example usage: +

+python3 radon_reader.py -a 94:3c:c6:dd:42:ce -t 1 -v
+python3 radon_reader.py -v
+
From 5a25abd5826c8e763e702ca5ba1499949c63f3a0 Mon Sep 17 00:00:00 2001 From: Nickolai Golubev Date: Tue, 5 Jul 2022 02:36:50 -0700 Subject: [PATCH 12/21] Update README.md --- README.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c960f49..4d14355 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ EtoTen v0.4 - 07/05/2022 - Added auto-scan ability - Change the read function to call the handler directly, instead of interacting with the UUIDs -Note: if specifying an -a MAC address, you now also have to specify a device type (either 0 for original RD200 or 1 for RD200 v2) +Note: if specifying an (-a) MAC address, you now also have to specify a device type (-t) (either 0 for original RD200 or 1 for RD200 v2) # Pre-req install steps: @@ -28,11 +28,10 @@ This project provides a tool which allows users collect current radon data from # Hardware Requirements -- FTLabs RadonEye RD200 -- Raspberry Pi w/Bluetooth LE (Low Energy) support +- FTLabs RadonEye RD200 v1 or v2 +- Raspberry Pi w/Bluetooth LE (Low Energy) support (RPi 3B/4/etc...) - -# Software Requeriments +# Software Requirements - Python 3.7 - bluepy Python library - paho-mqtt Python library From 207eb24d477a1f331d089b183e09151b1a57e590 Mon Sep 17 00:00:00 2001 From: Nickolai Golubev Date: Tue, 5 Jul 2022 02:37:22 -0700 Subject: [PATCH 13/21] Update README.md --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4d14355..b6250e1 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,7 @@ Note: if specifying an (-a) MAC address, you now also have to specify a device t # Pre-req install steps: -

-sudo apt install libglib2.0-dev
+
sudo apt install libglib2.0-dev
 pip3 install bluepy
 pip3 install paho-mqtt
 sudo setcap cap_net_raw+e /home/pi/.local/lib/python3.7/site-packages/bluepy/bluepy-helper
@@ -62,7 +61,6 @@ optional arguments:
   -ma              Enable Home Assistant MQTT output (Default: EmonCMS)
# Example usage: -

-python3 radon_reader.py -a 94:3c:c6:dd:42:ce -t 1 -v
+
python3 radon_reader.py -a 94:3c:c6:dd:42:ce -t 1 -v
 python3 radon_reader.py -v
 
From c43391d8d86eb231f2f242ab1de8c19e4f36887c Mon Sep 17 00:00:00 2001 From: etoten Date: Tue, 5 Jul 2022 11:26:02 +0100 Subject: [PATCH 14/21] fixed debug log --- radon_reader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radon_reader.py b/radon_reader.py index 21f60db..50f699a 100644 --- a/radon_reader.py +++ b/radon_reader.py @@ -17,7 +17,7 @@ from radon_reader_by_handle import radon_device_finder, radon_device_reader, radonDataRAW, ScanDelegate, ReadDelegate, nConnect -logger = logging.getLogger(__name__) +logger = logging.getLogger() handler = logging.StreamHandler(sys.stdout) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) From 9a0aa5fc5467b0d9b225615a7d5e19529700ec77 Mon Sep 17 00:00:00 2001 From: Nickolai Golubev Date: Tue, 5 Jul 2022 03:26:54 -0700 Subject: [PATCH 15/21] Update README.md --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b6250e1..6ad9641 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ sudo setcap cap_net_admin+eip /home/pi/.local/lib/python3.7/site-packages/bluepy
+ ------------ This project provides a tool which allows users collect current radon data from FTLab Radon Eye RD200 (Bluetooth only version). @@ -61,6 +62,7 @@ optional arguments: -ma Enable Home Assistant MQTT output (Default: EmonCMS)
# Example usage: -
python3 radon_reader.py -a 94:3c:c6:dd:42:ce -t 1 -v
-python3 radon_reader.py -v
+
python3 radon_reader.py -a 94:3c:c6:dd:42:ce -t 1 -v #verbose output/ specific device MAC
+python3 radon_reader.py -v #verbose output, auto scan
+python3 radon_reader.py -v -a 94:3c:c6:dd:42:ce -t 1 -ms localhost -mu radonuser -mw radon123  -ma -m #verbose output, specific device MAC, mqtt to home assistant
 
From d9738dd85189a2f0cb0bf1b71197f2a7acb7c311 Mon Sep 17 00:00:00 2001 From: Nickolai Golubev Date: Tue, 5 Jul 2022 04:21:25 -0700 Subject: [PATCH 16/21] Update README.md --- README.md | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 6ad9641..c83ed28 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # RadonReader 2022 RD200 v2 (=>2022) +This project provides a tool which allows users collect current radon data from FTLab Radon Eye RD200 v1 and V2 (2022+) (Bluetooth only versions). EtoTen v0.4 - 07/05/2022 - Forked Project @@ -10,7 +11,6 @@ EtoTen v0.4 - 07/05/2022 Note: if specifying an (-a) MAC address, you now also have to specify a device type (-t) (either 0 for original RD200 or 1 for RD200 v2) - # Pre-req install steps:
sudo apt install libglib2.0-dev
@@ -20,13 +20,29 @@ sudo setcap cap_net_raw+e /home/pi/.local/lib/python3.7/site-packages/bluepy/blu
 sudo setcap cap_net_admin+eip /home/pi/.local/lib/python3.7/site-packages/bluepy/bluepy-helper
 
+# Home assistant integration via MQTT: + +- Install mosquitto MQTT add-on in HA, configure it with a local user and password +- Install mosquitto MQTT integration in HA +- On the host machine run:
python3 radon_reader.py -v -ms localhost -mu radonuser -mw radon123  -ma -m
and listen to: + "environment/RADONEYE/#" in the MQTT integration in HA to verify messages are being sent + +- Now make the app send automatic updates to HA every 3 minutes +
crontab -e
+
*/3 * * * * python3 /home/pi/radonreader/radon_reader.py -v -a 94:3c:c6:dd:42:ce -t 1 -ms localhost -mu radonuser -mw radon123  -mw radon123  -ma -m #update radon reading via MQTT every 3 minutes
+ +- Add this to configuration.yaml: +

+mqtt:
+  sensor:
+    - state_topic: "environment/RADONEYE/#"
+      name: 'Radon Level'
+      unit_of_measurement: 'pCi/L'
+      value_template: "{{ value_json.radonvalue }}"
+
- ------------- - -This project provides a tool which allows users collect current radon data from FTLab Radon Eye RD200 (Bluetooth only version). - - +- Now you cam add a sensor card to your HA view +- # Hardware Requirements - FTLabs RadonEye RD200 v1 or v2 - Raspberry Pi w/Bluetooth LE (Low Energy) support (RPi 3B/4/etc...) @@ -37,10 +53,9 @@ This project provides a tool which allows users collect current radon data from - paho-mqtt Python library # History -- 0.4 - Forked +- 0.4 - Forked and modified extensively - 0.3 - Added MQTT support - # Usage
usage: radon_reader.py [-h] [-a] ADDRESS [-t] DEVICE_TYPE [-b] [-v] [-s] [-m] [-ms MQTT_SRV]
                        [-mp MQTT_PORT] [-mu MQTT_USER] [-mw MQTT_PW] [-ma]

From 23243e18c55bbd3ee318121912ac6f1e9c6cf0ae Mon Sep 17 00:00:00 2001
From: Nickolai Golubev 
Date: Tue, 5 Jul 2022 04:38:11 -0700
Subject: [PATCH 17/21] Update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index c83ed28..a9178e8 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,7 @@ sudo setcap cap_net_admin+eip /home/pi/.local/lib/python3.7/site-packages/bluepy
  
 - Now make the app send automatic updates to HA every 3 minutes
  
crontab -e
-
*/3 * * * * python3 /home/pi/radonreader/radon_reader.py -v -a 94:3c:c6:dd:42:ce -t 1 -ms localhost -mu radonuser -mw radon123  -mw radon123  -ma -m #update radon reading via MQTT every 3 minutes
+
*/3 * * * * /usr/bin/python3 /home/pi/radonreader/radon_reader.py -v -a 94:3c:c6:dd:42:ce -t 1 -ms localhost -mu radonuser -mw radon123  -mw radon123  -ma -m #update radon reading via MQTT every 3 minutes
- Add this to configuration.yaml:


From 44fb7136859df854b862d4b1a37c7e08ef7d9d4f Mon Sep 17 00:00:00 2001
From: etoten 
Date: Tue, 5 Jul 2022 21:22:27 +0100
Subject: [PATCH 18/21] fixed RD200 old

---
 .../radon_reader_by_handle.cpython-37.pyc     | Bin 3467 -> 3514 bytes
 radon_reader_by_handle.py                     |  10 +++++++++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/__pycache__/radon_reader_by_handle.cpython-37.pyc b/__pycache__/radon_reader_by_handle.cpython-37.pyc
index 57bd509ff48e43a9bd22e02430c148668729b7e8..ca80490e924a148775a53db3ec58285f56dde788 100644
GIT binary patch
delta 406
zcmX|-%}N6?5P)Zr%{EPU)2+79vY^F_KWD|O_yAst=uyg`NTJ}mh=(kK;K_^7tHS0H
zq~O7`PvOD47oWk|T`_?q-^>>#naA`!wTE$RfJgfBF+Jw8a7dC6+zxAHE9<(=_P^_W!p&?P`jdA%WOz`%&CiGP$J=MGs;GUJ#D%pioXxoI(-KxBkk0)vB%4?!U^03n}jN4Sq(K
zk}`41qeq0Ad(2_OPPy=0Osdi=Gr@mdW1~l_l}r5z5KLfuaFije1AHrPQa0e_T2%eo
z`IOVki{{)}jLiP>*gWIjZk0oW8Y7IP78bRLFyP&CBw*4wtn)*55=?{^W;u=sTboAk
F#9x1MQXT*R

delta 372
zcmYjNF-`+95cK-aj^p^83j`@qnv{?t{DB7m(jn-h1r$Y!gt-DCAE~G)BT-SDpAe;^
zpy3xh0Evc%HU;a@;E`?3&UnZ6>)>f%kFrcN8okZ?#MzboR)zs%9uQ{2eJ*u#xF|&}
zF~KzODnU`DWusOoed?2t0Q0tQFk}Tg=pH+IEc+6)-17JjqmN`Vz5a>S)BAC8ImhYpOpk=y
rqssb0zrf)*`als37;Yd1ONhJT3VNVP>Cwy~=Tupr7=*@9a{~MV$>UB?

diff --git a/radon_reader_by_handle.py b/radon_reader_by_handle.py
index 5373dbb..22e4e6a 100644
--- a/radon_reader_by_handle.py
+++ b/radon_reader_by_handle.py
@@ -77,8 +77,16 @@ def radon_device_reader(rdDeviceAddress,rdDeviceType):
 		nConnect(p, 5, rdDeviceAddress);
 		p.withDelegate(ReadDelegate())
 		#send -- "char-write-cmd 0x002a 50\r" ./temp_expect.sh  (https://community.home-assistant.io/t/radoneye-ble-interface/94962/115)
-		intHandle = int.from_bytes(b'\x00\x2a', "big")
+
+		if rdDeviceType == 1:
+			#handle: 0x002a, uuid: 00001524-0000-1000-8000-00805f9b34fb 
+			intHandle = int.from_bytes(b'\x00\x2a', "big")
+		elif rdDeviceType == 0:  #old
+			#handle: 0x000b, uuid: 00001524-1212-efde-1523-785feabcd123
+			intHandle = int.from_bytes(b'\x00\x0b', "big") 
+
 		bGETValues = b"\x50"
+
 		logger.debug('Sending payload (byte): %s To handle (int): %s', bGETValues, intHandle)
 		p.writeCharacteristic(intHandle, bGETValues, True);
 		while p.waitForNotifications(1):

From c8efe0797e50eb133b6432c0c71751d26de3bba3 Mon Sep 17 00:00:00 2001
From: etoten 
Date: Tue, 5 Jul 2022 22:26:27 +0100
Subject: [PATCH 19/21] added support for old device to read_script.sh file

---
 read_script.sh | 37 +++++++++++++++++++++++++++++--------
 1 file changed, 29 insertions(+), 8 deletions(-)

diff --git a/read_script.sh b/read_script.sh
index f789835..7308c12 100755
--- a/read_script.sh
+++ b/read_script.sh
@@ -4,8 +4,29 @@
 log_user 0
 #
 set timeout 4
-#
-spawn gatttool -b 94:3c:c6:dd:42:ce -I
+# MAC address of RD200 device
+set MAC_A "94:3c:c6:dd:42:ce"
+# 1 for new RD200 device, 0 for old RD200 device
+set DEVICE_TYPE 1
+
+#command sent to get data
+set COMMAND  50
+
+##New device:
+#send 0x002a -> notification receive on: 0x002c
+if {$DEVICE_TYPE == "1"} {
+      set SEND_HANDLE  0x002a
+      set RECIEVE_HANDLE  0x002c
+}
+
+##Old device:
+##send 0x000b -> notification receive on: 0x000d
+if {$DEVICE_TYPE ==  "0" } {
+      set SEND_HANDLE  0x000b
+      set RECIEVE_HANDLE  0x000d
+}
+
+spawn gatttool -b $MAC_A -I
 #
 match_max 100000
 #
@@ -20,19 +41,19 @@ while (1) {
 #
 send -- "mtu 507\r"
 expect "MTU was exchanged successfully" {
-
     sleep 1
-    send -- "char-write-cmd 0x002a 50\r"
+    send -- "char-write-cmd $SEND_HANDLE $COMMAND\r"
+
 
     set systemTime [clock seconds]
     puts "Time [clock format $systemTime -format %Y-%m-%dT%H:%M:%S]"
     set message1 ""
 
     expect {
-             -re "Notification handle = 0x002c value: (.+\n)" {
-              set message1 ${message1}$expect_out(1,string)
-              exp_continue
-        }
+               -re "Notification handle = $RECIEVE_HANDLE value: (.+\n)" {
+		  set message1 ${message1}$expect_out(1,string)
+                  exp_continue
+                }
       }
       puts "$message1"
   }

From e659968321ad5d151e8cbbd1d6933f41c10bc53f Mon Sep 17 00:00:00 2001
From: Nickolai Golubev 
Date: Sat, 3 Dec 2022 16:02:14 -0800
Subject: [PATCH 20/21] Update README.md

---
 README.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/README.md b/README.md
index a9178e8..63aa887 100644
--- a/README.md
+++ b/README.md
@@ -37,6 +37,7 @@ mqtt:
   sensor:
     - state_topic: "environment/RADONEYE/#"
       name: 'Radon Level'
+      unique_id: 'radon_level'
       unit_of_measurement: 'pCi/L'
       value_template: "{{ value_json.radonvalue }}"
 
From d889c754d713f9ccce3ec8aa23c0814d3894712e Mon Sep 17 00:00:00 2001 From: Nickolai Golubev Date: Wed, 1 Mar 2023 22:58:42 -0800 Subject: [PATCH 21/21] Update README.md fixed typo --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 63aa887..3866c60 100644 --- a/README.md +++ b/README.md @@ -42,8 +42,8 @@ mqtt: value_template: "{{ value_json.radonvalue }}"
-- Now you cam add a sensor card to your HA view -- +- Now you can add a sensor card to your HA view + # Hardware Requirements - FTLabs RadonEye RD200 v1 or v2 - Raspberry Pi w/Bluetooth LE (Low Energy) support (RPi 3B/4/etc...)