Shelly.Account (Shelly v0.3.0)

Copy Markdown View Source

Account-level Shelly Cloud API, authorized by an OAuth access token (Authorization: Bearer) — no per-device auth keys needed.

Every function takes a Shelly.Client holding a :token, usually straight from Shelly.OAuth.exchange_code/2.

All calls are paced through Shelly.RateGate when it is running (~1 request/second/account is the cloud's limit).

Summary

Functions

Status of every device on the account in ONE call (all_status). Returns {:ok, %{device_id => raw_status}} with lowercase ids; parse per device/channel with Shelly.Status.parse/4.

Flatten a list_devices/1 result into one entry per channel — multi-relay devices (Pro 2/3/4) become several addable rows.

List every device on the account (get_all_lists): id, user-given name, model/type, generation, channel count, room, online state.

Parse one device's all_statuses/1 entry for a channel. Online state comes from _dev_info.online, the cloud's own view, which every device carries — unlike cloud.connected, which only mains-powered Gen2+ hardware reports

Functions

all_statuses(client)

@spec all_statuses(Shelly.Client.t()) ::
  {:ok, %{optional(String.t()) => map()}} | {:error, term()}

Status of every device on the account in ONE call (all_status). Returns {:ok, %{device_id => raw_status}} with lowercase ids; parse per device/channel with Shelly.Status.parse/4.

Keys come from each entry's _dev_info.id, not from the map key Shelly returns them under: the vendor documents those outer keys as inconsistent ("should be ignored", notably for virtual/thermostat devices), and a caller looking a device up by id would silently miss it. The outer key is the fallback when an entry carries no _dev_info.

expand_channels(devices)

@spec expand_channels(map()) :: [map()]

Flatten a list_devices/1 result into one entry per channel — multi-relay devices (Pro 2/3/4) become several addable rows.

list_devices(client)

@spec list_devices(Shelly.Client.t()) :: {:ok, map()} | {:error, term()}

List every device on the account (get_all_lists): id, user-given name, model/type, generation, channel count, room, online state.

Returns {:ok, devices} where devices is the raw map keyed by device id — see expand_channels/1 for a flattened per-channel list.

parse_status(raw_status, channel)

@spec parse_status(map(), non_neg_integer()) :: Shelly.Status.t()

Parse one device's all_statuses/1 entry for a channel. Online state comes from _dev_info.online, the cloud's own view, which every device carries — unlike cloud.connected, which only mains-powered Gen2+ hardware reports:

{:ok, statuses} = Shelly.Account.all_statuses(account)
Shelly.Account.parse_status(statuses["0cdc7ef76644"], 0)

set_switch(client, device_id, channel, on?, opts \\ [])

@spec set_switch(
  Shelly.Client.t(),
  String.t(),
  non_neg_integer(),
  boolean(),
  keyword()
) ::
  :ok | {:error, term()}

Switch a relay channel on or off.

Takes no options — in particular there is no :toggle_after, since the account API has no equivalent of the v2 endpoint's cloud-side watchdog. Passing it returns {:error, :toggle_after_unsupported} rather than switching without the safety net you asked for. For unattended equipment, heating especially, drive control through Shelly.CloudV2.set_switch/5 with an auth key — see "Controlling equipment safely" in Shelly.