Coder Social home page Coder Social logo

tibber-meter-uploader's Introduction

Tibber Meter Uploader

Dieses Tool verwendet die Tibber-API, welcher unter https://app.tibber.com/v4/gql verfügbar ist, um tägliche Zählerstände automatisiert hochzuladen.

Es kann als Alternative zur manuellen monatlichen Eingabe von Zählerständen verwendet werden und ist nicht als Ersatz für den "Tibber Pulse" gedacht, welcher stündliche Werte übermittelt.

Bauen

Das Projekt kann mit Java und Maven gebaut werden (mvn package). Das Weiteren liegt ein Dockerfile bei, welches ein Packaging via docker build . -t tibber-meter-uploader ermöglicht.

Automatisierte Docker-Builds sind unter ghcr.io/micw/tibber-meter-uploader verfügbar.

Ausführen (docker)

docker run -it --rm \
  -e "READINGS_SOURCE_CLASS=ScriptedRestApiMeterReadingSource" \
  -e "READINGS_SCRIPT_COMMAND=echo test; exit 1" \
  -e [email protected] \
  -e TIBBER_PASSWORD=mysecretpassword \
  ghcr.io/micw/tibber-meter-uploader:master

Ausführen (nativ)

Pre-built jars can be downloaded from https://mega.nz/folder/pi4yjaoI#OXNDwnkfyH6xOEJEdtN3pg . To run it, you need a Java Runtime Environment (JRE) with version 11 or higher installed. COnfig can be passed as environment variables or by creating appliucation.yaml in the working directory (e.g. next to the downloaded jar file).

Example:

echo "TIBBER_LOGIN: [email protected]" > application.yaml
echo "TIBBER_PASSWORD: mysecretpassword" >> application.yaml
java -Xmx25M -jar tibber-meter-uploader.master.jar 

Memory assignment of the process can be tuned by the -Xmx option - adjust it to your needs so that the process does not get an out of memory error.

Konfiguration

Die Konfiguration erfolgt über eine Konfigurationsdatei (application.yaml, siehe Beispiel im Wurzelverzeichnis) oder über Umgebungsvariablen.

  • TIBBER_LOGIN (benötigt): E-Mail-Adresse eines Tibber-Accounts
  • TIBBER_PASSWORD (benötigt): Passwort eines Tibber-Accounts
  • READINGS_SOURCE_CLASS (benötigt): Implementierungsklasse der Quelle für Zählerstände (siehe unten)
  • SCHEDULING_ENABLED (default: true): Wenn der Parameter auf false gesetzt wird, terminiert der Prozess nach einem einmaligen Durchlauf
  • SCHEDULING_CRON (default: 0 0 * * * * = jede volle Stunde): Ermöglicht, den Ausführungszeitpunkt der regelmäßigen Durchläufe zu verändern
  • DRY_RUN (default: false): Wenn der Parameter auf true gesetzt wird, werden die an an Tibber zu übermittelnden Zählerstände nur angezeigt, aber nicht übertragen. Nützlich, um Quellen und die Konfiguration zu testen.

Meter Register ID

In einigen Fällen ist bei Tibber nicht der Standard-OBIS-Code 1-1:1.8.0 für den Gesamt-Strombezug hinterlegt sondern 1-1:1.8.0. In dem Fall erscheint beim Start eine Fehlermeldung ähnlich dieser:

Meter 149d2526-6c26-4435-9b2b-0dbfd3251bcd has no register with id '1-0:1.8.0'. Available registers are: 1-1:1.8.0

Über den Konfigurtationsparameter TIBBER_METER_REGISTER_ID = 1-1:1.8.0 kann die Anwendung so konfiguriert werden, dass Zählerstände für diesen OBIS-Code an Tibber übergeben werden.

Eine Liste gängiger OBIS-Codes und deren Bedeutung kann unter https://de.wikipedia.org/wiki/OBIS-Kennzahlen gefunden werden.

