eniris.nl

Eniris standaarden

Op deze pagina kunt u onze standaarden vinden om data te publiceren via MQTT of aan te leveren als CSV-bestand via FTP(S). Voor variaties hierop, gelieve onderstaand contactformulier te gebruiken.

Introductie

De standaarden worden gebruikt voor het versturen van tijdsgerelateerde data. Vooraleer we ingaan op de details van het versturen van de data via de standaarden zelf, geven we kort een woordje uitleg over hoe deze data wordt opgeslagen in onze tijdreeksdatabase. Achter de schermen maken we gebruik van de Influx database. Dit systeem heeft als voordeel dat het geoptimaliseerd is voor het efficiënt opslaan en query-en van tijdsreeksen.

Eén bepaald aspect dat daarin een belangrijke rol speelt, en dat we binnen de context van de API moeten toelichten is het idee van zogenaamde ‘retention policies’. Data binnen een bepaalde retention policy wordt gedurende een zekere termijn opgeslagen. Zodra deze voorbij is, wordt deze automatisch gerouleerd uit de database. De Eniris retention policies hebben namen die aangeven hoe frequent een bepaalde meetwaarde die binnen die policy wordt opgeslagen maximaal updatet. Zo hebben we volgende retention policies:

				
					 'rp_one_s' (één seconde)
 'rp_one_m' (één minuut)
 'rp_ten_m' (tien minuten)
 'rp_one_h' (één uur)
 'rp_six_h' (zes uren)
				
			

Data die wordt opgeslagen in een retention policy met een hoge frequentie wordt binnen de 10 dagen verwijderd, terwijl de data binnen een retention policy met een lagere frequentie tientallen jaren bewaard wordt. De motivatie is eenvoudig: de hoeveelheid data die per reeks wordt opgeslagen in de database is het product van de frequentie van het meetpunt en de duur dat data wordt gestockeerd. Door de duur te beperken, beperken we de hoeveelheid data per meetpunt. Vooraleer frequente data uitgerouleerd wordt, aggregeren we deze binnen een retention policy met een lagere frequentie (zodat het niet zo is dat een gebruiker met frequente metingen die enkele dagen terugklikt in zijn geschiedenis plots geen waardes meer terugvindt). Dit hele verhaal verklaart waarom, als u data via de standaarden doorgeeft, een indicatie dient te geven van de frequentie van de updates per reeks door de retention policy expliciet op te geven.

Tijdsreeksen

In de voorgaande paragraaf hebben we informeel over een reeks gesproken, maar we hebben tot nog toe niet heel duidelijk uitgelegd wat we daarmee precies bedoelen. Daarom geven we in deze alinea meer info over hoe data binnen een retention policy wordt opgeslagen.

Binnen elke retention policy zijn er een reeks metingen (measurements in Influx terminologie). Zo een meting kan u zich voorstellen als een tabel in Excel (ééntje met niet te veel kolommen, maar mogelijks zéér veel rijen), of als een SQL tabel. Binnen een measurement zijn er drie soorten kolommen.

De eerste kolom is eenvoudig te begrijpen: deze geeft per rij (een rij noemen we binnen deze context een meetpunt) een tijdsstip weer. Dit tijdsstip hoeft niet uniek te zijn: er kunnen meerdere meetpunten zijn die dezelfde timestamp delen.
De tweede kolom wordt de ’tag set’ genoemd. Dit is een groep van kolommen die zo is, dat als we binnen één measurement kijken naar de waardes van deze kolommen, dat deze kolommen uniek een specifieke meter beschrijven die een beperkt aantal zaken meet. Misschien is dit wat onduidelijk, dus daarom een voorbeeldje: stel dat we zonneinstallaties monitoren, en elke installatie heeft één of meerdere inverters met nummers 0 tot N-1 waarvan we telkens het actuele vermogen meten, en de extra energieproductie sinds onze laatste update. In zo een situatie zal onze tabel met inverter data een kolom “installatieId” bevatten, en een kolom “inverterId”, die samen uniek een inverter beschrijven (voor de SQL-kenners: denk aan een aggregate key). Per inverter hebben we dan nog twee waardes die we willen stockeren: het vermogen en de energie delta.
Dit is waar ons laatste type kolom de kop op steekt: de velden. Deze bevatten de eigenlijke meetwaardes, wat afhankelijk van de context een float kan zijn, een int, een boolean, of een string. Binnen ons voorbeeldje hebben we dus twee velden die samen de zogenaamde ‘veld set’ vormen: actualPower en energyDelta.

