TapHome

Shelly Plus 2PM

Packet Parser → HTTP
Submitted by
Last updated: 03. 2026
Shelly Plus 2PM

The Shelly Plus 2PM is a compact dual-channel Wi-Fi relay with built-in power metering on both channels. It fits behind a standard wall switch and can control two independent circuits, each rated up to 10 A (16 A total at 230 V AC), or drive a single motorized roller shutter. TapHome communicates with the device over HTTP using the Gen2+ RPC API on the local network — no cloud connection is required.

The device supports two operation profiles — switch and cover — selectable through the Shelly web UI or via the TapHome service action. In switch profile, both relay outputs (O1 and O2) operate independently with per-channel power monitoring. In cover profile, the two outputs drive a single motor for roller shutters, blinds, or curtains, with position control and calibration.

The Shelly Plus 2PM is discontinued. Its successor, the Shelly 2PM Gen3, offers the same dual-profile functionality with an upgraded processor (8 MB flash), up to 6 concurrent HTTP connections, and Matter upgradeability.

Configuration

The Shelly Plus 2PM connects over Wi-Fi. During TapHome template import, enter the device’s IP address (default placeholder 192.168.0.1).

Authentication must be disabled on the Shelly device for TapHome integration. TapHome does not support HTTP Digest Auth used by Gen2+ devices. Open the Shelly web UI (http://{device-ip}) → Settings → Authentication and ensure it is turned off.

If ECO mode is enabled on the Shelly device, it may cause communication timeouts due to the fast poll intervals used by the template (2.5–5 seconds). Disable ECO mode in the Shelly web UI if you experience intermittent connectivity issues.

Profile selection

The Shelly Plus 2PM operates in one of two profiles at a time. The active profile determines which TapHome devices are functional:

  • Switch profile — enables both relay switches (Switch 1 and Switch 2) and their per-channel energy meters. The shutter device and shutter energy meter will not respond.
  • Cover profile — enables the shutter device and its energy meter. The two switch devices and their energy meters will not respond.

The active profile is visible as a module-level service attribute (“Profile”) in TapHome. To change the profile, use the Profile service action at the module level, or switch it in the Shelly web UI. After changing the profile, the device reboots and only the devices matching the new profile will operate.

The template includes all six devices (2 switches + 2 switch power meters + 1 shutter + 1 shutter power meter), but only the devices matching the active profile will work. This is expected behavior — devices on the wrong profile simply do not respond.

Cover calibration

When using the cover profile, the motor travel limits must be calibrated before position control works. Until calibration is complete, current_pos returns null and the “Calibrated” service attribute shows false. Calibrate either through the Shelly web UI or by triggering the Calibrate service action on the Shutter device in TapHome. During calibration, the cover runs a multi-step sequence (full open → full close → full open → close in steps → open in steps) to measure travel distances.

Device capabilities

Relay control (switch profile)

The template exposes two independent relay switches. Each switch reads its state from /rpc/Switch.GetStatus?id={0,1} (output field, boolean) and controls the relay via /rpc/Switch.Set?id={0,1}&on=true|false.

Each switch exposes seven service attributes:

  • Source — source of the last command (http, UI, WS_in, etc.)
  • Temperature — internal device temperature in °C
  • Initial State — switch behavior on power-up (off, on, restore_last, or match_input)
  • Input Mode — physical input wiring mode (follow or detached)
  • Power Limit — maximum power threshold in watts for overpower protection
  • Voltage Limit — maximum voltage threshold in volts
  • Current Limit — maximum current threshold in amperes

Two service actions are available on each switch:

  • Set Initial State — configures the relay behavior after power-up (off, on, restore_last, match_input)
  • Set Mode — configures the physical input wiring mode (follow, detached)
Power metering (switch profile)

Each switch channel has a dedicated energy meter that reads two values from /rpc/Switch.GetStatus:

  • Real-time powerapower reported in watts, converted to kW by the template
  • Total consumptionaenergy.total reported in watt-hours, converted to kWh by the template

Each energy meter also exposes three service attributes:

  • Voltage — supply voltage in volts
  • Current — load current in amperes
  • Power Factor — power factor of the load

The meters are read-only — they update automatically with every poll cycle.

Shutter control (cover profile)

The shutter device controls a motorized roller shutter, curtain, or awning. It reads position from /rpc/Cover.GetStatus?id=0 (current_pos field, 0–100%) and writes via /rpc/Cover.GoToPosition?id=0&pos=N.

The shutter device exposes 21 service attributes:

  • Status — source, state (open/closed/opening/closing/stopped/calibrating), current and target position, movement timeout and start time
  • Calibration — whether position control is enabled (pos_control)
  • Temperature — internal device temperature in °C
  • Power-up behavior — initial state configuration (open, closed, stopped)
  • Input settings — input mode (single, dual, detached), swap inputs, invert directions
  • Protection limits — power limit (W), voltage limit (V), current limit (A)
  • Motor tuning — idle power threshold (0–50 W), idle confirmation period (0.25–2 s)
  • Movement limits — maximum open time (0.1–300 s), maximum close time (0.1–300 s)
  • Safety features — obstruction detection status, safety switch status

Six service actions are available on the shutter:

  • Open — fully opens the cover
  • Close — fully closes the cover
  • Stop — stops movement immediately
  • Calibrate — starts the calibration procedure for position control
  • Go to Position — moves the cover to a specific position (0–100%)
  • Reverse directions — toggles the invert_directions config and reboots the device
Power metering (cover profile)

The shutter has a dedicated energy meter that reads from /rpc/Cover.GetStatus:

  • Real-time powerapower reported in watts, converted to kW by the template
  • Total consumptionaenergy.total reported in watt-hours, converted to kWh by the template

The shutter energy meter also exposes voltage, current, and power factor as service attributes.

Service diagnostics

The template exposes two module-level service attributes:

  • MAC — device MAC address from system config
  • Profile — currently active device profile (switch or cover)

The module read script also checks restart_required from /rpc/Sys.GetStatus and surfaces a warning in TapHome if a reboot is pending.

Service actions

Two service actions are available at the module level:

  • Reboot — triggers a device reboot via /rpc/Shelly.Reboot
  • Profile — switches between switch and cover operating profiles via /rpc/Shelly.SetProfile
Additional capabilities

The Shelly Plus 2PM also exposes network frequency (freq), per-minute energy values (aenergy.by_minute), physical input states (input:0, input:1), WiFi signal strength (RSSI), and a switch toggle endpoint in its RPC responses. Energy counters can be reset via /rpc/Switch.ResetCounters (switch profile) or /rpc/Cover.ResetCounters (cover profile). In cover mode, slat/tilt position for venetian blinds is available when the hardware supports it. These capabilities can be added in a future template update.

Troubleshooting

Device not responding
  1. Verify the Shelly is connected to Wi-Fi and has a valid IP address
  2. Try using the mDNS hostname (shellyplus2pm-AABBCCDDEE.local) instead of the IP address — the IP may have changed after a DHCP renewal
  3. Open http://{device-ip}/rpc/Shelly.GetDeviceInfo in a browser — if it responds with JSON, the device is reachable
  4. Check that TapHome Core and Shelly are on the same network / VLAN
  5. Confirm authentication is disabled on the Shelly device
Profile mismatch — devices not responding

If some devices show no readings while others work correctly:

  1. Check which profile is currently active — the “Profile” service attribute at the module level shows the current mode
  2. Switch to the correct profile using the Profile service action, or ignore the unused devices
  3. After switching profiles, the device reboots automatically — allow a few seconds for reconnection
Cover position not working
  1. Verify the device is in cover profile — switch profile does not expose cover functionality
  2. Run the Calibrate service action on the Shutter device — position control requires completed calibration
  3. Check that the motor is connected correctly to O1 and O2 terminals
  4. Poll /rpc/Cover.GetStatus?id=0 manually and verify pos_control is true
Cover calibration fails

Calibration aborts if:

  • The cover fails to reach the end position within maxtime_open or maxtime_close
  • A safety feature (obstruction detection or safety switch) is triggered during calibration
  • An external stop command is issued during calibration
  • The motor direction does not match expected feedback
  • The device reboots during calibration

Check motor wiring, increase maxtime_open/maxtime_close if the motor is slow, and ensure no obstructions are present.

Power readings show zero
  1. Confirm the load is connected through the Shelly relay (not bypassed)
  2. Check that the relay is turned on — the meter only reads when current flows through the relay
  3. Poll /rpc/Switch.GetStatus?id=0 (switch profile) or /rpc/Cover.GetStatus?id=0 (cover profile) manually and verify apower returns a non-zero value

Gen2+ Shelly devices support up to 6 concurrent HTTP connections. While this is an improvement over Gen1 (2 connections), avoid polling from too many systems simultaneously (TapHome, Home Assistant, custom scripts) to prevent connection exhaustion.

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 Plus 2PM Module
Service Attributes
MACDevice MAC address from system config
ProfileActive device profile — switch or cover
Service Actions
RebootReboots the device
ProfileSwitches between switch and cover operating profiles — requires device reboot
Custom Variables

Shelly Plus 2 PM

Read (module)
VAR response := SENDHTTPREQUEST("/rpc/Sys.GetConfig");
IF response.IsSuccess
  VAR content := response.Content;
  VAR responseHeaders := response.Headers;
  SysConfig := response.Content;
END;
 
response := SENDHTTPREQUEST("/rpc/Sys.GetStatus");
IF response.IsSuccess
  content := response.Content;
  responseHeaders := response.Headers;
  if(PARSEJSON(response.Content, "$.restart_required") = true, ADDERROR("Restart required"));
END
Service Attributes
MAC
PARSEJSON(SysConfig, "$.device.mac");
Profile
PARSEJSON(SysConfig, "$.device.profile");
Service Actions
Reboot
VAR response := SENDHTTPREQUEST("/rpc/Shelly.Reboot");
IF response.IsSuccess
  VAR content := response.Content;
  VAR responseHeaders := response.Headers;
  Return("OK");
END;
Profile
Parameters: Profile
var profile := SWITCH(pr, 1, "cover", "switch");
VAR response := SENDHTTPREQUEST("/rpc/Shelly.SetProfile?name=\""+profile+"\"");
IF response.IsSuccess
  VAR content := response.Content;
  VAR responseHeaders := response.Headers;
  Return("OK");
END;
Power Meter (Shutter) Electricity Meter Read-only

Energy metering for cover mode — instantaneous power (kW) and cumulative energy (kWh)

numeric Unit: kW / kWh json_path
Service Attributes
VoltageSupply voltage in Volts
CurrentLoad current in Amperes
Power FactorPower factor of the load

Power Meter (Shutter)

Read total consumption
if PARSEJSON(SysConfig, "$.device.profile") = "switch"
    adderror("Device profile is set to switch");
else
    return(PARSEJSON(CoverStatus, "$.aenergy.total") / 1000);
end
Read demand
if PARSEJSON(SysConfig, "$.device.profile") = "cover"
    return(PARSEJSON(CoverStatus, "$.apower", true) / 1000);
end
Read (module)
if PARSEJSON(SysConfig, "$.device.profile") = "cover"
    var response := SENDHTTPREQUEST("/rpc/Cover.GetStatus?id=" + Id);
    IF response.IsSuccess
        VAR content := response.Content;
        VAR responseHeaders := response.Headers;
        CoverStatus := response.Content;
    END
end
Service Attributes
Voltage [V]
PARSEJSON(CoverStatus, "$.voltage", true);
Current [A]
PARSEJSON(CoverStatus, "$.current", true);
Power Factor
PARSEJSON(CoverStatus, "$.pf", true);
Power Meter (Switch 1) Electricity Meter Read-only

Energy metering for switch channel 1 — instantaneous power (kW) and cumulative energy (kWh)

numeric Unit: kW / kWh json_path
Service Attributes
VoltageSupply voltage in Volts
CurrentLoad current in Amperes
Power FactorPower factor of the load

Power Meter (Switch 1)

Read total consumption
if PARSEJSON(SysConfig, "$.device.profile") = "cover"
    adderror("Device profile is set to cover");
else
    return(PARSEJSON(SwitchStatus, "$.aenergy.total", true) / 1000);
end
Read demand
if PARSEJSON(SysConfig, "$.device.profile") = "switch"
    return(PARSEJSON(SwitchStatus, "$.apower", true) / 1000);
end
Read (module)
if PARSEJSON(SysConfig, "$.device.profile") = "switch"
    var response := SENDHTTPREQUEST("/rpc/Switch.GetStatus?id=" + Id);
    IF response.IsSuccess
        VAR content := response.Content;
        VAR responseHeaders := response.Headers;
        SwitchStatus := response.Content;
    END
end
Service Attributes
Voltage [V]
PARSEJSON(SwitchStatus, "$.voltage", true);
Current [A]
PARSEJSON(SwitchStatus, "$.current", true);
Power Factor
PARSEJSON(SwitchStatus, "$.pf", true);
Power Meter (Switch 2) Electricity Meter Read-only

Energy metering for switch channel 2 — instantaneous power (kW) and cumulative energy (kWh)

numeric Unit: kW / kWh json_path
Service Attributes
VoltageSupply voltage in Volts
CurrentLoad current in Amperes
Power FactorPower factor of the load

Power Meter (Switch 2)

Read total consumption
if PARSEJSON(SysConfig, "$.device.profile") = "cover"
    adderror("Device profile is set to cover");
else
    return(PARSEJSON(SwitchStatus, "$.aenergy.total", true) / 1000);
end
Read demand
if PARSEJSON(SysConfig, "$.device.profile") = "switch"
    return(PARSEJSON(SwitchStatus, "$.apower", true) / 1000);
end
Read (module)
if PARSEJSON(SysConfig, "$.device.profile") = "switch"
    var response := SENDHTTPREQUEST("/rpc/Switch.GetStatus?id=" + Id);
    IF response.IsSuccess
        VAR content := response.Content;
        VAR responseHeaders := response.Headers;
        SwitchStatus := response.Content;
    END
end
Service Attributes
Voltage [V]
PARSEJSON(SwitchStatus, "$.voltage", true);
Current [A]
PARSEJSON(SwitchStatus, "$.current", true);
Power Factor
PARSEJSON(SwitchStatus, "$.pf", true);
Shutter Slide

Motorized cover control with position tracking — requires calibration for position control

numeric Unit: % json_path
Service Attributes
SourceSource of the last cover command
StateCurrent cover state — open, closed, opening, closing, stopped, calibrating
Current PositionCurrent cover position in percent (0–100), null if uncalibrated
Target PositionTarget position when cover is moving
Move TimeoutSeconds until auto-stop during movement
Move Started atTimestamp when current movement started
CalibratedWhether position control is enabled (true after successful calibration)
TemperatureInternal device temperature in Celsius
Initial StateCover behavior on power-up — open, closed, or stopped
Input ModePhysical input wiring mode — single, dual, or detached
Power LimitMaximum power threshold in Watts for overpower protection
Voltage LimitMaximum voltage threshold in Volts for overvoltage protection
Current LimitMaximum current threshold in Amperes for overcurrent protection
Motor Idle Power ThresholdPower threshold below which the motor is considered idle (0–50 W)
Motor Idle Confirm PeriodDuration motor must stay below idle threshold to confirm stop (0.25–2 s)
Max Time OpenMaximum opening time before auto-stop (0.1–300 s)
Max Time CloseMaximum closing time before auto-stop (0.1–300 s)
Swap InputsWhether S1/S2 input assignment is swapped
Invert DirectionsWhether open/close directions are inverted
Obstruction DetectionWhether obstruction detection is enabled
Safety SwitchWhether the safety switch feature is enabled
Service Actions
OpenFully opens the cover
CloseFully closes the cover
StopStops cover movement immediately
CalibrateStarts cover calibration — required for position control
Go to PositionMoves the cover to a specific position (0–100%)
Reverse directionsToggles invert_directions config and reboots the device

Shutter

Read (module)
if PARSEJSON(SysConfig, "$.device.profile") = "switch"
    adderror("Device profile is set to switch");
else
    var response := SENDHTTPREQUEST("/rpc/Cover.GetStatus?id=" + Id);
    IF response.IsSuccess
        VAR content := response.Content;
        VAR responseHeaders := response.Headers;
        CoverStatus := response.Content;
    END
    
    response := SENDHTTPREQUEST("/rpc/Cover.GetConfig?id=" + Id);
    IF response.IsSuccess
        content := response.Content;
        responseHeaders := response.Headers;
        CoverConfig := response.Content;
    END
end
Read blind level
if PARSEJSON(SysConfig, "$.device.profile") = "switch"
    adderror("Device profile is set to switch");
else
    var response := SENDHTTPREQUEST("/rpc/Cover.GetStatus?id=" + Id);
    IF response.IsSuccess
        CoverStatus := response.Content;
    END
    if PARSEJSON(CoverStatus, "$.pos_control", true) = true
        var pos := -1;
        var curpos := PARSEJSON(CoverStatus, "$.current_pos", true);
        if ISNULL(curpos)
            adderror("Device lost its position. Open or close the cover completely to enable back position control.");
            return(0);
        end
        var target := PARSEJSON(CoverStatus, "$.target_pos", true);
        if(ISNULL(target), pos := curpos, pos := target);
        if PARSEJSON(CoverConfig, "$.invert_directions", true)
            return(linear(pos, 0, 0, 100, 1));
        else
            return(linear(pos, 0, 1, 100, 0));
        end
    else
        adderror("Device is not calibrated");
    end
end
Write blind level
if PARSEJSON(SysConfig, "$.device.profile") = "switch"
    adderror("Device profile is set to switch");
else
    var pos := 0;
    if PARSEJSON(CoverConfig, "$.invert_directions", true)
        pos := linear(Bl, 0, 0, 1, 100);
    else
        pos := linear(Bl, 0, 100, 1, 0);
    end
    VAR response := SENDHTTPREQUEST("rpc/Cover.GoToPosition?id=" + Id + "&pos=" + pos);
    IF response.IsSuccess
      VAR content := response.Content;
      Return("OK");
    else
      return(parsejson(response.Content,"$.message"));
    END
end
Service Attributes
Source
PARSEJSON(CoverStatus, "$.source", true);
State
PARSEJSON(CoverStatus, "$.state", true);
Current Position
PARSEJSON(CoverStatus, "$.current_pos", true);
Target Position
PARSEJSON(CoverStatus, "$.target_pos", true);
Move Timeout
PARSEJSON(CoverStatus, "$.move_timeout", true);
Move Started at
PARSEJSON(CoverStatus, "$.move_started_at", true);
Calibrated
PARSEJSON(CoverStatus, "$.pos_control", true);
Temperature [°C]
PARSEJSON(CoverStatus, "$.temperature.tC", true);
Initial State
PARSEJSON(CoverConfig, "$.initial_state", true);
Input Mode
PARSEJSON(CoverConfig, "$.in_mode", true);
Power Limit [W]
PARSEJSON(CoverConfig, "$.power_limit", true);
Voltage Limit [V]
PARSEJSON(CoverConfig, "$.voltage_limit", true);
Current Limit [A]
PARSEJSON(CoverConfig, "$.current_limit", true);
Motor Idle Power Threshold [W]
PARSEJSON(CoverConfig, "$.motor.idle_power_thr", true);
Motor Idle Confirm Period [s]
PARSEJSON(CoverConfig, "$.motor.idle_confirm_period", true);
Max Time Open [s]
PARSEJSON(CoverConfig, "$.maxtime_open", true);
Max Time Close [s]
PARSEJSON(CoverConfig, "$.maxtime_close", true);
Swap Inputs
PARSEJSON(CoverConfig, "$.swap_inputs", true);
Invert Directions
PARSEJSON(CoverConfig, "$.invert_directions", true);
Obstruction Detection
PARSEJSON(CoverConfig, "$.obstruction_detection", true);
Safety Switch
PARSEJSON(CoverConfig, "$.safety_switch", true);
Service Actions
Open
VAR response := SENDHTTPREQUEST("rpc/Cover.Open?id=" + Id );
IF response.IsSuccess
  VAR content := response.Content;
  Return("OK");
else
  return(parsejson(response.Content,"$.message"));
END;
Close
VAR response := SENDHTTPREQUEST("rpc/Cover.Close?id=" + Id );
IF response.IsSuccess
  VAR content := response.Content;
  Return("OK");
else
  return(parsejson(response.Content,"$.message"));
END;
Stop
VAR response := SENDHTTPREQUEST("rpc/Cover.Stop?id=" + Id );
IF response.IsSuccess
  VAR content := response.Content;
  Return("OK");
else
  return(parsejson(response.Content,"$.message"));
END;
Calibrate
VAR response := SENDHTTPREQUEST("rpc/Cover.Calibrate?id=" + Id );
IF response.IsSuccess
  VAR content := response.Content;
  Return("OK");
else
  return(parsejson(response.Content,"$.message"));
END;
Go to Position
Parameters: Position (0–100 pos)
VAR response := SENDHTTPREQUEST("rpc/Cover.GoToPosition?id=" + Id + "&pos=" + pos);
IF response.IsSuccess
  VAR content := response.Content;
  Return("OK");
else
  return(parsejson(response.Content,"$.message"));
END;
Reverse directions
var reverse := "false";
if(PARSEJSON(CoverConfig, "$.invert_directions"), reverse := "false", reverse := "true");
VAR response := SENDHTTPREQUEST("rpc/Cover.SetConfig?id=0&config={\"invert_directions\":" + reverse + "}");
IF response.IsSuccess
  SENDHTTPREQUEST("rpc/Shelly.Reboot");
  Return("OK");
else
  return(parsejson(response.Content,"$.message"));
END;
Switch 1 Switch

Relay output channel 1 — on/off control with power-up behavior and input mode configuration

boolean json_path
Values / States: ON · OFF
Service Actions
Set Initial StateConfigures the switch behavior on power-up
Set ModeConfigures the physical input wiring mode

Switch 1

Read switch state
if PARSEJSON(SysConfig, "$.device.profile") = "cover"
    adderror("Device profile is set to cover");
else
    RETURN(PARSEJSON(SwitchStatus, "$.output", true));
end
Write switch state
if PARSEJSON(SysConfig, "$.device.profile") = "switch"
    VAR response := SENDHTTPREQUEST("rpc/Switch.Set?id=" + Id + "&on=" + if(St,"true","false"));
    IF response.IsSuccess = false
      ADDERROR(response.StatusCode);
    END
end
Read (module)
if PARSEJSON(SysConfig, "$.device.profile") = "switch"
    var response := SENDHTTPREQUEST("/rpc/Switch.GetStatus?id=" + Id);
    IF response.IsSuccess
        VAR content := response.Content;
        VAR responseHeaders := response.Headers;
        SwitchStatus := response.Content;
    END
    
    response := SENDHTTPREQUEST("/rpc/Switch.GetConfig?id=" + Id);
    IF response.IsSuccess
        content := response.Content;
        responseHeaders := response.Headers;
        SwitchConfig := response.Content;
    END
end
Service Attributes
Source
PARSEJSON(SwitchStatus, "$.source", true);
Temprature [°C]
PARSEJSON(SwitchStatus, "$.temperature.tC", true);
Initial State
PARSEJSON(SwitchConfig, "$.initial_state", true);
Input Mode
PARSEJSON(SwitchConfig, "$.in_mode", true);
Power Limit [W]
PARSEJSON(SwitchConfig, "$.power_limit", true);
Voltage Limit [V]
PARSEJSON(SwitchConfig, "$.voltage_limit", true);
Current Limit [A]
PARSEJSON(SwitchConfig, "$.current_limit", true);
Service Actions
Set Initial State
Parameters: Mode
var mode := SWITCH(md, 1, "on", 2, "restore_last", 3, "match_input", "off");
VAR response := SENDHTTPREQUEST("rpc/Switch.SetConfig?id=" + Id +"&config={\"initial_state\":\""+mode+"\"}");
IF response.IsSuccess
  VAR content := response.Content;
  Return("OK");
else
  return(parsejson(response.Content,"$.message"));
END;
Set Mode
Parameters: Mode
var mode := SWITCH(md, 1, "detached", "follow");
VAR response := SENDHTTPREQUEST("rpc/Switch.SetConfig?id=" + Id +"&config={\"in_mode\":\""+mode+"\"}");
IF response.IsSuccess
  VAR content := response.Content;
  Return("OK");
else
  return(parsejson(response.Content,"$.message"));
END;
Switch 2 Switch

Relay output channel 2 — on/off control with power-up behavior and input mode configuration

boolean json_path
Values / States: ON · OFF
Service Actions
Set Initial StateConfigures the switch behavior on power-up
Set ModeConfigures the physical input wiring mode

Switch 2

Read switch state
if PARSEJSON(SysConfig, "$.device.profile") = "cover"
    adderror("Device profile is set to cover");
else
    RETURN(PARSEJSON(SwitchStatus, "$.output", true));
end
Write switch state
if PARSEJSON(SysConfig, "$.device.profile") = "switch"
    VAR response := SENDHTTPREQUEST("rpc/Switch.Set?id=" + Id + "&on=" + if(St,"true","false"));
    IF response.IsSuccess = false
      ADDERROR(response.StatusCode);
    END
end
Read (module)
if PARSEJSON(SysConfig, "$.device.profile") = "switch"
    var response := SENDHTTPREQUEST("/rpc/Switch.GetStatus?id=" + Id);
    IF response.IsSuccess
        VAR content := response.Content;
        VAR responseHeaders := response.Headers;
        SwitchStatus := response.Content;
    END
    
    response := SENDHTTPREQUEST("/rpc/Switch.GetConfig?id=" + Id);
    IF response.IsSuccess
        content := response.Content;
        responseHeaders := response.Headers;
        SwitchConfig := response.Content;
    END
end
Service Attributes
Source
PARSEJSON(SwitchStatus, "$.source", true);
Temprature [°C]
PARSEJSON(SwitchStatus, "$.temperature.tC", true);
Initial State
PARSEJSON(SwitchConfig, "$.initial_state", true);
Input Mode
PARSEJSON(SwitchConfig, "$.in_mode", true);
Power Limit [W]
PARSEJSON(SwitchConfig, "$.power_limit", true);
Voltage Limit [V]
PARSEJSON(SwitchConfig, "$.voltage_limit", true);
Current Limit [A]
PARSEJSON(SwitchConfig, "$.current_limit", true);
Service Actions
Set Initial State
Parameters: Mode
var mode := SWITCH(md, 1, "on", 2, "restore_last", 3, "match_input", "off");
VAR response := SENDHTTPREQUEST("rpc/Switch.SetConfig?id=" + Id +"&config={\"initial_state\":\""+mode+"\"}");
IF response.IsSuccess
  VAR content := response.Content;
  Return("OK");
else
  return(parsejson(response.Content,"$.message"));
END;
Set Mode
Parameters: Mode
var mode := SWITCH(md, 1, "detached", "follow");
VAR response := SENDHTTPREQUEST("rpc/Switch.SetConfig?id=" + Id +"&config={\"in_mode\":\""+mode+"\"}");
IF response.IsSuccess
  VAR content := response.Content;
  Return("OK");
else
  return(parsejson(response.Content,"$.message"));
END;
Connection: Packet Parser → HTTP
Possible improvements (8)
  • Frequency — Network frequency in Hz, available in both Switch and Cover status responses
  • Energy per Minute — Last 3 minute energy values in Wh, available but not exposed as separate device
  • Input 1 State — Physical input state (input:0), available in both profiles
  • Input 2 State — Physical input state (input:1), available in both profiles
  • Switch Toggle — Toggle switch without knowing current state — could be added as service action
  • Reset Energy Counters — Resets energy measurement counters — could be added as service action
  • Slat Position — Slat/tilt position for venetian blinds, if hardware supports it
  • WiFi Signal Strength — RSSI in dBm, available via WiFi component

Sources