TapHome

Shelly i3

Packet Parser → HTTP
Submitted by
Last updated: 06. 2026
Shelly i3

The Shelly i3 is a compact Wi-Fi 3-input action and scenes controller (model SHIX3-1). It has no relays or outputs — it functions purely as an input device that monitors three external switches or push-buttons connected to terminals SW1, SW2 and SW3. The 40 x 36 x 10 mm form factor allows it to be installed inside a standard back-box behind an existing wall switch. It is powered from 110–230 VAC (neutral required) or 24–60 VDC and consumes less than 1 W.

TapHome communicates with the device over HTTP on the local Wi-Fi network — no cloud connection is required. For each input the template creates two devices: a multi-value switch that decodes multi-click events (single, double, triple, long, and combined sequences) and a reed contact that exposes the raw 0/1 input state plus a service action to switch between toggle and momentary mode.

Setup

Wi-Fi pairing and IP address

After power-up, the i3 boots into Access Point mode with SSID shellyi3-XXXXXX (where XXXXXX is the last 6 hex digits of the MAC). To pair it with the home network:

  1. Connect a phone or laptop to the i3 access point
  2. Open http://192.168.33.1 in a browser (or use the Shelly mobile app)
  3. In the web UI go to Internet & Security → WIFI MODE - CLIENT, enter your home Wi-Fi credentials and save
  4. The device reboots and joins the home network via DHCP

To recover the assigned IP address use the router’s DHCP lease table or the mDNS hostname shellyi3-XXXXXXXXXXXX.local (12-character MAC suffix, advertised as _http._tcp.local.). During TapHome template import, enter this IP address as the only required parameter.

Disable HTTP authentication

TapHome cannot authenticate against the device. In the Shelly web UI go to Internet & Security → RESTRICT LOGIN and make sure the option is disabled before importing the template — otherwise every poll will fail with HTTP 401.

Button type configuration

Each of the three inputs can run in one of five btn_type modes. Only two are relevant for TapHome and exposed as a service action on the I1 / I2 / I3 devices:

  • Momentary — for push-buttons. The firmware decodes single short push (S), long push (L), double short push (SS), triple short push (SSS), short→long (SL) and long→short (LS). Required for the Events I{N} devices to fire anything other than None.
  • Toggle — for traditional rocker or toggle switches. Only the raw 0/1 state is reported; the multi-value switch stays at index 0.

The button type can be changed at any time from TapHome via the Button Type service action on each I1 / I2 / I3 device, or directly in the Shelly web UI under Settings → Input/Output settings.

The firmware also supports edge, detached and action modes, but these are not exposed in the TapHome template. They can still be set from the Shelly web UI without breaking the integration — only the multi-click decoding behaviour changes.

Device capabilities

Multi-click event decoding (Events I1, Events I2, Events I3)

For each input, a multi-value switch decodes the firmware-level event code into one of seven values:

IndexEventShelly code
0None"" (idle)
1ShortpushS
2LongpushL
3Double ShortpushSS
4Triple ShortpushSSS
5Shortpush + LongpushSL
6Longpush + ShortpushLS

The template polls /input/{0,1,2} every 2.5 seconds and reads the event field. With 6 events × 3 inputs Shelly markets the i3 as supporting up to 18 distinct multi-click actions (24 if raw on/off state changes are counted as separate triggers).

The long-push threshold and the multi-push window are configured globally on the device (defaults: 800 ms for long press, 500 ms inter-press window). They can be tuned from the Shelly web UI under Settings → Long Push Duration and Multi Push Time.

Raw input state and button-type control (I1, I2, I3)

For each input a reed-contact device exposes the raw logical state read from /input/{N} input field (0 = open, 1 = closed, after the optional btn_reverse inversion). Each I1 / I2 / I3 device also carries:

  • Button Type service attribute — current btn_type value (toggle / momentary / edge / detached / action)
  • Button Type service action — switches the input between Toggle and Momentary by writing POST /settings/input/{N}?btn_type=...

The raw state is suitable for door / window magnetic contacts wired to the SW terminals or for tracking the position of a toggle switch in real time.

Service diagnostics

