FertiRega LoRa Infrastructure Management
This repository manages the complete LoRaWAN infrastructure for the FertiRega irrigation system, including firmware releases, gateway provisioning, device configuration, and network monitoring.
Quick Navigation:
- 📊 Provisioning Portal - Web UI for device/gateway provisioning
- 📡 ChirpStack Dashboard - LoRaWAN network server
- 🖥️ Node-RED Dashboard - Flow editor and Node-RED interface
- 📈 Dashboard UI - Real-time sensor monitoring
- 📊 Grafana Dashboards - Advanced analytics and visualization
- 🔧 GitHub Actions - Automated workflows
🏗️ Infrastructure Architecture
graph BT
subgraph DEVICES["IoT Devices"]
D1["e.g. Lisbon Main
M5Stack ATOM DTU"] D2["e.g. Cascais Main
M5Stack ATOM DTU"] end subgraph GATEWAYS["LoRa Gateways"] GW1["e.g. rpi-gateway2
Raspberry Pi + WM1302"] GW2["e.g. Dragino HP0D
EU868"] end subgraph "Lab Infrastructure - Proxmox LXC" subgraph "LXC 108: lora-server.tail20aafa.ts.net" CS[ChirpStack v4.15.0
:8080 gRPC] MQTT[Mosquitto MQTT
:1883] GWBRIDGE[Gateway Bridge
:1700 UDP] end subgraph "LXC 109: node-red.tail20aafa.ts.net" NR[Node-RED v4.1.1
:1880] GRAFANA[Grafana Dashboards
:1880/ui/] end subgraph "LXC 110: thingsboard.tail20aafa.ts.net" TB[ThingsBoard CE
:8080] end end DEVICES -.->|LoRaWAN EU868| GATEWAYS GATEWAYS -->|Semtech UDP :1700| GWBRIDGE GWBRIDGE --> CS CS --> MQTT MQTT --> NR MQTT --> TB NR --> GRAFANA style CS fill:#4CAF50 style MQTT fill:#FF9800 style NR fill:#2196F3 style TB fill:#9C27B0 style DEVICES fill:#E91E63,stroke:#C2185B,stroke-width:3px style GATEWAYS fill:#00BCD4,stroke:#0097A7,stroke-width:3px
M5Stack ATOM DTU"] D2["e.g. Cascais Main
M5Stack ATOM DTU"] end subgraph GATEWAYS["LoRa Gateways"] GW1["e.g. rpi-gateway2
Raspberry Pi + WM1302"] GW2["e.g. Dragino HP0D
EU868"] end subgraph "Lab Infrastructure - Proxmox LXC" subgraph "LXC 108: lora-server.tail20aafa.ts.net" CS[ChirpStack v4.15.0
:8080 gRPC] MQTT[Mosquitto MQTT
:1883] GWBRIDGE[Gateway Bridge
:1700 UDP] end subgraph "LXC 109: node-red.tail20aafa.ts.net" NR[Node-RED v4.1.1
:1880] GRAFANA[Grafana Dashboards
:1880/ui/] end subgraph "LXC 110: thingsboard.tail20aafa.ts.net" TB[ThingsBoard CE
:8080] end end DEVICES -.->|LoRaWAN EU868| GATEWAYS GATEWAYS -->|Semtech UDP :1700| GWBRIDGE GWBRIDGE --> CS CS --> MQTT MQTT --> NR MQTT --> TB NR --> GRAFANA style CS fill:#4CAF50 style MQTT fill:#FF9800 style NR fill:#2196F3 style TB fill:#9C27B0 style DEVICES fill:#E91E63,stroke:#C2185B,stroke-width:3px style GATEWAYS fill:#00BCD4,stroke:#0097A7,stroke-width:3px
Data Flow:
- Devices → LoRaWAN uplinks (sensor data, GPS, battery status)
- Gateways → Forward packets to ChirpStack via Tailscale VPN
- ChirpStack → Decodes payloads, manages OTAA joins, queues downlinks
- MQTT Broker → Publishes uplink/downlink events
- Node-RED → Processes MQTT messages, stores in InfluxDB, displays in Grafana
- ThingsBoard → Optional IoT platform for advanced dashboards
📡 Registered Gateways
Note: Gateway information is automatically sourced from
manifest.json. The manifest is updated automatically by the Setup RPi Gateway workflow during gateway provisioning (see Provisioning tab).
| Gateway ID | Name | Hardware | OS | Local IP | Tailscale IP | Status |
|---|---|---|---|---|---|---|
| rpi-lora-gw-01.tail20aafa.ts.net | Raspberry Pi Gateway 01 | RPi 4 4GB + WM1302 HAT | Debian 12 | 192.168.52.199 | 100.98.189.41 | 🟢 Online |
| rpi-gateway2.tail20aafa.ts.net | RPi Gateway 2 | RPi 4 4GB + WM1302 HAT | Debian 13 | 192.168.52.197 | 100.106.81.30 | 🟢 Online |
| dragino-27ec14 | Dragino HP0D | Dragino HP0D EU868 | Embedded Linux | 192.168.52.198 | 100.107.37.85 | 🟢 Online |
🔌 Registered Devices
Note: Device information is automatically sourced from
manifest.json. The manifest is updated automatically by the Provision Device via Gateway workflow during device provisioning (see Provisioning tab).
| Device ID | Name | Location | DevEUI | Hardware | Sensors |
|---|---|---|---|---|---|
| lisbon-main | Lisbon Main Control Unit | Lisbon Facility | 70b3d57ed006a215 | M5Stack ATOM DTU | GXHTC3 (temp/humidity), 2x YF-S201 (flow), 2x valve control |
| cascais-main | Cascais Main Control Unit | Cascais Facility | 00f76bb00200820a | M5Stack ATOM DTU | GXHTC3 (temp/humidity), 2x YF-S201 (flow), 2x valve control |
🖥️ Lab Infrastructure
Proxmox LXC Containers
| Container | Hostname | IP (Tailscale) | OS | Resources | Services |
|---|---|---|---|---|---|
| LXC 108 | lora-server.tail20aafa.ts.net | 100.92.66.20 | Debian 12 | 4GB RAM, 2 CPU, 20GB | ChirpStack v4.15.0, PostgreSQL 16 + TimescaleDB, Redis, Mosquitto MQTT, Gateway Bridge |
| LXC 109 | node-red.tail20aafa.ts.net | 100.90.47.36 | Debian 12 | 1GB RAM, 1 CPU, 8GB | Node-RED v4.1.1, InfluxDB client, Grafana dashboards |
| LXC 110 | thingsboard.tail20aafa.ts.net | 100.87.74.33 | Debian 12 | 6GB RAM, 2 CPU, 30GB | ThingsBoard CE, PostgreSQL (dedicated) |
Service Ports
| Service | Container | Port | Protocol | Access |
|---|---|---|---|---|
| ChirpStack gRPC API | LXC 108 | 8080 | HTTP/gRPC | http://lora-server.tail20aafa.ts.net:8080 |
| ChirpStack REST API | LXC 108 | 8090 | HTTP/REST | http://lora-server.tail20aafa.ts.net:8090 |
| Gateway Bridge | LXC 108 | 1700 | UDP | Internal only |
| Mosquitto MQTT | LXC 108 | 1883 | MQTT | Internal only |
| Node-RED Editor | LXC 109 | 1880 | HTTP | http://node-red.tail20aafa.ts.net:1880 |
| Node-RED Dashboard UI | LXC 109 | 1880/ui/ | HTTP | http://node-red.tail20aafa.ts.net:1880/ui/ |
| Grafana | LXC 109 | 3000 | HTTP | http://node-red.tail20aafa.ts.net:3000 |
| ThingsBoard | LXC 110 | 8080 | HTTP | http://thingsboard.tail20aafa.ts.net:8080 |
📦 Release Checksums
Every firmware release includes cryptographic checksums (MD5 and SHA256) to verify the integrity of downloaded files. This ensures your firmware hasn't been corrupted or tampered with during download.
Where to find checksums:
- Navigate to the Releases page
- Select the desired release version
- Download
zephyr.bin.checksums.txtalongside the firmware binary - Verify the downloaded
zephyr.binmatches the published checksums before flashing
Example verification:
# macOS/Linux - verify SHA256
shasum -a 256 zephyr.bin
# Compare output with zephyr.bin.checksums.txt
# macOS/Linux - verify MD5
md5sum zephyr.bin
# Compare output with zephyr.bin.checksums.txt
🔐 Security
- All credentials managed via Bitwarden Secrets Manager (BWS)
- Tailscale VPN for secure remote access (Tailnet: tail20aafa.ts.net)
- SSH key-based authentication (no passwords)
- ChirpStack API tokens rotated via BWS
Uplink Payload Decoder
Enter uplink payload in hex format (with or without spaces)
Downlink Command Encoder
Hex:
Base64:
Payload Format Reference
Uplink Payload Structure
Each uplink contains a timestamp followed by sensor blocks:
[Timestamp (4B LE)] [Sensor Block 1] [Sensor Block 2] ...
Sensor block format: [Sensor ID (2B LE)] [Data Length (1B)] [Sensor Data (variable)]
Supported Sensors
- BATTERY_POWER (0x0000): Battery percentage + charging status (2 bytes)
- GX_HTC (0x0004): Temperature + humidity (8 bytes - IEEE 754 LE floats)
- OUTDOOR_VALVE (0x0006): Valve states + pulse counters + flow data (34 bytes)
- GPS_LOCATION (0x000B): Latitude + longitude + confirmed flag (9 bytes - IEEE 754 LE floats)
Downlink Command Structure (Extended Format)
[Timestamp (4B LE)] [MessageID (2B LE)] [TaskType (1B)] [Instruction (1B)] [Parameters...]
All downlink commands must use fPort 2
End Device Provisioning
Gateway Provisioning (Raspberry Pi + WM1302)
Complete hardware setup for gateways already registered via setup-tailscale.sh
Gateways registered in manifest via setup-tailscale.sh
Default SSH user (usually 'pi')
Initial SSH password (will be replaced with keypair)
Leave empty for default (38.7688141)
Leave empty for default (-9.0928242)