Tibber & Tibber Pulse

Begonnen von hyper2910, 20 November 2022, 10:27:31

Vorheriges Thema - Nächstes Thema

ch.eick

Zitat von: Torxgewinde am 01 Januar 2024, 15:27:31Hallo,
Bezüglich der Websocket habe ich heute mal angefangen, die Verbindung wird auch wohl aufgebaut - aber praktisch auch sofort wieder geschlossen. Vielleicht sieht jemand ja den Fehler, denn dann könnten wir direkt auf FHEM heraus die "liveMeasurements" auslesen. Die Attribute "homeId" und "token" muss man aus der API-Seite auslesen: https://developer.tibber.com/explorer
< snip >
Bist Du da schon weiter gekommen?
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

tomhead

#166
Zitat von: ch.eick am 02 Januar 2024, 13:38:53Hallo Tom,
hier mal ein Beispiel, der aus der Datenbank ermittelten Werte, was im userReadings geschieht.
nodes_consumption_day 9.3770
nodes_consumption_month 22.4870
nodes_consumption_year 22.4870
nodes_cost_avg 11.39
nodes_cost_max 33.63
nodes_cost_min 0.54
total_cost_day 2.19
total_cost_month 4.70
total_cost_year 4.70

Hallo Christian, Danke. Ich habe angenommen, dass aufgrund der Bezeichnungen (nodes_...) die Werte nur mit der red-node Anbindung erstellt werden. Aber ich verstehe dich so, dass das auch mit der HTTPMOD Version funktioniert?

Und noch eine Frage zu deinem letzten Update zur Berechnung der avg, min, max Werte: ist das so gedacht, dass der avg Wert nun über beide Tage gemittelt wird? Ich dachte, das war vorher der jeweilige Tagesmittelwert.

VG, Tom

Torxgewinde

#167
Zitat von: ch.eick am 02 Januar 2024, 16:34:10...
Bist Du da schon weiter gekommen?

Ja, es läuft nun 👍:
2024.01.02 22:54:42 3: Opening Tibber.ws device wss:websocket-api.tibber.com:443/v1-beta/gql/subscriptions
2024.01.02 22:54:43 3: Tibber.ws device opened
2024.01.02 22:54:43 1: Tibber.ws:connect: websocket data: >>>{"type":"connection_ack"}<<<
2024.01.02 22:54:43 1: Tibber.ws:onConnectionAck: got connection ack
2024.01.02 22:54:43 1: Tibber.ws:onConnectionAck: sending JSON: >>>{ "id":"TorxgewindeID", "type":"subscribe", "payload":{"variables":{}, "extensions":{}, "query":"subscription { liveMeasurement( homeId: \"...geheim...\" ) { timestamp power accumulatedConsumption accumulatedCost currency minPower averagePower maxPower }}"}}<<<
2024.01.02 22:54:55 1: Tibber.ws:connect: websocket data: >>><<<
2024.01.02 22:55:01 1: Tibber.ws:connect: websocket data: >>>{"id":"TorxgewindeID","type":"next","payload":{"data":{"liveMeasurement":{"timestamp":"2024-01-02T22:54:59.000+01:00","power":607,"accumulatedConsumption":15.2338,"accumulatedCost":4.08684,"currency":"EUR","minPower":0,"averagePower":664.7,"maxPower":4162}}}}<<<
2024.01.02 22:55:04 1: Tibber.ws:connect: websocket data: >>>{"id":"TorxgewindeID","type":"next","payload":{"data":{"liveMeasurement":{"timestamp":"2024-01-02T22:55:02.000+01:00","power":608,"accumulatedConsumption":15.2342,"accumulatedCost":4.086937,"currency":"EUR","minPower":0,"averagePower":664.7,"maxPower":4162}}}}<<<
2024.01.02 22:55:06 1: Tibber.ws:connect: websocket data: >>>{"id":"TorxgewindeID","type":"next","payload":{"data":{"liveMeasurement":{"timestamp":"2024-01-02T22:55:05.000+01:00","power":615,"accumulatedConsumption":15.2349,"accumulatedCost":4.087108,"currency":"EUR","minPower":0,"averagePower":664.7,"maxPower":4162}}}}<<<
2024.01.02 22:55:07 1: Tibber.ws:connect: websocket data: >>><<<
2024.01.02 22:55:14 1: Tibber.ws:connect: websocket data: >>>{"id":"TorxgewindeID","type":"next","payload":{"data":{"liveMeasurement":{"timestamp":"2024-01-02T22:55:11.000+01:00","power":623,"accumulatedConsumption":15.2359,"accumulatedCost":4.087353,"currency":"EUR","minPower":0,"averagePower":664.7,"maxPower":4162}}}}<<<
2024.01.02 22:55:18 1: Tibber.ws:connect: websocket data: >>>{"id":"TorxgewindeID","type":"next","payload":{"data":{"liveMeasurement":{"timestamp":"2024-01-02T22:55:18.000+01:00","power":610,"accumulatedConsumption":15.2369,"accumulatedCost":4.087597,"currency":"EUR","minPower":0,"averagePower":664.7,"maxPower":4162}}}}<<<
2024.01.02 22:55:19 1: Tibber.ws:connect: websocket data: >>><<<
2024.01.02 22:55:25 1: Tibber.ws:connect: websocket data: >>>{"id":"TorxgewindeID","type":"next","payload":{"data":{"liveMeasurement":{"timestamp":"2024-01-02T22:55:24.000+01:00","power":610,"accumulatedConsumption":15.2379,"accumulatedCost":4.087841,"currency":"EUR","minPower":0,"averagePower":664.7,"maxPower":4162}}}}<<<
2024.01.02 22:55:30 1: Tibber.ws:connect: websocket data: >>>{"id":"TorxgewindeID","type":"next","payload":{"data":{"liveMeasurement":{"timestamp":"2024-01-02T22:55:30.000+01:00","power":610,"accumulatedConsumption":15.2389,"accumulatedCost":4.088086,"currency":"EUR","minPower":0,"averagePower":664.6,"maxPower":4162}}}}<<<
2024.01.02 22:55:31 1: Tibber.ws:connect: websocket data: >>><<<
2024.01.02 22:55:37 1: Tibber.ws:connect: websocket data: >>>{"id":"TorxgewindeID","type":"next","payload":{"data":{"liveMeasurement":{"timestamp":"2024-01-02T22:55:37.000+01:00","power":637,"accumulatedConsumption":15.24,"accumulatedCost":4.088354,"currency":"EUR","minPower":0,"averagePower":664.6,"maxPower":4162}}}}<<<

