Select Git revision
-
Richard Mitchell authoredRichard Mitchell authored
sensors.go 4.26 KiB
package main
import (
hue "github.com/collinux/gohue"
log "github.com/golang/glog"
"github.com/prometheus/client_golang/prometheus"
)
type sensorCollector struct {
bridge *hue.Bridge
ignoreTypes []string
sensorValue *prometheus.GaugeVec
sensorLastUpdated *prometheus.GaugeVec
sensorOn *prometheus.GaugeVec
sensorBattery *prometheus.GaugeVec
sensorReachable *prometheus.GaugeVec
}
var variableSensorLabelNames = []string{
"name",
"type",
"model_id",
"manufacturer_name",
"product_name",
"unique_id",
}
func contains(a []string, x string) bool {
for _, n := range a {
if x == n {
return true
}
}
return false
}
// NewSensorCollector Create a new Hue collector for sensors
func NewSensorCollector(namespace string, bridge *hue.Bridge, ignoreTypes []string) prometheus.Collector {
c := sensorCollector{
bridge: bridge,
ignoreTypes: ignoreTypes,
sensorValue: prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Namespace: namespace,
Subsystem: "sensor",
Name: "value",
Help: "Sensor values",
},
variableSensorLabelNames,
),
sensorBattery: prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Namespace: namespace,
Subsystem: "sensor",
Name: "battery",
Help: "Sensor battery levels (%)",
},
variableSensorLabelNames,
),
sensorLastUpdated: prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Namespace: namespace,
Subsystem: "sensor",
Name: "last_updated",
Help: "Sensor last updated time",
},
variableSensorLabelNames,
),
sensorOn: prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Namespace: namespace,
Subsystem: "sensor",
Name: "on",
Help: "Sensor on/off (1/0)",
},
variableSensorLabelNames,
),
sensorReachable: prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Namespace: namespace,
Subsystem: "sensor",
Name: "reachable",
Help: "Sensor reachability (1/0)",
},
variableSensorLabelNames,
),
}
return c
}
func (c sensorCollector) Describe(ch chan<- *prometheus.Desc) {
c.sensorValue.Describe(ch)
c.sensorBattery.Describe(ch)
c.sensorLastUpdated.Describe(ch)
c.sensorOn.Describe(ch)
c.sensorReachable.Describe(ch)
}
func (c sensorCollector) Collect(ch chan<- prometheus.Metric) {
c.sensorValue.Reset()
c.sensorBattery.Reset()
c.sensorLastUpdated.Reset()
c.sensorOn.Reset()
c.sensorReachable.Reset()
sensors, err := c.bridge.GetAllSensors()
if err != nil {
log.Errorf("Failed to update sensors: %v", err)
}
for _, sensor := range sensors {
var sensorValue float64
if contains(c.ignoreTypes, sensor.Type) {
continue
} else if sensor.Type == "Daylight" {
// bridge daylight (sunrise / sunset) sensor
if sensor.State.Daylight {
sensorValue = 1
}
} else if sensor.Type == "ZGPSwitch" {
// Hue tap switch
sensorValue = float64(sensor.State.ButtonEvent)
} else if sensor.Type == "ZLLSwitch" {
// Hue dimmer switch
sensorValue = float64(sensor.State.ButtonEvent)
} else if sensor.Type == "ClipGenericStatus" {
sensorValue = float64(sensor.State.Status)
} else if sensor.Type == "ZLLTemperature" {
sensorValue = float64(sensor.State.Temperature)
} else if sensor.Type == "ZLLPresence" {
if sensor.State.Presence {
sensorValue = 1
}
} else if sensor.Type == "ZLLLightLevel" {
sensorValue = float64(sensor.State.LightLevel)
}
sensorLabels := prometheus.Labels{
"name": sensor.Name,
"model_id": sensor.ModelID,
"manufacturer_name": sensor.ManufacturerName,
"type": sensor.Type,
"unique_id": sensor.UniqueID,
"product_name": sensor.ProductName,
}
c.sensorValue.With(sensorLabels).Set(sensorValue)
c.sensorBattery.With(sensorLabels).Set(float64(sensor.Config.Battery))
c.sensorLastUpdated.With(sensorLabels).Set(float64(sensor.State.LastUpdated.Unix()))
if sensor.Config.On {
c.sensorOn.With(sensorLabels).Set(1)
} else {
c.sensorOn.With(sensorLabels).Set(0)
}
if sensor.Config.Reachable {
c.sensorReachable.With(sensorLabels).Set(1)
} else {
c.sensorReachable.With(sensorLabels).Set(0)
}
}
c.sensorValue.Collect(ch)
c.sensorBattery.Collect(ch)
c.sensorLastUpdated.Collect(ch)
c.sensorOn.Collect(ch)
c.sensorReachable.Collect(ch)
}