A lightweight environmental monitoring system for server rooms built on Raspberry Pi 4 with Sense HAT. Features real-time monitoring, REST API, Slack webhook alerts, and production-ready deployment options.
- Features
- Hardware Requirements
- Quick Start
- Configuration
- API Reference
- Webhook Notifications
- Deployment
- Troubleshooting
- Contributing
- Real-time Monitoring: Temperature with CPU heat compensation, humidity tracking
- Web Dashboard: Auto-refreshing interface at port 8080
- REST API: JSON endpoints with Bearer token authentication
- Swagger Documentation: Interactive API docs at
/docs - Slack Webhooks: Threshold-based alerts with configurable cooldowns
- Periodic Status Updates: Scheduled status reports via webhook
- LED Display: Current temperature on Sense HAT matrix
- Production Ready: Waitress WSGI server, health checks, metrics endpoint
- Docker Support: Pre-configured docker-compose for easy deployment
- Raspberry Pi 4 (2GB+ RAM recommended)
- Sense HAT add-on board
- 5V/3A USB-C power supply
- (Optional) Case for the Raspberry Pi
git clone https://github.com/freightcognition/temp_monitor.git
cd temp_monitor
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txtcp .env.example .env
# Generate a bearer token (required)
python3 -c "import secrets; print(secrets.token_hex(32))"
# Add the output to .env as BEARER_TOKEN=<token># Development
python temp_monitor.py
# Production (with Waitress)
./start_production.sh
# Docker
docker compose up -dAccess the dashboard at http://[raspberry-pi-ip]:8080
All configuration is done via environment variables in .env. Copy .env.example to get started.
| Variable | Default | Description |
|---|---|---|
BEARER_TOKEN |
(required) | API authentication token |
LOG_FILE |
temp_monitor.log |
Log file path |
CLOUDFLARED_TOKEN |
(required for CI) | Cloudflare Tunnel token for docker-compose cloudflared service (optional for local dev) |
| Variable | Default | Description |
|---|---|---|
SLACK_WEBHOOK_URL |
(optional) | Slack incoming webhook URL for alerts |
WEBHOOK_ENABLED |
true |
Enable/disable notifications |
WEBHOOK_RETRY_COUNT |
3 |
Retry attempts (1-10) |
WEBHOOK_RETRY_DELAY |
5 |
Initial retry delay in seconds |
WEBHOOK_TIMEOUT |
10 |
Request timeout in seconds |
| Variable | Default | Description |
|---|---|---|
ALERT_TEMP_MIN_C |
15.0 |
Low temperature alert (Celsius) |
ALERT_TEMP_MAX_C |
32.0 |
High temperature alert (Celsius) |
ALERT_HUMIDITY_MIN |
20.0 |
Low humidity alert (%) |
ALERT_HUMIDITY_MAX |
70.0 |
High humidity alert (%) |
| Variable | Default | Description |
|---|---|---|
STATUS_UPDATE_ENABLED |
false |
Enable periodic status reports |
STATUS_UPDATE_INTERVAL |
3600 |
Interval in seconds (min: 60) |
STATUS_UPDATE_ON_STARTUP |
false |
Send status on startup |
| Endpoint | Method | Description |
|---|---|---|
/ |
GET | Web dashboard |
/docs |
GET | Swagger UI documentation |
/health |
GET | Health check for load balancers |
/metrics |
GET | Application and system metrics |
Include header: Authorization: Bearer YOUR_TOKEN
| Endpoint | Method | Description |
|---|---|---|
/api/temp |
GET | Current temperature and humidity |
/api/raw |
GET | Raw sensor data for debugging |
/api/verify-token |
GET | Validate authentication token |
| Endpoint | Method | Description |
|---|---|---|
/api/webhook/config |
GET | Get current webhook configuration |
/api/webhook/config |
PUT | Update webhook config and thresholds |
/api/webhook/test |
POST | Send a test webhook message |
/api/webhook/enable |
POST | Enable webhook notifications |
/api/webhook/disable |
POST | Disable webhook notifications |
# Get temperature data
curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:8080/api/temp
# Response:
{
"temperature_c": 23.5,
"temperature_f": 74.3,
"humidity": 45.2,
"timestamp": "2024-01-15 14:23:45"
}
# Health check (no auth needed)
curl http://localhost:8080/health
# Response:
{
"status": "healthy",
"uptime_seconds": 12345,
"sensor_thread_alive": true,
"timestamp": 1705329825.123
}
# Update webhook thresholds
curl -X PUT http://localhost:8080/api/webhook/config \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"thresholds": {
"temp_min_c": 18.0,
"temp_max_c": 25.0
}
}'When configured with a Slack webhook URL, the system sends alerts when readings exceed thresholds.
- Temperature High: Triggered when temp >
ALERT_TEMP_MAX_C - Temperature Low: Triggered when temp <
ALERT_TEMP_MIN_C - Humidity High: Triggered when humidity >
ALERT_HUMIDITY_MAX - Humidity Low: Triggered when humidity <
ALERT_HUMIDITY_MIN
- Alert Cooldown: 5-minute cooldown between same alert type (prevents spam)
- Exponential Backoff: Retries with increasing delays on failure
- URL Masking: Webhook URLs are masked in API responses and logs for security
- Go to Slack API
- Create a new app or use an existing one
- Enable Incoming Webhooks
- Create a webhook for your channel
- Copy the URL to
SLACK_WEBHOOK_URLin.env
# Create logs directory and configure
mkdir -p logs
cp .env.example .env
# Edit .env with your settings
# Build and run
docker compose up -d
# View logs
docker compose logs -f
# Stop
docker compose downNote: Requires privileged mode for I2C/hardware access.
Cloudflare Tunnel: The bundled Cloudflare Tunnel service starts automatically:
- Add
CLOUDFLARED_TOKENto.env - Start with:
docker compose up -d - In Cloudflare Zero Trust UI, point the tunnel service at
http://temp-monitor:8080
Note: CLOUDFLARED_TOKEN is required for CI/production - the CI workflow (.github/workflows/ci.yml:79-83) enforces this and will fail deployment if missing. For local development, the token is optional: if not set, the cloudflared service will fail to start but the main temp-monitor service continues working. To run locally without Cloudflare Tunnel, use docker compose up -d temp-monitor.
sudo cp deployment/systemd/temp-monitor.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable temp-monitor.service
sudo systemctl start temp-monitor.serviceIf you are using Docker Compose, use deployment/systemd/temp-monitor-compose.service instead (update the WorkingDirectory and User).
- Memory Limit: 512MB (configurable)
- Server: Waitress WSGI, single worker/thread
- Health Checks: Every 30 seconds via
/health - Auto-restart: On failure with 10-second delay
For detailed production deployment, see docs/PI4_DEPLOYMENT.md.
The Sense HAT is affected by CPU heat. The system compensates using:
compensated_temp = raw_temp - ((cpu_temp - raw_temp) * factor)
The default factor is 0.7. Adjust in temp_monitor.py if readings seem inaccurate.
| Issue | Solution |
|---|---|
| Sense HAT not detected | Enable I2C via sudo raspi-config, check connection |
| Port 8080 blocked | Check firewall: sudo ufw allow 8080 |
| Inaccurate temperature | Adjust compensation factor in code |
| Webhook failures | Check URL, network connectivity, view logs |
| API returns 401/403 | Verify Bearer token in request header |
| Service won't start | Check logs: journalctl -u temp-monitor -f |
| Package | Version | Description |
|---|---|---|
| Flask | 2.3.3 | Web framework |
| Flask-RESTX | 1.3.0+ | REST API with Swagger |
| sense-hat | 2.6.0 | Sense HAT library |
| python-dotenv | 1.0.0 | Environment management |
| requests | 2.31.0 | HTTP client for webhooks |
| waitress | 2.1.2+ | Production WSGI server |
| psutil | 5.9.0+ | System metrics (optional) |
Contributions are welcome! Please feel free to submit a Pull Request.
