diff --git a/assets/js/app.ts b/assets/js/app.ts index f64be99a..f4ce4eef 100644 --- a/assets/js/app.ts +++ b/assets/js/app.ts @@ -203,6 +203,9 @@ const SensorChart: SensorChartHook = { if (unit === 'bps') { return formatBps(value) } + if (unit === '') { + return Math.round(value) + } return value + unit } }, @@ -233,6 +236,9 @@ const SensorChart: SensorChartHook = { if (unit === 'bps') { return formatBps(value) } + if (unit === '') { + return Math.round(value) + } return value + unit } }, @@ -337,6 +343,9 @@ const SensorChart: SensorChartHook = { if (unit === 'bps') { return context.dataset.label + ': ' + formatBps(context.parsed.y) } + if (unit === '') { + return context.dataset.label + ': ' + Math.round(context.parsed.y) + } return context.dataset.label + ': ' + context.parsed.y.toFixed(1) + unit } } diff --git a/lib/towerops/monitoring/executors/snmp_sensor_executor.ex b/lib/towerops/monitoring/executors/snmp_sensor_executor.ex index e9740976..0e026444 100644 --- a/lib/towerops/monitoring/executors/snmp_sensor_executor.ex +++ b/lib/towerops/monitoring/executors/snmp_sensor_executor.ex @@ -159,6 +159,10 @@ defmodule Towerops.Monitoring.Executors.SnmpSensorExecutor do "#{round(value)}#{unit || " RPM"}" end + defp format_value(value, "count", _unit) do + "#{trunc(value)}" + end + defp format_value(value, sensor_type, unit) do {precision, default_unit} = Map.get(@sensor_formats, sensor_type, {2, ""}) "#{Float.round(value, precision)}#{unit || default_unit}" diff --git a/lib/towerops/snmp/sensor_change_detector.ex b/lib/towerops/snmp/sensor_change_detector.ex index 2749742e..1ec08c9b 100644 --- a/lib/towerops/snmp/sensor_change_detector.ex +++ b/lib/towerops/snmp/sensor_change_detector.ex @@ -283,6 +283,10 @@ defmodule Towerops.Snmp.SensorChangeDetector do end end + defp format_sensor_value(value, "") when is_number(value) do + "#{trunc(value)}" + end + defp format_sensor_value(value, unit) when is_number(value) do "#{Float.round(value / 1.0, 1)}#{unit}" end diff --git a/test/towerops/monitoring/executors/snmp_sensor_executor_test.exs b/test/towerops/monitoring/executors/snmp_sensor_executor_test.exs index bc17aadd..851b91fe 100644 --- a/test/towerops/monitoring/executors/snmp_sensor_executor_test.exs +++ b/test/towerops/monitoring/executors/snmp_sensor_executor_test.exs @@ -212,6 +212,45 @@ defmodule Towerops.Monitoring.Executors.SnmpSensorExecutorTest do assert error_msg =~ "Sensor not found" end + test "formats count sensor output as integer", %{device: device, snmp_device: snmp_device} do + sensor = + %Sensor{} + |> Sensor.changeset(%{ + snmp_device_id: snmp_device.id, + sensor_descr: "Total number of ipv4 connections", + sensor_type: "count", + sensor_index: "mtxrCtIP4Entries.0", + sensor_oid: ".1.3.6.1.4.1.14988.1.1.22.1.2.0", + sensor_unit: "", + sensor_divisor: 1 + }) + |> Repo.insert!() + + {:ok, check} = + Monitoring.create_check(%{ + organization_id: device.organization_id, + device_id: device.id, + name: "IPv4 Connections", + check_type: "snmp_sensor", + source_type: "auto_discovery", + source_id: sensor.id, + config: %{ + "sensor_type" => "count", + "sensor_oid" => ".1.3.6.1.4.1.14988.1.1.22.1.2.0", + "sensor_unit" => "" + } + }) + + expect(SnmpMock, :get, fn _ip, _oid, _opts -> + {:ok, {:integer, 1270}} + end) + + assert {:ok, response} = SnmpSensorExecutor.execute(check) + assert response.value == 1270.0 + assert response.output =~ "1270" + refute response.output =~ "1270.0" + end + test "returns error when SNMP fails", %{device: device, snmp_device: snmp_device} do sensor = %Sensor{} diff --git a/test/towerops/snmp/sensor_change_detector_test.exs b/test/towerops/snmp/sensor_change_detector_test.exs index 151bf2e8..08c2a078 100644 --- a/test/towerops/snmp/sensor_change_detector_test.exs +++ b/test/towerops/snmp/sensor_change_detector_test.exs @@ -276,6 +276,32 @@ defmodule Towerops.Snmp.SensorChangeDetectorTest do assert "sensor_value_changed" in event_types end + test "formats count sensor values as integers in event messages", %{ + device: device, + snmp_device: snmp_device + } do + sensor = + create_sensor(snmp_device, %{ + sensor_type: "count", + sensor_descr: "IPv4 Connections", + sensor_unit: "", + last_value: 1000.0 + }) + + timestamp = DateTime.utc_now() + + Phoenix.PubSub.subscribe(Towerops.PubSub, "device:#{device.id}") + + SensorChangeDetector.detect_and_broadcast(sensor, 1270.0, timestamp) + + assert_receive {:device_event, event} + assert event.event_type == "sensor_value_changed" + assert event.message =~ "1000" + refute event.message =~ "1000.0" + assert event.message =~ "1270" + refute event.message =~ "1270.0" + end + test "broadcasts to both device and global event topics", %{ device: device, snmp_device: snmp_device