TapHome

Shelly TRV

Packet Parser → HTTP
Submitted by
Last updated: 04. 2026
Shelly TRV

The Shelly TRV (SHTRV-01) is a battery-powered Wi-Fi thermostatic radiator valve from Allterco Robotics. It mounts directly on a standard hot-water radiator valve body and regulates room temperature by driving the valve pin via an internal motor. TapHome communicates with the device over HTTP on the local network — no bridge, no cloud, no MQTT broker required.

Shelly TRV is discontinued and has been succeeded by the Bluetooth-based Shelly BLU TRV. Existing units keep working and this template remains fully supported; for new projects consider the successor.

Two alternative templates are provided for the same physical device — choose one based on the intended control pattern.

TemplateExposesUse case
Shelly TRV (main)Battery + closed-loop thermostatEnd-user room temperature control via setpoint (5-30 °C). Firmware drives the valve internally.
Shelly TRV (valve)Battery + valve dimmer + thermostat (setpoint variant)Smart rules that need direct valve override — expose valve position as a 0.0-1.0 dimmer.

Do not import both templates for the same physical device. Both bind to the same endpoint and poll loops will collide — writes will conflict and valve behaviour becomes unpredictable.

Hardware installation

The Shelly TRV has no wiring — it is a mechanical radiator head with internal electronics, powered by an internal Li-ion battery (Panasonic NCR18650BD, 3.7 V / 6500 mAh). It mounts directly on the radiator valve body via a metal retaining ring.

Compatible valve bodies

Native thread: M30 × 1.5. The following adapters are included in the retail box:

  • Danfoss — RA, RAV, RAVL
  • Caleffi
  • Giacomini
  • M28 × 1.5 — Sam, Slovarm, Comap, TA, Herz, MMA, Remagg
  • Pont à Mousson

Third-party adapters (not included) extend compatibility to Gampper, Ista, Meges, Ondal, Oventrop, Rossweiner, Vaillant and others.

Mounting procedure
  1. Ensure the radiator is turned off and cooled down.
  2. Turn the existing manual valve head counter-clockwise until fully open, then unscrew the metal retaining ring to remove it.
  3. Fit the correct adapter if the valve thread is not native M30 × 1.5.
  4. Seat the Shelly TRV on the valve body and tighten the metal ring clockwise — firmly but not over-tightened. Too loose or too tight both cause calibration to fail.
  5. Rotate the display to the desired orientation before fully tightening the ring.
  6. Briefly press Reset (back of device). The display shows CL (calibrating) and the internal motor moves in both directions. Successful calibration ends with AP on the display; failure shows E1.

Calibration must be performed after every remount on a different valve body. Until calibrated=true, TapHome setpoint and position writes are rejected with Device is not calibrated.

Charging

The device charges over USB-C (cable supplied, adapter not). A ≥1 A USB-C compliant charger brings the battery from empty to full in approximately 5 hours. Typical battery life is ~2 years (~5 months of a continuous heating season under typical use).

During charging the body of the device warms up and the internal temperature sensor reads incorrectly. Expect skewed room-temperature values while charger is not disconnected.

Configuration

TapHome import

During template import TapHome asks for a single parameter:

ParameterDescriptionDefault
IpAddressLocal IP address or mDNS hostname of the device192.168.0.1

Port 80 is fixed. HTTPS is not supported on Gen1. HTTP Basic Auth must be disabled on the device — TapHome does not authenticate HTTP requests to Gen1 Shelly devices.

Use the mDNS hostname (shellytrv-XXXXXX.local) where possible — it is resilient to DHCP lease changes. The TapHome IP Scanner (Settings → Network → Scan) discovers both the IP and the mDNS hostname.

Disable the weekly schedule

Shelly TRV has a built-in weekly scheduler (5 profiles, up to 18 scheduled changes per week per profile). When the schedule is enabled, the firmware overwrites any externally-written setpoint at the next scheduled event — TapHome setpoints are silently reverted.

The template surfaces this as a warning (Schedule is enabled). Before putting the device under TapHome control, either:

  • trigger the Disable schedule service action on the module (sends /settings/thermostats/0?schedule=false), or
  • select the Disable profile in the Shelly Cloud app or device Web UI.

The built-in temperature sensor is physically close to the hot radiator pipe and typically reads 1-3 °C higher than the actual room temperature. Two correction paths are available:

  • External sensor — pair a separate Wi-Fi thermometer (such as Shelly H&T) via the device Web UI → Sensor SettingsEnable external temperature corrections endpoint. The external sensor then POSTs the ambient temperature to the TRV.
  • Static offset — use the Set temperature offset service action on the Thermostat device (range ±20 °C) to compensate for a constant bias.

