De situatie
Fullwood zocht meer dan een nieuw ontwerp. Drie onderdelen moesten samen groeien: een simulator van de robot, de datalaag en hoe de melkveehouder die twee ziet.
Fullwood bouwt M²erlin-melkrobots. Een melkveehouder die er een koopt, koopt geen gadget. Hij runt een precisiebedrijf: 90 koeien of 300, één robot of een hele vloot, met dagelijkse beslissingen over diergezondheid, voerkosten, het juiste moment voor inseminatie en de bezetting van de machines.
Fullwood wilde dat de software diezelfde precisie kreeg, en die ambitie raakte de hele stack.
Aan de oppervlakte was FullSense functie voor functie gegroeid, en de volgende stap ging over prioriteit. Een melkveehouder moet om half zes de ene melding zien die ertoe doet, vóór de 79 die kunnen wachten. Storingen en informatieberichten hadden duidelijk verschillend gewicht nodig, en de koeienkaart moest het verhaal van een koe vertellen in plaats van alleen haar instellingen te tonen.
Daaronder zat de Data API, die het product jarenlang goed had gediend. De nieuwe schermen vroegen er meer van: data die nog niet beschikbaar was, slankere responses en een volledig gedocumenteerd contract.
Het lastigst was het testen. Stalsoftware laat pas over een hele dag zien hoe ze zich echt gedraagt: melkingen stapelen zich op, robots lopen vol en leeg, koeien komen te laat, separaties gaan af. Een stal past niet in een CI-pipeline, en je kunt geen twaalf uur wachten om een dashboard te controleren. Zonder realistisch robotgedrag op afroep konden wijzigingen aan de API of de frontend alleen tegen vaste testdata worden gecontroleerd.
Eén laag apart verbeteren was niet genoeg geweest. Een nieuwe frontend zou begrensd worden door wat de API kon leveren. Een betere API zonder realistische data zou onbewezen blijven. Daarom koos Fullwood ervoor de simulator, de data en het product samen te ontwikkelen.
Hoe we onderdeel werden van het team
We draaiden drie sporen binnen Fullwood. Alle drie werkten vanuit dezelfde domeinregels: lactatiefases, prioriteit van separaties, ernst van meldingen, en het verschil tussen een vaars in haar eerste lactatie en een koe in haar vijfde.
De simulator-Mino bouwde een virtuele robot. Geen mock die vaste antwoorden teruggeeft, maar een simulatie van hoe een M²erlin zich gedraagt (koeienbezoeken, melkingen, voerverstrekking, separatiebeslissingen) die naar een echte stalstack schrijft, op een klok die je kunt vooruitspoelen. Een tijdvak van vier uur draait in een paar minuten. Zo begint elke demo, test en ontwerpreview met een stal die echt een ochtend achter de rug heeft.
Het API-spoor vernieuwde het contract tussen robot en melkveehouder. In de .NET-backend van Fullwood verhuisden verouderde operaties naar een gedocumenteerd REST-contract. Waar het product data nodig had die nog niet bestond, kwamen nieuwe endpoints. De realtime robotstatus werd via ASP.NET Core SignalR gepusht, in plaats van door elk scherm opgevraagd. Elk gat dat de frontend vond, kwam in een geschreven log met metingen en reproductiestappen, en werd daarna opgelost of vastgelegd als besluit.
De FullSense-Mino bouwde de nieuwe FullSense. Het ontwerp volgt de dag op de boerderij: een statuscheck om half zes, triage halverwege de ochtend, levenscycluswerk in de middag, terugblik in de avond. Vanaf de eerste sprint bouwde het team tegen de echte Data API, nooit tegen een verzonnen backend.
De sporen versterkten elkaar. De simulator gaf de API realistisch verkeer en de frontend een stal die het bekijken waard was. De frontend vertelde de API wat melkveehouders echt nodig hebben, en de API gaf beide een contract waar ze op konden bouwen.
Wat we bouwden en waarom
Een robotsimulator, zodat de hele stack zich over tijd kan bewijzen. Stalsoftware faalt langzaam. Een KPI loopt weg, een melding gaat af in uur zes, een separatie belandt na het derde bezoek bij de verkeerde koe. Door de robot uur na uur te laten draaien, worden die trage fouten iets wat een team in minuten kan reproduceren. Daarom kreeg de simulator een eigen team en een eigen product, in plaats van als testhulpmiddel te worden behandeld.
Een API-contract dat is opgeschreven, niet aangenomen. De frontend mocht niet stilletjes om de API heen werken. Elke operatie die het product gebruikt, staat in een log met zijn status: live, gemockt met een opgegeven reden, of nog niet aangesloten. Ontbrekende data ging terug naar de backend als concreet verzoek, niet als gok. Waar het ertoe deed, veranderde het contract zelf: REST-endpoints voor de nieuwe schermen en een realtime hub voor de robotstatus. De API weerspiegelt nu wat het product echt gebruikt.
Een nieuw FullSense op dat fundament, geen nieuw jasje. Elk scherm opent met één dominant statussignaal. Elke entiteit (koe, robot, KPI, bedrijf) volgt dezelfde grammatica van drie toestanden: OK, Watch en Act. Een bedrijf met 300 gezonde koeien en twee zieke toont twee dingen, niet 302. Een koe staat er als individu met een geschiedenis, niet als datarij, en elke meetwaarde komt met haar trend en een referentiepunt.
We zeiden nee tegen sporen die los van elkaar werden gebouwd. De makkelijke weg was drie losse projecten: een frontendbureau, een API-backlog en een testomgeving, elk met een eigen roadmap. Wij hielden het één product. Een scherm is pas af als het werkt tegen de echte API, en een endpoint is pas bewezen als de simulator er realistisch verkeer doorheen heeft gestuurd.
Het bewijs
Een staldag op afroep. De simulator comprimeert uren robotgedrag tot minuten, met melkingen, voerbeurten en separaties die binnenkomen terwijl de virtuele klok doortikt. Demo's, ontwerpreviews en API-wijzigingen worden getest tegen een bedrijf dat echt heeft gedraaid, niet tegen een dataset die iemand heeft ingetypt.
Eén contract van robot tot scherm. De simulator, de .NET API en de frontend draaien op dezelfde stalstack. Elk gat dat bovenin de stack wordt gevonden, heeft een vastgelegde route naar een oplossing onderin.
Drie seconden, ingebouwd in de layout. Elk scherm heeft bovenaan één dominant signaal, en drempelkleuren betekenen hetzelfde op een robottegel als op een koeienkaart. Als de melkveehouder moet scrollen om te weten of hij zich zorgen moet maken, heeft het scherm gefaald.
Wat we samen bouwen
We zijn niet weggegaan. Alle drie de sporen draaien nog steeds mee binnen Fullwood.
De simulator-Mino verdiept het robotmodel, zodat een steeds groter deel van de stal te reproduceren, inspecteren en testen is. Het API-spoor blijft de afstand verkleinen tussen wat de robot vastlegt en wat de melkveehouder nodig heeft, inclusief realtime status over het hele bedrijf. De FullSense-Mino zet de resterende prototypeschermen over op live data, workflow voor workflow.
Het belangrijkste is hoe het werk nu gebeurt: gedeelde domeinregels, vastgelegde besluiten, en een stack waarin elke laag wordt bewezen door de andere. De software van Fullwood groeit mee met de machines van Fullwood.
