Smart Lab Platform
A digital transformation and AI platform for a whole organization at Milwaukee Tool (TTI Group): from test engineers and the test automation group to purchasing, planning, warehouse and operations.
- API modules
- 52
- IoT devices
- 200+
- Pull requests
- 1,070
- Automated tests
- 3,000+
The problem and the approach
Smart Lab Platform is a digital transformation and AI platform for a whole organization. It has about 150 users, from test engineers and the test automation group to purchasing, planning, warehouse and operations.
It grew out of the engineering test lab at Milwaukee Tool (TTI Group). The lab ran on many separate tools and spreadsheets: test plans and headcount, fixtures, equipment calibration, materials, work instructions, 7S audits, visitor feedback, purchasing follow-up, and the IoT devices on its chambers and machines. Smart Lab Platform puts them in one web app with one login and one permission model. An AI assistant answers questions across the modules.
The result: the lab’s processes moved entirely from manual work to automated work.
Full technical notes
What it covers
The backend has 52 API modules and the frontend 41 page sections. The README groups them into 13 functional areas, from test planning on a 3-level Gantt to 7S audits and purchasing. Access runs on 129 permissions in 35 scopes, and a permission tree shows where each right comes from. Visitors get a role that can only submit feedback. A read-only Viewer role lets people look around without changing data.
A scheduled job copies planning and purchasing data from the Lab Management System. That is the company system Khoa started as Senior Lab Automation Engineer. Test plan status is read-only on the platform and comes from that system. The goal is one source of truth for all three plan levels.
Devices and OTA
More than 200 devices run on production. They come in four families that share one device table:
- ESP32-S3 temperature and humidity sensors, with per-device calibration.
- Test chambers for temperature and humidity, dust and metal dust. The platform stores their Modbus register map.
- Machines, such as a dust collector and a vibration machine.
- An industrial ESP32-S3 edge gateway. It has 16 configurable pins in 11 modes, per-pin Kalman filtering and scaling, and Modbus RTU. By default it publishes batched readings over MQTT every 60 s.
Devices register with the API using a device API key, then fetch their configuration. That key can only read and write device and firmware data. Since July 2026 the gateway config is a dialog with Pins, Modbus and Raw JSON tabs. Before that, users edited the JSON by hand.
OTA is an HTTP pull. An admin uploads a firmware binary per device family and screen size. Every 5 minutes each device asks the platform for a newer version. If there is one, the device downloads it over HTTP, flashes it, reboots and reports its new version. An “update” command over MQTT makes a device check at once. The firmware image never passes through the broker. Versioning is latest-wins per family.
Device presence comes from the broker’s connect and disconnect events, not from polling devices. The browser watches live device data over MQTT on WebSocket, proxied by Nginx.
AI with read-only data
A router model sends each question to one of 5 specialist agents: inventory and assets, reporting, work instructions, maintenance planning, and testing advice. Each agent has its own tools and loads skills on demand. In September 2026 the skills were split from 5 large files into 22 small ones. An agent now loads about 20 lines instead of about 100. Answers stream to the browser over Server-Sent Events.
The model is a runtime setting. Model names that contain “claude” go to Claude hosted on Azure, and the rest go to Azure OpenAI.
The assistant reads the database only through 33 read-only views. Its database role can SELECT those views and nothing else, with a 10-second statement timeout. The role enforces this inside the database, which a keyword blocklist cannot do. In August 2026 a follow-up check found 13 built-in tools that still queried base tables, and all of them moved onto the views. Price columns then left the views. The API hides prices from users without the price permission, but the AI and MCP paths have no user identity to check.
Azure AI Content Understanding parses the work instructions, and Azure AI Search indexes them. Search combines keywords, 3,072-dimension vectors and semantic ranking. Since August 2026, agentic retrieval splits a complex question into sub-queries.
The model keeps per-user notes itself, through tool calls into PostgreSQL. The 10 newest notes go into the prompt. This replaced Mem0 and Neo4j.
The MCP server exposes 18 read-only tools and 5 prompts over Streamable HTTP, on the same views. It accepts an API key or HTTP Basic, both stored as hashes. Basic is there because Power Apps and Copilot Studio connectors support it natively.
Visitor feedback runs through a gated pipeline. A classifier goes first. Positive feedback goes to a strengths agent, and low-risk items skip the action plan. This stopped invented root causes and wrong severities on positive feedback. Other AI jobs describe the figures in work instructions, draft BOMs, write a weekly predictive-maintenance summary and triage user-reported issues.
How it was built
Smart Lab Platform started in July 2025 as a small IoT management system for ESP32 sensors and chambers. Firmware updates were in the first requirements document. It grew module by module into the lab’s main platform. After merges and duplicates are removed, the repo has 2,900+ commits. Khoa wrote 73% of them and an AI coding-agent team’s account 12%.
From July 2026 every change went through a pull request: 1,070 PRs by 25 October 2026, of which 1,062 merged. From mid-August, CI tests gated each merge. The repo has 1,873 backend test functions and 1,152 frontend test cases.
Since October 2026 Khoa has built the platform with that AI coding-agent team and coordinates its work. The team runs on Claude Code inside an agent swarm. In October it opened 468 of the month’s 483 PRs. A reviewer agent left a written verdict on 369 of them, often a block followed by a fix and a re-review. Khoa approves the merges. Across the whole history, 44% of the commits list Claude as co-author, starting in March 2026.
The platform runs on one on-prem server with Docker Compose. Nginx serves the React app next to the API, an MCP server, Redis, the MQTT broker and a separate solver container. The solver is for a plan scheduler that is still in development. PostgreSQL and InfluxDB run as external services.
Deploys run on a schedule. Since 15 October 2026 a separate pipeline deploys twice a day and skips days with no new commits. Schema changes are additive only and run at startup, with no migration step. There is one deploy path, on one host.
The code lives in a private work repo, so this page has no source link.
How data moves through the system
Drawn from the compose file, folder structure and config in the repo.
- edgeESP32 devicesSensors, chamber and machine controllers, 16-pin edge gateway
- brokerMQTT brokerEMQX, QoS 2
- apiPlatform APIFlask-RESTX, Gunicorn + gevent, 52 modules
- dataDataPostgreSQL, Redis 8, InfluxDB
- aiAI layerAzure OpenAI, Claude, Azure AI Search
- uiWeb appReact 19, MUI 9, Nginx
Main folders in the repo
- 01Read the repo
- 02Analyse README, docs, compose, package files
- 03Write the page, filter out internal details
- 04Reviewer agent checks it against the sources
- 05Khoa approves the page, then it deploys