Shelly TRV Gen1 2.2.4 – high battery drain / beacon-skip recovery – experimental firmware patch

Hi everyone,

over the last few days I’ve been investigating the unusually high battery consumption of some Shelly TRV Gen1 (SHTRV-01) devices and noticed suspicious behavior in the current firmware 2.2.4.

The firmware version investigated is:

20240619-130912/v2.2.4@ee290818

Initial problem

On multiple physical TRVs running the original 2.2.4 firmware, I was able to reproduce the following sequence in the debug log approximately once per minute:

Beacon skip error! Attempt recovery

followed by:

Enter powersave state 1

and a few seconds later:

Enter powersave state 3 (skip 20)

Because beacon skipping and power-save states are directly related to the TRV’s Wi-Fi power-saving behavior, I started investigating whether this recurring recovery behavior could be related to the unusually high battery consumption.

Important: A causal relationship between this behavior and battery drain has not yet been proven.

What I tested

To narrow down the possibility of the Wi-Fi environment being responsible, I tested different Wi-Fi configurations, RSSI conditions, CoIoT, and Mesh/band steering.

I also compared the behavior with older firmware versions.

The recurring recovery behavior appears to be firmware-dependent and is reproducible with firmware 2.2.4.

Firmware comparison

I then compared firmware 2.1.3 and 2.2.4 using Ghidra.

The normal RSSI-dependent beacon-skip logic exists in both firmware versions.

Depending on signal strength, the firmware selects a desired beacon skip of 20, 15, or 10.

However, firmware 2.2.4 contains an additional recovery path associated with the observed:

Beacon skip error! Attempt recovery

I developed an experimental one-byte control-flow patch that bypasses this additional recovery block.

The normal RSSI-dependent beacon-skip selection remains unchanged.

Hardware testing

The patched firmware is now running on multiple physical SHTRV-01 devices.

One patched device has currently been running continuously for more than 34 hours.

So far:

  • Wi-Fi connected
  • Shelly Cloud connected
  • desired_beacon_skip: 20
  • beacon_err_counter: 0
  • regular current beacon skip is 20 messages
  • no observed Beacon skip error! Attempt recovery
  • no observed recurring transition to Enter powersave state 1

A second patched TRV has also been tested for normal thermostat functionality:

  • Wi-Fi working
  • Shelly Cloud working
  • calibration successful
  • valve physically opened
  • valve physically closed again
  • no recovery loop observed during the monitored period

What about battery life?

This is currently the most important open question.

The patch reproducibly suppresses the suspicious recovery behavior in my testing so far.

However, I am not claiming yet that the patch fixes the battery drain.

Long-term battery testing is still in progress.

I’m also preparing another SHTRV-01 running the original, unmodified 2.2.4 firmware. It will be fully charged and used as a control device alongside the patched units.

This should allow a longer-term comparison of battery behavior between original and patched 2.2.4 firmware.

Open-source patcher

To avoid distributing modified Shelly firmware, I have published a small open-source patcher.

It creates the patched firmware locally from the user’s original Shelly 2.2.4 GBL file.

No Shelly firmware is distributed by the project.

The patcher is intentionally strict. Before modifying anything, it validates, among other things:

  • firmware size
  • SHA-256
  • GBL structure
  • CRC
  • expected ARM/Thumb instruction

After patching, the resulting firmware, CRC, and expected byte differences are verified again.

The project also includes a small local HTTP/1.1 OTA server with Range support for transferring the resulting firmware to the TRV.

Patcher:

Full reverse-engineering research and technical details:

Current patcher release:

v0.1.0 – experimental

Looking for additional testers and data

I’m particularly interested in data from other SHTRV-01 devices running the original 2.2.4 firmware.

If you have one of these devices, data from:

/debug/log

and

/stats

would be very useful.

Especially useful information includes:

  • exact firmware version
  • RSSI
  • whether Beacon skip error! Attempt recovery occurs
  • how frequently it occurs
  • desired_beacon_skip
  • real_beacon_skip
  • beacon_err_counter
  • battery percentage and battery voltage
  • approximate battery runtime
  • router / access point used

