-
+
+
+
+ <.button
+ class="dark:bg-gray-700"
+ phx-click="handle-ptz"
+ phx-value-action="up"
+ >
+ <.icon name="hero-arrow-up" />
+
+
+
+ <.button
+ class="dark:bg-gray-700"
+ phx-click="handle-ptz"
+ phx-value-action="left"
+ >
+ <.icon name="hero-arrow-left" />
+
+
+
+ <.button
+ class="dark:bg-gray-700"
+ phx-click="handle-ptz"
+ phx-value-action="down"
+ >
+ <.icon name="hero-arrow-down" />
+
+
+
+ <.button
+ class="dark:bg-gray-700"
+ phx-click="handle-ptz"
+ phx-value-action="home"
+ >
+ <.icon name="hero-home" />
+
+
+
+ <.button
+ class="dark:bg-gray-700"
+ phx-click="handle-ptz"
+ phx-value-action="right"
+ >
+ <.icon name="hero-arrow-right" />
+
+
+
+ <.button
+ class="dark:bg-gray-700"
+ phx-click="handle-ptz"
+ phx-value-action="zoom-in"
+ >
+ <.icon name="hero-plus" />
+
+
+
+ <.button
+ class="dark:bg-gray-700"
+ phx-click="handle-ptz"
+ phx-value-action="zoom-out"
+ >
+ <.icon name="hero-minus" />
+
+
+
+ <.button
+ class="dark:bg-gray-700"
+ phx-click={JS.toggle(to: "#presets-sidebar")}
+ >
+ <.icon name="hero-bars-3" />
+
+
+
+
"""
end
@@ -272,6 +304,7 @@ defmodule ExNVRWeb.DashboardLive do
|> assign_runs()
|> assign_timezone()
|> maybe_push_stream_event(nil)
+ |> assign_presets()
{:ok, assign(socket, start_date: nil, custom_duration: false)}
end
@@ -290,6 +323,7 @@ defmodule ExNVRWeb.DashboardLive do
|> assign_runs()
|> assign_timezone()
|> maybe_push_stream_event(socket.assigns.start_date)
+ |> assign_presets()
{:noreply, socket}
end
@@ -352,17 +386,19 @@ defmodule ExNVRWeb.DashboardLive do
def handle_event("handle-ptz", %{"action" => action}, socket) do
case action do
- "presets" ->
- socket
- |> put_flash(:error, "Presets not implemented yet")
- |> then(&{:noreply, &1})
-
"home" -> home(socket)
-
mode -> ptz_action(socket, mode)
+ _ ->
+ socket
+ |> put_flash(:error, "Action not recognized!")
+ |> then(&{:noreply, &1})
end
end
+ def handle_event("goto-preset", %{"token" => token}, socket) do
+ goto_preset(socket, token)
+ end
+
defp assign_devices(socket) do
assign(socket, devices: Devices.list())
end
@@ -431,6 +467,32 @@ defmodule ExNVRWeb.DashboardLive do
assign(socket, footage_form: to_form(params, as: "footage"))
end
+ defp assign_presets(socket, _device \\ nil) do
+ opts = get_onvif_access_info()
+ profile_token = opts[:profile_token]
+ body = %{"ProfileToken" => profile_token}
+
+ case Onvif.call(opts[:url], :get_presets, body, opts) do
+ {:ok, %{GetPresetsResponse: presets}} ->
+ presets =
+ Keyword.values(presets)
+ |> Enum.map(fn preset ->
+ %{
+ name: preset[:Name],
+ token: preset[:token]
+ }
+ end)
+
+ socket
+ |> assign(presets: presets)
+
+ {:error, _SoapResponse} ->
+ socket
+ |> put_flash(:error, "Couldn't load presets!")
+ |> assign(presets: [])
+ end
+ end
+
defp maybe_push_stream_event(socket, datetime) do
cond do
not connected?(socket) ->
@@ -567,15 +629,6 @@ defmodule ExNVRWeb.DashboardLive do
end
end
- defp get_onvif_access_info() do
- opts = [
- username: "admin",
- password: "Permanex1",
- url: "wg6.evercam.io:20974/onvif/ptz_service/",
- profile_token: "Profile_1"
- ]
- end
-
defp home(socket) do
speed = []
opts = get_onvif_access_info()
@@ -629,7 +682,7 @@ defmodule ExNVRWeb.DashboardLive do
case Onvif.call(opts[:url], :stop, body, opts) do
{:ok, _respose} ->
socket
- |> put_flash(:info, "Action succeeded")
+ |> put_flash(:info, "Move: #{mode} succeeded!")
|> then(&{:noreply, &1})
{:error, _SoapResponse} ->
@@ -640,11 +693,46 @@ defmodule ExNVRWeb.DashboardLive do
{:error, _SoapResponse} ->
socket
- |> put_flash(:error, "Couldn't perform the requested action!")
+ |> put_flash(:error, "Couldn't perform the move: #{mode}!")
|> then(&{:noreply, &1})
end
end
+ defp goto_preset(socket, token, speed \\ []) do
+ opts = get_onvif_access_info()
+ profile_token = opts[:profile_token]
+ body = %{"ProfileToken" => profile_token, "PresetToken" => token}
+
+ speed =
+ case pan_tilt_zoom_vector(speed) do
+ nil -> %{}
+ vector -> %{"Speed" => vector}
+ end
+
+ body = Map.merge(body, speed)
+
+ case Onvif.call(opts[:url], :goto_preset, body, opts) do
+ {:ok, _response} ->
+ socket
+ |> put_flash(:info, "Preset changed!")
+ |> then(&{:noreply, &1})
+
+ {:error, _SoapResponse} ->
+ socket
+ |> put_flash(:error, "Couldn't change preset!")
+ |> then(&{:noreply, &1})
+ end
+ end
+
+ defp get_onvif_access_info() do
+ opts = [
+ username: "admin",
+ password: "Permanex1",
+ url: "wg6.evercam.io:20974/onvif/ptz_service/",
+ profile_token: "Profile_1"
+ ]
+ end
+
defp pan_tilt_zoom_vector(vector) do
pan_tilt =
case {vector[:x], vector[:y]} do