diff --git a/tools/iaq/card10_iaq_notify.py b/tools/iaq/card10_iaq_notify.py index 2dba973938ceddea95c9c5d07487ca5f2560748a..89da7f69602c07e6180152f536556867f4436974 100644 --- a/tools/iaq/card10_iaq_notify.py +++ b/tools/iaq/card10_iaq_notify.py @@ -1,69 +1,74 @@ #!/usr/bin/env python3 +# Written 2021 by Stefan `Sec` Zehl + import argparse import struct import os import select +import sys from bluez import Manager parser = argparse.ArgumentParser(description='Receive IAQ values from Card10') -parser.add_argument('--mac', help='mac of device to query') +parser.add_argument('-v', '--verbose', help='help debug', action='count', default=0) +parser.add_argument('-m', '--mac', help='mac of device to query') +parser.add_argument('-i', '--influx', metavar='URL', + help='url of influxdb to push to. E.g.: http://influxdb:8086/write?db=card10') args = parser.parse_args() -mgr = Manager(); +if args.influx is not None: + import requests + +mgr = Manager() a = mgr.get_adapter() #print('Using adapter', a) # Get devices which support environmental sensing devices=a.get_devices('0000181a-0000-1000-8000-00805f9b34fb') -device=None - if len(devices)>1: print("Mutiple devices found:") for d in devices: print("-", d.Name, d.Address, end=" ") - if d.Address == args.mac: - print("(selected)") - device=d - elif args.mac is None and device is None: - print("(default)") - device=d - else: - print("") + if d.Address == args.mac: + print("(selected)") + device=d + elif args.mac is None and device is None: + print("(default)") + device=d + else: + print("") elif len(devices)==1: device=devices[0] - print("Using device", device.Name, device.Address) + if args.verbose: + print("Using device", device.Name, device.Address) else: print("No capable device found") + sys.exit(1) #print('Device:', device) device.connect() -services = device.get_gattservices(); +services = device.get_gattservices() def p_temp(data): - tmp=struct.unpack('=H',data) - t=tmp[0] - return {'temp': tmp[0]/100} + tmp=struct.unpack('=H', data) + return {'temperature': tmp[0]/100} def p_humidity(data): - tmp=struct.unpack('H',data) - t=tmp[0] - return {'humidity': t/100} + tmp=struct.unpack('H', data) + return {'humidity': tmp[0]/100} def p_pressure(data): - tmp=struct.unpack('I',data) - t=tmp[0] - return {'pressure': t/1000} - + tmp=struct.unpack('I', data) + return {'pressure': tmp[0]/1000} def p_iaq(data): names=['iaq_accuracy','iaq','co2'] - tmp=struct.unpack('=BHH',data) + tmp=struct.unpack('=BHH', data) return dict(zip(names, tmp)) characteristics={ @@ -79,21 +84,42 @@ fds=[] for suuid,svc in services.items(): chars=svc.get_gattcharacteristics() for uuid,char in chars.items(): -# print(" - ",uuid) +# print(" - ", uuid) if uuid in characteristics: - print("Found",uuid) + if args.verbose: + print("Found", uuid) an=char.AcquireNotify() # (fd, mtu) mapping[an[0]]=characteristics[uuid] fds.append(an[0]) +if len(fds)<len(characteristics): + print("WARN: Could only subscribe to %d characteristics"%len(fds), file=sys.stderr) +else: + print("Subscribed to %d characteristics on %s (%s)"%(len(fds), device.Name, device.Address)) + + +post=None while True: + if args.influx is not None: + post={} + ready,_,_ = select.select(fds,[],[]) for fd in ready: - print("notify:",end=" ") - data=os.read(fd, 100) #read max 100 characters - parse=mapping[fd](data) - print(parse) + ble_data=os.read(fd, 100) #read max 100 characters + parse=mapping[fd](ble_data) + if args.influx is not None: + post.update(parse) + else: + print("notify:", parse) + + if args.influx is not None: + line=" ".join(["air",",".join([k+"="+str(v) for k,v in post.items()])]) + if args.verbose: + print(line) + r = requests.post(args.influx, data=line) + if r.status_code != 204: + print(r.status_code, r.reason) #device.disconnect() print('Exit')