A single module-level service attribute exposes the Wi-Fi SSID the i3 is currently connected to (read from /statuswifi_sta.ssid). Other Gen1 diagnostics (uptime, MAC, RSSI, firmware update flag) are available on the device’s REST API but not exposed in this template.

Multi-click events fire only in momentary mode. If a physical input is wired through a traditional toggle switch, configure that input as Toggle and use the I{N} reed-contact device to read its 0/1 state — the matching Events I{N} device will stay at index 0.

Troubleshooting

Multi-click events not detected
  1. Verify the input is in momentary mode — open the I{N} device in TapHome, run the Button Type service action and select Momentary, or set it directly in the Shelly web UI under Settings → Input/Output settings
  2. In toggle mode the firmware reports only state changes; the Events I{N} multi-value switch remains at index 0
  3. Adjust Long Push Duration (default 800 ms) and Multi Push Time (default 500 ms) in the Shelly web UI if presses are decoded as the wrong event
  4. Long sequences such as SSS, SL or LS need the user to keep all presses inside the multi-push window — release pauses longer than that window are decoded as separate S events
Same event repeats forever / “stuck” event

The event field returned by /input/{N} is the last event decoded — the firmware does not auto-clear it. TapHome reads this field on every poll, so the multi-value switch will keep reporting the previous event until a new one occurs. This is normal behaviour and does not indicate a fault. When writing custom logic that triggers on every press, pair the event with the monotonic event_cnt counter (also exposed in /input/{N}) to detect a change instead of relying on the event value alone.

Device not responding
  1. Verify the i3 is connected to Wi-Fi — open http://{device-ip}/shelly in a browser; if it returns a JSON object, the device is reachable
  2. Try the mDNS hostname shellyi3-XXXXXXXXXXXX.local instead of the IP address — the IP may have changed after a DHCP renewal
  3. Make sure HTTP authentication is disabled under Internet & Security → Restrict login — TapHome cannot send credentials and every request will return HTTP 401
  4. Check that the TapHome Core and the Shelly device are on the same network or VLAN with mDNS / multicast allowed

Gen1 Shelly devices accept a maximum of 2 concurrent HTTP connections. The shipped template polls every input at 2.5 s intervals which is already close to the limit. Do not lower the poll interval, and avoid running another system (e.g., Home Assistant, custom scripts) that polls the same i3 simultaneously — communication may become unreliable.

The XML template ships with three reserved multi-value indices (7, 8, 9 with raw codes 71/72/73 and generic labels “7” / “8” / “9”). The Gen1 firmware emits no events beyond S, L, SS, SSS, SL and LS, so these indices are unused placeholders and the corresponding Events I{N} device value should never reach 7-9 in practice.

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 i3 Module
Service Attributes
Wi-FiSSID of the Wi-Fi network the device is currently connected to

Shelly i3

Service Attributes
Wifi
 VAR response := SENDHTTPREQUEST("/status");
 IF response.IsSuccess
  VAR content := response.Content;
  RETURN(PARSEJSON(content, "$.wifi_sta.ssid"));
  End
Events I1 Multi-value Switch Read-only

Decoded multi-click event for input I1 — None, Shortpush, Longpush, Double Shortpush, Triple Shortpush, Shortpush + Longpush, Longpush + Shortpush (fires only when Button Type is Momentary)

string (decoded to UInt8 via SWITCH) json_path
Values / States: None · Shortpush · Longpush · Double Shortpush · Triple Shortpush · Shortpush + Longpush · Longpush + Shortpush

Events I1

Read switch state
VAR response := SENDHTTPREQUEST("/input/0");
 IF response.IsSuccess
  VAR content := response.Content;
  RETURN(SWITCH(PARSEJSON(content, "event"),"S", 1, "L", 2, "SS", 3, "SSS", 4, "SL", 5, "LS", 6, 0));
 ELSE
  ADDERROR(response.StatusCode + " (" + response.ReasonPhrase + ")");
  RETURN(NaN);
 END
Events I2 Multi-value Switch Read-only

Decoded multi-click event for input I2 — None, Shortpush, Longpush, Double Shortpush, Triple Shortpush, Shortpush + Longpush, Longpush + Shortpush (fires only when Button Type is Momentary)

