# HomeElixir DSL

A complete reference of everything you can declare with `use HomeElixir.DSL`.
For a tutorial-style walkthrough, see the [README](readme.html).

## Entities

```elixir
entity type, "id" do
  ...
end
```

Every entity is defined by three things:

- **`type`** — the entity domain, one of the four supported types below
  (`:input_boolean`, `:input_number`, `:input_select`,
  `:alarm_control_panel`).
- **`id`** — the second argument to `entity/3`. It becomes the entity's
  Home Assistant `entity_id` (e.g. `input_boolean.presence`), the YAML
  file name (`input_boolean/presence.yaml`), and the suffix of the
  generated `get_*`/`set_*` helpers.
- **`name`** — optional, set inside the `do` block. The human-friendly
  display name shown in the Home Assistant UI. It's independent from
  `id`; if omitted, Home Assistant derives a display name from the id.

Everything else inside the `do` block is an optional, type-specific
attribute — listed under each type below. Keyword pairs not listed here
are still passed through as-is, so Home Assistant options not covered by
this guide keep working.

Declaring an entity injects `get_<type>_<id>/0` and
`set_<type>_<id>/...` helper functions into the enclosing module.

### `:input_boolean`

No required keys.

Optional attributes: `name`, `initial` (boolean), `icon` (an mdi icon
string, e.g. `"mdi:lightbulb"`).

```elixir
entity :input_boolean, "presence" do
  name "Presence"
  initial false
end
```

Injects `get_input_boolean_presence/0` and `set_input_boolean_presence/1`.

### `:input_number`

Requires `min` and `max`.

Optional attributes: `name`, `initial`, `step`, `mode` (`:slider` or
`:box`, as accepted by Home Assistant's `input_number`),
`unit_of_measurement`, `icon`.

```elixir
entity :input_number, "temperature_limit" do
  min 10
  max 30
  initial 20
end
```

With every optional attribute set:

```elixir
entity :input_number, "thermostat_offset" do
  min -5
  max 5
  initial 0
  name "Thermostat offset"
  step 0.5
  mode :slider
  unit_of_measurement "°C"
  icon "mdi:thermometer"
end
```

Injects `get_input_number_temperature_limit/0` and
`set_input_number_temperature_limit/1`.

### `:input_select`

Requires `options`.

Optional attributes: `name`, `initial`, `icon`, `editable` (boolean,
whether the options can be edited from the Home Assistant UI).

```elixir
entity :input_select, "cover_mode" do
  options ["open", "close"]
  initial "open"
end
```

With every optional attribute set:

```elixir
entity :input_select, "cover_mode" do
  options ["open", "close"]
  initial "open"
  name "Cover mode"
  icon "mdi:window-shutter"
  editable false
end
```

Injects `get_input_select_cover_mode/0` and
`set_input_select_cover_mode/1`.

### `:alarm_control_panel`

Requires `platform` and `code`.

Optional attributes: `arming_states` (list of alarm states that require
the code to arm), `arming_time`, `delay_time`, `trigger_time` (seconds,
applied to every arm mode unless overridden), and per-mode overrides
`armed_home`, `armed_away`, `armed_night`, `armed_vacation`,
`armed_custom_bypass` — each written as a keyword list, e.g.
`armed_home delay_time: 10` (a literal `%{delay_time: 10}` map also
works; both end up normalized to a map before being written to YAML).

```elixir
entity :alarm_control_panel, "alarm" do
  platform :manual
  code "1234"
end
```

With every optional attribute set:

```elixir
entity :alarm_control_panel, "alarm" do
  platform :manual
  code "1234"
  arming_states [:armed_home, :armed_away]
  arming_time 30
  delay_time 20
  trigger_time 120
  armed_home delay_time: 10
  armed_away delay_time: 30
  armed_night delay_time: 10
  armed_vacation delay_time: 30
  armed_custom_bypass delay_time: 10
end
```

Injects `get_alarm_control_panel_alarm/0` and
`set_alarm_control_panel_alarm_state/2`.

## Automations

```elixir
automation "alias" do
  trigger do
    ...
  end

  condition do
    ...
  end

  action do
    ...
  end
end
```

`condition` is optional. `trigger` and `action` each accept one or more of
the forms below.

### Triggers

#### `state`

Allowed keys: `affected_entities` (required), `to`, `from`.

```elixir
state do
  affected_entities [{:input_boolean, "presence"}]
  to true
end
```

#### `numeric_state`

Allowed keys: `affected_entities` (required), `above`, `below`.

```elixir
numeric_state do
  affected_entities [{:input_number, "temperature_limit"}]
  above 20
end
```

#### `sun`

Allowed keys: `event` (required).

```elixir
sun do
  event :sunrise
end
```

#### `time`

Allowed keys: `at` (required), `weekday`.

```elixir
time do
  at "22:00:00"
end
```

### Conditions

#### `state_condition`

Allowed keys: `affected_entities` (required), `state_value` (required).

```elixir
state_condition do
  affected_entities [{:alarm_control_panel, "alarm"}]
  state_value "armed_home"
end
```

#### `numeric_state_condition`

Allowed keys: `affected_entities` (required), `above`, `below`.

```elixir
numeric_state_condition do
  affected_entities [{:input_number, "temperature_limit"}]
  above 20
end
```

#### `logical_condition`

Combines nested conditions with `:and` or `:or` instead of the default
`:and`.

```elixir
logical_condition :or do
  state_condition do
    affected_entities [{:alarm_control_panel, "alarm"}]
    state_value "armed_home"
  end

  state_condition do
    affected_entities [{:alarm_control_panel, "alarm"}]
    state_value "armed_away"
  end
end
```

### Actions

#### `service`

Generic Home Assistant service call.

Allowed keys: `affected_entities` (required). For `domain: :input_select`,
also requires `option` (or `options`).

```elixir
service :input_boolean, "turn_on" do
  affected_entities [{:input_boolean, "presence"}]
end
```

```elixir
service :input_select, "select_option" do
  affected_entities [{:input_select, "cover_mode"}]
  option "open"
end
```

#### `persistent_notification`

Shows a notification in the Home Assistant UI.

Allowed keys: `message` (required), `title`.

```elixir
persistent_notification "create" do
  message "Hello from HomeElixir"
end
```

## Introspection helpers

Every module using `HomeElixir.DSL` also gets:

- `__home_elixir_entities__/0` — the entities declared in that module.
- `__home_elixir_automations__/0` — the automations declared in that module.
- `restart_home_assistant/0` — calls the Home Assistant restart service.