CEMS: real-time environmental monitoring for construction sites
The Construction & Environmental Management System collects environmental sensor data from construction sites and turns it into live dashboards, alerts and compliance reports.
- Role
- Full-stack developer
- Employer
- Ecologic Engineering
- Scope
- 15 sites · 10,000+ readings a day
- Stack
- Node.js, PostgreSQL, Redis, Socket.io
Overview
Construction sites have to keep track of environmental conditions and stay compliant while work is under way. CEMS brings sensor readings from 15 sites — more than 10,000 a day — into one platform.
The problem
Readings arrive from multiple kinds of IoT sensors at many sites. Teams need them in one place, quickly enough to act on, and compliance reporting shouldn’t depend on collecting data by hand.
What I built
- REST APIs for the platform, built with Node.js and Express.
- A WebSocket and Socket.io streaming pipeline that pushes live readings to dashboards.
- A data-aggregation pipeline that merges multiple IoT sensor sources into PostgreSQL time-series storage, with indexing and GraphQL query tuning for faster queries.
- A Redis layer: pub/sub between services, and caching for high-frequency reads.
- TensorFlow anomaly-detection models running on live sensor streams for proactive alerts.
- Docker-based deployment on AWS EC2.
Architecture
Sensor data from each site is ingested and aggregated by Node.js and TypeScript services, published over Redis pub/sub and stored as time series in PostgreSQL. Dashboards receive live updates over Socket.io, and a Python and TensorFlow service runs anomaly detection on the incoming stream.
-
Sites
IoT sensors15 construction sites -
Services
IngestionNode.js · TypeScriptAnomaly detectionPython · TensorFlow -
Data & delivery
PostgreSQLTime seriesLive dashboardsSocket.io · Redis pub/sub
Engineering decisions
- Pub/sub between ingestion and consumers. Redis pub/sub sits between ingestion and the services that use the readings, so sensor sources and consumers can change independently.
- Stream instead of poll. Dashboards receive readings over Socket.io as they arrive rather than polling the API.
- Time series in PostgreSQL. Readings are stored as time series in PostgreSQL and indexed for the time-range queries that dashboards and reports run.
Evidence and status
The codebase is private to Ecologic Engineering, so there is no public repository or live demo.
I can walk through the ingestion pipeline, streaming layer and storage design in an interview.