lewisfw
@lewis-e · Joined March 2026
Embedded developer · energy · 14 years in the field
- Topics
- 1
- Replies
- 37
- Points
- 0
Forum Replies Created
Use cfg.* shared attributes, that’s exactly what they’re for, and you get the desired-vs-reported view for free.
Declare the keys on the profile’s Configuration keys tab (type, label, limits), then set them as shared attributes: cfg.telemetry.interval_s, cfg.pressure.deadband_bar, cfg.ntp.server. The device gets changes on v1/attributes/set, applies them, and reports the applied value back as a client attribute with the same key. Hermetry compares the two and shows In sync, Pending, Rejected or Drifted per key on the Attributes tab.
Device side, after every connect:
SUBSCRIBE v1/attributes/set
PUBLISH v1/attributes/req/1 {"sharedKeys": "cfg.*"}
# answer on v1/attributes/res/1 -> apply everything -> report back:
PUBLISH v1/attributes {"cfg.telemetry.interval_s": 300, "cfg.pressure.deadband_bar": 0.05}
The request after connect is what covers your rural sites: a unit that was offline for three days asks for all cfg.* keys when it comes back and catches up. If a unit can’t apply something, report it in cfg_rejected, e.g. {"cfg_rejected": {"cfg.ntp.server": "apply_failed"}}, and the row shows Rejected with the reason. Apply idempotently, a message can arrive twice.
For 300 units, write the values with the API (POST …/attributes/shared, up to 100 keys per call) in a loop over the device list. The baseline and bulk-job screens are for devices that publish a settings manifest (licensed devices), so with your own firmware cfg.* is the route. Attributes page has the status table.
That was it. Thanks Serhat.
Mine connects fine and then gets disconnected after two or three gw messages. Plain device telemetry from the same box works.
For whoever writes the firmware: dedupe on the request id. A command can arrive twice. Keep the last 32 ids for ten minutes and skip repeats. Learned that with a reboot command.
Gauge bound to A value of a device (live) reacts instantly. The table of about 40 devices next to it lags by up to 30 seconds. Is that what Polled in the docs’ Live column means?
Side note: the same script also logs to journald when it runs as a service, and colour codes in the journal are annoying. Most logging libs let you turn colour off when stdout isn’t a tty.
If the ESP32 firmware uses a hardcoded DNS like 8.8.8.8, allow that too, or they’ll fail after the move and you’ll swear the firewall is fine.
Three things in that payload, I tripped on two of them with forklift trackers.
The map card’s Longitude column defaults to lng, Latitude to lat. You send lon, so every row has no longitude and gets skipped. Either rename the key on the device or set Longitude column to lon in the card. I’d rename on the device so every future board just works.
You’re sending the numbers as strings because you built the JSON with String(). Number-like text often works in comparisons, but send real numbers anyway. And String(float) gives two decimals by default, which is about a kilometre. Your trailers would all sit in the same spot.
And don’t publish when the fix isn’t valid or you’ll get trailers parked at 0,0 off Africa every time one boots in a shed.
if (gps.location.isValid() && gps.location.age() < 3000) {
char buf[96];
snprintf(buf, sizeof(buf), "{"lat":%.6f,"lng":%.6f,"spd_kmh":%.1f}",
gps.location.lat(), gps.location.lng(), gps.speed.kmph());
client.publish("v1/telemetry", buf);
}
snprintf with %f works on the ESP8266 core, unlike on an Uno. Card settings are on Map cards.
And check the 10-to-6 pin ISP adapter if you use one. I’ve had one with MISO and MOSI crossed that worked only by luck on one board type.
Aoife’s question is the right one. Cold moves the crystals.
The four in RX:
RSSI is how strong the received signal is, read from RegRssiValue (0x11), value / 2 as negative dBm. AGC picks the LNA gain from that so strong signals don’t saturate the receiver; your 0x0E already has AgcAutoOn (bit 3) set, leave it. FEI (frequency error indicator, RegFeiMsb/Lsb 0x1D/0x1E) measures how far the incoming carrier is from where the receiver expects it. AFC uses that measurement to retune the receiver onto the signal, at the start of a packet if AfcAutoOn (bit 4) is set. Yours is off.
A plain crystal is good for maybe ±10 to 20 ppm, and drifts with temperature. At 868 MHz, 20 ppm is about 17 kHz. Probe and receiver drift differently on a cold morning, and once the offset plus your deviation falls outside a 10.4 kHz receive bandwidth, the packet is gone. That’s your dropouts.
RegRxConfig (0x0D) = 0x1E // AfcAutoOn + AgcAutoOn + preamble detect trigger
RegAfcBw (0x13) = wide enough to catch the offset before AFC (e.g. 41.7 kHz)
RegRxBw (0x12) = 20.8 kHz after AFC
// or simply widen RxBw if you don't want AFC
Then send the FEI and RSSI of each probe as values next to the moisture reading. In Hermetry a chart of FEI against air temperature shows you which probes drift; ours showed 11 kHz swings on two units before we changed anything.
Guest networks in shops often have a captive portal or kick clients after a few hours, the ESP32s will hang there. Check that before. Do the sensors need to talk to anything in the store, or only out to the internet?
Also check what CA bundle the US firmware pins. If they pinned their region’s server cert instead of using a normal CA store, it may fail on the EU host for a different reason.
For an EKF you check it locally, on the Jacobians at the current operating point, but the intuition matters more: with one level sensor you see the net flow dh/dt, and q_in and k*sqrt(h) both enter it additively.
How hot? We had a Pi 4 throttle at 80 C inside a steel box in summer.
I have a drawer full of these, so here’s how they differ in practice.
HC-05: classic Bluetooth with the serial port profile, can be master or slave, configured with AT commands at 38400 when you hold the KEY/EN pin high at power-up. HC-06: classic SPP too, slave only, fewer AT commands, default 9600. HM-10: Bluetooth Low Energy, the “serial” data goes through characteristic FFE1. Lower power, but the Pi side has to speak BLE.
All three have 3.3 V logic on RX. Their breakout boards take 5 V on VCC, but put a divider on the Uno’s TX line (1k from the Uno, 2k to ground) before it goes into the module’s RX.
For your case the HC-06 is the least work. On the Pi:
sudo rfcomm bind 0 98:D3:31:F5:A2:10 1 # HC-06 address, channel 1
# /dev/rfcomm0 now behaves like a serial port
python3 -c "import serial; s=serial.Serial('/dev/rfcomm0', 9600); print(s.readline())"
Uno side, one line per reading so the Pi can split it easily:
Serial.print("flow_c="); Serial.print(tFlow, 2);
Serial.print(";return_c="); Serial.println(tReturn, 2);
If the Pi is already your gateway to Hermetry, report the heat pump as its own child device on v1/gw/telemetry rather than adding the keys to the Pi itself, then it gets its own page and alarms.

