hue_exporter/hue/hue.go

271 lines
6.1 KiB
Go
Raw Normal View History

2020-12-22 18:24:23 +01:00
package hue
import (
2020-12-28 17:29:44 +01:00
"encoding/json"
2020-12-22 18:24:23 +01:00
"fmt"
2020-12-28 17:29:44 +01:00
"io/ioutil"
2020-12-22 18:24:23 +01:00
"github.com/aexel90/hue_exporter/metric"
2020-12-28 17:29:44 +01:00
hueAPI "github.com/amimof/huego"
2020-12-22 18:24:23 +01:00
)
// Exporter data
type Exporter struct {
BaseURL string
Username string
}
2020-12-28 17:29:44 +01:00
type collectEntry struct {
Type string `json:"type"`
Result map[string]interface{} `json:"result"`
}
2020-12-22 18:24:23 +01:00
const (
2020-12-27 14:58:21 +01:00
TypeLight = "light"
2020-12-28 08:49:18 +01:00
TypeSensor = "sensor"
2020-12-27 14:58:21 +01:00
2020-12-28 17:29:44 +01:00
LabelName = "name"
LabelType = "type"
LabelID = "id"
LabelModelID = "model_id"
LabelManufacturerName = "manufacturer_name"
LabelSwVersion = "sw_version"
LabelSwConfigID = "sw_config_id"
LabelUniqueID = "unique_id"
LabelStateOn = "state_on"
LabelStateAlert = "state_alert"
LabelStateBri = "state_bri"
LabelStateColorMode = "state_color_mode"
LabelStateCT = "state_ct"
LabelStateReachable = "state_reachable"
LabelStateSaturation = "state_saturation"
LabelStateButtonEvent = "state_buttonevent"
LabelStateDaylight = "state_daylight"
LabelStateLastUpdated = "state_lastupdated"
LabelStateTemperature = "state_temperature"
LabelStateLightLevel = "state_lightlevel"
LabelConfigBattery = "config_battery"
LabelConfigOn = "config_on"
LabelConfigReachable = "config_reachable"
2020-12-22 18:24:23 +01:00
)
// InitMetrics func
func (exporter *Exporter) InitMetrics() (metrics []*metric.Metric) {
metrics = append(metrics, &metric.Metric{
2020-12-28 08:49:18 +01:00
HueType: TypeLight,
FqName: "hue_light_info",
Help: "Non-numeric data, value is always 1",
2020-12-28 17:29:44 +01:00
Labels: []string{
LabelName,
LabelID,
LabelType,
LabelModelID,
LabelManufacturerName,
LabelSwVersion,
LabelSwConfigID,
LabelUniqueID,
LabelStateOn,
LabelStateAlert,
LabelStateBri,
LabelStateCT,
LabelStateReachable,
LabelStateSaturation,
},
2020-12-28 08:49:18 +01:00
})
2020-12-27 14:58:21 +01:00
2020-12-28 12:55:45 +01:00
metrics = append(metrics, &metric.Metric{
2020-12-28 17:29:44 +01:00
HueType: TypeLight,
FqName: "hue_light_state",
Help: "light status (1=ON, 0=OFF)",
Labels: []string{
LabelName,
},
2020-12-28 12:55:45 +01:00
ResultKey: LabelStateOn,
})
2020-12-27 14:58:21 +01:00
metrics = append(metrics, &metric.Metric{
2020-12-28 08:49:18 +01:00
HueType: TypeSensor,
FqName: "hue_sensor_info",
Help: "Non-numeric data, value is always 1",
2020-12-28 17:29:44 +01:00
Labels: []string{
LabelName,
LabelID,
LabelType,
LabelModelID,
LabelManufacturerName,
LabelSwVersion,
LabelUniqueID,
LabelStateButtonEvent,
LabelStateDaylight,
LabelStateLastUpdated,
LabelStateTemperature,
LabelConfigBattery,
LabelConfigOn,
LabelConfigReachable,
},
2020-12-28 08:49:18 +01:00
})
metrics = append(metrics, &metric.Metric{
2020-12-28 17:29:44 +01:00
HueType: TypeSensor,
FqName: "hue_sensor_temperature",
Help: "temperature level celsius degree",
Labels: []string{
LabelName,
},
ResultKey: LabelStateTemperature,
2020-12-28 08:49:18 +01:00
})
metrics = append(metrics, &metric.Metric{
2020-12-28 17:29:44 +01:00
HueType: TypeSensor,
FqName: "hue_sensor_lightlevel",
Help: "light level",
Labels: []string{
LabelName,
},
ResultKey: LabelStateLightLevel,
2020-12-28 08:49:18 +01:00
})
2020-12-22 18:24:23 +01:00
return metrics
}
2020-12-28 17:29:44 +01:00
// CollectAll available hue metrics
func CollectAll(url string, username string, fileName string) {
bridge := hueAPI.New(url, username)
jsonContent := []collectEntry{}
2020-12-22 18:24:23 +01:00
2020-12-28 17:29:44 +01:00
sensorData, err := collectSensors(bridge)
if err != nil {
fmt.Sprintln(err)
return
}
2020-12-22 18:24:23 +01:00
2020-12-28 17:29:44 +01:00
lightData, err := collectLights(bridge)
2020-12-22 18:24:23 +01:00
if err != nil {
2020-12-28 17:29:44 +01:00
fmt.Sprintln(err)
return
}
for _, sensor := range sensorData {
jsonContent = append(jsonContent, collectEntry{
Type: "sensor",
Result: sensor,
})
}
for _, light := range lightData {
jsonContent = append(jsonContent, collectEntry{
Type: "light",
Result: light,
})
2020-12-22 18:24:23 +01:00
}
2020-12-28 17:29:44 +01:00
jsonString, err := json.MarshalIndent(jsonContent, "", "\t")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(jsonString))
if fileName != "" {
err = ioutil.WriteFile(fileName, jsonString, 0644)
if err != nil {
fmt.Printf("Failed writing JSON file '%s': %s\n", fileName, err.Error())
}
}
}
// Collect metrics
func (exporter *Exporter) Collect(metrics []*metric.Metric) (err error) {
bridge := hueAPI.New(exporter.BaseURL, exporter.Username)
2020-12-28 08:49:18 +01:00
sensorData, err := collectSensors(bridge)
if err != nil {
return err
}
2020-12-22 18:24:23 +01:00
2020-12-28 08:49:18 +01:00
lightData, err := collectLights(bridge)
if err != nil {
return err
}
2020-12-22 18:24:23 +01:00
2020-12-28 08:49:18 +01:00
for _, metric := range metrics {
2020-12-22 18:24:23 +01:00
switch metric.HueType {
case TypeLight:
2020-12-28 08:49:18 +01:00
metric.MetricResult = lightData
case TypeSensor:
metric.MetricResult = sensorData
2020-12-22 18:24:23 +01:00
}
}
return nil
}
2020-12-28 17:29:44 +01:00
func collectSensors(bridge *hueAPI.Bridge) (sensorData []map[string]interface{}, err error) {
2020-12-27 14:58:21 +01:00
2020-12-28 17:29:44 +01:00
sensors, err := bridge.GetSensors()
2020-12-27 14:58:21 +01:00
if err != nil {
2020-12-28 08:49:18 +01:00
return nil, fmt.Errorf("[error GetAllSensors()] '%v'", err)
2020-12-27 14:58:21 +01:00
}
for _, sensor := range sensors {
result := make(map[string]interface{})
2020-12-28 08:49:18 +01:00
result[LabelName] = sensor.Name
2020-12-28 17:29:44 +01:00
result[LabelID] = sensor.ID
2020-12-28 08:49:18 +01:00
result[LabelType] = sensor.Type
result[LabelModelID] = sensor.ModelID
result[LabelManufacturerName] = sensor.ManufacturerName
2020-12-28 17:29:44 +01:00
result[LabelSwVersion] = sensor.SwVersion
2020-12-28 08:49:18 +01:00
result[LabelUniqueID] = sensor.UniqueID
2020-12-28 17:29:44 +01:00
//State
for stateKey, stateValue := range sensor.State {
result["state_"+stateKey] = stateValue
}
//Config
for stateKey, stateValue := range sensor.Config {
result["config_"+stateKey] = stateValue
2020-12-27 14:58:21 +01:00
}
2020-12-28 08:49:18 +01:00
sensorData = append(sensorData, result)
2020-12-27 14:58:21 +01:00
}
2020-12-28 08:49:18 +01:00
return sensorData, nil
2020-12-27 14:58:21 +01:00
}
2020-12-28 17:29:44 +01:00
func collectLights(bridge *hueAPI.Bridge) (lightData []map[string]interface{}, err error) {
2020-12-22 18:24:23 +01:00
2020-12-28 17:29:44 +01:00
lights, err := bridge.GetLights()
2020-12-22 18:24:23 +01:00
if err != nil {
2020-12-28 08:49:18 +01:00
return nil, fmt.Errorf("[error GetAllLights()] '%v'", err)
2020-12-22 18:24:23 +01:00
}
for _, light := range lights {
result := make(map[string]interface{})
2020-12-28 08:49:18 +01:00
result[LabelName] = light.Name
2020-12-28 17:29:44 +01:00
result[LabelID] = light.ID
2020-12-28 08:49:18 +01:00
result[LabelType] = light.Type
result[LabelModelID] = light.ModelID
result[LabelManufacturerName] = light.ManufacturerName
2020-12-28 17:29:44 +01:00
result[LabelSwVersion] = light.SwVersion
result[LabelSwConfigID] = light.SwConfigID
2020-12-28 08:49:18 +01:00
result[LabelUniqueID] = light.UniqueID
2020-12-28 17:29:44 +01:00
// State
2020-12-28 08:49:18 +01:00
result[LabelStateOn] = light.State.On
result[LabelStateAlert] = light.State.Alert
result[LabelStateBri] = light.State.Bri
2020-12-28 17:29:44 +01:00
result[LabelStateColorMode] = light.State.ColorMode
result[LabelStateCT] = light.State.Ct
2020-12-28 08:49:18 +01:00
result[LabelStateReachable] = light.State.Reachable
2020-12-28 17:29:44 +01:00
result[LabelStateSaturation] = light.State.Sat
2020-12-28 08:49:18 +01:00
lightData = append(lightData, result)
2020-12-22 18:24:23 +01:00
}
2020-12-28 08:49:18 +01:00
return lightData, nil
2020-12-22 18:24:23 +01:00
}