Hier der aktuellen Stand:
defmod Tibber.ws dummy
attr Tibber.ws userattr websocketURL homeId token myId
attr Tibber.ws alias Tibber Websocket
attr Tibber.ws eventMap /wert connect:start/wert subscribe:subscr/wert disconnect:stop/
attr Tibber.ws homeId deineHomeIDHier
attr Tibber.ws icon hue_filled_plug
attr Tibber.ws myId TorxgewindeID
attr Tibber.ws readingList wert
attr Tibber.ws setList wert
attr Tibber.ws token deinTibberTokenHier
attr Tibber.ws userReadings connect:wert:.connect {\
my $hash = $defs{$name};;\
my $devState = DevIo_IsOpen($hash);;\
return "Device already open" if (defined($devState));;\
\
$hash->{DeviceName} = AttrVal($name, "websocketURL", "wss:echo.websocket.org:443");;\
#$hash->{SSL} = 1;;\
$hash->{TIMEOUT} = 10;;\
\
# special headers needed for Tibber, see also Developer Tools in Browser\
$hash->{header}{'Sec-WebSocket-Protocol'} = 'graphql-transport-ws';;\
$hash->{header}{'Host'} = 'websocket-api.tibber.com';;\
$hash->{header}{'Origin'} = 'https://developer.tibber.com';;\
\
# callback function when "select" signals data for us\
# websocket Ping/Pongs are treated in DevIo but still call this function\
$hash->{directReadFn} = sub () {\
my $hash = $defs{$name};;\
readingsBeginUpdate($hash);;\
\
# we can read without closing the DevIo, because select signalled data\
my $buf = DevIo_SimpleRead($hash);;\
\
if(!defined($buf)) {\
#DevIo_CloseDev($hash);;\
$buf = "not connected";;\
}\
\
Log(1, "$name:$reading: websocket data: >>>$buf<<<");;\
\
# only update our reading if buffer is not empty\
readingsBulkUpdate($hash, "websocketData", "$buf") if ($buf ne "");;\
readingsEndUpdate($hash, 1);;\
};;\
\
# open DevIo websocket\
DevIo_OpenDev($hash, 0, undef, sub(){\
my ($hash, $error) = @_;;\
return "$error" if ($error);;\
\
#immediately send what we would like to be notified for\
my $homeId = AttrVal($name, "homeId", "???");;\
my $token = AttrVal($name, "token", "???");;\
\
DevIo_SimpleWrite($hash, '{"type":"connection_init","payload":{"token":"'.$token.'"}}', 2);;\
});;\
\
return POSIX::strftime("%H:%M:%S",localtime(time()));;\
},\
disconnect:wert:.disconnect {\
my $hash = $defs{$name};;\
RemoveInternalTimer($hash);;\
DevIo_SimpleRead($hash);;\
DevIo_CloseDev($hash);;\
\
return POSIX::strftime("%H:%M:%S",localtime(time()));;\
},\
onDisconnect {\
my $myState = ReadingsVal($name, "state", "???");;\
return if ($myState ne "disconnected");;\
\
## timer callback function, called after a few seconds to initiate a reconnect\
#my $timerFunction = sub() {\
# my ($hash) = @_;;\
# my $devState = DevIo_IsOpen($hash);;\
# readingsSingleUpdate($hash, "wert", "connect", 1) if (!defined($devState));;\
#};;\
#my $hash = $defs{$name};;\
#RemoveInternalTimer($hash, $timerFunction);;\
#InternalTimer(gettimeofday() + 60, $timerFunction, $hash);;\
\
return POSIX::strftime("%H:%M:%S",localtime(time()));;\
},\
onConnectionAck:websocketData:.*connection_ack.* {\
Log(1, "$name:$reading: got connection ack");;\
\
my $hash = $defs{$name};;\
my $devState = DevIo_IsOpen($hash);;\
return "Device not open" if (!defined($devState));;\
\
my $homeId = AttrVal($name, "homeId", "???");;\
my $myId = AttrVal($name, "myId", "???");;\
\
my $json = '{ "id":"'. $myId .'", "type":"subscribe"'.", ";;\
$json .= '"payload":{';;\
$json .= '"variables":{}'.", ";;\
$json .= '"extensions":{}'.", ";;\
$json .= '"query":"subscription { liveMeasurement( homeId: \"'.$homeId.'\" ) ';;\
$json .= '{ timestamp power accumulatedConsumption accumulatedCost currency minPower averagePower maxPower }}"';;\
$json .= '}}';;\
\
Log(1, "$name:$reading: sending JSON: >>>$json<<<");;\
DevIo_SimpleWrite($hash, $json, 2);;\
\
return POSIX::strftime("%H:%M:%S",localtime(time()));;\
}
attr Tibber.ws websocketURL wss:websocket-api.tibber.com:443/v1-beta/gql/subscriptions

