Erfahrung mit Tibber und Symcon?

Hallo Markus,

wie gesagt, der Livestream via Websocket ist aus meiner Sicht (hab da aber bisher nicht viel Erfahrung) nicht so trivial wie die normale Query API, von daher wäre das bei mir erst mal nicht an Prio 1. Würde mich aber informieren ob/wie dass umsetzbar ist…
Allerdings habe ich mal kurz die Stream-Api definition angeschaut, und mit HT/NT wird das so wie ich das auf die Schnelle gehen habe nichts werden, da es nur einen Production und einen Consumption Wert gibt. Ist aus Sicht von Tibber auch logisch, da es da ja kein HT/NT sondern stündliche Tarife sind, wo eine Unterscheidung nach HT/NT keinen wirklichen Sinn macht.

Und mit Doc bin ich in Abstimmung bzgl. der Umsetzung. Falls noch Unterstützung benötigt wird gebe ich gerne bescheid.

Viele Grüße
Philipp

1 „Gefällt mir“

Was passiert an den Tagen, wo die Zeitumstellung (Winter-/Sommerzeit und umgekehrt) durchgeführt wird? Jetzt im März werden vermutlich 23 Werte seitens Tibber geliefert und wir brauchen 24 fürs Archiv. Auch im Oktober sollten 25 Werte geliefert werden, wie werden diese aber auf 24h abgebildet?

Gruß

Henning

Hallo Henning,

das ist eine gute Frage, aber vermutlich wie bei allen anderen Berechnungen über eine Zeitumstellung auch.
Aber zum schreiben ins Archiv wird der Zeitstempel (- 2Tage) genommen, den Tibber selber mitliefert.
Wenn Tibber den mit der Zeitumstellung richtig liefert, sollte es da keine Probleme geben.
Unter Umständen könnte dann mit nur 23 Werten in der Nacht zwischen 1-3h dann ggf. 2 Stunden lang der gleiche Wert stehen, müssen wir mal abwarten, was Tibber da liefert.

Für das Script mit den Stundenwerte sollte das aber ohne Bedeutung sein, es wäre ja nur bei dem Diagramm zu sehen.

Aber wenn ich da jetzt noch länger drüber nachdenke, bekomme ich einen Knoten im Hirn … :wink:

Viele Grüße,
Doc

Am 25.03.23 ab 13:00Uhr sollten wir die Daten für den 26.03.23 bekommen. Für einen normalen Tagen sehen die Daten so aus:

          array(24) {
            [0]=>
            object(stdClass)#1 (4) {
              ["total"]=>
              float(0,2876)
              ["energy"]=>
              float(0,1143)
              ["tax"]=>
              float(0,1733)
              ["startsAt"]=>
              string(29) "2023-03-08T00:00:00.000+01:00"

Da es am 26.3. nur 23h gibt, sollte das Array auch nur 23 Werte liefern. Die ersten beiden (Startteit 0:00Uhr und 1:00 MEZ mit dem Versatz +01:00 bezogen auf UTC und der Rest mit +02:00 (da jetzt MESZ).

26.3. 0:00Uhr MEZ - 172.800 Sekunden => OK

Unix Timestamp 1679785200
GMT Sat Mar 25 2023 23:00:00 GMT+0000
Your Time Zone Sun Mar 26 2023 00:00:00 GMT+0100 (Mitteleuropäische Normalzeit)
GMT Thu Mar 23 2023 23:00:00 GMT+0000
Your Time Zone Fri Mar 24 2023 00:00:00 GMT+0100 (Mitteleuropäische Normalzeit)

26.3. 1:00Uhr MEZ - 172.800 Sekunden => OK

Unix Timestamp 1679788800
GMT Sun Mar 26 2023 00:00:00 GMT+0000
Your Time Zone Sun Mar 26 2023 01:00:00 GMT+0100 (Mitteleuropäische Normalzeit)
GMT Fri Mar 24 2023 00:00:00 GMT+0000
Your Time Zone Fri Mar 24 2023 01:00:00 GMT+0100 (Mitteleuropäische Normalzeit)

26.3. 3:00Uhr MESZ - 172.800 Sekunden => Error

Unix Timestamp 1679792400
GMT Sun Mar 26 2023 01:00:00 GMT+0000
Your Time Zone Sun Mar 26 2023 03:00:00 GMT+0200 (Mitteleuropäische Sommerzeit)
GMT Fri Mar 24 2023 01:00:00 GMT+0000
Your Time Zone Fri Mar 24 2023 02:00:00 GMT+0100 (Mitteleuropäische Normalzeit)

Im Zeitraum 26.3. 3:00 bis 28.3. 3:00 sind die Werte 1h verschoben, sofern immer mit dem Wert 172.800 Sekunden gerechnet wird.

Gruß

Henning

Ja das kann sein, die Frage ist, ob es den Aufwand Wert ist hier im Script das noch genau für die Zeitumstellung abzuändern.
Es wird parallel von einem anderen Nutzer schon an einem Modul gearbeitet, ggf. kann man das mit reinfließen lassen.
So genau hatte ich mir das mit der Zeitverschiebung bis jetzt nicht angesehen, aber du hast recht, das wird sich verschieben.
Das ist halt immer blöb mit dem Schreiben von Zukunftswerten in die Vergangenheit ins Archiv.

Viele Grüße,
Doc

Das ist nicht schwer :slight_smile:, denn PHP berücksichtigt das für dich wenn du die strtotime Funktion nutzt.

Statt

 'TimeStamp' => ($timestamp-172800),

also genauer

 'TimeStamp' => strtotime('-2 days', $timestamp),

nehmen.

1 „Gefällt mir“

Danke dir.
Das man auch mit strtotime arbeiten kann war mir klar, aber das dann automatisch die Sommer/Winterzeitumstellung mit einfließt, war mir neu.
Man lernt halt nie aus … :wink:
Obwohl ich den Teil im PHP Manual auf die schnelle nicht gefunden hatte.

Ich habe es oben im Originalscript mal abgeändert, da war auch noch ein kleiner Fehler mit Reaggregation des Archives drin.
Mal schauen, wie es dann in 2 Wochen ausschaut.

Danke u. viele Grüße,
Doc

23 Werte auf 24 abzubilden kann noch funktionieren, aber im Oktober haben wir dann 25. Das wird interessant. Sorry, das ich der Spielverderber bin.

Sobald wir diese Umschaltung zwischen Normal- und Sommerzeit abschaffen, würde der Workaround ohne Probleme funktionieren.

Gruß

Henning

Das Ergebnis bei 28.3. 3:00Uhr minus 2Tage

string(19) „2023-03-28 02:00:00“
string(19) „2023-03-26 03:00:00“

Gruß

Henning
P.S.: damit getestet

<?php
    $timestamp = 1679961600; //Tue Mar 28 2023 00:00:00 GMT+0000 bzw. Tue Mar 28 2023 02:00:00 GMT+0200 (Mitteleuropäische Sommerzeit)
    var_dump (date("Y-m-d H:i:s", $timestamp));
    var_dump (date("Y-m-d H:i:s", strtotime('-2 days', $timestamp)));
?>

Servus, heute kam mein Pulse IR, der funktioniert soweit.

Ich kann auch die Werte via der Tibber Api über den Tibber Developer so abfragen:

subscription{
liveMeasurement(homeId:„f1d7c039-b2cf-4775-b0a7-2f1792e89xxx“){
timestamp
power
accumulatedConsumption
accumulatedCost
currency
minPower
averagePower
maxPower}
}

Aber wir bekomme ich das per Script hin?

Nimm doch einfach dieses Script als Vorlage.
Du brauchst doch nur deine Query dort eintragen und unten den entsprechenden Variablen zuordnen.

Grüße,
Doc

Das habe ich ja versucht:

$json = '{"query":"{subscription{(homeId:"f1d7c039-b2cf-4775-b0a7-2f1792e89xxx"){timestamp power accumulatedConsumption accumulatedCost currency minPower averagePower maxPower }}"}';

bekomme aber immer ein : [error] => syntax error

Ohne es jetzt selber ausprobiert zu haben, die Anzahl der geschweiften Klammern stimmt in deinem Beispiel nicht.

Zeig doch mal dein komplettes Script.

Wo bekommt man die HomeID her, will mal selber testen?

Viele Grüße,
Doc

die home id bekommt so raus:

man geht auf Tibber Developer

kopiert oben seien Token rein und gibt das ins Scriptfenster und drückt play :wink:

{
  viewer {
    login
    name
    homes {
      id
    }
  }}

Soweit ich das verstanden habe, geht das Abfragen von diesen Messwerten nicht, so wie man die Preise abrufen kann, sondern als Websocket, weil ja livedaten sind…

Websocket subscription client requirements

hier nachzulesen:

https://developer.tibber.com/docs/guides/calling-api

Die WebSocket Adresse: wss://websocket-api.tibber.com/v1-beta/gql/subscriptions

Da stehe ich erstmal auf dem Schlauch, wie ich das in PHP / Symcon abfragen könnte…

ich habe mit dem Websocket vom Symcon gespielt (das sind die Werte von der Demo):

$client = 39672; // der WS-Client
$json = '{"type":"connection_init","payload":{"token": "476c477d8a039529478ebd690d35ddd80e3308ffc49b59c65b142321aee963a4"}}';
WSC_SendMessage ($client, $json);

$query= '{"id": "1","type": "start","payload": {"query": "subscription{liveMeasurement(homeId:"c70dcbe5-4485-4821-933d-a8a86452737b"){ timestamp power powerProduction AccumulatedConsumption AccumulatedCost}}"}}';
WSC_SendMessage ($client, $query);

Aber es kommt nichts zurück :frowning:

Die Instance der Wecbsocket ist auch immer fehlerhaft und und im Debug vom Websocket steht da immer : ERROR | Keine Berechtigung

Hier wurde es schonmal versucht: Tibber (Norway) websocket subscription - #12 von cinemarillion

So es lag an meinem Symcon auf der Nas im Docker…
Auf dem Pi geht es :wink:

Anleitung:

  1. Websocket anlegen und so konfigurieren:

image

URL: wss://websocket-api.tibber.com/v1-beta/gql/subscriptions

Sec-WebSocket-Protocol graphql-transport-ws
User-Agent com.tibber/1.8.3

Dieses Script anlegen, für die register Variable:

<?php


$usage_now = 0;
$acc_h_usage = 0;
// wenn das Skript von einer RegisterVariable-Instanz aus aufgerufen worden ist
if ($_IPS['SENDER'] == "RegisterVariable")
{
    // bereits im Puffer der Instanz vorhandene Daten in $data kopieren
    $data  = RegVar_GetBuffer($_IPS['INSTANCE']);
    // neu empfangene Daten an $data anhängen
    $data .= $_IPS['VALUE'];
 
    // wenn das Trennzeichen ; in $data gefunden worden ist
    if (strpos($data, ';'))
    {
        // $data in durch ; separierte Datensätze zerlegen
        $datasets = explode(';', $data);
 
        // alle nicht durch ; terminierten Datensätze ausgeben
        for ($i = 0; $i < count($datasets) - 1; $i++)
        {
            echo "empfangener Datensatz: ".$datasets[$i]."\n";
        }
         // $data auf den Inhalt des letzten (unvollständigen) Datensatzes setzen
        $data = $datasets[count($datasets) - 1];
    }
setvalue(37128,$data);
$data2 = json_decode($data);
print_r($data2);


$accumul = $data2->payload->data->liveMeasurement->accumulatedConsumptionLastHour;
$consumption = $data2->payload->data->liveMeasurement->power;
$ts = $data2->payload->data->liveMeasurement->timestamp;
$sale = $data2->payload->data->liveMeasurement->powerProduction;
#SetValue ($acc_h_usage, $accumul);
print $accumul;

if ($consumption > 0) {
    #SetValue ($usage_now, $consumption);
    print $consumption;

} else {
    if ($sale !=null){
        #SetValue ($usage_now, 0-$sale);
        print $sale;
    }
};
RegVar_SetBuffer($_IPS['INSTANCE'], null);
};

Das Script muss nach seinen Bedürfnissen angepasst werden ! (Variable IDs !!!)

Dann eine Register Variable Anlegen und das eben angelegte Script verbinden / auswählen und das Gateway ändern, auf den Websocket.

Dann noch das Auslöse / Abfrage Script erstellen:

<?php

$client = 15403; //objectID for the WS client

    sleep (2);
    IPS_SetProperty ($client, 'Active', 0);
    IPS_ApplyChanges($client);
    sleep (2);
    IPS_SetProperty ($client, 'Active', 1);
    IPS_ApplyChanges($client);
    sleep (2);

$json = '{"type":"connection_init","payload":{"token": "<TOKEN>"}}';
WSC_SendMessage ($client, $json);
sleep (5);
$query= '{"id": "1","type": "subscribe","payload": {"query": "subscription{liveMeasurement(homeId:\"<home id >\"){timestamp power powerProduction accumulatedConsumptionLastHour accumulatedCost}}"}}';
WSC_SendMessage ($client, $query);

Hier wieder die Variabel / Instance IDs anpassen, Token und home ID eintragen ! nur die „<“ und „>“ entfernen ! Das :"" lassen !!!

1 „Gefällt mir“

Hier eine Übersicht, welche Werte man abfragen kann:

timestamp: String!

Timestamp when usage occurred

power: Float!

Consumption at the moment (Watt)

lastMeterConsumption: Float

Last meter active import register state (kWh)

accumulatedConsumption: Float!

kWh consumed since midnight

accumulatedProduction: Float!

net kWh produced since midnight

accumulatedConsumptionLastHour: Float!

kWh consumed since since last hour shift

accumulatedProductionLastHour: Float!

net kWh produced since last hour shift

accumulatedCost: Float

Accumulated cost since midnight; requires active Tibber power deal; includes VAT (where applicable)

accumulatedReward: Float

Accumulated reward since midnight; requires active Tibber power deal

currency: String

Currency of displayed cost; requires active Tibber power deal

minPower: Float!

Min consumption since midnight (Watt)

averagePower: Float!

Average consumption since midnight (Watt)

maxPower: Float!

Peak consumption since midnight (Watt)

powerProduction: Float

Net production (A-) at the moment (Watt)

powerReactive: Float

Reactive consumption (Q+) at the moment (kVAr)

powerProductionReactive: Float

Net reactive production (Q-) at the moment (kVAr)

minPowerProduction: Float

Min net production since midnight (Watt)

maxPowerProduction: Float

Max net production since midnight (Watt)

lastMeterProduction: Float

Last meter active export register state (kWh)

powerFactor: Float

Power factor (active power / apparent power)

voltagePhase1: Float

Voltage on phase 1; on Kaifa and Aidon meters the value is not part of every HAN data frame therefore the value is null at timestamps with second value other than 0, 10, 20, 30, 40, 50. There can be other deviations based on concrete meter firmware.

voltagePhase2: Float

Voltage on phase 2; on Kaifa and Aidon meters the value is not part of every HAN data frame therefore the value is null at timestamps with second value other than 0, 10, 20, 30, 40, 50. There can be other deviations based on concrete meter firmware. Value is always null for single phase meters.

voltagePhase3: Float

Voltage on phase 3; on Kaifa and Aidon meters the value is not part of every HAN data frame therefore the value is null at timestamps with second value other than 0, 10, 20, 30, 40, 50. There can be other deviations based on concrete meter firmware. Value is always null for single phase meters.

currentL1: Float

Current on L1; on Kaifa and Aidon meters the value is not part of every HAN data frame therefore the value is null at timestamps with second value other than 0, 10, 20, 30, 40, 50. There can be other deviations based on concrete meter firmware.

currentL2: Float

Current on L2; on Kaifa and Aidon meters the value is not part of every HAN data frame therefore the value is null at timestamps with second value other than 0, 10, 20, 30, 40, 50. There can be other deviations based on concrete meter firmware. Value is always null for single phase meters.

currentL3: Float

Current on L3; on Kaifa and Aidon meters the value is not part of every HAN data frame therefore the value is null at timestamps with second value other than 0, 10, 20, 30, 40, 50. There can be other deviations based on concrete meter firmware. Value is always null for single phase meters.

signalStrength: Int

Device signal strength (Pulse - dB; Watty - percent)

deprecated fields

Jetzt warst du schneller mit dem Post/Lösung :slight_smile:

War mit dem selben Set-Up mit dem Websocket heute morgen erfolgreich :slight_smile: Nur leider noch keine Zeit gehabt das per Post zu dokumentieren… was ja jetzt schon erfolgt ist :+1:

Aber noch eine Frage, bei mir musste bei meinen Tests die ID immer mit einer GUID füllen, eine einfache Zahl kam immer „falscher“ Request. Ging bei dir einfach die „1“ wie im Script?

Viele Grüße
Philipp

Ne bei mir ging das immer so mit der ID 1…

Was passiert ist jetzt klar …
So ein Diagramm habe ich in IPS auch noch nicht gesehen … :wink:

Aber auch die Tibber App scheint mit der Zeitumstellung noch zu kämpfen …

1 „Gefällt mir“

Bin seit 2.4. nun Tibber-Kunde und habe auch den Pulse schon installiert.
Vielen Dank für die Skripe, funktioniert bestens!!!
Plan ist bei mir auch bei günstigen Stromtarifen Großverbraucher zeitgesteuert einzuschalten und den Akku zu laden und den Akkustrom dann während der teuren Zeiten wieder zu verbrauchen. Ziel ist also im IPS ein EMS (Energy Management System) aufzubauen.