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
Switch a relay channel on or off.
Functions
@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.
Flatten a list_devices/1 result into one entry per channel —
multi-relay devices (Pro 2/3/4) become several addable rows.
@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.
@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)
@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.