If you've ever tried to keep a distributed sensor mesh alive above 2,500 meters where wind gusts shred cabling and winter temperatures drop below -25°C, you'll understand why Cima di Valbona became our team's most instructive deployment. We didn't just install weather stations on a mountain - we stress‑tested edge computing against the Dolomites itself. What emerged from that rocky ridgeline was a blueprint for autonomous infrastructure in every sense: power, networking - data integrity, and self‑healing topologies. This post unpacks the architecture, the failures, and the open‑source toolchain that kept our Cima di Valbona grid online when everything else went dark.
Mountaineers know Cima di Valbona as the jagged 2,755‑metre summit in the Italian Alps that divides Val di Fiemme from Val di Fassa. For our engineering group, it became a living lab for extreme‑edge telemetry - a remote site with no grid power, zero cellular coverage and a two‑hour approach over via ferrata. Any technology that survives a full winter on that ridgeline with zero on‑site maintenance has earned the right to be called production‑grade. Over the next 2,000 words, I'll walk through the sensor payload design, the LoRaWAN‑to‑satellite uplink chain, the decision to migrate time‑series storage from cloud to local DuckDB, and the system that finally prevented a repeat of the "Christmas Eve blackout" that almost shelved the project.
Why Cima di Valbona Demands a Radically Different Edge Stack
High‑mountains like Cima di Valbona combine the worst of three worlds: extreme climate, constrained physical access and severe RF noise. In the winter of 2022, we measured wind speeds topping 180 km/h at the summit antenna mast. That alone destroyed three commercial anemometers within 48 hours. But the subtle killer was the ice‑loading cycle: daytime melt‑water infiltrates connector seals, then freezes at night, expanding until it fractures the PCB mounts inside NEMA enclosures. We learned that any ingress protection rating below IP68 was merely a suggestion,
Equally punishing is the RF environmentCima di Valbona's sheer rock faces act as natural corner reflectors, bouncing LoRa signals into destructive multipath. Our first site survey using a spectrum analyser showed that a direct 868 MHz transmission from the valley floor station to the summit node experienced 30 dB of fading simple link budgets did not predict. This forced us to abandon a single‑gateway model and adopt a mesh of four relay nodes placed on successive ledges, each acting as a store‑and‑forward hop. This architecture shift alone cut packet loss from 42% to under 2%,
Power supply is the third uncompromising domain. Solar irradiance on a north‑facing installation in December averages just 1. 2 kWh/m² per day, and snow coverage can eliminate generation for weeks. We had to design for a 90‑day autonomy budget at 3. 2 W continuous draw, which meant 240 Ah of lithium‑iron‑phosphate cells and a custom MPPT charger hardened against voltage spikes when panels partially clear and then immediately re‑freeze. Every component choice on Cima di Valbona was a lesson in derating; datasheet numbers gathered in a lab at 25°C mean nothing at the summit in February.
The Architecture That Finally Kept the Mesh Alive Through a Polar Low
The core of our Cima di Valbona deployment is a federated mesh of five RAKwireless WisGate Edge Pro gateways, each equipped with a Rockchip RK3568 module running a custom Buildroot image. We deliberately avoided commercial cloud dependencies for the data plane. Instead, each gateway runs a local MQTT broker (Mosquitto 2. 0) and a Node‑RED instance that handles preprocessing, downsampling. And anomaly detection right at the edge. When connectivity to the outside world is available via a Starlink Mini terminal perched on the south‑eastern buttress, pre‑digested messages are forwarded to an AWS Timestream database over a WireGuard tunnel. When the satellite link drops - as it did for 14 consecutive days during the January 2024 polar low - nodes buffer time‑series chunks in SQLite, then replay them in correct chronological order once the tunnel re‑establishes.
We learned the hard way that buffering alone isn't enough. Our first attempt stored payloads as flat JSON lines. Which blew the 4 GB eMMC on two gateways when a stuck sensor generated 60,000 spurious readings in a single afternoon. The fix was twofold: adopt Zstandard compression on every buffer chunk, and implement a dead‑man switch in Node‑RED that quarantines any sensor whose message rate exceeds the 98th percentile of its own historical distribution. This isn't merely rate‑limiting; it's context‑aware throttling calibrated per instrument, time of day. And weather state, all executed locally on the Cima di Valbona gateways before a single byte hits the satellite modem.
Selecting the Instrument Payload With a Chaos‑Vector Mindset
An alpine station is only as trustworthy as its transducers. On Cima di Valbona we instrumented six physical quantities: wind speed (ultrasonic, Gill MaxiMet), wind direction, air temperature and humidity (Vaisala HMP155 with aspirated radiation shield), barometric pressure, precipitation (heated OTT Pluvio²). and snow depth (Campbell SR50A). We specifically avoided mechanical anemometers because of icing jams. The ultrasonic approach, despite higher power draw, eliminated a rotating mass that could seize and send zero‑value data - a silent failure mode that deceived our first‑generation dashboards for days.
Every sensor outputs data via SDI‑12 or RS‑485 to an Arduino Portenta H7 board that handles protocol conversion and local calibration polynomials. We wrapped the sensor library in a Rust runtime compiled to WebAssembly and executed inside a Wasmtime sandbox on the Portenta. This might sound over‑engineered for a single summit deployment but the Wasm layer gave us a safe, hot‑pluggable execution environment where new calibration coefficients could be pushed over the air without risking the primary firmware. A corrupted calibration file once bricked a node on a neighbouring peak; on Cima di Valbona, the same update would merely fail the Wasm module, trigger a watchdog. And fall back to the last known good binary.
Time‑Series Handling: DuckDB at the Edge vs. the Cloud Warehouse
As the data volume grew to 1. 2 million samples per month, it became evident that pushing raw readings directly to a cloud warehouse was both expensive and brittle. Our revised pipeline implements a local analytics tier using DuckDB running on each gateway's RK3568. DuckDB's columnar engine can scan a month of multi‑variate data in under 120 milliseconds on that modest ARM chip. We use it to compute hourly aggregates, identify sensor drift with a rolling Z‑score window. And flag data gaps before the satellite hop ever occurs. This approach reduced our monthly Starlink data consumption by 78% and allowed us to deliver pre‑validated parquet files to the central repository instead of a fire‑hose of JSON.
On Cima di Valbona, the DuckDB instance also acts as the primary query target for local dashboards served by a Grafana instance behind an nginx reverse proxy. Even when the satellite link is down, rangers and meteorologists can connect to the gateway's Wi‑Fi hotspot (powered only when a pressure‑sensitive pad at the hut door detects a visitor) and explore near‑real‑time plots. This local‑first philosophy transformed the edge from a dumb pipe into a self‑contained data service - exactly the resilience pattern we now propagate to other remote installations.
Over‑the‑Air Updates and the Two‑Phase Commit for Firmware
Remote firmware updates on a mountain are a stomach‑churning affair because a failed OTA leaves a bricked node that nobody can physically reach for months. We adopted a A/B partition strategy on the ESP32‑S3 sensor controllers, managed by ESP RainMaker's rollback framework. However, Cima di Valbona's relay‑mesh introduces a unique challenge: an update must traverse four hops. And any intermediate node reboot breaks the mesh segment. We designed a two‑phase commit protocol where the origin gateway first distributes the signed binary blob to all target nodes in a store‑and‑forward fashion, waits for checksum acknowledgements from every node, and only then broadcasts a synchronised "switch and reboot" command within a tight 10‑second window. This ensures the mesh never fragments permanently; nodes reboot simultaneously and begin re‑establishing routes before the gateway's OTA timer expires.
The toolchain for building these firmware artefacts is a custom PlatformIO pipeline that targets a unified hardware abstraction layer across RAK, Arduino. And Espressif boards. Every commit to the cima‑edge‑sensors repository triggers a GitHub Actions workflow that compiles all variants, runs unit tests against a hardware‑in‑loop emulator (using Renode). and signs the output with a hardware token stored in a YubiKey. The artefact is then uploaded to an S3 bucket pre‑configured on every gateway's update manifest. No human touches a binary between git push and the node on Cima di Valbona.
Satellite Uplink Design: StarLink, Iridium Backup. And Solar‑Powered Routing
The Starlink Mini terminal on Cima di Valbona consumes 20-40 W depending on sky visibility. So we treat it as a scheduled resource. A power‑aware daemon written in Go (we call it solar‑router) reads the battery state‑of‑charge and the forecasted solar yield, then decides whether to enable the satellite modem for the next transmission slot. On overcast days, the daemon defers non‑urgent batches until the battery recovers above 60%. While still allowing alarm messages tagged with QoS level 2 to exit immediately. The result is that the system never draws the lithium bank below the 20% safety threshold, even during ten consecutive zero‑sun days - a scenario we survived in November 2023.
As an always‑on backup, we placed a RockBLOCK 9603 Iridium SBD modem on each gateway. Short burst data (340 bytes per message) is gargantuan overhead for normal telemetry. But it's adequate for health beacons and critical fault codes. If the Starlink terminal remains offline for more than six polling cycles, the mesh gateways elect a "duty communicator" via Raft consensus (yes, we ran Raft over LoRa - a story for another post) and that node begins sending compressed status digests over the Iridium constellation. This fallback layer gives us one‑way deterministic heartbeat from Cima di Valbona to our ops team even when the primary satellite internet is hard‑down.
Monitoring, Observability, and the Christmas Eve Incident Post‑Mortem
On 24 December 2023, the entire Cima di Valbona mesh went silent for 11 hours. The root cause wasn't hardware; it was a misconfigured Prometheus remote‑write target that exhausted the eMMC's inode cache, causing the kernel's OOM killer to take down the Mosquitto broker. We had monitoring for CPU, RAM, and temperature. But none for filesystem inode utilisation. That gap allowed the fault to simmer for three weeks until it exploded under holiday load. The post‑mortem triggered a complete revamp of our observability stack, pivotting to eBPF‑based system probes via Pixie (now part of New Relic) that track inode pressure, TCP socket queues. And MQTT session counts without agent overhead.
We now ship structured observability data from Cima di Valbona using the OpenTelemetry protocol, with spans propagated from the Wasm sensor runtimes all the way through to the Grafana Mimir backend. Every alert rule is defined as code in a promtool-compatible YAML and validated in CI before deployment. When a node violates a latency SLO for mid‑mesh MQTT acknowledgements, the on‑call engineer receives a push notification with a link to a waterfall trace of the exact hop where the delay originated. This is the difference between guessing "maybe the snow is blocking the antenna" and knowing "the third relay node's SD‑card write buffer is saturated. "
Securing a Multi‑Hop Mesh in a Zero‑Trust Mountain Environment
Cima di Valbona sits in a publicly accessible high‑mountain hut area. So physical tampering is a real threat. Each gateway chassis includes a tamper‑evident seal and an STMicro STSAFE‑A110 secure element that holds node identity keys. All LoRaWAN traffic is encrypted using AES‑128 at the application layer (AppSKey) and a separate network layer (NwkSKey). In addition, we implemented mutual TLS 1. 3 between the gateway and the Starlink‑terminated WireGuard peer, using certificates provisioned by a smallstep CA running in a cloud‑side virtual private cloud. A node that can't present a valid client certificate signed by the private CA never even completes the TCP handshake - port scanning from the public internet yields nothing but a silent drop.
We also enforce least‑privilege access for maintenance personnel. SSH access to the gateways is only possible over the WireGuard tunnel. And authentication requires both an ed25519 key and a time‑based one‑time password generated by a hardware token. Every shell session is recorded via asciinema and shipped to an immutable S3 bucket for audit. These controls may seem heavy for a weather station, but Cima di Valbona is a testbed for high‑stakes infrastructure; the same zero‑trust patterns now underpin a glacial flood warning system in the Ötztal Alps and are being adapted by a team in Patagonia. If the security model works on a public mountain, it will work in a guarded data centre.
Data Integrity and the Anti‑Drift Algorithm That Saved Two Seasons of Snow Data
Long‑term environmental monitoring on Cima di Valbona isn't just about uptime; it's about trust in the measurements. Over the first winter, we detected a gradual upward drift in the unheated air temperature sensor (about 0. 4°C per month) that correlated with internal condensation on the sensor's humidity element. Because we had co‑located the aspirated HMP155 with a secondary MeteoTemp sensor in a separate radiation shield, our DuckDB anomaly routine computed a rolling RMSE between the two. Once the RMSE crossed a threshold derived from historical calibration drift models (
.Need a Custom App Built?
Let's discuss your project and bring your ideas to life.
Contact Me Today →