BuildingOS IoT Simulator microservice
npm install @buildingos/iotsimulatorBuildingOS IoT Simulator mimics the behavior of various IoT devices (Lights, HVAC, Sensors, etc.) within a virtual space. It connects to the BuildingOS platform via MQTT and HTTP APIs, providing real-time status updates and responding to control commands.
- Device Simulation: Simulates behaviors for multiple device types:
- Light: On/Off status.
- AirConditioning: Temperature, mode (Cool/Heat/Fan), fan speed.
- AirSensor: PM2.5, PM10, CO2, TVOC, Temperature, Humidity.
- HumanSensor: Occupancy status (Free/Busy).
- PowerSensor: Voltage, Current, Power, Energy (KWh).
- Service Discovery: Automatically registers with the BuildingOS Service Manager using MQTT.
- Auto-Provisioning: Can automatically create gateways and devices in the database if they don't exist (simulate API).
- MQTT Integration:
- Publishes device status to /iot/status/...
- Subscribes to control commands on /iot/action/...
- Data Persistence: Updates device status in the PostgreSQL database.
The simulator uses various algorithms to generate realistic data and handle control logic for different device types.
| Device Type | Update Interval | Initial State | Simulation Logic (Jitter/Behavior) |
| :--- | :--- | :--- | :--- |
| Light | 60s | online: 1, status: 'on' | Periodically reports current status. Responds to control commands immediately. |
| AirConditioning | 30s | online: 1, status: 'on', temp: 22, mode: 2 (Cool), fan: 15 (Low) | Temperature Drift: Gradually approaches target temperature (towards = current + direction * 0.2). Adds random jitter (±0.2) to simulated room temperature within range [16, 30]. |
| AirSensor | 60s | pm2.5: 7, co2: 692, temp: 23.3, hum: 39.7, ... | Applies random jitter to all environmental parameters:
- PM2.5: ±2 (Range 0-75)
- PM10: ±3 (Range 0-150)
- CO2: ±15 (Range 350-2000)
- Temp: ±0.2 (Range 16-35)
- Humidity: ±0.5 (Range 10-90) |
| HumanSensor | Random (Event-based) | status: 'free' | Event-Driven: Toggles between free and busy states at random intervals (Log-normal distribution, min 5s). Publishes immediately on state change. |
| PowerSensor | 30 mins | voltage: ~235V, power: ~6kW | Complex Simulation:
- Voltage: Jitters ±0.5V around 220V-240V.
- Current: Jitters ±0.5A for 27 loops.
- Power: Calculated as Current * 230V.
- KWh: Accumulates based on power usage (KWh += Power/1000). |
The simulator subscribes to /iot/action/# and processes incoming JSON payloads.
#### Control Logic by Device Type
* Light:
* Accepts action or status fields in payload.
* Values on, 1, true -> Turn ON.
* Values off, 0, false -> Turn OFF.
* AirConditioning:
* Status: on/off (similar to Light).
* Mode: Updates mode (1: Auto, 2: Cool, 3: Heat, 4: Fan, 5: Dry).
* Fan: Updates fan speed (15: Low, 45: Mid, 75: High).
* Temperature: Updates temperature (Target Temp). Clamped between 16°C and 30°C.
#### Group Control Support
The simulator supports hierarchical group control via MQTT topic structure:
1. Direct Device Control: /iot/action/.../{deviceCode} - Controls a specific device.
2. Area Control: /iot/action/.../{floorCode}/{areaCode} - Controls all devices of matching type in that area.
3. Floor Control: /iot/action/.../{floorCode} - Controls all devices of matching type on that floor.
The simulator is designed to run as a Docker container within the BuildingOS ecosystem.
``bash`Usually managed via docker-compose
docker run -d \
--name iotsimulator \
--network buildingos-prod-network \
-e DB_HOST=buildingos-postgres-prod \
-e MQTT_BROKER_URL=mqtt://buildingos-emqx-prod:1883 \
buildingos/iotsimulator:latest
1. Install Dependencies:
`bash`
npm install
2. Configure Environment:
Create a .env file in the root of the app (see Configuration section).
3. Start the Service:
`bash`
npm run start
The service is configured via environment variables.
| Database type | postgres |
| DB_HOST | Database host | localhost |
| DB_PORT | Database port | 5432 |
| DB_USER | Database username | buildingos |
| DB_PASSWORD | Database password | - |
| DB_NAME | Database name | buildingos |$3
| Variable | Description | Default |
|----------|-------------|---------|
| MQTT_BROKER_URL | MQTT Broker URL | ws://localhost:8083/mqtt (or mqtt://...) |
| MQTT_USERNAME | MQTT Username | - |
| MQTT_PASSWORD | MQTT Password | - |
| MQTT_CLIENT_ID | Custom Client ID | Auto-generated |
| PORT | HTTP Server Port | 3011 |
| DISCOVERY_TARGET| Hostname/IP for service discovery | iotsimulator (in Docker) or localhost |$3
| Variable | Description | Default |
|----------|-------------|---------|
| IOT_SIMULATOR_AUTOSTART | Auto-start simulation on boot | false |
| IOT_SIMULATOR_MODE | Operation mode (docker or auto) | auto |
| SPACE_CODE | Default space code for simulation | demo-space |
| API_BASE_URL | BuildingOS Backend API URL | - |
| API_TOKEN | Token for API calls | - |API Endpoints
The microservice exposes the following HTTP endpoints (typically mapped via the API Gateway):
-
POST /simulate: Triggers the simulation logic.
- Body: { "spaceCode": "...", "config": { "build": true } }
- GET /health: Health check endpoint.
- GET /mqtt: Returns current MQTT connection status.
- GET /templates: Returns available device templates.
- GET /menu.json: Returns the microservice menu configuration.MQTT Topics
$3
Devices publish their status periodically or on change to:
`
/iot/status/{type}/{spaceCode}/{areaCode}/{floorCode}/{floorAreaCode}/{deviceCode}
`
Payload: JSON array containing status objects.$3
To control a device, publish a JSON payload to:
`
/iot/action/{type}/{spaceCode}/{floorAreaCode}/{floorCode}/{areaCode}/{deviceCode}
`
Group Control:
- Floor Level: /iot/action/{type}/{spaceCode}/{floorAreaCode}/{floorCode}
- Area Level: /iot/action/{type}/{spaceCode}/{floorAreaCode}/{floorCode}/{areaCode}Payload Example:
`json
{
"action": "on",
"mode": 2,
"temperature": 24
}
``