Da der Querx nur begrenzten Speicher hat behält der nur eine gewisse Anzahl an Messungen. Ältere Messungen werden automatisch gelöscht. Mit einem Aufzeichnungsintervall von 5min und aktivierter Kompression komme ich so auf respektable rund 300 Tage.
Ich will die Daten aber länger speichern und für den schnellen Zugriff in einer SQL-Datenban ablegen (MariaDB unter WSL in meinem Fall).
Ich habe 1 Querx THP und daher eine DB Namens "phys_data" mit einer Tabelle namens "ClimateData" angelegt mit folgenden Feldern:
Sensor [TINYTEXT], Time {DATETIME], TemperatureLow [FLOAT], TemperatureAvg [FLOAT], TemperatureHigh [FLOAT], HumidityLow [FLOAT], HumidityAvg [FLOAT], HumidityHigh [FLOAT], PressureLow [FLOAT], PressureAvg [FLOAT], PressureHigh [FLOAT]
Mein Script ist sehr einfach gestrickt und basiert auf der Annahme, dass alle Querxe dieselbe Anzahl Datenfelder haben wie die DB. Es funktioniert auch nur, solange nur ein Querx genutzt wird.
Das Script sucht in der DB nach dem neuesten Eintrag (egal von welchem Querx). Anschliessend lädt es per Web-API die Daten ab diesem Zeitpunkt in 5min Schritten vom Qerx im XML-Format herunter. Der erste Eintrag wird ignoriert, da er ja mit dem letzten Eintrag in der DB übereinstimmt.
Diese XML-Daten werden auf Naive Art und Weise geparst und in SQL-Statements verpackt, die dann als Queries an die DB geschickt werden.
Damit kann ich einfach ab und zu (z.B. einmal pro Tag) die neuesten Daten vom Querx in die DB laden.
#!/usr/bin/python3
# by Marco Tedaldi, 2021
# published as public domain except for the parts that are under copyright by someone else (ie the parts copied from egnite example code)
# transfer the data from the querx sesor into the mariadb / mysql-DB
# procedure:
# - get the time of the latest data in the database as a Unix Timestamp
# - forge a ruequest string for the querx http interface and get the data in xml format
# - convert the data from xml to SQL and store it in the SQL DB
import sys
from MySQLdb import _mysql as mysql # we want to access a mysql / mariadb
import http.client # to get the data from the querx
import xml.etree.ElementTree as ET # to parse the XML from the querx
from datetime import datetime # to conver the timestamps to datetime for the DB
# access information for the Querx (copied from https://www.egnite.de/support/tutorials/tutorial-zugriff-auf-querx-messdaten-mit-python/)
querx_address = "192.88.99.2" #name or address of the Querx Sensor
querx_http_port = 80
xml_url = "/tpl/document.cgi?tpl/j/datalogger.tpl&format=xml"
# databse access information
db_address = "localhost"
db_user = "username"
db_pass = "VerySecurePW"
db_name = "phys_data"
db_table = "ClimateData"
# function to get the timestamp of the last entry
def get_lastTS(db):
db.query("""SELECT UNIX_TIMESTAMP(MAX(Time)) FROM ClimateData""")
result = db.store_result().fetch_row()
ts = int(result[0][0])
return(ts)
# copied from https://www.egnite.de/support/tutorials/tutorial-zugriff-auf-querx-messdaten-mit-python/
# adapted to get historical values
def get_xml(address, port, url):
try:
conn = http.client.HTTPConnection(address, port) # Python 3.x: httplib => http.client
conn.request("GET", url)
res = conn.getresponse()
xml = res.read()
return(xml)
except Exception as e:
print ("Error: " + str(e))
sys.exit(1)
# main program
if __name__ == "__main__":
db = mysql.connect( db_address, db_user, db_pass, db_name)
lastdata = get_lastTS(db)
print("Timestamp = " + str(lastdata))
xml_url = xml_url + "&start=" + str(lastdata) + "&step=300"
print("xml_url = " + xml_url)
climatedata = get_xml(querx_address, querx_http_port, xml_url)
root = ET.fromstring(climatedata)
sensorname = root.findtext('hostname')
data = root.find('data')
for rnr, record in enumerate(data):
if rnr != 0:
time = datetime.fromtimestamp(int(record.get('timestamp'))).strftime('%Y-%m-%d %H:%M:%S')
query = 'INSERT INTO ' + str(db_table) + ' VALUES (\'' + str(sensorname) + '\', \'' + time
for idx, entry in enumerate(record):
query = query + '\', \'' + str(entry.get('value'))
query = query + '\' );'
print('-> ' + query)
db.query(query)
db.close()
Ich bin kein Programmierer sondern hacke mir meine Tools einfach so zusammen, dass sie für mich funktionieren. Diese Software könnte von einem fähigen Programmierer in kurzer Zeit wahrscheinlich massiv verbessert werden um mit Kommandozeilen-Argumenten, mehr als einem Querx und einer anderen Anzahl Spalten in der DB umgehen zu können.
Ich veröffentliche diesen Code so wie er ist (abgesehen von den Teilen, die ich von egnite kopiert habe) zur freien Verwendung.