Nu kunnen we terug itereren naar de definitie van een reeks, waarover we het zo uitgebreid hadden in de vorige alinea: een reeks is een unieke combinatie van een measurement + waardes voor alle tags binnen een measurement + één veld. Binnen het voorbeeld zou een voorbeeld van een reeks kunnen zijn: alle actualPower waardes voor een inverter met id 0 in een installatie met naam ‘pvEniris’. Als u al de waardes binnen een specifieke numerieke reeks uit de database haalt en visualiseert, dan krijgt u normaal gezien een curve die logisch steek houdt (in het voorbeeld het actueel vermogen van een welbepaalde inverter over tijd). Hoe vaak zo’n curve geüpdatet wordt, is dus waar u naar moet kijken bij het kiezen van de retention policy.
We zien nu ook waarom er soms voor één tijdsstip meerdere meetpunten kunnen zijn: in het voorbeeld zouden deze punten overeen komen met updates van verschillende inverters voor hetzelfde tijdsstip. Het is wel zo dat binnen één reeks er voor één tijdsstip hoogstens één waarde is: als we twee keer wegschrijven wat de actualPower waarde is voor de inverter met id 0 in een installatie met naam ‘pvEniris’ op 9 april 2021 op de middag, dan zal de tweede geschreven waarde automatisch de eerdere waarde overschrijven.

Als deze alinea wat onduidelijk is, kan deze link nuttig zijn: https://docs.influxdata.com/influxdb/v1.8/concepts/glossary/

MQTT-standaard

Nu we inzicht hebben in hoe de data weggeschreven wordt in influx, en op dat vlak de juiste keuzes kunnen maken, is de eigenlijke implementatie van de MQTT standaard een koud kunstje. Als data geëncrypteerd verstuurd dient te worden, dan kan de data verstuurd worden via MQTT over TLS. Hiervoor dient u te connecteren met ‘mqtt.eniris.be’ (om de certificaten correct te valideren moet de domeinnaam gebruikt worden, niet het ip adres) op poort 8883. Als een toestel dit niet ondersteunt, kan een ongeëncrypteerde verbinding ook, via poort 1883. Hiervoor kan u connecteren met mqtt.eniris.be, of 188.166.18.198

Wij voorzien voor elk van uw toestellen een unieke gebruikersnaam en een wachtwoord combinatie om te authenticeren met de server. Voor een toestel kan u na aanmelden publiceren naar eender welk topic van de vorm:

				
					standard1/$rp/$mea/$user
				
			

Hierbij is $rp een retention policy, zoals hogerop beschreven, $mea is een naam voor een measurement (dit kan u vrij kiezen, we verzoeken enkel om camelCase te gebruiken bij het definiëren van measurement names). $user is de user name waarmee u inlogt.

Elk bericht codeert één meetpunt en is een json string van de vorm:

				
					{"time": $ts, "extraTags": $extraTags, "fields": $fields}
				
			

Waarbij $ts een unix timestamp is (in secondes). De variabele $extraTags is een dictionary (met key en value van het type string), waaraan steeds een element toegevoegd zal worden met als key “id” en als waarde de username. Het aldus resulterende dictionary specificeert de tag set van het meetpunt. Als er geen extra tags nodig zijn, kan deze variabele weggelaten worden. Merk op dat het niet zinvol is om aan extraTags een element met key “id” toe te voegen, aangezien de waarde daarvan steeds met de username zal overschreven worden. Tot slot is er $fields, een dictionary die de velden specificeert.

