You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

263 lines
7.5 KiB

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Dev: wh0ami
# Licence: Public Domain <https://unlicense.org>
# Project: https://codeberg.org/wh0ami/weather-backend/
# Bibliotheken importieren (+ Abhängigkeiten)
import os
import json
from pathlib import Path
from time import time
import math
from influxdb import InfluxDBClient # für InfluxDB Anbindung (pip3 install influxdb)
import Adafruit_DHT # für DHT22 (pip3 install Adafruit-DHT)
import Adafruit_BMP.BMP085 as BMP085 # für BMP180 (pip3 install Adafruit-BMP)
import smbus2 # für BME280 (pip3 install smbus2)
import bme280 # für BME280 (pip3 install RPi.bme280)
# Startzeit in Form eines UNIX-Timestamps
start = time()
# Temperatur mit dem DS18B20 messen
# file ist der vollständige Pfad zum Sensor
# /sys/bus/w1/devices/28-051760a432ff/w1_slave -> Erde
# /sys/bus/w1/devices/28-051760b320ff/w1_slave -> Außen
def ds18b20(file):
outtemp = False
if os.path.isfile(file):
f = open(file)
buffer = f.readline()
if "YES" in buffer:
outtemp = float(int(f.readline().split()[9][2:]) / 1000.0)
f.close()
return(outtemp)
# Temperatur mit dem DHT22 messen (DHT22 ist im Innengehäuse -> Innentemperatur)
# pin ist der genutzte Pin, in unserem Fall 17
def dht22(pin):
temp = False
humidity, temperature = Adafruit_DHT.read_retry(Adafruit_DHT.DHT22, pin)
if temperature is not None:
temp = float('{0:0.1f}'.format(temperature))
return(temp)
# Luftfeuchtigkeit mit dem BME280 messen
def bme280_hum():
humidity = False
bus = smbus2.SMBus(1)
address = 0x76
calibration_params = bme280.load_calibration_params(bus, address)
data = bme280.sample(bus, address, calibration_params)
if data.humidity is not None:
humidity = float(round(data.humidity, 2))
if humidity > 100:
humidity = 100.0
return(humidity)
# Temperatur mit dem BME280 messen
def bme280_temp():
temp = False
bus = smbus2.SMBus(1)
address = 0x76
calibration_params = bme280.load_calibration_params(bus, address)
data = bme280.sample(bus, address, calibration_params)
if data.temperature is not None:
temp = float(round(data.temperature, 2))
return(temp)
# Luftdruck mit dem BMP180 messen
def bmp180():
pressure = False
bmppress = BMP085.BMP085(mode=BMP085.BMP085_ULTRAHIGHRES).read_pressure()
if bmppress is not None:
pressure = int(round(bmppress / 100, 0))
return(pressure)
# Messungen
ts_ns = int(time())*1000000000
newdata = []
buffer = {}
buffer["measurement"] = 'aussentemperatur'
buffer["tags"] = {}
buffer["tags"]["comment"] = 'Aussentemperatur in °C'
buffer["tags"]["sensor"] = 'BME280'
buffer["time"] = ts_ns
buffer["fields"] = {}
#buffer["fields"]["wert"] = ds18b20('/sys/bus/w1/devices/28-051760b320ff/w1_slave')
try:
buffer["fields"]["wert"] = bme280_temp()
except:
buffer["fields"]["wert"] = False
if buffer["fields"]["wert"]:
newdata.append(buffer)
aussentemperatur = buffer["fields"]["wert"]
else:
aussentemperatur = None
buffer = {}
buffer["measurement"] = 'bodentemperatur'
buffer["tags"] = {}
buffer["tags"]["comment"] = 'Bodentemperatur in °C'
buffer["tags"]["sensor"] = 'DS18B20'
buffer["time"] = ts_ns
buffer["fields"] = {}
buffer["fields"]["wert"] = ds18b20('/sys/bus/w1/devices/28-051760a432ff/w1_slave')
if buffer["fields"]["wert"]:
newdata.append(buffer)
buffer = {}
buffer["measurement"] = 'innentemperatur'
buffer["tags"] = {}
buffer["tags"]["comment"] = 'Innentemperatur in °C'
buffer["tags"]["sensor"] = 'dht22'
buffer["time"] = ts_ns
buffer["fields"] = {}
buffer["fields"]["wert"] = dht22(17)
if buffer["fields"]["wert"]:
newdata.append(buffer)
buffer = {}
buffer["measurement"] = 'relative_luftfeuchtigkeit'
buffer["tags"] = {}
buffer["tags"]["comment"] = 'Luftfeuchtigkeit in %'
buffer["tags"]["sensor"] = 'BME280'
buffer["time"] = ts_ns
buffer["fields"] = {}
try:
buffer["fields"]["wert"] = bme280_hum()
except:
buffer["fields"]["wert"] = False;
if buffer["fields"]["wert"]:
newdata.append(buffer)
relative_luftfeuchtigkeit = buffer["fields"]["wert"]
else:
relative_luftfeuchtigkeit = None
buffer = {}
buffer["measurement"] = 'luftdruck'
buffer["tags"] = {}
buffer["tags"]["comment"] = 'Luftdruck in hPa'
buffer["tags"]["sensor"] = 'BMP180'
buffer["time"] = ts_ns
buffer["fields"] = {}
try:
buffer["fields"]["wert"] = bmp180()
except:
buffer["fields"]["wert"] = False
if buffer["fields"]["wert"]:
newdata.append(buffer)
# Taupunkt und Luftfeuchtigkeit berechnen
#Bezeichnungen:
#r = relative Luftfeuchte
#T = Temperatur in °C
#TK = Temperatur in Kelvin (TK = T + 273.15)
#TD = Taupunkttemperatur in °C
#DD = Dampfdruck in hPa
#SDD = Sättigungsdampfdruck in hPa
#
#Parameter:
#a = 7.5, b = 237.3 für T >= 0
#a = 7.6, b = 240.7 für T < 0 über Wasser (Taupunkt)
#a = 9.5, b = 265.5 für T < 0 über Eis (Frostpunkt)
#
#R* = 8314.3 J/(kmol*K) (universelle Gaskonstante)
#mw = 18.016 kg/kmol (Molekulargewicht des Wasserdampfes)
#AF = absolute Feuchte in g Wasserdampf pro m3 Luft
#
#Formeln:
#1. SDD(T) = 6.1078 * 10^((a*T)/(b+T))
#2. DD(r,T) = r/100 * SDD(T)
#3. r(T,TD) = 100 * SDD(TD) / SDD(T)
#4. TD(r,T) = b*v/(a-v) mit v(r,T) = log10(DD(r,T)/6.1078)
#5. AF(r,TK) = 10^5 * mw/R* * DD(r,T)/TK; AF(TD,TK) = 10^5 * mw/R* * SDD(TD)/TK
#
# Quelle: http://www.wetterochs.de/wetter/feuchte.html (abgerufen am 04.05.2019 um 12 Uhr)
if aussentemperatur is not None and relative_luftfeuchtigkeit is not None:
if aussentemperatur >= 0:
a = 7.5
b = 237.3
else:
a = 7.6
b = 240.7
# Hilfswerte berechnen
saettigungsdampfdruck = float(6.1078 * 10 ** ((a * aussentemperatur)/(b + aussentemperatur)))
dampfdruck = float(relative_luftfeuchtigkeit / 100 * saettigungsdampfdruck)
aussentemperatur_kelvin = float(aussentemperatur + 273.15)
# Taupunkt berechnen
v = float(math.log10(dampfdruck / 6.1078))
taupunkt = float(round(b * v / (a - v), 2))
# absolute Luftfeuchtigkeit berechnen
absolute_luftfeuchtigkeit = float(round(float(10 ** 5 * 18.016 / 8314.3 * dampfdruck / aussentemperatur_kelvin), 2))
buffer = {}
buffer["measurement"] = 'absolute_luftfeuchtigkeit'
buffer["tags"] = {}
buffer["tags"]["comment"] = 'Luftfeuchtigkeit in g/m³'
buffer["tags"]["sensor"] = '-'
buffer["time"] = ts_ns
buffer["fields"] = {}
buffer["fields"]["wert"] = absolute_luftfeuchtigkeit
newdata.append(buffer)
buffer = {}
buffer["measurement"] = 'taupunkt'
buffer["tags"] = {}
buffer["tags"]["comment"] = 'Taupunkt in °C'
buffer["tags"]["sensor"] = '-'
buffer["time"] = ts_ns
buffer["fields"] = {}
buffer["fields"]["wert"] = taupunkt
newdata.append(buffer)
else:
taupunkt = False
absolute_luftfeuchtigkeit = False
# Messdauer berechnen
buffer = {}
buffer["measurement"] = 'messdauer_detailed'
buffer["tags"] = {}
buffer["tags"]["comment"] = 'Messdauer in Sekunden'
buffer["time"] = ts_ns
buffer["fields"] = {}
buffer["fields"]["wert"] = time() - start
newdata.append(buffer)
# Konfiguration für die Datenbankverbindung einlesen
config_path = str(os.path.dirname(os.path.realpath(__file__)))+"/config.json"
if Path(config_path).is_file():
try:
with open(config_path, "r") as infile:
config = json.load(infile)["config"]
except:
print("Fehler beim Öffnen der Konfigurationsdatei!")
exit(1)
else:
print("[Fehler] Konfigurationsdatei nicht gefunden! Die Datei muss config.json heißen und im selben Verzeichnis wie dieses Script liegen.")
exit(1)
# Datenbankverbindung aufbauen und Daten in die Datenbank schreiben
client = InfluxDBClient(config["host"], config["port"], config["username"], config["password"])
client.switch_database(config["database"])
client.write_points(newdata)
exit(0)