NEWS
Heizöl24 - MEX
-
Habe hier ein Python Script erstellt, welches funktioniert!
Herzlichen Dank an cpatscheider für seine Unterstützung! ( https://github.com/Secret-Lab-Productions/heizoel24-mex/discussions/2 )
Die Daten sind dann unter mqtt/0/MEX zufinden.
Cronjob (crontab -e):
0 */3 * * * /home/pi/mex.py # Pfad anpassen!
Rechte 754 ( chmod 754 mex.py )
#!/usr/bin/python3 ################################## # V1.1 # # MEX-Daten in ioBroker einlesen # # Benötigt den MQTT Adapter # # (C) 2024 Daniel Luginbühl # ################################## ########################### WICHTIGE INFOS ############################### #### Dieses Script per Cronjob alle 2 bis 4 Stunden ausführen #### #### Im ioBroker ist der MQTT Broker/Client Adapter zu installieren #### #### Einstellungen: #### #### IP: Server/Broker #### #### Authentifizierungseinstellungen: Benutzer/Passwort definieren #### #### Zu installieren (auf Host, wo dieses Script läuft): #### #### sudo apt install python3-requests #### #### pip install paho-mqtt #### ########################################################################## #### Hier Einträge anpassen! #### username = "AAAAA@gmail.com" # Deine Email Adresse bei Heizoel24 passwort = "BBBBBBBBB" # Dein Passwort bei Heizoel24 broker_address = "192.168.1.50" # ioBroker IP, auf welchem der MQTT (Server) Adapter läuft mqtt_user = "uuuuuu" # ioBroker MQTT User (in Authentifizierungseinstellungen definiert) mqtt_pass = "pppppp" # ioBroker MQTT Passwort (in Authentifizierungseinstellungen definiert) debug = False # True = Debug Infos auf die Konsole ########################################################################## import requests import time import json import paho.mqtt.client as mqtt def mqtt_send(client, topic, wert): client.publish("MEX/" + topic, wert) def login(): if debug: print('Login in...') global session_id global logged_in url = "https://api.heizoel24.de/app/api/app/Login" newHeaders = {'Content-type': 'application/json'} reply = requests.post(url, json = { "Password" : passwort, "Username" : username}, headers=newHeaders) if reply.status_code == 200: if debug: print("Login OK") reply_json = json.loads(reply.text) if reply_json['ResultCode'] == 0: session_id = reply_json['SessionId'] if debug: print('Session ID: ' + session_id) logged_in = True else: print('Login nicht OK! Heizoel24 Login Status Code: ' + str(reply.status_code)) def mex(): login() if debug: print('Refresh sensor data cache...') url = 'https://api.heizoel24.de/app/api/app/GetDashboardData/'+ session_id + '/1/1/False' reply = requests.get(url) if reply.status_code == 200: if debug: print("Daten wurden empfangen") sensor_data = reply else: if debug: print('Heizoel24 GetDashboardData Status Code: ' + str(reply.status_code)) sensor_data = "error" # Fehler. Keine Daten empfangen. return sensor_data def main(): daten = mex() if daten == "error": print("Fehler. Keine Daten empfangen.") return daten = daten.json() if debug: print(daten) topic1 = ['SensorId', 'IsMain', 'CurrentVolumePercentage', 'CurrentVolume', 'NotifyAtLowLevel', 'NotifyAtAlmostEmptyLevel', 'NotificationsEnabled', 'Usage', 'RemainsUntil', 'MaxVolume', 'ZipCode', 'MexName', 'LastMeasurementTimeStamp', 'LastMeasurementWithDifferentValue', 'BatteryPercentage', 'Battery', 'LitresPerCentimeter', 'LastMeasurementWasSuccessfully', 'SensorTypeId', 'HasMeasurements', 'MeasuredDaysCount', 'LastMeasurementWasTooHigh', 'YearlyOilUsage', 'RemainingDays', 'LastOrderPrice', 'ResultCode', 'ResultMessage'] topic2 = ['LastOrderPrice', 'PriceComparedToYesterdayPercentage', 'PriceForecastPercentage', 'HasMultipleMexDevices', 'DashboardViewMode', 'ShowComparedToYesterday', 'ShowForecast', 'ResultCode', 'ResultMessage'] RemainsUntilCombined = ['MonthAndYear', 'RemainsValue', 'RemainsUnit'] client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "MEX") client.username_pw_set(mqtt_user, mqtt_pass) client.connect(broker_address) if debug: print("---------------------") for n in range(len(topic2)): if debug: print(topic2[n] + ":", daten[topic2[n]]) mqtt_send(client, "PricingForecast/" + topic2[n], daten[topic2[n]]) daten = daten["Items"] daten = daten[0] if debug: print("---------------------") for n in range(len(topic1)): if debug: print(topic1[n] + ":", daten[topic1[n]]) mqtt_send(client, "Items/" + topic1[n], daten[topic1[n]]) daten3 = daten['RemainsUntilCombined'] if debug: print("---------------------") print('RemainsUntilCombined:') for n in range(len(RemainsUntilCombined)): if debug: print(RemainsUntilCombined[n] + ":", daten3[RemainsUntilCombined[n]]) mqtt_send(client, "RemainsUntilCombined/" + RemainsUntilCombined[n], daten3[RemainsUntilCombined[n]]) client.disconnect() #### Beispiel Ausgaben. Diese können dann natürlich auch in Datenpunkte geschrieben werden. #### # print() # print("SensorId: ", daten["SensorId"]) # print("Aktueller Inhalt in %: ", daten["CurrentVolumePercentage"]) # print("Aktueller Inhalt in Liter:", daten["CurrentVolume"]) # print("Max Tankinhalt in Liter: ", daten["MaxVolume"]) # print("MEX Batterie in %: ", daten["BatteryPercentage"]) # print("Letzte Messung in Ordnung:", daten["LastMeasurementWasSuccessfully"]) # print("Letzte Messung war am: ", daten["LastMeasurementTimeStamp"]) # print("Reicht noch für Tage: ", daten["RemainingDays"]) if __name__ == '__main__': main()
Auch hier zufinden: https://github.com/ltspicer/iobroker.mex
-
@spicer
sehr sehr cool .... vielen Dank dafür!!!eine Frage zu einer Fehlermedung die ich erhalte:
root@DietPi:/home/script# python3 /home/script/mex.py Traceback (most recent call last): File "/home/script/mex.py", line 141, in <module> main() File "/home/script/mex.py", line 95, in main client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "MEX") AttributeError: module 'paho.mqtt.client' has no attribute 'CallbackAPIVersion'
Was könnte da falsch laufen?
-
@gjo editiere Zeile 95 nach:
client = mqtt.Client("MEX")Ich vermute, dass Du mqtt Version < 2.0 hast.
Werde das beim nächsten Update abfangen. -
das war auch meine Vermutung.
heidenei ... nach:
root@DietPi:/home/script# pip install paho-mqtt --upgrade Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple/ Requirement already satisfied: paho-mqtt in /usr/local/lib/python3.7/dist-packages (1.6.1) Collecting paho-mqtt Downloading https://www.piwheels.org/simple/paho-mqtt/paho_mqtt-2.0.0-py3-none-any.whl (66 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 66.9/66.9 kB 746.1 kB/s eta 0:00:00 Installing collected packages: paho-mqtt Attempting uninstall: paho-mqtt Found existing installation: paho-mqtt 1.6.1 Uninstalling paho-mqtt-1.6.1: Successfully uninstalled paho-mqtt-1.6.1 Successfully installed paho-mqtt-2.0.0 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv [notice] A new release of pip is available: 23.3.2 -> 24.0 [notice] To update, run: python3 -m pip install --upgrade pip
kommt jetzt:
root@DietPi:/home/script# python3 /home/script/mex.py Traceback (most recent call last): File "/usr/local/lib/python3.7/dist-packages/paho/mqtt/client.py", line 49, in <module> from typing import Literal ImportError: cannot import name 'Literal' from 'typing' (/usr/lib/python3.7/typing.py) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/home/script/mex.py", line 38, in <module> import paho.mqtt.client as mqtt File "/usr/local/lib/python3.7/dist-packages/paho/mqtt/client.py", line 51, in <module> from typing_extensions import Literal # type: ignore ModuleNotFoundError: No module named 'typing_extensions' root@DietPi:/home/script#
also via:
root@DietPi:/home/script# pip install typing-extensions Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple/ Collecting typing-extensions Downloading https://www.piwheels.org/simple/typing-extensions/typing_extensions-4.7.1-py3-none-any.whl (33 kB) Installing collected packages: typing-extensions Successfully installed typing-extensions-4.7.1
nachinstalliert. dann mit folgendem Ergebnis:
root@DietPi:/home/script# python3 /home/script/mex.py /home/script/mex.py:95: DeprecationWarning: Callback API version 1 is deprecated, update to latest version client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "MEX")
-
@gjo
Diese Warnung ist ok. Die hab ich auch. Sollte eigentlich funktionieren so.
Funktioniert's denn?
Frage: Bist Du als root unterwegs, nicht als pi?Edit:
Warnung ist nun weg. Code nutzt nun aktuelle Parameter -
@spicer
die Daten kommen an ... wie cool. Danke nochmal.
ja, auf dem Testsystem hatte ich s mir einfacher gemacht. -
V1.2 auf github
- DataReceived Punkt hinzugefügt
- paho-mqtt Versionsabfrage
-
@gjo sagte in Heizöl24 - MEX:
ja, auf dem Testsystem hatte ich s mir einfacher gemacht.
Das ist aber auch nur vermeintlich einfacher.
In der Realität ist es nämlich aufwändiger die Rechte richtig zu halten.
Und deswegen gilt halt: NIE root.Die Meldung:
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
steht nämlich da auch nicht zum Spaß.
-
@thomas-braun sagte in Heizöl24 - MEX:
@gjo sagte in Heizöl24 - MEX:
ja, auf dem Testsystem hatte ich s mir einfacher gemacht.
Das ist aber auch nur vermeintlich einfacher.
In der Realität ist es nämlich aufwändiger die Rechte richtig zu halten.
Und deswegen gilt halt: NIE root.Die Meldung:
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
steht nämlich da auch nicht zum Spaß.
Jep. Dachte ich mir auch, dass das wegen dem root so ist
-
V1.3 auch auf github.
#!/usr/bin/python3 ###################################################################################### ################################### V1.3 ################### ################################### MEX-Daten in ioBroker einlesen ################### ################################### Benötigt den MQTT Adapter ################### ################################### (C) 2024 Daniel Luginbühl ################### ###################################################################################### ######################################### WICHTIGE INFOS ############################# ################## Im ioBroker ist der MQTT Broker/Client Adapter zu installieren ## ################## Einstellungen: ## ################## IP: Server/Broker ## ################## Authentifizierungseinstellungen: Benutzer/Passwort definieren ## ################## ---------------------------------------------------------------- ## ################## Alles als User PI ausführen! ## ################## ---------------------------------------------------------------- ## ################## mex.py Script auf Rechte 754 setzen mit: ## ################## chmod 754 mex.py ## ################## Dieses Script per Cronjob alle 2 bis 4 Stunden ausführen: ## ################## crontab -e ## ################## 0 */3 * * * /home/pi/mex.py # Pfad ggf anpassen! ## ################## ---------------------------------------------------------------- ## ################## Vorgängig zu installieren (auf Host, wo dieses Script läuft): ## ################## sudo apt install python3-requests ## ################## pip3 install paho-mqtt ## ################## pip3 install typing-extensions ## ###################################################################################### ###################################################################################### ################################### Hier Einträge anpassen! ########################## username = "AAAAA@gmail.com" # Deine Email Adresse bei HeizOel24 passwort = "BBBBBBBBB" # Dein Passwort bei HeizOel24 broker_address = "192.168.1.50" # ioBroker IP, auf welchem der MQTT (Server) Adapter läuft mqtt_user = "uuuuuu" # ioBroker MQTT User (in Authentifizierungseinstellungen definiert) mqtt_pass = "pppppp" # ioBroker MQTT Passwort (in Authentifizierungseinstellungen definiert) debug = False # True = Debug Infos auf die Konsole ###################################################################################### ###################################################################################### import requests import time import json import paho.mqtt.client as mqtt def mqtt_send(client, topic, wert): client.publish("MEX/" + topic, wert) def login(): if debug: print('Login in...') global session_id url = "https://api.heizoel24.de/app/api/app/Login" newHeaders = {'Content-type': 'application/json'} reply = requests.post(url, json = { "Password" : passwort, "Username" : username}, headers=newHeaders) return_flag = False if reply.status_code == 200: if debug: print("Login OK") reply_json = json.loads(reply.text) if reply_json['ResultCode'] == 0: session_id = reply_json['SessionId'] if debug: print('Session ID: ' + session_id) return_flag = True else: if debug: print('ResultCode nicht 0. Keine Session ID erhalten!') else: if debug: print('Login fehlgeschlagen! Heizoel24 Login Status Code: ' + str(reply.status_code)) return return_flag def mex(): login_status = login() if login_status == False: return "error" if debug: print('Refresh sensor data cache...') url = 'https://api.heizoel24.de/app/api/app/GetDashboardData/'+ session_id + '/1/1/False' reply = requests.get(url) if reply.status_code == 200: if debug: print("Daten wurden empfangen") sensor_data = reply else: if debug: print('Heizoel24 GetDashboardData Status Code: ' + str(reply.status_code)) sensor_data = "error" # Fehler. Keine Daten empfangen. return sensor_data def main(): topic1 = ['SensorId', 'IsMain', 'CurrentVolumePercentage', 'CurrentVolume', 'NotifyAtLowLevel', 'NotifyAtAlmostEmptyLevel', 'NotificationsEnabled', 'Usage', 'RemainsUntil', 'MaxVolume', 'ZipCode', 'MexName', 'LastMeasurementTimeStamp', 'LastMeasurementWithDifferentValue', 'BatteryPercentage', 'Battery', 'LitresPerCentimeter', 'LastMeasurementWasSuccessfully', 'SensorTypeId', 'HasMeasurements', 'MeasuredDaysCount', 'LastMeasurementWasTooHigh', 'YearlyOilUsage', 'RemainingDays', 'LastOrderPrice', 'ResultCode', 'ResultMessage'] topic2 = ['LastOrderPrice', 'PriceComparedToYesterdayPercentage', 'PriceForecastPercentage', 'HasMultipleMexDevices', 'DashboardViewMode', 'ShowComparedToYesterday', 'ShowForecast', 'ResultCode', 'ResultMessage'] RemainsUntilCombined = ['MonthAndYear', 'RemainsValue', 'RemainsUnit'] try: client = mqtt.Client("mex") if debug: print("paho-mqtt version < 2.0") except: client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, "mex") if debug: print("paho-mqtt version >= 2.0") if debug: print("---------------------") print("client:", client) print("---------------------") client.username_pw_set(mqtt_user, mqtt_pass) client.connect(broker_address) daten = mex() if daten == "error": if debug: print("Fehler. Keine Daten empfangen.") mqtt_send(client, "Items/DataReceived", False) client.disconnect() return daten = daten.json() if debug: print() print("JSON-Daten:") print("===========") print() print(daten) print() if debug: print("---------------------") print() for n in range(len(topic2)): if debug: print(topic2[n] + ":", daten[topic2[n]]) mqtt_send(client, "PricingForecast/" + topic2[n], daten[topic2[n]]) daten = daten["Items"] daten = daten[0] if debug: print("---------------------") for n in range(len(topic1)): if debug: print(topic1[n] + ":", daten[topic1[n]]) mqtt_send(client, "Items/" + topic1[n], daten[topic1[n]]) mqtt_send(client, "Items/DataReceived", True) daten3 = daten['RemainsUntilCombined'] if debug: print("---------------------") print('RemainsUntilCombined:') for n in range(len(RemainsUntilCombined)): if debug: print(RemainsUntilCombined[n] + ":", daten3[RemainsUntilCombined[n]]) mqtt_send(client, "RemainsUntilCombined/" + RemainsUntilCombined[n], daten3[RemainsUntilCombined[n]]) client.disconnect() if __name__ == '__main__': main()
-
Ich wäre übrigens sehr empfänglich für Hilfe beim Erstellen eines ioBroker Adapters.
Die Links
https://iobroker.readthedocs.io/de/latest/development/adapter.html
und
https://www.codeconvert.ai/python-to-javascript-converter
hab ich zwar, aber ohne Hilfe ist das doch etwas schwierig.
Ich weiss nichtmal, wie ich meinem Code beibringe, Input- und Output vom/zum ioBroker zu senden/empfangen.
Mit anderen Worten: Die Schnittstelle.
Bin für jeden Rat dankbar.
Totaler Anfänger im programmieren bin ich nicht.
Jedoch Java = 0 Ahnung. Python sieht's anders aus (hoffentlich oben im Py-Script ersichtlich).
Bin halt ein Basic & Assembler Kind aus den C64 bzw Atari Jahren ^^ -
Hier (aus Zeitgründen) nur eine ganz kurze Info:
-) Am besten schaust du dir einen (eher einfachen) Adapter auf github mal an und versuchst zu verstehen was da steht.
-) Ein Grundverständnis für javascript (das ist NICHT Java) ist hilfreich. Aber wenn du eine andere Sprache kannst, sollte das nicht das Problem sein.
-) Für Testzwecke erstellst du am besten einen neuen Adapter mittels adapter creator.
-) Testen tust du am besten mittels dev-server.
Ich würde dir empfehlen dich in der telgramm Gruppe adapter-developer-starters anzumelden. Invite Links windest du auf www.iobroker.dev. Dort gibts sicher wen der dir mal ein wenig beim Start helfen kann und wird.
P.S: Uns ja, die dokumentation ist (m.E.) eine der größten Baustellen / Schwachstellen von ioB. Wenns es da leite gibt die sowas gener schreiben sind sie sicher gern gesehen. (Viele Code-Entwickler schreiben ungern Dokumentaionen ...)
-
Das Script ließt den MEX direkt aus und der Adapter geht über den Heizöl24 Account?
Bitte ignorieren wer lesen kann ist im Vorteil -
@xadox
Für den ioBroker hab ich ja einen Adapter erstellt ( https://github.com/ltspicer/ioBroker.heizoel24-mex )
Und hier ist die aktuelle Version vom Script: https://github.com/ltspicer/heizoel24.mex