From 30bb7d77fcb4083bded154bc18e3fd6f686dbc18 Mon Sep 17 00:00:00 2001 From: Alan Brenner Date: Mon, 7 Nov 2022 20:52:58 -0500 Subject: [PATCH 1/2] Add support for Tripp Lite AVR650UM. Add an OpenWRT init script. Add cross compiling for OpenWRT steps to the readme. --- README.md | 32 +++- main.go | 243 +++++++++++++++--------------- prometheus-tripplite-ups-exporter | 12 ++ 3 files changed, 165 insertions(+), 122 deletions(-) create mode 100755 prometheus-tripplite-ups-exporter diff --git a/README.md b/README.md index fbae74b..683ef0c 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,33 @@ This is a simple Prometheus exporter for Tripp Lite UPS devices that expose their properties as a USB HID device. -As of today this has only been tested on a SMART1500LCD with USB vendor ID 09AE and product ID 2012. It has only been tested on Linux (and specifically a Raspberry Pi) though it should also work on Mac and Windows thanks to the [Gopher Interface Devices](https://github.com/karalabe/hid) HID library it uses. +As of today this has only been tested on Tripp Lite devices with USB vendor ID 09AE, including a SMART1500LCD with product ID 2012, and an AVR650UM with product ID 3024. It has only been tested on Linux (a Raspberry Pi, an Intel NUC (native build), a Linksys WRT3200ACM (native build), and a VoCore2 (cross-compiled)) though it should also work on Mac and Windows thanks to the [Gopher Interface Devices](https://github.com/karalabe/hid) HID library it uses. + +## Cross Compiling + +<<<<<<< HEAD +As this is written in Go, cross-compilation is simple, and the preferred method for building when the target OS is OpenWrt Linux. For example, the command: + + GOOS=linux GOARCH=mipsle GOMIPS=softfloat go build -o tripplite-ups-export main.go + +will generate an executable suitable for running on a VoCore2 running OpenWRT 22.03. See https://go.dev/doc/install/source#environment for the list of valid combinations and additional CPU specific options (like GOMIPS as above). +======= +As this is written in Go, cross-compilation is logically simple, and the preferred method for building when the target OS is OpenWrt Linux. However, the C package used to access USB devices has to be compiled for the target platform, otherwise the UPS will never be detected. For OpenWrt, set up a toolchain as described in https://openwrt.org/docs/guide-developer/toolchain/use-buildsystem up to making the kernel_menuconfig. This will generate the staging_dir with the needed gcc compiler. + +The OpenWrt `git clone` directory as used below is `$HOME/Source/External/openwrt`, so update the export line as needed to point the directory used and the toolchain version. The below: + + export STAGING_DIR=$HOME/Source/External/openwrt/staging_dir/toolchain-mipsel_24kc_gcc-11.2.0_musl + CGO_ENABLED=1 CC=$STAGING_DIR/bin/mipsel-openwrt-linux-musl-gcc GOOS=linux GOARCH=mipsle GOMIPS=softfloat go get -a -ldflags '-w' github.com/karalabe/hid + CGO_ENABLED=1 CC=$STAGING_DIR/bin/mipsel-openwrt-linux-musl-gcc GOOS=linux GOARCH=mipsle GOMIPS=softfloat go build -a -ldflags '-w -extldflags -static' -o tripplite-ups-exporter-mipsel main.go + +will generate a static executable suitable for running on a VoCore2 running OpenWRT 22.03. The below generates a static executable suitable for running on a Linksys WRT3200ACM, also running running OpenWRT. + + export STAGING_DIR=$HOME/Source/External/openwrt/staging_dir/toolchain-arm_cortex-a9+vfpv3-d16_gcc-11.2.0_musl_eabi + CGO_ENABLED=1 CC=$STAGING_DIR/bin/arm-openwrt-linux-muslgnueabi-gcc GOOS=linux GOARCH=arm go get -a -ldflags '-w' github.com/karalabe/hid + CGO_ENABLED=1 CC=$STAGING_DIR/bin/arm-openwrt-linux-muslgnueabi-gcc GOOS=linux GOARCH=arm go build -a -ldflags '-w -extldflags -static' -o tripplite-ups-exporter-arm7 main.go + +See https://go.dev/doc/install/source#environment for the list of valid combinations and additional CPU specific options (like GOMIPS as above). +>>>>>>> 59c3939 (Added support for Tripp Lite AVR650UM. Added an OpenWRT startup script. Added Cross Compiling to the README.md for OpenWRT builds.) ## Installing @@ -26,6 +52,10 @@ Then you can run the service: By default the exporter will listen on port 9528. This can be changed with the `-addr` flag. +### OpenWRT init script + +The prometheus-tripplite-ups-exporter script goes in /etc/init.d on OpenWRT to enable automatic startup on boot. The script expects the appropriate binary at /usr/bin/prometheus-tripplite-ups-exporter. + ## Contributing Issues and pull requests are welcome. When filing a PR, please make sure the code has been run through `gofmt`. diff --git a/main.go b/main.go index fda30a5..9c9a28c 100644 --- a/main.go +++ b/main.go @@ -1,147 +1,148 @@ package main import ( - "flag" - "fmt" - "io" - "net/http" - "os" - "time" - - "github.com/karalabe/hid" -) - -const ( - vendorID = 0x09ae - productID = 0x2012 + "flag" + "fmt" + "io" + "net/http" + "os" + "time" + + "github.com/karalabe/hid" ) type formatFunc func(data []byte, d *hid.Device, name string, w io.Writer) type feature struct { - name string - reportID byte - length int - format formatFunc + name string + reportID byte + length int + format formatFunc } func intFormatter(data []byte, d *hid.Device, name string, w io.Writer) { - var v uint64 - for i, b := range data { - v |= uint64(b) << (8 * i) - } + var v uint64 + for i, b := range data { + v |= uint64(b) << (8 * i) + } - fmt.Fprintf(w, "# TYPE %s gauge\n", name) - fmt.Fprintf(w, "%s{path=\"%s\",product=\"%s\"} %d\n", name, d.Path, d.Product, v) + fmt.Fprintf(w, "# TYPE %s gauge\n", name) + fmt.Fprintf(w, "%s{path=\"%s\",product=\"%s\"} %d\n", name, d.Path, d.Product, v) } func oneTenthFloatFormatter(data []byte, d *hid.Device, name string, w io.Writer) { - var v uint64 - for i, b := range data { - v |= uint64(b) << (8 * i) - } - - fmt.Fprintf(w, "# TYPE %s gauge\n", name) - fmt.Fprintf(w, "%s{path=\"%s\",product=\"%s\"} %f\n", name, d.Path, d.Product, float64(v)/10.0) + var v uint64 + for i, b := range data { + v |= uint64(b) << (8 * i) + } + fmt.Fprintf(w, "# TYPE %s gauge\n", name) + fmt.Fprintf(w, "%s{path=\"%s\",product=\"%s\"} %f\n", name, d.Path, d.Product, float64(v)/10.0) } func statusFormatter(data []byte, d *hid.Device, name string, w io.Writer) { - bitOn := func(b byte, i int) int { - if b&(1< Date: Thu, 10 Nov 2022 13:47:18 -0500 Subject: [PATCH 2/2] add another tested UPS; remove merge issue --- README.md | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/README.md b/README.md index 683ef0c..60bf0f0 100644 --- a/README.md +++ b/README.md @@ -2,17 +2,10 @@ This is a simple Prometheus exporter for Tripp Lite UPS devices that expose their properties as a USB HID device. -As of today this has only been tested on Tripp Lite devices with USB vendor ID 09AE, including a SMART1500LCD with product ID 2012, and an AVR650UM with product ID 3024. It has only been tested on Linux (a Raspberry Pi, an Intel NUC (native build), a Linksys WRT3200ACM (native build), and a VoCore2 (cross-compiled)) though it should also work on Mac and Windows thanks to the [Gopher Interface Devices](https://github.com/karalabe/hid) HID library it uses. +As of today this has only been tested on Tripp Lite devices with USB vendor ID 09AE, including a SMART1500LCD with product ID 2012, an AVR900U and an AVR650UM, both with product ID 3024. It has only been tested on Linux (a Raspberry Pi, an Intel NUC (native build), a Linksys WRT3200ACM (native build), and a VoCore2 (cross-compiled)) though it should also work on Mac and Windows thanks to the [Gopher Interface Devices](https://github.com/karalabe/hid) HID library it uses. ## Cross Compiling -<<<<<<< HEAD -As this is written in Go, cross-compilation is simple, and the preferred method for building when the target OS is OpenWrt Linux. For example, the command: - - GOOS=linux GOARCH=mipsle GOMIPS=softfloat go build -o tripplite-ups-export main.go - -will generate an executable suitable for running on a VoCore2 running OpenWRT 22.03. See https://go.dev/doc/install/source#environment for the list of valid combinations and additional CPU specific options (like GOMIPS as above). -======= As this is written in Go, cross-compilation is logically simple, and the preferred method for building when the target OS is OpenWrt Linux. However, the C package used to access USB devices has to be compiled for the target platform, otherwise the UPS will never be detected. For OpenWrt, set up a toolchain as described in https://openwrt.org/docs/guide-developer/toolchain/use-buildsystem up to making the kernel_menuconfig. This will generate the staging_dir with the needed gcc compiler. The OpenWrt `git clone` directory as used below is `$HOME/Source/External/openwrt`, so update the export line as needed to point the directory used and the toolchain version. The below: @@ -28,7 +21,6 @@ will generate a static executable suitable for running on a VoCore2 running Open CGO_ENABLED=1 CC=$STAGING_DIR/bin/arm-openwrt-linux-muslgnueabi-gcc GOOS=linux GOARCH=arm go build -a -ldflags '-w -extldflags -static' -o tripplite-ups-exporter-arm7 main.go See https://go.dev/doc/install/source#environment for the list of valid combinations and additional CPU specific options (like GOMIPS as above). ->>>>>>> 59c3939 (Added support for Tripp Lite AVR650UM. Added an OpenWRT startup script. Added Cross Compiling to the README.md for OpenWRT builds.) ## Installing