Programmablauf

  • Beim Start sowie einmal pro volle Stunde versucht sich der Client an der Tibber-API anzumelden und das Benutzerprofil incl. der zuletzt gemeldeten Zählerstände abzurufen
  • Es wird derzeit nur ein Zuhause mit einem Zähler unterstützt
  • Sind für ein oder mehrere Tage in der Vergangenheit (maximal 30 Tage zurück) noch keine Zählerstände vorhanden, wird die konfigurierte Quelle nach Zählerständen in diesem Zeitraum befragt
  • fehlende Zählerstände werden nachgetragen

Quellen

Um flexibel zu sein, unterstützt das Tool konfigurierbare Quellen für die Zählerstände.

ScriptedRestApiMeterReadingSource

Diese Quelle führt ein Shell-Script aus, um Zählerstände zu beziehen. Als Ergebnis wird eine Liste mit je einem Datum + Zählerstand in kWh pro Zeile erwartet (getrennt mit Leerzeichen, Semikolon oder Komma).

Beispiel:

2023-01-19 10003
2023-01-20 10114
2023-01-21 10234
2023-01-22 10521

Die folgenden Konfigurationsparameter sind für die Quelle verfügbar:

  • READINGS_SOURCE_CLASS (benötigt): ScriptedRestApiMeterReadingSource für diese Quelle
  • READINGS_SCRIPT_COMMAND (benötigt): Auszuführender Befehl oder Shell-Script. Der Befehl wird an eine Shell mittels sh -c ${READINGS_SCRIPT_COMMAND} übergeben
  • READINGS_METER(optional): Wenn angegeben, prüft die Quelle, dass die von der Tibber-Api gelieferte Zählernummer dieser Zählernummer entspricht.

Innerhalb des Shell-Scriptes stehen die folgenden Umgebnugsvariablen zur Verfügung:

  • FIRST_DAY - Der erste Tag, für den der Zählerstand benötigt wird. Format: 2023-01-19
  • LAST_DAY - Der letzte Tag, für den der Zählerstand benötigt wird. Format: 2023-01-22
  • METER - Die abgefragte Zähelernummer. Format: 1EBZ0123456789
  • FIRST_DAY_START_ISO_TZ - Die Startzeit des ersten Tages, Format: 2023-01-19T00:00:00+01:00[Europe/Berlin]
  • LAST_DAY_END_ISO_TZ - Die Startzeit des Folgetages des letzten Tages. Format: 2023-01-23T00:00:00+01:00[Europe/Berlin]

CommandLineMeterReadingSource

Diese Quelle ließt Zählerstände von der Kommandozeile. Es können mehrere Zählerstände im Format datum=zählerstand übergeben werden. Statt des Datums kann auch das Schlüsselwort today verwendet werden, um den aktuellen Tag zu übergeben.

Beispiel:

java -jar tibber-uploader.jar 2023-01-19=10003 2023-01-20=10114 2023-01-21=10234 today=10521

Die folgenden Konfigurationsparameter sind für die Quelle verfügbar:

  • READINGS_SOURCE_CLASS (benötigt): CommandLineMeterReadingSource für diese Quelle
  • READINGS_METER(optional): Wenn angegeben, prüft die Quelle, dass die von der Tibber-Api gelieferte Zählernummer dieser Zählernummer entspricht.

Es ist sinnvoll, diese Quelle zusammen mit dem Konfigurationsparameter SCHEDULING_ENABLED=false zu verwenden, um das Programm nach dem Upload der Werte zu beenden.

DummyMeterReadingSource

Diese Quelle stellt ein einzelnes statisches Reading zum Testen zur Verfügung.

