You can connect a „Register Variable“ instance behind the WebSocket and it will receive all WebSocket messages. RegisterVariable — IP-Symcon :: Automation Software
parey
You can connect a „Register Variable“ instance behind the WebSocket and it will receive all WebSocket messages. RegisterVariable — IP-Symcon :: Automation Software
parey
Thank you! An important step forward
And I figured out that I had to empty the buffer at the end of the cycle. But I still don’t quite know how to get the variables :noob:
At the other (non subscription) request i get a json array(?) which I then parse (?) into current price etc, but when I try to adapt the subscription in the same way I get a blank.
This is an typical string I get in return:
{„type“:„data“,„id“:„1“,„payload“:{„data“:{„liveMeasurement“:{„timestamp“:„2022-08-05T16:44:10.000+02:00“,„power“:0,„powerProduction“:942,„accumulatedConsumption“:16.138631,„accumulatedCost“:46.609486}}}}
Which is in the $data variable from the example script in the documentation.
$accumul = $data->payload->data->liveMeasurment->accumulatedConsumption[0];
SetValue (13928, $accumul);
which then is blank. When I use
SetValue (13928, $data);
I get the whole data string in the variable.
Do you have any more pointers for me, please?
Andreas
I made it! The [0] wasn’t supposed to be there. Lots of trial, googeling and failing, before I achieved success.
could you please write the solution ?
Hi, everybody!
I’ve gotten some questions as to how I did this, and I was planning to answer now, but the API at tibber has changed, and I jet again don’t know how to solve this. So my solution has stopped reporting the realtime, and accumulated consumption.
The change is the removed supprot for (the ended) graphql-ws protocol and the replacement with graphql-transport-ws protocol. I think I managed to get around that problem, by changing the protocol name, but there is now also a requirement to set user-agent header, which I don’t quite understand… As I’ve said before I have no background in programming, just what snippets I’ve managed to pick up for forums and stackexchange etc.
I’m in contact with tibber now on chat, and hopefully we can figure it out.
On the other hand. This problem is only with the current consumption, accumulated hourly consupstion data, which reqiures an subscription-connection. For the price-data I have another soulution that works just fine. It’s a script which sets three variables according to the current pricedata.
This then sets the color on the aeotec ss6 in the living-room, and on a colorbulb in the downstairs bathroom, si we always can check the pricelevel.
<?php
$pris = 12345; //variabel for pris
$nivaa = 23456; //variabel for prisnivå, 1-5 og 0 for error
$dyr = 34567; //boolsk variabel for dyr strøm, sann eller usann
$json = '{"query":"{viewer {homes {currentSubscription {priceInfo {current {total level energy tax startsAt }}}}}}"}';
# Create a connection
$ch = curl_init('https://api.tibber.com/v1-beta/gql');
# Setting our options
curl_setopt($ch, CURLOPT_URL, 'https://api.tibber.com/v1-beta/gql');
curl_setopt($ch, CURLOPT_HTTPHEADER,
array('Content-Type: application/json',
'Authorization: Bearer /*insert your token here*/')); // token
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
# Get the response
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response);
$current = $data->data->viewer->homes[0];
$level = $current->currentSubscription->priceInfo->current->level;
$total = $current->currentSubscription->priceInfo->current->total;
$energy = $current->currentSubscription->priceInfo->current->energy;
$tax = $current->currentSubscription->priceInfo->current->tax;
SetValue ($pris, $total);
switch ($level) {
case 'VERY_CHEAP':
SetValue ($nivaa, 1);
SetValue ($dyr, 0);
break;
case 'CHEAP':
SetValue ($nivaa, 2);
SetValue ($dyr, 0);
break;
case 'NORMAL':
SetValue ($nivaa, 3);
SetValue ($dyr, 0);
break;
case 'EXPENSIVE':
SetValue ($nivaa, 4);
SetValue ($dyr, 1);
break;
case 'VERY_EXPENSIVE':
SetValue ($nivaa, 5);
SetValue ($dyr, 1);
break;
default:
SetValue ($nivaa, 0);
SetValue ($dyr, 0);
}?>
I made a workaround after trying out the websockets in postman. As I recieve data and connection, the protocol was never the problem
This is how I now get data (throug the workaround)
Create a WS client under i/o instances:
Then I run a script (openWS) to open and initialize the connection:
{
$client = 34873; //objectID for the WS client
$json = '{"type":"connection_init","payload":{"token":"<access token here>"}}';
WSC_SendMessage ($client, $json);
sleep (5);
$query= '{"id": "1","type": "subscribe","payload": {"query": "subscription{liveMeasurement(homeId:\"<HomeID here>\"){timestamp power powerProduction accumulatedConsumptionLastHour accumulatedCost}}"}}';
WSC_SendMessage ($client, $query);
}
This results in resonse from the tibber-server feeding the requested data every few seconds.
I then have a registervariable connected to the tibber Websocket, and the registervariable runs a script (WSforbruk) which looks like this:
<?php
//ønsker: forbruk nå, (produksjon nå), akkumulert forbruk
$usage_now = 37938;
$acc_h_usage = 18071;
// 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];
}
$data2 = json_decode($data);
$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);
if ($consumption > 0) {
SetValue ($usage_now, $consumption);
} else {
if ($sale !=null){
SetValue ($usage_now, 0-$sale);
}
};
RegVar_SetBuffer($_IPS['INSTANCE'], null);
};
I don’t quite understand all of this script, but it gives me my current usage og sale from the solar panels and the accumulated usage for the current hour put into the two variables defined at the top.
The problems I have now:
Is there a way to either monitor the „opened“ message and the run the connection inizialization, og through a script deactivate and reactivate the WS-client? Or to make an if 12345 is erroneous then (…)?
And of course: Is this an acceptable solution, or should it be reworked?
Where do you put this?
I get :Interface is an error state. Please check message log for more information.
in debug websocket client I get: ERROR permision denied
This is how my WebSocket is configured now. Tibber support-chat suggested the changes you see. Is this how your’s is configured?
There was a change in the websocket config in 6.2 or 6.3, I think. I don’t think it’ll work woithout it…
Then i have upgraded to 6.3
But websocket connects and reconnects all the time. Do i need to get an personal „user-Agent“?
The two scripts are excecuted in a time-interval?
i get code:4408, Reason:Connection initialisation timeout
How do you get the registervariabel to run the script
Thats fron a debug on the websocket? You have to time the script to when it’s „opened“, then you’ll end up with the „connection_ack“ message, and the requst for the subscription can be sent.
I changed my openWS script to work around this issue:
// Sjekke om det er mer enn 6 min siden TibberWS er oppdatert
$tib_forbruk = 37938;
$ws=34873;
$time = date(IPS_GetVariable($tib_forbruk)['VariableUpdated']);
$time = time() - $time; // to get the time since that moment
if ($time > 360)
// slå av og på WS, slik at den kommer i "opened"
{
sleep (2);
IPS_SetProperty ($ws, 'Active', 0);
IPS_ApplyChanges($ws);
sleep (2);
IPS_SetProperty ($ws, 'Active', 1);
IPS_ApplyChanges($ws);
sleep (2);
// autentisitere og starte subscription
$json = '{"type":"connection_init","payload":{"token":"<insert your token here>"}}';
WSC_SendMessage ($ws, $json);
sleep (5);
$query= '{"id": "1","type": "subscribe","payload": {"query": "subscription{liveMeasurement(homeId:\"<insert your homeId here>\"){timestamp power powerProduction accumulatedConsumptionLastHour accumulatedCost}}"}}';
WSC_SendMessage ($ws, $query);
}
It might not be up to best practice in PHP (feel free to prettyfy, anybody), but I think it does the trick. Try it out, and please report back wheter it worked or not.
As this script checks wheter the data from tibber is quite recent, I think it’s safe to run it every 4 minutes, to check. If the data’s updated it just closes, right?
regards Andreas
Dubble tap the regvar, and choose the script as target. Sorry, I can’t screenshot right now.
Alright… at least i got something different now. I have tried several different commands but they all result in tis response:
Do you have a Tibber-dude i can ask?
I feel a bit stupid right now
There seems to be something wrong with the query string. I think you missed the slashes in the query.
$query= '{"id": "1","type": "subscribe","payload": {"query": "subscription{liveMeasurement(homeId:\"<insert your homeId here>\"){timestamp power powerProduction accumulatedConsumptionLastHour accumulatedCost}}"}}';
I’ve had that stupid-feeling quite a few times Still ooften do, actually…
A
I’ll be damned…
It’s working
tousand takk