Overview
Beyond the local web dashboard, I also wrote the application layer that interfaces the Pi with the cloud backend. This is the hive-monitor-agent — a Python application running on the Pi that publishes sensor data, receives commands, and manages device state through MQTT and REST APIs. Full networking protocol details are on the Week 11 — Networking and Communications page; this section focuses on the application code that interfaces the user (via the cloud dashboard) with the input/output devices on the Pi.
What the Application Does
The agent application is the bridge between the physical devices (sensors, cameras, servo, LEDs) and the user's cloud dashboard. It:
- Reads sensors — polls SHT45 temperature/humidity sensors every 60 seconds via I²C multiplexer, formats readings into structured JSON
- Publishes telemetry — sends sensor data, weight, door state, fan state, and GPS coordinates to AWS IoT Core over MQTT
- Receives commands — subscribes to MQTT topics for door open/close, LED control, and camera start/stop
- Manages device shadow — reports current device state and receives desired-state deltas from the cloud (config changes, metadata updates)
- Buffers offline — queues publishes in a local SQLite database when the network is down, replays them on reconnect
Application Architecture
┌─────────────────────────────────────────────────────┐
│ hive-monitor-agent (Python) │
├─────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────┐ │
│ │ Driver │ │ Telemetry │ │ Command │ │
│ │ Scheduler │ │ Publisher │ │ Handler │ │
│ │ │ │ │ │ │ │
│ │ • SHT45 read │ │ • 60s cycle │ │ • door │ │
│ │ • HX711 read │ │ • JSON fmt │ │ • LED │ │
│ │ • door state │ │ • QoS 1 │ │ • camera │ │
│ └──────┬───────┘ └──────┬───────┘ └────┬─────┘ │
│ │ │ │ │
│ ┌──────▼──────────────────▼───────────────▼─────┐ │
│ │ MQTT Client (paho-mqtt) │ │
│ │ • mTLS with X.509 cert │ │
│ │ • Auto-reconnect with exponential backoff │ │
│ │ • LWT for disconnect detection │ │
│ └──────────────────────┬────────────────────────┘ │
│ │ │
│ ┌──────────────────────▼────────────────────────┐ │
│ │ Offline Buffer (SQLite) │ │
│ │ • /var/lib/hive-monitor/buffer.db │ │
│ │ • 7-day / 500 MB FIFO cap │ │
│ │ • Replay at ≤50 msg/s on reconnect │ │
│ └───────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
│
│ TCP 8883 (MQTT over mTLS)
▼
AWS IoT Core → Cloud Dashboard (user interface)
Key Interfaces
1. REST API — Bootstrap & Binding
Before the MQTT connection is established, the Pi uses a REST API client to bootstrap itself:
| Endpoint |
Method |
Purpose |
/devices/{serial}/bind-packet | GET | Poll for device credentials (cert, key, config) |
/hives/bind | POST | Manual bind with one-time token |
The bootstrap application handles HTTP response codes intelligently: 404 means "keep polling" (device not claimed yet), 200 means install the bind packet, anything else triggers exponential backoff (10s → 300s cap).
2. MQTT — Telemetry Publishing
The main application interface is MQTT publish/subscribe. The agent formats sensor readings into JSON and publishes to topic-scoped channels:
// Example telemetry payload published every 60s
{
"timestamp": "2026-05-18T14:30:00Z",
"seq": 4521,
"sensors": {
"brood_box": {"temp_c": 34.8, "humidity_pct": 62.1},
"super_1": {"temp_c": 31.2, "humidity_pct": 58.4},
"ambient": {"temp_c": 22.5, "humidity_pct": 45.0}
},
"weight_kg": 38.7,
"door_state": "open",
"fan_state": "auto",
"fan_rpm": 3200,
"led_state": "off",
"gps": {"lat": 35.227, "lon": -80.843}
}
3. MQTT — Command Handling
The application subscribes to downlink topics and executes commands on the physical devices:
.../door/command → drives the servo to open/close the entrance gate
.../led/command → toggles LED boards via GPIO MOSFETs
.../camera/{channel}/control → starts/stops camera streaming sessions
Each command includes a request_id for idempotent deduplication — if the same command arrives twice (network retry), the application only executes it once.
4. Device Shadow — State Synchronization
The AWS IoT Device Shadow provides a persistent state store that syncs between the Pi and the cloud dashboard:
- Reported state — the Pi publishes what it's currently doing (sensor readings, door position, config version)
- Desired state — the cloud dashboard sets what it wants (new sampling rate, updated sensor config, metadata changes)
- Delta — when desired ≠ reported, the Pi receives a delta and applies the change
This means a user can change the hive's sampling interval from the web dashboard, and the Pi picks it up automatically — even if it was offline when the change was made.
Technologies Used
- Python — application logic, sensor drivers, MQTT client
- paho-mqtt — MQTT 5 client library with mTLS support
- HTTPS (urllib/requests) — REST API client for bootstrap and binding
- SQLite — offline message buffer with FIFO eviction
- JSON — structured data format for all API payloads
- X.509 certificates — mutual TLS authentication
- systemd — service management, auto-restart, conditional startup
Repository Structure — Smart-Beehive
The application code lives in the hive-monitor repository. Key directories:
hive-monitor/
├── pi/
│ ├── agent/ # hive-monitor-agent — main application
│ │ ├── drivers/ # Sensor drivers (SHT45, HX711, camera)
│ │ ├── mqtt_client.py # MQTT connection, pub/sub, reconnect logic
│ │ ├── telemetry.py # Telemetry publisher (60s cycle)
│ │ ├── command_handler.py # Downlink command execution (door, LED, camera)
│ │ ├── shadow_client.py # AWS IoT Device Shadow sync
│ │ └── offline_buffer.py # SQLite FIFO buffer for network outages
│ ├── installer/
│ │ └── bind.sh # Device binding script (manual path)
│ ├── bootstrap/
│ │ └── bootstrap.py # Fleet bootstrap polling service
│ └── image/ # Pi OS image build scripts
├── docs/ # Architecture docs, manual bind guide
└── .github/workflows/ # CI — image builds, linting
The agent is structured as a set of cooperating services managed by systemd. Each driver (sensor, camera, servo) runs independently and publishes to shared state that the telemetry publisher picks up on its 60-second cycle.
How This Meets the Assignment
| Requirement |
How It's Met |
| Write an application |
Python MQTT agent + REST API client running as a systemd service |
| Interfaces a user with a device |
User controls door/LEDs and views sensor data through cloud dashboard, which communicates with the Pi via MQTT |
| Input device you made |
Custom sensor extension board (Week 9) — SHT45 readings published as telemetry |
| Output device you made |
Custom LED PCBs (Week 10) — controlled via MQTT commands from the dashboard |
See Week 11 — Networking and Communications for the full protocol specification (MQTT topics, auth model, firewall rules, offline behavior).