Extra informatie over het coderen van de velden vindt u in een voorbeeld python file (de enige dependency is paho-mqtt). Deze kunt u bij ons opvragen door onderstaand formulier in te vullen.

Data reliability

Om de kwaliteit van data mee te geven kan er gewerkt worden met een extraTag ‘reliable’. Deze dient ’true’ of ‘false’ te zijn en van het type string.

Controleren of data goed toekomt

Via MQTT explorer kunt u verbinding maken met onze broker. MQTT explorer is hier te downloaden: http://mqtt-explorer.com/
Als u MQTT explorer heeft geïnstalleerd dant dient u eerst een verbinding tot stand te brengen. Selecteer “+” om een nieuwe verbinding toe te voegen.

 

CSV-standaard

Op basis van ons nieuw verworven inzicht in hoe de data bewaard wordt in influx, is het begrijpen en opstellen van een standaard CSV file voor de hand liggend.

De CSV bestanden overzetten naar de server kan via FTP, of het veiligere FTPS. Voor elk van u toestellen voorzien we een unieke gebruikersnaam en een wachtwoord combinatie om te authenticeren met de server.
Na login dienen bestanden geüpload te worden naar de map ‘files’. Zodra een bestand verwerkt is, zal dit automatisch uit deze map verwijderd worden.

De bestandsnaam kan vrij gekozen worden, maar het is belangrijk om te voorkomen dat een nog niet verwerkt bestand overschreven wordt door een bestand met andere, nieuwe data.
Daarom raden we aan om de naam van uw bestanden zo op te stellen dat deze uniek is. Een typische manier om dit te realiseren is door een oplopend nummer of het precieze tijdsstip van upload in de bestandsnaam te verwerken.

In het CSV bestand wordt een ‘;’ gebruikt als scheidingsteken tussen de verschillende kolommen. Een newline wordt geëncodeerd door middel van een ‘\n’ of ‘\r\n’ (de standaardmethode op de meeste besturingssystemen).
De inhoud van elke cel dient tussen dubbele aanhalingstekens geplaatst te worden. Dit geeft aanleiding tot enkele randgevallen:

  • Als de inhoud van een cel een ‘”‘ bevat, wordt dit gecodeerd als ‘\”‘
  • Als de inhoud van de cel een ‘\’ teken bevat, wordt dit gecodeerd als ‘\\’ Deze codering wordt standaard toegepast door de meeste spreadsheet programma’s.

Het CSV bestand zelf bestaat een een opeenvolging van groepen lijnen die meetpunten encoderen die binnen één measurement en retention policy moeten opgeslagen worden. Hieronder wordt een voorbeeld gegeven van zo één groep van lijnen.

Een lijngroep heeft steeds 5 rijen van headers, waarna de meetpunten zelf volgen.

De headers zijn gespecificeerd als volgt:

				
					"retention policy";"rp_one_m"

				
			
  • De eerste lijn specificeert de retention policy van de meetpunten in de lijngroep. De eerste cel bevat de tekst “retention policy”, en de tweede cel geeft de retention policy zelf aan.
				
					
"measurement";"C"
				
			
  • De tweede lijn specificeert het measurement van de meetpunten in de lijngroep. De eerste cel bevat de tekst “measurement”, en de tweede cel bevat de naam van het measurement (dit kan u vrij kiezen, we verzoeken enkel om camelCase te gebruiken bij het definiëren van measurement names).
				
					"time";"subId";"caloricEnergy";"caloricEnergyCool";"temperatureFlow";"temperatureReturn"

				
			
  • De derde lijn benoemt de kolommen van de meetpunten. De eerste kolom noemt steeds “time”, de overige kolommen geven de namen aan van de tags en velden van elk van de meetpunten.
				
					;"tag";"field";"field";"field";"field"
				
			
  • De vierde lijn geeft voor elk van de niet-time kolommen aan of deze een tag of een veld is.
				
					;;"float";"float";"float";"float"
				
			
  • De vijfde lijn specificeert voor elk van de velden wat het datatype is van deze velden (tags wordt steeds als strings opgeslagen, dus voor deze wordt geen type aangegeven). Mogelijke datatypes zijn: ‘float’ (kommagetal), ‘integer’ (geheel getal), ‘string’ (tekst) en ‘boolean’ (booleaanse waarde).
 