For best thermal comfort combine a reliable external sensor with a small static offset as fallback.

Device capabilities

The main template exposes the device as a battery indicator plus a closed-loop thermostat. The valve template keeps the same module and battery, but exposes valve position as a dimmer and uses a setpoint variant that disables automatic PID control when written. Module-level diagnostics and actions are identical for both templates.

Battery status

The battery is exposed as a multi-value switch derived from the reported charge level and USB-C charger state. The charger state takes precedence over the level:

StateCondition
Criticalbat.value < 25
Lowbat.value 25-50
Normalbat.value 50-75
Fullbat.value > 75
Chargingcharger != disconnected

Two supplementary service attributes report the raw battery charge (%) and cell voltage (V, nominal ~3.7 V, typical range 2.6-4.2 V). The template raises Low battery at <50 % and Battery charge is critically low at <25 %.

Thermostat (main template)

A closed-loop room thermostat: TapHome writes the target setpoint, the TRV firmware drives valve position internally based on its built-in (or external) temperature sensor.

  • Read: measured room temperature (thermostats[0].tmp.value) and active target (thermostats[0].target_t.value)
  • Write: setpoint 5-30 °C via /settings/thermostats/0?target_t={Se}

Supplementary thermostat attributes include Temperature offset [°C], Valve position [%] (read-only, for visibility into the PID output), Force close, Extra pressure and Automatic calibration correction. Corresponding service actions let TapHome set the offset, toggle the force-close mode (valve stays fully closed regardless of setpoint) and toggle extra-pressure mode (boosts actuation for stiff valves).

Setpoint writes fail with Device is not calibrated while calibrated=false, and the template adds a warning when the weekly schedule is enabled (since the firmware will overwrite external writes on the next schedule event).

Valve dimmer (valve template)

An alternative template exposes the valve actuator directly as a dimmer device (0.0-1.0 → 0-100 %). TapHome writes position via /thermostats/0?pos={Le*100} — the firmware moves the motor to the requested position and implicitly disables automatic target-temperature control.

The valve template adds Force close, Extra pressure and Automatic calibration correction service attributes (plus the matching toggle actions) on the valve device, so that smart-rule authors can drive the motor directly for scenarios such as emergency close, manual pre-heating or boost sequences.

Thermostat (valve template variant)

The valve template still exposes a thermostat device so that setpoint can be written from the same TapHome device group, but its write script sends both target_t and target_t_enabled=false so that firmware PID does not fight a manually-driven valve. Service attribute set is reduced to Temperature offset [°C] (valve-body attributes such as force_close and valve_state migrate to the valve device instead). The template warns when target_t.enabled=true is observed — that indicates a conflict between the valve dimmer and automatic control.

Module diagnostics and actions

The module (head unit) polls /status and /settings every 3 seconds and exposes device-wide diagnostics and actions:

  • Diagnostics: Wi-Fi SSID, IP address, MAC, received signal strength (RSSI in dBm), calibration state, schedule on/off, display brightness (1-7) and display flipped state.
  • Actions: Disable schedule, Reboot, Calibrate (triggers /calibrate), Update firmware (pulls SHTRV-01_build.gbl from the official Shelly EU firmware server), Set display brightness and Flip display.
Additional capabilities

The device also exposes — but the current templates do not yet surface — several Gen1 features: passive open-window detection (/window), the symmetrical Force open action, fallback ambient temperature (auto_temp), child lock, window-open auto-close delay, scheduled-setpoint sensor (schedule_t), active-profile index, remaining boost minutes and the Trigger boost action (/thermostats/0?boost_minutes=N), internal electronics thermal state (tmp_state), and firmware-update availability as a sensor. CoIoT push and MQTT transport are both supported at device level but not used — TapHome pulls /status every 3 s instead. These can be added in a future template update.

Troubleshooting

Device is not calibrated

Every setpoint and valve-position write returns Device is not calibrated until the TRV completes a successful calibration cycle.

  1. Make sure the device is firmly seated on the valve body — the retaining ring must be tight enough for the motor to load against the valve pin, but not so tight that it deforms.
  2. Trigger the Calibrate service action on the module (sends /calibrate). The display briefly shows CL while the motor moves in both directions.
  3. On success calibrated becomes true and writes succeed; failure shows E1 on the display — usually indicates an incorrect mount.
