NestGen2.Wifi (nest_gen2 v0.6.6)

Copy Markdown View Source

Wi-Fi: status, scanning, joining a network, and saved networks.

The platform runs wpa_supplicant and udhcpc (see platform/wifi) in place of Nest's connection manager; this module talks to wpa_supplicant through its control socket. If they aren't running, status/0 reports :unavailable and the other calls return {:error, :unavailable}.

NestGen2.Wifi.status()
#=> %{state: :connected, ssid: "HomeNet", ip: "192.0.2.7", signal_dbm: -58}

{:ok, networks} = NestGen2.Wifi.scan()
{:ok, %{ip: ip}} = NestGen2.Wifi.connect("Phone hotspot", "correct horse")

connect/2 is safe to try: the new network is only saved once it has an address. On any failure the previous network is selected again, and the saved configuration is left unchanged. Passwords are stored as the derived WPA key, never as entered.

Publishes {:nest_gen2, :wifi, %{state, ssid, ip}} whenever those change.

Summary

Functions

Returns a specification to start this module under a supervisor.

Joins a network. password is nil for an open network, or to use the saved key of a network joined before. Takes up to about a minute; call it from a separate process, not from a GenServer that must stay responsive.

Removes a saved network (not the one in use).

Saves a network without switching to it: the Nest joins it by itself whenever it's in range and no saved network it prefers is (for example a phone hotspot, set up before taking the Nest somewhere new). A saved network with the same SSID is replaced. password nil saves an open network. Like connect/2, only the derived WPA key is stored, never the password.

SSIDs of the saved networks.

Scans for networks (takes a few seconds). Strongest first, one entry per SSID.

Current connection.

Types

network()

@type network() :: %{
  ssid: String.t(),
  signal_dbm: integer(),
  secured: boolean(),
  saved: boolean()
}

status()

@type status() :: %{
  state: :connected | :connecting | :disconnected | :unavailable,
  ssid: String.t() | nil,
  ip: String.t() | nil,
  signal_dbm: integer() | nil
}

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

connect(ssid, password \\ nil)

@spec connect(String.t(), String.t() | nil) ::
  {:ok, %{ssid: String.t(), ip: String.t()}}
  | {:error,
     :wrong_password
     | :not_found
     | :no_ip
     | :timeout
     | :password_required
     | :bad_password_length
     | :busy
     | :unavailable
     | term()}

Joins a network. password is nil for an open network, or to use the saved key of a network joined before. Takes up to about a minute; call it from a separate process, not from a GenServer that must stay responsive.

forget(ssid)

@spec forget(String.t()) :: :ok | {:error, :not_found | :connected | :unavailable}

Removes a saved network (not the one in use).

save(ssid, password \\ nil)

@spec save(String.t(), String.t() | nil) ::
  :ok | {:error, :bad_password_length | :unavailable | term()}

Saves a network without switching to it: the Nest joins it by itself whenever it's in range and no saved network it prefers is (for example a phone hotspot, set up before taking the Nest somewhere new). A saved network with the same SSID is replaced. password nil saves an open network. Like connect/2, only the derived WPA key is stored, never the password.

saved_networks()

@spec saved_networks() :: [String.t()]

SSIDs of the saved networks.

scan()

@spec scan() :: {:ok, [network()]} | {:error, term()}

Scans for networks (takes a few seconds). Strongest first, one entry per SSID.

start_link(_)

status()

@spec status() :: status()

Current connection.