From d27800981133650880db7159e5c95123c462b463 Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Sat, 11 Aug 2018 13:16:41 +0200 Subject: [PATCH] Power: CGI for Prometheus --- power/Makefile | 21 +++++++++++++ power/power-cgi.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 power/Makefile create mode 100644 power/power-cgi.c diff --git a/power/Makefile b/power/Makefile new file mode 100644 index 0000000..973d6e6 --- /dev/null +++ b/power/Makefile @@ -0,0 +1,21 @@ +TOPDIR=/root/turris + +include $(TOPDIR)/rules.mk +include $(TOPDIR)/include/package.mk + +PC := PATH=$(STAGING_DIR_HOST)/bin:$(PATH) PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) PKG_CONFIG_LIBDIR=$(PKG_CONFIG_PATH) STAGING_PREFIX=$(STAGING_DIR)/usr $(PKG_CONFIG) +MB_CFLAGS := $(shell $(PC) --cflags libmodbus) +MB_LDFLAGS := $(shell $(PC) --libs libmodbus) + +export PATH=$(TARGET_PATH_PKG) +CC=$(TARGET_CC_NOCACHE) +LD=$(TARGET_LD_NOCACHE) +CFLAGS=$(TARGET_CFLAGS) $(MB_CFLAGS) -std=gnu99 +LDFLAGS=$(TARGET_LDFLAGS) $(MB_LDFLAGS) + +all: power-cgi upload + +power-cgi: power-cgi.c + +upload: + rsync -av power-cgi micac:/www/burrow/power.cgi diff --git a/power/power-cgi.c b/power/power-cgi.c new file mode 100644 index 0000000..ac0f361 --- /dev/null +++ b/power/power-cgi.c @@ -0,0 +1,77 @@ +#include +#include +#include +#include +#include + +typedef unsigned int uint; + +void die(const char *msg, ...) +{ + va_list args; + va_start(args, msg); + vsyslog(LOG_ERR, msg, args); + // vfprintf(stderr, msg, args); + // fputc('\n', stderr); + printf("Status: 500\n"); + printf("Content-Type: text/plain\n\n"); + printf("Internal error, see syslog.\n"); + exit(0); +} + +static uint16_t reg[22]; + +int32_t get_s32(uint i) +{ + if (reg[i+1] < 0x8000) + return (reg[i+1] << 16) | reg[i]; + else + return ((reg[i+1] - 65536) * 65536) + reg[i]; +} + +int main(void) +{ + openlog("power.cgi", LOG_PID, LOG_LOCAL0); + + modbus_t *ctx = modbus_new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1); + if (!ctx) + die("Unable to establish Modbus context"); + modbus_set_slave(ctx, 42); + if (modbus_connect(ctx) < 0) + die("Unable to connect to Modbus"); + + if (modbus_read_registers(ctx, 0, 22, reg) < 0) + die("Modbus read failed"); + + printf("Content-type: text/plain; version=0.0.4\n\n"); + + printf("# HELP pm_voltage Voltage between phases and neutral [V]\n"); + printf("# TYPE pm_voltage gauge\n"); + printf("pm_voltage{phase=\"L1N\"} %.1f\n", get_s32(0) / 10.); + printf("pm_voltage{phase=\"L2N\"} %.1f\n", get_s32(2) / 10.); + printf("pm_voltage{phase=\"L3N\"} %.1f\n", get_s32(4) / 10.); + + printf("# HELP pm_current Current through phases [A]\n"); + printf("# TYPE pm_current gauge\n"); + printf("pm_current{phase=\"L1\"} %.3f\n", get_s32(6) / 1000.); + printf("pm_current{phase=\"L2\"} %.3f\n", get_s32(8) / 1000.); + printf("pm_current{phase=\"L3\"} %.3f\n", get_s32(10) / 1000.); + + printf("# HELP pm_power Total power [W]\n"); + printf("# TYPE pm_power gauge\n"); + printf("pm_power %.1f\n", get_s32(12) / 10.); + + printf("# HELP pm_energy Total energy [kWh]\n"); + printf("# TYPE pm_energy gauge\n"); + printf("pm_energy %.1f\n", get_s32(14) / 10.); + + printf("# HELP pm_reactive_power Reactive power [VAr]\n"); + printf("# TYPE pm_reactive_power gauge\n"); + printf("pm_reactive_power %.1f\n", get_s32(18) / 10.); + + printf("# HELP pm_reactive_energy Total reactive energy [kVArh]\n"); + printf("# TYPE pm_reactive_energy gauge\n"); + printf("pm_reactive_energy %.1f\n", get_s32(20) / 10.); + + return 0; +} -- 2.39.2