From 100c2dabe859ffa4d615b1af5a7bb090287406d1 Mon Sep 17 00:00:00 2001 From: Holger Date: Sat, 18 Apr 2026 16:51:43 +0200 Subject: [PATCH 1/3] chore(inputs.huebridge): Update to latest Hue API version --- go.mod | 8 +- go.sum | 8 + plugins/inputs/huebridge/bridge.go | 197 +++++++++--------- plugins/inputs/huebridge/huebridge.go | 3 +- .../huebridge/testdata/metrics/huebridge.txt | 28 +-- 5 files changed, 121 insertions(+), 123 deletions(-) diff --git a/go.mod b/go.mod index 9cee23197fff2..8e9daa3d090eb 100644 --- a/go.mod +++ b/go.mod @@ -202,7 +202,7 @@ require ( github.com/srebhan/protobufquery v1.0.4 github.com/stretchr/testify v1.11.1 github.com/tbrandon/mbserver v0.0.0-20170611213546-993e1772cc62 - github.com/tdrn-org/go-hue v0.3.0 + github.com/tdrn-org/go-hue v1.2.0 github.com/tdrn-org/go-nsdp v0.5.1 github.com/tdrn-org/go-tr064 v0.3.0 github.com/testcontainers/testcontainers-go v0.42.0 @@ -374,7 +374,7 @@ require ( github.com/go-jose/go-jose/v4 v4.1.4 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.22.5 // indirect + github.com/go-openapi/jsonpointer v0.23.0 // indirect github.com/go-openapi/jsonreference v0.21.4 // indirect github.com/go-openapi/swag v0.26.0 // indirect github.com/go-openapi/swag/cmdutils v0.26.0 // indirect @@ -461,7 +461,7 @@ require ( github.com/likexian/gokit v0.25.16 // indirect github.com/lufia/plan9stats v0.0.0-20260330125221-c963978e514e // indirect github.com/magiconair/properties v1.8.10 // indirect - github.com/mailru/easyjson v0.9.0 // indirect + github.com/mailru/easyjson v0.9.2 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-ieproxy v0.0.11 // indirect github.com/mattn/go-isatty v0.0.20 // indirect @@ -496,7 +496,7 @@ require ( github.com/nats-io/nuid v1.0.1 // indirect github.com/ncruces/go-strftime v1.0.0 // indirect github.com/ncw/swift/v2 v2.0.3 // indirect - github.com/oapi-codegen/runtime v1.1.1 // indirect + github.com/oapi-codegen/runtime v1.4.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.148.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.1 // indirect diff --git a/go.sum b/go.sum index 1b55fd22c947b..7ecdc18d5754b 100644 --- a/go.sum +++ b/go.sum @@ -1290,6 +1290,8 @@ github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-openapi/jsonpointer v0.22.5 h1:8on/0Yp4uTb9f4XvTrM2+1CPrV05QPZXu+rvu2o9jcA= github.com/go-openapi/jsonpointer v0.22.5/go.mod h1:gyUR3sCvGSWchA2sUBJGluYMbe1zazrYWIkWPjjMUY0= +github.com/go-openapi/jsonpointer v0.23.0 h1:c25HFTJ6uWGmoe5BQI6p72p4o7KnlWYsy1MeFlAumsw= +github.com/go-openapi/jsonpointer v0.23.0/go.mod h1:iWRmZTrGn7XwYhtPt/fvdSFj1OfNBngqRT2UG3BxSqY= github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= github.com/go-openapi/swag v0.26.0 h1:GVDXCmfvhfu1BxiHo8/FA+BbKmhecHnG3varjON5/RI= @@ -1855,6 +1857,8 @@ github.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3 github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mailru/easyjson v0.9.2 h1:dX8U45hQsZpxd80nLvDGihsQ/OxlvTkVUXH2r/8cb2M= +github.com/mailru/easyjson v0.9.2/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -2034,6 +2038,8 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmtpMYro= github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= +github.com/oapi-codegen/runtime v1.4.0 h1:KLOSFOp7UzkbS7Cs1ms6NBEKYr0WmH2wZG0KKbd2er4= +github.com/oapi-codegen/runtime v1.4.0/go.mod h1:5sw5fxCDmnOzKNYmkVNF8d34kyUeejJEY8HNT2WaPec= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852/go.mod h1:eqOVx5Vwu4gd2mmMZvVZsgIqNSaW3xxRThUJ0k/TPk4= @@ -2377,6 +2383,8 @@ github.com/tbrandon/mbserver v0.0.0-20170611213546-993e1772cc62 h1:Oj2e7Sae4XrOs github.com/tbrandon/mbserver v0.0.0-20170611213546-993e1772cc62/go.mod h1:qUzPVlSj2UgxJkVbH0ZwuuiR46U8RBMDT5KLY78Ifpw= github.com/tdrn-org/go-hue v0.3.0 h1:ywIlfTx9lcDp+n9XyGNY/9mUihW82lsWUanTzvdfeMc= github.com/tdrn-org/go-hue v0.3.0/go.mod h1:KUnPy2lGoP43ygNoCg6jVEhf8h5fpRn0Esjxq9syCnU= +github.com/tdrn-org/go-hue v1.2.0 h1:GjLkbOhDCgK/i/Kp+d9S5gJ8DKSsLk8edpn5PNBHnHs= +github.com/tdrn-org/go-hue v1.2.0/go.mod h1:WW/nt+xwuz7f2XIfe6aMMKzmqN0jXjeSEA6c0F9j6js= github.com/tdrn-org/go-nsdp v0.5.1 h1:w80Y5zF02nEopj/ycTcsDzeq5DgYeKquvGe8xuWXcEM= github.com/tdrn-org/go-nsdp v0.5.1/go.mod h1:e2I00mSN+Gl8DBgQmSerI6z4M2KrsQbN0SjpQYoI1OI= github.com/tdrn-org/go-tr064 v0.3.0 h1:jeab3z69trkwsxNN1Vo3W+ED/u61MbWTZW4PNI2+1pg= diff --git a/plugins/inputs/huebridge/bridge.go b/plugins/inputs/huebridge/bridge.go index fec9bc0f55fc0..46c1af261fa27 100644 --- a/plugins/inputs/huebridge/bridge.go +++ b/plugins/inputs/huebridge/bridge.go @@ -1,6 +1,7 @@ package huebridge import ( + "context" "crypto/tls" "fmt" "maps" @@ -35,28 +36,28 @@ func (b *bridge) String() string { return b.url.Redacted() } -func (b *bridge) process(acc telegraf.Accumulator) error { +func (b *bridge) process(ctx context.Context, acc telegraf.Accumulator) error { if b.resolvedClient == nil { if err := b.resolve(); err != nil { return err } } b.log.Tracef("Processing bridge %s", b) - if err := b.fetchMetadata(); err != nil { + if err := b.fetchMetadata(ctx); err != nil { // Discard previously resolved client and re-resolve on next process call b.resolvedClient = nil return err } - acc.AddError(b.processLights(acc)) - acc.AddError(b.processTemperatures(acc)) - acc.AddError(b.processLightLevels(acc)) - acc.AddError(b.processMotionSensors(acc)) - acc.AddError(b.processDevicePowers(acc)) + acc.AddError(b.processLights(ctx, acc)) + acc.AddError(b.processTemperatures(ctx, acc)) + acc.AddError(b.processLightLevels(ctx, acc)) + acc.AddError(b.processMotionSensors(ctx, acc)) + acc.AddError(b.processDevicePowers(ctx, acc)) return nil } -func (b *bridge) processLights(acc telegraf.Accumulator) error { - getLightsResponse, err := b.resolvedClient.GetLights() +func (b *bridge) processLights(ctx context.Context, acc telegraf.Accumulator) error { + getLightsResponse, err := b.resolvedClient.GetLights(ctx) if err != nil { return fmt.Errorf("failed to access bridge lights on %s: %w", b, err) } @@ -64,26 +65,24 @@ func (b *bridge) processLights(acc telegraf.Accumulator) error { return fmt.Errorf("failed to fetch bridge lights from %s: %s", b, getLightsResponse.HTTPResponse.Status) } responseData := getLightsResponse.JSON200.Data - if responseData != nil { - for _, light := range *responseData { - tags := make(map[string]string) - tags["bridge_id"] = b.resolvedClient.Bridge().BridgeId - tags["room"] = b.resolveResourceRoom(*light.Id, *light.Metadata.Name) - tags["device"] = *light.Metadata.Name - fields := make(map[string]interface{}) - if *light.On.On { - fields["on"] = 1 - } else { - fields["on"] = 0 - } - acc.AddGauge("huebridge_light", fields, tags) + for _, light := range responseData { + tags := make(map[string]string) + tags["bridge_id"] = b.resolvedClient.Bridge().BridgeId + tags["room"] = b.resolveResourceRoom(light.Id, light.Metadata.Name) + tags["device"] = light.Metadata.Name + fields := make(map[string]interface{}) + if light.On.On { + fields["on"] = 1 + } else { + fields["on"] = 0 } + acc.AddGauge("huebridge_light", fields, tags) } return nil } -func (b *bridge) processTemperatures(acc telegraf.Accumulator) error { - getTemperaturesResponse, err := b.resolvedClient.GetTemperatures() +func (b *bridge) processTemperatures(ctx context.Context, acc telegraf.Accumulator) error { + getTemperaturesResponse, err := b.resolvedClient.GetTemperatures(ctx) if err != nil { return fmt.Errorf("failed to access bridge temperatures on %s: %w", b, err) } @@ -91,24 +90,22 @@ func (b *bridge) processTemperatures(acc telegraf.Accumulator) error { return fmt.Errorf("failed to fetch bridge temperatures from %s: %s", b, getTemperaturesResponse.HTTPResponse.Status) } responseData := getTemperaturesResponse.JSON200.Data - if responseData != nil { - for _, temperature := range *responseData { - temperatureName := b.resolveDeviceName(*temperature.Id) - tags := make(map[string]string) - tags["bridge_id"] = b.resolvedClient.Bridge().BridgeId - tags["room"] = b.resolveResourceRoom(*temperature.Id, temperatureName) - tags["device"] = temperatureName - tags["enabled"] = strconv.FormatBool(*temperature.Enabled) - fields := make(map[string]interface{}) - fields["temperature"] = *temperature.Temperature.TemperatureReport.Temperature - acc.AddGauge("huebridge_temperature", fields, tags) - } + for _, temperature := range responseData { + temperatureName := b.resolveDeviceName(temperature.Id) + tags := make(map[string]string) + tags["bridge_id"] = b.resolvedClient.Bridge().BridgeId + tags["room"] = b.resolveResourceRoom(temperature.Id, temperatureName) + tags["device"] = temperatureName + tags["enabled"] = strconv.FormatBool(temperature.Enabled) + fields := make(map[string]interface{}) + fields["temperature"] = *temperature.Temperature.TemperatureReport.Temperature + acc.AddGauge("huebridge_temperature", fields, tags) } return nil } -func (b *bridge) processLightLevels(acc telegraf.Accumulator) error { - getLightLevelsResponse, err := b.resolvedClient.GetLightLevels() +func (b *bridge) processLightLevels(ctx context.Context, acc telegraf.Accumulator) error { + getLightLevelsResponse, err := b.resolvedClient.GetLightLevels(ctx) if err != nil { return fmt.Errorf("failed to access bridge lights levels on %s: %w", b, err) } @@ -116,25 +113,23 @@ func (b *bridge) processLightLevels(acc telegraf.Accumulator) error { return fmt.Errorf("failed to fetch bridge light levels from %s: %s", b, getLightLevelsResponse.HTTPResponse.Status) } responseData := getLightLevelsResponse.JSON200.Data - if responseData != nil { - for _, lightLevel := range *responseData { - lightLevelName := b.resolveDeviceName(*lightLevel.Id) - tags := make(map[string]string) - tags["bridge_id"] = b.resolvedClient.Bridge().BridgeId - tags["room"] = b.resolveResourceRoom(*lightLevel.Id, lightLevelName) - tags["device"] = lightLevelName - tags["enabled"] = strconv.FormatBool(*lightLevel.Enabled) - fields := make(map[string]interface{}) - fields["light_level"] = *lightLevel.Light.LightLevelReport.LightLevel - fields["light_level_lux"] = math.Pow(10.0, (float64(*lightLevel.Light.LightLevelReport.LightLevel)-1.0)/10000.0) - acc.AddGauge("huebridge_light_level", fields, tags) - } + for _, lightLevel := range responseData { + lightLevelName := b.resolveDeviceName(lightLevel.Id) + tags := make(map[string]string) + tags["bridge_id"] = b.resolvedClient.Bridge().BridgeId + tags["room"] = b.resolveResourceRoom(lightLevel.Id, lightLevelName) + tags["device"] = lightLevelName + tags["enabled"] = strconv.FormatBool(lightLevel.Enabled) + fields := make(map[string]interface{}) + fields["light_level"] = *lightLevel.Light.LightLevelReport.LightLevel + fields["light_level_lux"] = math.Pow(10.0, (float64(*lightLevel.Light.LightLevelReport.LightLevel)-1.0)/10000.0) + acc.AddGauge("huebridge_light_level", fields, tags) } return nil } -func (b *bridge) processMotionSensors(acc telegraf.Accumulator) error { - getMotionSensorsResponse, err := b.resolvedClient.GetMotionSensors() +func (b *bridge) processMotionSensors(ctx context.Context, acc telegraf.Accumulator) error { + getMotionSensorsResponse, err := b.resolvedClient.GetMotionSensors(ctx) if err != nil { return fmt.Errorf("failed to access bridge motion sensors on %s: %w", b, err) } @@ -142,28 +137,26 @@ func (b *bridge) processMotionSensors(acc telegraf.Accumulator) error { return fmt.Errorf("failed to fetch bridge motion sensors from %s: %s", b, getMotionSensorsResponse.HTTPResponse.Status) } responseData := getMotionSensorsResponse.JSON200.Data - if responseData != nil { - for _, motionSensor := range *responseData { - motionSensorName := b.resolveDeviceName(*motionSensor.Id) - tags := make(map[string]string) - tags["bridge_id"] = b.resolvedClient.Bridge().BridgeId - tags["room"] = b.resolveResourceRoom(*motionSensor.Id, motionSensorName) - tags["device"] = motionSensorName - tags["enabled"] = strconv.FormatBool(*motionSensor.Enabled) - fields := make(map[string]interface{}) - if *motionSensor.Motion.MotionReport.Motion { - fields["motion"] = 1 - } else { - fields["motion"] = 0 - } - acc.AddGauge("huebridge_motion_sensor", fields, tags) + for _, motionSensor := range responseData { + motionSensorName := b.resolveDeviceName(motionSensor.Id) + tags := make(map[string]string) + tags["bridge_id"] = b.resolvedClient.Bridge().BridgeId + tags["room"] = b.resolveResourceRoom(motionSensor.Id, motionSensorName) + tags["device"] = motionSensorName + tags["enabled"] = strconv.FormatBool(motionSensor.Enabled) + fields := make(map[string]interface{}) + if *motionSensor.Motion.MotionReport.Motion { + fields["motion"] = 1 + } else { + fields["motion"] = 0 } + acc.AddGauge("huebridge_motion_sensor", fields, tags) } return nil } -func (b *bridge) processDevicePowers(acc telegraf.Accumulator) error { - getDevicePowersResponse, err := b.resolvedClient.GetDevicePowers() +func (b *bridge) processDevicePowers(ctx context.Context, acc telegraf.Accumulator) error { + getDevicePowersResponse, err := b.resolvedClient.GetDevicePowers(ctx) if err != nil { return fmt.Errorf("failed to access bridge device powers on %s: %w", b, err) } @@ -171,21 +164,19 @@ func (b *bridge) processDevicePowers(acc telegraf.Accumulator) error { return fmt.Errorf("failed to fetch bridge device powers from %s: %s", b, getDevicePowersResponse.HTTPResponse.Status) } responseData := getDevicePowersResponse.JSON200.Data - if responseData != nil { - for _, devicePower := range *responseData { - if devicePower.PowerState.BatteryLevel == nil && devicePower.PowerState.BatteryState == nil { - continue - } - devicePowerName := b.resolveDeviceName(*devicePower.Id) - tags := make(map[string]string) - tags["bridge_id"] = b.resolvedClient.Bridge().BridgeId - tags["room"] = b.resolveResourceRoom(*devicePower.Id, devicePowerName) - tags["device"] = devicePowerName - fields := make(map[string]interface{}) - fields["battery_level"] = *devicePower.PowerState.BatteryLevel - fields["battery_state"] = *devicePower.PowerState.BatteryState - acc.AddGauge("huebridge_device_power", fields, tags) + for _, devicePower := range responseData { + if devicePower.PowerState.BatteryLevel == nil && devicePower.PowerState.BatteryState == nil { + continue } + devicePowerName := b.resolveDeviceName(devicePower.Id) + tags := make(map[string]string) + tags["bridge_id"] = b.resolvedClient.Bridge().BridgeId + tags["room"] = b.resolveResourceRoom(devicePower.Id, devicePowerName) + tags["device"] = devicePowerName + fields := make(map[string]interface{}) + fields["battery_level"] = *devicePower.PowerState.BatteryLevel + fields["battery_state"] = *devicePower.PowerState.BatteryState + acc.AddGauge("huebridge_device_power", fields, tags) } return nil } @@ -295,20 +286,20 @@ func (b *bridge) resolveRemoteBridge(locator *hue.RemoteBridgeLocator) error { return nil } -func (b *bridge) fetchMetadata() error { - err := b.fetchResourceTree() +func (b *bridge) fetchMetadata(ctx context.Context) error { + err := b.fetchResourceTree(ctx) if err != nil { return err } - err = b.fetchDeviceNames() + err = b.fetchDeviceNames(ctx) if err != nil { return err } - return b.fetchRoomAssignments() + return b.fetchRoomAssignments(ctx) } -func (b *bridge) fetchResourceTree() error { - getResourcesResponse, err := b.resolvedClient.GetResources() +func (b *bridge) fetchResourceTree(ctx context.Context) error { + getResourcesResponse, err := b.resolvedClient.GetResources(ctx) if err != nil { return fmt.Errorf("failed to access bridge resources on %s: %w", b, err) } @@ -322,15 +313,13 @@ func (b *bridge) fetchResourceTree() error { } b.resourceTree = make(map[string]string, len(*responseData)) for _, resource := range *responseData { - if resource.Owner != nil { - b.resourceTree[*resource.Id] = *resource.Owner.Rid - } + b.resourceTree[resource.Id] = resource.Owner.Rid } return nil } -func (b *bridge) fetchDeviceNames() error { - getDevicesResponse, err := b.resolvedClient.GetDevices() +func (b *bridge) fetchDeviceNames(ctx context.Context) error { + getDevicesResponse, err := b.resolvedClient.GetDevices(ctx) if err != nil { return fmt.Errorf("failed to access bridge devices on %s: %w", b, err) } @@ -342,15 +331,15 @@ func (b *bridge) fetchDeviceNames() error { b.deviceNames = make(map[string]string) return nil } - b.deviceNames = make(map[string]string, len(*responseData)) - for _, device := range *responseData { - b.deviceNames[*device.Id] = *device.Metadata.Name + b.deviceNames = make(map[string]string, len(responseData)) + for _, device := range responseData { + b.deviceNames[device.Id] = device.Metadata.Name } return nil } -func (b *bridge) fetchRoomAssignments() error { - getRoomsResponse, err := b.resolvedClient.GetRooms() +func (b *bridge) fetchRoomAssignments(ctx context.Context) error { + getRoomsResponse, err := b.resolvedClient.GetRooms(ctx) if err != nil { return fmt.Errorf("failed to access bridge rooms on %s: %w", b, err) } @@ -362,10 +351,10 @@ func (b *bridge) fetchRoomAssignments() error { b.roomAssignments = maps.Clone(b.configRoomAssignments) return nil } - b.roomAssignments = make(map[string]string, len(*responseData)) - for _, roomGet := range *responseData { - for _, children := range *roomGet.Children { - b.roomAssignments[*children.Rid] = *roomGet.Metadata.Name + b.roomAssignments = make(map[string]string, len(responseData)) + for _, roomGet := range responseData { + for _, children := range roomGet.Children { + b.roomAssignments[children.Rid] = roomGet.Metadata.Name } } maps.Copy(b.roomAssignments, b.configRoomAssignments) diff --git a/plugins/inputs/huebridge/huebridge.go b/plugins/inputs/huebridge/huebridge.go index adf6b2811bd9f..cf5a308388925 100644 --- a/plugins/inputs/huebridge/huebridge.go +++ b/plugins/inputs/huebridge/huebridge.go @@ -2,6 +2,7 @@ package huebridge import ( + "context" _ "embed" "errors" "fmt" @@ -89,7 +90,7 @@ func (h *HueBridge) Gather(acc telegraf.Accumulator) error { wg.Add(1) go func() { defer wg.Done() - acc.AddError(bridge.process(acc)) + acc.AddError(bridge.process(context.Background(), acc)) }() } wg.Wait() diff --git a/plugins/inputs/huebridge/testdata/metrics/huebridge.txt b/plugins/inputs/huebridge/testdata/metrics/huebridge.txt index 1399190568534..1ade34cf161d3 100644 --- a/plugins/inputs/huebridge/testdata/metrics/huebridge.txt +++ b/plugins/inputs/huebridge/testdata/metrics/huebridge.txt @@ -1,14 +1,14 @@ -huebridge_light,bridge_id=0123456789ABCDEF,device=Name#3,room=Name#15 on=0i 1737181537879611000 -huebridge_light,bridge_id=0123456789ABCDEF,device=Name#8,room=Name#14 on=0i 1737181537879628000 -huebridge_light,bridge_id=0123456789ABCDEF,device=Name#12,room=Name#16 on=0i 1737181537879632000 -huebridge_light,bridge_id=0123456789ABCDEF,device=Name#6,room=Name#13 on=0i 1737181537879634000 -huebridge_light,bridge_id=0123456789ABCDEF,device=Name#1,room=Name#13 on=0i 1737181537879635000 -huebridge_light,bridge_id=0123456789ABCDEF,device=Name#2,room=Name#13 on=0i 1737181537879637000 -huebridge_light,bridge_id=0123456789ABCDEF,device=Name#5,room=Name#15 on=0i 1737181537879639000 -huebridge_light,bridge_id=0123456789ABCDEF,device=Name#9,room=Name#13 on=0i 1737181537879640000 -huebridge_light,bridge_id=0123456789ABCDEF,device=Name#11,room=Name#15 on=0i 1737181537879642000 -huebridge_light,bridge_id=0123456789ABCDEF,device=Name#4,room=Name#14 on=0i 1737181537879646000 -huebridge_temperature,bridge_id=0123456789ABCDEF,device=Name#7,enabled=true,room=Name#15 temperature=17.6299991607666 1737181537879828000 -huebridge_light_level,bridge_id=0123456789ABCDEF,device=Name#7,enabled=true,room=Name#15 light_level=18948i,light_level_lux=78.46934003526889 1737181537880034000 -huebridge_motion_sensor,bridge_id=0123456789ABCDEF,device=Name#7,enabled=true,room=Name#15 motion=0i 1737181537880213000 -huebridge_device_power,bridge_id=0123456789ABCDEF,device=Name#7,room=Name#15 battery_level=100i 1737181537880360000 +huebridge_light,bridge_id=0123456789ABCDEF,device=Name#19,room=Name#28 on=0i 1737181537879611000 +huebridge_light,bridge_id=0123456789ABCDEF,device=Name#24,room=Name#28 on=0i 1737181537879628000 +huebridge_light,bridge_id=0123456789ABCDEF,device=Name#17,room=Name#28 on=0i 1737181537879632000 +huebridge_light,bridge_id=0123456789ABCDEF,device=Name#22,room=Name#26 on=0i 1737181537879634000 +huebridge_light,bridge_id=0123456789ABCDEF,device=Name#15,room=Name#26 on=0i 1737181537879635000 +huebridge_light,bridge_id=0123456789ABCDEF,device=Name#18,room=Name#27 on=0i 1737181537879637000 +huebridge_light,bridge_id=0123456789ABCDEF,device=Name#21,room=Name#27 on=0i 1737181537879639000 +huebridge_light,bridge_id=0123456789ABCDEF,device=Name#25,room=Name#29 on=0i 1737181537879640000 +huebridge_light,bridge_id=0123456789ABCDEF,device=Name#16,room=Name#26 on=0i 1737181537879642000 +huebridge_light,bridge_id=0123456789ABCDEF,device=Name#20,room=Name#26 on=0i 1737181537879646000 +huebridge_temperature,bridge_id=0123456789ABCDEF,device=Name#1,enabled=true,room=Name#28 temperature=18.899999618530273 1737181537879828000 +huebridge_light_level,bridge_id=0123456789ABCDEF,device=Name#1,enabled=true,room=Name#28 light_level=4895i,light_level_lux=3.0860289794360645 1737181537880034000 +huebridge_motion_sensor,bridge_id=0123456789ABCDEF,device=Name#1,enabled=true,room=Name#28 motion=0i 1737181537880213000 +huebridge_device_power,bridge_id=0123456789ABCDEF,device=Name#1,room=Name#28 battery_level=77i 1737181537880360000 From ea459d447498945429fc83d27c2578695d8dc850 Mon Sep 17 00:00:00 2001 From: Holger Date: Mon, 20 Apr 2026 19:38:03 +0200 Subject: [PATCH 2/3] Working in review comments --- plugins/inputs/huebridge/bridge.go | 74 +++++++++++++++++------------- 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/plugins/inputs/huebridge/bridge.go b/plugins/inputs/huebridge/bridge.go index 46c1af261fa27..0e84b6868da22 100644 --- a/plugins/inputs/huebridge/bridge.go +++ b/plugins/inputs/huebridge/bridge.go @@ -66,11 +66,12 @@ func (b *bridge) processLights(ctx context.Context, acc telegraf.Accumulator) er } responseData := getLightsResponse.JSON200.Data for _, light := range responseData { - tags := make(map[string]string) - tags["bridge_id"] = b.resolvedClient.Bridge().BridgeId - tags["room"] = b.resolveResourceRoom(light.Id, light.Metadata.Name) - tags["device"] = light.Metadata.Name - fields := make(map[string]interface{}) + tags := map[string]string{ + "bridge_id": b.resolvedClient.Bridge().BridgeId, + "room": b.resolveResourceRoom(light.Id, light.Metadata.Name), + "device": light.Metadata.Name, + } + fields := make(map[string]interface{}, 1) if light.On.On { fields["on"] = 1 } else { @@ -92,13 +93,15 @@ func (b *bridge) processTemperatures(ctx context.Context, acc telegraf.Accumulat responseData := getTemperaturesResponse.JSON200.Data for _, temperature := range responseData { temperatureName := b.resolveDeviceName(temperature.Id) - tags := make(map[string]string) - tags["bridge_id"] = b.resolvedClient.Bridge().BridgeId - tags["room"] = b.resolveResourceRoom(temperature.Id, temperatureName) - tags["device"] = temperatureName - tags["enabled"] = strconv.FormatBool(temperature.Enabled) - fields := make(map[string]interface{}) - fields["temperature"] = *temperature.Temperature.TemperatureReport.Temperature + tags := map[string]string{ + "bridge_id": b.resolvedClient.Bridge().BridgeId, + "room": b.resolveResourceRoom(temperature.Id, temperatureName), + "device": temperatureName, + "enabled": strconv.FormatBool(temperature.Enabled), + } + fields := map[string]interface{}{ + "temperature": *temperature.Temperature.TemperatureReport.Temperature, + } acc.AddGauge("huebridge_temperature", fields, tags) } return nil @@ -115,14 +118,16 @@ func (b *bridge) processLightLevels(ctx context.Context, acc telegraf.Accumulato responseData := getLightLevelsResponse.JSON200.Data for _, lightLevel := range responseData { lightLevelName := b.resolveDeviceName(lightLevel.Id) - tags := make(map[string]string) - tags["bridge_id"] = b.resolvedClient.Bridge().BridgeId - tags["room"] = b.resolveResourceRoom(lightLevel.Id, lightLevelName) - tags["device"] = lightLevelName - tags["enabled"] = strconv.FormatBool(lightLevel.Enabled) - fields := make(map[string]interface{}) - fields["light_level"] = *lightLevel.Light.LightLevelReport.LightLevel - fields["light_level_lux"] = math.Pow(10.0, (float64(*lightLevel.Light.LightLevelReport.LightLevel)-1.0)/10000.0) + tags := map[string]string{ + "bridge_id": b.resolvedClient.Bridge().BridgeId, + "room": b.resolveResourceRoom(lightLevel.Id, lightLevelName), + "device": lightLevelName, + "enabled": strconv.FormatBool(lightLevel.Enabled), + } + fields := map[string]interface{}{ + "light_level": *lightLevel.Light.LightLevelReport.LightLevel, + "light_level_lux": math.Pow(10.0, (float64(*lightLevel.Light.LightLevelReport.LightLevel)-1.0)/10000.0), + } acc.AddGauge("huebridge_light_level", fields, tags) } return nil @@ -139,12 +144,13 @@ func (b *bridge) processMotionSensors(ctx context.Context, acc telegraf.Accumula responseData := getMotionSensorsResponse.JSON200.Data for _, motionSensor := range responseData { motionSensorName := b.resolveDeviceName(motionSensor.Id) - tags := make(map[string]string) - tags["bridge_id"] = b.resolvedClient.Bridge().BridgeId - tags["room"] = b.resolveResourceRoom(motionSensor.Id, motionSensorName) - tags["device"] = motionSensorName - tags["enabled"] = strconv.FormatBool(motionSensor.Enabled) - fields := make(map[string]interface{}) + tags := map[string]string{ + "bridge_id": b.resolvedClient.Bridge().BridgeId, + "room": b.resolveResourceRoom(motionSensor.Id, motionSensorName), + "device": motionSensorName, + "enabled": strconv.FormatBool(motionSensor.Enabled), + } + fields := make(map[string]interface{}, 1) if *motionSensor.Motion.MotionReport.Motion { fields["motion"] = 1 } else { @@ -169,13 +175,15 @@ func (b *bridge) processDevicePowers(ctx context.Context, acc telegraf.Accumulat continue } devicePowerName := b.resolveDeviceName(devicePower.Id) - tags := make(map[string]string) - tags["bridge_id"] = b.resolvedClient.Bridge().BridgeId - tags["room"] = b.resolveResourceRoom(devicePower.Id, devicePowerName) - tags["device"] = devicePowerName - fields := make(map[string]interface{}) - fields["battery_level"] = *devicePower.PowerState.BatteryLevel - fields["battery_state"] = *devicePower.PowerState.BatteryState + tags := map[string]string{ + "bridge_id": b.resolvedClient.Bridge().BridgeId, + "room": b.resolveResourceRoom(devicePower.Id, devicePowerName), + "device": devicePowerName, + } + fields := map[string]interface{}{ + "battery_level": *devicePower.PowerState.BatteryLevel, + "battery_state": *devicePower.PowerState.BatteryState, + } acc.AddGauge("huebridge_device_power", fields, tags) } return nil From a41e09948a90a111f50c7b28e855b565dd5ae136 Mon Sep 17 00:00:00 2001 From: Holger Date: Tue, 21 Apr 2026 21:30:03 +0200 Subject: [PATCH 3/3] Fix format after merge of PR https://github.com/influxdata/telegraf/pull/18739 --- plugins/inputs/huebridge/bridge.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/inputs/huebridge/bridge.go b/plugins/inputs/huebridge/bridge.go index b793c99e312c5..44f1046209318 100644 --- a/plugins/inputs/huebridge/bridge.go +++ b/plugins/inputs/huebridge/bridge.go @@ -89,7 +89,7 @@ func (b *bridge) processLights(ctx context.Context, acc telegraf.Accumulator) er fields["color_x"] = float64(light.Color.Xy.X) fields["color_y"] = float64(light.Color.Xy.Y) } - acc.AddGauge("huebridge_light", fields, tags) + acc.AddGauge("huebridge_light", fields, tags) } return nil }