string (decoded to UInt8 via SWITCH) json_path
Values / States: None · Shortpush · Longpush · Double Shortpush · Triple Shortpush · Shortpush + Longpush · Longpush + Shortpush

Events I2

Read switch state
VAR response := SENDHTTPREQUEST("/input/1");
 IF response.IsSuccess
  VAR content := response.Content;
  RETURN(SWITCH(PARSEJSON(content, "event"),"S", 1, "L", 2, "SS", 3, "SSS", 4, "SL", 5, "LS", 6, 0));
 ELSE
  ADDERROR(response.StatusCode + " (" + response.ReasonPhrase + ")");
  RETURN(NaN);
 END
Write switch state
# Simple HTTP Request:
# VAR response := SENDHTTPREQUEST("/example/set/value=" + Mu);
# IF response.IsSuccess = false
#  ADDERROR(response.StatusCode);
# END
#
# Set Http request method, body and headers
# VAR response := SENDHTTPREQUEST("/example/setValue", "GET", "value=" + Mu, "header1:value1", "header2:value2", ...);\r
# Or VAR request := HTTPREQUEST("/example/setValue");
# request.Method := "PUT";
# VAR response := SENDHTTPREQUEST(request);
#r
#
# Send TCP, UDP data:
# VAR data1 := "{\"name\":\"John\", \"age\":" + Mu + "}";
# SENDDATA(data1);
# VAR data2 := TOBYTES("{\"name\":\"John\", \"age\":" + Mu + "}", "iso-8859-1");
# SENDDATA(data2);
# You can process received TCP or UDP data in the Listener script
#
#
# Upload data to FTP:
# FTPUPLOAD("filePath", "somedata=" + Mu, "write"); # use "append" mode to append data to existing file
Events I3 Multi-value Switch Read-only

Decoded multi-click event for input I3 — None, Shortpush, Longpush, Double Shortpush, Triple Shortpush, Shortpush + Longpush, Longpush + Shortpush (fires only when Button Type is Momentary)

string (decoded to UInt8 via SWITCH) json_path
Values / States: None · Shortpush · Longpush · Double Shortpush · Triple Shortpush · Shortpush + Longpush · Longpush + Shortpush

Events I3

Read switch state
VAR response := SENDHTTPREQUEST("/input/2");
 IF response.IsSuccess
  VAR content := response.Content;
  RETURN(SWITCH(PARSEJSON(content, "event"),"S", 1, "L", 2, "SS", 3, "SSS", 4, "SL", 5, "LS", 6, 0));
 ELSE
  ADDERROR(response.StatusCode + " (" + response.ReasonPhrase + ")");
  RETURN(NaN);
 END
Write switch state
# Simple HTTP Request:
# VAR response := SENDHTTPREQUEST("/example/set/value=" + Mu);
# IF response.IsSuccess = false
#  ADDERROR(response.StatusCode);
# END
#
# Set Http request method, body and headers
# VAR response := SENDHTTPREQUEST("/example/setValue", "GET", "value=" + Mu, "header1:value1", "header2:value2", ...);\r
# Or VAR request := HTTPREQUEST("/example/setValue");
# request.Method := "PUT";
# VAR response := SENDHTTPREQUEST(request);
#r
#
# Send TCP, UDP data:
# VAR data1 := "{\"name\":\"John\", \"age\":" + Mu + "}";
# SENDDATA(data1);
# VAR data2 := TOBYTES("{\"name\":\"John\", \"age\":" + Mu + "}", "iso-8859-1");
# SENDDATA(data2);
# You can process received TCP or UDP data in the Listener script
#
#
# Upload data to FTP:
# FTPUPLOAD("filePath", "somedata=" + Mu, "write"); # use "append" mode to append data to existing file
Input I1 Reed Contact Read-only

Raw logical state of input I1 — 0 (open) or 1 (closed), reflecting the live position of the switch wired to terminal SW1

boolean json_path
Service Attributes
Button TypeCurrent input behaviour mode for I1 — Toggle (traditional switch) or Momentary (push button, required for multi-click decoding)
Service Actions
Button TypeSwitches input I1 between Toggle (traditional switch) and Momentary (push button — required for the Events I1 multi-click decoding to fire)

