FactoryPulse is a simulator-first, hardware-ready industrial monitoring platform. It ingests machine sensor readings, stores historical data, detects deterministic anomalies, manages operational alerts, and visualizes factory health through a live dashboard.
The project is intentionally focused: no login, no AI, no payments, and no unrelated enterprise features. The core value is a stable monitoring workflow that works today with simulated machines and can later accept readings from real devices or gateway adapters through the same HTTP ingestion API.
Industrial teams need a clear way to monitor machine health, detect abnormal readings, understand why an alert was created, and decide what an operator should do next. FactoryPulse demonstrates that workflow in a Dockerized full-stack application with real-time updates, explainable alerts, historical readings, and hardware-ready ingestion.
- Real-time factory dashboard with machine health, open incidents, offline machines, and live connection state.
- Machine detail pages with latest readings, health explanation, alert history, recommendations, and charts.
- Deterministic anomaly detection for temperature, vibration, energy usage, offline status, and sensor failure.
- Alert lifecycle with Pending, Active, Acknowledged, Resolved, and Cleared states.
- Alert persistence logic that separates short sensor spikes from persistent real problems.
- Simulator scenarios for short spikes, persistent overheating, persistent vibration, energy spike, offline machines, sensor failure, multi-machine incidents, and normal operation.
- Device registration for simulator and hardware sources.
- Optional device tokens for hardware-style ingestion validation.
- WebSocket updates for dashboard, machine detail, and alerts.
- Docker Compose setup with frontend, backend, and PostgreSQL.
- Pytest coverage for ingestion, alert lifecycle, simulator behavior, devices, dashboard summary, and validation.
- Frontend: React, TypeScript, Tailwind CSS, Vite
- Backend: FastAPI, Python, SQLAlchemy
- Database: PostgreSQL
- Real-time: WebSockets
- Charts: Recharts
- Testing: Pytest
- Runtime: Docker Compose
Simulator or Hardware Gateway
|
v
POST /readings ---> FastAPI ingestion service
| |-- validates machine_id, reading values, and optional device_token
| |-- stores readings in PostgreSQL
| |-- updates machine status and last_seen_at
| |-- runs deterministic anomaly detection
| |-- separates short spikes from persistent incidents
| |-- creates, updates, acknowledges, resolves, and clears alerts
| |-- calculates machine health and trend explanations
v
WebSocket /ws/live ---> React dashboard, machine detail screens, and alert review
- Simulator-first design allows development and demos without physical hardware.
- FactoryPulse uses a stable ingestion API so real devices or gateways can send readings without changing backend code.
- Device IDs and optional device tokens identify hardware sources.
- WebSockets provide live dashboard updates.
- Deterministic anomaly detection keeps alerts explainable and testable.
- Alert persistence keeps short spikes from becoming noisy incidents while keeping real incidents open for operators.
- PostgreSQL stores historical readings, machines, devices, and alerts.
- Docker Compose makes the full stack reproducible.
FactoryPulse starts with simulated industrial machines:
- CNC Machine 01
- Robotic Arm 02
- Conveyor Belt 01
- Cooling Unit 01
- Packaging Machine 01
The simulator writes readings through the same backend path used by real devices:
- temperature
- vibration
- energy_usage
- status
- timestamp
The dashboard includes controlled scenarios for demonstrations and testing:
- Normal operation
- Short temperature spike
- Persistent overheating
- Persistent high vibration
- Energy spike
- Machine offline
- Sensor failure
- Critical multi-machine incident
- Return all machines to normal operation
FactoryPulse is simulator-first and hardware-ready. It currently generates simulated industrial sensor data, but real devices, Raspberry Pi, ESP32, industrial gateways, or protocol adapters can send readings to the same HTTP ingestion API without backend code changes.
Hardware devices can POST readings to:
POST http://localhost:8002/readingsExample payload:
{
"machine_id": "cnc-01",
"temperature": 72.5,
"vibration": 0.42,
"energy_usage": 210,
"status": "running",
"device_token": "optional-device-token",
"timestamp": "2026-05-20T12:00:00Z",
"sensor_unit": "metric"
}Hardware metadata:
machine_id: unique machine identifier used in sensor payloads.device_token: optional key used to verify that a device is allowed to send readings.source_type:simulatororhardware.expected_sensors: sensors the device is expected to send.is_active: whether a device is enabled for ingestion and simulator/dashboard active counts.last_seen_at: latest received reading timestamp.
For protocols such as MQTT, OPC UA, Modbus, PLC systems, or existing company gateways, an adapter can translate machine data into FactoryPulse's JSON schema and forward it to POST /readings. FactoryPulse does not implement those protocols directly in this version; it provides the stable HTTP adapter target.
FactoryPulse separates machine state from alert lifecycle. Machine state updates automatically based on latest readings, while alert incidents follow pending, active, acknowledged, resolved, and cleared states. Short spikes may clear automatically, but persistent issues become active alerts that require operator review and manual resolution.
Devices can be registered with:
POST /devicesDevices can also be disabled or enabled without deleting historical readings or alerts:
PATCH /devices/{machine_id}/disable
PATCH /devices/{machine_id}/enableDisabled devices remain available for history but are ignored by simulator activity and dashboard active counts where appropriate.
Connection status is derived from last_seen_at:
- Online: last reading received within 30 seconds.
- Delayed: last reading received within 2 minutes.
- Offline: no reading for more than 2 minutes or no data yet.
FactoryPulse alerts are generated from incoming sensor readings, but the system does not treat every spike as an incident.
- Pending: an abnormal value was detected, but it has not persisted long enough to require operator action.
- Active: the abnormal condition persisted beyond the configured threshold and needs attention.
- Acknowledged: an operator reviewed the active alert, but the incident is still open.
- Resolved: an operator manually marked the incident as handled.
- Cleared: a short spike returned to normal before becoming an active incident.
FactoryPulse also tracks condition state separately:
- Condition active: the latest readings still show the abnormal condition.
- Condition cleared: latest readings returned to normal, but an active or acknowledged alert remains open until an operator resolves it.
Default demo thresholds are intentionally short: warning persistence is 5 seconds, critical persistence is 8 seconds, and offline persistence is 8 seconds. They can be changed through ALERT_WARNING_PERSISTENCE_SECONDS, ALERT_CRITICAL_PERSISTENCE_SECONDS, and ALERT_OFFLINE_PERSISTENCE_SECONDS.
Acknowledging an alert does not physically repair a machine. If abnormal readings continue, FactoryPulse keeps the same incident open and updates it instead of creating duplicate alert spam. Active and acknowledged alerts do not disappear automatically; normal readings only mark their condition as cleared. The operator then marks the incident resolved.
FactoryPulse creates warning or critical alerts for:
- High temperature: warning above 85 C, critical above 95 C.
- High vibration: warning above 0.8 g, critical above 1.2 g.
- High energy usage: warning above 300 W, critical above 400 W.
- Offline machine status: critical.
- Sensor failure: invalid telemetry values.
Each alert includes machine context, severity, reason, timestamp, operator-readable message, and recommendation.
The frontend subscribes to:
WS /ws/live
The WebSocket sends live machine summaries, alert updates, dashboard summary changes, and newly created readings. This keeps the dashboard, alert center, and machine detail screens aligned with incoming sensor data.
Health score is deterministic and ranges from 0 to 100.
- Healthy: 90-100
- Warning: 60-89
- Critical: 0-59
- Offline: 0
The score considers latest temperature, vibration, energy usage, offline status, active warning alerts, active critical alerts, and recent trend direction. Each machine response includes a short explanation for why the score changed.
From the project root:
docker compose up --buildOpen:
- Frontend: http://localhost:5175
- Backend docs: http://localhost:8002/docs
- Backend health: http://localhost:8002/health
- PostgreSQL: localhost:5434
Configured ports:
- Frontend:
5175:5173 - Backend:
8002:8000 - PostgreSQL:
5434:5432
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /health |
Service health |
| GET | /dashboard/summary |
Factory-level metrics and recent anomalies |
| GET | /devices |
List registered simulator and hardware devices |
| POST | /devices |
Register a simulator or hardware device |
| PATCH | /devices/{machine_id}/disable |
Disable a device without deleting history |
| PATCH | /devices/{machine_id}/enable |
Enable a disabled device |
| GET | /machines |
List machine summaries |
| GET | /machines/{machine_id} |
Machine detail summary |
| GET | /machines/{machine_id}/health |
Machine health score, trend, and explanation |
| GET | /machines/{machine_id}/readings |
Historical readings |
| GET | /machines/{machine_id}/alerts |
Alerts for one machine |
| GET | /alerts |
Alert history |
| POST | /alerts/{alert_id}/acknowledge |
Acknowledge that an operator reviewed an alert |
| POST | /alerts/{alert_id}/resolve |
Mark an alert resolved when the latest readings no longer show the issue |
| POST | /readings |
Sensor ingestion |
| POST | /simulator/scenario |
Simulate professional test scenarios |
| WS | /ws/live |
Live machine and alert updates |
Backend:
cd backend
python -m pytestFrontend:
cd frontend
npm install
npm run buildThe backend test suite covers health checks, machine listing, dashboard summary, hardware device registration, hardware-style readings, token validation, invalid payloads, connection status logic, anomaly detection, alert lifecycle, duplicate alert prevention, simulator scenarios, and WebSocket snapshots.
Before creating a zip or publishing to GitHub, run the cleanup script to remove generated files. Run npm install again inside frontend after cleanup.
.\scripts\clean.ps1The cleanup script removes frontend/node_modules, frontend/dist, backend pytest cache, test databases, __pycache__, and *.pyc files.
- MQTT, OPC UA, Modbus, or PLC adapter examples.
- ESP32 or Raspberry Pi demo firmware.
- Stronger device authentication and token rotation.
- Production deployment configuration.
- Historical analytics and export workflows.
FactoryPulse - Real-Time Industrial IoT Monitoring Platform. Built a Dockerized full-stack platform that simulates industrial machine sensor data, supports hardware-ready sensor ingestion, detects anomalies, manages alerts, stores historical readings, and visualizes machine health through real-time dashboards. Designed a stable ingestion API for future integration with ESP32, Raspberry Pi, industrial gateways, or protocol adapters.
Tech: React, TypeScript, FastAPI, PostgreSQL, SQLAlchemy, WebSockets, Docker, Pytest, Recharts.




