#!/usr/bin/env python3 import datetime from os import environ as env from time import sleep import json import click import configparser from airthings import fetch_measurements, discover_devices from influxdb import InfluxDBClient from influxdb.exceptions import InfluxDBClientError def read_config(file): config = configparser.ConfigParser() config.read(file) return config @click.group() @click.option('--debug/--no-debug') @click.option('-c', '--config', default="config.ini", help='give config file') @click.pass_context def cli(ctx, debug, config): ctx.ensure_object(dict) ctx.obj['DEBUG'] = debug ctx.obj['CONFIG'] = config if debug: click.echo("Debug is enabled") @cli.command() @click.pass_context def verify(ctx): """verify your configuration - does not do much yet!""" config = read_config(ctx.obj['CONFIG']) influx_host = env.get("InfluxdbHost", config['DEFAULT']['InfluxdbHost']) influx_port = env.get("InfluxdbPort", config['DEFAULT']['InfluxdbPort']) influx_user = env.get("InfluxdbUser", config['DEFAULT']['InfluxdbUser']) influx_pass = env.get("InfluxdbPassword", config['DEFAULT']['InfluxdbPassword']) influx_db = env.get("InfluxdbDatabase", config['DEFAULT']['InfluxdbDatabase']) client = InfluxDBClient(influx_host, influx_port, influx_user, influx_pass, influx_db) @cli.command() def identify(): """Lists available sensors nearby""" airthings_devices = fetch_measurements() print("Found %s Airthings device(s):" % len(airthings_devices)) for device in airthings_devices: print("=" * 36) print("\tMAC address:", device.mac_address) print("\tIdentifier:", device.identifier) print("\tModel:", device.label) print("\tModel number:", device.model_number) print("\tHas measurements:", device.has_measurements) print("\tSensor capabilities:") for sensor, supported in device.sensor_capabilities.items(): print("\t", sensor, "=", "YES" if supported else "NO") print("+" * 11, "Measurements", "+" * 11) print("\t", device.humidity) print("\t", device.radon_short_term_avg) print("\t", device.radon_long_term_avg) print("\t", device.temperature) print("\t", device.atmospheric_pressure) print("\t", device.co2) print("\t", device.voc) @cli.command() @click.pass_context def start(ctx): """ """ click.echo("Starting the Airthings to Influxdb Bridge") click.echo("Reading the config...") config = read_config(ctx.obj['CONFIG']) influx_host = env.get("InfluxdbHost", config['DEFAULT']['InfluxdbHost']) influx_port = env.get("InfluxdbPort", config['DEFAULT']['InfluxdbPort']) influx_user = env.get("InfluxdbUser", config['DEFAULT']['InfluxdbUser']) influx_pass = env.get("InfluxdbPassword", config['DEFAULT']['InfluxdbPassword']) influx_db = env.get("InfluxdbDatabase", config['DEFAULT']['InfluxdbDatabase']) interval = env.get("Interval", config['DEFAULT']['Interval']) click.echo("Starting the Influxdb Client...") client = InfluxDBClient(influx_host, influx_port, influx_user, influx_pass, influx_db) data = [] click.echo("Starting sensor probing") while True: click.echo("Searching devices...") airthings_devices = fetch_measurements() print("Found %s Airthings devices:" % len(airthings_devices)) for device in airthings_devices: print("=" * 36) print("\tMAC address:", device.mac_address) print("\tIdentifier:", device.identifier) print("\tModel:", device.label) print("\tModel number:", device.model_number) print("\tHas measurements:", device.has_measurements) click.echo("Collecting sensor data...") now = datetime.datetime.now() if device.humidity: json_body = { "measurement": "humidity", "tags": { "mac address": device.mac_address, "identifier": device.identifier, "model": device.label, "model number": device.model_number }, "time": now, "fields": { "value": device.humidity.value } } data.append(json_body) if device.radon_short_term_avg: json_body = { "measurement": "radon_short_term_avg", "tags": { "mac address": device.mac_address, "identifier": device.identifier, "model": device.label, "model number": device.model_number }, "time": now, "fields": { "value": device.radon_short_term_avg.value } } data.append(json_body) if device.radon_long_term_avg: json_body = { "measurement": "radon_long_term_avg", "tags": { "mac address": device.mac_address, "identifier": device.identifier, "model": device.label, "model number": device.model_number }, "time": now, "fields": { "value": device.radon_long_term_avg.value } } data.append(json_body) if device.temperature: json_body = { "measurement": "temperature", "tags": { "mac address": device.mac_address, "identifier": device.identifier, "model": device.label, "model number": device.model_number }, "time": now, "fields": { "value": device.temperature.value } } data.append(json_body) if device.co2: json_body = { "measurement": "co2", "tags": { "mac address": device.mac_address, "identifier": device.identifier, "model": device.label, "model number": device.model_number }, "time": now, "fields": { "value": device.co2.value } } data.append(json_body) if device.voc: json_body = { "measurement": "voc", "tags": { "mac address": device.mac_address, "identifier": device.identifier, "model": device.label, "model number": device.model_number }, "time": now, "fields": { "value": device.voc.value } } data.append(json_body) #write data click.echo("Trying to send datapoints...") try: client.write_points(data) click.echo("Sent!") except InfluxDBClientError as e: click.echo("An error occured: %s" % e) click.echo("Storing data for now, waiting for the next interval." % e) click.echo("Sleeping for %s seconds" % interval) sleep(int(interval)) if __name__ == '__main__': cli()