Een industrieel IoT-platform bouwen met .NET en Azure
6 feb 2026
Gedurende vijf jaar bij HUSS B.V. heb ik een industrieel IoT-platform ontworpen en gebouwd dat data verzamelt van productieapparatuur, deze in near-real-time verwerkt en presenteert via rapportagedashboards. Wat begon als een prototype groeide uit tot een productiesysteem dat meerdere productieklanten bedient. Hier is wat ik onderweg heb geleerd.
Hoe ziet een industrieel IoT-platform eruit?
Een industrieel IoT-platform verbindt fysieke machines op een fabrieksvloer met software die hun data bruikbaar maakt. In de kern is het een pipeline: apparaten genereren telemetrie, die telemetrie wordt opgenomen en verwerkt, en vervolgens opgeslagen en gevisualiseerd. Het doel is om productieoperators en managers inzicht te geven in apparatuurprestaties, productieoutput en afwijkingen — zonder dat ze de fabrieksvloer op hoeven.
Ons platform bij HUSS volgde een gelaagde architectuur:
- Device layer — PLC’s en sensoren op productieapparatuur die data pushen via MQTT of HTTP
- Ingestion layer — Azure-gehoste endpoints die telemetrie ontvangen, authenticatie en throttling afhandelen
- Processing layer — .NET Core workers die binnenkomende data normaliseren, valideren en verrijken
- Storage layer — SQL Server voor gestructureerde telemetrie en metadata
- Dashboard layer — Blazor Server-applicatie met realtime en historische rapportageviews
Elke laag was onafhankelijk deploybaar. Die scheiding was er niet vanaf dag een — die ontstond na het eerste jaar toen we ontdekten dat het koppelen van ingestion aan processing knelpunten veroorzaakte tijdens piekbelasting.
De juiste Azure-services kiezen voor IoT
Het kiezen van de juiste ingestion- en messagingservices was een van de vroegste — en meest bepalende — beslissingen. Azure biedt meerdere opties, en de trade-offs zijn niet altijd duidelijk totdat je midden in het productieverkeer zit.
Zo hebben wij ze beoordeeld:
| Service | Sterke punten | Beperkingen | Ons oordeel |
|---|---|---|---|
| Azure IoT Hub | Device management, per-device auth, twin state, cloud-to-device messaging | Hogere kosten op schaal, complexiteit voor scenario’s met alleen telemetrie | Gebruikt voor apparaten die bidirectionele communicatie nodig hebben |
| Azure Event Hubs | Hoge doorvoer, eenvoudig producer-model, kosteneffectief voor telemetry-only streams | Geen device management, geen cloud-to-device messaging | Primair ingestiepad voor high-volume telemetrie |
| Custom REST endpoints | Volledige controle, makkelijk te debuggen, past bij bestaande device-firmware | Je bent zelf verantwoordelijk voor betrouwbaarheid, schaling en backpressure | Gebruikt voor legacy-apparaten met HTTP-only firmware |
We kwamen uit op een hybride aanpak. Event Hubs handelde het gros van de telemetrie-ingestie af omdat de meeste apparaten alleen data upstream hoefden te pushen. IoT Hub was gereserveerd voor apparaten waar we firmware-updates of remote configuratie nodig hadden. Een handvol oudere machines kon alleen plain HTTP POST, dus draaiden we een kleine .NET Core API voor Event Hubs voor die gevallen.
De les: kies niet standaard de service met de meeste features. Stem de service af op de capaciteiten van het apparaat en het communicatiepatroon.
Waarom Blazor voor het dashboard
We kozen Blazor Server voor het rapportagedashboard omdat het ons een rijke, interactieve UI liet bouwen terwijl de hele stack in C# en .NET bleef. Voor een klein team — soms alleen ik — was die consistentie belangrijker dan welke framework-benchmark dan ook.
Blazor Server werkte goed voor ons specifieke geval omdat:
- Realtime updates via SignalR kwamen bijna gratis mee. Wanneer nieuwe telemetrie binnenkwam, weerspiegelden dashboards dit binnen seconden zonder polling.
- Server-side rendering betekende dat we geen API’s hoefden bloot te stellen voor de frontend. Het dashboard bevroeg de database rechtstreeks via services.
- Gedeelde models tussen de backend-verwerkingspipeline en het dashboard elimineerden een hele klasse van serialisatiebugs.
De trade-off was gevoeligheid voor latency. Blazor Server vereist een persistente WebSocket-verbinding, en als het netwerk van de gebruiker haperde, bevroor de UI. Voor fabrieksvloerkiosken op bekabeld ethernet was dit prima. Voor managers die dashboards checkten via hotel-Wi-Fi — minder prima. We losten het op met reconnectie-logica en een laadstatus die eerlijk was over wat er gebeurde.
Zou ik vandaag opnieuw Blazor kiezen? Voor een intern of B2B-dashboard met een bekend gebruikersbestand, ja. Voor een publieksgericht consumentenproduct zou ik serieuzer kijken naar een ontkoppelde SPA.
Omgaan met onbetrouwbare apparaatconnectiviteit
Productieomgevingen zijn vijandig voor netwerkverbindingen. Metalen behuizingen, elektromagnetische interferentie van zware machines en faciliteiten waar het trekken van nieuwe kabels een inkoopproces van zes maanden is. Ontwerpen voor intermitterende connectiviteit was geen optie — het was de basisaanname.
Onze aanpak had drie pijlers:
- Lokale buffering op apparaten. Elke device-agent sloeg telemetrie lokaal op en stuurde deze door wanneer de verbinding hersteld was. Berichten bevatten timestamps van de apparaatklok, zodat laat binnenkomende data in het juiste tijdvenster werd geplaatst.
- Idempotente ingestie. Elk telemetriebericht had een uniek ID. De ingestion layer dedupliceerde bij het invoegen, zodat opnieuw afgespeelde berichten van reconnecterende apparaten geen aggregaten corrumpeerden.
- Gezondheidsmonitoring met afwezigheidsdetectie. In plaats van alleen te alerteren op slechte data, alerteerden we op ontbrekende data. Als een apparaat dat normaal elke 30 seconden rapporteert 5 minuten stil was, triggerde dat een onderzoek.
De afwezigheidsdetectie bleek waardevoller dan welke anomaliedetectie op de data zelf dan ook. Een machine die rare getallen produceert is zorgwekkend. Een machine die geen getallen produceert betekent meestal dat er echt iets mis is.
Waarom SQL Server voor time-series data
Dit is de beslissing die de meeste wenkbrauwen doet fronsen. Time-series databases zoals InfluxDB of TimescaleDB bestaan precies voor dit soort workloads. Wij kozen toch voor SQL Server omdat het al in de stack zat, het team het goed kende en het voor onze datavolumes meer dan adequaat presteerde.
Ons telemetrievolume lag in de tientallen miljoenen rijen per maand — significant maar niet enorm naar time-series-maatstaven. Met de juiste indexering, tabelpartitionering op datum en een geplande job die ruwe data oprolde naar uur- en dagaggregaten, handelde SQL Server queries over maanden aan data af in minder dan een seconde.
De praktische voordelen waren reeel:
- Vertrouwde tooling. Entity Framework Core, SQL Server Management Studio en goed begrepen backup- en herstelprocedures.
- Joins over domeinen heen. Telemetriedata naast device-metadata, klantconfiguratie en gebruikersvoorkeuren in dezelfde database — geen cross-systeem queries.
- Operationele eenvoud. Een database-engine om te monitoren, patchen en tunen in plaats van twee.
Als ons volume 10x hoger was geweest of als we sub-seconde queries over jaren aan ruwe data nodig hadden, was een dedicated time-series store de juiste keuze geweest. Ken je datavolumes voordat je naar gespecialiseerde infrastructuur grijpt.
Opschalen van prototype naar productie
Het prototype was een enkele Azure App Service die alles draaide — ingestie, verwerking, database-toegang en het dashboard. Het werkte voor drie apparaten. Het werkte niet voor dertig.
De grootste veranderingen van prototype naar productie gingen niet over code — ze gingen over operations. Specifiek:
- Infrastructure-as-code met ARM templates verving handmatige Azure Portal-configuratie. Elke omgeving — dev, staging, productie — was reproduceerbaar vanuit een template. Geen “het werkt in mijn omgeving” meer wanneer het antwoord een ontbrekende app setting was.
- CI/CD-pipelines in Azure DevOps automatiseerden build, test en deployment. Pull request-builds vingen problemen af voordat ze een gedeelde omgeving bereikten. Release-pipelines promoveerden door stages met goedkeuringsgates.
- Gestructureerde logging en Application Insights vervingen console.log-achtig debuggen. Wanneer de data van een apparaat niet meer in dashboards verscheen, konden we het volledige pad traceren van ingestie via verwerking naar opslag en precies vinden waar het misging.
- Separate schaling voor ingestie en dashboard. De ingestion workers schaelden op basis van Event Hub-partitie-lag. Het Blazor-dashboard schaalde op basis van actieve WebSocket-verbindingen. Ze hadden compleet verschillende belastingspatronen en hadden onafhankelijke schalingsregels nodig.
Het opzetten van dit operationele fundament kostte echte tijd — weken, geen dagen. Maar elk geinvesteerd uur betaalde zich tienvoudig terug wanneer er om 2 uur ‘s nachts iets misging en de monitoring ons precies vertelde wat en waar.
Lessen geleerd over vijf jaar
Vijf jaar werken aan een enkel platform leert je dingen die geen greenfield-project kan:
- Schema-migraties op live telemetrietabellen zijn angstaanjagend. Plan je datamodel vanaf dag een met uitbreidbaarheid in gedachten. We voegden vroeg een JSON-metadatakolom toe die ons tientallen schemawijzigingen later bespaarde.
- Device-firmware is het moeilijkst om te updaten. Je cloudcode kun je in minuten deployen. Firmware op een machine in een fabriek achter de firewall van een klant kan weken duren om uit te rollen. Ontwerp je protocol zodat het altijd backward-compatible is.
- Monitoring is een feature, geen overhead. De dashboards die we voor de machines van onze klanten bouwden? Datzelfde hadden we nodig voor de gezondheid van ons eigen platform. Behandel observability als een eersteklas productvereiste.
- Begin met minder Azure-services. Elke managed service voegt een factuurregel, een faalscenario en iets om te leren toe. Voeg complexiteit alleen toe wanneer een concreet probleem erom vraagt.
Veelgestelde vragen
Welke programmeertaal is het best voor industriele IoT-platformen?
C# met .NET Core is een sterke keuze voor industriele IoT-platformen vanwege de prestaties, sterke typering en diepe integratie met Azure-services. Het ecosysteem biedt standaard libraries voor MQTT, HTTP en message queue-protocollen. Dat gezegd hebbende, de beste taal is degene waarvoor je team kan werven en die je op lange termijn kunt onderhouden — Python en Go komen ook veel voor in deze ruimte.
Hoe ga je om met time-series data zonder een time-series database?
SQL Server kan time-series workloads effectief afhandelen op gemiddelde schaal — tientallen miljoenen rijen per maand — met de juiste tabelpartitionering, datumgebaseerde indexering en vooraf berekende aggregatietabellen. De sleutel is het scheiden van ruwe dataretentie en rapportagequeries. Ruwe data wordt opgerold naar uur- en dagaggregaten, en de meeste dashboardqueries raadplegen de aggregaattabellen in plaats van ruwe telemetrie te scannen.
Is Blazor geschikt voor realtime IoT-dashboards?
Blazor Server is goed geschikt voor realtime IoT-dashboards in gecontroleerde netwerkomgevingen. De ingebouwde SignalR-verbinding biedt push-updates zonder polling, en het server-side houden van de rendering betekent dat het dashboard directe toegang heeft tot backend-data zonder een API-laag. De voornaamste beperking is de afhankelijkheid van een stabiele WebSocket-verbinding, waardoor het minder ideaal is voor onbetrouwbare mobiele netwerken.
Welke Azure-services heb je nodig voor een IoT-platform?
Een minimaal Azure IoT-platform heeft een ingestieservice nodig — Event Hubs voor telemetry-only of IoT Hub voor bidirectionele communicatie — een compute-laag zoals App Service of Azure Functions voor verwerking, een database voor opslag en Application Insights voor monitoring. Begin met deze vier bouwstenen en voeg services zoals Stream Analytics of Time Series Insights alleen toe wanneer een specifieke vereiste de toegevoegde complexiteit en kosten rechtvaardigt.
Hoe zorg je voor databetrouwbaarheid met onbetrouwbare fabrieksnetwerkverbindingen?
Betrouwbaarheid in fabrieksomgevingen vereist een driedelige strategie: lokale buffering op het apparaat zodat data connectiviteitsgaten overleeft, idempotente ingestie op de server zodat dubbele berichten van reconnecties onschadelijk zijn, en afwezigheidsgebaseerde monitoring die alerteert wanneer verwachte data stopt met binnenkomen. De buffer op het apparaat is het meest kritieke onderdeel — geen enkele hoeveelheid cloud-side engineering kan data herstellen die nooit lokaal is opgeslagen.