Initial Commit
							parent
							
								
									b8617ad52d
								
							
						
					
					
						commit
						73188fcb78
					
				@ -0,0 +1 @@
 | 
			
		||||
*.py		text eol=lf
 | 
			
		||||
@ -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…
					
					
				
		Reference in New Issue