10 #include <mysql/mysql.h>
14 static char *host = NULL;
15 static char *user = NULL;
16 static char *pass = NULL;
17 static char *dbnm = "watermeter";
19 int dbconfig(char *conffile)
21 FILE *fp = fopen(conffile, "r");
27 while (fgets(buf, sizeof(buf), fp)) {
31 e = buf + strlen(buf) - 1;
32 if (*e == '\n') *e = '\0';
34 g_warning("%s:%d line too long", conffile, lc);
38 if ((k = strchr(buf, '#'))) {
42 for (k = buf; k < e && isspace(*k); k++) /*nothing*/ ;
43 for (v = k; v < e && !isspace(*v)
44 && *v != ':' && *v != '='; v++) /*nothing*/ ;
46 if (*k == '\0') continue; /* empty or comment-only line */
47 for (; v < e && (isspace(*v) || *v == ':' || *v == '=')
50 g_warning("%s:%d no value for key \"%s\"",
56 printf("k=%s v=%s\n", k, v);
58 if (!strcmp(k, "host")) host = strdup(v);
59 else if (!strcmp(k, "user")) user = strdup(v);
60 else if (!strcmp(k, "password")) pass = strdup(v);
61 else if (!strcmp(k, "database")) dbnm = strdup(v);
63 g_warning("%s:%d unrecognized key \"%s\"",
72 int dbstore(uint8_t which, uint32_t val)
80 char tstr[32], prevtstr[32];
81 char *table = (which == 1) ? "cold" : "hot";
84 uint32_t prev_val = 0;
88 (void)gmtime_r(&t, &tm);
89 (void)strftime(tstr, sizeof(tstr), "%Y-%m-%d %H:%M:%S", &tm);
91 if(!mysql_real_connect(&mysql, host, user, pass, dbnm, 0, NULL, 0)) {
92 g_warning("mysql connect error: %s\n", mysql_error(&mysql));
95 mysql_autocommit(&mysql, FALSE);
96 /* ==== Was the sensor reset since last measurement? ==== */
97 snprintf(statement, sizeof(statement),
98 "select value from %scnt order by timestamp desc limit 1;\n",
100 if ((rc = mysql_query(&mysql, statement)))
101 g_warning("mysql \"%s\" error: %s\n",
102 statement, mysql_error(&mysql));
103 else if ((result = mysql_store_result(&mysql))){
104 MYSQL_ROW row = mysql_fetch_row(result);
105 if (row && *row) prev_val = atoi(*row);
106 mysql_free_result(result);
108 if (val < prev_val) {
109 snprintf(statement, sizeof(statement),
110 "insert into %sadj values (\"%s\",%u);\n",
111 table, tstr, prev_val);
112 g_info("%s %u <= %u, %s", table, val, prev_val, statement);
113 if ((rc = mysql_query(&mysql, statement)))
114 g_warning("mysql \"%s\" error: %s\n",
115 statement, mysql_error(&mysql));
117 /* ==== Is this a part of a series of bogus events? ==== */
118 snprintf(statement, sizeof(statement),
119 "select timestamp from %scnt "
120 "where timestamp > subtime(\"%s\", \"0 0:0:10\") "
121 "order by timestamp desc;\n",
123 if ((rc = mysql_query(&mysql, statement)))
124 g_warning("mysql \"%s\" error: %s\n",
125 statement, mysql_error(&mysql));
126 else if ((result = mysql_store_result(&mysql))){
127 my_ulonglong rows = mysql_num_rows(result);
131 MYSQL_ROW row = mysql_fetch_row(result);
133 strncpy(prevtstr, *row, sizeof(prevtstr));
135 g_warning("mysql_fetch_row after \"%s\": "
136 "no result despite rows=%llu\n",
144 mysql_free_result(result);
147 snprintf(statement, sizeof(statement),
148 "insert into %sadj values (\"%s\", -1);\n",
150 g_info("%s %u at \"%s\" bogus, %s",
151 table, val, tstr, statement);
152 if ((rc = mysql_query(&mysql, statement)))
153 g_warning("mysql \"%s\" error: %s\n",
154 statement, mysql_error(&mysql));
157 snprintf(statement, sizeof(statement),
158 "insert into %sadj values (\"%s\", -1);\n",
160 g_info("previous %s at \"%s\" was bogus too, %s",
161 table, prevtstr, statement);
162 if ((rc = mysql_query(&mysql, statement)))
163 g_warning("mysql \"%s\" error: %s\n",
164 statement, mysql_error(&mysql));
166 /* ==== Update the counter table regardless ==== */
167 snprintf(statement, sizeof(statement),
168 "insert into %scnt values (\"%s\",%u);\n",
170 if ((rc = mysql_query(&mysql, statement)))
171 g_warning("mysql \"%s\" error: %s\n",
172 statement, mysql_error(&mysql));
175 if ((rc = mysql_commit(&mysql)))
176 g_warning("mysql commit error: %s\n",
177 mysql_error(&mysql));
184 int main(int const argc, char *argv[])
186 if (dbconfig(argv[1])) {
187 printf("could not parse config file\n");
190 printf("host: %s\nuser: %s\npass: %s\ndbnm: %s\n",
191 host, user, pass, dbnm);