ch.eick

Hallo Tom,
Zitat von: tomhead am 02 Januar 2024, 18:43:49Hallo Christian, Danke. Ich habe angenommen, dass aufgrund der Bezeichnungen (nodes_...) die Werte nur mit der red-node Anbindung erstellt werden. Aber ich verstehe dich so, dass das auch mit der HTTPMOD Version funktioniert?
der Namensteil "nodes_" kommt aus den Tibber Daten.
ZitatUnd noch eine Frage zu deinem letzten Update zur Berechnung der avg, min, max Werte: ist das so gedacht, dass der avg Wert nun über beide Tage gemittelt wird? Ich dachte, das war vorher der jeweilige Tagesmittelwert.
Ja, das habe ich jetzt über alle Daten von fc0 und fc1 gebildet, um einen besseren Wert zu bekommen. Es kam vor, dass z.B. fc0 zwar ein Triggerfenster hat was jedoch um einiges höher lag als das von fc1. Jetzt würde das Triggerfenster dann um 14 Uhr, wenn der nächste Tag geliefert wird mit dem Preisniveau vom fc1 neu angepasst werden.

Den fc_med habe ich bisher nur ermittelt, jedoch noch nicht eingebaut.

VG  Christian
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

jnewton957

ich bin ja nun auch seit 1.1.2024 tibber-Kunde.

Ein wenig kämpfe ich noch mit der Stabilität der Anwendung bzw. den Daten.