De meetpunten zelf worden gecodeerd als volgt:
				
					"1621432700000000000";"C10";"1520";"1200";"41.56";"41.16"
"1621432699000000000";"C9";"874";"2233";"12.54";"16.6"
"1621432698000000000";"C8";"6724";"10630";"21.81";"21.82"
"1621432697000000000";"C7";"19122";"5801";"15.31";"18.95"
				
			
 
  • De time kolom bevat de unix tijd in nanosecondes (i.e. de het aantal nanosecondes sinds 1 januari 1970 in de UMT tijdszone)
  • De tags worden als strings verwerkt, waarbij de ‘”‘ en ‘\’ karakters gecodeerd worden als ‘\”‘ resp. ‘\\’. Er wordt automatisch aan alle meetpunten een extra tag ‘id’ toegevoegd, met als waarde de gebruikersnaam die gebruikt werd om met de server te connecteren. Als voor een bepaald meetpunt een tag niet gedefinieerd is, is het belangrijk dat de cel *volkomen* leeg gelaten wordt, d.w.z. de separators (of de separator en de newline) volgen onmiddellijk op elkaar; een opeenvolging van twee aanhalingstekens tussen de separators wordt geïnterpreteerd als een ledige string.
  • Velden van het string datatype worden verwerkt alsof het tags zijn.
  • Velden van het float of integer datatype dienen geldige kommgetallen (waarbij ‘.’ gebruikt wordt als decimaal teken), resp. gehele getallen te bevatten. Als een veld niet gedefinieerd is kunnen de separators elkaar direct opvolgen, of mag de inhoud van de cel de ledige string zijn.
  • Velden van het boolean datatype kunnen de waarde “true”, “True”, “T” of “1” aannemen om ‘waar’ te coderen, en “false”, “False”, “F” of “0” om ‘vals’ te coderen. Als een veld niet gedefinieerd is kunnen de separators elkaar direct opvolgen, of mag de inhoud van de cel de ledige string zijn.
 
 
Volledig voorbeeld van een CSV-bestand:
				
					
"retention policy";"rp_one_m"
"measurement";"C"
"time";"subId";"caloricEnergy";"caloricEnergyCool";"temperatureFlow";"temperatureReturn"
;"tag";"tag";"field";"field";"field";"field"
;;"float";"float";"float";"float"
"1621432700000000000";"C10";"1520";"1200";"41.56";"41.16"
"1621432699000000000";"C9";"874";"2233";"12.54";"16.6"
"1621432698000000000";"C8";"6724";"10630";"21.81";"21.82"
"1621432697000000000";"C7";"19122";"5801";"15.31";"18.95"
				
			
  
Tweede voorbeeld van een CSV-bestand:
				
					
"retention policy";"rp_one_m"
"measurement";"C"
"time";"subId";"caloricEnergy";"caloricEnergyCool";"temperatureFlow";"temperatureReturn"
;"tag";"field";"field";"field";"field"
;;"float";"float";"float";"float"
"1621432700000000000";"C10";"1520";"1200";"41.56";"41.16"
"1621432699000000000";"C9";"874";"2233";"12.54";"16.6"
"1621432698000000000";"C8";"6724";"10630";"21.81";"21.82"
"1621432697000000000";"C7";"19122";"5801";"15.31";"18.95"


"retention policy";"rp_ten_m"
"measurement";"W"
"time";"subId";"heatEnergy";"totalFlow"
;"tag";"tag";"field";"field";"field"
;;"float";"float";"float";"float"
"1621432700000000000";"W10";"1520";"1200";"41.56"
"1621432699000000000";"W9";"874";"2233";"12.54"
"1621432698000000000";"W8";"6724";"10630";"21.81"
"1621432697000000000";"W7";"19122";"5801";"15.31"
				
			

Aanvraagformulier

Contacteer ons