225 lines
7.5 KiB
Python
225 lines
7.5 KiB
Python
#!/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))
|