Wenn ich bei den nodes_00_0x_cost, nodes_00_0x_consumption eine "0" (kein null) im listing/DB habe, muss ich davon ausgehen, dass mir tibber die Daten nicht korrekt liefert ?

nodes_00_00_consumption 0.103                2024-01-03 13:41:17
nodes_00_00_cost        0.0276               2024-01-03 13:41:17
nodes_00_00_from        2024-01-03 10:00:00  2024-01-03 13:41:17
nodes_00_01_consumption 0                    2024-01-03 13:41:17
nodes_00_01_cost        0                    2024-01-03 13:41:17
nodes_00_01_from        2024-01-03 11:00:00  2024-01-03 13:41:17
nodes_00_02_consumption 0                    2024-01-03 13:41:17
nodes_00_02_cost        0                    2024-01-03 13:41:17
nodes_00_02_from        2024-01-03 12:00:00  2024-01-03 13:41:17

Eine Idee, woran das ggf. (sonst) liegen könnte?

Danke
FHEM6.2 auf Pi5
V 1.66 nanoCUL 433 (IT)
V 1.66 nanoCUL868 (HM)
sqlite3 LogDb
ELRO AB440, DECT200,  TFA30.3125, esp8266, HM, TabletUI, IR-Schreiblesekopf (Udo),tibber Pulse, Kostal Pico, cfos Wallbox, Modbus TCP

ch.eick

Zitat von: jnewton957 am 03 Januar 2024, 13:53:52ich bin ja nun auch seit 1.1.2024 tibber-Kunde.
Ein wenig kämpfe ich noch mit der Stabilität der Anwendung bzw. den Daten.
Wenn ich bei den nodes_00_0x_cost, nodes_00_0x_consumption eine "0" (kein null) im listing/DB habe, muss ich davon ausgehen, dass mir tibber die Daten nicht korrekt liefert ?
< snip >
Eine Idee, woran das ggf. (sonst) liegen könnte?
Hallo,
die Werte kommen so von Tibber und es könnte z.B. sein, dass Du wirklich keinen, oder einen sehr kleinen Verbrauch gehabt hast, wenn eventuell eine PV mit Speicher mit im Spiel ist.

## Bei den Kosten kommt es vor, dass Tibber diese noch nicht berechnet hat (null). Dann werden sie meistens bei der nächsten Abfrage geliefert.
## Das Schreiben in die Datenbank erfolgt im userReadings mit dem von Tibber gelieferten TIMESTAMP. Sollte später von Tibber ein aktualisierter
## Wert geliefert werden, wir dieser dann in der Datenbank ebenfalls korrigiert übernommen (ON DUPLICATE KEY UPDATE)
get03-2Name nodes_00_00_cost
get03-2OExpr ($val ne "0" and $val ne "null")? round($val,4) : $val

## Der Wert von Consumpion wird direkt von Tibber gelesen
get03-3Name nodes_00_00_consumption
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

jnewton957

Komisch ist es schon.
Habe mal über die https://developer.tibber.com/explorer eine live Abfrage gemacht.

{
  "liveMeasurement": {
    "timestamp": "2024-01-03T16:27:02.000+01:00",
    "power": 423.4,
    "accumulatedConsumption": 14.4858,
    "accumulatedCost": null,
    "currency": null,
    "minPower": 0,
    "averagePower": 880.4,
    "maxPower": 5145.5
  }
}

Quasi gleiches Ergebnis. accumulatedCost": null, currency": null,

ich beobachte das mal weiter. Aktuell haben wir keinen PV Ertrag und eben 423.4 W Verbrauch.
FHEM6.2 auf Pi5
V 1.66 nanoCUL 433 (IT)
V 1.66 nanoCUL868 (HM)
sqlite3 LogDb
ELRO AB440, DECT200,  TFA30.3125, esp8266, HM, TabletUI, IR-Schreiblesekopf (Udo),tibber Pulse, Kostal Pico, cfos Wallbox, Modbus TCP

Torxgewinde

Hier die aktuelle Version der "liveMeasurements" via Websocket. Die homeId und der token sind funktionale Demo-Werte von https://developer.tibber.com/explorer:

defmod Tibber.ws dummy
attr Tibber.ws userattr websocketURL homeId token myId
attr Tibber.ws alias Tibber Websocket
attr Tibber.ws eventMap /wert connect:start/wert disconnect:stop/
attr Tibber.ws homeId 96a14971-525a-4420-aae9-e5aedaa129ff
attr Tibber.ws icon hue_filled_plug
attr Tibber.ws myId TorxgewindeID
attr Tibber.ws readingList wert
attr Tibber.ws setList wert
attr Tibber.ws token 5K4MVS-OjfWhK_4yrjOlFe1F6kJXPVf7eQYggo8ebAE
attr Tibber.ws userReadings connect:wert:.connect {\
    my $hash = $defs{$name};;\
    my $devState = DevIo_IsOpen($hash);;\
    return "Device already open" if (defined($devState));;\
    \
    $hash->{DeviceName} = AttrVal($name, "websocketURL", "wss:echo.websocket.org:443");;\
    \
    # special headers needed for Tibber, see also Developer Tools in Browser\
    $hash->{header}{'Sec-WebSocket-Protocol'} = 'graphql-transport-ws';;\
    $hash->{header}{'Host'} = 'websocket-api.tibber.com';;\
    $hash->{header}{'Origin'} = 'https://developer.tibber.com';;\
    \
    # callback function when "select" signals data for us\
    # websocket Ping/Pongs are treated in DevIo but still call this function\
    $hash->{directReadFn} = sub () {\
        my $hash = $defs{$name};;\
        readingsBeginUpdate($hash);;\
        \
        # we can read without closing the DevIo, because select signalled data\
        my $buf = DevIo_SimpleRead($hash);;\
        \
        if(!defined($buf)) {\
            DevIo_CloseDev($hash);;\
            $buf = "not_connected";;\
        }\
        \
        #Log(1, "$name:$reading: websocket data: >>>$buf<<<");;\
        \
        # only update our reading if buffer is not empty\
        readingsBulkUpdate($hash, "websocketData", "$buf") if ($buf ne "");;\
        readingsEndUpdate($hash, 1);;\
    };;\
    \
    # open DevIo websocket\
    DevIo_OpenDev($hash, 0, undef, sub(){\
        my ($hash, $error) = @_;;\
        return "$error" if ($error);;\
        \
        my $token = AttrVal($name, "token", "???");;\
        \
        DevIo_SimpleWrite($hash, '{"type":"connection_init","payload":{"token":"'.$token.'"}}', 2);;\
    });;\
        \
    return POSIX::strftime("%H:%M:%S",localtime(time()));;\
},\
disconnect:wert:.disconnect {\
    my $hash = $defs{$name};;\
    RemoveInternalTimer($hash);;\
    DevIo_SimpleRead($hash);;\
    DevIo_CloseDev($hash);;\
    \
    return POSIX::strftime("%H:%M:%S",localtime(time()));;\
},\
onDisconnect {\
    my $myState = ReadingsVal($name, "state", "???");;\
    my $myData = ReadingsVal($name, "websocketData", "???");;\
    return if ($myState ne "disconnected" and $myData ne "not_connected");;\
    \
    ## timer callback function, called after a few seconds to initiate a reconnect\
    my $timerFunction = sub() {\
        my ($hash) = @_;;\
        readingsSingleUpdate($hash, "wert", "connect", 1);;\
    };;\
    my $hash = $defs{$name};;\
    RemoveInternalTimer($hash, $timerFunction);;\
    \
    # wait a random time before reconnect (exponential backoff TBD):\
    my $rwait = int(rand(200)) + 30;;\
    InternalTimer(gettimeofday() + $rwait, $timerFunction, $hash);;\
    \
    return POSIX::strftime("%H:%M:%S",localtime(time()));;\
},\
onConnectionAck:websocketData:.*connection_ack.* {\
    Log(1, "$name:$reading: got connection ack");;\
    \
    my $hash = $defs{$name};;\
    my $devState = DevIo_IsOpen($hash);;\
    return "Device not open" if (!defined($devState));;\
    \
    my $homeId = AttrVal($name, "homeId", "???");;\
    my $myId = AttrVal($name, "myId", "???");;\
    \
    my $json = '{ "id":"'. $myId .'", "type":"subscribe"'.", ";;\
    $json .= '"payload":{';;\
    $json .= '"variables":{}'.", ";;\
    $json .= '"extensions":{}'.", ";;\
    $json .= '"query":"subscription { liveMeasurement( homeId: \"'.$homeId.'\" ) ';;\
    #$json .= '{ timestamp power accumulatedConsumption accumulatedCost currency minPower averagePower maxPower signalStrength }}"';;\
    $json .= '{ timestamp power lastMeterConsumption accumulatedConsumption accumulatedProduction ';;\
    $json .= 'accumulatedProductionLastHour accumulatedCost accumulatedReward currency minPower averagePower maxPower ';;\
    $json .= 'powerProduction powerReactive powerProductionReactive minPowerProduction maxPowerProduction lastMeterProduction ';;\
    $json .= 'powerFactor voltagePhase1 voltagePhase2 voltagePhase3 signalStrength }}"';;\
    $json .= '}}';;\
    \
    Log(1, "$name:$reading: sending JSON: >>>$json<<<");;\
    DevIo_SimpleWrite($hash, $json, 2);;\
        \
    return POSIX::strftime("%H:%M:%S",localtime(time()));;\
},\
onNextLiveMeasurement:websocketData:.*next.*payload.*data.*liveMeasurement.* {\
    my $val = ReadingsVal($name, "websocketData", "{}");;\
    my %res = %{json2nameValue($val, undef, undef, "payload_data_liveMeasurement.*")};;\
    \
    my $ret = "got values for:\n";;\
    foreach my $k (sort keys %res) {\
        $ret .= "$k\n";;\
        readingsBulkUpdate($hash, makeReadingName($k), $res{$k});;\
    }\
    return $ret;;\
}
attr Tibber.ws websocketURL wss:websocket-api.tibber.com:443/v1-beta/gql/subscriptions

