towerops/lib/towerops/snmp/wireless_client.ex
Graham McIntie b12d46c716 Add wireless client table discovery and improve subscriber matching
Poll connected client/SM tables from APs via vendor-specific SNMP:
- Cambium ePMP: cambiumAPConnectedSTATable
- Ubiquiti airOS: ubntStaTable
- MikroTik RouterOS: mtxrWlRtabTable

Wireless client MAC matches now take highest priority for
subscriber-to-AP mapping, giving accurate per-radio subscriber counts.
2026-02-16 11:16:52 -06:00

56 lines
1.5 KiB
Elixir

defmodule Towerops.Snmp.WirelessClient do
@moduledoc """
Schema for wireless client associations polled from APs.
Stores the connected subscriber radios (CPEs/SMs) discovered via
vendor-specific SNMP wireless registration/client tables.
"""
use Ecto.Schema
import Ecto.Changeset
@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
schema "wireless_clients" do
field :mac_address, :string
field :ip_address, :string
field :hostname, :string
field :signal_strength, :integer
field :snr, :integer
field :distance, :integer
field :tx_rate, :integer
field :rx_rate, :integer
field :uptime_seconds, :integer
field :last_seen_at, :utc_datetime
field :metadata, :map, default: %{}
belongs_to :device, Towerops.Devices.Device
belongs_to :organization, Towerops.Organizations.Organization
timestamps(type: :utc_datetime)
end
@doc false
def changeset(wireless_client, attrs) do
wireless_client
|> cast(attrs, [
:device_id,
:organization_id,
:mac_address,
:ip_address,
:hostname,
:signal_strength,
:snr,
:distance,
:tx_rate,
:rx_rate,
:uptime_seconds,
:last_seen_at,
:metadata
])
|> validate_required([:device_id, :organization_id, :mac_address, :last_seen_at])
|> foreign_key_constraint(:device_id)
|> foreign_key_constraint(:organization_id)
|> unique_constraint([:device_id, :mac_address])
end
end