Webhooks
Betaalde module
Deze module is te bestellen via de webshop. Lees meer over modules.
De webhook module biedt de mogelijkheid om gegevens uit de CEMM in andere systemen te gebruiken. De gegevens worden direct vanuit de CEMM naar de door jou ingestelde URL verzonden als HTTP POST bericht. De server ontvangt dan een JSON object met onder andere het CEMM ID en gegevens van meters. Je stelt zelf in welke gegevens worden verstuurd en hoe vaak dit gebeurt. De identiteit van de CEMM kan door de server worden geverifieerd via een API key in de URL of een header, of via een HMAC sleutel.
Webhook instellen
Ga naar 'Gereedschap' > 'Webhooks' en klik op 'Webhook toevoegen'. Er opent een popup met alle mogelijke opties.
- URL de volledige URL zoals
https://cemm.nl/api/v1/cemm-webhook?api_key=102b22e1afe363064c34ad2328f1f5814bbd727
- SSL verifiëren maakt het mogelijk SSL verificatie uit te zetten. Dit is handig voor het geval de CEMM niet overweg kan met het servercertificaat.
- Extra headers een lijst met extra headers. Zet iedere header op een nieuwe regel en scheid naam en waarde met een dubbele punt. Zie het volgende voorbeeld:
X-Mijn-Header: een bepaalde waarde nog-een-header: 123456-abc
- HMAC sleutel stel een sleutel in zodat de CEMM berichten kan ondertekenen (zie paragraaf HMAC). Klik op de knop om een sleutel te genereren.
- Interval stel in hoe vaak de CEMM gegevens stuurt. De opties zijn: 1 minuut, 5 minuten, 10 minuten, 15 minuten, ieder uur, iedere dag. Het gekozen interval wordt afgestemd op de werkelijke tijd. Een webhook met een interval van bijv. 15 minuten wordt uitgevoerd om bijv. 10:00, 10:15, 10:30, 10:45, etc..
- Expression een optionele expressie om te bepalen of de webhook wordt uitgevoerd. Zie de expressies pagina voor meer informatie. Met de knop kun je de expressie testen.
- Kanalen bij iedere meter horen één of meer kanalen. Een kanaal is bijvoorbeeld 'vermogen', 'energie' of 'voltage'. Kies zelf per meter welke kanalen worden meegestuurd. Bekijk hier een overzicht van veelvoorkomende kanalen.
- Onderwerpen geef aan welke waardes meegestuurd moeten worden, zie paragraaf 'Kanalen en onderwerpen' voor meer informatie
Kanalen en onderwerpen
De CEMM verzamelt heel veel verschillende gegevens, meestal heb je niet alles nodig, daarom kun je bij kanalen en onderwerpen exact aangeven waar je in bent geïnteresseerd. Niet alle combinaties van kanalen en onderwerpen bestaan, zie onderstaande tabel voor de mogelijke onderwerpen/combinaties.
Onderwerp | Sleutel | vermogen, flow, voltage, ... ( AVG ) |
energie, volume ( COUNTER , PULSE ) |
berekende data, tarieven ( CALCULATED , TARIFF ) |
---|---|---|---|---|
Actueel | realtime |
✅ | ❌ | ❌ |
Meterstand | reading |
❌ | ✅ | ❌ |
Vandaag | this/day |
✅ | ✅ | ✅ |
Deze maand | this/month |
✅ | ✅ | ✅ |
Dit jaar | this/year |
❌ | ✅ | ✅ |
Afgelopen minuut | last/minute |
✅ | ✅ | ✅ |
Afgelopen kwartier | last/15minutes |
✅ | ✅ | ✅ |
Afgelopen uur | last/hour |
✅ | ✅ | ✅ |
Gisteren | last/day |
✅ | ✅ | ✅ |
Afgelopen maand | last/month |
✅ | ✅ | ✅ |
Afgelopen jaar | last/year |
❌ | ✅ | ✅ |
Gegevens
Onderstaand voorbeeld is de JSON body van een webhook waarbij van de slimme meter (smartmeter-dsmr
) data van drie kanalen wordt verstuurd:
electric_energy_import_t1
electric_energy_import_t2
electric_power_import
En van drie onderwerpen: realtime
, reading
en last/day
.
{
"format": "basic-v1",
"cemm": 23000060,
"time": 1701869760,
"data": {
"smartmeter-dsmr": {
"electric_energy_import_t1": {
"realtime": null,
"reading": {
"time": 1701869700,
"value": 108446.491
},
"last/day": {
"time": 1701817140,
"value": 68.83699999999953
}
},
"electric_energy_import_t2": {
"realtime": null,
"reading": {
"time": 1701869700,
"value": 145843.763
},
"last/day": {
"time": 1701817140,
"value": 125.1480000000156
}
},
"electric_power_import": {
"realtime": {
"time": 1701869776,
"value": 4340
},
"reading": null,
"last/day": {
"time": 1701817140,
"value": 8076.414408153813
}
}
}
}
}
De time
in de root is het moment waarop de webhook is gestart. De time
bij ieder onderwerp is de tijd waarop die value
voor het laatst werd bijgewerkt.
De waardes van onderwerp realtime
van electric_energy_import_t1
en electric_energy_import_t2
zijn null
omdat energie geen realtime waarde heeft. Omgekeerd is de waarde van reading
van electric_power_import
leeg omdat een vermogen geen meterstand heeft. Andere onderwerpen kunnen ook op null
staan als de CEMM geen (recente) waarde heeft vastgelegd.
Daarnaast heeft een meter die vandaag is toegevoegd nog geen last/day
, dit geldt ook voor o.a. last/month
en last/year
. De waarde hiervoor zal dan ook null
zijn.
Handmatig uitvoeren
Tijdens het configureren van webhooks is het handig om de webhook meteen te kunnen testen. Klik rechtsboven in het blok van de webhook om het opties menu te openen en kies voor 'Nu uitvoeren'. Het webhook request wordt binnen enkele secondes uitgevoerd. Hierna zal de status verschijnen. (Een eventuele expressie wordt niet geëvalueerd. De expressie kan getest worden tijdens het bewerken van de webhook.)
Status
Per webhook worden de vijf laatste statussen bijgehouden. Deze zijn zichtbaar op de overzichtspagina. De status bevat het tijdstip, het ruwe HTTP request, de eerste 1000 karakters van het antwoord (indien beschikbaar) en de HTTP status code (indien beschikbaar).
Timeout
Ieder webhook request van de CEMM naar de server moet binnen 5 seconde worden voltooid, anders treedt er een timeout op. Dit is ingebouwd om de resources van de CEMM te beschermen. Als je meer tijd nodig hebt om het request te verwerken raden we aan om de binnenkomende gegevens in een achtergrondproces te verwerken. Op die manier kan het request snel voltooid worden.
HMAC
Door een HMAC sleutel in te stellen kan de CEMM de inhoud van HTTP berichten ondertekenen. Op de server kan de inhoud van het bericht worden geverifieerd. Hiervoor moet de sleutel vooraf gedeeld worden.
De HMAC hash wordt gemaakt op basis van de JSON POST body, de opgegeven sleutel en de hash functie SHA-512. De hash wordt vervolgens met het bericht meegestuurd in de header X-Signature
.
Hier volgen twee voorbeelden van het verifiëren van een HMAC:
python
import hashlib
import hmac
headers = {"X-Signature": "f686cf234fb863d761c9fa690d032e4259ac214936888102b22e1afe363064c34ad2328f1f5814bbd727dfd30280bc727730682a9534572a7a0e07f2d74c1d24"}
body = '{"format":"basic-v1","cemm":23000060,"time":1701869760,"data":{"smartmeter-dsmr":{"electric_energy_import_t1":{"realtime":{"time":1701869776,"value":108446.491}}}}}'
CEMM_HMAC_SECRET = "abcdef"
signature = hmac.new(CEMM_HMAC_SECRET.encode("utf-8"), body.encode("utf-8"), digestmod=hashlib.sha512)
is_valid = hmac.compare_digest(headers["X-Signature"], signature.hexdigest())
print(is_valid)
PHP
$headers = getallheaders();
$json = file_get_contents('php://input');
$secret = "abcdef";
$actual_hash = hash_hmac("sha512", $json, $secret);
$expected_hash = $headers["X-Signature"];
$is_valid = hash_equals($expected_hash, $actual_hash);
echo $is_valid;
Extra voorbeeld 1
Instellingen
Gekozen kanalen
Request
De keys onder data
hebben de volgende betekenis:
zon
enwater
verwijzen naar de twee meters (de keys zullen niet wijzigen als je achteraf de naam van de meter aanpast).- het volgende niveau zijn de keys van de kanalen. Voor
zon
zijn datelectric_energy_import
enelectric_power_import
, voorwater
zijn datvolume
enflow
. De kanalen worden bepaald door het type meter dat is aangesloten.- het volgende niveau zijn de onderwerpen die bij het instellen van de webhook zijn gekozen. In het voorbeeld
realtime
,reading
,this/day
,this/month
,last/hour
enlast/day
.
- het volgende niveau zijn de onderwerpen die bij het instellen van de webhook zijn gekozen. In het voorbeeld
- het volgende niveau zijn de keys van de kanalen. Voor
POST https://wiki.cemm.nl/
User-Agent: CEMM/1.4.1
Content-Type: application/json
Content-Length: 1214
{
"format":"basic-v1",
"cemm":23000051,
"time":1709131860,
"data":{
"zon":{
"electric_energy_import":{
"realtime":null,
"reading":{
"time":1709131680,
"value":19924.468354439534
},
"this/day":{
"time":1709131680,
"value":3.9249999999999874
},
"this/month":{
"time":1709131680,
"value":122.93600000000406
},
"last/hour":{
"time":1709128740,
"value":0.5410000000000004
},
"last/day":null
},
"electric_power_import":{
"realtime":{
"time":1709131795,
"value":258.34534176860836
},
"reading":null,
"this/day":{
"time":1709131680,
"value":248.43580553623997
},
"this/month":{
"time":1709131680,
"value":185.50925059014241
},
"last/hour":{
"time":1709128740,
"value":542.02723000405
},
"last/day":null
}
},
"water":{
"volume":{
"realtime":null,
"reading":{
"time":1709131680,
"value":-17.776000824174844
},
"this/day":{
"time":1709131680,
"value":0
},
"this/month":{
"time":1709131680,
"value":0
},
"last/hour":{
"time":1709128740,
"value":0
},
"last/day":null
},
"flow":{
"realtime":{
"time":1709131795,
"value":0.0
},
"reading":null,
"this/day":{
"time":1709131680,
"value":0.0
},
"this/month":{
"time":1709131680,
"value":0.0
},
"last/hour":{
"time":1709128740,
"value":0.0
},
"last/day":null
}
}
}
}
Extra voorbeeld 2
POST https://wiki.cemm.nl/
User-Agent: CEMM/1.4.1
Content-Type: application/json
Content-Length: 7605
{
"format":"basic-v1",
"cemm":23000060,
"time":1709132955,
"data":{
"smartmeter-dsmr":{
"electric_energy_import_t1":{
"realtime":null,
"reading":{
"time":1709132760,
"value":112116.728
},
"this/day":{
"time":1709132760,
"value":28.69999999999709
},
"last/day":{
"time":1709111695,
"value":33.40700000000652
},
"last/month":{
"time":1709111695,
"value":1905.0019999999931
}
},
"electric_energy_import_t2":{
"realtime":null,
"reading":{
"time":1709132760,
"value":149467.436
},
"this/day":{
"time":1709132760,
"value":36.89400000000023
},
"last/day":{
"time":1709111695,
"value":33.038999999989755
},
"last/month":{
"time":1709111695,
"value":1604.4279999999853
}
},
"electric_energy_export_t1":{
"realtime":null,
"reading":{
"time":1709132760,
"value":48138.559
},
"this/day":{
"time":1709132760,
"value":0.0
},
"last/day":{
"time":1709111695,
"value":0.0
},
"last/month":{
"time":1709111695,
"value":70.1730000000025
}
},
"electric_energy_export_t2":{
"realtime":null,
"reading":{
"time":1709132760,
"value":58934.256
},
"this/day":{
"time":1709132760,
"value":0.3080000000045402
},
"last/day":{
"time":1709111695,
"value":5.552999999999884
},
"last/month":{
"time":1709111695,
"value":19.868999999998778
}
},
"electric_power_import":{
"realtime":{
"time":1709132893,
"value":1120.0
},
"reading":null,
"this/day":{
"time":1709132760,
"value":4035.0677789363885
},
"last/day":{
"time":1709111695,
"value":2782.3546860572496
},
"last/month":{
"time":1709111695,
"value":3884.556879346602
}
},
"electric_power_export":{
"realtime":{
"time":1709132893,
"value":0.0
},
"reading":null,
"this/day":{
"time":1709132760,
"value":27.262426138338547
},
"last/day":{
"time":1709111695,
"value":237.6348107109882
},
"last/month":{
"time":1709111695,
"value":61.37119799971558
}
},
"tariff_import_low":{
"realtime":null,
"reading":null,
"this/day":{
"time":1709132760,
"value":0.0
},
"last/day":{
"time":1709111695,
"value":0
},
"last/month":{
"time":1709111695,
"value":0
}
},
"tariff_import_high":{
"realtime":null,
"reading":null,
"this/day":{
"time":1709132760,
"value":0.0
},
"last/day":{
"time":1709111695,
"value":0
},
"last/month":{
"time":1709111695,
"value":0
}
},
"tariff_export_low":{
"realtime":null,
"reading":null,
"this/day":{
"time":1709132760,
"value":0.0
},
"last/day":{
"time":1709111695,
"value":0
},
"last/month":{
"time":1709111695,
"value":0
}
},
"tariff_export_high":{
"realtime":null,
"reading":null,
"this/day":{
"time":1709132760,
"value":0.0
},
"last/day":{
"time":1709111695,
"value":0
},
"last/month":{
"time":1709111695,
"value":0
}
},
"electric_usage_power":{
"realtime":{
"time":1709132760,
"value":4468.5208092301145
},
"reading":null,
"this/day":{
"time":1709132760,
"value":6189.922344948609
},
"last/day":{
"time":1709111695,
"value":5002.196890784957
},
"last/month":{
"time":1709111695,
"value":4273.426488144169
}
},
"electric_usage_energy":{
"realtime":{
"time":1709132760,
"value":0.07724670409411191
},
"reading":null,
"this/day":{
"time":1709132760,
"value":104.47005627440683
},
"last/day":{
"time":1709111695,
"value":126.76181353760086
},
"last/month":{
"time":1709111695,
"value":4081.1401252780483
}
},
"voltage":{
"realtime":{
"time":1709132887,
"value":225.52859497070312
},
"reading":null,
"this/day":{
"time":1709132760,
"value":223.5587521518232
},
"last/day":{
"time":1709111695,
"value":225.55949949896805
},
"last/month":{
"time":1709111695,
"value":224.96433063381807
}
}
},
"eastron-sdm72d":{
"electric_energy_import":{
"realtime":null,
"reading":{
"time":1709132760,
"value":763.3569946289062
},
"this/day":{
"time":1709132760,
"value":16.0570068359375
},
"last/day":{
"time":1709111695,
"value":9.86297607421875
},
"last/month":{
"time":1709111695,
"value":229.64297485351562
}
},
"electric_energy_export":{
"realtime":null,
"reading":{
"time":1709132760,
"value":776.322021484375
},
"this/day":{
"time":1709132760,
"value":10.10601806640625
},
"last/day":{
"time":1709111695,
"value":18.46002197265625
},
"last/month":{
"time":1709111695,
"value":233.24900817871094
}
},
"electric_power_import":{
"realtime":{
"time":1709132887,
"value":0.0
},
"reading":null,
"this/day":{
"time":1709132760,
"value":986.9791716452116
},
"last/day":{
"time":1709111695,
"value":403.9844269462078
},
"last/month":{
"time":1709111695,
"value":180.90035580554255
}
},
"electric_power_export":{
"realtime":{
"time":1709132887,
"value":1779.3206787109375
},
"reading":null,
"this/day":{
"time":1709132760,
"value":626.618709519146
},
"last/day":{
"time":1709111695,
"value":757.3359520594064
},
"last/month":{
"time":1709111695,
"value":156.23585151712632
}
}
},
"zon-huawei":{
"electric_power_import":{
"realtime":{
"time":1709132889,
"value":1901.969482421875
},
"reading":null,
"this/day":{
"time":1709132760,
"value":1247.5659812210574
},
"last/day":{
"time":1709111695,
"value":1286.1269798498952
},
"last/month":{
"time":1709111695,
"value":194.55099319039567
}
},
"electric_energy_import":{
"realtime":null,
"reading":{
"time":1709132760,
"value":45211.69921875
},
"this/day":{
"time":1709132760,
"value":20.1640625
},
"last/day":{
"time":1709111695,
"value":31.1328125
},
"last/month":{
"time":1709111695,
"value":293.203125
}
},
"electric_energy_export":{
"realtime":null,
"reading":{
"time":1709132760,
"value":654.0829467773438
},
"this/day":{
"time":1709132760,
"value":0.09698486328125
},
"last/day":{
"time":1709111695,
"value":0.17401123046875
},
"last/month":{
"time":1709111695,
"value":4.9580078125
}
}
},
"laadpaal-1":{
"electric_power_import":{
"realtime":{
"time":1709132887,
"value":10.27
},
"reading":null,
"this/day":{
"time":1709132760,
"value":1365.5888912061178
},
"last/day":{
"time":1709111695,
"value":703.9443515482691
},
"last/month":{
"time":1709111695,
"value":118.73642770230836
}
},
"electric_power_export":{
"realtime":{
"time":1709132887,
"value":0
},
"reading":null,
"this/day":{
"time":1709132760,
"value":3.7539103232533884e-05
},
"last/day":{
"time":1709111695,
"value":0.0
},
"last/month":{
"time":1709111695,
"value":0.051200749131142975
}
},
"electric_energy_import":{
"realtime":null,
"reading":{
"time":1709132760,
"value":311.7
},
"this/day":{
"time":1709132760,
"value":22.129999999999995
},
"last/day":{
"time":1709111695,
"value":17.170000000000016
},
"last/month":{
"time":1709111695,
"value":179.72468750000002
}
},
"electric_energy_export":{
"realtime":null,
"reading":{
"time":1709132760,
"value":0.15
},
"this/day":{
"time":1709132760,
"value":0.0
},
"last/day":{
"time":1709111695,
"value":0.0
},
"last/month":{
"time":1709111695,
"value":0.2209995460510254
}
}
},
"sdm630-l1":{
"electric_power_l1":{
"realtime":{
"time":1709132889,
"value":1238.5511474609375
},
"reading":null,
"this/day":{
"time":1709132760,
"value":590.6241447116944
},
"last/day":{
"time":1709111695,
"value":303.3399274113759
},
"last/month":{
"time":1709111695,
"value":138.11782871744913
}
},
"electric_energy_import_l1":{
"realtime":null,
"reading":{
"time":1709132760,
"value":15389.361328125
},
"this/day":{
"time":1709132760,
"value":9.6044921875
},
"last/day":{
"time":1709111695,
"value":7.3720703125
},
"last/month":{
"time":1709111695,
"value":209.8681640625
}
},
"electric_energy_export_l1":{
"realtime":null,
"reading":{
"time":1709132760,
"value":0.0
},
"this/day":{
"time":1709132760,
"value":0
},
"last/day":{
"time":1709111695,
"value":0
},
"last/month":{
"time":1709111695,
"value":0
}
}
}
}
}