Zook

Für was steht denn die "myId" bei
attr Tibber.ws myId TorxgewindeID ?
Ist das der Login bei Tibber?

Zitat von: Torxgewinde am 04 Januar 2024, 18:31:22Hier die aktuelle Version der "liveMeasurements" via Websocket. Die homeId und der token sind funktionale Demo-Werte von https://developer.tibber.com/explorer:

defmod Tibber.ws dummy
attr Tibber.ws userattr websocketURL homeId token myId
attr Tibber.ws alias Tibber Websocket
attr Tibber.ws eventMap /wert connect:start/wert disconnect:stop/
attr Tibber.ws homeId 96a14971-525a-4420-aae9-e5aedaa129ff
attr Tibber.ws icon hue_filled_plug
attr Tibber.ws myId TorxgewindeID
attr Tibber.ws readingList wert
attr Tibber.ws setList wert
attr Tibber.ws token 5K4MVS-OjfWhK_4yrjOlFe1F6kJXPVf7eQYggo8ebAE
attr Tibber.ws userReadings connect:wert:.connect {\
    my $hash = $defs{$name};;\
    my $devState = DevIo_IsOpen($hash);;\
    return "Device already open" if (defined($devState));;\
    \
    $hash->{DeviceName} = AttrVal($name, "websocketURL", "wss:echo.websocket.org:443");;\
    \
    # special headers needed for Tibber, see also Developer Tools in Browser\
    $hash->{header}{'Sec-WebSocket-Protocol'} = 'graphql-transport-ws';;\
    $hash->{header}{'Host'} = 'websocket-api.tibber.com';;\
    $hash->{header}{'Origin'} = 'https://developer.tibber.com';;\
    \
    # callback function when "select" signals data for us\
    # websocket Ping/Pongs are treated in DevIo but still call this function\
    $hash->{directReadFn} = sub () {\
        my $hash = $defs{$name};;\
        readingsBeginUpdate($hash);;\
        \
        # we can read without closing the DevIo, because select signalled data\
        my $buf = DevIo_SimpleRead($hash);;\
        \
        if(!defined($buf)) {\
            DevIo_CloseDev($hash);;\
            $buf = "not_connected";;\
        }\
        \
        #Log(1, "$name:$reading: websocket data: >>>$buf<<<");;\
        \
        # only update our reading if buffer is not empty\
        readingsBulkUpdate($hash, "websocketData", "$buf") if ($buf ne "");;\
        readingsEndUpdate($hash, 1);;\
    };;\
    \
    # open DevIo websocket\
    DevIo_OpenDev($hash, 0, undef, sub(){\
        my ($hash, $error) = @_;;\
        return "$error" if ($error);;\
        \
        my $token = AttrVal($name, "token", "???");;\
        \
        DevIo_SimpleWrite($hash, '{"type":"connection_init","payload":{"token":"'.$token.'"}}', 2);;\
    });;\
        \
    return POSIX::strftime("%H:%M:%S",localtime(time()));;\
},\
disconnect:wert:.disconnect {\
    my $hash = $defs{$name};;\
    RemoveInternalTimer($hash);;\
    DevIo_SimpleRead($hash);;\
    DevIo_CloseDev($hash);;\
    \
    return POSIX::strftime("%H:%M:%S",localtime(time()));;\
},\
onDisconnect {\
    my $myState = ReadingsVal($name, "state", "???");;\
    my $myData = ReadingsVal($name, "websocketData", "???");;\
    return if ($myState ne "disconnected" and $myData ne "not_connected");;\
    \
    ## timer callback function, called after a few seconds to initiate a reconnect\
    my $timerFunction = sub() {\
        my ($hash) = @_;;\
        readingsSingleUpdate($hash, "wert", "connect", 1);;\
    };;\
    my $hash = $defs{$name};;\
    RemoveInternalTimer($hash, $timerFunction);;\
    \
    # wait a random time before reconnect (exponential backoff TBD):\
    my $rwait = int(rand(200)) + 30;;\
    InternalTimer(gettimeofday() + $rwait, $timerFunction, $hash);;\
    \
    return POSIX::strftime("%H:%M:%S",localtime(time()));;\
},\
onConnectionAck:websocketData:.*connection_ack.* {\
    Log(1, "$name:$reading: got connection ack");;\
    \
    my $hash = $defs{$name};;\
    my $devState = DevIo_IsOpen($hash);;\
    return "Device not open" if (!defined($devState));;\
    \
    my $homeId = AttrVal($name, "homeId", "???");;\
    my $myId = AttrVal($name, "myId", "???");;\
    \
    my $json = '{ "id":"'. $myId .'", "type":"subscribe"'.", ";;\
    $json .= '"payload":{';;\
    $json .= '"variables":{}'.", ";;\
    $json .= '"extensions":{}'.", ";;\
    $json .= '"query":"subscription { liveMeasurement( homeId: \"'.$homeId.'\" ) ';;\
    #$json .= '{ timestamp power accumulatedConsumption accumulatedCost currency minPower averagePower maxPower signalStrength }}"';;\
    $json .= '{ timestamp power lastMeterConsumption accumulatedConsumption accumulatedProduction ';;\
    $json .= 'accumulatedProductionLastHour accumulatedCost accumulatedReward currency minPower averagePower maxPower ';;\
    $json .= 'powerProduction powerReactive powerProductionReactive minPowerProduction maxPowerProduction lastMeterProduction ';;\
    $json .= 'powerFactor voltagePhase1 voltagePhase2 voltagePhase3 signalStrength }}"';;\
    $json .= '}}';;\
    \
    Log(1, "$name:$reading: sending JSON: >>>$json<<<");;\
    DevIo_SimpleWrite($hash, $json, 2);;\
        \
    return POSIX::strftime("%H:%M:%S",localtime(time()));;\
},\
onNextLiveMeasurement:websocketData:.*next.*payload.*data.*liveMeasurement.* {\
    my $val = ReadingsVal($name, "websocketData", "{}");;\
    my %res = %{json2nameValue($val, undef, undef, "payload_data_liveMeasurement.*")};;\
    \
    my $ret = "got values for:\n";;\
    foreach my $k (sort keys %res) {\
        $ret .= "$k\n";;\
        readingsBulkUpdate($hash, makeReadingName($k), $res{$k});;\
    }\
    return $ret;;\
}
attr Tibber.ws websocketURL wss:websocket-api.tibber.com:443/v1-beta/gql/subscriptions

