towerops/priv/profiles/os_discovery/routeros.yaml
Graham McIntire c545672efe fix(snmp): auto-rescale implausible temperature readings
Some MikroTik models report `mtxrGaugeValue` (mtxrGaugeUnit=1, °C) in
deci-degrees, while others — like the CRS317 in upstream test data —
return whole degrees. The MIB doesn't disclose which, so the YAML
profile can't pick one literal divisor. Result: a sensor that should
read 56.92 °C was being stored and alerted on as 5,692 °C.

- Towerops.Snmp.SensorScale.normalize/2: divide-by-10 a temperature
  reading until it falls below 150 °C, capped at 3 iterations. Other
  sensor types pass through untouched.
- DevicePollerWorker.poll_simple_sensor wires the normaliser in after
  the YAML divisor is applied, so live polling stops storing bogus
  values immediately.
- DeviceOverheating rule now bounds the query at 150 °C as defense in
  depth so a future scaling glitch never produces a 5,000 °C alert.
- mix towerops.fix_mikrotik_temperature_scaling backfills any rows
  already in the DB by re-running normalize/2 over them.
- routeros.yaml profile gets a comment pointing at the runtime
  normaliser instead of a wrong unconditional divisor.
2026-05-10 12:21:24 -05:00

269 lines
13 KiB
YAML

