2025-06-24 09:31:26 +00:00

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

pip install -r requirements.txt

2. Configure Settings

Edit config.py to match your environment:

# 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

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 flat topic structure for each location:

Location/{location}/Time         # Timestamp
Location/{location}/Status       # "online" or "offline"
Location/{location}/Temperature  # Temperature value
Location/{location}/Humidity     # Humidity value
Location/{location}/CO2          # CO2 sensors only
Location/{location}/alerts       # Alert messages

Note: The CO2 topic is only published for sensors that support CO2 measurement.

Example Topics

Location/Warehouse-B/Time        → "2024-01-15 10:30:25"
Location/Warehouse-B/Status      → "online"
Location/Warehouse-B/Temperature → "23.5"
Location/Warehouse-B/Humidity    → "65.2"

Location/Office/Time        → "2024-01-15 10:30:25"
Location/Office/Status      → "online"
Location/Office/Temperature → "24.1"
Location/Office/Humidity    → "58.3"
Location/Office/CO2         → "420"

Alert Format

{
  "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:

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
TIMEZONE_OFFSET Timezone offset from UTC (hours) 7 (GMT+7)

🏥 Health Check & Monitoring

Optional Health Check Server

The service includes an optional HTTP health check server for monitoring:

Health Response Example

{
  "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

{
  "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:

# Deploy to Nomad cluster
nomad job run poe-sensor.nomad

# Check deployment status
nomad job status poe-sensor

# View logs
nomad alloc logs <allocation_id>

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
Description
No description provided
Readme 149 KiB
Languages
Python 90.7%
HCL 9.3%