Intel NUC mit Proxmox; Busware CUL 868 v3; Signalduino; Synology DS 420, DS 215j + APC USV; Amazon Alexa + HA Bridge; FritzBox 7490; Fritz Dect 200; Fritz Dect 210; Brennenstuhl RCS 1000; Philips HUE; HM-SEC-WDS-2, HM-SEC-SCo; VU+ SOLO 4K und diverse Module

ch.eick

#174
Zitat von: Zook am 05 Januar 2024, 14:12:08Für was steht denn die "myId" bei
attr Tibber.ws myId TorxgewindeID ?
Ist das der Login bei Tibber?
Ja, die ID und das Token identifizieren den Kunden.
Wer noch kein Kunde ist kann mit der ID und dem Token von der Entwickler Seite üben, dann kommen aber fiktive Testdaten und als Wehrung Schwedische Kronen ;-)
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

tomhead

Zitat von: ch.eick am 05 Januar 2024, 16:24:28
Zitat von: Zook am 05 Januar 2024, 14:12:08Für was steht denn die "myId" bei
attr Tibber.ws myId TorxgewindeID ?
Ist das der Login bei Tibber?
Ja, die ID und das Token identifizieren den Kunden.
Verstehe ich aber auch noch nicht ganz; es gibt ja die homeID und den Token (die sind ja als eigene attr gesetzt), aber was ist dann myID?