modules:
os:
sysDescr_regex: '/RouterOS (?<hardware>.*)/'
features: MIKROTIK-MIB::mtxrLicLevel.0
features_template: 'Level {{ MIKROTIK-MIB::mtxrLicLevel.0 }}'
serial: MIKROTIK-MIB::mtxrSerialNumber.0
version: MIKROTIK-MIB::mtxrLicVersion.0
sensors:
additional_oids:
data:
-
oid:
- MIKROTIK-MIB::mtxrInterfaceStatsName
temperature:
data:
-
oid: MIKROTIK-MIB::mtxrOpticalTable
value: MIKROTIK-MIB::mtxrOpticalTemperature
num_oid: '.1.3.6.1.4.1.14988.1.1.19.1.1.6.{{ $index }}'
descr: MIKROTIK-MIB::mtxrOpticalName
entPhysicalIndex: '{{ $index }}'
entPhysicalIndex_measured: 'ports'
group: transceiver
index: 'mtxrOpticalTemperature.{{ $index }}'
-
oid: MIKROTIK-MIB::mtxrGaugeTable
value: MIKROTIK-MIB::mtxrGaugeValue
num_oid: '.1.3.6.1.4.1.14988.1.1.3.100.1.3.{{ $index }}'
descr: MIKROTIK-MIB::mtxrGaugeName
group: System
# mtxrGaugeValue (mtxrGaugeUnit=1) reports °C, but the
# raw scale varies by model — CRS317 returns whole
# degrees (36), some RB-series devices return
# deci-degrees (569). The poller normalises any
# implausibly large temperature reading at write time
# (see Towerops.Snmp.SensorScale) so we leave divisor
# at the literal protocol value here.
index: 'mtxrGaugeTemperature.{{ $index }}'
skip_values:
- oid: MIKROTIK-MIB::mtxrGaugeUnit
op: '!='
value: 1
voltage:
data:
-
oid: MIKROTIK-MIB::mtxrOpticalTable
value: MIKROTIK-MIB::mtxrOpticalSupplyVoltage
num_oid: '.1.3.6.1.4.1.14988.1.1.19.1.1.7.{{ $index }}'
divisor: 1000
descr: MIKROTIK-MIB::mtxrOpticalName
entPhysicalIndex: '{{ $index }}'
entPhysicalIndex_measured: 'ports'
group: transceiver
index: 'mtxrOpticalSupplyVoltage.{{ $index }}'
-
oid: MIKROTIK-MIB::mtxrPOETable
value: MIKROTIK-MIB::mtxrPOEVoltage
num_oid: '.1.3.6.1.4.1.14988.1.1.15.1.1.4.{{ $index }}'
divisor: 10
descr: '{{ MIKROTIK-MIB::mtxrPOEName }} POE'
group: Ports
index: 'mtxrPOEVoltage.{{ $index }}'
-
oid: MIKROTIK-MIB::mtxrGaugeTable
value: MIKROTIK-MIB::mtxrGaugeValue
num_oid: '.1.3.6.1.4.1.14988.1.1.3.100.1.3.{{ $index }}'
descr: MIKROTIK-MIB::mtxrGaugeName
group: System
divisor: 10
index: 'mtxrGaugeVoltage.{{ $index }}'
skip_values:
- oid: MIKROTIK-MIB::mtxrGaugeUnit
op: '!='
value: 3
-
oid: MIKROTIK-MIB::mtxrHlVoltage
num_oid: '.1.3.6.1.4.1.14988.1.1.3.8.{{ $index }}'
divisor: 10
descr: 'Voltage {{ $index }}'
current:
data:
-
oid: MIKROTIK-MIB::mtxrOpticalTable
value: MIKROTIK-MIB::mtxrOpticalTxBiasCurrent
num_oid: '.1.3.6.1.4.1.14988.1.1.19.1.1.8.{{ $index }}'
descr: '{{ MIKROTIK-MIB::mtxrOpticalName }} Tx Bias'
entPhysicalIndex: '{{ $index }}'
entPhysicalIndex_measured: 'ports'
group: transceiver
divisor: 1000
index: 'mtxrOpticalTxBiasCurrent.{{ $index }}'
-
oid: MIKROTIK-MIB::mtxrPOETable
value: MIKROTIK-MIB::mtxrPOECurrent
num_oid: '.1.3.6.1.4.1.14988.1.1.15.1.1.5.{{ $index }}'
descr: '{{ MIKROTIK-MIB::mtxrPOEName }} POE'
group: Ports
divisor: 1000
index: 'mtxrPOECurrent.{{ $index }}'
-
oid: MIKROTIK-MIB::mtxrGaugeTable
value: MIKROTIK-MIB::mtxrGaugeValue
num_oid: '.1.3.6.1.4.1.14988.1.1.3.100.1.3.{{ $index }}'
descr: MIKROTIK-MIB::mtxrGaugeName
group: System
divisor: 10
index: 'mtxrGaugeCurrent.{{ $index }}'
skip_values:
- oid: MIKROTIK-MIB::mtxrGaugeUnit
op: '!='
value: 4
dbm:
data:
-
oid: MIKROTIK-MIB::mtxrOpticalTable
value: MIKROTIK-MIB::mtxrOpticalTxPower
num_oid: '.1.3.6.1.4.1.14988.1.1.19.1.1.9.{{ $index }}'
descr: '{{ MIKROTIK-MIB::mtxrOpticalName }} Tx'
entPhysicalIndex: '{{ $index }}'
entPhysicalIndex_measured: 'ports'
group: transceiver
divisor: 1000
index: 'mtxrOpticalTxPower.{{ $index }}'
-
oid: MIKROTIK-MIB::mtxrOpticalTable
value: MIKROTIK-MIB::mtxrOpticalRxPower
num_oid: '.1.3.6.1.4.1.14988.1.1.19.1.1.10.{{ $index }}'
descr: '{{ MIKROTIK-MIB::mtxrOpticalName }} Rx'
entPhysicalIndex: '{{ $index }}'
entPhysicalIndex_measured: 'ports'
group: transceiver
divisor: 1000
index: 'mtxrOpticalRxPower.{{ $index }}'
state:
data:
-
oid: MIKROTIK-MIB::mtxrOpticalTable
value: MIKROTIK-MIB::mtxrOpticalRxLoss
num_oid: '.1.3.6.1.4.1.14988.1.1.19.1.1.3.{{ $index }}'
descr: '{{ MIKROTIK-MIB::mtxrOpticalName }} Rx'
group: Ports
index: 'mtxrOpticalRxLoss.{{ $index }}'
state_name: mtxrOpticalRxLoss
states:
- { descr: no, graph: 1, value: 0, generic: 0 }
- { descr: yes, graph: 1, value: 1, generic: 2 }
- { descr: 'null', graph: 1, value: 2, generic: 3 }
-
oid: MIKROTIK-MIB::mtxrOpticalTable
value: MIKROTIK-MIB::mtxrOpticalTxFault
num_oid: '.1.3.6.1.4.1.14988.1.1.19.1.1.4.{{ $index }}'
descr: '{{ MIKROTIK-MIB::mtxrOpticalName }} Tx'
group: Ports
index: 'mtxrOpticalTxFault.{{ $index }}'
state_name: mtxrOpticalTxFault
states:
- { descr: no, graph: 1, value: 0, generic: 0 }
- { descr: yes, graph: 1, value: 1, generic: 2 }
- { descr: 'null', graph: 1, value: 2, generic: 3 }
-
oid: MIKROTIK-MIB::mtxrPOETable
value: MIKROTIK-MIB::mtxrPOEStatus
num_oid: '.1.3.6.1.4.1.14988.1.1.15.1.1.3.{{ $index }}'
descr: '{{ MIKROTIK-MIB::mtxrPOEName }} POE'
group: Ports
index: 'mtxrPOEStatus.{{ $index }}'
state_name: mtxrPOEStatus
states:
- { descr: 'disabled', graph: 1, value: 1, generic: 3 }
- { descr: 'waitingForLoad', graph: 1, value: 2, generic: 3 }
- { descr: 'poweredOn', graph: 1, value: 3, generic: 0 }
- { descr: 'overload', graph: 1, value: 4, generic: 2 }
-
oid: MIKROTIK-MIB::mtxrGaugeTable
value: MIKROTIK-MIB::mtxrGaugeValue
num_oid: '.1.3.6.1.4.1.14988.1.1.3.100.1.3.{{ $index }}'
descr: MIKROTIK-MIB::mtxrGaugeName
group: System
state_name: mtxrGaugeStatus
skip_values:
- oid: MIKROTIK-MIB::mtxrGaugeUnit
op: '!='
value: 6
states:
- { value: 0, generic: 0, graph: 1, descr: 'ok' }
- { value: 1, generic: 2, graph: 1, descr: 'fail' }
-
oid: MIKROTIK-MIB::mtxrWl60GConnected
num_oid: '.1.3.6.1.4.1.14988.1.1.1.8.1.4.{{ $index }}'
descr: Station Connected
group: Wireless
index: 'mtxrWl60GConnected.{{ $index }}'
state_name: mtxrWl60GConnected
states:
- { value: 0, generic: 2, graph: 1, descr: 'disconnected' }
- { value: 1, generic: 0, graph: 1, descr: 'connected' }
-
oid: MIKROTIK-MIB::mtxrWl60GMode
num_oid: '.1.3.6.1.4.1.14988.1.1.1.8.1.2.{{ $index }}'
descr: Mode
group: Wireless
index: 'mtxrWl60GMode.{{ $index }}'
state_name: mtxrWl60GMode
states:
- { value: 0, generic: 0, graph: 1, descr: 'AP Bridge' }
- { value: 1, generic: 0, graph: 1, descr: 'Station Bridge' }
- { value: 2, generic: 0, graph: 1, descr: 'Sniff' }
- { value: 3, generic: 0, graph: 1, descr: 'Bridge' }
power:
data:
-
oid: MIKROTIK-MIB::mtxrPOETable
value: MIKROTIK-MIB::mtxrPOEPower
num_oid: '.1.3.6.1.4.1.14988.1.1.15.1.1.6.{{ $index }}'
descr: '{{ MIKROTIK-MIB::mtxrPOEName }} POE'
group: Ports
divisor: 10
index: 'mtxrPOEPower.{{ $index }}'
-
oid: MIKROTIK-MIB::mtxrGaugeTable
value: MIKROTIK-MIB::mtxrGaugeValue
num_oid: '.1.3.6.1.4.1.14988.1.1.3.100.1.3.{{ $index }}'
descr: MIKROTIK-MIB::mtxrGaugeName
group: System
divisor: 10
index: 'mtxrGaugePower.{{ $index }}'
skip_values:
- oid: MIKROTIK-MIB::mtxrGaugeUnit
op: '!='
value: 5
fanspeed:
data:
-
oid: MIKROTIK-MIB::mtxrGaugeTable
value: MIKROTIK-MIB::mtxrGaugeValue
num_oid: '.1.3.6.1.4.1.14988.1.1.3.100.1.3.{{ $index }}'
descr: MIKROTIK-MIB::mtxrGaugeName
group: System
index: 'mtxrGuageFanspeed.{{ $index }}'
skip_values:
- oid: MIKROTIK-MIB::mtxrGaugeUnit
op: '!='
value: 2
count:
data:
-
oid: MIKROTIK-MIB::mtxrDHCPLeaseCount
num_oid: '.1.3.6.1.4.1.14988.1.1.6.1.{{ $index }}'
descr: DHCP Lease Count
index: mtxrDHCPLeaseCount.{{ $index }}
-
oid: MIKROTIK-MIB::mtxrCtTotalEntries
num_oid: .1.3.6.1.4.1.14988.1.1.22.1.1.{{ $index }}
descr: 'Total number of connections'
index: mtxrCtTotalEntries.{{ $index }}
group: Firewall
-
oid: MIKROTIK-MIB::mtxrCtIP4Entries
num_oid: .1.3.6.1.4.1.14988.1.1.22.1.2.{{ $index }}
descr: 'Total number of ipv4 connections'
index: mtxrCtIP4Entries.{{ $index }}
group: Firewall
-
oid: MIKROTIK-MIB::mtxrCtIP6Entries
num_oid: .1.3.6.1.4.1.14988.1.1.22.1.3.{{ $index }}
descr: 'Total number of ipv6 connections'
index: mtxrCtIP6Entries.{{ $index }}
group: Firewall