Sketch initial battery sensor
[khatus.git] / x5 / khatus_sensor_battery.c
CommitLineData
d03cabfe
SK
1#include <assert.h>
2#include <ctype.h>
3#include <errno.h>
4#include <fcntl.h>
5#include <limits.h>
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9#include <time.h>
10#include <unistd.h>
11
12#include "khatus_lib_log.h"
13#include "khatus_lib_time.h"
14
15#define usage(...) {print_usage(); fprintf(stderr, "Error:\n " __VA_ARGS__); exit(EXIT_FAILURE);}
16
17#define MAX_LEN 20
18#define END_OF_MESSAGE '\n'
19
20char *argv0;
21
22char path[PATH_MAX];
23
24double opt_interval = 1.0;
25char *opt_battery = "BAT0";
26char *opt_fifo = NULL;
27
28void
29print_usage()
30{
31 printf(
32 "%s: [OPT ...] FIFO\n"
33 "\n"
34 "FIFO = string # path to fifo file\n"
35 "OPT = -i int # interval\n"
36 " | -b string # battery file name from /sys/class/power_supply/\n"
37 " | -h # help message (i.e. what you're reading now :) )\n",
38 argv0);
39}
40
41void
42opt_parse(int argc, char **argv)
43{
44 char c;
45
46 while ((c = getopt(argc, argv, "f:i:h")) != -1)
47 switch (c) {
48 case 'f':
49 opt_battery = calloc(strlen(optarg), sizeof(char));
50 strcpy(opt_battery, optarg);
51 break;
52 case 'i':
53 opt_interval = atof(optarg);
54 break;
55 case 'h':
56 print_usage();
57 exit(EXIT_SUCCESS);
58 case '?':
59 if (optopt == 'f' || optopt == 'i')
60 fprintf(stderr,
61 "Option -%c requires an argument.\n",
62 optopt);
63 else if (isprint(optopt))
64 fprintf (stderr,
65 "Unknown option `-%c'.\n",
66 optopt);
67 else
68 fprintf(stderr,
69 "Unknown option character `\\x%x'.\n",
70 optopt);
71 exit(EXIT_FAILURE);
72 default:
73 assert(0);
74 }
75 opt_fifo = argv[optind];
76 debug("opt_fifo: %s\n", opt_fifo);
77 if (!opt_fifo)
78 usage("No filename was provided\n");
79}
80
81void
82loop(struct timespec *ti, char *fifo, char *buf, int fun(char *))
83{
84 int fd = -1;
85 int w = -1; /* written */
86 int r = -1; /* remaining */
87 int i = -1; /* buffer position */
88
89 for (;;) {
90 debug("openning \"%s\"\n", fifo);
91 fd = open(fifo, O_WRONLY);
92 if (fd < 0)
93 fatal("Failed to open FIFO file: \"%s\". Error: %s\n",
94 fifo,
95 strerror(errno));
96 debug("openned. fd: %d\n", fd);
97 r = fun(buf);
98 buf[r] = END_OF_MESSAGE;
99 for (i = 0; (w = write(fd, buf + i++, 1)) && r; r--)
100 ;
101 if (w < 0)
102 fatal("Failed to write to %s. Err num: %d, Err msg: %s\n",
103 fifo,
104 errno,
105 strerror(errno));
106 if (close(fd) < 0)
107 fatal("Failed to close %s. Err num: %d, Err msg: %s\n",
108 fifo,
109 errno,
110 strerror(errno));
111 fd = -1;
112 debug("closed. fd: %d\n", fd);
113 snooze(ti);
114 }
115}
116
117int
118read_capacity(char *buf)
119{
120 FILE *fp;
121 int cap;
122
123 if (!(fp = fopen(path, "r")))
124 fatal("Failed to open %s. errno: %d, msg: %s\n",
125 path, errno, strerror(errno));
126
127 switch (fscanf(fp, "%d", &cap)) {
128 case -1: fatal("EOF\n");
129 case 0: fatal("Read 0\n");
130 case 1: break;
131 default: assert(0);
132 }
133 fclose(fp);
134 return snprintf(buf, 6, "%3d%%\n", cap);
135}
136
137int
138main(int argc, char **argv)
139{
140 argv0 = argv[0];
141
142 char buf[10];
143 char *path_fmt = "/sys/class/power_supply/%s/capacity";
144 struct timespec ti = timespec_of_float(opt_interval);
145
146 opt_parse(argc, argv);
147
148 memset(path, '\0', PATH_MAX);
149 snprintf(path, PATH_MAX, path_fmt, opt_battery);
150 loop(&ti, opt_fifo, buf, &read_capacity);
151}
This page took 0.036772 seconds and 4 git commands to generate.