Name the node behind each firmware row, not just the hive it sits in - #171
Merged
Conversation
Every row under Firmware -> HiveInside nodes / HiveTraffic counters is headed by
the HIVE name ("shire-01"). That says where a node sits and nothing about which
unit it is, so a beekeeper running several identical nodes had no way to tell
them apart from the dashboard — least of all when two rows both read "relay
failed" and the question is which device to walk out to.
Each row's label now carries a "?" that names the node itself: the local name it
advertises, and the BLE address it is paired on. HiveInside 0.5.0 advertises
"HiveInside-XXXX" (the last two bytes of its address); for a node still on older
firmware the tooltip says so and offers the address, which is then the only
identifier there is. A row with neither gets no "?" rather than one that opens
onto nothing.
Firmware forwards both as nested hives[].ble.device_name / .mac. The name is
captured from the scan response alongside the identity record, on the same terms
(active scan, may arrive on a report carrying no measurement) and for every
beacon type, not only HiveInside.
HiveTraffic gets the same plumbing: bee_counter_wire.h now reads an optional
"name" from the counter's measurement JSON and forwards it as
hives[].bee_counter.device_name. No counter firmware sends one yet — a document
without it parses exactly as before — so until then the row falls back to
hives[].bee_counter.mac, which HiveHub writes before the !present return and
therefore reports even for a counter that never answered.
The counter's paired MAC is passed to writeSnapshotToHive rather than carried on
beecnt::Snapshot: it is configuration, the call site already has it, and that
struct is a MAX_HIVES-sized stack array.
Both identity fields ride in hive_readings.raw_json rather than earning a
column, like the HiveTraffic image version — they change only when a node is
re-paired and nothing charts them. Declared on HiveBleIn / HiveBeeCounterIn so
they are typed at the boundary rather than left to extra="allow".
Tests: the wire decoder gains a "name" case (read when present, empty when
absent, truncated not overrun, unterminated refused).
CI began failing on 2026-08-22 with
UnknownPackageError: Could not find the package with
'adafruit/Adafruit SHT4x Library @ 1.0.4' requirements
on a commit that had passed the same workflow fourteen hours earlier. Nothing in
the repo changed between those two runs: the PlatformIO registry pruned every
published version of this library except the newest, so the exact pin stopped
resolving. Developer machines kept building throughout, because ~/.platformio
already held the package and a cached install never re-queries the registry —
which is why this only ever showed up on a clean runner.
The registry now lists 1.0.5 alone (`pio pkg show`), and the upstream 1.0.4 tag
still exists, so this is a registry-side prune rather than an upstream
withdrawal.
Bumping is safe and slightly better than a straight unblock. Adafruit_SHT4x.h is
byte-identical between the two tags, so there is no API change; the only code
difference is that 1.0.5 deletes i2c_dev, temp_sensor and humidity_sensor before
reassigning them in begin(). This firmware re-runs begin() on every I2C heal
(see sht4x_recovery.h — reinit() is a required step of the recovery sequence, not
an edge case), so on 1.0.4 each heal leaked an Adafruit_I2CDevice and two
Adafruit_Sensor objects on a device expected to run for months.
The pinning rules at the top of platformio.ini gain a note on this failure mode,
including the instruction NOT to relax the pin to a caret range to dodge it — a
range that resolves differently on two machines is the exact problem this file is
arranged to prevent.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Every row under Firmware → HiveInside nodes / HiveTraffic counters is headed by the hive name (
shire-01). That says where a node sits and nothing about which unit it is, so a beekeeper running several identical nodes had no way to tell them apart from the dashboard — least of all when two rows both readrelay failedand the question is which device to walk out to.What changed
Each row's label carries a ? that names the node itself: the local name it advertises, and the BLE address it is paired on.
Advertises itself as "HiveInside-8A3F". BLE address C4:9D:ED:8A:3F:11.HiveInside-XXXX, so the "why is this blank" question answers itself rather than reading as a fault.Firmware
hives[].ble.device_name/.mac. The name is captured from the scan response alongside the identity record, on the same terms (active scan, may arrive on a report carrying no measurement) and for every beacon type — a beekeeper telling two HolyIots apart has the same problem.HiveTraffic
Same plumbing, end to end.
bee_counter_wire.hreads an optional"name"from the counter's measurement JSON →hives[].bee_counter.device_name. No counter firmware sends one yet — a document without it parses exactly as before — so until then the row falls back tohives[].bee_counter.mac, which HiveHub writes before the!presentreturn and therefore reports even for a counter that never answered. That is precisely the "relay failed" row where the identity matters most.The counter's paired MAC is passed to
writeSnapshotToHiverather than carried onbeecnt::Snapshot: it is configuration, the call site already has it, and that struct is aMAX_HIVES-sized stack array (carrying it there cost ~324 bytes of stack for something already in hand).Server
Two schema declarations, no migration. Both fields ride in
hive_readings.raw_jsonrather than earning a column, like the HiveTraffic image version — they change only when a node is re-paired and nothing charts them. Declared onHiveBleIn/HiveBeeCounterInso they are typed at the boundary rather than left toextra="allow".The
blepair sits after the!presentreturn, unlike the counter's: a hive with no beacon heard emits nobleobject at all, and creating one just to carry an address would change what the presence of that object means for every reader ofhive_readings. The dashboard reads the newest reading that has the field, so a node that missed one scan window keeps its identity anyway.Files
ble_sensor.{h,cpp}bee_counter_wire.h,bee_counter_client.{h,cpp},sensors.cppschemas.pyserver/dashboard/assets/views.js,website/dashboard-demo/assets/views.jshiveinside-ble-sensor.md,hivetraffic-bee-counter.mdtest_bee_counter_wire.cppTesting
Passing locally:
namecases: read when present, empty when absent, truncated not overrun, unterminated refused. Plus the existing fw:2–fw:5 contract suite._hive_reading_row_params→raw_json→_hive_reading_row_to_dict.hives[]. Confirmed all four cases (named node, unnamed node, named counter, identity-less counter → no?), no console errors.Not built: the ESP32 firmware. PlatformIO's registry (
*.platformio.org) is blocked by this environment's network policy, sopio runcannot fetch scons or the NimBLE / ArduinoJson deps. The changed C++ is unbuilt here — CI is the first real compile.Not included
FIRMWARE_VERSIONin separate commits.hives[], so the relay sections do not appear there.views.jsis kept in sync perdashboard-demo/README.md, but wiring up demo fixtures would be a separate change.Companion
Needs MacNite/HiveInside#70 for HiveInside nodes to advertise a name at all. This side is useful without it — the address fallback works today — and the tooltip tells you what to relay to get a name.
🤖 Generated with Claude Code
https://claude.ai/code/session_01T9ZUAmc45AB5Mf7ETM82Uv
Generated by Claude Code