In de Junior IOT GPS Challenge dagen we externe partners uit om te koppelen aan de data van onze game kaart. Dit kan resulteren in nieuwe weergave vormen in jullie versie van de Digitale Tweeling. Het is interessant hoe dezelfde data er opeens heel anders uit kan zien!

Hier een paar tips om te ontdekken hoe jullie de koppelingen kunnen leggen.

Data bron vanuit JuniorIOTChallenge.nl

Onze data wordt betrekkelijk simpel opgeslagen. We hebben een demo ‘applicatie’ gemaakt in html, zodat je kunt zien hoe je via de http toegang zelf de data kunt ophalen: http://junioriotchallenge.nl/game/

In het script dataUpdater.js kan je bekijken hoe we door de data itereren. We zien bijvoorbeeld de volgende regels:

var dataJsonURL = “http://junioriotchallenge.nl/ttn_data/gamedata/nodes.json”;
var gridJsonURL = “http://junioriotchallenge.nl/ttn_data/gamedata/game.json”;

Overigens hebben we ook een 3d weergave beschikbaar: http://junioriotchallenge.nl/game/3d.html

Daarnaast duiken we dieper in de data middels de grafiek pagina: http://junioriotchallenge.nl/graph/

Https sources versus http

We draaien de Junioriotchallenge website als static website in AWS. Dit is ook waarom de opgeslagen files vanuit onze Amazon S3 opslag via deze route vrij toegankelijk zijn. De toegang via deze domain name werkt alleen met http.

Wanneer je jouw website draait in een https omgeving, dan heb je ook https toegang nodig tot deze data. Hiervoor hebben we nu toegang gemaakt met Amazon Cloudfront. via deze url:  https://dxyygehiqsmwy.cloudfront.net/game/  –> we zien wel dat onze scripts nog terugvallen naar een dataconnectie via http, waardoor onze viewer alleen werkt via http://junioriotchallenge.nl/game/

De index file nodes.json en nodes_yyyymmdd.json

We schrijven voor de nodes file een actuele versie een een versie met datum/tijd. Hierin vind je per device (node) de meest recente timestamp, gps locatie, enkele meetwaarden,de url naar het meest recente bericht en de url naar de log file. De logfile wordt tevens met een timestamp opgeslagen.

In dit laatst genoemde bestand zie je bijvoorbeeld in het laatste bericht van 2024-01-01 voor device ‘alkmaar2023-021-v3’ welke onderdeel is van de app ‘burgernetwerken-alkmaar-v2-v3’ de volgende tekst:

… “url”:”http://junioriotchallenge.nl/ttn_data/ttn_messages_partitioned/app=burgernetwerken-alkmaar-v2-v3/y=2024/m=01/d=01/2024-01-01 23.49.46.69878.txt”,”log”:”http://junioriotchallenge.nl/ttn_data/gamedata/node_log_app=burgernetwerken-alkmaar-v2-v3_alkmaar2023-021-v3_20240101.json”

Unieke datafile per bericht

Als voorbeeld datafile kan je kijken naar: http://junioriotchallenge.nl/ttn_data/ttn_messages_partitioned/app=burgernetwerken-alkmaar-v2-v3/y=2024/m=01/d=01/2024-01-01%2023.49.46.69878.txt

De naam van elk bestand is uniek en onvoorspelbaar. Daarom maken we twee verzamel files, die bij het binnenkomen van de berichten telkens worden geupdated:

  • De index files nodes.json en nodes_yyyymmdd.json waarmee je het meest recente bericht kunt vinden van elke device, om bijvoorbeeld de actuele locatie te bepalen.
  • Een log file per dag per device.

De logfile per device per dag

Als voorbeeld logfile kan je kijken naar: http://junioriotchallenge.nl/ttn_data/gamedata/node_log_app=burgernetwerken-alkmaar-v2-v3_alkmaar2023-021-v3_20240101.json

De naam van het bestand is opgebouwd vanuit de app naam ‘burgernetwerken-alkmaar-v2-v3’, device naam ‘alkmaar2023-021-v3’ en de datum 2024-01-01. In dit bestand zijn alle meetwaarden opgenomen.