Input I1

Read
VAR response := SENDHTTPREQUEST("/input/0");
 IF response.IsSuccess
  VAR content := response.Content;
  RETURN(PARSEJSON(content, "input"));
 ELSE
  ADDERROR(response.StatusCode + " (" + response.ReasonPhrase + ")");
  RETURN(NaN);
 END
Read (module)
# Simple HTTP Request:
# VAR response := SENDHTTPREQUEST("/example/getValue");
# IF response.IsSuccess
#  VAR content := response.Content;
#  VAR responseHeaders := response.Headers;
#  RETURN(PARSEXML(content, "//element1/value1"));
# ELSE
#  ADDERROR(response.StatusCode + " (" + response.ReasonPhrase + ")");
#  RETURN(NaN);
# END
#
# Set Http request method, body and headers
# VAR response := SENDHTTPREQUEST("/example/getValue", "GET", "some data", "header1:value1", "header2:value2", ...);
# OR
# VAR request := HTTPREQUEST("/example/getValue", "POST", "some data");
# request.headers := { "header1:value1", "header2:value2", ...};
# request.method := "GET";
# request.data := null;
# VAR response := SENDHTTPREQUEST(request);
#
#
# Send TCP, UDP data:
# VAR data1 := BYTECOLLECTION("0a bb ea df 01");
# SENDDATA(data1);
# VAR data2 := "{\"name\":\"John\", \"age\":32}";
# SENDDATA(data2);
# VAR data3 := TOBYTES("{\"name\":\"John\", \"age\":32}", "iso-8859-1");
# SENDDATA(data3);
# Process received TCP or UDP data and set device values in the Listener script
#
#
# Download data from FTP:
# FTPDOWNLOAD("filePath");
Service Attributes
Button Type
 VAR response := SENDHTTPREQUEST("/settings/input/0");
 IF response.IsSuccess
  VAR content := response.Content;
  RETURN(PARSEJSON(content, "btn_type"));
 END
Service Actions
Button Type
Parameters: Button Type
 var Ru := SWITCH(Bu, 0, "toggle","momentary") ;
 VAR response := SENDHTTPREQUEST("/settings/input/0?btn_type=" + Ru);
Input I2 Reed Contact Read-only

Raw logical state of input I2 — 0 (open) or 1 (closed), reflecting the live position of the switch wired to terminal SW2

boolean json_path
Service Attributes
Button TypeCurrent input behaviour mode for I2 — Toggle (traditional switch) or Momentary (push button, required for multi-click decoding)
Service Actions
Button TypeSwitches input I2 between Toggle (traditional switch) and Momentary (push button — required for the Events I2 multi-click decoding to fire)

Input I2

Read
VAR response := SENDHTTPREQUEST("/input/1");
 IF response.IsSuccess
  VAR content := response.Content;
  RETURN(PARSEJSON(content, "input"));
 ELSE
  ADDERROR(response.StatusCode + " (" + response.ReasonPhrase + ")");
  RETURN(NaN);
 END
Service Attributes
Button Type
 VAR response := SENDHTTPREQUEST("/settings/input/1");
 IF response.IsSuccess
  VAR content := response.Content;
  RETURN(PARSEJSON(content, "btn_type"));
 END
Service Actions
Button Type
Parameters: Button Type
 var Ru := SWITCH(Bu, 0, "toggle","momentary") ;
 VAR response := SENDHTTPREQUEST("/settings/input/1?btn_type=" + Ru);
Input I3 Reed Contact Read-only

Raw logical state of input I3 — 0 (open) or 1 (closed), reflecting the live position of the switch wired to terminal SW3

boolean json_path
Service Attributes
Button TypeCurrent input behaviour mode for I3 — Toggle (traditional switch) or Momentary (push button, required for multi-click decoding)
Service Actions
Button TypeSwitches input I3 between Toggle (traditional switch) and Momentary (push button — required for the Events I3 multi-click decoding to fire)

Input I3