Setpoint gets reverted every few hours

This is the weekly schedule overwriting external writes. Check Schedule service attribute — if on, trigger the Disable schedule action on the module, or disable the active profile in the Shelly Cloud app.

Room temperature reads too high

Two common causes:

  • Charger connected. Room-temperature readings are invalid while charger != disconnected. Unplug USB-C and allow the device to cool down.
  • Built-in sensor bias. The sensor sits close to hot pipes and typically reads 1-3 °C high. Either enable the external temperature corrections endpoint and pair a Shelly H&T (or compatible Wi-Fi thermometer) in the same room, or apply a static Set temperature offset (e.g. -1.5 °C).
Display shows E1 / E2

E1 — calibration problem. Remount the device, tighten the ring carefully and trigger a new calibration cycle.

E2 — temperature sensor problem. tmp.is_valid becomes false in /status and the template adds a Temperature sensor error error. If the issue persists after a reboot, the sensor has likely failed — contact Shelly support.

Device unreachable
  1. Verify the TRV is connected to Wi-Fi — press Up + Down for 5 s and scroll through the status parameters; CO indicates a connected Wi-Fi client.
  2. Confirm TapHome CCU and TRV are on the same network / VLAN — Shelly Gen1 does not route across subnets by default.
  3. Try the mDNS hostname (shellytrv-XXXXXX.local) instead of the IP — the DHCP lease may have changed.
  4. Open http://{device-ip}/status in a browser. If the JSON response arrives, the device is reachable and the problem is in TapHome configuration.

Gen1 Shelly devices accept only 2 concurrent HTTP connections. If TapHome and another system (Home Assistant, Node-RED) poll the same device at the same time, communication becomes unreliable. Keep poll interval at the template default (3 s) and avoid additional pollers.

Enabling MQTT on Gen1 Shelly devices irreversibly disables Shelly Cloud. TapHome uses HTTP only — leave MQTT off unless you explicitly want to migrate away from Shelly Cloud.

How to install in TapHome

Prerequisites

  • Shelly device installed and powered on
  • Local Wi-Fi network (2.4 GHz)
  • TapHome CCU on the same network

Step 1 — Connect Shelly to Wi-Fi

Option A — Shelly app (recommended):

  1. Download the Shelly app (iOS / Android)
  2. Tap +Add Device and follow the Bluetooth pairing wizard
  3. Enter your Wi-Fi credentials when prompted

Option B — AP mode (no app):

  1. On first power-up the device creates a hotspot: ShellyXXX-AABBCCDDEE
  2. Connect your phone/PC to that hotspot
  3. Open http://192.168.33.1Internet & SecurityWi-Fi Mode - Client
  4. Enter SSID and password → Save

Shelly only supports 2.4 GHz networks. 5 GHz networks will not appear in the scan.

Step 2 — Find the device address

Shelly Gen1 devices support mDNS (Zeroconf). You can reach the device using a hostname instead of an IP address:

1
shelly<model>-<MAC>.local

For example: shelly1pm-AABBCCDDEE.local (MAC address in uppercase hex, no colons).

Recommended: use the TapHome IP Scanner. Open the TapHome app and use the IP Scanner (Settings → Network → Scan). The scanner will discover devices on your network and show both the IP address and the mDNS hostname. Use the hostname instead of the IP address for a more reliable connection — it stays the same even if the device’s IP changes after a router reboot.

Alternative methods to find the IP address:

  • Shelly app: Device detail → Device info → IP address
  • Shelly web UI: Connect to the device AP before Wi-Fi setup — the IP is shown after saving
  • Router DHCP table: Look for a hostname like shelly1pm-AABBCCDDEE

Step 3 — Configure in TapHome

  1. In TapHome, add a new Packet Parser (HTTP) module
  2. Address: enter the mDNS hostname (e.g., shelly1pm-AABBCCDDEE.local) or IP address from Step 2
  3. Port: 80 (default, no change needed)
  4. Import the template — TapHome will poll /status to read device state

HTTP authentication is disabled by default on Shelly devices. If you have enabled login protection, TapHome does not support HTTP Basic Auth at this time — keep auth disabled for TapHome integration.

Available devices

