#!/usr/bin/python -u ''' -------------------------------------------------------------------------------- Type: Python 3.x script Author: Milan Toman (milan.v.toman@gmail.com) Description: Weather station (davis vantage vue) collector, coupled with the infamous arduino source on http://wp.spoton.cz/2017/11/24/davis-vantague-vue-arduino-and-a-raspberry-pi-3/ en-fucking-joy influxDB SCHEMA: DB weather measure temphumi ---------------- temperature | humidity | external, internal | pressure --------------------------------------------------------- field field tag field -------------------------------------------------------------------------------- Import libraries -------------------------------------------------------------------------------- ''' # mandatory import requests import sys import os import re import textwrap import argparse import time import datetime import serial import simplejson as json import influxdb import configparser # optionally, future modules, locally available, I hate dependencies from pprint import pprint _SCRIPT_PATH = os.path.dirname(os.path.abspath(sys.argv[0])) sys.path.append(_SCRIPT_PATH + "/lib") #import ventilLogger ''' -------------------------------------------------------------------------------- Define variables -------------------------------------------------------------------------------- ''' config = configparser.ConfigParser() config.read(_SCRIPT_PATH + "/../web/config/plutonium.ini") _VERSION = 1.0 _NAME = u"Vantage Vue external measure enrichment" _LOG_DIR = _SCRIPT_PATH + '/log/' _LOG_FILE_ROOT = re.sub(u'./', '', sys.argv[0]) _LOG_FILE = _LOG_DIR + _LOG_FILE_ROOT + u'.log' _DEBUG_FILE = _LOG_DIR + _LOG_FILE_ROOT + u'.dbg' # finite loop implementation, tout for 43200 cycles tout = 0 _ABS_ZERO = 273.15 _HEIGHT = 455 _EXT_MEASURE_DEVICE = '/dev/ttyUSBext' pressure_adjusted = 0 influx_weather_write = [] influx_host = config['InfluxDB']['_influx_host'] influx_port = config['InfluxDB']['_influx_port'] influx_user = config['InfluxDB']['_influx_user'] influx_pwd = config['InfluxDB']['_influx_pwd'] weather_db = config['InfluxDB']['_influx_weather_db'] status_db = config['InfluxDB']['_influx_status_db'] ''' -------------------------------------------------------------------------------- Set up logging - disabled, need to enable this iin future -------------------------------------------------------------------------------- ''' ''' -------------------------------------------------------------------------------- Setup arguments and Options - not edited, sample shite -------------------------------------------------------------------------------- ''' desc = u'''\ DESCRIPTION: Vantage Vue pressure enrichment script ''' epi = u'''\ ERROR CODES: ? EXAMPLES: ? ''' formatter = argparse.RawDescriptionHelpFormatter arg_parser = argparse.ArgumentParser(description = desc, formatter_class = formatter, epilog = textwrap.dedent(epi)) args = arg_parser.parse_args() ''' -------------------------------------------------------------------------------- Generic, standalone functions -------------------------------------------------------------------------------- ''' # Obvious shit, set up the client class influx_weather_client = influxdb.client.InfluxDBClient( influx_host, influx_port, influx_user, influx_pwd, weather_db ) ''' -------------------------------------------------------------------------------- Classes -------------------------------------------------------------------------------- ''' class extDataDecode(object): def __init__(self): __name__ = u'Davis external data decoder' self.height = _HEIGHT self.temp_dict = {} def load_external_data(self): # Data external to the ISS self.pressure = float(external_data['P']) self.inside_temp = round(float(external_data['T']), 2) self.inside_hum = external_data['H'] def adjust_pressure(self, temp): sh = 0.0065 * self.height base = 1 - (sh) / (temp + sh + _ABS_ZERO) result = round(self.pressure * pow(base, -5.257), 2) return result class DBwriter(object): def __init__(self): __name__ = "Database writer class, Influx" def construct(self, connector, measurement, fields, tags): """ Takes values in a writes them to influxdb requires: list(connector): connector with all ticks to be written at once str(measurement): the measurement ID to be written dict(fields): fields to be written in one tick dict(tags): tags to be written with the fields returns: list(result_connector) """ result_connector = connector result_connector.append({"measurement": measurement, "fields": fields, "tags": tags} ) return result_connector ''' -------------------------------------------------------------------------------- Main -------------------------------------------------------------------------------- ''' if '__main__': davis_decoder = extDataDecode() davis_writer = DBwriter() try: with serial.Serial(_EXT_MEASURE_DEVICE, 9600) as data: # Now, let it run a couple times, end and restart via systemd while tout < 400: line = data.readline() #print(line) external_data = 0 try: external_data = eval(line) except SyntaxError as e_syntax: print("ERROR (syntax): {}".format(e_syntax)) except TypeError as e_type: print("ERROR (Type): {}".format(e_type)) except ValueError as e_value: print("ERROR (Type): {}".format(e_value)) if external_data != 0: # Get data external to the ISS, from local PCB / internal # sensors and create base values for influx writing davis_decoder.load_external_data() influx_weather_write = davis_writer.construct( influx_weather_write, "temphumi", {"pressure": davis_decoder.pressure}, {"type" : "raw"} ) influx_weather_write = davis_writer.construct( influx_weather_write, "temphumi", {"pressure": davis_decoder.inside_temp}, {"type" : "internal"} ) influx_weather_write = davis_writer.construct( influx_weather_write, "temphumi", {"pressure": davis_decoder.inside_hum}, {"type" : "internal"} ) # Write the whole blob into Influx DB influx_weather_client.write_points(influx_weather_write) tout = tout + 1 time.sleep(1) else: print("No data here, mate.") except serial.serialutil.SerialException as e: print("Serial Error {}".format(e))