fix: use agent-collected data for live polling when agent assigned
Modified GraphLive live polling to check for agent assignments and use agent-collected sensor data from the database instead of doing direct SNMP polling. This respects the agent assignment and prevents Phoenix from bypassing the agent for live graph updates. Also refactored handle_params to reduce nesting depth.
This commit is contained in:
parent
dd8c97a45f
commit
e0592dbf3d
1 changed files with 84 additions and 35 deletions
|
|
@ -2,6 +2,7 @@ defmodule ToweropsWeb.GraphLive.Show do
|
|||
@moduledoc false
|
||||
use ToweropsWeb, :live_view
|
||||
|
||||
alias Towerops.Agents
|
||||
alias Towerops.Devices
|
||||
alias Towerops.Monitoring
|
||||
alias Towerops.Snmp
|
||||
|
|
@ -18,46 +19,64 @@ defmodule ToweropsWeb.GraphLive.Show do
|
|||
def handle_params(%{"id" => device_id, "sensor_type" => sensor_type} = params, _, socket) do
|
||||
organization = socket.assigns.current_scope.organization
|
||||
|
||||
# Verify device exists and user has access
|
||||
case Devices.get_device(device_id) do
|
||||
nil ->
|
||||
with {:ok, device} <- find_device(device_id),
|
||||
:ok <- verify_device_access(device, organization) do
|
||||
socket = initialize_graph_view(socket, device_id, sensor_type, params)
|
||||
{:noreply, socket}
|
||||
else
|
||||
{:error, :not_found} ->
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:error, "Device not found")
|
||||
|> push_navigate(to: ~p"/devices")}
|
||||
|
||||
device ->
|
||||
# Check if device belongs to current organization
|
||||
if device.organization_id == organization.id do
|
||||
maybe_subscribe_to_device(socket, device_id)
|
||||
|
||||
range = Map.get(params, "range", "24h")
|
||||
interface_id = Map.get(params, "interface_id")
|
||||
sensor_id = Map.get(params, "sensor_id")
|
||||
storage_id = Map.get(params, "storage_id")
|
||||
|
||||
socket =
|
||||
socket
|
||||
|> assign(:device_id, device_id)
|
||||
|> assign(:sensor_type, sensor_type)
|
||||
|> assign(:range, range)
|
||||
|> assign(:interface_id, interface_id)
|
||||
|> assign(:sensor_id, sensor_id)
|
||||
|> assign(:storage_id, storage_id)
|
||||
|> assign(:is_live_mode, range == "live")
|
||||
|> maybe_start_live_polling()
|
||||
|> load_graph_data()
|
||||
|
||||
{:noreply, socket}
|
||||
else
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:error, "You don't have access to this device")
|
||||
|> push_navigate(to: ~p"/devices")}
|
||||
end
|
||||
{:error, :access_denied} ->
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:error, "You don't have access to this device")
|
||||
|> push_navigate(to: ~p"/devices")}
|
||||
end
|
||||
end
|
||||
|
||||
defp find_device(device_id) do
|
||||
case Devices.get_device(device_id) do
|
||||
nil -> {:error, :not_found}
|
||||
device -> {:ok, device}
|
||||
end
|
||||
end
|
||||
|
||||
defp verify_device_access(device, organization) do
|
||||
if device.organization_id == organization.id do
|
||||
:ok
|
||||
else
|
||||
{:error, :access_denied}
|
||||
end
|
||||
end
|
||||
|
||||
defp initialize_graph_view(socket, device_id, sensor_type, params) do
|
||||
maybe_subscribe_to_device(socket, device_id)
|
||||
|
||||
range = Map.get(params, "range", "24h")
|
||||
interface_id = Map.get(params, "interface_id")
|
||||
sensor_id = Map.get(params, "sensor_id")
|
||||
storage_id = Map.get(params, "storage_id")
|
||||
|
||||
# Check if device has agent assignment
|
||||
has_agent = Agents.get_device_assignment(device_id) != nil
|
||||
|
||||
socket
|
||||
|> assign(:device_id, device_id)
|
||||
|> assign(:sensor_type, sensor_type)
|
||||
|> assign(:range, range)
|
||||
|> assign(:interface_id, interface_id)
|
||||
|> assign(:sensor_id, sensor_id)
|
||||
|> assign(:storage_id, storage_id)
|
||||
|> assign(:is_live_mode, range == "live")
|
||||
|> assign(:has_agent_assignment, has_agent)
|
||||
|> maybe_start_live_polling()
|
||||
|> load_graph_data()
|
||||
end
|
||||
|
||||
defp maybe_subscribe_to_device(socket, device_id) do
|
||||
_ =
|
||||
if connected?(socket) do
|
||||
|
|
@ -644,12 +663,19 @@ defmodule ToweropsWeb.GraphLive.Show do
|
|||
|
||||
# Poll sensors and update buffer
|
||||
defp poll_and_update_buffer(socket, device) do
|
||||
client_opts = build_snmp_client_opts(device)
|
||||
now = DateTime.utc_now()
|
||||
timestamp_ms = DateTime.to_unix(now, :millisecond)
|
||||
|
||||
# Poll sensors based on graph type
|
||||
new_points = poll_sensors_for_live_mode(socket.assigns, client_opts, timestamp_ms)
|
||||
# Check if device has agent assignment
|
||||
new_points =
|
||||
if socket.assigns.has_agent_assignment do
|
||||
# Use agent-collected data from database
|
||||
fetch_latest_agent_data(socket.assigns, timestamp_ms)
|
||||
else
|
||||
# Do direct SNMP polling
|
||||
client_opts = build_snmp_client_opts(device)
|
||||
poll_sensors_for_live_mode(socket.assigns, client_opts, timestamp_ms)
|
||||
end
|
||||
|
||||
# Update buffer with new points (rolling window)
|
||||
{updated_buffer, point_count} =
|
||||
|
|
@ -669,6 +695,29 @@ defmodule ToweropsWeb.GraphLive.Show do
|
|||
})
|
||||
end
|
||||
|
||||
# Fetch latest sensor data collected by agent
|
||||
defp fetch_latest_agent_data(assigns, timestamp_ms) do
|
||||
sensors = get_sensors_for_live_mode(assigns)
|
||||
|
||||
sensors
|
||||
|> Enum.map(fn sensor ->
|
||||
# Get the most recent sensor reading from the database
|
||||
case Snmp.get_latest_sensor_reading(sensor.id) do
|
||||
nil ->
|
||||
nil
|
||||
|
||||
reading ->
|
||||
%{
|
||||
sensor_id: sensor.id,
|
||||
label: sensor.sensor_descr,
|
||||
value: Float.round(reading.value || 0.0, 1),
|
||||
timestamp: timestamp_ms
|
||||
}
|
||||
end
|
||||
end)
|
||||
|> Enum.reject(&is_nil/1)
|
||||
end
|
||||
|
||||
# Build SNMP client options
|
||||
defp build_snmp_client_opts(device) do
|
||||
snmp_config = Devices.get_snmp_config(device)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue