Questions about Tempest lightning data after capturing a thunderstorm (UDP vs cloud vs NEA)

Hi,

I’m working on the local UDP integration for Home Assistant and captured the raw UDP broadcasts from my Tempest (firmware 181) on a wired host during a thunderstorm this morning: about 90 minutes, 369 evt_strike packets, 93 obs_st packets. I also compared them with your REST API’s observations for the same period and with NEA’s lightning observations. A few things don’t match the UDP API documentation (v171), and I’d like to get them right rather than guess:

  1. Energy. Every evt_strike energy value has bit 24 set: they range from 16,778,368 to 17,149,029, i.e. 2^24 plus 1,152 … 371,813. The documentation’s example is 3848, but Tempest data from 2020 in this forum has bit 24 set too, including one value of exactly 2^24. What does bit 24 mean, is the rest the 21-bit energy value of the AS3935 lightning sensor chip, and does exactly 2^24 mean an energy of 0?

  2. Distance values. Almost all distances are the AS3935’s distance steps (1, 5, 6, 8, 14, 24 km), as listed in the chip’s datasheet and here in 2019, plus 63 twice, which I take to be the sensor’s “out of range” value. But I also got one 7 and one 23, which aren’t AS3935 steps. Does the firmware process the distance beyond passing on the sensor’s estimate? And is 63 intended to mean “out of range”?

  3. Average distance in obs_st. The per-minute “Lightning Strike Avg Distance” is the rounded mean of that minute’s strike distances including 63s. For example, strikes at 63 and 8 km gave an average of 36 km. Is that intended? Should consumers treat an average as unreliable whenever the minute contained an out-of-range strike?

  4. sensor_status. My Tempest in Singapore reports a constant 666111 (0xA29FF) in device_status, which by the documented bits means every sensor failed, while all of them report plausible values. This looks like the hub firmware 194 issue in UDP sensor_status 655871 and Sensor status bits, which went away when support updated the hub, so I’ll ask support to update mine. My Tempest in Sweden (hub firmware 321), which is connected to a Power Booster on external power, reports a constant 67076 (0x10604). “Power Booster Shore Power” (bit 16) fits, and “lightning disturber” (bit 2) is set in every status message, which is also what the updated hub in the first thread reports. What does the disturber flag tell a consumer?

    • Does it mean the AS3935 rejected at least one disturber since the previous device_status, or is it latched?
    • Is a permanently set flag expected, for example because the firmware tunes the sensor’s sensitivity up to the point where disturbers occur?
    • Could the Power Booster’s power supply cause disturbers?

    And is there current documentation for the other bits? In 2020 dsj wrote that bits above the 9th are for internal use, but the documentation now defines bits 15 and 16. My guesses from the data: bit 11 accompanies battery power saving (the Singapore Tempest is at 2.42–2.45 V and sends rapid_wind every 6–15 s, and another user saw 2048 when their battery reached 2.42 V), and bits 9 and 10 appear on the Tempest that reports debug: 1.

  5. Hub time. Timestamps from my hub in Singapore (firmware 194) drift by about 1.3 seconds per hour relative to an NTP-synced host and are then stepped back; my hub in Sweden (firmware 321) stays within a second. How and how often does the hub sync its clock?

  6. Qualified strikes. As explained in this forum in 2020, UDP carries the device’s raw strikes, and the app and REST API show strikes “qualified” by your back end (confirmed, suppressed as false, or added as missed). Is the qualification result per strike available through the REST API, so a local integration could tell which of the device’s strikes were confirmed?

  7. Cloud lightning during the same storm. For the same minutes, /observations/device returns 71 strikes where the device sent 367 evt_strike packets, and from 03:48 UTC no strikes at all, although the device kept reporting 2–8 per minute. Singapore’s NEA publishes lightning observations from its lightning detection network, and they show intense lightning over the station in that period: the nearest within about a kilometre of the station (NEA gives a location accuracy of 0.2–2 km), and 27–69 cloud-to-ground readings per 5 minutes. In minutes where the cloud counts 0 strikes but the device reported some, the cloud’s average distance is always 42 (it’s 0 in minutes where the device reported none); the same 42 was reported in 2021 without an answer. What does 42 mean, and where do the cloud’s strikes and distances come from? Are the device’s strikes qualified against a lightning network, as the 2023 change for cloud-to-cloud strikes suggests, and could a gap in that data explain why strikes were suppressed after 03:48 UTC while NEA recorded lightning within about a kilometre?

For context: the Home Assistant integration surfaces these values directly (for example “last lightning distance” and “average distance”), so I’d like our documentation and handling to reflect what the device actually reports.

I can share the capture (pcap and JSON) if it helps.

Thanks!

I don’t know the answers, but if #3 is true, than this is clearly a bug. the 63 is just 111111 in binary and is indeed out-of-range according to the specs. Which I would interpret as the device detected a valid pulse (or what it things is valid) but it is outside it’s 40km range. One shouldn’t assume that this is 63 km away while averaging.

Thanks! It is true, at least in my capture. Out of 369 strikes, two came with distance 63, and both ended up in the minute’s average. The clearest case is the minute ending 03:05:38 UTC, which had exactly two strikes:

{"type":"evt_strike", ..., "evt":[1790478295,63,16849914]}
{"type":"evt_strike", ..., "evt":[1790478312,8,16784321]}
{"type":"obs_st", ..., "obs":[[1790478338, ..., 36,2, ...]]}

(63 + 8) / 2 = 35.5, reported as an average of 36 km with a count of 2. The other one was in a minute with six strikes at 5 km: the reported average was 13 instead of 5.

Agreed that 63 should be treated as “out of range” rather than a distance. That’s what my proposed change to the library behind the Home Assistant integration does for single strikes, but the per-minute average arrives already computed, so it can’t be corrected on the receiving side.

A correction and an update to question 4 from WeatherFlow’s own documentation:

  • The current UDP API documentation defines bit 9 (0x200) as “power booster detected”, so that bit on my Swedish Tempest is explained, and my guess that bits 9 and 10 relate to debug was wrong for bit 9. Bit 10 is still undocumented.
  • The help article on Solar Power & Rechargeable Battery explains the rapid_wind cadence: on firmware 175 and newer, below about 2.65 V, the Tempest samples wind every 3, 6 or 15 s depending on the gust. My Singapore Tempest (2.34–2.45 V over the last day) matches that, and it’s the one with bit 11 set, while the Swedish one stays above 2.65 V and doesn’t have it. So bit 11 may mean “dynamic power saving active”. Can anyone confirm?

One more data point on bit 11. I power-cycled my Singapore Tempest and hub today. For the first hour after boot, sensor_status was 655871 (0xA01FF) and rapid_wind came every 3 seconds. At one hour of uptime (between 3,546 and 3,607 s), bits 11 and 13 appeared (666111, 0xA29FF), and at the same moment rapid_wind switched to the 6/15-second dynamic wind sampling described in the Solar Power & Rechargeable Battery article. The battery stayed at 2.39 V throughout.

So bits 11 and 13 look like “dynamic power saving active”, which the firmware enables an hour after boot when the battery is below about 2.65 V. That would also make the 655871 several of you have reported the same pattern as mine (bits 0–8, 17 and 19) without power saving.

There’s a many-year history of sensor_status returning bogus values as well as things in the UDP that are not documented publicly.

Personally I’d code base on the ‘public’ UDP api, basically ignore sensor_status completely, and code defensively so you don’t get breakage if things get silently added to the UDP broadcast. It happens.