# POE Sensor - Modbus to MQTT Bridge Service A robust Python service that reads temperature, humidity, and CO2 data from multiple Modbus TCP sensors and publishes the data to an MQTT broker with comprehensive monitoring and alerting capabilities. ## 📁 Project Structure ``` POE-sensor/ ├── config.py # Configuration constants and sensor definitions ├── sensor_bridge.py # Core logic for Modbus and MQTT operations ├── sensor_tracker.py # Sensor status tracking and alerting system ├── health_check.py # HTTP health check server (optional monitoring) ├── main.py # Entry point and application lifecycle management ├── requirements.txt # Python dependencies ├── poe-sensor.nomad # Nomad deployment configuration └── README.md # This documentation ``` ## 🚀 Quick Start ### 1. Install Dependencies ```bash pip install -r requirements.txt ``` ### 2. Configure Settings Edit `config.py` to match your environment: ```python # Modbus sensor configuration MODBUS_HOSTS = [ {"ip": "10.84.60.31", "location": "Warehouse-B", "type": "temperature_humidity"}, {"ip": "10.84.60.37", "location": "Office", "type": "cwt_co2"}, # Add more sensors as needed ] # MQTT configuration MQTT_BROKER = "mqtt.service.mesh" MQTT_USERNAME = "relay" MQTT_PASSWORD = "your_password" ``` ### 3. Run the Service ```bash python main.py ``` ## 📊 Features ### Core Functionality - **Multi-Sensor Support**: Handles both temperature/humidity and CO2 sensors - **Modbus TCP Client**: Reads data from multiple Modbus holding registers - **MQTT Publisher**: Publishes sensor data to structured MQTT topics - **Data Processing**: Converts raw sensor values to calibrated readings - **Error Handling**: Robust error handling and retry mechanisms - **Resource Management**: Automatic connection cleanup and garbage collection ### Monitoring & Alerting - **Real-time Sensor Tracking**: Individual sensor health monitoring - **Automatic Alerting**: MQTT alerts for sensor failures and recovery - **Health Check API**: Optional HTTP endpoints for system monitoring - **Comprehensive Logging**: Detailed logging for debugging and monitoring - **Status Reporting**: Real-time sensor status via MQTT topics ### Production Ready - **Nomad Deployment**: Ready-to-deploy Nomad job configuration - **Docker Support**: Containerized deployment with dependency management - **Environment Configuration**: Environment variable support for flexible deployment - **Graceful Shutdown**: Proper cleanup and signal handling ## 📈 Data Format & Topics ### MQTT Topic Structure The service uses a hierarchical topic structure for better organization: ``` Location/{location_name}/{sensor_type}/Time # Timestamp Location/{location_name}/{sensor_type}/Status # "online" or "offline" Location/{location_name}/{sensor_type}/Temperature # Temperature value Location/{location_name}/{sensor_type}/Humidity # Humidity value Location/{location_name}/{sensor_type}/CO2 # CO2 sensors only Location/{location_name}/{sensor_type}/alerts # Alert messages ``` ### Example Topics ``` Location/Warehouse-B/temperature-humidity/Time → "2024-01-15 10:30:25" Location/Warehouse-B/temperature-humidity/Status → "online" Location/Warehouse-B/temperature-humidity/Temperature → "23.5" Location/Warehouse-B/temperature-humidity/Humidity → "65.2" Location/Office/CO2-gas/Time → "2024-01-15 10:30:25" Location/Office/CO2-gas/Status → "online" Location/Office/CO2-gas/Temperature → "24.1" Location/Office/CO2-gas/Humidity → "58.3" Location/Office/CO2-gas/CO2 → "420" ``` ### Alert Format ```json { "alert_type": "sensor_failure", "timestamp": "2024-01-15T10:30:25Z", "sensor_id": "10.84.60.31_Warehouse-B", "sensor_ip": "10.84.60.31", "sensor_location": "Warehouse-B", "sensor_type": "temperature_humidity", "consecutive_failures": 3, "last_error": "Connection timeout", "severity": "critical" } ``` ## 🔧 Configuration ### Sensor Configuration Add sensors to the `MODBUS_HOSTS` list in `config.py`: ```python MODBUS_HOSTS = [ # Temperature/Humidity sensors {"ip": "10.84.60.31", "location": "Warehouse-B", "type": "temperature_humidity"}, {"ip": "10.84.60.32", "location": "Warehouse-C", "type": "temperature_humidity"}, # CO2 sensors (CWT series) {"ip": "10.84.60.37", "location": "Office", "type": "cwt_co2"}, ] ``` ### Environment Variables The service supports environment variable configuration: | Variable | Description | Default | |----------|-------------|---------| | `MQTT_BROKER` | MQTT broker address | "mqtt.service.mesh" | | `MQTT_PORT` | MQTT broker port | 1883 | | `MQTT_USERNAME` | MQTT username | "relay" | | `MQTT_PASSWORD` | MQTT password | - | | `PUBLISH_INTERVAL` | Data publish interval (seconds) | 10 | | `HEALTH_CHECK_ENABLED` | Enable HTTP health server | true | | `HEALTH_CHECK_PORT` | Health server port | 8080 | | `ALERTING_ENABLED` | Enable MQTT alerts | true | | `SENSOR_TIMEOUT_THRESHOLD` | Failures before alert | 3 | | `RECOVERY_CONFIRMATION_COUNT` | Successes to confirm recovery | 2 | ## 🏥 Health Check & Monitoring ### Optional Health Check Server The service includes an optional HTTP health check server for monitoring: - **http://localhost:8080/health** - Basic service health status - **http://localhost:8080/sensors** - Detailed sensor status information ### Health Response Example ```json { "status": "healthy", "timestamp": "2024-01-15T10:30:25Z", "service": "poe-sensor", "version": "1.0.0", "sensors_total": 7, "sensors_online": 6, "sensors_health": 85.7 } ``` ### Sensor Status Response ```json { "timestamp": "2024-01-15T10:30:25Z", "total_sensors": 7, "online_sensors": 6, "offline_sensors": 1, "sensors": { "10.84.60.31_Warehouse-B": { "ip": "10.84.60.31", "location": "Warehouse-B", "type": "temperature_humidity", "status": "online", "last_success": "2024-01-15T10:29:45Z", "uptime_percentage": 98.5 } } } ``` ## 🚀 Production Deployment ### Nomad Deployment The service is designed for production deployment using HashiCorp Nomad: ```bash # Deploy to Nomad cluster nomad job run poe-sensor.nomad # Check deployment status nomad job status poe-sensor # View logs nomad alloc logs ``` ### Key Deployment Features - **No Health Check Dependencies**: Service is considered healthy when running - **Fast Deployment**: Minimal startup time requirements - **Auto-restart**: Automatic restart on application crashes - **Resource Limits**: Configured CPU and memory limits - **Log Management**: Automatic log rotation and retention ### Docker Configuration The Nomad job uses a pre-configured Docker image with: - Python 3.x runtime - Required system dependencies - Automatic dependency installation - Git-based source code deployment ## 📡 Sensor Support ### Temperature/Humidity Sensors - **Register 0**: Temperature (formula: (125 - (-40)) * raw / 1650 - 40) - **Register 1**: Humidity (formula: raw * 100 / 1000) - **Output**: Temperature in °C, Humidity in %RH ### CWT CO2 Sensors - **Register 0**: Humidity (0.1%RH resolution) - **Register 1**: Temperature (0.1°C resolution, 2's complement) - **Register 2**: CO2 (1ppm resolution) - **Output**: Temperature in °C, Humidity in %RH, CO2 in ppm ## 🔧 Troubleshooting ### Common Issues 1. **Sensor Connection Failures** - Check network connectivity to sensor IPs - Verify Modbus port (default: 505) is accessible - Check sensor power and network configuration 2. **MQTT Connection Issues** - Verify MQTT broker address and credentials - Check network connectivity to MQTT broker - Review MQTT broker logs for connection attempts 3. **Health Check Not Responding** - Health check server is optional and non-blocking - Service will continue running even if health server fails - Check port 8080 availability if health check is needed ### Log Analysis Monitor logs for key indicators: - **Connection status**: Modbus and MQTT connection messages - **Data reading**: Successful sensor data retrieval - **Publishing status**: MQTT message publication confirmation - **Error conditions**: Connection failures and retry attempts - **Sensor health**: Failure/recovery notifications ### Performance Monitoring - **Cycle completion**: Monitor sensor processing cycles - **Memory usage**: Automatic garbage collection logs - **Alert frequency**: Sensor failure and recovery alerts - **Uptime percentage**: Individual sensor reliability metrics ## 🤝 Contributing 1. Fork the repository 2. Create a feature branch (`git checkout -b feature/amazing-feature`) 3. Make your changes with proper testing 4. Commit your changes (`git commit -m 'Add amazing feature'`) 5. Push to the branch (`git push origin feature/amazing-feature`) 6. Open a Pull Request ### Development Guidelines - Follow Python PEP 8 style guidelines - Add comprehensive logging for new features - Test with multiple sensor types - Update documentation for configuration changes - Ensure backward compatibility when possible ## 📝 License This project is licensed under the MIT License - see the LICENSE file for details. ## 🆘 Support For issues and questions: 1. Check the troubleshooting section above 2. Review application logs for error details 3. Verify network connectivity and sensor configuration 4. Create an issue in the project repository with: - Detailed error description - Relevant log excerpts - Environment configuration - Steps to reproduce the issue