]> mj.ucw.cz Git - home-hw.git/blob - power/cgi/power-cgi.c
Auto: Meditation mode turned off
[home-hw.git] / power / cgi / power-cgi.c
1 #include <stdio.h>
2 #include <stdarg.h>
3 #include <stdlib.h>
4 #include <syslog.h>
5 #include <modbus.h>
6
7 typedef unsigned int uint;
8
9 void die(const char *msg, ...)
10 {
11         va_list args;
12         va_start(args, msg);
13         vsyslog(LOG_ERR, msg, args);
14         // vfprintf(stderr, msg, args);
15         // fputc('\n', stderr);
16         printf("Status: 500\n");
17         printf("Content-Type: text/plain\n\n");
18         printf("Internal error, see syslog.\n");
19         exit(0);
20 }
21
22 static uint16_t reg[22];
23
24 int32_t get_s32(uint i)
25 {
26         if (reg[i+1] < 0x8000)
27                 return (reg[i+1] << 16) | reg[i];
28         else
29                 return ((reg[i+1] - 65536) * 65536) + reg[i];
30 }
31
32 int main(void)
33 {
34         openlog("power.cgi", LOG_PID, LOG_LOCAL0);
35
36         modbus_t *ctx = modbus_new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
37         if (!ctx)
38                 die("Unable to establish Modbus context");
39         modbus_set_slave(ctx, 42);
40         if (modbus_connect(ctx) < 0)
41                 die("Unable to connect to Modbus");
42
43         if (modbus_read_registers(ctx, 0, 22, reg) < 0)
44                 die("Modbus read failed");
45
46         printf("Content-type: text/plain; version=0.0.4\n\n");
47
48         printf("# HELP pm_voltage Voltage between phases and neutral [V]\n");
49         printf("# TYPE pm_voltage gauge\n");
50         printf("pm_voltage{phase=\"L1N\"} %.1f\n", get_s32(0) / 10.);
51         printf("pm_voltage{phase=\"L2N\"} %.1f\n", get_s32(2) / 10.);
52         printf("pm_voltage{phase=\"L3N\"} %.1f\n", get_s32(4) / 10.);
53
54         printf("# HELP pm_current Current through phases [A]\n");
55         printf("# TYPE pm_current gauge\n");
56         printf("pm_current{phase=\"L1\"} %.3f\n", get_s32(6) / 1000.);
57         printf("pm_current{phase=\"L2\"} %.3f\n", get_s32(8) / 1000.);
58         printf("pm_current{phase=\"L3\"} %.3f\n", get_s32(10) / 1000.);
59
60         printf("# HELP pm_power Total power [W]\n");
61         printf("# TYPE pm_power gauge\n");
62         printf("pm_power %.1f\n", get_s32(12) / 10.);
63
64         printf("# HELP pm_energy Total energy [kWh]\n");
65         printf("# TYPE pm_energy gauge\n");
66         printf("pm_energy %.1f\n", get_s32(14) / 10.);
67
68         printf("# HELP pm_reactive_power Reactive power [VAr]\n");
69         printf("# TYPE pm_reactive_power gauge\n");
70         printf("pm_reactive_power %.1f\n", get_s32(18) / 10.);
71
72         printf("# HELP pm_reactive_energy Total reactive energy [kVArh]\n");
73         printf("# TYPE pm_reactive_energy gauge\n");
74         printf("pm_reactive_energy %.1f\n", get_s32(20) / 10.);
75
76         return 0;
77 }