track more state changes

This commit is contained in:
Graham McIntire 2026-01-29 10:43:23 -06:00
parent e0552ac97d
commit e76bd1fd91
2 changed files with 45 additions and 9 deletions

View file

@ -493,7 +493,10 @@ defmodule Towerops.Workers.DevicePollerWorker do
end
defp handle_state_sensor_poll_result(state_sensor, {:ok, new_state_value}, timestamp, device_id) do
old_state_value = state_sensor.state_value
old_state_descr = state_sensor.state_descr
old_status = state_sensor.status
new_status = entity_state_to_status(new_state_value)
new_descr = entity_state_to_descr(new_state_value)
@ -504,8 +507,19 @@ defmodule Towerops.Workers.DevicePollerWorker do
last_checked_at: timestamp
})
if old_status != new_status do
broadcast_state_sensor_change(state_sensor, old_status, new_status, device_id, timestamp)
# Track any state value change, not just status changes
# This catches changes like "6X (64QAM)" -> "8X (256QAM)" that have the same status
if old_state_value != nil && old_state_value != new_state_value do
state_changes = %{
old_state_value: old_state_value,
new_state_value: new_state_value,
old_state_descr: old_state_descr,
new_state_descr: new_descr,
old_status: old_status,
new_status: new_status
}
broadcast_state_sensor_change(state_sensor, state_changes, device_id, timestamp)
end
end
@ -518,19 +532,36 @@ defmodule Towerops.Workers.DevicePollerWorker do
})
end
defp broadcast_state_sensor_change(state_sensor, old_status, new_status, device_id, timestamp) do
defp broadcast_state_sensor_change(state_sensor, state_changes, device_id, timestamp) do
%{
old_state_value: old_state_value,
new_state_value: new_state_value,
old_state_descr: old_state_descr,
new_state_descr: new_state_descr,
old_status: old_status,
new_status: new_status
} = state_changes
severity = determine_state_change_severity(old_status, new_status)
event_type = determine_state_change_event_type(new_status)
# Format message like: "RX Modulation Rate changed from 6X (64QAM)(6) to 8X (256QAM)(8)"
message =
"#{state_sensor.sensor_descr} changed from #{old_state_descr}(#{old_state_value}) to #{new_state_descr}(#{new_state_value})"
event = %{
device_id: device_id,
event_type: event_type,
severity: severity,
message: "#{state_sensor.sensor_descr} status changed from #{old_status} to #{new_status}",
message: message,
metadata: %{
state_sensor_id: state_sensor.id,
sensor_name: state_sensor.sensor_descr,
entity_type: state_sensor.entity_type,
old_state_value: old_state_value,
new_state_value: new_state_value,
old_state_descr: old_state_descr,
new_state_descr: new_state_descr,
old_status: old_status,
new_status: new_status
},

View file

@ -788,18 +788,23 @@ defmodule ToweropsWeb.DeviceLive.Show do
end
# Sensor type classification helpers
# These check multiple signals (type, unit, description) to correctly categorize sensors
# since some devices (especially Mikrotik) report incorrect unit types
# Trust sensor_type first (set during SNMP discovery based on OID)
# Only fall back to unit/description matching if sensor_type is missing/unknown
defp temperature_sensor?(sensor) do
# Primary: Check sensor_type (set during discovery based on OID)
type_match = sensor.sensor_type in ["temperature", "cpu_temperature", "celsius"]
# Fallback: Check unit for devices that don't set sensor_type correctly
unit_match = sensor.sensor_unit in ["°C", "C", "celsius"]
# Only use description as last resort if type and unit don't match
# and only for unambiguous temperature keywords
descr_match =
sensor.sensor_descr &&
String.contains?(String.downcase(sensor.sensor_descr), ["temperature", "temp"]) &&
!type_match && !unit_match &&
sensor.sensor_descr &&
String.contains?(String.downcase(sensor.sensor_descr), "temperature") &&
!String.contains?(String.downcase(sensor.sensor_descr), "voltage")
# Match by type OR unit, but exclude if description says "voltage"
(type_match || unit_match || descr_match) && !voltage_by_description?(sensor)
end