Torxgewinde

#176
Ich habe eine Demo bei CoolTux hochgeladen, damit man es in Aktion sehen kann: https://demo-fhem.cooltux.net/fhem?room=Power

Die Parameter die man anpassen MUSS:

Den Parameter myId KANN man anpassen. Er dient nur dazu, dass man der Websocket eine ID mitgibt die dann in den folgenden Antworten genutzt wird. Der Wert scheint frei wählbar zu sein und hat keine weitere Relevanz außer dass man die Antwort ggf. von anderen unterscheiden kann. Sinn macht mir das für einen Websocket und eine HomeId nicht, aber ggf. ist das vorgesehen wenn man mehrere Websockets/HomeIds gleichzeitig nutzen will. Die Explorer-Testseite selbst trägt da Werte wie zum Beispiel "96a14971-525a-4420-aae9-e5aedaa129ff" ein, die sind aber jedesmal anders. TorxgewindeID ist einfach nur irgendein Wert, man kann da auch "Bla-Blubb-Foo-Bar" etc. eintragen.

Die Doku für Graph-QL über Websockets habe ich hier gefunden: https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md
Zitatid field so the client can identify each response from the server.

tomhead

Zitat von: jnewton957 am 03 Januar 2024, 16:29:52Komisch ist es schon.
Habe mal über die https://developer.tibber.com/explorer eine live Abfrage gemacht.

{
  "liveMeasurement": {
    "timestamp": "2024-01-03T16:27:02.000+01:00",
    "power": 423.4,
    "accumulatedConsumption": 14.4858,
    "accumulatedCost": null,
    "currency": null,
    "minPower": 0,
    "averagePower": 880.4,
    "maxPower": 5145.5
  }
}

Quasi gleiches Ergebnis. accumulatedCost": null, currency": null,

ich beobachte das mal weiter. Aktuell haben wir keinen PV Ertrag und eben 423.4 W Verbrauch.

Ist bei mir auch so, alle Werte sind vorhanden, nur accumulatedCost:null, currency:null

tomhead

Ich bräuchte bitte noch mal Hilfe, wie ich die Vorschauwerte für die nächsten 3h über ftui dargestellt bekomme. Die Werte werden ja im Tool von Christian für die uitable berechnet, liegen aber nicht als eigene Readings mit der zugehörigen Uhrzeit ab. Wie bekomme ich das analog der uitable in ftui dargestellt?
Danke und Grüße, Tom

ch.eick

Zitat von: tomhead am 06 Januar 2024, 08:27:06Ich bräuchte bitte noch mal Hilfe, wie ich die Vorschauwerte für die nächsten 3h über ftui dargestellt bekomme. Die Werte werden ja im Tool von Christian für die uitable berechnet, liegen aber nicht als eigene Readings mit der zugehörigen Uhrzeit ab. Wie bekomme ich das analog der uitable in ftui dargestellt?
Danke und Grüße, Tom
Hallo Tom,
das ist die Funktion Price{} im EVU_Tibber Device, die die entsprechenden readings fc[0|1]_[hh]_total aus dem EVU_Tibber_connect ausliest und formatiert anzeigt.
Dabei ist 0 die aktuelle und 1-n die jeweils nächsten Stunden. Durch den Vergleich mit fc_trigger_price wird der Wert dann noch in rot/grün als html formatiert, die Berechnung wird nicht im uiTable gemacht.

VG   Christian
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick