Compare commits

...

10 commits

Author SHA1 Message Date
6f2a73f46e add basic authorization 2023-10-17 21:28:30 +02:00
5705db4d60 remove host mode and add -listen-address parameter 2023-10-17 18:30:47 +02:00
aexel90
9b8ee4a931
Create docker-image.yml 2023-01-27 13:26:39 +01:00
Alexander Thiel
0373514272 grafana dashboard update 2022-10-24 21:20:49 +02:00
Alexander Thiel
325704fb1e grafana link 2022-10-23 21:29:27 +02:00
Alexander Thiel
9a5657d727 docker rework 2022-10-23 20:45:16 +02:00
aexel90
22a96b528f readme docker 2022-10-19 00:02:21 +02:00
aexel90
0cf0b0409a template reworked 2022-10-18 23:55:37 +02:00
aexel90
e2aa30cb2c update 2022-10-18 23:51:18 +02:00
aexel90
c98d4269ba docker update 2022-10-18 21:55:26 +02:00
7 changed files with 207 additions and 37 deletions

View file

@ -1,3 +1,5 @@
USERNAME=***** USERNAME=*****
HUE_URL=192.168.178.34 HUE_URL=192.168.178.34
METRICS_FILE=****** LISTEN_ADDRESS=127.0.0.1:9773
AUTH_USER=user
AUTH_PASS=password

18
.github/workflows/docker-image.yml vendored Normal file
View file

@ -0,0 +1,18 @@
name: Docker Image CI
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build the Docker image
run: docker build . --file Dockerfile --tag hue_exporter:$(date +%s)

View file

@ -9,6 +9,7 @@ RUN go build -o /hue_exporter
FROM alpine:latest FROM alpine:latest
WORKDIR / WORKDIR /
COPY --from=build /hue_exporter /hue_exporter COPY --from=build /hue_exporter /hue_exporter
COPY hue_metrics.json ./
EXPOSE 9773 EXPOSE 9773
ENTRYPOINT [ "sh", "-c", "/hue_exporter -username ${USERNAME} -hue-url ${HUE_URL} -metrics-file ${METRICS_FILE} " ] ENTRYPOINT [ "sh", "-c", "/hue_exporter -username ${USERNAME} -hue-url ${HUE_URL} -metrics-file hue_metrics.json -listen-address ${LISTEN_ADDRESS} -auth.user ${AUTH_USER} -auth.pass ${AUTH_PASS}" ]

View file

@ -4,13 +4,13 @@ This exporter exports some variables from Philips Hue Bridge
(https://www.philips-hue.com) (https://www.philips-hue.com)
to prometheus. to prometheus.
## Building ## Build
go get github.com/aexel90/hue_exporter/ go get github.com/aexel90/hue_exporter/
cd $GOPATH/src/github.com/aexel90/hue_exporter cd $GOPATH/src/github.com/aexel90/hue_exporter
go install go install
## Running ## Execute
How to create a user for your bridge is described here: https://developers.meethue.com/develop/get-started-2/ How to create a user for your bridge is described here: https://developers.meethue.com/develop/get-started-2/
@ -34,6 +34,12 @@ Usage:
-username string -username string
The username token having bridge access The username token having bridge access
## Docker
cp .env.template .env
vi .env
docker-compose up -d --build
## Example execution ## Example execution
### Running within prometheus: ### Running within prometheus:
@ -76,4 +82,6 @@ Usage:
Dashboard ID is 13645. Dashboard ID is 13645.
https://grafana.com/grafana/dashboards/13645
![Grafana](https://raw.githubusercontent.com/aexel90/hue_exporter/main/grafana/screenshot.jpg) ![Grafana](https://raw.githubusercontent.com/aexel90/hue_exporter/main/grafana/screenshot.jpg)

View file

@ -1,13 +1,14 @@
version: '3.4' version: '3.4'
services: services:
stravakomootsync: hue_exporter:
image: hue_exporter image: hue_exporter
build: build:
context: . context: .
dockerfile: ./Dockerfile.multistage dockerfile: ./Dockerfile
restart: unless-stopped restart: unless-stopped
container_name: hue_exporter container_name: hue_exporter
#network_mode: "host"
ports: ports:
- 9773:9773 - 9773:9773
env_file: env_file:

View file

@ -1,4 +1,47 @@
{ {
"__inputs": [
{
"name": "DS_PROMETHEUS",
"label": "Prometheus",
"description": "",
"type": "datasource",
"pluginId": "prometheus",
"pluginName": "Prometheus"
}
],
"__elements": {},
"__requires": [
{
"type": "grafana",
"id": "grafana",
"name": "Grafana",
"version": "9.2.1"
},
{
"type": "panel",
"id": "graph",
"name": "Graph (old)",
"version": ""
},
{
"type": "datasource",
"id": "prometheus",
"name": "Prometheus",
"version": "1.0.0"
},
{
"type": "panel",
"id": "stat",
"name": "Stat",
"version": ""
},
{
"type": "panel",
"id": "table",
"name": "Table",
"version": ""
}
],
"annotations": { "annotations": {
"list": [ "list": [
{ {
@ -25,14 +68,14 @@
"fiscalYearStartMonth": 0, "fiscalYearStartMonth": 0,
"gnetId": 13645, "gnetId": 13645,
"graphTooltip": 0, "graphTooltip": 0,
"id": 4, "id": null,
"links": [], "links": [],
"liveNow": false, "liveNow": false,
"panels": [ "panels": [
{ {
"datasource": { "datasource": {
"type": "prometheus", "type": "prometheus",
"uid": "nLstfzWgz" "uid": "${DS_PROMETHEUS}"
}, },
"fieldConfig": { "fieldConfig": {
"defaults": { "defaults": {
@ -75,9 +118,14 @@
"text": {}, "text": {},
"textMode": "auto" "textMode": "auto"
}, },
"pluginVersion": "8.5.3", "pluginVersion": "9.2.1",
"targets": [ "targets": [
{ {
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"editorMode": "code",
"expr": "hue_bridge_info", "expr": "hue_bridge_info",
"format": "table", "format": "table",
"instant": true, "instant": true,
@ -92,7 +140,7 @@
{ {
"datasource": { "datasource": {
"type": "prometheus", "type": "prometheus",
"uid": "nLstfzWgz" "uid": "${DS_PROMETHEUS}"
}, },
"fieldConfig": { "fieldConfig": {
"defaults": { "defaults": {
@ -135,9 +183,13 @@
"text": {}, "text": {},
"textMode": "auto" "textMode": "auto"
}, },
"pluginVersion": "8.5.3", "pluginVersion": "9.2.1",
"targets": [ "targets": [
{ {
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"expr": "hue_bridge_info", "expr": "hue_bridge_info",
"format": "table", "format": "table",
"instant": true, "instant": true,
@ -152,7 +204,7 @@
{ {
"datasource": { "datasource": {
"type": "prometheus", "type": "prometheus",
"uid": "nLstfzWgz" "uid": "${DS_PROMETHEUS}"
}, },
"fieldConfig": { "fieldConfig": {
"defaults": { "defaults": {
@ -195,9 +247,14 @@
"text": {}, "text": {},
"textMode": "auto" "textMode": "auto"
}, },
"pluginVersion": "8.5.3", "pluginVersion": "9.2.1",
"targets": [ "targets": [
{ {
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"editorMode": "code",
"expr": "hue_bridge_info", "expr": "hue_bridge_info",
"format": "table", "format": "table",
"instant": true, "instant": true,
@ -212,7 +269,7 @@
{ {
"datasource": { "datasource": {
"type": "prometheus", "type": "prometheus",
"uid": "nLstfzWgz" "uid": "${DS_PROMETHEUS}"
}, },
"fieldConfig": { "fieldConfig": {
"defaults": { "defaults": {
@ -255,9 +312,14 @@
"text": {}, "text": {},
"textMode": "auto" "textMode": "auto"
}, },
"pluginVersion": "8.5.3", "pluginVersion": "9.2.1",
"targets": [ "targets": [
{ {
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"editorMode": "code",
"expr": "hue_bridge_info", "expr": "hue_bridge_info",
"format": "table", "format": "table",
"instant": true, "instant": true,
@ -272,7 +334,7 @@
{ {
"datasource": { "datasource": {
"type": "prometheus", "type": "prometheus",
"uid": "nLstfzWgz" "uid": "${DS_PROMETHEUS}"
}, },
"fieldConfig": { "fieldConfig": {
"defaults": { "defaults": {
@ -316,9 +378,14 @@
"text": {}, "text": {},
"textMode": "auto" "textMode": "auto"
}, },
"pluginVersion": "8.5.3", "pluginVersion": "9.2.1",
"targets": [ "targets": [
{ {
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"editorMode": "code",
"expr": "hue_bridge_info", "expr": "hue_bridge_info",
"format": "table", "format": "table",
"instant": true, "instant": true,
@ -333,7 +400,7 @@
{ {
"datasource": { "datasource": {
"type": "prometheus", "type": "prometheus",
"uid": "nLstfzWgz" "uid": "${DS_PROMETHEUS}"
}, },
"fieldConfig": { "fieldConfig": {
"defaults": { "defaults": {
@ -376,9 +443,14 @@
"text": {}, "text": {},
"textMode": "auto" "textMode": "auto"
}, },
"pluginVersion": "8.5.3", "pluginVersion": "9.2.1",
"targets": [ "targets": [
{ {
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"editorMode": "code",
"expr": "hue_bridge_info", "expr": "hue_bridge_info",
"format": "table", "format": "table",
"instant": true, "instant": true,
@ -393,7 +465,7 @@
{ {
"datasource": { "datasource": {
"type": "prometheus", "type": "prometheus",
"uid": "nLstfzWgz" "uid": "${DS_PROMETHEUS}"
}, },
"fieldConfig": { "fieldConfig": {
"defaults": { "defaults": {
@ -437,9 +509,14 @@
"text": {}, "text": {},
"textMode": "value" "textMode": "value"
}, },
"pluginVersion": "8.5.3", "pluginVersion": "9.2.1",
"targets": [ "targets": [
{ {
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"editorMode": "code",
"expr": "hue_bridge_info", "expr": "hue_bridge_info",
"format": "table", "format": "table",
"instant": true, "instant": true,
@ -454,7 +531,7 @@
{ {
"datasource": { "datasource": {
"type": "prometheus", "type": "prometheus",
"uid": "nLstfzWgz" "uid": "${DS_PROMETHEUS}"
}, },
"description": "", "description": "",
"fieldConfig": { "fieldConfig": {
@ -497,9 +574,14 @@
"text": {}, "text": {},
"textMode": "auto" "textMode": "auto"
}, },
"pluginVersion": "8.5.3", "pluginVersion": "9.2.1",
"targets": [ "targets": [
{ {
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"editorMode": "code",
"expr": "sum(hue_light_state)", "expr": "sum(hue_light_state)",
"format": "table", "format": "table",
"hide": false, "hide": false,
@ -516,7 +598,7 @@
{ {
"datasource": { "datasource": {
"type": "prometheus", "type": "prometheus",
"uid": "nLstfzWgz" "uid": "${DS_PROMETHEUS}"
}, },
"description": "", "description": "",
"fieldConfig": { "fieldConfig": {
@ -559,9 +641,14 @@
"text": {}, "text": {},
"textMode": "auto" "textMode": "auto"
}, },
"pluginVersion": "8.5.3", "pluginVersion": "9.2.1",
"targets": [ "targets": [
{ {
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"editorMode": "code",
"expr": "count(hue_light_state)-sum(hue_light_state)", "expr": "count(hue_light_state)-sum(hue_light_state)",
"format": "table", "format": "table",
"instant": true, "instant": true,
@ -586,7 +673,7 @@
"dashes": false, "dashes": false,
"datasource": { "datasource": {
"type": "prometheus", "type": "prometheus",
"uid": "nLstfzWgz" "uid": "${DS_PROMETHEUS}"
}, },
"decimals": 1, "decimals": 1,
"fill": 0, "fill": 0,
@ -619,7 +706,7 @@
"alertThreshold": false "alertThreshold": false
}, },
"percentage": false, "percentage": false,
"pluginVersion": "8.5.3", "pluginVersion": "9.2.1",
"pointradius": 2, "pointradius": 2,
"points": false, "points": false,
"renderer": "flot", "renderer": "flot",
@ -629,9 +716,15 @@
"steppedLine": false, "steppedLine": false,
"targets": [ "targets": [
{ {
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"editorMode": "code",
"expr": "10^((hue_sensor_lightlevel-1)/10000)", "expr": "10^((hue_sensor_lightlevel-1)/10000)",
"interval": "", "interval": "",
"legendFormat": "{{name}}", "legendFormat": "{{name}}",
"range": true,
"refId": "A" "refId": "A"
} }
], ],
@ -681,7 +774,7 @@
"dashes": false, "dashes": false,
"datasource": { "datasource": {
"type": "prometheus", "type": "prometheus",
"uid": "nLstfzWgz" "uid": "${DS_PROMETHEUS}"
}, },
"decimals": 1, "decimals": 1,
"fill": 0, "fill": 0,
@ -714,7 +807,7 @@
"alertThreshold": false "alertThreshold": false
}, },
"percentage": false, "percentage": false,
"pluginVersion": "8.5.3", "pluginVersion": "9.2.1",
"pointradius": 2, "pointradius": 2,
"points": false, "points": false,
"renderer": "flot", "renderer": "flot",
@ -724,9 +817,15 @@
"steppedLine": false, "steppedLine": false,
"targets": [ "targets": [
{ {
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"editorMode": "code",
"expr": "hue_sensor_temperature/100", "expr": "hue_sensor_temperature/100",
"interval": "", "interval": "",
"legendFormat": "{{name}}", "legendFormat": "{{name}}",
"range": true,
"refId": "A" "refId": "A"
} }
], ],
@ -767,7 +866,7 @@
{ {
"datasource": { "datasource": {
"type": "prometheus", "type": "prometheus",
"uid": "nLstfzWgz" "uid": "${DS_PROMETHEUS}"
}, },
"fieldConfig": { "fieldConfig": {
"defaults": { "defaults": {
@ -923,9 +1022,14 @@
} }
] ]
}, },
"pluginVersion": "8.5.3", "pluginVersion": "9.2.1",
"targets": [ "targets": [
{ {
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"editorMode": "code",
"expr": "hue_sensor_info{type=~\"ZLL.*\"}", "expr": "hue_sensor_info{type=~\"ZLL.*\"}",
"format": "table", "format": "table",
"instant": true, "instant": true,
@ -978,8 +1082,9 @@
{ {
"datasource": { "datasource": {
"type": "prometheus", "type": "prometheus",
"uid": "nLstfzWgz" "uid": "${DS_PROMETHEUS}"
}, },
"description": "",
"fieldConfig": { "fieldConfig": {
"defaults": { "defaults": {
"color": { "color": {
@ -1172,9 +1277,14 @@
} }
] ]
}, },
"pluginVersion": "8.5.3", "pluginVersion": "9.2.1",
"targets": [ "targets": [
{ {
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"editorMode": "code",
"expr": "hue_light_info", "expr": "hue_light_info",
"format": "table", "format": "table",
"instant": true, "instant": true,
@ -1229,20 +1339,20 @@
} }
], ],
"refresh": "5m", "refresh": "5m",
"schemaVersion": 36, "schemaVersion": 37,
"style": "dark", "style": "dark",
"tags": [], "tags": [],
"templating": { "templating": {
"list": [] "list": []
}, },
"time": { "time": {
"from": "now-6h", "from": "now-30m",
"to": "now" "to": "now"
}, },
"timepicker": {}, "timepicker": {},
"timezone": "", "timezone": "",
"title": "Philips Hue", "title": "Philips Hue",
"uid": "X7uYULiRk", "uid": "X7uYULiRk",
"version": 6, "version": 1,
"weekStart": "" "weekStart": ""
} }

32
main.go
View file

@ -21,12 +21,31 @@ var (
flagUsername = flag.String("username", "", "The username token having bridge access") flagUsername = flag.String("username", "", "The username token having bridge access")
flagAddress = flag.String("listen-address", "127.0.0.1:9773", "The address to listen on for HTTP requests.") flagAddress = flag.String("listen-address", "127.0.0.1:9773", "The address to listen on for HTTP requests.")
flagMetricsFile = flag.String("metrics-file", "hue_metrics.json", "The JSON file with the metric definitions.") flagMetricsFile = flag.String("metrics-file", "hue_metrics.json", "The JSON file with the metric definitions.")
authUser = flag.String("auth.user", "", "Username for basic auth.")
authPass = flag.String("auth.pass", "", "Password for basic auth. Enables basic auth if set.")
flagTest = flag.Bool("test", false, "Test configured metrics") flagTest = flag.Bool("test", false, "Test configured metrics")
flagCollect = flag.Bool("collect", false, "Collect all available metrics") flagCollect = flag.Bool("collect", false, "Collect all available metrics")
flagCollectFile = flag.String("collect-file", "", "The JSON file where to store collect results") flagCollectFile = flag.String("collect-file", "", "The JSON file where to store collect results")
) )
type basicAuthHandler struct {
handler http.HandlerFunc
user string
password string
}
func (h *basicAuthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
user, password, ok := r.BasicAuth()
if !ok || password != h.password || user != h.user {
w.Header().Set("WWW-Authenticate", "Basic realm=\"metrics\"")
http.Error(w, "Invalid username or password", http.StatusUnauthorized)
return
}
h.handler(w, r)
return
}
func main() { func main() {
flag.Parse() flag.Parse()
@ -55,7 +74,18 @@ func main() {
hueCollector.Test() hueCollector.Test()
} else { } else {
prometheus.MustRegister(hueCollector) prometheus.MustRegister(hueCollector)
http.Handle("/metrics", promhttp.Handler()) handler := promhttp.Handler()
if *authUser != "" || *authPass != "" {
if *authUser == "" || *authPass == "" {
log.Fatal("You need to specify -auth.user and -auth.pass to enable basic auth")
}
handler = &basicAuthHandler{
handler: promhttp.Handler().ServeHTTP,
user: *authUser,
password: *authPass,
}
}
http.Handle("/metrics", handler)
fmt.Printf("metrics available at http://%s/metrics\n", *flagAddress) fmt.Printf("metrics available at http://%s/metrics\n", *flagAddress)
log.Fatal(http.ListenAndServe(*flagAddress, nil)) log.Fatal(http.ListenAndServe(*flagAddress, nil))
} }