forked from michaelmilnik/radonreader
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathradon_reader.py
130 lines (105 loc) · 5.08 KB
/
radon_reader.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!/usr/bin/python
""" radon_reader.py: RadonEye RD200 (Bluetooth/BLE) Reader """
__progname__ = "RadonEye RD200 (Bluetooth/BLE) Reader"
__version__ = "0.3.8"
__author__ = "Carlos Andre"
__email__ = "candrecn at hotmail dot com"
__date__ = "2019-10-20"
import argparse, struct, time, re, json
import paho.mqtt.client as mqtt
from bluepy import btle
from time import sleep
from random import randint
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)
parser.add_argument('-v','--verbose',action='store_true',help='Verbose mode', required=False)
parser.add_argument('-s','--silent',action='store_true',help='Output only radon value (without unit and timestamp)', required=False)
parser.add_argument('-m','--mqtt',action='store_true',help='Also send radon value to a MQTT server', required=False)
parser.add_argument('-ms',dest='mqtt_srv',help='MQTT server URL or IP address', required=False)
parser.add_argument('-mp',dest='mqtt_port',type=int,help='MQTT server service port (Default: 1883)', required=False, default=1883)
parser.add_argument('-mu',dest='mqtt_user',help='MQTT server username', required=False)
parser.add_argument('-mw',dest='mqtt_pw',help='MQTT server password', required=False)
parser.add_argument('-ma',dest='mqtt_ha',action='store_true',help='Switch to Home Assistant MQTT output (Default: EmonCMS)', required=False)
args = parser.parse_args()
args.address = args.address.upper()
if not re.match("^([0-9A-F]{2}:){5}[0-9A-F]{2}$", args.address) or (args.mqtt and (args.mqtt_srv == None or args.mqtt_user == None or args.mqtt_pw == None)):
parser.print_help()
quit()
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)
# Write 0x50 to 00001524-1212-efde-1523-785feabcd123
if args.verbose and not args.silent:
print ("Writing...")
uuidWrite = btle.UUID("00001524-1212-efde-1523-785feabcd123")
RadonEyeWrite = RadonEyeService.getCharacteristics(uuidWrite)[0]
RadonEyeWrite.write(bytes("\x50","utf-8"))
# Read from 3rd to 6th byte of 00001525-1212-efde-1523-785feabcd123
if args.verbose and not args.silent:
print ("Reading...")
uuidRead = btle.UUID("00001525-1212-efde-1523-785feabcd123")
RadonEyeValue = RadonEyeService.getCharacteristics(uuidRead)[0]
RadonValue = RadonEyeValue.read()
RadonValue = struct.unpack('<f',RadonValue[2:6])[0]
DevBT.disconnect()
# Raise exception (will try get Radon value from RadonEye again) if received a very
# high radon value or lower than 0.
# Maybe a bug on RD200 or Python BLE Lib?!
if ( RadonValue > 1000 ) or ( RadonValue <= 0 ):
raise Exception("Very strange radon value. Debugging needed.")
if args.becquerel:
Unit="Bq/m^3"
RadonValue = ( RadonValue * 37 )
else:
Unit="pCi/L"
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))
if args.mqtt:
if args.verbose and not args.silent:
print ("Sending to MQTT...")
if args.mqtt_ha:
mqtt_out="Home Assistant"
else:
mqtt_out="EmonCMS"
print ("MQTT Server: %s | Port: %s | Username: %s | Password: %s | Output: %s" % (args.mqtt_srv, args.mqtt_port, args.mqtt_user, args.mqtt_pw, mqtt_out))
# REKey = Last 3 bluetooth address octets (Register/Identify multiple RadonEyes).
# Sample: D7-21-A0
REkey = args.address[9:].replace(":","-")
clientMQTT = mqtt.Client("RadonEye_%s" % REkey)
clientMQTT.username_pw_set(args.mqtt_user,args.mqtt_pw)
clientMQTT.connect(args.mqtt_srv, args.mqtt_port)
if args.mqtt_ha:
ha_var = json.dumps({"radonvalue": "%0.2f" % (RadonValue)})
clientMQTT.publish("environment/RADONEYE/"+REkey,ha_var,qos=1)
else:
noha_var = round(RadonValue, 2)
clientMQTT.publish("emon/RADONEYE/"+REkey,noha_var,qos=1)
if args.verbose and not args.silent:
print ("OK")
sleep(1)
clientMQTT.disconnect()
try:
GetRadonValue()
except Exception as e:
if args.verbose and not args.silent:
print (e)
for i in range(1,4):
try:
if args.verbose and not args.silent:
print ("Failed, trying again (%s)..." % i)
sleep(5)
GetRadonValue()
except Exception as e:
if args.verbose and not args.silent:
print (e)
if i < 3:
continue
else:
print ("Failed.")
break