Skip to content

Commit

Permalink
ui: update device from onvif page (#570)
Browse files Browse the repository at this point in the history
  • Loading branch information
gBillal authored Feb 6, 2025
1 parent d9f282b commit 91f7e3e
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 13 deletions.
2 changes: 1 addition & 1 deletion ui/lib/ex_nvr/devices.ex
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ defmodule ExNVR.Devices do
def update_state(%Device{} = device, state), do: __MODULE__.update(device, %{state: state})

@spec list() :: [Device.t()]
@spec list(map()) :: [Device.t()]
@spec list(map() | Keyword.t()) :: [Device.t()]
def list(params \\ %{}), do: Repo.all(Device.filter(params) |> order_by([d], d.inserted_at))

@spec ip_cameras() :: [Device.t()]
Expand Down
1 change: 1 addition & 0 deletions ui/lib/ex_nvr/model/device.ex
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ defmodule ExNVR.Model.Device do
{:state, value}, q when is_atom(value) -> where(q, [d], d.state == ^value)
{:state, values}, q when is_list(values) -> where(q, [d], d.state in ^values)
{:type, value}, q -> where(q, [d], d.type == ^value)
{:mac, mac_addr}, q -> where(q, [d], d.mac == ^mac_addr)
_, q -> q
end)
end
Expand Down
3 changes: 2 additions & 1 deletion ui/lib/ex_nvr_web/live/device_live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@ defmodule ExNVRWeb.DeviceLive do

def mount(%{"id" => device_id}, _session, socket) do
device = Devices.get!(device_id)
device_params = get_device_params(socket.assigns.flash) |> Map.delete(:name)

{:ok,
assign(socket,
device: device,
disks_data: get_disks_data(),
device_form: to_form(Devices.change_device_update(device)),
device_form: to_form(Devices.change_device_update(device, device_params)),
device_type: Atom.to_string(device.type),
remote_storages: list_remote_storages()
)}
Expand Down
4 changes: 4 additions & 0 deletions ui/lib/ex_nvr_web/live/onvif/stream_profile.ex
Original file line number Diff line number Diff line change
Expand Up @@ -337,3 +337,7 @@ defmodule ExNVRWeb.Onvif.StreamProfile do
|> Enum.reverse()
end
end

defimpl Phoenix.HTML.Safe, for: Onvif.Media.Ver20.Schemas.Profile.VideoEncoder.Resolution do
def to_iodata(%{width: width, height: height}), do: "#{width}|#{height}"
end
20 changes: 13 additions & 7 deletions ui/lib/ex_nvr_web/live/onvif_discovery_live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ defmodule ExNVRWeb.OnvifDiscoveryLive do
end

defmodule CameraDetails do
defstruct onvif_device: nil, network_interface: nil, media_profiles: []
defstruct onvif_device: nil, network_interface: nil, media_profiles: [], devices: []
end

def mount(_params, _session, socket) do
Expand Down Expand Up @@ -78,7 +78,9 @@ defmodule ExNVRWeb.OnvifDiscoveryLive do
end
end

def handle_event("add-device", _params, socket) do
def handle_event("add-device", params, socket) do
device_id = params["id"] || "new"

selected_device = socket.assigns.selected_device
device_details = socket.assigns.device_details

Expand Down Expand Up @@ -116,7 +118,7 @@ defmodule ExNVRWeb.OnvifDiscoveryLive do
stream_config: stream_config,
credentials: %{username: selected_device.username, password: selected_device.password}
})
|> redirect(to: ~p"/devices/new")
|> redirect(to: ~p"/devices/#{device_id}")
|> then(&{:noreply, &1})
end

Expand Down Expand Up @@ -205,6 +207,7 @@ defmodule ExNVRWeb.OnvifDiscoveryLive do
%CameraDetails{onvif_device: onvif_device}
|> get_network_interface()
|> get_profiles()
|> get_devices()
end

defp get_network_interface(%CameraDetails{} = details) do
Expand All @@ -227,6 +230,13 @@ defmodule ExNVRWeb.OnvifDiscoveryLive do
end
end

defp get_devices(%{network_interface: nil} = details), do: details

defp get_devices(%{network_interface: net_interface} = details) do
mac_addr = net_interface.info.hw_address
%{details | devices: ExNVR.Devices.list(mac: mac_addr)}
end