… “alkmaar2023-021-v3_2024-01-01T00:27:39.693380059Z”:{“BME280_Hum”:55,”BME280_Press”:99470,”BME280_Temp”:16.4,”BME280internal_Hum”:0,”BME280internal_Press”:0,”BME280internal_Temp”:-1,”LAT”:”52.640807″,”LON”:”4.747736″,”Lux”:0.23,”Lux_mt”:254,”P”:994.7,”PM10″:27,”PM25″:14.6,”RH”:55,”T”:16.4,”Vbat”:4.07,”Vcomp”:0,”Vsupply”:5.1,”arduino_VCC”:0,”arduino_Vbat”:0,”arduino_tempCPU”:-100,”bytes_length”:115,
…”raw_dBc_min”:3247,”__url”:”http://junioriotchallenge.nl/ttn_data/ttn_messages_partitioned/app=burgernetwerken-alkmaar-v2-v3/y=2024/m=01/d=01/2024-01-01 00.27.39.69338.txt”,”__counter”:5271,”__time”:”2024-01-01T00:27:39.693380059Z”,”__time_ymd”:”20240101002739″},
“alkmaar2023-021-v3_2024-01-01T00:35:43.690752382Z”: …

Deze gegevens worden uitgelezen door de grafiekpagina om per meetwaarde een grafiek weer te kunnen geven: https://junioriotchallenge.nl/graph/?dateStart=20240101&dateEnd=20240101&application=app%3Dburgernetwerken-alkmaar-v2-v3&device=alkmaar2023-021-v3&values=all

Logfile als geojson

Vor elke logfile wordt (voorlopig) ook een geojson file opgeslagen, bijvoorbeeld: http://junioriotchallenge.nl/ttn_data/gamedata/node_log_app=burgernetwerken-alkmaar-v2-v3_alkmaar2023-021-v3_20240101.geojson

Dashboard file game.json en game_

Bij de ontvangst van elk databericht controleren we of de betreffende sensor deelneemt in het spel op de kaart. Historisch houden we de tussenstanden bij.

Voor elke spelnaam wordt historie opgeslagen. Bijvoorbeeld voor het spel in 2024 ‘AlkmaarGame2024Prep’:

Een van de eerste games in 2018 geeft een heerlijk eenvoudige datafile. Het spel heet ‘AlkmaarGame’, waarbij de url wordt gevormd als:

De historische files geven de mogelijkheid om terug te bladeren door de data van een specifiek spel, wellicht zelfs een animatie weer te geven over verschillende speldagen. Deze weergave hebben we nog niet ingebouwd.

De actuele stand van de meest actuele game vind je op: http://junioriotchallenge.nl/ttn_data/gamedata/game.json

Spel definitie in game.json

In game.json zie je de definitie van de spelgrenzen, en welke vlakken zijn ingevuld door de verschillende teams.

  • grid: een nested array met elke row een rij in de tabel, en daarin de vakjes per kolom, per vakje de meest recente meetgegevens en aan welk team het vakje toebehoort
  • game:
    • de hoekpunten van de boundingbox, en boxsize (in GPS graden)
    • de kleuren van de teams
    • de toewijzing van devices aan de teams

De inhoud:

{
    "grid": [
        null,
        [
            null,
            null,
            null,
            {
                "team": "groen",
                "time": "2018-06-01T06:39:10.528213162Z",
                "count": 1,
                "measuretime": "2018-06-01T06:39:10.528213162Z",
                "moist": 0,
                "pm25": -1,
                "pm10": -1,
                "temp": 0.04,
                "tempCPU": -9
            }
        ],
        [
            null,
            null,
            null,
            {
                "team": "groen",
                "time": "2018-06-01T06:38:38.536827572Z",
                "count": 2,
                "measuretime": "2018-06-01T06:38:54.577948495Z",
                "moist": 0,
                "pm25": -1,
                "pm10": -1,
                "temp": 0.03,
                "tempCPU": -9
            }
        ],
        [
            null,
            null,
            {
                "team": "groen",
                "time": "2018-06-01T06:38:22.526368437Z",
                "count": 1,
                "measuretime": "2018-06-01T06:38:22.526368437Z",
                "moist": 0,
                "pm25": -1,
                "pm10": -1,
                "temp": 0.01,
                "tempCPU": -9
            }
        ],
        null,
        null,
        [
            {
                "team": "groen",
                "time": "2018-06-01T09:51:30.555356917Z",
                "count": 1,
                "measuretime": "2018-06-01T09:51:30.555356917Z",
                "moist": 0,
                "pm25": -1,
                "pm10": -1,
                "temp": 3.81,
                "tempCPU": -9
            },
            {
                "team": "groen",
                "time": "2018-05-31T18:37:30.530946136Z",
                "count": 31,
                "measuretime": "2018-06-01T11:24:18.526042313Z",
                "moist": 0,
                "pm25": -1,
                "pm10": -1,
                "temp": 4.07,
                "tempCPU": 60
            }
        ],
        null,
        null,
        null,
        null,
        null,
        [
            {
                "team": "groen",
                "time": "2018-06-01T04:39:27.526267995Z",
                "count": 2,
                "measuretime": "2018-06-01T05:59:11.535545811Z",
                "moist": 0,
                "pm25": -1,
                "pm10": -1,
                "temp": 226.31,
                "tempCPU": -8
            }
        ],
        [
            {
                "team": "groen",
                "time": "2018-06-01T00:11:27.522364781Z",
                "count": 1,
                "measuretime": "2018-06-01T00:11:27.522364781Z",
                "moist": 0,
                "pm25": -1,
                "pm10": -1,
                "temp": 225.44,
                "tempCPU": -7
            }
        ]
    ],
    "score": {
        "groen": 7
    },
    "game": {
        "name": "AlkmaarGame",
        "time_start": "2018-03-24T00:00",
        "time_end": "2018-09-24T15:30",
        "lat_min": 52.6295,
        "lat_max": 52.63799,
        "lat_boxsize": 0.0005,
        "lng_min": 4.737,
        "lng_max": 4.7555,
        "lng_boxsize": 0.001,
        "node_team": {
            "lora32u4-nummer-vijf": "groen",
            "powerbank_tracker": "orange",
            "lora32u4-nummer-een": "groen",
            "murmellius001": "paars",
            "lora32u4-nummer-twee": "geel",
            "max001": "geel",
            "floris001": "geel",
            "ike-explorer2": "paars",
            "lora32u4-nummer-vier": "groen",
            "teamdata001": "groen",
            "team_data_plus_explorer": "groen",
            "sodaqexplorer-nummer-een": "blauw",
            "banaan1": "blauw",
            "banaan2": "blauw",
            "banaan007": "blauw",
            "michiel_e3": "rood",
            "other": "gray"
        },
        "team_color": {
            "rood": "FF0000",
            "orange": "FF8000",
            "geel": "FFFF00",
            "groen": "00FF00",
            "blauw": "0000FF",
            "paars": "FF00FF",
            "gray": "808080"
        }
    }
}

Afspraken over het gebruik

We publiceren onze data op Junioriotchallenge.nl als open data. Je mag deze data gebruiken, weergaves maken etcetera, zolang het resultaat ook beschikbaar is open en publiek gebruik. Wij publiceren graag een link naar jullie weergave/app/gebruik met een beknopte toelichting.

Het is aan te bevelen om in jouw deel van de dataverwerking er van uit te gaan dat we namen, hoekpunten, meetwaardes, spelnaam, aantallen en kleuren vanuit de json files lezen. Alles kan een volgende dag helemaal anders zijn. Zorg er daarom voor dat ook jouw software zich hier flexibel op inspeelt.

De data in meer detail

We beschrijven de dataflow en de details van de meetwaarden in meer detail op: https://junioriot.nl/burgernetwerken-data-explained/

Integratie via de dataflow vanaf onze TTN integratie

Met RIVM hebben we een integratie ingeregeld voor de data kaart ‘SamenMeten’. Omdat dit project bij RIVM steunt op de dataflow van The Things Network is deze integratie op stabiele wijze ingebouwd in de data pipeline.  https://www.rivm.nl/lucht/meten-modelleren-berekenen/samen-meten

De kaart met meetpunten vind je hier: https://samenmeten.rivm.nl/dataportaal/

 

Integratievoorbeeld met dagelijkse data retrieval in Digitale Tweeling Alkmaar

Gemeente Alkmaar heeft een dagelijkse ‘load’ van de data ingeregeld naar hun Azure data platform. Hiermee tonen ze de verschillende meetwaardes van de stadssensoren op de kaart.

Je bekijkt de kaart hier: https://digitale-tweeling-alkmaar.azurewebsites.net/digitale_tweeling

De integratie partner van Gemeente Alkmaar vertelt hier over de samenwerking met de gemeente: https://analyze.nl/project/smart-city-alkmaar/

Integratievoorbeeld met client script in browser

De integratiepartner ven Gemeente Alkmaar heeft een ‘Junior IOT game’ laag toegevoegd aan de digitale tweeling van gemeente Alkmaar. Hiermee kunnen gebruikers live meekijken met de game op de kaart.

De game kaart staat nu onder het kopje “overig”: https://dtp-alkmaar.azurewebsites.net/twin
Met deze link krijg je enkel de game in het menu: https://dtp-alkmaar.azurewebsites.net/twin?m=204,205

Andere voorbeelden

We hopen dat snel andere voorbeelden volgen via onze nieuwe integratie partners.