Die folgenden Konfigurationsparameter sind für die Quelle verfügbar:

  • READINGS_SOURCE_CLASS (benötigt): DummyMeterReadingSource für diese Quelle
  • READINGS_METER(optional): Wenn angegeben, prüft die Quelle, dass die von der Tibber-Api gelieferte Zählernummer dieser Zählernummer entspricht.
  • DUMMY_READING_DATE(benötigt): Datum des Dummy-Readings, z.b. 2023-01-19
  • DUMMY_READING_VALUE(benötigt): Wert des Dummy-Readings, z.b. 10003

tibber-meter-uploader's People

Contributors

markuslaube avatar micw avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

tibber-meter-uploader's Issues

Home Assistant / ESP Home

Moin,

Ich nutze Unraid für meine Docker Container und habe Home Assistant in einer VM Laufen.

Wichtig ist im moment eher folgendes:

Ich habe dein Script in einem Docker Container am laufen. Dieses läuft auch.

`2023-06-12 09:46:14.888 INFO 23 --- [ main] de.wyraz.tibberuploader.TibberUploader : Starting TibberUploader v1.0.0-SNAPSHOT using Java 17-ea on a0a17ae29489 with PID 23 (/tibber-meter-uploader-1.0.0-SNAPSHOT.jar started by root in /)
2023-06-12 09:46:14.890 INFO 23 --- [ main] de.wyraz.tibberuploader.TibberUploader : No active profile set, falling back to 1 default profile: "default"
2023-06-12 09:46:15.844 INFO 23 --- [ main] de.wyraz.tibberuploader.TibberUploader : Started TibberUploader in 1.418 seconds (JVM running for 1.82)
2023-06-12 09:46:16.420 INFO 23 --- [ main] ploader$$EnhancerBySpringCGLIB$$99e182ba : No recent readings found. Starting from 2023-05-13
2023-06-12 09:46:16.439 WARN 23 --- [ main] .w.t.s.ScriptedRestApiMeterReadingSource : Script exited with code 1
StdOut:
test

StdErr:
`

Nun habe ich einen anderen Docker Container mit ESP Home. Hier ist ein ESP an meinem Stromzähler, der die Werte alle via MQTT an mein Home Assistant liefert.
Dies klappt auch schon länger und schaut wie folgt aus:
[09:49:31][V][sensor:059]: 'stromTotal': Received new state 41835.667969 [09:49:31][D][sensor:109]: 'stromTotal': Sending state 41835.66797 kWh with 2 decimals of accuracy [09:49:31][V][sensor:059]: 'phase1': Received new state -1108.000000 [09:49:31][D][sensor:109]: 'phase1': Sending state -1108.00000 W with 2 decimals of accuracy [09:49:31][V][sensor:059]: 'phase2': Received new state 4.840000 [09:49:31][D][sensor:109]: 'phase2': Sending state 4.84000 W with 2 decimals of accuracy [09:49:31][V][sensor:059]: 'phase3': Received new state 43.150002 [09:49:31][D][sensor:109]: 'phase3': Sending state 43.15000 W with 2 decimals of accuracy [09:49:31][V][sensor:059]: 'phasenTotal': Received new state -1060.010010 [09:49:31][D][sensor:109]: 'phasenTotal': Sending state -1060.01001 W with 2 decimals of accuracy