Testers of the experimental patch are of course also welcome.

The more devices and Wi-Fi environments we can compare, the better we can determine how reproducible this behavior is on firmware 2.2.4 and whether suppressing the recovery loop actually results in a measurable improvement in battery life over the long term.

Please note: This patch modifies the device firmware and is experimental. Use it at your own risk. This is an unofficial community project and is not affiliated with Shelly.

Research status update

A quick update on the ongoing Shelly TRV Gen1 battery-drain investigation.

Since the original post, the firmware analysis has progressed significantly and I now have a much better understanding of the recurring:

Beacon skip error! Attempt recovery

behavior in firmware 2.2.4.

The original patch was mainly suppressing the symptom

The original experimental patch bypassed the complete Beacon Recovery block.

This was very useful for isolating the behavior and confirmed that the recurring recovery cycle could be stopped while normal RSSI-dependent beacon skipping, Wi-Fi and Shelly Cloud continued to operate.

However, further reverse engineering indicates that the recovery mechanism itself has a legitimate purpose.

Because of that, I no longer consider completely disabling Beacon Recovery to be the preferred final solution.

The original patch is now treated as an experimental isolation patch.

New findings

The value used by the recovery logic has now been identified as the firmware’s real_beacon_skip value, which is derived from WF200 Wi-Fi beacon statistics.

Further analysis revealed several problems around how this value is calculated, interpreted and reused.

Most importantly, I found a stale-state condition that explains why the recovery can become self-sustaining.

After a recovery is triggered, the firmware clears the previous beacon measurement baseline but retains the value that caused the recovery.

When the next measurement arrives, the firmware establishes a new baseline, but before enough fresh data exists to calculate a new value, the old recovery-triggering value can be evaluated again.

This causes another recovery, which clears the new baseline again.

The device can therefore enter a cycle where:

old recovery condition
        ↓
Beacon Recovery
        ↓
measurement baseline cleared
        ↓
new baseline established
        ↓
old condition evaluated again
        ↓
Beacon Recovery
        ↓
       ...

This explains how the recovery message can repeat approximately once per minute without requiring a new Wi-Fi/beacon problem every minute.

There are also additional measurement-validity issues in the same logic that are now part of the investigation.

A new patch is in development

Based on these findings, I am now developing a new patch approach.

Instead of simply disabling Beacon Recovery, the new patch is intended to correct the underlying beacon measurement and stale-state behavior while preserving legitimate recovery functionality.

The current candidate is called Patch C-C.

It has already passed a detailed static pre-build analysis and falsification review without identifying a known static blocker.

The next steps are:

  1. build the experimental firmware;
  2. independently verify the resulting firmware/GBL;
  3. test it on physical TRV hardware;
  4. verify that legitimate Beacon Recovery still works correctly;
  5. continue the long-term battery comparison.

So this is not yet a claim that the battery-drain problem has been solved.

mDNS testing continues separately

The periodic mDNS activity discovered during the investigation is still being tested independently.

A separate test variant suppresses the targeted recurring mDNS activity while leaving Beacon Recovery unchanged.

This allows both mechanisms to be evaluated separately instead of assuming that the TRV battery drain has a single cause.

Current status

The investigation has therefore moved beyond simply suppressing the visible recovery loop.

We now have a much more detailed explanation of why the 2.2.4 Beacon Recovery can become stuck in a recurring cycle, and the goal is now to correct the underlying behavior rather than just bypass the recovery function.

What still remains unknown is what causes the first problematic recovery event on affected devices in real-world operation and how much this mechanism contributes to the overall battery drain.

This distinction is important because battery-drain behavior has also been observed historically with older firmware that does not contain the same 2.2.4 Beacon Recovery mechanism.

Long-term battery logging therefore continues in parallel with the firmware work.

I will keep the GitHub research repository updated as the investigation and hardware testing progress.

Thanks to everyone who has contributed observations, logs and feedback so far.