Initial Commit

master
Hofei90 4 years ago
parent b8617ad52d
commit 73188fcb78

1
.gitattributes vendored

@ -0,0 +1 @@
*.py text eol=lf

132
.gitignore vendored

@ -0,0 +1,132 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# Smartmeter Konfigurationsfile
wetterconfig.toml

@ -1,2 +1,101 @@
# weewx_to_grafanaserver
# Vorbereitungen
## Koordinaten vorbereiten
[Bayernatlas](https://geoportal.bayern.de "Bayernatlas") besuchen, Adresse der
Station eingeben, Koordinaten werden später benötigt.
Kooardinaten müssen dem Administrator bei der Stationsregistrierung mittgeteilt
werden.
# Installation Client Skripte
## Python
Es wird mindestens Python 3.7+ vorausgesetzt
## Benötigte Python Module installieren
```console
apt install python3-systemd
git clone https://git.pertl-ing.de/Hofei/weewx_to_grafanaserver.git /home/pi/weewx_to_grafanaserver
pip3 install -r requirements.txt
```
Bei der Installation ist gegenfalls zu achten die Module für den passenden User
zu installieren (bsp. sudo pip3 install ... oder pip3 install --user).
Die beiliegenden Service Units sind für den User root ausgelegt
Es empiehlt sich folgenden Pfad zu verwenden, da hierfür die Service Units schon vorbereitet sind,
Abweichungen müssen angepasst werden
`/home/pi/weewx_to_grafanaserver`.
## Konfiguration anpassen
```console
cp vorlage_wetterconfig.toml wetterconfig.toml
nano wetterconfig.toml
```
## Inbetriebnahme
Da WeeWx in der Standardinstallation mit root Rechten läuft, so benötigen auch diese Skripte root Rechte
um auf die Datenbank von WeeWx zugreifen zu können. Somit empfiehlt es sich die root Crontab zu verwenden
(`sudo crontab -e`)
Anstelle der Verwendung der Crontab liegen im Repository für jedes Exportskript eine Systemd Service Unit mit Timer Unit
bei.
Dies stellt den **moderneren** Weg dar. Hierfür die universelle Anleitung unter dem Punkt Systemd Unit beachten
### grafana_export.py
Datei erstmals manuell ausführen. Erste Ausführung wird je nach Weewx Datenbank-
größe viel Zeit in Anspruch nehmen. --> Geduldig abwarten!
Nach der erfolgreichen ersten Übertragung der Wetterdaten aus der Weewx
Datenbank einen Cronjob mit dem gewünschten Ausführintervall erstellen
(Standardmäßig alle 5 Minuten)
#### Cronjob
````console
crontab -e
````
`*/5 * * * * python3 /home/pi/weewx_to_grafanaserver/grafana_export.py`
### Feinstaubsensor (Optional)
Wer einen Feinstaubsensor hat, die URL in der Konfigurationsdatei hinterlegen und `feinstaub.py` direkt aufrufen,
entweder mit Cronjob oder Systemd Service Unit
#### Cronjob
````console
crontab -e
````
`*/5 * * * * python3 /home/pi/weewx_to_grafanaserver/feinstaub.py`
Hinweis: Grafana kann nur nach erfolgreicher Stationsregistrierung
funktionieren. Hierfür den Administrator kontaktieren mit Besitzer, Stationsname
und Koordinaten
### Systemd Unit
Alternativ zur Crontab kann eine Systemd Unit verwendet werden.
Hierfür die zugehörigen Dateien mit der Endung .service und .timer im systemd_files Ordner nach
`/etc/systemd/system` kopieren und die Rechte anpassen
```console
cp <files> /etc/systemd/system/
chmod 644 /etc/systemd/system/<file>
```
Anschließend kann das Skript manuell getestet werden mit:
```console
systemctl start <unitname>.service
```
Verläuft dieser Test positiv, kann der Timer gestartet werden:
```console
systemctl start <timername>.timer
systemctl enable <timername>.timer
```

@ -0,0 +1,40 @@
-- Funktion für PostgreSQL Server, für Clientskripte nicht relevant
-- FUNCTION: public.set_intervall(interval, timestamp with time zone, timestamp with time zone)
-- DROP FUNCTION public.set_intervall(interval, timestamp with time zone, timestamp with time zone);
CREATE OR REPLACE FUNCTION public.set_intervall(
min_intervall interval,
von_timestamp timestamp with time zone,
bis_timestamp timestamp with time zone)
RETURNS interval
LANGUAGE 'sql'
COST 100
VOLATILE
AS $BODY$
SELECT CASE
WHEN (min_intervall <= '1 seconds'::interval and '1 seconds'::interval > (bis_timestamp::timestamp - von_timestamp::timestamp) / 2000) THEN ('1 seconds'::interval)
WHEN (min_intervall <= '10 seconds'::interval and '10 seconds'::interval > (bis_timestamp::timestamp - von_timestamp::timestamp) / 2000) THEN ('10 seconds'::interval)
WHEN (min_intervall <= '30 seconds'::interval and '30 seconds'::interval > (bis_timestamp::timestamp - von_timestamp::timestamp) / 2000) THEN ('30 seconds'::interval)
WHEN (min_intervall <= '1 minutes'::interval and '1 minutes'::interval > (bis_timestamp::timestamp - von_timestamp::timestamp) / 2000) THEN ('1 minutes'::interval)
WHEN (min_intervall <= '5 minutes'::interval and '5 minutes'::interval > (bis_timestamp::timestamp - von_timestamp::timestamp) / 2000) THEN ('5 minutes'::interval)
WHEN (min_intervall <= '15 minutes'::interval and '15 minutes'::interval > (bis_timestamp::timestamp - von_timestamp::timestamp) / 2000) THEN ('15 minutes'::interval)
WHEN (min_intervall <= '30 minutes'::interval and '30 minutes'::interval > (bis_timestamp::timestamp - von_timestamp::timestamp) / 2000) THEN ('30 minutes'::interval)
WHEN (min_intervall <= '60 minutes'::interval and '60 minutes'::interval > (bis_timestamp::timestamp - von_timestamp::timestamp) / 2000) THEN ('60 minutes'::interval)
WHEN (min_intervall <= '120 minutes'::interval and '120 minutes'::interval > (bis_timestamp::timestamp - von_timestamp::timestamp) / 2000) THEN ('120 minutes'::interval)
WHEN (min_intervall <= '240 minutes'::interval and '240 minutes'::interval > (bis_timestamp::timestamp - von_timestamp::timestamp) / 2000) THEN ('240 minutes'::interval)
WHEN (min_intervall <= '480 minutes'::interval and '480 minutes'::interval > (bis_timestamp::timestamp - von_timestamp::timestamp) / 2000) THEN ('480 minutes'::interval)
WHEN (min_intervall <= '720 minutes'::interval and '720 minutes'::interval > (bis_timestamp::timestamp - von_timestamp::timestamp) / 2000) THEN ('720 minutes'::interval)
WHEN (min_intervall <= '1440 minutes'::interval and '1440 minutes'::interval > (bis_timestamp::timestamp - von_timestamp::timestamp) / 2000) THEN ('1440 minutes'::interval)
WHEN (min_intervall <= '2880 minutes'::interval and '2880 minutes'::interval > (bis_timestamp::timestamp - von_timestamp::timestamp) / 2000) THEN ('2880 minutes'::interval)
WHEN (min_intervall <= '10080 minutes'::interval and '10080 minutes'::interval > (bis_timestamp::timestamp - von_timestamp::timestamp) / 2000) THEN ('10080 minutes'::interval)
WHEN (min_intervall <= '43200 minutes'::interval and '43200 minutes'::interval > (bis_timestamp::timestamp - von_timestamp::timestamp) / 2000) THEN ('43200 minutes'::interval)
ELSE ('43200 minutes'::interval)
END;
$BODY$;
ALTER FUNCTION public.set_intervall(interval, timestamp with time zone, timestamp with time zone)
OWNER TO hofei;

@ -0,0 +1,73 @@
from dataclasses import dataclass
import datetime
from dataclasses_json import dataclass_json
import requests
import json
import pprint
@dataclass_json
@dataclass
class Basiswetterdaten:
ts: datetime.datetime
stationsname: str
outtemp: float = None
outluftfeuchte: float = None
heatindex: float = None
taupunkt: float = None
luftdruck: float = None
regenaktuell: float = None
regenrate: float = None
wind: float = None
windrichtung: str = None
windboe: float = None
windboe_richtung: str = None
windrichtung_grad: float = None
out_abs_luftfeuchte: float = None
windchill: float = None
@dataclass_json
@dataclass
class Zusatzwetterdaten:
ts: datetime.datetime
stationsname: str
wertname: str
wert: float
public: bool
def status_auswerten(r, logger, daten):
if not (r.status_code == 200 or r.status_code == 201):
logger.error(f"Statuscode: {r.status_code}\n Message: {r.text}")
logger.error(pprint.pprint(daten))
def sende_daten(url, table, headers, daten, logger):
url = f"{url}{table}"
for data in daten:
data.ts = datetime.datetime.fromtimestamp(int(data.ts)).strftime("%Y-%m-%d %H:%M:%S")
logger.debug(f"Folgende Daten werden gesendet an {table}:\n {daten}")
r = requests.post(url, headers=headers, json=[data.to_dict() for data in daten])
status_auswerten(r, logger, daten)
if r.status_code == 409:
logger.error("Primary Key Verletzung. Beginne Datensätze einzeln zu übertragen")
for data in daten:
r = requests.post(url, headers=headers, json=data.to_dict())
status_auswerten(r, logger, data)
def hole_letzten_ts(url, table, headers, username):
query = f"select=ts&stationsname=eq.{username}&limit=1&order=ts.desc"
url = f"{url}{table}"
r = requests.get(url, headers=headers, params=query)
if r.status_code == 200:
inhalt = json.loads(r.text)
try:
ts_str = inhalt[0]["ts"]
ts = datetime.datetime.strptime(ts_str, "%Y-%m-%dT%H:%M:%S%z")
except IndexError:
ts = datetime.datetime(1970, 1, 1)
return ts
else:
raise TypeError(r.text)

Binary file not shown.

@ -0,0 +1,31 @@
"""
In diesem Modul können eigene Funktionen zur Datenerstellung Generierung integriert werden
Es stehen aufbereitete Rohdaten und die Datenbankverbindung zur Verfügung
Wichtig dabei ist, dass die selbsterstellten Funktionen in der Funktion eigene_wetterdaten
registriert werden, und die Werte in das Dictionary aufbereitete_daten ergänzt werden. Das Keyfeld stellt sogleich
den Namen in der Datenbank dar."""
import messwerte_umrechner as mwu
from weewx_db_model import Archive
def bad(rohdaten):
datensatz = Archive.get(Archive.date_time == rohdaten["ts"])
if datensatz.extra_temp1:
if datensatz.us_units:
rohdaten["bad_temp"] = mwu.temperaturumrechner(datensatz.extra_temp1)
else:
rohdaten["bad_temp"] = datensatz.extra_temp1
if isinstance(datensatz.extra_humid1, (int, float)):
rohdaten["bad_feuchte"] = float(round(datensatz.extra_humid1))
if datensatz.extra_humid1 and datensatz.extra_temp1:
rohdaten["bad_abs_feuchte"] = mwu.absolute_luftfeuchtigkeit(rohdaten["bad_temp"],
rohdaten["bad_feuchte"])
rohdaten["in_abs_feuchte"] = mwu.absolute_luftfeuchtigkeit(rohdaten["inTemp"],
rohdaten["inLuftfeuchte"])
return rohdaten
def eigene_wetterdaten(rohdaten):
rohdaten_mit_eigene_daten = bad(rohdaten)
return rohdaten_mit_eigene_daten

@ -0,0 +1,50 @@
import datetime
import os
import requests
import toml
import setup_logging
from db_postgrest import Zusatzwetterdaten, sende_daten
def config_laden():
configfile = os.path.join(SKRIPTPFAD, "wetterconfig.toml")
with open(configfile) as file:
return toml.loads(file.read())
SKRIPTPFAD = os.path.abspath(os.path.dirname(__file__))
CONFIG = config_laden()
LOGGER = setup_logging.create_logger("feinstaub", CONFIG["loglevel"])
def read_data(url, stationsname):
datenliste = []
try:
r = requests.get(url, timeout=10)
data = r.json()
except requests.exceptions.ConnectionError:
daten = None
else:
daten = {"pm10": data["sensordatavalues"][0]["value"],
"pm2_5": data["sensordatavalues"][1]["value"]}
timestamp = datetime.datetime.now().timestamp()
for key, value in daten.items():
datenliste.append(Zusatzwetterdaten(timestamp, stationsname, key, value, True))
return datenliste
def main():
headers = {f"Authorization": "{user} {token}".format(user=CONFIG["zieldb"]["postgrest"]["user"],
token=CONFIG["zieldb"]["postgrest"]["token"])}
url = CONFIG["zieldb"]["postgrest"]["url"]
if not url.endswith("/"):
url = f"{url}/"
daten = read_data(CONFIG["feinstaub"]["url"], CONFIG["grafana"]["grafana_name"])
sende_daten(url, CONFIG["zieldb"]["postgrest"]["tablename_zusatzwetterdaten"], headers, daten, LOGGER)
if __name__ == "__main__":
main()

@ -0,0 +1,169 @@
#!/usr/bin/python3
import datetime
import os
import sys
import time
import toml
from psutil import process_iter
import eigene_wetterdaten
import messwerte_umrechner as mwu
import weewx_db_model as db_weewx
import setup_logging
import db_postgrest
def config_laden():
configfile = os.path.join(SKRIPTPFAD, "wetterconfig.toml")
with open(configfile) as file:
return toml.loads(file.read())
SKRIPTPFAD = os.path.abspath(os.path.dirname(__file__))
CONFIG = config_laden()
LOGGER = setup_logging.create_logger("grafana_export", CONFIG["loglevel"])
SENDELIMIT = 1000
def check_process():
processliste = [p.cmdline() for p in process_iter() if "python" in p.name()]
return sum([p.count(sys.argv[0]) for p in processliste])
def rohdaten_laden(timestamp, stationsname):
aufruf_wiederholen = False
LOGGER.debug("Lese WeeWx Datenbank")
query = db_weewx.Archive.select().where(db_weewx.Archive.date_time > timestamp)\
.order_by(db_weewx.Archive.date_time.asc()).limit(int(SENDELIMIT * 1.5))
gesamtzahl = (len(query))
if gesamtzahl > SENDELIMIT:
gesamtzahl = SENDELIMIT
LOGGER.info(f"Gesamtanzahl an Datensätze: {gesamtzahl} wird geladen")
basiswetterdaten_liste = []
zusatzwetterdaten_liste = []
for nr, datensatz in enumerate(query):
LOGGER.debug(f"Datensatz {nr + 1} von {gesamtzahl}")
rohdaten = {"ts": datensatz.date_time}
if datensatz.us_units == 1:
rohdaten["outtemp"] = mwu.temperaturumrechner(datensatz.out_temp)
rohdaten["inTemp"] = mwu.temperaturumrechner(datensatz.in_temp)
rohdaten["luftdruck"] = mwu.druckumrechner(datensatz.barometer)
rohdaten["wind"] = mwu.windumrechner(datensatz.wind_speed)
rohdaten["windboe"] = mwu.windumrechner(datensatz.wind_gust)
rohdaten["regenrate"] = mwu.regen_rate(datensatz.rain_rate)
rohdaten["regenaktuell"] = mwu.regen_menge(datensatz.rain)
rohdaten["taupunkt"] = mwu.temperaturumrechner(datensatz.dewpoint)
rohdaten["heatindex"] = mwu.temperaturumrechner(datensatz.heatindex)
rohdaten["windchill"] = mwu.temperaturumrechner(datensatz.windchill)
else:
rohdaten["outtemp"] = datensatz.out_temp
rohdaten["inTemp"] = datensatz.in_temp
rohdaten["luftdruck"] = datensatz.barometer
rohdaten["wind"] = datensatz.wind_speed
rohdaten["windboe"] = datensatz.wind_gust
rohdaten["regenrate"] = datensatz.rain_rate
rohdaten["regenaktuell"] = datensatz.rain
rohdaten["taupunkt"] = datensatz.dewpoint
rohdaten["heatindex"] = datensatz.heatindex
rohdaten["wincchill"] = datensatz.windchill
if isinstance(datensatz.out_humidity, (int, float)):
rohdaten["outluftfeuchte"] = float(round(datensatz.out_humidity, 0))
else:
rohdaten["outluftfeuchte"] = None
if isinstance(datensatz.in_humidity, (int, float)):
rohdaten["inLuftfeuchte"] = float(round(datensatz.in_humidity, 0))
else:
rohdaten["inLuftfeuchte"] = None
if isinstance(datensatz.wind_dir, (int, float)):
rohdaten["windrichtung_grad"] = float(round(datensatz.wind_dir, 1))
else:
rohdaten["windrichtung_grad"] = None
if isinstance(datensatz.wind_gust_dir, (int, float)):
rohdaten["windboe_richtung"] = float(round(datensatz.wind_gust_dir, 1))
else:
rohdaten["windboe_richtung"] = None
rohdaten["windrichtung"] = mwu.himmelsrichtungwandler(datensatz.wind_dir)
rohdaten["out_abs_luftfeuchte"] = mwu.absolute_luftfeuchtigkeit(rohdaten["outtemp"], rohdaten["outluftfeuchte"])
rohdaten = eigene_wetterdaten.eigene_wetterdaten(rohdaten)
basiswetterdaten_liste.append(
db_postgrest.Basiswetterdaten(stationsname=stationsname,
**{key: value for key, value in rohdaten.items() if
key in db_postgrest.Basiswetterdaten.__dataclass_fields__}))
zusatzdatenliste = [{key: value} for key, value in rohdaten.items() if
key not in db_postgrest.Basiswetterdaten.__dataclass_fields__]
for zusatzdaten in zusatzdatenliste:
for key, value in zusatzdaten.items():
if key is None or value is None:
continue
zusatzwetterdaten_liste.append(
db_postgrest.Zusatzwetterdaten(ts=rohdaten["ts"], stationsname=stationsname, wertname=key,
wert=value, public=False))
if nr >= SENDELIMIT - 1:
aufruf_wiederholen = True
break
return basiswetterdaten_liste, zusatzwetterdaten_liste, aufruf_wiederholen
def freigabe_setzen(zusatzwetterdaten_liste):
for zusatzdaten in zusatzwetterdaten_liste:
if zusatzdaten.wertname in CONFIG["grafana"]["public"]:
zusatzdaten.public = CONFIG["grafana"]["public"][zusatzdaten.wertname]
else:
zusatzdaten.public = False
return zusatzwetterdaten_liste
def main():
laufende_prozesse = check_process()
if laufende_prozesse > 1:
print("EXIT aufgrund laufender Prozesse")
sys.exit()
# Verzögerung aufgrund vom Cronjob, >>alle 5Minute, damit es nicht mit der Erstellung von Weewx kolidiert
time.sleep(CONFIG["weewx"]["sleeptime"])
db_adapter = CONFIG["weewx"]["db"]
db = db_weewx.init_db(CONFIG["weewx"][db_adapter]["database"], db_adapter, CONFIG["weewx"].get(db_adapter))
db_weewx.database.initialize(db)
headers = {f"Authorization": "{user} {token}".format(user=CONFIG["zieldb"]["postgrest"]["user"],
token=CONFIG["zieldb"]["postgrest"]["token"])}
url = CONFIG["zieldb"]["postgrest"]["url"]
if not url.endswith("/"):
url = f"{url}/"
while True:
letzter_ts_server = db_postgrest.hole_letzten_ts(url,
CONFIG["zieldb"]["postgrest"]["tablename_basiswetterdaten"],
headers, CONFIG["grafana"]["grafana_name"])
basiswetterdaten, zusatzwetterdaten, aufruf_wiederholen = rohdaten_laden(letzter_ts_server.timestamp(),
CONFIG["grafana"]["grafana_name"])
zusatzwetterdaten = freigabe_setzen(zusatzwetterdaten)
db_postgrest.sende_daten(url, CONFIG["zieldb"]["postgrest"]["tablename_basiswetterdaten"], headers,
basiswetterdaten, LOGGER)
db_postgrest.sende_daten(url, CONFIG["zieldb"]["postgrest"]["tablename_zusatzwetterdaten"], headers,
zusatzwetterdaten, LOGGER)
if not aufruf_wiederholen:
break
if __name__ == "__main__":
start = datetime.datetime.now()
LOGGER.debug(f"Start: {start}")
try:
main()
except KeyboardInterrupt:
LOGGER.info("Durch Benutzer abgebrochen")
else:
LOGGER.info("Export erfolgreich")
ende = datetime.datetime.now()
LOGGER.debug(f"Ende: {ende}")
LOGGER.debug(f"Dauer: {ende - start}")

@ -0,0 +1,134 @@
"""
Modul zum Umrechnen der US Einheiten aus Weewx in das Metrische System
Version 0.1
"""
import math
from typing import Optional, Union
def temperaturumrechner(fahrenheit: Optional[Union[int, float]]) -> Optional[float]:
"""
Umrechnung von Fahrenheit in Celsius
:param fahrenheit: int, float or None
:return: float or None
"""
if isinstance(fahrenheit, (int, float)):
celsius = (fahrenheit - 32) / 1.8
celsius = round(celsius, 2)
return celsius
else:
return None
def druckumrechner(inHG):
"""
Umwandlung von inHG in mBar
:param inHG: int, float or None
:return: float or None
"""
if isinstance(inHG, (int, float)):
mbar = inHG * 33.86389
mbar = round(mbar, 2)
return mbar
else:
return None
def himmelsrichtungwandler(grad):
"""
Umwandlung von Grad in Himmelsrichtung
von (>) bis (<=)
N 348,75 11,25
NNO 11,25 33,75
NO 33,75 56,25
ONO 56,25 78,75
O 78,75 101,25
OSO 101,25 123,75
SO 123,75 146,25
SSO 146,25 168,75
S 168,75 191,25
SSW 191,25 213,75
SW 213,75 236,25
WSW 236,25 258,75
W 258,75 281,25
WNW 281,25 303,75
NW 303,75 326,25
NNW 326,25 348,75
:param grad: float or None
:return: String or None
"""
if isinstance(grad, (int, float)):
richtung = ("N", "NNO", "NO", "ONO", "O", "OSO", "SO", "SSO", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW",
"N")
return richtung[int((int(grad / (360 / 32)) + 1) / 2)]
else:
return None
def windumrechner(wind):
"""
Umwandlung von milen pro std in km/h
:param wind: Int, float or None
:return: Float or None
"""
if isinstance(wind, (int, float)):
kmh = wind * 1.609346
kmh = round(kmh, 2)
return kmh
else:
return None
def regen_rate(wert):
"""
Umwandlung von Inch/h in mm/h
:param wert: Int, float or None
:return: Float or None
"""
if isinstance(wert, (int, float)):
regenrate = wert * 25.4
regenrate = round(regenrate, 2)
return regenrate
else:
return None
def regen_menge(wert):
"""
Umwandlung von Inch in mm
:param wert: Int, float or None
:return: Float or None
"""
if isinstance(wert, (int, float)):
regenmenge = wert * 25.4
regenmenge = round(regenmenge, 2)
return regenmenge
else:
return None
def magnus_formel_wasser(temperatur):
sattdampfdruck_wasser = 611.2 * math.e ** ((17.62 * temperatur) / (243.12 + temperatur))
return sattdampfdruck_wasser
def wasserdampf_partialdruck_berechnen(relative_feuchte, sattdampfdruck_wasser):
wasserdampf_partialdruck = (relative_feuchte/100) * sattdampfdruck_wasser
return wasserdampf_partialdruck
def celsius_in_kelvin(temperatur):
kelvin = temperatur + 273.15
return kelvin
def absolute_luftfeuchtigkeit(temperatur, relative_feuchte):
"""g/m³"""
if temperatur is None or relative_feuchte is None:
return
sattdampfdruck_wasser = magnus_formel_wasser(temperatur)
wasserdampf_partialdruck = wasserdampf_partialdruck_berechnen(relative_feuchte, sattdampfdruck_wasser)
kelvin = celsius_in_kelvin(temperatur)
abs_feuchte = round((wasserdampf_partialdruck / (461.51 * kelvin)) * 1000, 3)
return abs_feuchte

@ -0,0 +1,5 @@
requests
peewee
psutil
toml
dataclasses-json

@ -0,0 +1,82 @@
#!/usr/bin/python3
"""
Beschreibung:
Hilfskript zum Erstellen einer logging Instanz in Abhängigkeit, ob das Skript manuell gestartet worden ist oder
ob das Skript per Service Unit gestartet wurde
Abhängig dessen wird entweder die Logging Instanz mit einem JournalHandler erstellt (Service Unit)
oder mit einem StreamHandler (manuell)
Author: Hofei
Datum: 03.08.2018
Version: 0.1
"""
import logging
import os
import shlex
import subprocess
from systemd import journal
def __setup_logging(loglevel, frm, startmethode, unitname):
"""
Erstellt die Logger Instanz für das Skript
"""
logger = logging.getLogger()
logger.setLevel(loglevel)
logger.handlers = []
if startmethode == "auto":
log_handler = journal.JournalHandler(SYSLOG_IDENTIFIER=unitname)
else:
log_handler = logging.StreamHandler()
log_handler.setLevel(loglevel)
log_handler.setFormatter(frm)
logger.addHandler(log_handler)
return logger
def __get_service_unit_pid(unitname):
"""Ermittelt ob das ausführende Skript mit einer Service Unit gestartet worden ist, wenn ja so ist das
Ergebnis (pid_service_unit) != 0"""
cmd = "systemctl show -p MainPID {}".format(unitname)
cmd = shlex.split(cmd)
antwort = subprocess.run(cmd, stdout=subprocess.PIPE)
ausgabe = antwort.stdout
# strip entfernt \n, split teilt am = in eine Liste und [1] weißt die Zahl in die Variable zu
pid_service_unit = int(ausgabe.decode().strip().split("=")[1])
return pid_service_unit
def __get_startmethode(unitname):
"""Verglicht die PID vom skript mit der pid Service Unit Prüfung
wenn die Nummern gleich sind wird auf auto gestellt, wenn nicht auf manuell"""
pid_service_unit = __get_service_unit_pid(unitname)
pid_skript = os.getpid()
if pid_service_unit == pid_skript:
startmethode = "auto"
else:
startmethode = "manuell"
return startmethode
def __set_loggerformat(startmethode):
"""Stellt die passende Formattierung ein"""
if startmethode == "auto":
frm = logging.Formatter("%(levelname)s: %(message)s", "%d.%m.%Y %H:%M:%S")
else:
frm = logging.Formatter("%(asctime)s %(levelname)s: %(message)s", "%d.%m.%Y %H:%M:%S")
return frm
def create_logger(unitname, loglevel):
"""Dies ist die aufzurufende Funktion bei der Verwendung des Moduls von außen
Liefert die fertige Logging Instanz zurück"""
startmethode = __get_startmethode(unitname)
frm = __set_loggerformat(startmethode)
return __setup_logging(loglevel, frm, startmethode, unitname)
if __name__ == "__main__":
logger = create_logger("testunit", 10)
logger.debug("Testnachricht")

@ -0,0 +1,11 @@
# Pfad zum speichern: /etc/systemd/system/feinstaub.service
[Unit]
Description=ServiceUnit zum starten des Feinstaub Skriptes
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/python3 /home/pi/weewx_to_grafanaserver/feinstaub.py
[Install]
WantedBy=multi-user.target

@ -0,0 +1,10 @@
# Pfad zum speichern: /etc/systemd/system/feinstaub.timer
[Unit]
Description=Timer zum Aufruf der Feinstaub Service Unit
[Timer]
OnCalendar=OnCalendar=*:0/5
Unit=feinstaub.service
[Install]
WantedBy=multi-user.target

@ -0,0 +1,11 @@
# Pfad zum speichern: /etc/systemd/system/grafana_export.service
[Unit]
Description=ServiceUnit zum starten des Grafana Export Skriptes
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/python3 /home/pi/weewx_to_grafanaserver/grafana_export.py
[Install]
WantedBy=multi-user.target

@ -0,0 +1,10 @@
# Pfad zum speichern: /etc/systemd/system/grafana_export.timer
[Unit]
Description=Timer zum Aufruf der Grafana Export Service Unit
[Timer]
OnCalendar=OnCalendar=*:0/5
Unit=grafana_export.service
[Install]
WantedBy=multi-user.target

@ -0,0 +1,50 @@
# vorlage_wetterconfig.toml umbennen in wetterconfig.toml
loglevel = 20 # (0=NOTSET 10=DEBUG 20=INFO 30=WARNING 40=ERROR 50=CRITICAL) Standard = 20
[weewx]
sleeptime = 60 # Zeitverzögerung wie lange Skript bis zur Ausführung wartet damit es nicht kolidiert mit Weewx
db = "mysql" # "mysql" | "sqlite"
[weewx.mysql]
database = "<datenbankname>"
user = "<username>"
password = "<password>"
host= "localhost"
[weewx.sqlite]
database = ":memory:" # Path to database file or :memory:
[zieldb]
[zieldb.postgrest]
url = "<url>"
user = "<user>"
token = "<token>"
tablename_basiswetterdaten = ""
tablename_zusatzwetterdaten = ""
# Grafana Konfiguration
[grafana]
pfad_ausgabe = "/PFAD/WOHIN/AUSGABE/FÜR/GRAFANA/"
grafana_name = "STATIONSNAME" # Wie Station bei Admin gemeldet
server_url = "GRAFANA_SERVER_URL" # Erhältlich bei Admin von Grafana
token = "GRAFANA_TOKEN" # Erhältlich bei Admin von Grafana
dateiname = "DATEINAME_FÜR_ABHOLUNG" # Standard: "daten_grafana.toml"
server_info_url = "GRAFANA_SERVER_INFO_URL" # Erhältlich bei Admin von Grafana
longitude = "STATIONSKOORDINATEN"
latitude = "STATIONSKOORDINATEN"
# Hier alle Zusatzdaten eintragen welche (nicht) öffentlich sichtbar sein sollen
[grafana.public]
inTemp = false
inLuftfeuchte = false
bad_temp = false
bad_feuchte = false
bad_abs_feuchte = false
[feinstaub]
url = ""

@ -0,0 +1,850 @@
from peewee import *
database = Proxy()
class UnknownField(object):
def __init__(self, *_, **__): pass
class BaseModel(Model):
class Meta:
database = database
class Archive(BaseModel):
et = FloatField(column_name='ET', null=True)
uv = FloatField(column_name='UV', null=True)
altimeter = FloatField(null=True)
barometer = FloatField(null=True)
cons_battery_voltage = FloatField(column_name='consBatteryVoltage', null=True)
date_time = AutoField(column_name='dateTime')
dewpoint = FloatField(null=True)
extra_humid1 = FloatField(column_name='extraHumid1', null=True)
extra_humid2 = FloatField(column_name='extraHumid2', null=True)
extra_temp1 = FloatField(column_name='extraTemp1', null=True)
extra_temp2 = FloatField(column_name='extraTemp2', null=True)
extra_temp3 = FloatField(column_name='extraTemp3', null=True)
hail = FloatField(null=True)
hail_rate = FloatField(column_name='hailRate', null=True)
heatindex = FloatField(null=True)
heating_temp = FloatField(column_name='heatingTemp', null=True)
heating_voltage = FloatField(column_name='heatingVoltage', null=True)
in_humidity = FloatField(column_name='inHumidity', null=True)
in_temp = FloatField(column_name='inTemp', null=True)
in_temp_battery_status = FloatField(column_name='inTempBatteryStatus', null=True)
interval = IntegerField()
leaf_temp1 = FloatField(column_name='leafTemp1', null=True)
leaf_temp2 = FloatField(column_name='leafTemp2', null=True)
leaf_wet1 = FloatField(column_name='leafWet1', null=True)
leaf_wet2 = FloatField(column_name='leafWet2', null=True)
out_humidity = FloatField(column_name='outHumidity', null=True)
out_temp = FloatField(column_name='outTemp', null=True)
out_temp_battery_status = FloatField(column_name='outTempBatteryStatus', null=True)
pressure = FloatField(null=True)
radiation = FloatField(null=True)
rain = FloatField(null=True)
rain_battery_status = FloatField(column_name='rainBatteryStatus', null=True)
rain_rate = FloatField(column_name='rainRate', null=True)
reference_voltage = FloatField(column_name='referenceVoltage', null=True)
rx_check_percent = FloatField(column_name='rxCheckPercent', null=True)
soil_moist1 = FloatField(column_name='soilMoist1', null=True)
soil_moist2 = FloatField(column_name='soilMoist2', null=True)
soil_moist3 = FloatField(column_name='soilMoist3', null=True)
soil_moist4 = FloatField(column_name='soilMoist4', null=True)
soil_temp1 = FloatField(column_name='soilTemp1', null=True)
soil_temp2 = FloatField(column_name='soilTemp2', null=True)
soil_temp3 = FloatField(column_name='soilTemp3', null=True)
soil_temp4 = FloatField(column_name='soilTemp4', null=True)
supply_voltage = FloatField(column_name='supplyVoltage', null=True)
tx_battery_status = FloatField(column_name='txBatteryStatus', null=True)
us_units = IntegerField(column_name='usUnits')
wind_battery_status = FloatField(column_name='windBatteryStatus', null=True)
wind_dir = FloatField(column_name='windDir', null=True)
wind_gust = FloatField(column_name='windGust', null=True)
wind_gust_dir = FloatField(column_name='windGustDir', null=True)
wind_speed = FloatField(column_name='windSpeed', null=True)
windchill = FloatField(null=True)
class Meta:
table_name = 'archive'
class ArchiveDayEt(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_ET'
class ArchiveDayUv(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_UV'
class ArchiveDayMetadata(BaseModel):
name = CharField(primary_key=True)
value = TextField(null=True)
class Meta:
table_name = 'archive_day__metadata'
class ArchiveDayAltimeter(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_altimeter'
class ArchiveDayBarometer(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_barometer'
class ArchiveDayConsBatteryVoltage(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_consBatteryVoltage'
class ArchiveDayDewpoint(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_dewpoint'
class ArchiveDayExtraHumid1(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_extraHumid1'
class ArchiveDayExtraHumid2(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_extraHumid2'
class ArchiveDayExtraTemp1(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_extraTemp1'
class ArchiveDayExtraTemp2(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_extraTemp2'
class ArchiveDayExtraTemp3(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_extraTemp3'
class ArchiveDayHail(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_hail'
class ArchiveDayHailRate(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_hailRate'
class ArchiveDayHeatindex(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_heatindex'
class ArchiveDayHeatingTemp(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_heatingTemp'
class ArchiveDayHeatingVoltage(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_heatingVoltage'
class ArchiveDayInHumidity(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_inHumidity'
class ArchiveDayInTemp(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_inTemp'
class ArchiveDayInTempBatteryStatus(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_inTempBatteryStatus'
class ArchiveDayLeafTemp1(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_leafTemp1'
class ArchiveDayLeafTemp2(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_leafTemp2'
class ArchiveDayLeafWet1(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_leafWet1'
class ArchiveDayLeafWet2(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_leafWet2'
class ArchiveDayOutHumidity(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_outHumidity'
class ArchiveDayOutTemp(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_outTemp'
class ArchiveDayOutTempBatteryStatus(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_outTempBatteryStatus'
class ArchiveDayPressure(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_pressure'
class ArchiveDayRadiation(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_radiation'
class ArchiveDayRain(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_rain'
class ArchiveDayRainBatteryStatus(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_rainBatteryStatus'
class ArchiveDayRainRate(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_rainRate'
class ArchiveDayReferenceVoltage(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_referenceVoltage'
class ArchiveDayRxCheckPercent(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_rxCheckPercent'
class ArchiveDaySoilMoist1(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_soilMoist1'
class ArchiveDaySoilMoist2(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_soilMoist2'
class ArchiveDaySoilMoist3(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_soilMoist3'
class ArchiveDaySoilMoist4(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_soilMoist4'
class ArchiveDaySoilTemp1(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_soilTemp1'
class ArchiveDaySoilTemp2(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_soilTemp2'
class ArchiveDaySoilTemp3(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_soilTemp3'
class ArchiveDaySoilTemp4(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_soilTemp4'
class ArchiveDaySupplyVoltage(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_supplyVoltage'
class ArchiveDayTxBatteryStatus(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_txBatteryStatus'
class ArchiveDayWind(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
dirsumtime = IntegerField(null=True)
max = FloatField(null=True)
max_dir = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
squaresum = FloatField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsquaresum = FloatField(null=True)
wsum = FloatField(null=True)
xsum = FloatField(null=True)
ysum = FloatField(null=True)
class Meta:
table_name = 'archive_day_wind'
class ArchiveDayWindBatteryStatus(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_windBatteryStatus'
class ArchiveDayWindDir(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_windDir'
class ArchiveDayWindGust(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_windGust'
class ArchiveDayWindGustDir(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_windGustDir'
class ArchiveDayWindSpeed(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_windSpeed'
class ArchiveDayWindchill(BaseModel):
count = IntegerField(null=True)
date_time = AutoField(column_name='dateTime')
max = FloatField(null=True)
maxtime = IntegerField(null=True)
min = FloatField(null=True)
mintime = IntegerField(null=True)
sum = FloatField(null=True)
sumtime = IntegerField(null=True)
wsum = FloatField(null=True)
class Meta:
table_name = 'archive_day_windchill'
def init_db(name, type_="sqlite", config=None):
config = config or {}
drivers = {
"sqlite": SqliteDatabase,
"mysql": MySQLDatabase,
}
try:
cls = drivers[type_]
except KeyError:
raise ValueError("Unknown database type: {}".format(type_)) from None
del config["database"]
db = cls(name, **config)
return db
Loading…
Cancel
Save