mirror of
https://github.com/unpoller/unpoller.git
synced 2026-10-19 07:41:32 +02:00
Prefer a known stats channel and fall back to airQuality for temperature and humidity. Omit channels whose status is unknown, and add the particulate and gas series only when the controller includes them. Co-authored-by: Cursor <cursoragent@cursor.com>
194 lines
5.3 KiB
Go
194 lines
5.3 KiB
Go
package datadogunifi
|
|
|
|
import (
|
|
"github.com/unpoller/unifi/v6"
|
|
)
|
|
|
|
// batchProtectDevices generates UniFi Protect device datapoints for Datadog.
|
|
//
|
|
// Each device kind is guarded independently because GetProtectDevices leaves the field for a
|
|
// failing endpoint nil/empty rather than failing the whole poll.
|
|
func (u *DatadogUnifi) batchProtectDevices(r report, d *unifi.ProtectDevices) {
|
|
if d == nil {
|
|
return
|
|
}
|
|
|
|
if d.NVR != nil {
|
|
u.batchProtectNVR(r, d)
|
|
}
|
|
|
|
for _, s := range d.Sensors {
|
|
if s != nil {
|
|
u.batchProtectSensor(r, d, s)
|
|
}
|
|
}
|
|
|
|
for _, c := range d.Cameras {
|
|
if c != nil {
|
|
u.batchProtectCamera(r, d, c)
|
|
}
|
|
}
|
|
|
|
for _, l := range d.Lights {
|
|
if l != nil {
|
|
u.batchProtectLight(r, d, l)
|
|
}
|
|
}
|
|
|
|
for _, b := range d.Bridges {
|
|
if b != nil {
|
|
u.batchProtectBridge(r, d, b)
|
|
}
|
|
}
|
|
|
|
for _, ls := range d.LinkStations {
|
|
if ls != nil {
|
|
u.batchProtectLinkStation(r, d, ls)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (u *DatadogUnifi) batchProtectNVR(r report, d *unifi.ProtectDevices) {
|
|
metricName := metricNamespace("protect_nvr")
|
|
nvr := d.NVR
|
|
|
|
tags := tagMapToTags(cleanTags(map[string]string{
|
|
"source": d.SourceName,
|
|
"name": nvr.Name,
|
|
"mac": nvr.MAC,
|
|
"guid": nvr.GUID,
|
|
}))
|
|
|
|
_ = r.reportGauge(metricName("present"), 1.0, tags)
|
|
_ = r.reportGauge(metricName("state"), unifi.ProtectStateValue(nvr.State), tags)
|
|
}
|
|
|
|
func (u *DatadogUnifi) batchProtectSensor(r report, d *unifi.ProtectDevices, s *unifi.ProtectSensor) {
|
|
metricName := metricNamespace("protect_sensor")
|
|
|
|
tags := tagMapToTags(cleanTags(map[string]string{
|
|
"source": d.SourceName,
|
|
"name": s.Name,
|
|
"mac": s.MAC,
|
|
"guid": s.GUID,
|
|
}))
|
|
|
|
_ = r.reportGauge(metricName("present"), 1.0, tags)
|
|
_ = r.reportGauge(metricName("state"), unifi.ProtectStateValue(s.State), tags)
|
|
_ = r.reportGauge(metricName("is_opened"), boolToFloat64(s.IsOpened.Val), tags)
|
|
_ = r.reportGauge(metricName("is_motion_detected"), boolToFloat64(s.IsMotionDetected.Val), tags)
|
|
|
|
if s.BatteryStatus != nil {
|
|
_ = r.reportGauge(metricName("battery_percent"), s.BatteryStatus.Percentage.Val, tags)
|
|
_ = r.reportGauge(metricName("battery_low"), boolToFloat64(s.BatteryStatus.IsLow.Val), tags)
|
|
}
|
|
|
|
if temp, ok := s.TemperatureReading(); ok {
|
|
_ = r.reportGauge(metricName("temperature"), temp, tags)
|
|
}
|
|
|
|
if humidity, ok := s.HumidityReading(); ok {
|
|
_ = r.reportGauge(metricName("humidity"), humidity, tags)
|
|
}
|
|
|
|
if light, ok := s.LightReading(); ok {
|
|
_ = r.reportGauge(metricName("light"), light, tags)
|
|
}
|
|
|
|
if s.AirQuality == nil {
|
|
return
|
|
}
|
|
|
|
aq := s.AirQuality
|
|
channels := []struct {
|
|
name string
|
|
reading *unifi.ProtectSensorStatValue
|
|
}{
|
|
{"aqi", aq.AQI},
|
|
{"co2_ppm", aq.CO2},
|
|
{"tvoc", aq.TVOC},
|
|
{"voc", aq.VOC},
|
|
{"vape", aq.Vape},
|
|
{"pm1_0", aq.PM1p0},
|
|
{"pm2_5", aq.PM2p5},
|
|
{"pm4_0", aq.PM4p0},
|
|
{"pm10", aq.PM10p0},
|
|
}
|
|
|
|
for _, ch := range channels {
|
|
value, ok := ch.reading.Reading()
|
|
if !ok {
|
|
continue
|
|
}
|
|
|
|
_ = r.reportGauge(metricName(ch.name), value, tags)
|
|
}
|
|
}
|
|
|
|
func (u *DatadogUnifi) batchProtectCamera(r report, d *unifi.ProtectDevices, c *unifi.ProtectCamera) {
|
|
metricName := metricNamespace("protect_camera")
|
|
|
|
tags := tagMapToTags(cleanTags(map[string]string{
|
|
"source": d.SourceName,
|
|
"name": c.Name,
|
|
"mac": c.MAC,
|
|
"guid": c.GUID,
|
|
}))
|
|
|
|
_ = r.reportGauge(metricName("present"), 1.0, tags)
|
|
_ = r.reportGauge(metricName("state"), unifi.ProtectStateValue(c.State), tags)
|
|
_ = r.reportGauge(metricName("mic_enabled"), boolToFloat64(c.IsMicEnabled.Val), tags)
|
|
}
|
|
|
|
func (u *DatadogUnifi) batchProtectLight(r report, d *unifi.ProtectDevices, l *unifi.ProtectLight) {
|
|
metricName := metricNamespace("protect_light")
|
|
|
|
tags := tagMapToTags(cleanTags(map[string]string{
|
|
"source": d.SourceName,
|
|
"name": l.Name,
|
|
"mac": l.MAC,
|
|
"guid": l.GUID,
|
|
}))
|
|
|
|
_ = r.reportGauge(metricName("present"), 1.0, tags)
|
|
_ = r.reportGauge(metricName("state"), unifi.ProtectStateValue(l.State), tags)
|
|
_ = r.reportGauge(metricName("is_light_on"), boolToFloat64(l.IsLightOn.Val), tags)
|
|
_ = r.reportGauge(metricName("is_dark"), boolToFloat64(l.IsDark.Val), tags)
|
|
_ = r.reportGauge(metricName("is_pir_motion_detected"), boolToFloat64(l.IsPirMotionDetected.Val), tags)
|
|
}
|
|
|
|
func (u *DatadogUnifi) batchProtectBridge(r report, d *unifi.ProtectDevices, b *unifi.ProtectBridge) {
|
|
metricName := metricNamespace("protect_bridge")
|
|
|
|
tags := tagMapToTags(cleanTags(map[string]string{
|
|
"source": d.SourceName,
|
|
"name": b.Name,
|
|
"mac": b.MAC,
|
|
"guid": b.GUID,
|
|
}))
|
|
|
|
_ = r.reportGauge(metricName("present"), 1.0, tags)
|
|
_ = r.reportGauge(metricName("state"), unifi.ProtectStateValue(b.State), tags)
|
|
_ = r.reportGauge(metricName("client_count"), float64(len(b.Clients)), tags)
|
|
_ = r.reportGauge(metricName("max_clients"), b.MaxClients.Val, tags)
|
|
}
|
|
|
|
func (u *DatadogUnifi) batchProtectLinkStation(r report, d *unifi.ProtectDevices, ls *unifi.ProtectLinkStation) {
|
|
metricName := metricNamespace("protect_link_station")
|
|
|
|
tags := tagMapToTags(cleanTags(map[string]string{
|
|
"source": d.SourceName,
|
|
"name": ls.Name,
|
|
"mac": ls.MAC,
|
|
"guid": ls.GUID,
|
|
}))
|
|
|
|
_ = r.reportGauge(metricName("present"), 1.0, tags)
|
|
_ = r.reportGauge(metricName("state"), unifi.ProtectStateValue(ls.State), tags)
|
|
_ = r.reportGauge(metricName("is_alarm_hub"), boolToFloat64(ls.IsAlarmHub.Val), tags)
|
|
|
|
if ls.AlarmHub != nil {
|
|
_ = r.reportGauge(metricName("armed"), boolToFloat64(ls.AlarmHub.Armed.Val), tags)
|
|
}
|
|
}
|