#!/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 InfluxDBServerError 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 Influxdb configuration""" 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) click.echo("Trying to connect to influxdb...") try: ping = client.ping() click.echo("Success! Version: %s"% ping) except InfluxDBClientError as e: click.echo("An error occured: %s" % e) @cli.command() def identify(): """Lists available sensors nearby""" airthings_devices = fetch_measurements() click.echo("Found %s Airthings device(s):" % len(airthings_devices)) for device in airthings_devices: click.echo("=" * 36) click.echo("\tMAC address: %s" % device.mac_address) click.echo("\tIdentifier: %s" % device.identifier) click.echo("\tModel: %s" % device.label) click.echo("\tModel number: %s" % device.model_number) click.echo("\tHas measurements:" + str(device.has_measurements)) click.echo("\tSensor capabilities:") for sensor, supported in device.sensor_capabilities.items(): click.echo("\t" + sensor + "=" + "YES" if supported else "\t" + "NO") click.echo("+" * 11 + "Measurements" + "+" * 11) click.echo("\t %s" % device.humidity) click.echo("\t %s" % device.radon_short_term_avg) click.echo("\t %s" % device.radon_long_term_avg) click.echo("\t %s" % device.temperature) click.echo("\t %s" % device.atmospheric_pressure) click.echo("\t %s" % device.co2) click.echo("\t %s" % device.voc) @cli.command() @click.pass_context def start(ctx): """ Start collecting data from your airthings sensors """ 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() click.echo("Found %s Airthings devices:" % len(airthings_devices)) for device in airthings_devices: click.echo("=" * 36) click.echo("\tMAC address: %s" % device.mac_address) click.echo("\tIdentifier: %s" % device.identifier) click.echo("\tModel: %s" % device.label) click.echo("\tModel number: %s" % device.model_number) click.echo("\tHas measurements: %s" % 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 InfluxDBServerError as e: click.echo("An error occured: %s" % e) click.echo("Storing data for now, waiting for the next interval.") click.echo("Sleeping for %s seconds" % interval) sleep(int(interval)) if __name__ == '__main__': cli()