> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hyperwisor.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Switch

> A latching on/off control that sends a command on each toggle — settings, triggers, and firmware.

<Info>
  **Category:** Controls · **Sends commands:** yes · **Reads data:** no
</Info>

## Mental model

A **Switch is a light switch.** It *holds* a state — on or off — and sends a
command each time you flip it. Unlike a [Button](/dashboard/widgets/button) (a
one-shot), a Switch represents a persistent state your device should be in.

## When to use it

* Turn something on and keep it on (a relay, a fan, a mode)
* Any binary state the user sets and the device holds

## Settings

### General

* **Widget Title / ID**
* **Initial state** — ON or OFF at load
* **ON text / OFF text** · **ON label / OFF label** — the state text and labels
* **Show text labels** · **show icon** · **icon size**

### Style

Status color, label color, container shape (pill / rounded / square), plus the
common border/font/background controls.

### Triggers

A Switch usually needs **two triggers** — one for on, one for off. Events:

| Event      | Fires when                                                |
| ---------- | --------------------------------------------------------- |
| `on`       | Toggled on                                                |
| `off`      | Toggled off                                               |
| `toggle`   | Either direction (carries the new boolean)                |
| `change`   | State changed                                             |
| `click`    | Pressed                                                   |
| *(common)* | `load`, `ready`, `destroy`, `update`, `visible`, `hidden` |

## Example — toggle a relay

**Triggers:**

```
Trigger 1:  WHEN on  → Current Device → Operate → ON   { "relay": 1 }
Trigger 2:  WHEN off → Current Device → Operate → OFF  { "relay": 1 }
```

**Firmware** (Arduino):

```cpp theme={null}
device.setUserCommandHandler([](JsonObject &msg) {
  if (!device.findAction(msg, "Operate", "ON").isNull())  digitalWrite(RELAY, HIGH);
  if (!device.findAction(msg, "Operate", "OFF").isNull()) digitalWrite(RELAY, LOW);
});
```

## Reflecting real device state

To make the Switch show the device's *actual* state (not just what the user tapped),
push the state back from firmware to the Switch's widget ID:

```cpp theme={null}
device.updateWidget(targetId, "relaySwitch", String(isOn ? "on" : "off"));
```

## Script API example

The same interactions from a [dashboard script](/script/overview):

```js theme={null}
widget.on('relaySwitch', 'toggle', (isOn) => {
  widget.setText('stateLabel', isOn ? 'ON' : 'OFF');
  ws.send(context.deviceId, { relay: isOn ? 1 : 0 });
});
```

<CardGroup cols={2}>
  <Card title="Triggers in full" icon="bolt" href="/dashboard/triggers">
    Wiring the on/off commands.
  </Card>

  <Card title="Button" icon="hand-pointer" href="/dashboard/widgets/button">
    For one-shot actions instead of state.
  </Card>
</CardGroup>
