FritzApi

Build StatusDocsHex.pm

Fritz!Box Home Automation API Client for Elixir (documentation).

Usage

iex> {:ok, client} = FritzApi.Client.new()
...> |> FritzApi.Client.login("admin", "changeme")
iex> FritzApi.get_device_list_infos(client)
{:ok, [%FritzApi.Actor{
ain: "687690315761",
fwversion: "03.87",
id: 21,
manufacturer: "AVM",
name: "FRITZ!DECT #1",
powermeter: %{energy: 0.475, power: 0.0},
present: true,
productname: "FRITZ!DECT 200",
switch: %{
devicelock: false,
lock: false,
mode: :manual,
state: false
},
temperature: %{
celsius: 23.5,
offset: 0.0
}
}]}
iex> FritzApi.set_switch_off(client, "687690315761")
:ok
iex> FritzApi.get_temperature(client, "687690315761")
{:ok, 23.5}

Example: Automatic Session Refresh

defmodule Switch do
use GenServer
defmodule State do
@derive {Inspect, except: [:password]}
defstruct [:username, :password, :ain, :client]
end
def start_link(opts) do
GenServer.start_link(__MODULE__, opts)
end
def turn_on, do: GenServer.call(__MODULE__, :turn_on)
def turn_off, do: GenServer.call(__MODULE__, :turn_off)
@impl true
def init(opts) do
client =
FritzApi.Client.new(
base_url: opts[:host],
receive_timeout: :timer.seconds(30)
)
state = %State{
username: Keyword.fetch!(opts, :username),
password: Keyword.fetch!(opts, :password),
ain: Keyword.fetch!(opts, :ain),
client: client
}
{:ok, state, {:continue, :login}}
end
@impl true
def handle_continue(:login, %State{} = state) do
{:ok, client} = FritzApi.Client.login(state.client, state.username, state.password)
{:noreply, %State{state | client: client}}
end
@impl true
def handle_call(:turn_on, _from, %State{} = state) do
{result, state} = refresh_session(&FritzApi.set_switch_on(&1, state.ain), state)
{:reply, result, state}
end
def handle_call(:turn_off, _from, %State{} = state) do
{result, state} = refresh_session(&FritzApi.set_switch_off(&1, state.ain), state)
{:reply, result, state}
end
defp refresh_session(fun, %State{} = state) do
with {:error, %FritzApi.Error{reason: :session_expired}} <- fun.(state.client),
{:ok, client} <- FritzApi.Client.login(state.client, state.username, state.password) do
{fun.(client), %State{state | client: client}}
else
result -> {result, state}
end
end
end
iex> {:ok, pid} = Switch.start_link(username: "admin", password: "admin", ain: "000111222333")
iex> Switch.turn_on(pid)
:ok

Installation

Add fritz_api to your list of dependencies in mix.exs:

def deps do
[
{:fritz_api, "~> 2.1"},
{:hackney, "~> 1.17"}
]
end

By default, fritz_api uses hackney (via Tesla.Adapter.Hackney). Add hackney to the list of dependencies too if you don't want to use another HTTP adapter (see Tesla Adapters to find all available adapters and FritzApi.Client.new/1 on how to configure another adapter).

The docs can be found at hexdocs.pm/fritz_api.

References