Shelly TRV Module
Service Attributes
WiFi SSID
IP address
MAC address
Received signal strengthWi-Fi signal strength in dBm — typical good range -55 to -70 dBm, below -80 dBm is unreliable
CalibratedWhether valve mechanical calibration is complete — setpoint and valve-position writes are rejected until calibration succeeds
ScheduleWeekly schedule on/off — when on, the firmware overwrites externally-written setpoints on the next schedule event
Display brightnessLED display brightness level (1 = dim, 7 = bright)
Display flippedWhether the LED display is rotated 180° for upside-down mounting
Service Actions
Disable scheduleDisables the weekly schedule so external setpoints are not reverted at the next schedule event
Reboot
CalibrateStarts the mechanical valve calibration cycle — mandatory after every remount on a different valve body
Update firmwareTriggers OTA firmware update from the official Shelly EU firmware server
Set display brightnessSets the LED display brightness (1 = dim, 7 = bright)
Flip displayToggles the 180° display rotation for upside-down valve orientations
Custom Variables

Shelly TRV

Read (module)
VAR response := SENDHTTPREQUEST("/status");
IF response.IsSuccess
    status := response.Content;
END

response := SENDHTTPREQUEST("/settings");
IF response.IsSuccess
    settings := response.Content;
END

if(PARSEJSON(status, "$.thermostats[0].schedule"), adderror("Schedule is enabled"));
if(PARSEJSON(status, "$.update.has_update"), addwarning("Firmware update is available"));

var bat := PARSEJSON(status, "$.bat.value");
if bat < 25
    addwarning("Battery charge is criticaly low");
elseif bat < 50
    addwarning("Low battery");
end
Service Attributes
Wifi
PARSEJSON(status, "$.wifi_sta.ssid")
${ipAddress}
PARSEJSON(status, "$.wifi_sta.ip")
MAC
PARSEJSON(status, "$.mac")
Received signal strength
PARSEJSON(status, "$.wifi_sta.rssi")
Calibrated
if(PARSEJSON(status, "$.calibrated"), "${detail_deviceSettings_true}", "${detail_deviceSettings_false}")
Schedule
 VAR response := SENDHTTPREQUEST("/thermostats/0");
IF response.IsSuccess
 VAR content := response.Content;
 VAR responseHeaders := response.Headers;
 RETURN(SWITCH(PARSEJSON(content, "$.schedule"), true, "On", "Off"));
END
Display brightness
PARSEJSON(settings, "$.display.brightness")
Display flipped
if(PARSEJSON(settings, "$.display.flipped"), "${detail_deviceSettings_true}", "${detail_deviceSettings_false}")
Service Actions
Disable schedule
var response := SENDHTTPREQUEST("/settings/thermostats/0?schedule=false");
if(response.IsSuccess, return("OK"), return(response.Content));
Reboot
VAR response := SENDHTTPREQUEST("/reboot");
if(response.IsSuccess, return("OK"), return(response.Content));
Calibrate
VAR response := SENDHTTPREQUEST("/calibrate");
if(response.IsSuccess, return("OK"), return(response.Content));
Update firmware
VAR response := SENDHTTPREQUEST("/ota?url=http://shelly-api-eu.shelly.cloud/firmware/SHTRV-01_build.gbl");
if(response.IsSuccess, return("OK"), return(response.Content));
Set display brightness
Parameters: Brightness (1-7) (1–7 Br)
var response := SENDHTTPREQUEST("/settings?display_brightness=" + Br);
if(response.IsSuccess, return("OK"), return(response.Content));
Flip display
var response := SENDHTTPREQUEST("/settings?display_flipped=" + if(PARSEJSON(settings, "$.display.flipped"), "false", "true"));
if(response.IsSuccess, return("OK"), return(response.Content));
Battery Multi-value Switch Read-only

Battery charge level as a multi-value switch — Critical (<25%), Low (25-50%), Normal (50-75%), Full (>75%), Charging (USB-C connected). Charging state takes precedence over level

numeric Unit: % multi-value switch
Values / States: Critical · Low · Normal · Full · Charging

Battery

Read switch state
if PARSEJSON(status, "$.charger")
    return(4);
end

var bat := PARSEJSON(status, "$.bat.value");
if bat > 75
    return(3);
elseif bat > 50
    return(2);
elseif bat > 25
    return(1);
else
    return(0);
end
Service Attributes
Value [%]
PARSEJSON(status, "$.bat.value");
Voltage [V]
PARSEJSON(status, "$.bat.voltage");
Thermostat Thermostat

Closed-loop room thermostat — write target temperature (5-30 °C), firmware drives the valve internally using the built-in or external sensor

