TapHome

Shelly 3EM MQTT

Packet Parser → MQTT
Submitted by
Last updated: 06. 2026
Shelly 3EM MQTT

The Shelly 3EM is a 3-phase Wi-Fi energy meter from Shelly’s first generation (Gen1). It measures active power, voltage, current, power factor and lifetime energy independently for each of three phases using three included 120 A split-core CT clamps, and includes a built-in 10 A relay typically used to drive an external power contactor coil. TapHome communicates with the device over MQTT — the device pushes per-phase measurements to a broker, the TapHome PacketParser module subscribes to the shellies/# topic tree and routes the values to four child devices (3 electric meters + 1 contactor switch).

This is the MQTT variant of the Shelly 3EM template. An HTTP variant is also available — choose MQTT when you already run a local MQTT broker, want push-based updates instead of polling, or need to share the meter with multiple consumers (TapHome plus another system). Note that enabling MQTT on Gen1 firmware disables Shelly Cloud — the two cannot run simultaneously.

Configuration

Enabling MQTT in the Shelly 3EM

Open the Shelly 3EM web UI (http://{device-ip} or http://shelly3em-{MAC}.local) and configure the MQTT client:

  1. Go to Internet & SecurityAdvanced - Developer Settings
  2. Tick Enable action execution via MQTT
  3. Fill Server with {MQTT broker IP address}:{port} — typically 192.168.1.10:1883
  4. (Optional) Set Username and Password if the broker requires authentication
  5. Click SAVE — the device reboots and connects to the broker

Gen1 Shelly devices do not support MQTT over TLS. Communication between the device and the broker is unencrypted plain TCP on port 1883. Username and password are sent in plaintext. Use the MQTT broker only on a trusted local network.

Enabling MQTT automatically disables Shelly Cloud on Gen1 firmware. To revert, untick the MQTT option and re-enable Cloud in Internet & Security.

Finding the Device ID

The TapHome template subscribes to shellies/shellyem3-{dID}/#, where {dID} is the device’s MAC suffix used as the MQTT topic prefix.

To find it in the Shelly 3EM web UI:

  1. Open the device web UI in a browser
  2. Go to SettingsDevice Info
  3. Copy the first Device ID string (NOT the value in brackets) — this equals the WiFi MAC address (e.g., DC4F227649A1)

Alternatively, query GET http://{device-ip}/settings and read the mqtt.id field.

Template setup

After importing the template in TapHome, set three import parameters:

ParameterDescriptionExample
IpAddressMQTT broker IP address192.168.1.10
PortMQTT broker port1883
dIDDevice ID (MAC suffix) of the Shelly 3EMDC4F227649A1

The module then subscribes to shellies/# (QoS 0) and listener scripts route per-phase emeter and relay messages to the corresponding child devices. The default MQTT update period of the device is 30 seconds — it can be reduced via GET http://{device-ip}/settings?mqtt_update_period=N (set 0 to publish only on change).

The MQTT topic prefix on the wire is shellyem3-{MAC} while the device’s mDNS hostname is shelly3em-{MAC}.local — Shelly uses two different forms for the same device. The template follows the actual MQTT topic prefix (shellyem3-). If MQTT messages do not arrive, subscribe to shellies/# with an MQTT client to verify the prefix the firmware is using.

Device capabilities

Per-phase active power and lifetime energy

The template creates three electric meter devices — one for each phase (CT clamp 1 → phase A, clamp 2 → phase B, clamp 3 → phase C). Each meter reads two values:

  • Active power — instantaneous power from shellies/shellyem3-{dID}/emeter/{i}/power (W), divided by 1000 and stored as kW
  • Total energy consumed — lifetime cumulative energy from .../emeter/{i}/total (Wh), divided by 1000 and stored as kWh

Each CT clamp is rated for 120 A and is non-invasive (clip-on, no wire cutting required). The included 3 CT clamps are individually marked and calibrated — they are NOT interchangeable between channels.

Per-phase electrical parameters

Each electric meter exposes four service attributes for advanced monitoring:

  • Voltage [V] — RMS line-to-neutral voltage on that phase (.../emeter/{i}/voltage)
  • Current [A] — RMS current measured by the corresponding CT clamp (.../emeter/{i}/current)
  • Power factor — ratio of active to apparent power, range −1.00 to 1.00 (.../emeter/{i}/pf)
  • Returned energy [Wh] — lifetime energy returned to the grid on that phase (.../emeter/{i}/total_returned), useful for PV / bidirectional metering

The combination of total (consumed) and total_returned (exported) per phase makes the template suitable for solar / grid-feed installations.

Energy counter reset

Each phase has a Reset total service action that publishes reset_totals to shellies/shellyem3-{dID}/emeter/{i}/command. This zeroes both the total and total_returned counters for that specific phase — useful when re-purposing the meter or starting a new measurement period.

Contactor relay

The on-board 10 A relay is exposed as a switch device. The state is read from shellies/shellyem3-{dID}/relay/0 (on → 1, anything else → 0) and controlled by publishing on or off to .../relay/0/command. The relay is rated 10 A / 240 V AC and is typically wired through the I (line input) and O (relay output) terminals to drive the coil of an external power contactor for switching higher loads.

The MQTT template does not publish a 3-phase total power sum (total_power is HTTP-only on Gen1). Create a TapHome virtual device that sums the three per-phase power values if you need a single household-power figure.

Troubleshooting

No MQTT messages received
  1. Confirm MQTT is enabled in the Shelly web UI (Internet & SecurityAdvanced - Developer SettingsEnable action execution via MQTT) and the device has rebooted after saving
  2. Verify the broker IP and port in the device match the IpAddress/Port import parameters in TapHome
  3. Subscribe to shellies/# with an MQTT client (e.g., MQTT Explorer, mosquitto_sub) and check whether the device publishes anything — verify the actual topic prefix (shellyem3-{dID}) matches the dID you entered in TapHome
  4. Ensure the MQTT broker is running and reachable from both the Shelly 3EM and the TapHome Core
  5. If the device IP recently changed, try connecting to the mDNS hostname shelly3em-{MAC}.local to verify the device is reachable on the network
Energy readings show zero or implausible values
  1. Confirm each CT clamp is connected to the correct input — clamp marked IA must be wired to terminals IA-/IA+, IB to IB-/IB+, IC to IC-/IC+. The clamps are calibrated per channel and are not interchangeable.
  2. Verify the arrow on the CT clamp body points in the direction of current flow (from source towards load). A reversed clamp produces a negative power factor and inverts the consumption / return classification.
  3. Check that voltage inputs VA, VB, VC are wired to the matching phases that the CT clamps measure — mismatched voltage / current pairing produces wrong power and power-factor readings.
  4. If a single phase reads zero while the others are correct, swap that CT clamp with a known-good one to isolate clamp vs. circuit.
Cannot enable MQTT — Cloud is in use

On Gen1 firmware, MQTT and Shelly Cloud are mutually exclusive. If the Enable action execution via MQTT checkbox is greyed out, disable Shelly Cloud first under Internet & SecurityCloud, then re-open the MQTT settings.

Shelly Cloud history disappeared after enabling MQTT

This is expected — enabling MQTT disables Cloud, including its 365-day history retention. If you need both real-time MQTT control in TapHome and long-term history, route MQTT messages through your own broker and keep historical data in TapHome (or a separate logging system).

Each CT clamp must always be wired to the Shelly 3EM terminals before clipping it around a live conductor. Voltage induced across an open CT secondary winding can reach dangerous levels and damage the clamp.

How to install in TapHome

Prerequisites

  • Shelly device connected to Wi-Fi (see HTTP connection guide if not done yet)
  • MQTT broker running on your local network (e.g., Mosquitto, Home Assistant, or TapHome built-in broker)
  • TapHome CCU on the same network as the broker

On Gen1 devices, enabling MQTT disables Shelly Cloud. Both cannot run simultaneously. On Gen2/Plus devices this limitation does not apply.

Step 1 — Enable MQTT on the Shelly device

Gen1 devices (Shelly 1, 1PM, 2.5, EM, 3EM, Plug S, RGBW2, Dimmer, TRV…)

  1. Open the Shelly web UI: http://<device-ip>/
  2. Navigate to Internet & SecurityAdvanced — MQTT
  3. Enable MQTT
  4. Set MQTT Server: <broker-ip>:<port> (e.g., 192.168.1.10:1883)
  5. Optionally set MQTT User and MQTT Password if your broker requires authentication
  6. Click Save — the device will reboot and connect to the broker

Gen2 / Plus devices (Shelly Plus 1, Plus 1PM, Plus 2PM, Plus Plug S, Plus H&T, Pro 3EM…)

  1. Open the Shelly web UI: http://<device-ip>/
  2. Navigate to SettingsMQTT
  3. Enable MQTT
  4. Set Server: <broker-ip>:<port> (e.g., 192.168.1.10:1883)
  5. The Client ID is pre-filled with the device ID (e.g., shellyplus1pm-AABBCCDDEE) — leave as-is unless you have a specific reason to change it
  6. Click Save and reboot the device

To verify MQTT is working, use an MQTT client (e.g., MQTT Explorer) and subscribe to shellies/# (Gen1) or <device-id>/# (Gen2). You should see status messages from the device.

Step 2 — Find the Device ID / MQTT Client ID

Some templates require a Device ID or MQTT Client ID parameter. This is the unique identifier used in MQTT topics.

  • Gen1: found on the label as MAC address (e.g., AABBCCDDEE). Device ID = shelly<model>-<mac>, e.g., shelly1pm-AABBCCDDEE
  • Gen2/Plus: found in the Shelly web UI under SettingsDevice InfoDevice ID, or on the device label

Step 3 — Configure in TapHome

  1. In TapHome, add a new Packet Parser (MQTT) module
  2. IP Address: enter the MQTT broker IP (e.g., 192.168.1.10)
  3. Port: 1883 (default; use 8883 for TLS)
  4. Device ID / MQTT Client ID: enter the value from Step 2 (if required by the template)
  5. Import the template — TapHome will subscribe to the device topics automatically

Available devices

Shelly 3EM MQTT Module
Custom Variables
dID (string)MAC suffix of the Shelly 3EM that forms the MQTT topic prefix shellies/shellyem3-{dID}/... — find it in Shelly web UI → Settings → Device Info (first string, NOT the value in brackets)
Open Shelly 3EM web UI → Settings → Device Info → copy the first Device ID string (NOT the value in brackets); equals the WiFi MAC address (e.g. DC4F227649A1)
Electric Meter (Phase 1) Electricity Meter Read-only

Active power (kW) and lifetime energy (kWh) on phase A — read from CT clamp 1, with W→kW and Wh→kWh conversion

numeric Unit: kW / kWh
Service Attributes
Returned EnergyLifetime energy returned to the grid on phase A (Wh) — useful for PV / bidirectional metering
VoltageRMS line-to-neutral voltage on phase A (V)
CurrentRMS current measured by CT clamp 1 (A)
Power FactorPower factor on phase A — ratio of active to apparent power, range −1.00 to 1.00
Service Actions
Reset TotalResets both the total and total_returned energy counters for phase A to zero

Electric Meter (Phase 1)

Read total consumption
# 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");
Read demand
# 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");
Listener
IF(RECEIVEDMSG.TOPIC = "shellies/shellyem3-"+dID+"/emeter/0/power")
 Ed := todouble(TOSTRING(RECEIVEDMSG.PAYLOAD))/1000;
elseif(RECEIVEDMSG.TOPIC = "shellies/shellyem3-"+dID+"/emeter/0/total")
 To := todouble(TOSTRING(RECEIVEDMSG.PAYLOAD))/1000;
END
Service Attributes
returned energy [Wh]
IF(parsejson(x, "Topic") = "shellies/shellyem3-"+dID+"/emeter/0/total_returned")
 return(parsejson(x, "Payload"));
END
voltage [V]
IF(parsejson(x, "Topic") = "shellies/shellyem3-"+dID+"/emeter/0/voltage")
 return(todouble(parsejson(x, "Payload")));
END
current [A]
IF(parsejson(x, "Topic") = "shellies/shellyem3-"+dID+"/emeter/0/current")
 return(todouble(parsejson(x, "Payload")));
END
power factor
IF(parsejson(x, "Topic") = "shellies/shellyem3-"+dID+"/emeter/0/pf")
 return(todouble(parsejson(x, "Payload")));
END
Service Actions
Reset total
mqttpublish("shellies/shellyem3-"+dID+"/emeter/0/command", "reset_totals");
Electric Meter (Phase 2) Electricity Meter Read-only

Active power (kW) and lifetime energy (kWh) on phase B — read from CT clamp 2, with W→kW and Wh→kWh conversion

numeric Unit: kW / kWh
Service Attributes
Returned EnergyLifetime energy returned to the grid on phase B (Wh) — useful for PV / bidirectional metering
VoltageRMS line-to-neutral voltage on phase B (V)
CurrentRMS current measured by CT clamp 2 (A)
Power FactorPower factor on phase B — ratio of active to apparent power, range −1.00 to 1.00
Service Actions
Reset TotalResets both the total and total_returned energy counters for phase B to zero

Electric Meter (Phase 2)

Read total consumption
# 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");
Read demand
# 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");
Listener
IF(RECEIVEDMSG.TOPIC = "shellies/shellyem3-"+dID+"/emeter/1/power")
 Ed := todouble(TOSTRING(RECEIVEDMSG.PAYLOAD))/1000;
 elseif(RECEIVEDMSG.TOPIC = "shellies/shellyem3-"+dID+"/emeter/1/total")
 To := todouble(TOSTRING(RECEIVEDMSG.PAYLOAD))/1000;
END
Service Attributes
total returned [Wh]
IF(parsejson(x, "Topic") = "shellies/shellyem3-"+dID+"/emeter/1/total_returned")
 return(todouble(parsejson(x, "Payload")));
END
voltage [V]
IF(parsejson(x, "Topic") = "shellies/shellyem3-"+dID+"/emeter/1/voltage")
 return(todouble(parsejson(x, "Payload")));
END
current [A]
IF(parsejson(x, "Topic") = "shellies/shellyem3-"+dID+"/emeter/1/current")
 return(todouble(parsejson(x, "Payload")));
END
power factor
IF(parsejson(x, "Topic") = "shellies/shellyem3-"+dID+"/emeter/1/pf")
 return(todouble(parsejson(x, "Payload")));
END
Service Actions
Reset total
mqttpublish("shellies/shellyem3-"+dID+"/emeter/1/command", "reset_totals");
Electric Meter (Phase 3) Electricity Meter Read-only

Active power (kW) and lifetime energy (kWh) on phase C — read from CT clamp 3, with W→kW and Wh→kWh conversion

numeric Unit: kW / kWh
Service Attributes
Returned EnergyLifetime energy returned to the grid on phase C (Wh) — useful for PV / bidirectional metering
VoltageRMS line-to-neutral voltage on phase C (V)
CurrentRMS current measured by CT clamp 3 (A)
Power FactorPower factor on phase C — ratio of active to apparent power, range −1.00 to 1.00
Service Actions
Reset TotalResets both the total and total_returned energy counters for phase C to zero

Electric Meter (Phase 3)

Read total consumption
# 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");
Read demand
# 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");
Listener
IF(RECEIVEDMSG.TOPIC = "shellies/shellyem3-"+dID+"/emeter/2/power")
 Ed := todouble(TOSTRING(RECEIVEDMSG.PAYLOAD))/1000;
 elseif(RECEIVEDMSG.TOPIC = "shellies/shellyem3-"+dID+"/emeter/2/total")
 To := todouble(TOSTRING(RECEIVEDMSG.PAYLOAD))/1000;
END
Service Attributes
total returned [Wh]
IF(parsejson(x, "Topic") = "shellies/shellyem3-"+dID+"/emeter/2/total_returned")
 return(todouble(parsejson(x, "Payload")));
END
voltage [V]
IF(parsejson(x, "Topic") = "shellies/shellyem3-"+dID+"/emeter/2/voltage")
 return(todouble(parsejson(x, "Payload")));
END
current [A]
IF(parsejson(x, "Topic") = "shellies/shellyem3-"+dID+"/emeter/2/current")
 return(todouble(parsejson(x, "Payload")));
END
Power Factor
IF(parsejson(x, "Topic") = "shellies/shellyem3-"+dID+"/emeter/2/pf")
 return(todouble(parsejson(x, "Payload")));
END
Service Actions
reset total
mqttpublish("shellies/shellyem3-"+dID+"/emeter/2/command", "reset_totals");
Contactor Relay Switch

On-board 10 A relay — typically wired to drive the coil of an external power contactor through the I/O terminals

boolean
Values / States: ON · OFF

Contactor Relay

Read switch state
# 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");
Write switch state
# Simple HTTP Request:
MQTTPUBLISH("shellies/shellyem3-"+dID+"/relay/0/command", switch(St,1,"on","off"));
# VAR response := SENDHTTPREQUEST("/example/set/value=" + St);
# IF response.IsSuccess = false
#  ADDERROR(response.StatusCode);
# END
#
# Set Http request method, body and headers
# VAR response := SENDHTTPREQUEST("/example/setValue", "GET", "value=" + St, "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\":" + St + "}";
# SENDDATA(data1);
# VAR data2 := TOBYTES("{\"name\":\"John\", \"age\":" + St + "}", "iso-8859-1");
# SENDDATA(data2);
# You can process received TCP or UDP data in the Listener script
#
#
# Upload data to FTP:
# FTPUPLOAD("filePath", "somedata=" + St, "write"); # use "append" mode to append data to existing file
Listener
# Parse received bytes:
IF(RECEIVEDMSG.TOPIC = "shellies/shellyem3-"+dID+"/relay/0")
 St := switch(TOSTRING(RECEIVEDMSG.PAYLOAD),"on",1,0);
END
Connection: Packet Parser → MQTT
Possible improvements (10)
  • Reactive Power (per phase) — Instantaneous reactive power in VAR per phase — useful for power-quality diagnostics.
  • Short-term Energy Counter — Watt-minute counter since boot (volatile). Template uses lifetime 'total' instead.
  • Short-term Returned Energy — Watt-minute returned counter since boot (volatile).
  • Contactor Coil Power — Power draw through the on-board relay (small — coil only).
  • Contactor Coil Energy — Energy through the on-board relay (Wm).
  • Connection Status (LWT) — Last-Will-and-Testament topic — true on connect, false retained on disconnect. Could detect offline 3EM.
  • Device Announcement (JSON) — Periodic JSON announce containing id, mac, ip, fw_ver, new_fw, model.
  • Full Status JSON — Complete /status payload as JSON — could expose Wi-Fi RSSI, internal temperature, all 4 emeter channels.
  • 4th CT — Theft / Leakage Detection — Optional 4th split-core CT on IN+/IN- terminal for neutral leakage / energy-theft detection. NOT published over MQTT — only HTTP.
  • Total Active Power — 3EM does not publish total_power over MQTT (only HTTP). Sum the three phase Ed values in a TapHome virtual device.

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