Files
airthings-influxdb/airthings-influxdb.py
2021-03-12 17:50:17 +01:00

226 lines
8.2 KiB
Python
Executable File

#!/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()