defp do_reorder_profiles([], _token, _direction), do: []

defp do_reorder_profiles([head | tail], token, direction) do
Expand Down Expand Up @@ -289,7 +299,3 @@ defmodule ExNVRWeb.OnvifDiscoveryLive do
end
end
end

defimpl Phoenix.HTML.Safe, for: Onvif.Media.Ver20.Schemas.Profile.VideoEncoder.Resolution do
def to_iodata(%{width: width, height: height}), do: "#{width}|#{height}"
end
37 changes: 35 additions & 2 deletions ui/lib/ex_nvr_web/live/onvif_discovery_live.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,43 @@
/>
</div>
</div>
<div class="w-full pr-5 pb-5 mb-5">
<.button :if={@selected_device} phx-click="add-device" class="float-right">
<div class="flex flex-row-reverse pr-5">
<.button :if={@selected_device} phx-click="add-device">
Add device
</.button>

<.button
data-dropdown-toggle="update-device-dropdown"
class={
["inline-flex items-center mr-3"] ++
if @selected_device && @device_details.devices != [], do: [], else: ["hidden"]
}
type="button"
>
Update device <.icon name="hero-chevron-down-solid" class="w-4 h-4 ms-3" />
</.button>

<div
id="update-device-dropdown"
class="z-10 hidden bg-white divide-y divide-gray-100 rounded-lg shadow-sm w-44 dark:bg-gray-700"
>
<ul
:if={@selected_device}
class="py-2 text-sm text-gray-700 dark:text-gray-200"
aria-labelledby="dropdownDefaultButton"
>
<li :for={device <- @device_details.devices}>
<a
href="#"
class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white"
phx-click="add-device"
phx-value-id={device.id}
>
{device.name}
</a>
</li>
</ul>
</div>
</div>
</.card>
</div>
33 changes: 31 additions & 2 deletions ui/test/ex_nvr_web/live/onvif_discovery_live_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ defmodule ExNVRWeb.OnvifDiscoveryLiveTest do

use ExNVRWeb.ConnCase

import ExNVR.AccountsFixtures
import ExNVR.{AccountsFixtures, DevicesFixtures}
import Mimic
import Phoenix.LiveViewTest

Expand Down Expand Up @@ -123,7 +123,7 @@ defmodule ExNVRWeb.OnvifDiscoveryLiveTest do
{:ok,
[
%NetworkInterface{
info: %NetworkInterface.Info{name: "eth0"},
info: %NetworkInterface.Info{name: "eth0", hw_address: "aa:bb:cc:00:11:22"},
ipv4: %NetworkInterface.IPv4{
config: %NetworkInterface.IPv4.Config{
manual: %{address: "192.168.1.100"}
Expand Down Expand Up @@ -254,6 +254,8 @@ defmodule ExNVRWeb.OnvifDiscoveryLiveTest do
] do
assert html =~ term
end

assert has_element?(lv, "button.hidden", "Update device")
end

test "render cached device details", %{conn: conn, discover_params: params} do
Expand Down Expand Up @@ -289,5 +291,32 @@ defmodule ExNVRWeb.OnvifDiscoveryLiveTest do
assert device_params.stream_config.snapshot_uri == "http://192.168.1.100:8101/snapshot"
assert device_params.vendor == "Evercam"
end

test "redirect to update device", %{conn: conn, discover_params: params} do
camera_device_fixture("/tmp", %{name: "Camera 1", mac: "aa:bb:cc:00:11:22"})
camera_device_fixture("/tmp", %{name: "Camera 2"})
device = camera_device_fixture("/tmp", %{name: "Camera 3", mac: "aa:bb:cc:00:11:22"})

{:ok, lv, _html} = live(conn, ~p"/onvif-discovery")

lv
|> form("#discover_form", params)
|> render_submit()

html = lv |> element("li[phx-click='device-details']") |> render_click()

assert html =~ "Camera 1"
refute html =~ "Camera 2"
assert html =~ "Camera 3"

refute has_element?(lv, "button.hidden", "Update device")
assert has_element?(lv, "button", "Update device")

assert {:ok, _conn} =
lv
|> element("a", "Camera 3")
|> render_click()
|> follow_redirect(conn, ~p"/devices/#{device.id}")
end
end
end

0 comments on commit 91f7e3e

Please sign in to comment.