hue_exporter/hue/hue.go

241 lines
6.5 KiB
Go
Raw Permalink 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-29 14:10:47 +01:00
typeLight = "light"
typeSensor = "sensor"
2020-12-29 14:24:09 +01:00
typeBridge = "bridge"
2020-12-29 14:10:47 +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"
labelAPIVersion = "api_version"
labelBridgeID = "bridge_id"
labelIPAddress = "ip_address"
labelInternetServiceInternet = "internetservice_internet"
labelInternetServiceRemoteAccess = "internetservice_remoteaccess"
labelInternetServiceSwUpdate = "internetservice_swupdate"
labelInternetServiceTime = "internetservice_time"
labelLocalTime = "local_time"
labelSwUpdate2LastChange = "sw_update_last_change"
labelZigbeeChannel = "zigbee_channel"
2020-12-22 18:24:23 +01:00
)
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
}
2020-12-29 14:10:47 +01:00
bridgeData, err := collectBridgeInfo(bridge)
if err != nil {
fmt.Sprintln(err)
return
}
2020-12-28 17:29:44 +01:00
for _, sensor := range sensorData {
2020-12-29 14:10:47 +01:00
jsonContent = append(jsonContent, collectEntry{Type: "sensor", Result: sensor})
2020-12-28 17:29:44 +01:00
}
for _, light := range lightData {
2020-12-29 14:10:47 +01:00
jsonContent = append(jsonContent, collectEntry{Type: "light", Result: light})
}
for _, bridge := range bridgeData {
jsonContent = append(jsonContent, collectEntry{Type: "bridge", Result: bridge})
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-29 14:24:09 +01:00
bridgeData, err := collectBridgeInfo(bridge)
if err != nil {
return err
}
2020-12-28 08:49:18 +01:00
for _, metric := range metrics {
2020-12-22 18:24:23 +01:00
switch metric.HueType {
2020-12-29 14:10:47 +01:00
case typeLight:
2020-12-28 08:49:18 +01:00
metric.MetricResult = lightData
2020-12-29 14:10:47 +01:00
case typeSensor:
2020-12-28 08:49:18 +01:00
metric.MetricResult = sensorData
2020-12-29 14:24:09 +01:00
case typeBridge:
metric.MetricResult = bridgeData
2020-12-29 14:10:47 +01:00
default:
return fmt.Errorf("Type '%v' currently not supported", metric.HueType)
2020-12-22 18:24:23 +01:00
}
2020-12-29 14:10:47 +01:00
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-29 14:10:47 +01:00
return nil, fmt.Errorf("[GetAllSensors()] '%v'", err)
2020-12-27 14:58:21 +01:00
}
for _, sensor := range sensors {
result := make(map[string]interface{})
2020-12-29 14:10:47 +01:00
result[labelName] = sensor.Name
result[labelID] = sensor.ID
result[labelType] = sensor.Type
result[labelModelID] = sensor.ModelID
result[labelManufacturerName] = sensor.ManufacturerName
result[labelSwVersion] = sensor.SwVersion
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-29 14:10:47 +01:00
return nil, fmt.Errorf("[GetAllLights()] '%v'", err)
2020-12-22 18:24:23 +01:00
}
for _, light := range lights {
result := make(map[string]interface{})
2020-12-29 14:10:47 +01:00
result[labelName] = light.Name
result[labelID] = light.ID
result[labelType] = light.Type
result[labelModelID] = light.ModelID
result[labelManufacturerName] = light.ManufacturerName
result[labelSwVersion] = light.SwVersion
result[labelSwConfigID] = light.SwConfigID
result[labelUniqueID] = light.UniqueID
2020-12-28 17:29:44 +01:00
// State
2020-12-29 14:10:47 +01:00
result[labelStateOn] = light.State.On
result[labelStateAlert] = light.State.Alert
result[labelStateBri] = light.State.Bri
result[labelStateColorMode] = light.State.ColorMode
result[labelStateCT] = light.State.Ct
result[labelStateReachable] = light.State.Reachable
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
}
2020-12-29 14:10:47 +01:00
func collectBridgeInfo(bridge *hueAPI.Bridge) (bridgeData []map[string]interface{}, err error) {
config, err := bridge.GetConfig()
if err != nil {
return nil, fmt.Errorf("[GetConfig] '%v'", err)
}
result := make(map[string]interface{})
result[labelName] = config.Name
result[labelAPIVersion] = config.APIVersion
result[labelBridgeID] = config.BridgeID
result[labelIPAddress] = config.IPAddress
result[labelInternetServiceInternet] = config.InternetService.Internet
result[labelInternetServiceRemoteAccess] = config.InternetService.RemoteAccess
result[labelInternetServiceSwUpdate] = config.InternetService.SwUpdate
result[labelInternetServiceTime] = config.InternetService.Time
result[labelLocalTime] = config.LocalTime
result[labelModelID] = config.ModelID
result[labelSwVersion] = config.SwVersion
result[labelSwUpdate2LastChange] = config.SwUpdate2.LastChange
result[labelZigbeeChannel] = config.ZigbeeChannel
bridgeData = append(bridgeData, result)
return bridgeData, nil
}