numeric Unit: °C
Service Attributes
Temperature offset [°C]Static offset added to measured room temperature — useful when the built-in sensor reads high due to hot-pipe proximity
Valve position [%]Current valve opening in percent (0 = fully closed, 100 = fully open)
Force closeWhether the valve is forced fully closed regardless of the setpoint
Extra pressureWhether extra-pressure mode is active — applies additional mechanical force to actuate stiff valves
Automatic calibration correctionWhether fine-tune calibration correction is applied to the mechanical stroke
Service Actions
Set temperature offsetSets the sensor temperature offset (-20 to +20 °C) to compensate for built-in sensor warm bias
Toggle force closeToggles force-close mode — valve stays fully closed regardless of the setpoint
Toggle extra pressureToggles extra-pressure mode — boosts valve actuation for stiff valves

Thermostat

Read temperature
PARSEJSON(status, "$.thermostats[0].tmp.value")
Read (module)
if(! PARSEJSON(status, "$.thermostats[0].tmp.is_valid"), adderror("Temperature sensor error"));
Read desired temperature
PARSEJSON(status, "$.thermostats[0].target_t.value")
Write desired temperature
if(status = "0", return(Se));

if !PARSEJSON(status, "$.calibrated")
    ADDERROR("Device is not calibrated");
    return(NaN);
end

VAR response := SENDHTTPREQUEST("/settings/thermostats/0?target_t=" + Se);
IF response.IsSuccess = false
  ADDERROR(response.StatusCode);
END
Service Attributes
Temperature offset [°C]
PARSEJSON(settings, "$.thermostats[0].temperature_offset")
${device_variable_valvestate} [%]
PARSEJSON(status, "$.thermostats[0].pos")
Force close
if(PARSEJSON(settings, "$.thermostats[0].force_close"), "${detail_deviceSettings_true}", "${detail_deviceSettings_false}")
Extra pressure
if(PARSEJSON(settings, "$.thermostats[0].extra_pressure"), "${detail_deviceSettings_true}", "${detail_deviceSettings_false}")
Automatic calibration correction
if(PARSEJSON(settings, "$.thermostats[0].calibration_correction"), "${detail_deviceSettings_true}", "${detail_deviceSettings_false}")
Service Actions
Set temperature offset
Parameters: Offset (-20–20 C)
VAR response := SENDHTTPREQUEST("/settings/thermostats/0?temperature_offset=" + C);
if(response.IsSuccess, return("OK"), return(response.Content));
Toggle force close
var response := SENDHTTPREQUEST("/settings/thermostats/0?force_close=" + if(PARSEJSON(settings, "$.thermostats[0].force_close"), "false", "true"));
if(response.IsSuccess, return("OK"), return(response.Content));
Toggle extra pressure
var response := SENDHTTPREQUEST("/settings/thermostats/0?extra_pressure=" + if(PARSEJSON(settings, "$.thermostats[0].extra_pressure"), "false", "true"));
if(response.IsSuccess, return("OK"), return(response.Content));
Connection: Packet Parser → HTTP
Possible improvements (14)
  • Active schedule profile — Currently active profile index (0-4) when scheduling is enabled. Could be added as a multi-value indicator
  • Scheduled setpoint — Setpoint that the firmware would apply on the next schedule event
  • Boost remaining — Remaining boost time in minutes; pairs with /thermostats/0?boost_minutes=N write
  • Trigger boost — Temporary heating boost action — not currently exposed as service action
  • Internal thermal state — Electronics thermal state (Normal / High / Very High); early warning for overheating
  • Firmware update availability — Currently surfaced only as warning in module readscript — could be a service attribute
  • Open window detection — Passive open-window detection based on temperature drop; publishes 'state: open|closed' and MQTT topic shellies/{id}/window
  • Force open — Forces valve 100% open — symmetrical counterpart to force_close which IS implemented
  • Window-open auto-close delay — Delay (1-3600 s) before closing the valve after open-window detection
  • Fallback ambient temperature — Fallback setpoint (0-27 °C, 0 = disabled) used when no active setpoint exists
  • Child lock — Locks the physical Up/Down buttons on the device
  • Schedule rules configuration — Up to 18 rules/profile, 5 named profiles. Complex config — usually managed via Shelly Cloud app
  • CoIoT push updates — Optional multicast push (CoAP) — TapHome uses pull polling, not required
  • MQTT control — Gen1 MQTT alternative transport — enabling MQTT irreversibly disables Shelly Cloud

Sources