Hold oversikt over strømforbruket med data fra Tibber

Jeg skaffet en Tibber Pulse som jeg koblet opp i sikringsskapet. Den måler strømforbruket hvert 2.5 sekunder og jeg kan få tak i de dataene. Jeg kan holdeøye med forbruket og også se dette sammen med fremtidig strømpris og temperatur. Jeg seteter opp et dashboard i Grafana. Serversystemene kjøres på en linux server jeg har gående. Nøyaktig det samme oppsettet skal kunne kjøres på de fleste nyere linux systemer som bruker systemd (inkludert rasbian på rasberry pi). Dersom du bruker et system som ikke har systemd, vil alt fungere med unntak av oppsettet for autostart. For å hente inn værvarsel,se http://sickel.net/blogg/?p=1923.

Inntil videre tar jeg omveien via Tibbers skyløsning. PyTibber gir et oppsett som gjør dette enkelt. Da kan data hentes inn enkelt etter et “pip install tibber”:

#!/usr/bin/python3

import asyncio
import aiohttp
import tibber
import json  

ACCESS_TOKEN = "Tibber access token"
FILE='/var/www/html/homelog2/pulse.json'
# Can be picked up by my webserver

async def _callback(pkg):
    data = pkg.get("data")
    if data is None:
        return
    pulsedata=data.get("liveMeasurement")
    with open(FILE,'w') as outfile:
        json.dump(pulsedata,outfile)
    

async def run():
    async with aiohttp.ClientSession() as session:
        tibber_connection = tibber.Tibber(ACCESS_TOKEN, websession=session)
        await tibber_connection.update_info()
    home = tibber_connection.get_homes()[0]
    await home.rt_subscribe(_callback)

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    asyncio.ensure_future(run())
    loop.run_forever()

Dette scriptet henter data fortløpende og lagrer det som en json fil i en katalog som serves av en http-server. Jeg ønsker at dette skal kjøre kontinuerlig og starte automatisk om serveren starter om, så jeg har kopiert pythonscriptet til /usr/local/bin og definert en service-fil:

[Unit]
Description=Tibber pulse collector
After=network-online.target
Wants=network-online.target systemd-networkd-wait-online.service
StartLimitIntervalSec=500
StartLimitBurst=5

[Service]
Type=simple
ExecStart=/usr/local/bin/tibberpulse.py
User=morten
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

Dette er lagret som /etc/systemd/system/tibberpulse.service. For å få dette til å kjøre, må man fortelle systemd at det finnes nye service-filer, så starte servicen og til slutt sette at den skal startes med reboot. Dette er følgende kommandoer:

sudo systemctl daemon-reload
sudo systemctl start tibberpulse.service
sudo systemctl enable tibberpulse.service

Da kan man skjekke at servicen kjører:

morten@sjest:~(master)$ systemctl status tibberpulse.service 
● tibberpulse.service - Tibber pulse collector
     Loaded: loaded (/etc/systemd/system/tibberpulse.service; enabled; vendor preset: enabled)
     Active: active (running) since Sat 2021-12-18 17:27:59 CET; 5 days ago
   Main PID: 120163 (tibberpulse.py)
      Tasks: 2 (limit: 19086)
     Memory: 28.3M
        CPU: 6min 24.729s
     CGroup: /system.slice/tibberpulse.service
             └─120163 /usr/bin/python3 /usr/local/bin/tibberpulse.py

Dec 22 18:02:10 sjest tibberpulse.py[120163]:   File "/home/morten/.local/lib/python3.9/site-packages/graphql_subsc>
Dec 22 18:02:10 sjest tibberpulse.py[120163]:     msg = await asyncio.wait_for(self.websocket.recv(), timeout=30)
Dec 22 18:02:10 sjest tibberpulse.py[120163]:   File "/usr/lib/python3.9/asyncio/tasks.py", line 481, in wait_for
Dec 22 18:02:10 sjest tibberpulse.py[120163]:     return fut.result()
Dec 22 18:02:10 sjest tibberpulse.py[120163]:   File "/home/morten/.local/lib/python3.9/site-packages/websockets/le>
Dec 22 18:02:10 sjest tibberpulse.py[120163]:     await self.ensure_open()
Dec 22 18:02:10 sjest tibberpulse.py[120163]:   File "/home/morten/.local/lib/python3.9/site-packages/websockets/le>
Dec 22 18:02:10 sjest tibberpulse.py[120163]:     raise self.connection_closed_exc()
Dec 22 18:02:10 sjest tibberpulse.py[120163]: websockets.exceptions.ConnectionClosedError: no close frame received >
Dec 23 00:08:01 sjest tibberpulse.py[120163]: No data, reconnecting.

Den har feilet noen ganger, men har blitt startet opp igjen og har kjørt uten problemer i halvannet døgn. (Feilen 22 skyldes sannsynligvis at jeg koblet om en nettverkskabel, den burde vært håndtert med en try – except)

Jeg vil også ha inn data om nåværend og fremtidig strømpris. For å gjøre ting enkelt, henter jeg inn dette en gang i timen med crontab (fyll inn egen Tibber-token):

1 * * * * /usr/bin/curl -H "Authorization: Bearer Tibber-token" -H "Content-Type: application/json" -X POST -d '{"query":"{ viewer { homes { currentSubscription{ priceInfo{ current{ total energy tax startsAt } today { total energy tax startsAt } tomorrow { total energy tax startsAt } } } } } }"}' https://api.tibber.com/v1-beta/gql > /var/www/html/homelog2/cost.json

I grafana lager jeg tre datakilder basert på JSON-API som henter inn pulse.json, cost.json og weather.json fra webserveren min. For viserinstrumenetene, er det bare spørring etter et parameter,som eksempel for aktult effekttrekk:

De to andre blir litt mer kompliserte, for aktuell strømpris er Field
$.data.viewer.homes[*].currentSubscription.priceInfo.current.total

og for temperatur er det
$.properties.timeseries[*].data.instant.details.air_temperature

For tidsserien må jeg både hente inn tidspunkt og verdi:

Den øverste henter (resten av) dagens strømpriser, den midterste henter temperaturvarsel (JSON API er et navn jeg satt på datakilden før jeg forsto hvordan den navningen fungerer. Hadde jeg satt det opp nå, ville den hett “metdata”). Den siste henter morgendagens strømpriser.

For klipp og lim:

$.data.viewer.homes[].currentSubscription.priceInfo.today[].startsAt
$.data.viewer.homes[*].currentSubscription.priceInfo.today[*].total
$.properties.timeseries[*].time
$.properties.timeseries[*].data.instant.details.air_temperature
$.data.viewer.homes[*].currentSubscription.priceInfo.tomorrow[*].startsAt
$.data.viewer.homes[*].currentSubscription.priceInfo.tomorrow[*].total

Dersom man av en eller annen grunn ønsker seg strømprisen uten avgifter, bruk “energy” i stedet for “total” i de aktuelle felten

This entry was posted in Diverse. Bookmark the permalink.