---
title: "Shelly DUO MQTT"
description: "Control up to 5 Shelly DUO white bulbs over MQTT — brightness, CCT 3000-6500 K with smooth transitions and per-bulb kW/kWh metering. TapHome Gen1 integration."
url: "https://taphome.com/en/compatibility/shelly-duo-mqtt/"
language: en
lastmod: 2026-10-08
generator: hugo
ai:
  topics: ["mqtt","lighting","wifi","tunable-white","cct","power-metering","led-bulb","gen1","mdns"]
  questions: ["How to integrate Shelly DUO with TapHome via MQTT?","How to find the Shelly DUO MQTT Device ID?","How to control multiple Shelly DUO bulbs from one TapHome template?","Why does the Shelly DUO show zero power readings in TapHome?","Why is the warmest color temperature only 3000 K instead of 2700 K?","Does enabling MQTT on Shelly DUO disable Shelly Cloud?"]
---

# Shelly DUO MQTT

Communication: Packet Parser → MQTT

- [Shelly DUO Product Page](https://www.shelly.com/en/products/shop/shelly-bulb-duo)
- [Shelly Gen1 MQTT API Documentation](https://shelly-api-docs.shelly.cloud/gen1/#shelly-duo-mqtt)

> Network address
> 
> With the MQTT broker built into TapHome, enter `127.0.0.1` as the broker address in TapHome. In the device, enter the IP address of the TapHome Core and give the Core an IP reservation in the router.
> 
> [Network Preparation](https://taphome.com/en/docs/setup/network-preparation/)

## Integration guide

The Shelly DUO (model **SHBDUO-1**) is a Gen1 Wi-Fi LED smart bulb available in **E27** and **GU10** form factors. The plain DUO is **white-only** with tunable color temperature and dimmable brightness — it has no RGB channels (the RGB-capable variant is the *DUO RGBW* / `shellycolorbulb-` and uses a separate template). This is the **MQTT variant** of the TapHome integration; an [HTTP variant](https://taphome.com/en/compatibility/shelly-duo/) is also available for single-bulb setups.

The template supports up to **5 DUO bulbs** per module through a shared MQTT broker on the local network. Each bulb is identified by a `bulbNtopic` module variable pointing to the bulb's MQTT Device ID, and exposes both a white-light device and an electric meter — 10 devices total.

## Configuration

### MQTT broker

The template needs an MQTT broker reachable on the local network — any standard broker works (Mosquitto, EMQX, or the broker built into Home Assistant). The broker runs on **port 1883** with no TLS (Gen1 Shelly hardware does not support MQTT over TLS), so keep it on a trusted segment.

After importing the template, set the broker connection in the module's import parameters:

| Parameter | Default | Description |
|-----------|---------|-------------|
| **MQTT Broker IP** (`IpAddress`) | `192.168.0.1` | Broker address on the local network |
| **MQTT Broker port** (`Port`) | `1883` | Standard MQTT port (no TLS) |
| **Transition time** (`TransitionTime`) | `300` | Default per-bulb fade duration in milliseconds |

### Enabling MQTT on the bulb

Each Shelly DUO must be pointed at the broker before it will publish or accept commands:

1. Open the bulb's web UI at `http://<bulb-ip>` (find the IP in your router's DHCP table or via the Shelly app)
2. Go to **Internet & Security** → **Advanced — MQTT** and enable **MQTT**
3. Enter the broker's **server** (IP and port, e.g. `192.168.0.10:1883`) and leave **username** / **password** empty (the TapHome template does not surface broker authentication)
4. Optionally adjust the **MQTT prefix** if you do not want the default `shellies/ShellyBulbDuo-<MAC6>`
5. Save and reboot the bulb — once it reconnects it starts publishing on `shellies/ShellyBulbDuo-<id>/light/0/status`

### Device ID (`bulbNtopic`)

Each Shelly DUO has a unique MQTT Device ID in the format **`ShellyBulbDuo-<MAC6>`**, where `<MAC6>` is the last 6 hex characters of the MAC address (e.g. `ShellyBulbDuo-B929CC`). This same value is the bulb's mDNS hostname (`ShellyBulbDuo-<MAC6>.local`).

The Device ID can be found:

- In the Shelly web UI: **Settings** → **Device Info** → `mqtt.id` field
- Via HTTP: `GET http://<bulb-ip>/settings` → `mqtt.id`
- On the device label / packaging (last 6 chars of the MAC)
- As the mDNS hostname, e.g. `ShellyBulbDuo-B929CC.local`

Open the **Shelly DUO MQTT** module in TapHome and fill the topic variables for each bulb you want to use:

| Variable | Default | Description |
|----------|---------|-------------|
| `bulb1topic` | `ShellyBulbDuo-deviceid1` | MQTT Device ID of the first DUO bulb |
| `bulb2topic` | `ShellyBulbDuo-deviceid2` | MQTT Device ID of the second DUO bulb |
| `bulb3topic` | `ShellyBulbDuo-deviceid3` | MQTT Device ID of the third DUO bulb |
| `bulb4topic` | `ShellyBulbDuo-deviceid4` | MQTT Device ID of the fourth DUO bulb |
| `bulb5topic` | `ShellyBulbDuo-deviceid5` | MQTT Device ID of the fifth DUO bulb |

Replace the placeholder with the actual Device ID for each bulb you want to control (e.g. `ShellyBulbDuo-B929CC`). The module subscribes to `shellies/#` and the per-bulb listener scripts filter messages by topic prefix. Slots that are still left at the placeholder value raise an error in TapHome until they are configured or removed from the template.

### Per-bulb transition time

Each Light device exposes a `transitionTime` custom variable (in milliseconds, range 0-5000 ms) which defaults to the module-level `TransitionTime` import parameter. Override it on individual bulbs if you want different fade durations — the value is sent on every brightness or CCT change as the `transition` field in the `/light/0/set` JSON payload.

> [!WARNING]
> Enabling MQTT on a Gen1 Shelly device **disables Shelly Cloud** — both cannot run simultaneously. HTTP REST and CoIoT remain available, so the bulb stays reachable from the local network.

## Device capabilities

The template exposes 10 devices per module — 5 white-tunable lights and 5 electric meters, one pair per physical bulb. All 5 pairs are functionally identical, distinguished only by the `bulbNtopic` they listen on.

### Light control

Each Light device is mapped as a **White Light** in TapHome with two control properties:

- **Brightness** — read from the `$.brightness` field (0-100) of the `light/0/status` JSON, scaled to TapHome's 0.0-1.0 range; written via `light/0/set` with `"turn":"on", "brightness":N, "transition":<ms>`
- **Color temperature** — read from `$.temp` (3000-6500 K), written via `light/0/set` with `"temp":K, "transition":<ms>`

Switching the light off uses a separate `light/0/command` topic with the `off` payload, which is faster than constructing a JSON `set` message. Brightness and CCT updates always include the `transition` field so the bulb fades smoothly instead of jumping.

### Power metering

Each Electric Meter device subscribes to two scalar topics published by the bulb roughly once per second:

| TapHome value | Source topic | Source unit | Conversion | Display unit |
|---------------|--------------|-------------|------------|--------------|
| Real-time power | `shellies/ShellyBulbDuo-<id>/light/0/power` | W | `÷ 1000` | kW |
| Total consumption | `shellies/ShellyBulbDuo-<id>/light/0/energy` | watt-minutes | `÷ 60000` | kWh |

The watt-minute → kWh conversion is needed because Shelly Gen1 firmware reports cumulative energy in W·min rather than W·h.

> [!TIP]
> Power monitoring is silently zero until **Settings → Device Model** is configured (E27 or GU10) in the Shelly app or web UI. The TapHome listener emits an info banner reminding you of this on first read. Once the model is set, the bulb starts reporting non-zero `power`/`energy` immediately.

## Troubleshooting

### Bulb not responding

1. Verify the bulb is connected to Wi-Fi and reachable on the LAN — open `http://<bulb-ip>/shelly`. A response containing `"type":"SHBDUO-1"` confirms the device.
2. Try the mDNS hostname (`ShellyBulbDuo-<MAC6>.local`) instead of the IP address — DHCP renewals or router reboots can change the IP.
3. Confirm MQTT is enabled under the bulb's **Internet & Security → Advanced — MQTT** settings and that the broker IP/port match the TapHome import parameters.
4. Use an MQTT client (e.g. **MQTT Explorer** or `mosquitto_sub -h <broker> -t 'shellies/#' -v`) to verify the bulb is publishing on `shellies/ShellyBulbDuo-<id>/...`.

### "Set correct 'bulbNtopic' value" error

The listener script raises this error when a `bulbNtopic` is still set to the default placeholder (`ShellyBulbDuo-deviceid`). Either fill in the real Device ID for that slot, or remove the unused devices from the template if you only have a few bulbs.

### Power and energy stay at zero

1. Open the Shelly app (or web UI) → **Settings** → **Device Model** and select the matching sub-model (**Shelly Bulb DUO E27** or **Shelly Bulb DUO GU10**). The bulb only computes `power`/`energy` once the model is known.
2. Confirm the bulb is actually on — the meter only updates while current is flowing.
3. Subscribe to `shellies/ShellyBulbDuo-<id>/light/0/power` directly with an MQTT client to verify the bulb publishes a non-zero value.

### Warmest CCT only goes down to 3000 K

The TapHome XML clamps CCT to **3000-6500 K** to match the marketed E27 range. The hardware itself supports **2700-6500 K** on the GU10 sub-model and through the raw `/light/0/set` API, so the warmest 300 K of the GU10's range is unreachable through the TapHome template.

### Light transitions look jerky

Increase the per-bulb `transitionTime` custom variable (or the module-level `TransitionTime` default). 300 ms is fine for small dimming steps but can look stepped on large brightness or CCT changes — try 800-1500 ms for a smoother fade.

> [!WARNING]
> Gen1 Shelly devices use **plain MQTT** on port 1883 — there is no TLS support. The TapHome template also does not expose broker `username` / `password`, so use an unauthenticated broker on a trusted local network or VLAN.

## How to install in TapHome

### Prerequisites

- Shelly device connected to Wi-Fi (2.4 GHz), e.g. through the Shelly app or the device's own access point
- 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

> [!WARNING]
> 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 & Security** → **Advanced — 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 **Settings** → **MQTT**
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

With the TapHome built-in broker, `<broker-ip>` is the IP address of the TapHome Core. Give the Core an IP reservation in the router, otherwise the device loses the broker when the router changes the address → [Network Preparation](https://taphome.com/en/docs/setup/network-preparation/).

> [!TIP]
> 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 **Settings** → **Device Info** → **Device ID**, or on the device label

### Step 3 — Configure in TapHome

1. In TapHome, add a new **Packet Parser (MQTT)** module
2. **IP Address:** `127.0.0.1` for the TapHome built-in broker (the control unit connects to itself, the address never changes); for an external broker its IP address (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 10

These devices appear in TapHome after import.

Shelly DUO MQTT Module

Custom Variables

`bulb1topic` (string) = ShellyBulbDuo-deviceid1 MQTT device ID of the first Shelly DUO bulb — format is 'ShellyBulbDuo-DEVICEID'

Open http://shellyIpAddress in a browser → Settings → Device Info → copy the mqtt.id (or Device ID) field. Default mDNS hostname matches the MQTT id (ShellyBulbDuo-{MAC6}.local).

`bulb2topic` (string) = ShellyBulbDuo-deviceid2 MQTT device ID of the second Shelly DUO bulb 

`bulb3topic` (string) = ShellyBulbDuo-deviceid3 MQTT device ID of the third Shelly DUO bulb 

`bulb4topic` (string) = ShellyBulbDuo-deviceid4 MQTT device ID of the fourth Shelly DUO bulb 

`bulb5topic` (string) = ShellyBulbDuo-deviceid5 MQTT device ID of the fifth Shelly DUO bulb

Electric Meter 1 Electricity Meter Read-only

Real-time power (kW) and cumulative energy (kWh) of bulb 1 — requires Settings → Device Model to be set in the Shelly app, otherwise both values stay at 0

numeric Unit: kW / kWh

Listener

```taphome
ADDINFO("To enable power monitoring, open device settings in Shelly app or web browser and configure device model in Settings->Device Model");

IF(INDEXOF(bulb1topic, "ShellyBulbDuo-deviceid") = 0)
    ADDERROR("Set correct 'bulb1topic' value in module variables. Topic format is 'ShellyBulbDuo-<deviceid>'. The Device ID can be found by opening url 'http://shellyIpAddress', in Settings -> Device info.");
    RETURN(-1);
END

IF INDEXOF(RECEIVEDMSG.TOPIC, "shellies/" + bulb1topic + "/light/0/power") = 0
    Ed := TODOUBLE(TOSTRING(RECEIVEDMSG.PAYLOAD)) / 1000.0;
ELSEIF INDEXOF(RECEIVEDMSG.TOPIC, "shellies/" + bulb1topic + "/light/0/energy") = 0
    To := TODOUBLE(TOSTRING(RECEIVEDMSG.PAYLOAD)) / 60000.0;
END
```

Light 1 White Light Read and write

White-tunable bulb 1 — on/off, brightness 0-100 % and color temperature 3000-6500 K with smooth transitions

json Unit: % / K json\_path

Variable: `transitionTime` — Per-bulb transition time in milliseconds (0-5000 ms) inherited from the TransitionTime import parameter

Listener

```taphome
IF(INDEXOF(bulb1topic, "ShellyBulbDuo-deviceid") = 0)
    ADDERROR("Set correct 'bulb1topic' value in module variables. Topic format is 'ShellyBulbDuo-<deviceid>'. The Device ID can be found by opening url 'http://shellyIpAddress', in Settings -> Device info.");
    RETURN(-1);
END

IF INDEXOF(RECEIVEDMSG.TOPIC, "shellies/" + bulb1topic + "/light/0/status") != 0
    RETURN(0);
END

IF RECEIVEDMSG.PAYLOAD.LENGTH = 0
    RETURN(0);
END

VAR ison := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.ison", 1);
VAR bright := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.brightness");

IF ISNULL(ison) OR ISNULL(bright)
    RETURN(0);
END

Ct := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.temp", 1);

IF ison
    Hb := bright / 100.0;
    St := isOn;
ELSE 
    Hb := 0;
    St := 0;
END
```

Write brightness

```taphome
IF St > 0.5
    VAR topic := "shellies/" + bulb1topic + "/light/0/set";    
    MQTTPUBLISH(topic, "{\"turn\": \"on\", \"transition\": " + transitionTime + ", \"brightness\": " + ROUND(Hb*100.0) + "}");
ELSE
    MQTTPUBLISH("shellies/" + bulb1topic + "/light/0/command", "off");
END
```

Write color temperature

```taphome
IF ISNAN(Ct)
    RETURN(0);
END

VAR topic := "shellies/" + bulb1topic + "/light/0/set";
MQTTPUBLISH(topic, "{\"transition\": " + transitionTime + ", \"temp\":" + Ct + "}");
```

Electric Meter 2 Electricity Meter Read-only

Real-time power (kW) and cumulative energy (kWh) of bulb 2 — requires Settings → Device Model to be set in the Shelly app, otherwise both values stay at 0

numeric Unit: kW / kWh

Listener

```taphome
ADDINFO("To enable power monitoring, open device settings in Shelly app or web browser and configure device model in Settings->Device Model");

IF(INDEXOF(bulb2topic, "ShellyBulbDuo-deviceid") = 0)
    ADDERROR("Set correct 'bulb2topic' value in module variables. Topic format is 'ShellyBulbDuo-<deviceid>'. The Device ID can be found by opening url 'http://shellyIpAddress', in Settings -> Device info.");
    RETURN(-1);
END

IF INDEXOF(RECEIVEDMSG.TOPIC, "shellies/" + bulb2topic + "/light/0/power") = 0
    Ed := TODOUBLE(TOSTRING(RECEIVEDMSG.PAYLOAD)) / 1000.0;
ELSEIF INDEXOF(RECEIVEDMSG.TOPIC, "shellies/" + bulb2topic + "/light/0/energy") = 0
    To := TODOUBLE(TOSTRING(RECEIVEDMSG.PAYLOAD)) / 60000.0;
END
```

Light 2 White Light Read and write

White-tunable bulb 2 — on/off, brightness 0-100 % and color temperature 3000-6500 K with smooth transitions

json Unit: % / K json\_path

Variable: `transitionTime` — Per-bulb transition time in milliseconds (0-5000 ms) inherited from the TransitionTime import parameter

Listener

```taphome
IF(INDEXOF(bulb2topic, "ShellyBulbDuo-deviceid") = 0)
    ADDERROR("Set correct 'bulb2topic' value in module variables. Topic format is 'ShellyBulbDuo-<deviceid>'. The Device ID can be found by opening url 'http://shellyIpAddress', in Settings -> Device info.");
    RETURN(-1);
END

IF INDEXOF(RECEIVEDMSG.TOPIC, "shellies/" + bulb2topic + "/light/0/status") != 0
    RETURN(0);
END

IF RECEIVEDMSG.PAYLOAD.LENGTH = 0
    RETURN(0);
END

VAR ison := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.ison", 1);
VAR bright := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.brightness");

IF ISNULL(ison) OR ISNULL(bright)
    RETURN(0);
END

Ct := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.temp", 1);

IF ison
    Hb := bright / 100.0;
    St := isOn;
ELSE 
    Hb := 0;
    St := 0;
END
```

Write brightness

```taphome
IF St > 0.5
    VAR topic := "shellies/" + bulb2topic + "/light/0/set";    
    MQTTPUBLISH(topic, "{\"turn\": \"on\", \"transition\": " + transitionTime + ", \"brightness\": " + ROUND(Hb*100.0) + "}");
ELSE
    MQTTPUBLISH("shellies/" + bulb2topic + "/light/0/command", "off");
END
```

Write color temperature

```taphome
IF ISNAN(Ct)
    RETURN(0);
END

VAR topic := "shellies/" + bulb2topic + "/light/0/set";
MQTTPUBLISH(topic, "{\"transition\": " + transitionTime + ", \"temp\":" + Ct + "}");
```

Electric Meter 3 Electricity Meter Read-only

Real-time power (kW) and cumulative energy (kWh) of bulb 3 — requires Settings → Device Model to be set in the Shelly app, otherwise both values stay at 0

numeric Unit: kW / kWh

Listener

```taphome
ADDINFO("To enable power monitoring, open device settings in Shelly app or web browser and configure device model in Settings->Device Model");

IF(INDEXOF(bulb3topic, "ShellyBulbDuo-deviceid") = 0)
    ADDERROR("Set correct 'bulb3topic' value in module variables. Topic format is 'ShellyBulbDuo-<deviceid>'. The Device ID can be found by opening url 'http://shellyIpAddress', in Settings -> Device info.");
    RETURN(-1);
END

IF INDEXOF(RECEIVEDMSG.TOPIC, "shellies/" + bulb3topic + "/light/0/power") = 0
    Ed := TODOUBLE(TOSTRING(RECEIVEDMSG.PAYLOAD)) / 1000.0;
ELSEIF INDEXOF(RECEIVEDMSG.TOPIC, "shellies/" + bulb3topic + "/light/0/energy") = 0
    To := TODOUBLE(TOSTRING(RECEIVEDMSG.PAYLOAD)) / 60000.0;
END
```

Light 3 White Light Read and write

White-tunable bulb 3 — on/off, brightness 0-100 % and color temperature 3000-6500 K with smooth transitions

json Unit: % / K json\_path

Variable: `transitionTime` — Per-bulb transition time in milliseconds (0-5000 ms) inherited from the TransitionTime import parameter

Listener

```taphome
IF(INDEXOF(bulb3topic, "ShellyBulbDuo-deviceid") = 0)
    ADDERROR("Set correct 'bulb3topic' value in module variables. Topic format is 'ShellyBulbDuo-<deviceid>'. The Device ID can be found by opening url 'http://shellyIpAddress', in Settings -> Device info.");
    RETURN(-1);
END

IF INDEXOF(RECEIVEDMSG.TOPIC, "shellies/" + bulb3topic + "/light/0/status") != 0
    RETURN(0);
END

IF RECEIVEDMSG.PAYLOAD.LENGTH = 0
    RETURN(0);
END

VAR ison := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.ison", 1);
VAR bright := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.brightness");

IF ISNULL(ison) OR ISNULL(bright)
    RETURN(0);
END

Ct := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.temp", 1);

IF ison
    Hb := bright / 100.0;
    St := isOn;
ELSE 
    Hb := 0;
    St := 0;
END
```

Write brightness

```taphome
IF St > 0.5
    VAR topic := "shellies/" + bulb3topic + "/light/0/set";    
    MQTTPUBLISH(topic, "{\"turn\": \"on\", \"transition\": " + transitionTime + ", \"brightness\": " + ROUND(Hb*100.0) + "}");
ELSE
    MQTTPUBLISH("shellies/" + bulb3topic + "/light/0/command", "off");
END
```

Write color temperature

```taphome
IF ISNAN(Ct)
    RETURN(0);
END

VAR topic := "shellies/" + bulb3topic + "/light/0/set";
MQTTPUBLISH(topic, "{\"transition\": " + transitionTime + ", \"temp\":" + Ct + "}");
```

Electric Meter 4 Electricity Meter Read-only

Real-time power (kW) and cumulative energy (kWh) of bulb 4 — requires Settings → Device Model to be set in the Shelly app, otherwise both values stay at 0

numeric Unit: kW / kWh

Listener

```taphome
ADDINFO("To enable power monitoring, open device settings in Shelly app or web browser and configure device model in Settings->Device Model");

IF(INDEXOF(bulb4topic, "ShellyBulbDuo-deviceid") = 0)
    ADDERROR("Set correct 'bulb4topic' value in module variables. Topic format is 'ShellyBulbDuo-<deviceid>'. The Device ID can be found by opening url 'http://shellyIpAddress', in Settings -> Device info.");
    RETURN(-1);
END

IF INDEXOF(RECEIVEDMSG.TOPIC, "shellies/" + bulb4topic + "/light/0/power") = 0
    Ed := TODOUBLE(TOSTRING(RECEIVEDMSG.PAYLOAD)) / 1000.0;
ELSEIF INDEXOF(RECEIVEDMSG.TOPIC, "shellies/" + bulb4topic + "/light/0/energy") = 0
    To := TODOUBLE(TOSTRING(RECEIVEDMSG.PAYLOAD)) / 60000.0;
END
```

Light 4 White Light Read and write

White-tunable bulb 4 — on/off, brightness 0-100 % and color temperature 3000-6500 K with smooth transitions

json Unit: % / K json\_path

Variable: `transitionTime` — Per-bulb transition time in milliseconds (0-5000 ms) inherited from the TransitionTime import parameter

Listener

```taphome
IF(INDEXOF(bulb4topic, "ShellyBulbDuo-deviceid") = 0)
    ADDERROR("Set correct 'bulb4topic' value in module variables. Topic format is 'ShellyBulbDuo-<deviceid>'. The Device ID can be found by opening url 'http://shellyIpAddress', in Settings -> Device info.");
    RETURN(-1);
END

IF INDEXOF(RECEIVEDMSG.TOPIC, "shellies/" + bulb4topic + "/light/0/status") != 0
    RETURN(0);
END

IF RECEIVEDMSG.PAYLOAD.LENGTH = 0
    RETURN(0);
END

VAR ison := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.ison", 1);
VAR bright := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.brightness");

IF ISNULL(ison) OR ISNULL(bright)
    RETURN(0);
END

Ct := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.temp", 1);

IF ison
    Hb := bright / 100.0;
    St := isOn;
ELSE 
    Hb := 0;
    St := 0;
END
```

Write brightness

```taphome
IF St > 0.5
    VAR topic := "shellies/" + bulb4topic + "/light/0/set";    
    MQTTPUBLISH(topic, "{\"turn\": \"on\", \"transition\": " + transitionTime + ", \"brightness\": " + ROUND(Hb*100.0) + "}");
ELSE
    MQTTPUBLISH("shellies/" + bulb4topic + "/light/0/command", "off");
END
```

Write color temperature

```taphome
IF ISNAN(Ct)
    RETURN(0);
END

VAR topic := "shellies/" + bulb4topic + "/light/0/set";
MQTTPUBLISH(topic, "{\"transition\": " + transitionTime + ", \"temp\":" + Ct + "}");
```

Electric Meter 5 Electricity Meter Read-only

Real-time power (kW) and cumulative energy (kWh) of bulb 5 — requires Settings → Device Model to be set in the Shelly app, otherwise both values stay at 0

numeric Unit: kW / kWh

Listener

```taphome
ADDINFO("To enable power monitoring, open device settings in Shelly app or web browser and configure device model in Settings->Device Model");

IF(INDEXOF(bulb5topic, "ShellyBulbDuo-deviceid") = 0)
    ADDERROR("Set correct 'bulb5topic' value in module variables. Topic format is 'ShellyBulbDuo-<deviceid>'. The Device ID can be found by opening url 'http://shellyIpAddress', in Settings -> Device info.");
    RETURN(-1);
END

IF INDEXOF(RECEIVEDMSG.TOPIC, "shellies/" + bulb5topic + "/light/0/power") = 0
    Ed := TODOUBLE(TOSTRING(RECEIVEDMSG.PAYLOAD)) / 1000.0;
ELSEIF INDEXOF(RECEIVEDMSG.TOPIC, "shellies/" + bulb5topic + "/light/0/energy") = 0
    To := TODOUBLE(TOSTRING(RECEIVEDMSG.PAYLOAD)) / 60000.0;
END
```

Light 5 White Light Read and write

White-tunable bulb 5 — on/off, brightness 0-100 % and color temperature 3000-6500 K with smooth transitions

json Unit: % / K json\_path

Variable: `transitionTime` — Per-bulb transition time in milliseconds (0-5000 ms) inherited from the TransitionTime import parameter

Listener

```taphome
IF(INDEXOF(bulb5topic, "ShellyBulbDuo-deviceid") = 0)
    ADDERROR("Set correct 'bulb5topic' value in module variables. Topic format is 'ShellyBulbDuo-<deviceid>'. The Device ID can be found by opening url 'http://shellyIpAddress', in Settings -> Device info.");
    RETURN(-1);
END

IF INDEXOF(RECEIVEDMSG.TOPIC, "shellies/" + bulb5topic + "/light/0/status") != 0
    RETURN(0);
END

IF RECEIVEDMSG.PAYLOAD.LENGTH = 0
    RETURN(0);
END

VAR ison := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.ison", 1);
VAR bright := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.brightness");

IF ISNULL(ison) OR ISNULL(bright)
    RETURN(0);
END

Ct := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.temp", 1);

IF ison
    Hb := bright / 100.0;
    St := isOn;
ELSE 
    Hb := 0;
    St := 0;
END
```

Write brightness

```taphome
IF St > 0.5
    VAR topic := "shellies/" + bulb5topic + "/light/0/set";    
    MQTTPUBLISH(topic, "{\"turn\": \"on\", \"transition\": " + transitionTime + ", \"brightness\": " + ROUND(Hb*100.0) + "}");
ELSE
    MQTTPUBLISH("shellies/" + bulb5topic + "/light/0/command", "off");
END
```

Write color temperature

```taphome
IF ISNAN(Ct)
    RETURN(0);
END

VAR topic := "shellies/" + bulb5topic + "/light/0/set";
MQTTPUBLISH(topic, "{\"transition\": " + transitionTime + ", \"temp\":" + Ct + "}");
```

**Connection:** Packet Parser → MQTT • Hostname: `ShellyBulbDuo-{MAC}.local`

Possible improvements (7)

- Connection Status (LWT) — Last Will and Testament — true on connect, false on disconnect. Could detect offline bulbs.
- Full Status JSON — Complete /status as JSON. Could expose wifi\_sta.rssi, has\_update, uptime, source of last command.
- Device Announce — Emitted on boot/announce — payload {id, model, mac, ip, fw\_ver, new\_fw}. Useful for auto-discovery.
- White channel (0-100 %) — Separate 'white' parameter (0-100) on the set JSON; template only writes brightness/temp.
- Timer (auto on/off) — Auto-off timer in seconds via set JSON. Not surfaced as TapHome capability.
- Warm-white below 3000 K — TapHome XML clamps MinColorTemperature to 3000 K; the bulb hardware can go down to 2700 K (GU10). E27 marketed range starts at 3000 K — clamp matches E27 spec but loses 300 K of GU10 range.
- MQTT broker authentication — Shelly device side supports MQTT username/password, but TapHome import parameters do not expose them. Workaround: open broker without auth on a trusted segment.

## Import parameters

Enter these values when you import the XML.

| Asked in the app       | Default       |
|------------------------|---------------|
| Mqtt Broker IP address | `192.168.0.1` |
| Mqtt Broker port       | `1883`        |
| Transition time (ms)   | `300`         |

## Sources

- Shelly Gen1 API Reference
  
  [shelly-api-docs.shelly.cloud](https://shelly-api-docs.shelly.cloud/gen1/) 2026-03-12
- Home Assistant Shelly Integration
  
  [www.home-assistant.io](https://www.home-assistant.io/integrations/shelly/) 2026-03-12
- Shelly DUO — MQTT Bulb API
  
  [shelly-api-docs.shelly.cloud](https://shelly-api-docs.shelly.cloud/gen1/#shelly-duo-mqtt) 2026-04-25
- Shelly DUO — Product Datasheet
  
  [shellystore.co.uk](https://shellystore.co.uk/wp-content/uploads/2021/05/Duo-specs.pdf) 2026-04-25
  
  [PDF](https://taphome.com/compatibility/devices/shelly-duo-mqtt/manufacturer/duo-specs.pdf)

Manufacturer documents are © their respective owners. They are provided as published by the manufacturer, for reference only.

## Related Documentation

- [MQTT Integration](https://taphome.com/en/compatibility/mqtt-guide/)
- [Packet Parser (HTTP, TCP, UDP, FTP, MQTT)](https://taphome.com/en/docs/integration/packet-parser/)
- [Packet parser functions](https://taphome.com/en/docs/script/packet-parser/)
- [Parsing functions](https://taphome.com/en/docs/script/parsing-functions/)
- [MQTT Broker](https://taphome.com/en/docs/integration/packet-parser/mqtt-broker/)
- [Listener scripts](https://taphome.com/en/docs/script/listener-scripts/)

