defmodule LambentExWeb.DevicesLive.Index do
use LambentExWeb, :live_view
require Logger
@pubsub_name LambentEx.PubSub
use Phoenix.LiveEditableView
alias LambentEx.LiveEdit
@impl true
def mount(_params, _session, socket) do
Phoenix.PubSub.subscribe(@pubsub_name, "scan-82667777")
Phoenix.PubSub.subscribe(@pubsub_name, "scan-manual")
{:ok,
socket
|> assign(:devices, %{})
|> assign(:nonew, true)}
end
@impl true
def handle_params(params, _url, socket) do
{:noreply, apply_action(socket, socket.assigns.live_action, params)}
end
defp re_nil(r) do
case r do
"" -> nil
otherwise -> otherwise
end
end
@impl true
def handle_info({:devices_pub, devices}, socket) do
n = Map.merge(socket.assigns.devices, devices)
{:noreply, socket |> assign(:devices, n)}
end
@impl true
def handle_info({:rename, data}, socket) do
id = data["id"] |> String.trim_trailing("name") |> String.trim_trailing("namem")
name = data["data"] |> re_nil
case socket.assigns[:devices] |> Map.get(id) |> Map.get("type") do
a when a in ["7777-8266", "7777-flex"] ->
LambentEx.Scan.ESP8266x7777.rename(:mac, id, name)
"mqtt-tasmota" ->
xname = socket.assigns[:devices] |> Map.get(id) |> Map.get("dname")
LambentEx.MQTT.rename(xname, id, name)
type ->
Logger.info("Need handler for this type: #{type}")
:ok
end
{:noreply, socket}
end
@impl true
def handle_info({:reorder, data}, socket) do
id = data["id"] |> String.trim_trailing("ord") |> String.trim_trailing("ordm")
tgt = data["ok"]["ord"]
case socket.assigns[:devices] |> Map.get(id) |> Map.get("type") do
"7777-8266" ->
LambentEx.Scan.ESP8266x7777.reorder(:mac, id, tgt)
"7777-flex" ->
LambentEx.Scan.ESP8266x7777.reorder(:mac, id, tgt)
type ->
Logger.info("Need handler for this type: #{type}")
:ok
end
{:noreply, socket}
end
@impl true
def handle_info({:replace, data}, socket) do
id = data["id"] |> String.trim_trailing("place") |> String.trim_trailing("placem")
pl = data["data"] |> re_nil
case socket.assigns[:devices] |> Map.get(id) |> Map.get("type") do
"7777-8266" ->
LambentEx.Scan.ESP8266x7777.replace(:mac, id, pl)
"7777-flex" ->
LambentEx.Scan.ESP8266x7777.replace(:mac, id, pl)
"mqtt-tasmota" ->
xname = socket.assigns[:devices] |> Map.get(id) |> Map.get("dname")
LambentEx.MQTT.replace(xname, id, pl)
type ->
Logger.info("Need handler for this type: #{type}")
:ok
end
{:noreply, socket}
end
@impl true
def handle_info({:manual_result, ip, status}, socket) do
socket =
case status do
{:lambent, sox} ->
put_flash(
socket,
:info,
"Found a #{max(sox, 1)}ch device at #{ip}, waiting on its MAC to show up in ARP."
)
:not_lambent ->
put_flash(socket, :error, "Nothing lambent answered at #{ip}.")
:no_iface ->
put_flash(socket, :error, "#{ip} is not on any of the scanned interfaces.")
end
{:noreply, socket}
end
@impl true
def handle_event("manual", %{"ip" => ip}, socket) do
ip = String.trim(ip)
case IP.from_string(ip) do
{:ok, addr} when tuple_size(addr) == 4 ->
LambentEx.Scan.ESP8266x7777.manual(ip)
{:noreply, socket |> put_flash(:info, "Probing #{ip} ...")}
_otherwise ->
{:noreply, socket |> put_flash(:error, "#{ip} is not a valid IPv4 address.")}
end
end
@impl true
def handle_event("poke", %{"id" => id, "dname" => name}, socket) do
case socket.assigns[:devices] |> Map.get(id) |> Map.get("type") do
a when a in ["7777-8266", "7777-flex"] ->
LambentEx.Scan.ESP8266x7777.poke(id)
"mqtt-tasmota" ->
LambentEx.MQTT.do_poke(name, id)
type ->
Logger.info("Need handler for this type: #{type}")
:ok
end
{:noreply, socket}
end
# the plain poke uses the indicator LED when the device has one, this one
# always lights the strands
@impl true
def handle_event("poke_strands", %{"id" => id}, socket) do
case socket.assigns[:devices] |> Map.get(id) |> Map.get("type") do
a when a in ["7777-8266", "7777-flex"] ->
LambentEx.Scan.ESP8266x7777.poke(id, :strands)
type ->
Logger.info("Need handler for this type: #{type}")
:ok
end
{:noreply, socket}
end
@impl true
def handle_event("poke", %{"id" => id}, socket) do
case socket.assigns[:devices] |> Map.get(id) |> Map.get("type") do
a when a in ["7777-8266", "7777-flex"] ->
LambentEx.Scan.ESP8266x7777.poke(id)
type ->
Logger.info("Need handler for this type: #{type}")
:ok
end
{:noreply, socket}
end
defp apply_action(socket, :index, _params) do
socket
|> assign(:page_link, "Devices")
|> assign(:page_title, "Detected Devices")
|> assign(:source, nil)
end
# where a device is reached. mqtt devices are told apart by the type their
# broker stamps on them, not by a "POWER" key: a multi-channel tasmota only
# reports POWER1, POWER2, ... and used to take the page down
defp pip(map) do
case map do
%{"ip" => ip} when is_tuple(ip) -> ip |> Tuple.to_list() |> Enum.join(".")
%{"ip" => ip} when is_binary(ip) -> ip
%{"type" => "mqtt-" <> _kind, "dname" => broker} -> "MQTT (#{broker})"
%{"type" => "mqtt-" <> _kind} -> "MQTT"
_otherwise -> "?"
end
end
defp options() do
[:rgb, :grb, :rgbww, :rgbnw, :rgbcw, :rgbaw, :rgbxw]
end
end
neiam
/lambent_ex
Lambent Aether 5
public · Issues · Pulls 1 · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
Log in to mark this repository.
5.6 KiB · text
History
9c0fc16