This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

Tibber API
#21
(05.04.2020, 00:10)Erwin van der Zwart Wrote: Hi,

You should check if the table content is valid before drilling down deeper...
Code:
1234567
if data then    if data.payload then       if data.payload.power then          grp.checkwrite('1/1/1’, data.payload.power)       end    end end
BR,

Erwin

Of course, thanks Erwin  Smile

Best regards, Jørn.
Reply
#22
THank you for the input Jørn. It now Works like a charm.
Schneider Wiser (homeLynk), Power Tags, DALI, Multitouch Pro, Panasonic Heating pump, Flexit balansed ventilation, HUE integration, Lemus Speaker system. Tibber integration.
Reply
#23
Jørn and stemic01:

Could you give a short brief here about what you could do with Tibber and LM in combination? Did you get this working with Tibber API? Do you translate the hour prices to KNX GA?
Reply
#24
(07.01.2021, 19:12)Rune Wrote: Jørn and stemic01:

Could you give a short brief here about what you could do with Tibber and LM in combination? Did you get this working with Tibber API? Do you translate the hour prices to KNX GA?

Hi.  
Group addresses: Yes, I translate the Tibber values into Logic Machine Group Addresses. Per now over the bus-range of addresses, but I plan to change this to virtual addresses treduce the traffic load on the KNX bus. If you plan to show tibber values on a KNX visualization panel you might need to stay in the standard group addresses range.

Tibber integration: Per now I only use this for visualization purposes. Highlighting when prices are high or when consumption are high. Plus trending on prices and consumption. 
So there is no magic going on with cutting power to items, lower heating, stop water heating etc according to prices. But it should be pretty straight forward. It would be pretty easy to make a for exmple a phillips HUE lamp to change color accodring to power prices or current power consumption if you wanted so.  

For electrical vehicle and charging when it is cheap - i do believe that the TIbber / Eeesy charging solution is more streamlined and better (I do not have EV, so I have not tested this). 

The Tibber integration has been working great for me - except one returning issue which is propably a programming error in one of my scripts (Scripts from this thread). It seems like the script either crashes or the Tibber API blocks the connection after some time. I don't know what is the problem, but I usually do the following: 
- Deactivate / activate the Tibber script 
- Restart the Logic Machine 
- Manually change the group address value in Logic machine (example just put in a value "1" in consumption and price. 

One or all of these usually solves the problem.
Schneider Wiser (homeLynk), Power Tags, DALI, Multitouch Pro, Panasonic Heating pump, Flexit balansed ventilation, HUE integration, Lemus Speaker system. Tibber integration.
Reply
#25
(11.01.2021, 21:43)stemic01 Wrote:
(07.01.2021, 19:12)Rune Wrote: Jørn and stemic01:

Could you give a short brief here about what you could do with Tibber and LM in combination? Did you get this working with Tibber API? Do you translate the hour prices to KNX GA?

Hi.  
Group addresses: Yes, I translate the Tibber values into Logic Machine Group Addresses. Per now over the bus-range of addresses, but I plan to change this to virtual addresses treduce the traffic load on the KNX bus. If you plan to show tibber values on a KNX visualization panel you might need to stay in the standard group addresses range.

Tibber integration: Per now I only use this for visualization purposes. Highlighting when prices are high or when consumption are high. Plus trending on prices and consumption. 
So there is no magic going on with cutting power to items, lower heating, stop water heating etc according to prices. But it should be pretty straight forward. It would be pretty easy to make a for exmple a phillips HUE lamp to change color accodring to power prices or current power consumption if you wanted so.  

For electrical vehicle and charging when it is cheap - i do believe that the TIbber / Eeesy charging solution is more streamlined and better (I do not have EV, so I have not tested this). 

The Tibber integration has been working great for me - except one returning issue which is propably a programming error in one of my scripts (Scripts from this thread). It seems like the script either crashes or the Tibber API blocks the connection after some time. I don't know what is the problem, but I usually do the following: 
- Deactivate / activate the Tibber script 
- Restart the Logic Machine 
- Manually change the group address value in Logic machine (example just put in a value "1" in consumption and price. 

One or all of these usually solves the problem.

Thank you for your report.

I got help from a colleague to make a script based on this thread and the only option I need now, is the price per hour. It's working now and it is pretty nice. Smile
Reply
#26
(12.01.2021, 20:37)Rune Wrote:
(11.01.2021, 21:43)stemic01 Wrote:
(07.01.2021, 19:12)Rune Wrote: Jørn and stemic01:

Could you give a short brief here about what you could do with Tibber and LM in combination? Did you get this working with Tibber API? Do you translate the hour prices to KNX GA?

Hi.  
Group addresses: Yes, I translate the Tibber values into Logic Machine Group Addresses. Per now over the bus-range of addresses, but I plan to change this to virtual addresses treduce the traffic load on the KNX bus. If you plan to show tibber values on a KNX visualization panel you might need to stay in the standard group addresses range.

Tibber integration: Per now I only use this for visualization purposes. Highlighting when prices are high or when consumption are high. Plus trending on prices and consumption. 
So there is no magic going on with cutting power to items, lower heating, stop water heating etc according to prices. But it should be pretty straight forward. It would be pretty easy to make a for exmple a phillips HUE lamp to change color accodring to power prices or current power consumption if you wanted so.  

For electrical vehicle and charging when it is cheap - i do believe that the TIbber / Eeesy charging solution is more streamlined and better (I do not have EV, so I have not tested this). 

The Tibber integration has been working great for me - except one returning issue which is propably a programming error in one of my scripts (Scripts from this thread). It seems like the script either crashes or the Tibber API blocks the connection after some time. I don't know what is the problem, but I usually do the following: 
- Deactivate / activate the Tibber script 
- Restart the Logic Machine 
- Manually change the group address value in Logic machine (example just put in a value "1" in consumption and price. 

One or all of these usually solves the problem.

Thank you for your report.

I got help from a colleague to make a script based on this thread and the only option I need now, is the price per hour. It's working now and it is pretty nice. Smile

I use this for price per hour, i use it as a scheduled script with 15 minute intervals. Insert token and replace "Strømpris denne time" with your group address or group name, 4 byte floating point datatype, output in "øre" ;o)

Code:
12345678910111213141516171819202122232425262728293031
https = require('ssl.https') json = require('json') ltn12 = require('ltn12') token = 'TOKEN HERE' --Token data = json.encode({   query = '{viewer {homes {currentSubscription {priceInfo {current {total}}}}}}' --kwh pris med avgifter }) tbl = {} res, code = https.request({   url = 'https://api.tibber.com/v1-beta/gql',   method = 'POST',   headers = {     ['authorization'] = 'Bearer ' .. token,     ['content-type']  = 'application/json',     ['content-length'] = #data,   },   source = ltn12.source.string(data),   sink = ltn12.sink.table(tbl), }) if res and code == 200 then   resp = table.concat(tbl)   resp = json.pdecode(resp) homes = resp.data.viewer.homes info = homes[ 1 ].currentSubscription.priceInfo.current   grp.write('Strømpris denne time', info.total*100) else   log(res, code) end

(11.01.2021, 21:43)stemic01 Wrote:
(07.01.2021, 19:12)Rune Wrote: Jørn and stemic01:

Could you give a short brief here about what you could do with Tibber and LM in combination? Did you get this working with Tibber API? Do you translate the hour prices to KNX GA?

Hi.  
Group addresses: Yes, I translate the Tibber values into Logic Machine Group Addresses. Per now over the bus-range of addresses, but I plan to change this to virtual addresses treduce the traffic load on the KNX bus. If you plan to show tibber values on a KNX visualization panel you might need to stay in the standard group addresses range.

Tibber integration: Per now I only use this for visualization purposes. Highlighting when prices are high or when consumption are high. Plus trending on prices and consumption. 
So there is no magic going on with cutting power to items, lower heating, stop water heating etc according to prices. But it should be pretty straight forward. It would be pretty easy to make a for exmple a phillips HUE lamp to change color accodring to power prices or current power consumption if you wanted so.  

For electrical vehicle and charging when it is cheap - i do believe that the TIbber / Eeesy charging solution is more streamlined and better (I do not have EV, so I have not tested this). 

The Tibber integration has been working great for me - except one returning issue which is propably a programming error in one of my scripts (Scripts from this thread). It seems like the script either crashes or the Tibber API blocks the connection after some time. I don't know what is the problem, but I usually do the following: 
- Deactivate / activate the Tibber script 
- Restart the Logic Machine 
- Manually change the group address value in Logic machine (example just put in a value "1" in consumption and price. 

One or all of these usually solves the problem.

I run in to this from time to time as well. I just created a script that checks if value has been updated recently and turns tibber script off and on. Have not had to do anything manual since. I run it as a scheduled script every 3 minutes.

Code:
12345678
obj = grp.find('Aktuelt forbruk watt') -- insert group address for consumption delta = os.time() - obj.updatetime if delta >= 10 then   script.disable('Tibber websocket') -- replace with the name of your tibber websocket script   os.sleep(1)   script.enable('Tibber websocket') -- replace with the name of your tibber websocket script   alert('Restartet Tibber script') end

Best regards, Jørn.
Reply
#27
Trying to wrap my head around to get the data out from my logs and howto extract the data and to write them into groupaddresses

I see the data in scriptlogs, but can't find out howto extract the 24 hours values into seperate GA's

My script:


Code:
12345678910111213141516171819202122232425262728293031
https = require('ssl.https') json = require('json') ltn12 = require('ltn12') token = 'MYTOKEN' data = json.encode({   query = '{viewer {homes {currentSubscription {priceInfo {today {total startsAt }}}}}}' }) tbl = {} res, code = https.request({   url = 'https://api.tibber.com/v1-beta/gql',   method = 'POST',   headers = {     ['authorization'] = 'Bearer ' .. token,     ['content-type']  = 'application/json',     ['content-length'] = #data,   },   source = ltn12.source.string(data),   sink = ltn12.sink.table(tbl), }) if res and code == 200 then   resp = table.concat(tbl)   resp = json.pdecode(resp)   log(resp.data.viewer.homes) info = homes[1].currentSubscription.priceInfo.today[1].total -- Value for hour 0-1 grp.write('33/0/0', info.total*100) end


Results from my scriptlog:

Tibber API 09.08.2021 22:54:24
* table:
[1]
  * table:
  ["currentSubscription"]
    * table:
    ["priceInfo"]
      * table:
      ["today"]
        * table:
        [1]
          * table:
          ["startsAt"]
            * string: 2021-08-09T00:00:00+02:00
          ["total"]
            * number: 0.7054
        [2]
          * table:
          ["startsAt"]
            * string: 2021-08-09T01:00:00+02:00
          ["total"]
            * number: 0.6915
        [3]
          * table:
          ["startsAt"]
            * string: 2021-08-09T02:00:00+02:00
          ["total"]
            * number: 0.5271
        [4]
          * table:
          ["startsAt"]
            * string: 2021-08-09T03:00:00+02:00
          ["total"]
            * number: 0.4968
        [5]
          * table:
          ["startsAt"]
            * string: 2021-08-09T04:00:00+02:00
          ["total"]
            * number: 0.7097
        [6]
          * table:
          ["startsAt"]
            * string: 2021-08-09T05:00:00+02:00
          ["total"]
            * number: 0.7656
        [7]
          * table:
          ["startsAt"]
            * string: 2021-08-09T06:00:00+02:00
          ["total"]
            * number: 0.8536
        [8]
          * table:
          ["startsAt"]
            * string: 2021-08-09T07:00:00+02:00
          ["total"]
            * number: 0.8735
        [9]
          * table:
          ["startsAt"]
            * string: 2021-08-09T08:00:00+02:00
          ["total"]
            * number: 0.8917
        [10]
          * table:
          ["startsAt"]
            * string: 2021-08-09T09:00:00+02:00
          ["total"]
            * number: 0.8721
        [11]
          * table:
          ["startsAt"]
            * string: 2021-08-09T10:00:00+02:00
          ["total"]
            * number: 0.8418
        [12]
          * table:
          ["startsAt"]
            * string: 2021-08-09T11:00:00+02:00
          ["total"]
            * number: 0.8247
        [13]
          * table:
          ["startsAt"]
            * string: 2021-08-09T12:00:00+02:00
          ["total"]
            * number: 0.8182
        [14]
          * table:
          ["startsAt"]
            * string: 2021-08-09T13:00:00+02:00
          ["total"]
            * number: 0.8108
        [15]
          * table:
          ["startsAt"]
            * string: 2021-08-09T14:00:00+02:00
          ["total"]
            * number: 0.8135
        [16]
          * table:
          ["startsAt"]
            * string: 2021-08-09T15:00:00+02:00
          ["total"]
            * number: 0.8085
        [17]
          * table:
          ["startsAt"]
            * string: 2021-08-09T16:00:00+02:00
          ["total"]
            * number: 0.8252
        [18]
          * table:
          ["startsAt"]
            * string: 2021-08-09T17:00:00+02:00
          ["total"]
            * number: 0.9003
        [19]
          * table:
          ["startsAt"]
            * string: 2021-08-09T18:00:00+02:00
          ["total"]
            * number: 0.9642
        [20]
          * table:
          ["startsAt"]
            * string: 2021-08-09T19:00:00+02:00
          ["total"]
            * number: 0.9705
        [21]
          * table:
          ["startsAt"]
            * string: 2021-08-09T20:00:00+02:00
          ["total"]
            * number: 0.9249
        [22]
          * table:
          ["startsAt"]
            * string: 2021-08-09T21:00:00+02:00
          ["total"]
            * number: 0.913
        [23]
          * table:
          ["startsAt"]
            * string: 2021-08-09T22:00:00+02:00
          ["total"]
            * number: 0.887
        [24]
          * table:
          ["startsAt"]
            * string: 2021-08-09T23:00:00+02:00
          ["total"]
            * number: 0.8531





Scripts errorlog:
Tibber API 09.08.2021 22:55:24
Resident script:29: attempt to index global 'homes' (a nil value)
stack traceback:


Any hints howto proceed?
I wan't to have hourvalue 0-1 in GA 33/0/0, hourvalue 1-2 in GA 33/0/1 and so on...

BR, Odd Egil
Reply
#28
Try this:
Code:
12
value = resp.data.viewer.homes[1].currentSubscription.priceInfo.today[1].total grp.write('33/0/0', tonumber(value) * 100)
Reply
#29
(09.08.2021, 23:01)Erwin van der Zwart Wrote: Try this:
Code:
12
value = resp.data.viewer.homes[1].currentSubscription.priceInfo.today[1].total grp.write('33/0/0', tonumber(value) * 100)

That did work exactly like I wanted it to!
Tested with the first six values and they are just like in my Tibber App, just that API has one more decimal



Thank you very much
Reply
#30
Hi.
I'm using this script and it works nice, now I want to present the next hour and second next hours price in my visualisation, and maybe my previous hours price.

I now get the price per hour in a scheduled script and grp.write this to a separate GAs, this script is running once a day. But just wanna show the next and second next hours next to the current price in visu.
Can I modify this script to always shoe the next hours price in the same GA? someone that have done the same solution?
Reply
#31
Change token / group addresses as needed:
Code:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
https = require('ssl.https') json = require('json') ltn12 = require('ltn12') token = '476c477d8a039529478ebd690d35ddd80e3308ffc49b59c65b142321aee963a4' -- demo token query = [[ {   viewer {     homes {       currentSubscription {         priceInfo {           today {             total             startsAt           }           tomorrow {             total             startsAt           }         }       }     }   } } ]] data = json.encode({ query = query }) tbl = {} res, code = https.request({   url = 'https://api.tibber.com/v1-beta/gql',   method = 'POST',   headers = {     ['authorization'] = 'Bearer ' .. token,     ['content-type']  = 'application/json',     ['content-length'] = #data,   },   source = ltn12.source.string(data),   sink = ltn12.sink.table(tbl), }) if res and code == 200 then   resp = table.concat(tbl)   resp = json.pdecode(resp)   homes = resp.data.viewer.homes   today = homes[ 1 ].currentSubscription.priceInfo.today or {}   tomorrow = homes[ 1 ].currentSubscription.priceInfo.tomorrow or {}   function getprice(hour)     local entry     local index = hour + 1     if index > 24 then       entry = tomorrow[ index - 24 ]     else       entry = today[ index ]     end     if entry then       return entry.total     end   end   hour = os.date('*t').hour   grp.update('1/1/1', getprice(hour))   grp.update('1/1/2', getprice(hour + 1))   grp.update('1/1/3', getprice(hour + 2)) else   log(res, code) end
Reply
#32
Tibber seem to have updated their API (see  Tibber Developer).
Has anybody updated the LUA script to read consumption from HAN port via the Tibber API? 

My script has stopped working with the message:

string: connection failed: Websocket Handshake failed: Invalid Sec-Websocket-Accept (expected ******* = got nil)
Reply
#33
(06.01.2023, 10:00)mjaanes Wrote: Tibber seem to have updated their API (see  Tibber Developer).
Has anybody updated the LUA script to read consumption from HAN port via the Tibber API? 

My script has stopped working with the message:

string: connection failed: Websocket Handshake failed: Invalid Sec-Websocket-Accept (expected ******* = got nil)

I have the same problem..
My resident script has  a os.sleep beacause the CPU-load went too high with real-time subscription
Code:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
---------------------------- if not client then     os.sleep(50) -- wait 50 seconds     number_of_measurements = 0   ws = require('user.websocket')   json = require('json')   token = 'mySecretToken' --log('starting')     query = [[   subscription{     liveMeasurement(homeId:"mySecretHomeId"){       timestamp       power       accumulatedConsumption           accumulatedConsumptionLastHour       minPower       averagePower       maxPower     }   }   ]]     url = 'wss://api.tibber.com/v1-beta/gql/subscriptions'   client, err = ws.client('sync', 10)   res, err = client:connect(url)   if res then     client:send(json.encode({       type = 'connection_init',       payload = 'token=' .. token,     }))     client:send(json.encode({       id = 2,       type = 'start',       payload = {         query = query       }     }))   else     log('connection failed: ' .. tostring(err))     client:close()     client = nil   end else   data, _, _, opcode, err = client:receive()     if data then      --log('data= ' ..data)     data2 = json.pdecode(data)     if data2 and data2.payload then     tibber = data2.payload.data.liveMeasurement                   --log(tibber)       timestamp_text = tibber.timestamp       timestamp_text_sub = string.sub(timestamp_text, 12, 19)             grp.write('32/4/1', (tonumber(tibber.power))/1000)             grp.write('32/4/2', (tonumber(tibber.accumulatedConsumption)))             grp.write('32/4/3', (tonumber(tibber.accumulatedConsumptionLastHour)))             grp.write('32/4/4', (tonumber(tibber.minPower))/1000)             grp.write('32/4/5', (tonumber(tibber.averagePower))/1000)             grp.write('32/4/6', (tonumber(tibber.maxPower))/1000)             grp.write('32/4/7', timestamp_text_sub)                  --log('Suksess')     client:close()     client = nil     end   else     log('receive failed: ' .. tostring(err))     client:close()     client = nil   end   end
Reply
#34
I am having same issues and need some help to get this up running again... Anyone solved this matter? Any help would be very appreciated.
Schneider Wiser (homeLynk), Power Tags, DALI, Multitouch Pro, Panasonic Heating pump, Flexit balansed ventilation, HUE integration, Lemus Speaker system. Tibber integration.
Reply
#35
Use updated user.websocket library attached to this post.

Change token / homeId as needed. Add object updates at line 78. Use grp.checkupdate or grp.checkwrite so that LM is not overloaded with unnecessary duplicate values.

Code:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
ws = require('user.websocket') json = require('json') http = require('socket.http') ltn12 = require('ltn12') token = '12345' payload = json.encode({ query = '{viewer { websocketSubscriptionUrl } }' }) res = http.request({   url = 'https://api.tibber.com/v1-beta/gql',   method = 'POST',   headers = {     ['Authorization'] = 'Bearer ' .. token,     ['Content-Type'] = 'application/json',     ['Content-Length'] = #payload,   },   source = ltn12.source.string(payload), }) res = json.pdecode(res) if type(res) == 'table' and res.data then   url = res.data.viewer.websocketSubscriptionUrl   client, err = ws.client('sync', 30)   client.protocol = 'graphql-transport-ws'   res, err = client:connect(url)   query = [[   subscription {     liveMeasurement(homeId: "a-b-c-d") {       timestamp       power       accumulatedConsumption       accumulatedCost       currency       minPower       averagePower       maxPower     }   }   ]] else   res = nil end if res then   res, err = client:send(json.encode({     type = 'connection_init',     payload = {       token = token     }   }))   client:receive()   ts, tu = os.microtime()   res, err = client:send(json.encode({     id = ts .. '-' .. tu,     type = 'subscribe',     payload = {       query = query     }   }))   while true do     data, opcode, _, _, err = client:receive()     if data then       if opcode == ws.PING then         client:send(data, ws.PONG)       elseif opcode == ws.TEXT then         data = json.pdecode(data)         if type(data) == 'table' then           -- update objects here         end       end     else       log('receive failed: ' .. tostring(err))       break     end   end else   log('connection failed: ' .. tostring(err)) end if client then   client:close()   client = nil end

Attached Files
.lua   websocket.lua (Size: 13.79 KB / Downloads: 38)
Reply
#36
Thank you admin
It seems to work very well now. I get updates every 2 seconds.
Reply
#37
(10.01.2023, 10:52)admin Wrote: Use updated user.websocket library attached to this post.

Change token / homeId as needed. Add object updates at line 78. Use grp.checkupdate or grp.checkwrite so that LM is not overloaded with unnecessary duplicate values.

Code:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
ws = require('user.websocket') json = require('json') http = require('socket.http') ltn12 = require('ltn12') token = '12345' payload = json.encode({ query = '{viewer { websocketSubscriptionUrl } }' }) res = http.request({   url = 'https://api.tibber.com/v1-beta/gql',   method = 'POST',   headers = {     ['Authorization'] = 'Bearer ' .. token,     ['Content-Type'] = 'application/json',     ['Content-Length'] = #payload,   },   source = ltn12.source.string(payload), }) res = json.pdecode(res) if type(res) == 'table' and res.data then   url = res.data.viewer.websocketSubscriptionUrl   client, err = ws.client('sync', 30)   client.protocol = 'graphql-transport-ws'   res, err = client:connect(url)   query = [[   subscription {     liveMeasurement(homeId: "a-b-c-d") {       timestamp       power       accumulatedConsumption       accumulatedCost       currency       minPower       averagePower       maxPower     }   }   ]] else   res = nil end if res then   res, err = client:send(json.encode({     type = 'connection_init',     payload = {       token = token     }   }))   client:receive()   ts, tu = os.microtime()   res, err = client:send(json.encode({     id = ts .. '-' .. tu,     type = 'subscribe',     payload = {       query = query     }   }))   while true do     data, opcode, _, _, err = client:receive()     if data then       if opcode == ws.PING then         client:send(data, ws.PONG)       elseif opcode == ws.TEXT then         data = json.pdecode(data)         if type(data) == 'table' then           -- update objects here         end       end     else       log('receive failed: ' .. tostring(err))       break     end   end else   log('connection failed: ' .. tostring(err)) end if client then   client:close()   client = nil end

Hi, the new websocket.lua (or the new GraphQL transport protocol) seem to create a much more unstable connection than before. I get "Websocket receive failed: closed" 3-4 times per minute and I need to restart the resident script every 10 minute. Are the timeouts too short? Response code is 1006. I hope there will be a more stable approach to this  Smile
Reply
#38
Can you send your script with token via PM so we can test locally?
Reply
#39
After updating the firmware on my LM4 to 20230607, I have got problems with my Tibber real-time subscription.
* string: connection failed: Websocket Handshake failed: Invalid Sec-Websocket-Accept (expected 1LdxwNzFf64n31QWSHxXqslHgAI= got nil)

Is the websocket file in post #35 also the right one for the LM4?
Reply
#40
Can you send your token and home ID via PM?
Reply


Forum Jump: