extract sensor change detection from DevicePollerWorker into shared SensorChangeDetector module. add sensor_value_changed event for non-% sensors when value differs from last_value. agent channel now detects changes and updates last_value, matching phoenix poller behavior.
66 lines
1.9 KiB
Elixir
66 lines
1.9 KiB
Elixir
defmodule Towerops.Devices.Event do
|
|
@moduledoc """
|
|
Device event schema for tracking changes and incidents.
|
|
"""
|
|
use Ecto.Schema
|
|
|
|
import Ecto.Changeset
|
|
|
|
@type severity :: :info | :warning | :critical
|
|
|
|
@type event_type ::
|
|
:interface_up
|
|
| :interface_down
|
|
| :interface_speed_change
|
|
| :interface_mtu_change
|
|
| :interface_mac_change
|
|
| :interface_admin_status_change
|
|
| :device_discovered
|
|
| :device_rediscovered
|
|
| :sensor_threshold_warning
|
|
| :sensor_threshold_critical
|
|
| :sensor_threshold_normal
|
|
| :sensor_value_spike
|
|
| :sensor_value_drop
|
|
| :sensor_value_changed
|
|
|
|
@primary_key {:id, :binary_id, autogenerate: true}
|
|
@foreign_key_type :binary_id
|
|
|
|
schema "device_events" do
|
|
field :event_type, :string
|
|
field :severity, :string
|
|
field :message, :string
|
|
field :metadata, :map, default: %{}
|
|
field :occurred_at, :utc_datetime
|
|
|
|
belongs_to :device, Towerops.Devices.Device
|
|
|
|
timestamps(type: :utc_datetime, updated_at: false)
|
|
end
|
|
|
|
@doc false
|
|
def changeset(event, attrs) do
|
|
event
|
|
|> cast(attrs, [:device_id, :event_type, :severity, :message, :metadata, :occurred_at])
|
|
|> validate_required([:device_id, :event_type, :severity, :message, :occurred_at])
|
|
|> validate_inclusion(:event_type, [
|
|
"interface_up",
|
|
"interface_down",
|
|
"interface_speed_change",
|
|
"interface_mtu_change",
|
|
"interface_mac_change",
|
|
"interface_admin_status_change",
|
|
"device_discovered",
|
|
"device_rediscovered",
|
|
"sensor_threshold_warning",
|
|
"sensor_threshold_critical",
|
|
"sensor_threshold_normal",
|
|
"sensor_value_spike",
|
|
"sensor_value_drop",
|
|
"sensor_value_changed"
|
|
])
|
|
|> validate_inclusion(:severity, ["info", "warning", "critical"])
|
|
|> foreign_key_constraint(:device_id)
|
|
end
|
|
end
|