A React simulator for StopCode, a rugged 6-button downtime reason logger built for CNC and metal fabrication environments. Built as part of the Tractian Summer Internship Case Study (April 2026).
Live demo: aarushassudani.xyz/Tractican
The app simulates the full StopCode hardware + dashboard experience in a browser:
- Virtual Device (left panel): Simulates the physical StopCode unit. Press any of the 6 reason-code buttons to log a downtime event. Toggle Wi-Fi on/off to simulate offline buffering and sync.
- Admin Dashboard (right panel): Four tabs showing what a plant manager or maintenance engineer would see in the Tractian dashboard after StopCode integration.
| Tab | What It Shows |
|---|---|
| Feed | Live event feed. Each button press logs a timestamped entry with device ID and reason code. Offline events sync with a staggered animation when Wi-Fi is toggled back on. |
| OEE | Real-time OEE analytics computed live against actual elapsed shift time. Availability, Performance, and Quality update every second and not just on button press. Unplanned stops degrade Availability; event volume degrades Performance; material jams and tool breakages degrade Quality. |
| Vitals | Simulated ESP32-S3 hardware telemetry: CPU temp (live drift), battery drain, flash usage (tracks offline queue size against 8MB capacity), and uptime. |
| Config | Remote button label editor. Simulates OTA config push -- rename any of the 6 buttons, changes propagate immediately to the device panel. Includes save confirmation and factory reset. |
Offline-first architecture simulation Toggle the Wi-Fi switch offline, press buttons, then toggle back online. Queued events flush to the feed with a staggered sync animation, mirroring the real device's capture-buffer-sync architecture. The queue persists to localStorage so it survives page refresh.
Live OEE calculation
OEE is computed in real time using src/utils/oeeCalculator.js. Availability degrades with unplanned stops; Performance degrades with event volume; Quality degrades specifically with material jams and tool breakages. The model uses an 8-hour shift (480 minutes) as its base.
Synthesized audio All sounds are generated via Web Audio API -- no audio files. Button press: 60ms square wave. Machine stop buzzer: 550ms dual sawtooth. Sync chirp: 200ms sine sweep. Lazy-initialized to handle autoplay restrictions.
50ms debounce per button Each button has an independent debounce guard matching real mechanical switch bounce characteristics. Two different buttons pressed rapidly both register; the same button double-pressed within 50ms only registers once.
src/
├── App.jsx # Root component, owns all shared state
├── components/
│ ├── DevicePanel/
│ │ ├── DevicePanel.jsx # Hardware enclosure simulation
│ │ ├── EInkDisplay.jsx # Monochrome e-paper display
│ │ ├── WiFiToggle.jsx # Online/offline toggle
│ │ └── ReasonButton.jsx # One per reason code (x6)
│ └── Dashboard/
│ ├── Dashboard.jsx # Tabbed container
│ ├── LiveEventFeed.jsx # Feed tab
│ ├── OEEAnalytics.jsx # OEE tab
│ ├── HardwareVitals.jsx # Vitals tab
│ └── AdminConfig.jsx # Config tab
├── hooks/
│ ├── useEventStore.js # Core state machine, event lifecycle, sync logic
│ └── useDebounce.js # Per-button debounce guard
└── utils/
├── constants.js # Single source of truth for all config values
├── oeeCalculator.js # OEE computation from event array
├── localStorage.js # Offline queue persistence
└── audio.js # Web Audio API sound synthesis
All tunable values live in src/utils/constants.js. Key ones:
FLASH_CAPACITY_MB = 8 // ESP32-S3-WROOM-1U-N8 onboard flash
DEBOUNCE_MS = 50 // Button debounce guard
SYNC_STAGGER_MS = 220 // Delay between synced events in feed
COUNTDOWN_SECONDS = 5 // Machine stop simulation timer
OEE_PARAMS = {
shiftMinutes: 480,
unplannedMinutesPerEvent: 4,
plannedMinutesPerEvent: 8,
performanceBase: 91,
qualityBase: 98
}
HARDWARE_VITALS = {
cpuTempC: 42,
batteryPct: 88,
batteryCapacityMah: 2000,
firmwareVersion: 'v2.1.4',
uptimeOffsetSec: 52320 // Pre-seeds uptime at 14h 32m
}git clone https://github.com/aarush8/Tractican
cd Tractican
npm install
npm run devRequires Node 18+. Built with Vite + React.
StopCode is a physical device, not just software. The demo simulates:
- ESP32-S3-WROOM-1U-N8 -- dual-core Xtensa LX7 at 240MHz, 8MB SPI flash, Wi-Fi + BLE
- 1.54" SPI monochrome e-ink display -- ultra-low power, retains last logged reason without power
- 6x 60mm illuminated arcade buttons -- Cherry MX-style microswitches, 45-60 cN actuation, glove-operable
- IP67 / NEMA 4X enclosure -- dust-tight, cutting fluid resistant, water-resistant
- 2000mAh LiPo backup battery -- maintains operation and data integrity through power loss
Full BOM pricing, compliance requirements, and ROI model are in the Technical Appendix.
Built for the Tractian Summer Internship Innovation Case Study. StopCode addresses the human-context gap in OEE data collection: automated sensors detect that a machine stopped, but cannot capture why. A single button press at the moment of stoppage closes that gap.
The demo is intentionally faithful to the real device architecture -- offline-first, single-action logging, and dashboard integration -- to make the product concept tangible for a leadership audience.