Die Werte kommen vom Stromzähler wie folgt an:
String phase1String = "1-0:21.7.0255(";
String phase2String = "1-0:41.7.0
255(";
String phase3String = "1-0:61.7.0255(";
String phasenTotalString = "1-0:1.7.0
255(";
String stromTotalString = "1-0:1.8.0*255(";

Die Sensoren im ESP lesen sie wie folgt aus:

sensor:

  • platform: custom
    lambda: |-
    auto my_custom_sensor = new UartReadLineSensor(id(uart_bus));
    App.register_component(my_custom_sensor);
    return {my_custom_sensor->stromTotal, my_custom_sensor->phase1, my_custom_sensor->phase2, my_custom_sensor->phase3, my_custom_sensor->phasenTotal};
    sensors:
    • name: "stromTotal"
      accuracy_decimals: 2
      unit_of_measurement: "kWh"
    • name: "phase1"
      accuracy_decimals: 2
      unit_of_measurement: "W"
    • name: "phase2"
      accuracy_decimals: 2
      unit_of_measurement: "W"
    • name: "phase3"
      accuracy_decimals: 2
      unit_of_measurement: "W"
    • name: "phasenTotal"
      accuracy_decimals: 2
      unit_of_measurement: "W"

Frage: Wie bekomme ich diese nun an dein script übermittelt, so dass dein Script diese an Tibber übertragen kann?

Container schmiert ab beim starten

Hi,
ich habe 2 Docker Container für 2 Zähler am laufen.

Bis letzte woche lief alles top.

nun gibt ein Container einen Fehler, obwohl der andere ohne probleme weiter läuft.

Ich habe ihn schon neu aufgesetzt, aber dennoch komme ich nicht weiter :/

Beim Starten geht er gleich wieder weg..

. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _ | \ \ \
\/ )| |)| | | | | || (| | ) ) ) )
' |
| .__|| ||| |_, | / / / /
=========||==============|/=///_/
:: Spring Boot :: (v2.5.14)

2023-09-04 12:48:17.156 INFO 22 --- [ main] de.wyraz.tibberuploader.TibberUploader : Starting TibberUploader v1.0.0-SNAPSHOT using Java 17-ea on 0111dd7ee01a with PID 22 (/tibber-meter-uploader-1.0.0-SNAPSHOT.jar started by root in /)
2023-09-04 12:48:17.168 INFO 22 --- [ main] de.wyraz.tibberuploader.TibberUploader : No active profile set, falling back to 1 default profile: "default"
2023-09-04 12:48:21.922 INFO 22 --- [ main] de.wyraz.tibberuploader.TibberUploader : Started TibberUploader in 6.666 seconds (JVM running for 8.195)
2023-09-04 12:48:23.532 INFO 22 --- [ main] ConditionEvaluationReportLoggingListener :

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2023-09-04 12:48:23.597 ERROR 22 --- [ main] o.s.boot.SpringApplication : Application run failed

java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:820) ~[spring-boot-2.5.14.jar!/:2.5.14]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:801) ~[spring-boot-2.5.14.jar!/:2.5.14]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:350) ~[spring-boot-2.5.14.jar!/:2.5.14]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1370) ~[spring-boot-2.5.14.jar!/:2.5.14]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1359) ~[spring-boot-2.5.14.jar!/:2.5.14]
at de.wyraz.tibberuploader.TibberUploader.main(TibberUploader.java:28) ~[classes!/:1.0.0-SNAPSHOT]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49) ~[tibber-meter-uploader-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
at org.springframework.boot.loader.Launcher.launch(Launcher.java:108) ~[tibber-meter-uploader-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
at org.springframework.boot.loader.Launcher.launch(Launcher.java:58) ~[tibber-meter-uploader-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:88) ~[tibber-meter-uploader-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "errors" (class de.wyraz.tibberuploader.tibber.InternalAccountInfoResponse), not marked as ignorable (one known property: "data"])
at [Source: (org.apache.http.client.entity.LazyDecompressingInputStream); line: 1, column: 12] (through reference chain: de.wyraz.tibberuploader.tibber.InternalAccountInfoResponse["errors"])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61) ~[jackson-databind-2.12.6.1.jar!/:2.12.6.1]
at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:987) ~[jackson-databind-2.12.6.1.jar!/:2.12.6.1]
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1974) ~[jackson-databind-2.12.6.1.jar!/:2.12.6.1]
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1701) ~[jackson-databind-2.12.6.1.jar!/:2.12.6.1]
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1679) ~[jackson-databind-2.12.6.1.jar!/:2.12.6.1]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:330) ~[jackson-databind-2.12.6.1.jar!/:2.12.6.1]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:187) ~[jackson-databind-2.12.6.1.jar!/:2.12.6.1]
at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:322) ~[jackson-databind-2.12.6.1.jar!/:2.12.6.1]
at com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:2033) ~[jackson-databind-2.12.6.1.jar!/:2.12.6.1]
at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1426) ~[jackson-databind-2.12.6.1.jar!/:2.12.6.1]
at de.wyraz.tibberuploader.tibber.TibberPrivateApi.getAccoutInfo(TibberPrivateApi.java:122) ~[classes!/:1.0.0-SNAPSHOT]
at de.wyraz.tibberuploader.TibberUploader.uploadMissingReadings(TibberUploader.java:52) ~[classes!/:1.0.0-SNAPSHOT]
at de.wyraz.tibberuploader.TibberUploader.run(TibberUploader.java:43) ~[classes!/:1.0.0-SNAPSHOT]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:817) ~[spring-boot-2.5.14.jar!/:2.5.14]
... 13 common frames omitted

