---
title: "Shelly DUO RGBW MQTT"
description: "Control up to 5 Shelly DUO RGBW bulbs via MQTT — full RGB color, tunable white 3000–6500 K, smooth transitions, and power metering. TapHome integration template."
url: "https://taphome.com/en/compatibility/shelly-duo-rgbw-mqtt/"
language: en
lastmod: 2026-03-30
generator: hugo
ai:
  topics: ["mqtt","lighting","wifi","rgbw","color-temperature","power-metering"]
  questions: ["How to integrate Shelly DUO RGBW with TapHome via MQTT?","What does the Shelly DUO RGBW MQTT TapHome template control?","How to connect multiple Shelly DUO RGBW bulbs via MQTT to TapHome?","How to find the Shelly DUO RGBW MQTT Device ID?","Why does my Shelly DUO RGBW show zero power readings?","How to switch between RGB and white mode on Shelly DUO RGBW via MQTT?"]
---

# Shelly DUO RGBW MQTT

Communication: Packet Parser → MQTT

- [Shelly DUO RGBW Product Page](https://www.shelly.com/en/products/shop/shelly-duo-rgbw-gu10)

> 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 RGBW (model SHCB-1) is a Gen1 Wi-Fi smart LED bulb available in E27 and GU10 form factors. It supports full RGB color and tunable white (CCT 3000–6500 K) with smooth transition effects. This is the **MQTT variant** of the TapHome integration — the template communicates with bulbs through a shared MQTT broker on the local network. An [HTTP variant](https://taphome.com/en/compatibility/shelly-duo-rgbw/) is also available for single-bulb setups.

The template supports up to **5 Shelly DUO RGBW bulbs** per module. Each bulb instance is distinguished by a `bulbNtopic` custom variable pointing to the bulb's MQTT Device ID. Each bulb exposes an RGBW light device and an electric meter — 10 devices total.

## Configuration

### Device ID

Each Shelly DUO RGBW bulb has a unique MQTT Device ID in the format `shellycolorbulb-<DEVICEID>`, where `<DEVICEID>` is derived from the MAC address (e.g., `shellycolorbulb-B929CC`).

The Device ID can be found:

- On the device packaging or label (MAC address)
- In the Shelly web UI: **Settings** → **Device Info**
- Via API: `GET http://<device-ip>/settings` → `mqtt.id` field

### Module variables

After importing the template in TapHome, configure the bulb topic variables:

| Variable | Default | Description |
|----------|---------|-------------|
| `bulb1topic` | `shellycolorbulb-deviceid1` | MQTT Device ID for bulb 1 |
| `bulb2topic` | `shellycolorbulb-deviceid2` | MQTT Device ID for bulb 2 |
| `bulb3topic` | `shellycolorbulb-deviceid3` | MQTT Device ID for bulb 3 |
| `bulb4topic` | `shellycolorbulb-deviceid4` | MQTT Device ID for bulb 4 |
| `bulb5topic` | `shellycolorbulb-deviceid5` | MQTT Device ID for bulb 5 |

Replace the default placeholder with the actual Device ID of each bulb (e.g., `shellycolorbulb-B929CC`). Only configure the slots you actually use — unused slots with the default placeholder will display an error prompting you to set the correct topic.

The module subscribes to `shellies/#` (QoS 0, port 1883) and the listener scripts filter messages by the configured topic prefix for each bulb.

> [!WARNING]
> On Gen1 Shelly devices, enabling MQTT **disables Shelly Cloud**. Both cannot run simultaneously.

## Device capabilities

### Light control

Each bulb is mapped as an HSB Light device in TapHome. The bulb operates in two mutually exclusive modes:

- **Color mode** — full RGB control via red, green, and blue channels (0–255 each) plus gain (0–100%). TapHome converts RGB to HSV internally — hue (0–360°), saturation, and brightness are available as control properties. Setting hue or saturation sends a `color/0/set` JSON payload with `"mode":"color"`.
- **White mode** — tunable white via color temperature (3000–6500 K) and brightness (0–100%). Setting a CCT value in TapHome automatically switches the bulb to white mode by publishing `"mode":"white"` with the temperature and brightness.

All write commands include a configurable transition time (default 300 ms) for smooth fading between states. A debounce mechanism prevents stale reads during transitions — the template ignores incoming MQTT status messages for `transitionTime + 3000 ms` after each write command.

### Power metering

Each bulb instance includes an electric meter that reads two values:

- **Real-time power** — from `shellies/{id}/light/0/power`, reported in watts, converted to kW (payload / 1000)
- **Total consumption** — from `shellies/{id}/light/0/energy`, reported in watt-minutes, converted to kWh (payload / 60 000)

> [!TIP]
> Power monitoring requires the device model to be configured in the Shelly app or web UI under **Settings** > **Device Model**. Without this configuration, power readings remain at zero.

### Additional capabilities

The Shelly DUO RGBW also supports light effects (meteor shower, gradual change, breath, flash, on/off gradual, red/green change), a dedicated white LED channel (0–255) in color mode, MQTT connection status via LWT topic, and a full JSON status report (firmware ≥1.8.0) with Wi-Fi RSSI, uptime, and temperature data. These capabilities can be added in a future template update.

## Troubleshooting

### Bulbs not responding

1. Verify MQTT is enabled in each bulb's web UI (**Internet & Security** > **Advanced — MQTT**)
2. Confirm the broker address and port are correct in both the Shelly device settings and TapHome module configuration
3. Check that each `bulbNtopic` custom variable matches the bulb's Device ID exactly (e.g., `shellycolorbulb-B929CC`)
4. Use an MQTT client (e.g., MQTT Explorer) to subscribe to `shellies/#` and verify each bulb publishes messages

### Colors appear incorrect

1. Verify the bulb is in color mode — RGB colors only work in color mode, not white mode
2. Ensure saturation is greater than zero — a saturation of 0 produces white light regardless of hue
3. Check that gain (brightness in color mode) is not set to zero

### Power readings show zero

1. Confirm the device model is configured in the Shelly app or web UI (**Settings** > **Device Model**)
2. Verify the bulb is turned on — the meter only reads when the bulb draws power

> [!WARNING]
> Gen1 Shelly devices do **not** support MQTT over TLS. Communication between the bulbs and the MQTT broker is unencrypted (plain MQTT, port 1883). Ensure the MQTT broker is on a trusted local network.

## 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 RGBW MQTT Module

Custom Variables

|                                                   |                                                                                                                                                                            |
|---------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `bulb1topic` (string) = shellycolorbulb-deviceid1 | MQTT Device ID of bulb 1, used in the topic shellies/&lt;Device ID&gt;/… — format is 'shellycolorbulb-DEVICEID' (find Device ID in Shelly web UI → Settings → Device Info) |
| `bulb2topic` (string) = shellycolorbulb-deviceid2 | MQTT topic name of bulb 2                                                                                                                                                  |
| `bulb3topic` (string) = shellycolorbulb-deviceid3 | MQTT topic name of bulb 3                                                                                                                                                  |
| `bulb4topic` (string) = shellycolorbulb-deviceid4 | MQTT topic name of bulb 4                                                                                                                                                  |
| `bulb5topic` (string) = shellycolorbulb-deviceid5 | MQTT topic name of bulb 5                                                                                                                                                  |

Electric Meter 1 Electricity Meter Read-only

Power consumption and energy metering for bulb 1 — instantaneous power (kW) and cumulative energy (kWh)

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, "shellycolorbulb-deviceid") = 0)
    ADDERROR("Set correct 'bulb1topic' value in module variables. Topic format is 'shellycolorbulb-<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
```

RGBW Light 1 HSB Light Read and write

HSB light with dual mode — full RGB color with gain, or tunable white (3000–6500 K) with brightness

json JSON (ison, mode, red, green, blue, white, gain, temp, brightness, effect)

Listener

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

VAR now := NOW();
IF now.Ticks < debounceTimestamp
    RETURN(0);
END

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

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

BOOL ison := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.ison", 1);
VAR mode := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.mode", 1);

IF ISNULL(mode)
    RETURN(0);
END

INT bright;

IF mode = "color"
    UINT8 red := PARSEJSON(RECEIVEDMSG.PAYLOADStatus, "$.red");
    UINT8 green := PARSEJSON(RECEIVEDMSG.PAYLOADStatus, "$.green");
    UINT8 blue := PARSEJSON(RECEIVEDMSG.PAYLOADStatus, "$.blue");
    bright := PARSEJSON(RECEIVEDMSG.PAYLOADStatus, "$.gain");
    
    VAR hsvColor := RGBTOHSV(red, green, blue);
    
    Hd := ROUND(hsvColor.Hue);
    Sa := ROUND(hsvColor.Saturation * 100.0) / 100.0;
    Ct := NaN;
ELSE
    Ct := PARSEJSON(RECEIVEDMSG.PAYLOADStatus, "$.temp");
    bright := PARSEJSON(RECEIVEDMSG.PAYLOADStatus, "$.brightness");
END

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

Write brightness

```taphome
VAR now := NOW();
debounceTimestamp := now.Ticks + transitionTime + 3000;

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

Write hue

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

VAR now := NOW();
debounceTimestamp := now.Ticks + transitionTime + 3000;

VAR topic := "shellies/" + bulb1topic + "/color/0/set";
VAR rgbColor := HSVTORGB(Hd, Sa, 1);

VAR data := "{\"mode\": \"color\", \"gain\": " + ROUND(Hb*100.0) + ", \"transition\":" + transitionTime + ",\"red\":" + rgbColor.red + ",\"green\":" + rgbColor.green + ",\"blue\":" + rgbColor.blue + "}";

MQTTPUBLISH(topic, data);
```

Write saturation

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

VAR now := NOW();
debounceTimestamp := now.Ticks + transitionTime + 3000;

VAR topic := "shellies/" + bulb1topic + "/color/0/set";
VAR rgbColor := HSVTORGB(Hd, Sa, 1);

VAR data := "{\"mode\": \"color\", \"gain\": " + ROUND(Hb*100.0) + ", \"transition\":" + transitionTime + ",\"red\":" + rgbColor.red + ",\"green\":" + rgbColor.green + ",\"blue\":" + rgbColor.blue + "}";

MQTTPUBLISH(topic, data);
```

Write color temperature

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

VAR now := NOW();
debounceTimestamp := now.Ticks + transitionTime + 3000;

VAR topic := "shellies/" + bulb1topic + "/color/0/set";

MQTTPUBLISH(topic, "{\"mode\": \"white\", \"brightness\": " + ROUND(Hb*100.0) + ", \"transition\": " + transitionTime + ", \"temp\":" + Ct + "}");
```

Electric Meter 2 Electricity Meter Read-only

Power consumption and energy metering for bulb 2 — instantaneous power (kW) and cumulative energy (kWh)

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, "shellycolorbulb-deviceid") = 0)
    ADDERROR("Set correct 'bulb2topic' value in module variables. Topic format is 'shellycolorbulb-<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
```

RGBW Light 2 HSB Light Read and write

HSB light with dual mode — full RGB color with gain, or tunable white (3000–6500 K) with brightness

json JSON (ison, mode, red, green, blue, white, gain, temp, brightness, effect)

Listener

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

VAR now := NOW();
IF now.Ticks < debounceTimestamp
    RETURN(0);
END

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

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

BOOL ison := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.ison", 1);
VAR mode := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.mode", 1);

IF ISNULL(mode)
    RETURN(0);
END

INT bright;

IF mode = "color"
    UINT8 red := PARSEJSON(RECEIVEDMSG.PAYLOADStatus, "$.red");
    UINT8 green := PARSEJSON(RECEIVEDMSG.PAYLOADStatus, "$.green");
    UINT8 blue := PARSEJSON(RECEIVEDMSG.PAYLOADStatus, "$.blue");
    bright := PARSEJSON(RECEIVEDMSG.PAYLOADStatus, "$.gain");
    
    VAR hsvColor := RGBTOHSV(red, green, blue);
    
    Hd := ROUND(hsvColor.Hue);
    Sa := ROUND(hsvColor.Saturation * 100.0) / 100.0;
    Ct := NaN;
ELSE
    Ct := PARSEJSON(RECEIVEDMSG.PAYLOADStatus, "$.temp");
    bright := PARSEJSON(RECEIVEDMSG.PAYLOADStatus, "$.brightness");
END

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

Write brightness

```taphome
VAR now := NOW();
debounceTimestamp := now.Ticks + transitionTime + 3000;

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

Write hue

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

VAR now := NOW();
debounceTimestamp := now.Ticks + transitionTime + 3000;

VAR topic := "shellies/" + bulb2topic + "/color/0/set";
VAR rgbColor := HSVTORGB(Hd, Sa, 1);

VAR data := "{\"mode\": \"color\", \"gain\": " + ROUND(Hb*100.0) + ", \"transition\":" + transitionTime + ",\"red\":" + rgbColor.red + ",\"green\":" + rgbColor.green + ",\"blue\":" + rgbColor.blue + "}";

MQTTPUBLISH(topic, data);
```

Write saturation

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

VAR now := NOW();
debounceTimestamp := now.Ticks + transitionTime + 3000;

VAR topic := "shellies/" + bulb2topic + "/color/0/set";
VAR rgbColor := HSVTORGB(Hd, Sa, 1);

VAR data := "{\"mode\": \"color\", \"gain\": " + ROUND(Hb*100.0) + ", \"transition\":" + transitionTime + ",\"red\":" + rgbColor.red + ",\"green\":" + rgbColor.green + ",\"blue\":" + rgbColor.blue + "}";

MQTTPUBLISH(topic, data);
```

Write color temperature

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

VAR now := NOW();
debounceTimestamp := now.Ticks + transitionTime + 3000;

VAR topic := "shellies/" + bulb2topic + "/color/0/set";

MQTTPUBLISH(topic, "{\"mode\": \"white\", \"brightness\": " + ROUND(Hb*100.0) + ", \"transition\": " + transitionTime + ", \"temp\":" + Ct + "}");
```

Electric Meter 3 Electricity Meter Read-only

Power consumption and energy metering for bulb 3 — instantaneous power (kW) and cumulative energy (kWh)

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, "shellycolorbulb-deviceid") = 0)
    ADDERROR("Set correct 'bulb3topic' value in module variables. Topic format is 'shellycolorbulb-<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
```

RGBW Light 3 HSB Light Read and write

HSB light with dual mode — full RGB color with gain, or tunable white (3000–6500 K) with brightness

json JSON (ison, mode, red, green, blue, white, gain, temp, brightness, effect)

Listener

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

VAR now := NOW();
IF now.Ticks < debounceTimestamp
    RETURN(0);
END

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

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

BOOL ison := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.ison", 1);
VAR mode := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.mode", 1);

IF ISNULL(mode)
    RETURN(0);
END

INT bright;

IF mode = "color"
    UINT8 red := PARSEJSON(RECEIVEDMSG.PAYLOADStatus, "$.red");
    UINT8 green := PARSEJSON(RECEIVEDMSG.PAYLOADStatus, "$.green");
    UINT8 blue := PARSEJSON(RECEIVEDMSG.PAYLOADStatus, "$.blue");
    bright := PARSEJSON(RECEIVEDMSG.PAYLOADStatus, "$.gain");
    
    VAR hsvColor := RGBTOHSV(red, green, blue);
    
    Hd := ROUND(hsvColor.Hue);
    Sa := ROUND(hsvColor.Saturation * 100.0) / 100.0;
    Ct := NaN;
ELSE
    Ct := PARSEJSON(RECEIVEDMSG.PAYLOADStatus, "$.temp");
    bright := PARSEJSON(RECEIVEDMSG.PAYLOADStatus, "$.brightness");
END

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

Write brightness

```taphome
VAR now := NOW();
debounceTimestamp := now.Ticks + transitionTime + 3000;

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

Write hue

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

VAR now := NOW();
debounceTimestamp := now.Ticks + transitionTime + 3000;

VAR topic := "shellies/" + bulb3topic + "/color/0/set";
VAR rgbColor := HSVTORGB(Hd, Sa, 1);

VAR data := "{\"mode\": \"color\", \"gain\": " + ROUND(Hb*100.0) + ", \"transition\":" + transitionTime + ",\"red\":" + rgbColor.red + ",\"green\":" + rgbColor.green + ",\"blue\":" + rgbColor.blue + "}";

MQTTPUBLISH(topic, data);
```

Write saturation

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

VAR now := NOW();
debounceTimestamp := now.Ticks + transitionTime + 3000;

VAR topic := "shellies/" + bulb3topic + "/color/0/set";
VAR rgbColor := HSVTORGB(Hd, Sa, 1);

VAR data := "{\"mode\": \"color\", \"gain\": " + ROUND(Hb*100.0) + ", \"transition\":" + transitionTime + ",\"red\":" + rgbColor.red + ",\"green\":" + rgbColor.green + ",\"blue\":" + rgbColor.blue + "}";

MQTTPUBLISH(topic, data);
```

Write color temperature

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

VAR now := NOW();
debounceTimestamp := now.Ticks + transitionTime + 3000;

VAR topic := "shellies/" + bulb3topic + "/color/0/set";

MQTTPUBLISH(topic, "{\"mode\": \"white\", \"brightness\": " + ROUND(Hb*100.0) + ", \"transition\": " + transitionTime + ", \"temp\":" + Ct + "}");
```

Electric Meter 4 Electricity Meter Read-only

Power consumption and energy metering for bulb 4 — instantaneous power (kW) and cumulative energy (kWh)

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, "shellycolorbulb-deviceid") = 0)
    ADDERROR("Set correct 'bulb4topic' value in module variables. Topic format is 'shellycolorbulb-<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
```

RGBW Light 4 HSB Light Read and write

HSB light with dual mode — full RGB color with gain, or tunable white (3000–6500 K) with brightness

json JSON (ison, mode, red, green, blue, white, gain, temp, brightness, effect)

Listener

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

VAR now := NOW();
IF now.Ticks < debounceTimestamp
    RETURN(0);
END

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

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

BOOL ison := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.ison", 1);
VAR mode := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.mode", 1);

IF ISNULL(mode)
    RETURN(0);
END

INT bright;

IF mode = "color"
    UINT8 red := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.red");
    UINT8 green := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.green");
    UINT8 blue := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.blue");
    bright := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.gain");
    
    VAR hsvColor := RGBTOHSV(red, green, blue);
    
    Hd := ROUND(hsvColor.Hue);
    Sa := ROUND(hsvColor.Saturation * 100.0) / 100.0;
    Ct := NaN;
ELSE
    Ct := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.temp");
    bright := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.brightness");
END

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

Write brightness

```taphome
VAR now := NOW();
debounceTimestamp := now.Ticks + transitionTime + 3000;

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

Write hue

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

VAR now := NOW();
debounceTimestamp := now.Ticks + transitionTime + 3000;

VAR topic := "shellies/" + bulb4topic + "/color/0/set";
VAR rgbColor := HSVTORGB(Hd, Sa, 1);

VAR data := "{\"mode\": \"color\", \"gain\": " + ROUND(Hb*100.0) + ", \"transition\":" + transitionTime + ",\"red\":" + rgbColor.red + ",\"green\":" + rgbColor.green + ",\"blue\":" + rgbColor.blue + "}";

MQTTPUBLISH(topic, data);
```

Write saturation

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

VAR now := NOW();
debounceTimestamp := now.Ticks + transitionTime + 3000;

VAR topic := "shellies/" + bulb4topic + "/color/0/set";
VAR rgbColor := HSVTORGB(Hd, Sa, 1);

VAR data := "{\"mode\": \"color\", \"gain\": " + ROUND(Hb*100.0) + ", \"transition\":" + transitionTime + ",\"red\":" + rgbColor.red + ",\"green\":" + rgbColor.green + ",\"blue\":" + rgbColor.blue + "}";

MQTTPUBLISH(topic, data);
```

Write color temperature

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

VAR now := NOW();
debounceTimestamp := now.Ticks + transitionTime + 3000;

VAR topic := "shellies/" + bulb4topic + "/color/0/set";

MQTTPUBLISH(topic, "{\"mode\": \"white\", \"brightness\": " + ROUND(Hb*100.0) + ", \"transition\": " + transitionTime + ", \"temp\":" + Ct + "}");
```

Electric Meter 5 Electricity Meter Read-only

Power consumption and energy metering for bulb 5 — instantaneous power (kW) and cumulative energy (kWh)

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, "shellycolorbulb-deviceid") = 0)
    ADDERROR("Set correct 'bulb5topic' value in module variables. Topic format is 'shellycolorbulb-<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
```

RGBW Light 5 HSB Light Read and write

HSB light with dual mode — full RGB color with gain, or tunable white (3000–6500 K) with brightness

json JSON (ison, mode, red, green, blue, white, gain, temp, brightness, effect)

Listener

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

VAR now := NOW();
IF now.Ticks < debounceTimestamp
    RETURN(0);
END

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

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

BOOL ison := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.ison", 1);
VAR mode := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.mode", 1);

IF ISNULL(mode)
    RETURN(0);
END

INT bright;

IF mode = "color"
    UINT8 red := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.red");
    UINT8 green := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.green");
    UINT8 blue := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.blue");
    bright := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.gain");
    
    VAR hsvColor := RGBTOHSV(red, green, blue);

    Hd := ROUND(hsvColor.Hue);
    Sa := ROUND(hsvColor.Saturation * 100.0) / 100.0;
    Ct := NaN;
ELSE
    Ct := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.temp");
    bright := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.brightness");
END

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

Write brightness

```taphome
VAR now := NOW();
debounceTimestamp := now.Ticks + transitionTime + 3000;

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

Write hue

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

VAR now := NOW();
debounceTimestamp := now.Ticks + transitionTime + 3000;

VAR topic := "shellies/" + bulb5topic + "/color/0/set";
VAR rgbColor := HSVTORGB(Hd, Sa, 1);

VAR data := "{\"mode\": \"color\", \"gain\": " + ROUND(Hb*100.0) + ", \"transition\":" + transitionTime + ",\"red\":" + rgbColor.red + ",\"green\":" + rgbColor.green + ",\"blue\":" + rgbColor.blue + "}";

MQTTPUBLISH(topic, data);
```

Write saturation

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

VAR now := NOW();
debounceTimestamp := now.Ticks + transitionTime + 3000;

VAR topic := "shellies/" + bulb5topic + "/color/0/set";
VAR rgbColor := HSVTORGB(Hd, Sa, 1);

VAR data := "{\"mode\": \"color\", \"gain\": " + ROUND(Hb*100.0) + ", \"transition\":" + transitionTime + ",\"red\":" + rgbColor.red + ",\"green\":" + rgbColor.green + ",\"blue\":" + rgbColor.blue + "}";

MQTTPUBLISH(topic, data);
```

Write color temperature

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

VAR now := NOW();
debounceTimestamp := now.Ticks + transitionTime + 3000;

VAR topic := "shellies/" + bulb5topic + "/color/0/set";

MQTTPUBLISH(topic, "{\"mode\": \"white\", \"brightness\": " + ROUND(Hb*100.0) + ", \"transition\": " + transitionTime + ", \"temp\":" + Ct + "}");
```

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

Possible improvements (4)

- Connection Status — LWT topic — true on connect, false on disconnect. Could detect offline bulbs.
- Full Status JSON — Complete /status as JSON (fw ≥1.8.0). Could parse wifi\_sta.rssi, uptime, temperature.
- Light Effects — Effect index 0–6: off, meteors, gradual change, breath, flash, on/off gradual, red/green change. Not exposed in template.
- White Channel (RGBW) — Separate white LED channel (0–255) in color mode. Template uses RGB+gain only, white channel not exposed.

## 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 RGBW — MQTT Color Bulb API
  
  [shelly-api-docs.shelly.cloud](https://shelly-api-docs.shelly.cloud/gen1/#shelly-color-bulb) 2026-03-30

## 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/)

