commit f3e42189f29a591897998e30f9897539862f93cd Author: root Date: Mon Jul 22 13:44:29 2024 -0400 init diff --git a/README.md b/README.md new file mode 100644 index 0000000..3f7902b --- /dev/null +++ b/README.md @@ -0,0 +1,16 @@ +# CyberPower Exporter + +Export UPS data via HTTP for prometheus service + +## Setup + +### Prerequisites + +- [Bun](https://bun.sh) + +### Instructions + +1. Download the [PowerPanel](https://cyberpower.com/global/en/product/sku/powerpanel_for_linux#downloads) +2. Install the package: `sudo dpkg -i powerpanel.deb` +3. Install the service: +4. Start service automatically: `sudo systemctl enable power-exporter && sudo systemctl start power-exporter` diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..107b74e --- /dev/null +++ b/install.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +if [ "$UID" != "0" ]; then + echo "Please run as root" + exit 1 +fi + +# Install UPS driver +if [ -z "$(which pwrstat)" ]; then + echo "Installing Power Panel..." + dpkg -i powerpanel.deb +fi + +# Setup exporter +echo "Installing Exporter..." +cp power-exporter.js /usr/local/bin/power-exporter.js +chmod +x /usr/local/bin/power-exporter.js + +# Setup service +echo "Stting Up Service..." +cp power-exporter.service /etc/systemd/system/power-exporter.service +chmod +x /etc/systemd/system/power-exporter.service +systemctl enable power-exporter +systemctl restart power-exporter + +echo "Done!" +sleep 1 +echo "" +journalctl -u power-exporter -n 1 diff --git a/power-exporter.js b/power-exporter.js new file mode 100755 index 0000000..3d5c429 --- /dev/null +++ b/power-exporter.js @@ -0,0 +1,39 @@ +import { $ } from 'bun'; +import http from 'http'; + +const port = 3000; + +async function scrape() { + const data = await $`pwrstat -status`.text(); + const r = /^\s*(.+?)\.{3,} (.+)$/gm; + + let found, map = {}; + while(!!(found = r.exec(data))) + map[found[1]] = found[2]; + + return { + model: map["Model Name"], + vendor: map["Power Supply by"], + state: map["State"], + charge: Number(/\d+/g.exec(map["Battery Capacity"])[0]) / 100, + remaining: map["Remaining Runtime"], + rated_voltage: Number(/\d+/g.exec(map["Rating Voltage"])[0]), + rated_wattage: Number(/\d+/g.exec(map["Rating Power"])[0]), + input_voltage: Number(/\d+/g.exec(map["Utility Voltage"])[0]), + output_voltage: Number(/\d+/g.exec(map["Output Voltage"])[0]), + load_wattage: Number(/\d+/g.exec(map["Load"])[0]), + load_percentage: Number(/(\d+) %/g.exec(map["Load"])[1]) / 100, + last_test: map["Test Result"], + last_outage: map["Last Power Event"], + }; +} + +function format(a) { + return Object.entries(a).map(([key, value]) => `${key} ${typeof value == 'string' ? `"${value}"` : value}`).join('\n'); +} + +http.createServer(async (req, res) => { + res.end(format(await scrape())); +}).listen(port, () => { + console.log(`Exporter running on http://localhost:${port}`) +}); diff --git a/power-exporter.service b/power-exporter.service new file mode 100644 index 0000000..6fb67b6 --- /dev/null +++ b/power-exporter.service @@ -0,0 +1,10 @@ +[Unit] +Description=Export UPS metrics to webpage for scraping +After=network.target + +[Service] +ExecStart=/root/.bun/bin/bun /usr/local/bin/power-exporter.js +Restart=always + +[Install] +WantedBy=multi-user.target diff --git a/powerpanel.deb b/powerpanel.deb new file mode 100644 index 0000000..e4e5894 Binary files /dev/null and b/powerpanel.deb differ