** Drücke eine BELIEBIGE TASTE, um dieses Fenster zu schließen ** `

Home Assistant

Ist es auch möglich den Zählerstand über Home Assistant an Tibber zu senden?

OBIS register 1-0:1.8.0 not always available

The user @wischnu reported that he gets the following error. The reason is that the meter on tibber's side does not request the default OBIS register for total power consumption (see https://de.wikipedia.org/wiki/OBIS-Kennzahlen for reference).

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2023-02-25 11:17:17.108 ERROR 25773 --- [ main] o.s.boot.SpringApplication : Application run failed

java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:820) ~[spring-boot-2.5.14.jar!/:2.5.14]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:801) ~[spring-boot-2.5.14.jar!/:2.5.14]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:350) ~[spring-boot-2.5.14.jar!/:2.5.14]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1370) ~[spring-boot-2.5.14.jar!/:2.5.14]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1359) ~[spring-boot-2.5.14.jar!/:2.5.14]
at de.wyraz.tibberuploader.TibberUploader.main(TibberUploader.java:28) ~[classes!/:1.0.0-SNAPSHOT]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49) ~[tibber.jar:1.0.0-SNAPSHOT]
at org.springframework.boot.loader.Launcher.launch(Launcher.java:108) ~[tibber.jar:1.0.0-SNAPSHOT]
at org.springframework.boot.loader.Launcher.launch(Launcher.java:58) ~[tibber.jar:1.0.0-SNAPSHOT]
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:88) ~[tibber.jar:1.0.0-SNAPSHOT]
Caused by: java.lang.IllegalArgumentException: Meter 861645c7-c339-46fb-a9dc-45873bddd383 has no register with id '1-0:1.8.0'
at de.wyraz.tibberuploader.tibber.InternalAccountInfoResponse$AccountInfoMeter.unwrap(InternalAccountInfoResponse.java:96) ~[classes!/:1.0.0-SNAPSHOT]
at de.wyraz.tibberuploader.tibber.InternalAccountInfoResponse$AccountInfoMe.unwrap(InternalAccountInfoResponse.java:44) ~[classes!/:1.0.0-SNAPSHOT]
at de.wyraz.tibberuploader.tibber.InternalAccountInfoResponse.unwrap(InternalAccountInfoResponse.java:14) ~[classes!/:1.0.0-SNAPSHOT]
at de.wyraz.tibberuploader.tibber.TibberPrivateApi.getAccoutInfo(TibberPrivateApi.java:116) ~[classes!/:1.0.0-SNAPSHOT]
at de.wyraz.tibberuploader.TibberUploader.uploadMissingReadings(TibberUploader.java:52) ~[classes!/:1.0.0-SNAPSHOT]
at de.wyraz.tibberuploader.TibberUploader.run(TibberUploader.java:43) ~[classes!/:1.0.0-SNAPSHOT]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:817) ~[spring-boot-2.5.14.jar!/:2.5.14]
... 13 common frames omitted

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.