A comprehensive IoT solution for environmental monitoring using Bosch BME688 gas sensors with Raspberry Pi, featuring real-time data visualization, machine learning capabilities, and kiosk mode display. This sensor system was designed with SPE (Single Pair Ethernet) technology by Zemfyre Inc, the leader in SPE technology solutions. The application software was expertly designed by the IoT software experts team at Iotistic Inc.
- Environmental Monitoring: Real-time sensing using Bosch BME688 4-in-1 environmental sensors (temperature, humidity, pressure, gas/air quality)
- SPE Technology: Designed with Single Pair Ethernet (SPE) connectivity for simplified wiring and power delivery
- IoT Stack: Complete containerized solution with Docker Compose
- Data Visualization: Grafana dashboards for real-time monitoring and historical analysis
- Data Storage: InfluxDB time-series database for sensor data
- MQTT Communication: Eclipse Mosquitto broker for sensor data streaming
- Automation: Node-RED for IoT workflows and data processing
- Machine Learning: Custom Node-RED ML nodes for predictive analytics
- Kiosk Mode: Full-screen dashboard display for dedicated monitoring stations
- Web Admin: Management interface for system configuration
- Multi-Platform: Supports Raspberry Pi (1-5), x86_64, and ARM architectures
- Architecture
- Hardware Requirements
- Software Requirements
- Quick Start
- Installation Methods
- Service Configuration
- Usage
- Development
- Troubleshooting
- Maintenance
- Contributing
- License
- Support
- Version
The system consists of several containerized services:
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
β BOSCH BME688 β β Raspberry Pi β β Web Client β
β Environmental βββββΆβ I2C Reader βββββΆβ Dashboard β
β Sensor β β β β β
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Docker Container Stack β
βββββββββββββββββββ¬ββββββββββββββββββ¬ββββββββββββββββββ¬ββββββββββββββ€
β Mosquitto β Node-RED β InfluxDB β Grafana β
β MQTT Broker β Flow Engine β Time Series β Visualizationβ
β Port: 1883 β Port: 1880 β Port: 8086 β Port: 3000 β
βββββββββββββββββββ΄ββββββββββββββββββ΄ββββββββββββββββββ΄ββββββββββββββ€
β Nginx Reverse Proxy β
β Port: 80 β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Service | Purpose | Default Port | Container Name |
|---|---|---|---|
| Nginx | Reverse proxy & web server | 80 | nginx |
| Mosquitto | MQTT message broker | 1883/9001 | mosquitto |
| Node-RED | IoT flow programming | 1880 | nodered |
| InfluxDB | Time-series database | 8086 | influxdb |
| Grafana | Data visualization | 3000 | grafana |
| BME688 | Environmental sensor reader | - | bme688 |
| Admin Panel | System management | 51850 | admin |
- Raspberry Pi 3 or newer (Pi 3+ required for optimal performance)
- 8GB+ SD Card (16GB+ recommended)
- Stable power supply (5V 2.5A minimum for Pi 3+)
- Network connectivity (Ethernet or WiFi)
- Bosch BME688 Environmental Sensor
- 4-in-1 measurements: Temperature, Humidity, Pressure, Gas/Air Quality
- SPE Connectivity: Single Pair Ethernet for data and power (designed by Zemfyre Inc)
- Ethernet Connection: Sensor connected to Raspberry Pi via Ethernet interface
- Default Network Address: Configurable via DHCP or static IP assignment
- x86_64 Linux systems (Ubuntu, Debian)
- ARM64 single-board computers
- Debian/Raspbian 11+ (Bullseye or newer)
- NodeJS
- Docker & Docker Compose (installed automatically)
- NodeJS
- Ansible (for automated deployment)
- Git
- SSH access to target system
For a completely automated setup on a fresh Raspberry Pi:
# Download and run the installer
curl -fsSL https://scripts.iotistic.ca/install | bashThis will:
- β Install all dependencies
- β Configure the system
- β Deploy all services
- β Set up kiosk mode (optional)
- β Configure networking (optional)
- Clone the repository:
git clone https://github.com/dsamborschi/zemfyre-sensor.git
cd zemfyre-sensor- Run the installer:
chmod +x bin/install.sh
./bin/install.sh- Follow the interactive prompts to configure your installation
Perfect for single Raspberry Pi setups:
# SSH into your Raspberry Pi
ssh pi@<raspberry-pi-ip>
# Download and run installer
curl -fsSL https://raw.githubusercontent.com/dsamborschi/zemfyre-sensor/master/bin/install.sh | bashIdeal for multiple devices or remote deployment using containerized Ansible:
- Configure inventory:
# Edit ansible/hosts.ini with your Pi's details
echo "[email protected] ansible_ssh_pass=yourpassword" > ansible/hosts.ini- Configure environment:
# Copy and edit the environment file
cp ansible/.env.pi.example ansible/.env.pi
# Edit .env.pi with your specific configuration- Run deployment (using containerized Ansible):
# Execute the deployment script
./ansible/run.shThe run.sh script automatically:
- Builds the Ansible Docker container
- Mounts the project workspace
- Loads environment variables from
.env.pi - Executes the deployment playbook
For development and testing:
# Clone repository
git clone https://github.com/dsamborschi/zemfyre-sensor.git
cd zemfyre-sensor
# Start development stack
docker-compose -f docker-compose.dev.yml up -dCreate .env file to customize port mappings:
# External port mappings
MOSQUITTO_PORT_EXT=51883
MOSQUITTO_WS_PORT_EXT=59001
NODERED_PORT_EXT=51880
INFLUXDB_PORT_EXT=58086
GRAFANA_PORT_EXT=53000
ADMIN_PORT=51850
# InfluxDB Configuration
INFLUXDB_INIT_ORG=Zemfyre
INFLUXDB_INIT_BUCKET=ZUS80LP
# Network Configuration
NTP_SERVER_IP=192.168.1.100
KIOSK_IP=192.168.1.30/24For complete sensor setup, configuration, and CLI commands, see the comprehensive guide:
π Sensor Setup Guide - Complete hardware setup, network configuration, MQTT broker setup, and troubleshooting
This guide covers:
- Hardware Setup: Physical connections and SPE connectivity
- Initial Connection: Serial and network access methods
- CLI Configuration: Complete command reference for network and MQTT setup
- Sensor Validation: BME688 environmental sensor verification
- Troubleshooting: Common issues and diagnostic commands
Quick Reference: The BME688 sensor connects via SPE (Single Pair Ethernet) and provides 4-in-1 environmental measurements: temperature, humidity, pressure, and gas/air quality.
After installation, access your services at:
| Service | URL | Description |
|---|---|---|
| Dashboard | http://<pi-ip>/dashboard/kiosk |
Full-screen monitoring dashboard |
| Grafana | http://<pi-ip>:3000 |
Data visualization (admin/admin) |
| Node-RED | http://<pi-ip>:1880 |
Flow programming interface |
| InfluxDB | http://<pi-ip>:8086 |
Database management |
| Admin Panel | http://<pi-ip>:51850 |
System management |
- Grafana:
admin/admin(change on first login) - InfluxDB: Setup wizard on first access
- Temperature Data:
sensor/temperature - Humidity Data:
sensor/humidity - Pressure Data:
sensor/pressure - Gas/Air Quality:
sensor/gas - System Status:
system/status - Alerts:
alerts/environmental
The system automatically:
- Reads environmental data from BME688 sensor every second (temperature, humidity, pressure, gas resistance)
- Publishes data to MQTT broker on separate topics
- Stores historical data in InfluxDB
- Visualizes real-time and historical data in Grafana
- Triggers alerts based on configured thresholds for air quality and environmental conditions
zemfyre-sensor/
βββ admin/ # Web admin interface
βββ ansible/ # Deployment automation
β βββ roles/
β β βββ system/ # System configuration
β β βββ network/ # Network setup
β β βββ kiosk/ # Kiosk mode setup
β βββ deploy.yml # Main playbook
βββ api/ # REST API service
βββ bin/ # Installation scripts
βββ grafana/ # Grafana configuration
βββ influx/ # InfluxDB setup
βββ bme688/ # Environmental sensor code
βββ mosquitto/ # MQTT broker config
βββ nginx/ # Reverse proxy config
βββ nodered/ # Node-RED flows and nodes
- Add to Docker Compose:
your-sensor:
build: ./sensors/your-sensor
volumes:
- /dev:/dev
privileged: true
networks:
- zemfyre-netThe system includes custom machine learning nodes:
- Dataset Management: Load, create, split datasets
- Model Training: Various ML algorithms
- Prediction: Real-time inference
- Evaluation: Model performance metrics
- System logs:
/var/log/syslog - Docker logs:
docker-compose logs - Application logs:
logs/directory in each service - Sensor logs: Check BME688 container output
For Raspberry Pi 3 and older:
- Reduce Grafana refresh rates
- Limit InfluxDB retention policies
- Optimize Node-RED flows
- Use memory limits in docker-compose.yml
For Resource-Constrained Systems:
# Add to docker-compose.yml services
deploy:
resources:
limits:
memory: 512M
reservations:
memory: 256M# Update containers
cd /home/$USER/iotistic
./bin/upgrade_containers.sh
# System updates
sudo apt update && sudo apt upgrade# Backup InfluxDB data
docker exec influxdb influx backup /backup
# Backup Grafana dashboards
docker exec grafana grafana-cli admin export-dashboard
# Backup Node-RED flows
cp nodered/data/flows.json flows_backup_$(date +%Y%m%d).json# Check all services
docker-compose ps
# Monitor resource usage
docker stats
# Check disk space
df -hIf you see errors like Release file for http://archive.raspberrypi.com/debian/dists/bookworm/InRelease is not valid yet, your Pi's system time is ahead. Fix it immediately:
# Disable NTP temporarily to prevent further drift
sudo timedatectl set-ntp false
# Switch to public NTP pools for reliable time sync
sudo sed -i 's/^NTP=.*/NTP=0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.org/' /etc/systemd/timesyncd.conf
# Restart time sync service
sudo systemctl restart systemd-timesyncd
# Wait for sync to complete
sleep 3
# Verify time is correct
timedatectl
dateNote: If system time drifts again, check network connectivity:
# Verify gateway is configured (required for NTP)
nmcli connection show eth0 | grep ipv4
# If gateway is missing, add it:
sudo nmcli connection modify eth0 ipv4.gateway 192.168.2.1
sudo nmcli connection up eth0
# Then re-enable NTP
sudo timedatectl set-ntp trueIf docker compose up --build fails:
# Clean up broken images and volumes
docker system prune -af
docker volume prune -f
# Rebuild from scratch
cd /home/zemfyre/iotistic
docker compose up -d --build --force-recreate --pull alwaysIf /system-time or other API endpoints return connection errors:
# Check if API container is running
docker ps | grep zemfyre-api
# View logs
docker logs zemfyre-api --tail 50
# Restart API service
docker compose restart apiWe welcome contributions! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
- Follow Python PEP 8 style guide
- Add unit tests for new features
- Update documentation
- Ensure Docker builds work on all platforms
This project is licensed under the MIT License. See LICENSE for details.
- Issues: GitHub Issues
- Documentation: Wiki
- Discussions: GitHub Discussions
Current version: Latest (rolling release from master branch)
For stable releases, check: Releases
Powered by Zemfyre Inc SPE Technology | Software by Iotistic Inc IoT Experts | Made with β€οΈ for the IoT community
Zemfyre Inc is the industry leader in Single Pair Ethernet (SPE) technology, providing innovative solutions for simplified industrial networking. Our SPE technology enables both data and power transmission over a single pair of wires, reducing installation complexity and costs for IoT deployments.
The application software was expertly crafted by the IoT software specialists at Iotistic Inc. Our team brings decades of experience in industrial IoT solutions, containerized applications, and real-time data systems. We specialize in creating robust, scalable IoT platforms for environmental monitoring and industrial automation.
Our expert IoT consulting and development services are designed to help you optimize your systems and drive innovation. Contact us today to discuss how we can support your next project!
curl -X POST http://localhost:3002/api/v1/state/target
-H "Content-Type: application/json"
-d '{
"apps": {
"1001": {
"appId": 1001,
"appName": "my-nginx-test",
"services": [
{
"serviceId": 1,
"serviceName": "nginx",
"imageName": "nginx:alpine",
"appId": 1001,
"appName": "my-nginx-test",
"config": {
"image": "nginx:alpine",
"ports": ["8085:80"],
"environment": {
"ENV": "production"
}
}
}
]
}
}
}'
curl -X POST http://localhost:3002/api/v1/state/apply
curl -X POST http://localhost:3002/api/v1/state/target
-H "Content-Type: application/json"
-d '{
"apps": {
"1002": {
"appId": 1002,
"appName": "other-app",
"services": [...]
}
}
}'
curl http://localhost:3002/api/v1/state
curl -X POST http://localhost:3002/api/v1/state/target
-H "Content-Type: application/json"
-d '{
"apps": {
"1001": {
"appId": 1001,
"appName": "my-nginx-test",
"services": [
{
"serviceId": 1,
"serviceName": "nginx",
"imageName": "nginx:alpine",
"appId": 1001,
"appName": "my-nginx-test",
"config": {
"image": "nginx:alpine",
"ports": ["8085:80"]
}
}
]
},
"1002": {
"appId": 1002,
"appName": "database",
"services": [
{
"serviceId": 1,
"serviceName": "postgres",
"imageName": "postgres:15-alpine",
"appId": 1002,
"appName": "database",
"config": {
"image": "postgres:15-alpine",
"ports": ["5432:5432"],
"environment": {
"POSTGRES_PASSWORD": "mysecretpassword",
"POSTGRES_DB": "mydb"
}
}
}
]
}
}
}'