Read
VAR response := SENDHTTPREQUEST("/input/2");
 IF response.IsSuccess
  VAR content := response.Content;
  RETURN(PARSEJSON(content, "input"));
 ELSE
  ADDERROR(response.StatusCode + " (" + response.ReasonPhrase + ")");
  RETURN(NaN);
 END
Read (module)
# Simple HTTP Request:
# VAR response := SENDHTTPREQUEST("/example/getValue");
# IF response.IsSuccess
#  VAR content := response.Content;
#  VAR responseHeaders := response.Headers;
#  RETURN(PARSEXML(content, "//element1/value1"));
# ELSE
#  ADDERROR(response.StatusCode + " (" + response.ReasonPhrase + ")");
#  RETURN(NaN);
# END
#
# Set Http request method, body and headers
# VAR response := SENDHTTPREQUEST("/example/getValue", "GET", "some data", "header1:value1", "header2:value2", ...);
# OR
# VAR request := HTTPREQUEST("/example/getValue", "POST", "some data");
# request.headers := { "header1:value1", "header2:value2", ...};
# request.method := "GET";
# request.data := null;
# VAR response := SENDHTTPREQUEST(request);
#
#
# Send TCP, UDP data:
# VAR data1 := BYTECOLLECTION("0a bb ea df 01");
# SENDDATA(data1);
# VAR data2 := "{\"name\":\"John\", \"age\":32}";
# SENDDATA(data2);
# VAR data3 := TOBYTES("{\"name\":\"John\", \"age\":32}", "iso-8859-1");
# SENDDATA(data3);
# Process received TCP or UDP data and set device values in the Listener script
#
#
# Download data from FTP:
# FTPDOWNLOAD("filePath");
Service Attributes
Button Type
 VAR response := SENDHTTPREQUEST("/settings/input/2");
 IF response.IsSuccess
  VAR content := response.Content;
  RETURN(PARSEJSON(content, "btn_type"));
 END
Service Actions
Button Type
Parameters: Button Type
 var Ru := SWITCH(Bu, 0, "toggle","momentary") ;
 VAR response := SENDHTTPREQUEST("/settings/input/2?btn_type=" + Ru);
Connection: Packet Parser → HTTP
Possible improvements (14)
  • Input Event Counter — Monotonic UInt16 counter incrementing on every decoded event — required to reliably detect rapid repeats since the event field is sticky. Could be exposed as a Variable per input.
  • Extended Button Type modes — Template's Button Type service action only exposes Toggle/Momentary; firmware also supports edge, detached and action modes.
  • Input Logic Reverse — Inverts logical state of an input. Could be added as bool service action per input.
  • Long-push Minimum Duration — Default 800 ms, range 1–5000 ms. Global parameter applied to all three inputs.
  • Long-push Maximum Duration — Default 800 ms, range 1–5000 ms.
  • Multi-push Window — Default 500 ms, range 1–1000 ms. Window for joining short pushes into SS/SSS sequences.
  • Action / Webhook Table — Per-event HTTP webhook URLs (btn_on_url, btn_off_url, shortpush_url, longpush_url, double_shortpush_url, triple_shortpush_url, shortpush_longpush_url, longpush_shortpush_url). Out of scope for TapHome which polls inputs directly.
  • Wi-Fi Signal Strength — RSSI in dBm, available in /status. Could be added as a module-level service attribute.
  • Firmware Update Available — Boolean from /status. Other Shelly Gen1 templates expose this as 'FW update' service attribute.
  • Uptime — Seconds since boot. Diagnostic value commonly exposed by other Shelly Gen1 templates.
  • MAC Address — Diagnostic identifier, commonly exposed by other Shelly Gen1 templates as a service attribute.
  • Cloud Status — Shelly Cloud enable + connection booleans.
  • MQTT Connection Status — MQTT broker connection state.
  • While-pressed Long-push Pulse — MQTT-only feature: stays at 1 for the duration of a long press, useful for 'while-pressed' actions. Not available via HTTP polling.

Sources

Found a problem with this device template?

Tell us what's wrong, what's missing, or how the template should behave. We rely on your feedback to keep the catalog accurate.

Verified by TapHome

Want to use this in your TapHome Core?

Open this template in the Customer Portal to apply it to one of your homes, or to draft a refinement and submit it back to the catalog.

Open in portal