brewco/rdconfig.c

changeset 487
d5bc44183aa4
parent 486
5a237a99a793
child 488
bee1f70fb42b
equal deleted inserted replaced
486:5a237a99a793 487:d5bc44183aa4
1 /*****************************************************************************
2 * Copyright (C) 2015
3 *
4 * Michiel Broek <mbroek at mbse dot eu>
5 *
6 * This file is part of the mbsePi-apps
7 *
8 * This is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2, or (at your option) any
11 * later version.
12 *
13 * mbsePi-apps is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with ThermFerm; see the file COPYING. If not, write to the Free
20 * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 *****************************************************************************/
22
23 #include "rdconfig.h"
24 #include "brewco.h"
25 #include "util.h"
26 #include "xutil.h"
27
28 int debug = TRUE;
29 sys_config Config; /* System configuration */
30 extern char *etcpath;
31
32
33 #define MY_ENCODING "utf-8"
34
35 const char TEMPSTATE[3][8] = { "OK", "MISSING", "ERROR" };
36 const char DEVTYPE[6][5] = { "NA", "W1", "GPIO", "I2C", "SPI", "SIM" };
37 const char DEVPRESENT[4][6] = { "UNDEF", "NO", "YES", "ERROR" };
38 const char DEVDIR[7][11] = { "UNDEF", "IN_BIN", "OUT_BIN", "IN_ANALOG", "OUT_ANALOG", "OUT_PWM", "INTERN" };
39 const char WHIRLPOOL_TYPE[3][5] = { "OFF", "COLD", "HOT" };
40 const char PIDDIRECTION[2][8] = { "DIRECT", "REVERSE" };
41 const char PIDMODE[2][10] = { "MANUAL", "AUTOMATIC" };
42
43
44 void killconfig(void)
45 {
46 units_list *unit;
47 devices_list *device;
48
49 if (Config.name)
50 free(Config.name);
51 Config.name = NULL;
52
53 Config.my_port = 6554;
54 Config.tempFormat = 'C';
55 if (Config.roomtemp)
56 free(Config.roomtemp);
57 Config.roomtemp = NULL;
58 Config.lcd_cols = 20;
59 Config.lcd_rows = 4;
60
61 for (unit = Config.units; unit; unit = unit->next) {
62 if (unit->uuid)
63 free(unit->uuid);
64 if (unit->name)
65 free(unit->name);
66 if (unit->hlt_sensor.uuid)
67 free(unit->hlt_sensor.uuid);
68 if (unit->mlt_sensor.uuid)
69 free(unit->mlt_sensor.uuid);
70 if (unit->hlt_heater.uuid)
71 free(unit->hlt_heater.uuid);
72 if (unit->mlt_heater.uuid)
73 free(unit->mlt_heater.uuid);
74 if (unit->mlt_pump.uuid)
75 free(unit->mlt_pump.uuid);
76 if (unit->PID_hlt)
77 free(unit->PID_hlt);
78 if (unit->PID_mlt)
79 free(unit->PID_mlt);
80 free(unit);
81 }
82 Config.units = NULL;
83
84 for (device = Config.devices; device; device = device->next) {
85 if (device->uuid)
86 free(device->uuid);
87 if (device->address)
88 free(device->address);
89 if (device->description)
90 free(device->description);
91 if (device->comment)
92 free(device->comment);
93 free(device);
94 }
95 Config.devices = NULL;
96
97 #ifdef USE_SIMULATOR
98 if (Config.simulator)
99 free(Config.simulator);
100 Config.simulator = NULL;
101 #endif
102 }
103
104
105
106 int do_wrconfig(void);
107 int do_wrconfig(void)
108 {
109 int rc = 0;
110 FILE *fp;
111 char *mypath = NULL;
112 xmlTextWriterPtr writer;
113 xmlBufferPtr buf;
114 units_list *unit;
115 devices_list *device;
116
117 /*
118 * Create a new XML buffer, to which the XML document will be written
119 */
120 if ((buf = xmlBufferCreate()) == NULL) {
121 syslog(LOG_NOTICE, "wrconfig: error creating the xml buffer");
122 return 1;
123 }
124
125 /*
126 * Create a new XmlWriter for memory, with no compression.
127 */
128 if ((writer = xmlNewTextWriterMemory(buf, 0)) == NULL) {
129 syslog(LOG_NOTICE, "wrconfig: error creating the xml writer");
130 return 1;
131 }
132
133 /*
134 * Use indentation instead of one long line
135 */
136 if ((rc = xmlTextWriterSetIndent(writer, 2)) < 0) {
137 syslog(LOG_NOTICE, "wrconfig: error setting Indent");
138 return 1;
139 }
140
141 /*
142 * Start the document with the xml default for the version,
143 * encoding ISO 8859-1 and the default for the standalone
144 * declaration.
145 */
146 if ((rc = xmlTextWriterStartDocument(writer, NULL, MY_ENCODING, NULL)) < 0) {
147 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterStartDocument");
148 return 1;
149 }
150
151 /*
152 * Start an element named "BREWCO". Since thist is the first
153 * element, this will be the root element of the document.
154 */
155 if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "BREWCO")) < 0) {
156 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterStartElement");
157 return 1;
158 }
159
160 /*
161 * Add an attribute with name "VERSION" and value "1" to BRWCO.
162 */
163 if ((rc = xmlTextWriterWriteElement(writer, BAD_CAST "VERSION", BAD_CAST "1")) < 0) {
164 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
165 return 1;
166 }
167 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "NAME", "%s", Config.name)) < 0) {
168 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
169 return 1;
170 }
171 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "LISTEN_PORT", "%d", Config.my_port)) < 0) {
172 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
173 return 1;
174 }
175 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "TEMPFORMAT", "%c", Config.tempFormat)) < 0) {
176 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
177 return 1;
178 }
179 if (Config.roomtemp) {
180 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ROOMTEMP_UUID", "%s", Config.roomtemp->uuid)) < 0) {
181 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
182 return 1;
183 }
184 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ROOMTEMP_STATE", "%d", Config.roomtemp->state)) < 0) {
185 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
186 return 1;
187 }
188 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ROOMTEMP_VALUE", "%d", Config.roomtemp->value)) < 0) {
189 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
190 return 1;
191 }
192 }
193
194 /*
195 * Start an element named "LCDS" as child of BREWCO.
196 */
197 if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "LCDS")) < 0) {
198 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterStartElement");
199 return 1;
200 }
201 /*
202 * Start one LCD. It is possible to connect 7 LCD displays on the i2c bus.
203 * However this program doesn't use more then one yet.
204 */
205 if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "LCD")) < 0) {
206 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterStartElement");
207 return 1;
208 }
209 if ((rc = xmlTextWriterWriteElement(writer, BAD_CAST "VERSION", BAD_CAST "1")) < 0) {
210 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
211 return 1;
212 }
213 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ADDRESS", "0x%x", Config.lcd_address)) < 0) {
214 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
215 return 1;
216 }
217 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "COLUMNS", "%d", Config.lcd_cols)) < 0) {
218 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
219 return 1;
220 }
221 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ROWS", "%d", Config.lcd_rows)) < 0) {
222 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
223 return 1;
224 }
225 /*
226 * Close the element named LCD.
227 */
228 if ((rc = xmlTextWriterEndElement(writer)) < 0) {
229 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterEndElement");
230 return 1;
231 }
232 /*
233 * Close the element LCDS.
234 */
235 if ((rc = xmlTextWriterEndElement(writer)) < 0) {
236 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterEndElement");
237 return 1;
238 }
239
240 /*
241 * Brewsystems
242 */
243 if (Config.units) {
244 if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "BREWSYSTEMS")) < 0) {
245 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterStartElement");
246 return 1;
247 }
248 for (unit = Config.units; unit; unit = unit->next) {
249 /*
250 * Only configuration items are written, measured values and states
251 * are written to a state file.
252 */
253 if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "BREWSYSTEM")) < 0) {
254 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterStartElement");
255 return 1;
256 }
257 if ((rc = xmlTextWriterWriteElement(writer, BAD_CAST "VERSION", BAD_CAST "1")) < 0) {
258 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
259 return 1;
260 }
261 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "UUID", "%s", unit->uuid)) < 0) {
262 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
263 return 1;
264 }
265 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "NAME", "%s", unit->name)) < 0) {
266 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
267 return 1;
268 }
269 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "NUMBER", "%d", unit->number)) < 0)) {
270 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
271 return 1;
272 }
273 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ACTIVE", "%d", unit->active)) < 0)) {
274 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
275 return 1;
276 }
277
278 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_SENSOR_UUID", "%s", unit->hlt_sensor.uuid)) < 0)) {
279 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
280 return 1;
281 }
282 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_SENSOR_STATE", "%d", unit->hlt_sensor.state)) < 0)) {
283 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
284 return 1;
285 }
286 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_SENSOR_VALUE", "%d", unit->hlt_sensor.value)) < 0)) {
287 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
288 return 1;
289 }
290
291 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_HEATER_UUID", "%s", unit->hlt_heater.uuid)) < 0)) {
292 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
293 return 1;
294 }
295 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_HEATER_VALUE", "%d", unit->hlt_heater.value)) < 0)) {
296 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
297 return 1;
298 }
299 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_HEATER_DELAY", "%d", unit->hlt_heater.delay)) < 0)) {
300 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
301 return 1;
302 }
303
304 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_HEATER_MLTFIRST", "%d", unit->hlt_heater_mltfirst)) < 0)) {
305 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
306 return 1;
307 }
308
309 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_SENSOR_UUID", "%s", unit->mlt_sensor.uuid)) < 0)) {
310 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
311 return 1;
312 }
313 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_SENSOR_STATE", "%d", unit->mlt_sensor.state)) < 0)) {
314 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
315 return 1;
316 }
317 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_SENSOR_VALUE", "%d", unit->mlt_sensor.value)) < 0)) {
318 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
319 return 1;
320 }
321
322 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_HEATER_UUID", "%s", unit->mlt_heater.uuid)) < 0)) {
323 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
324 return 1;
325 }
326 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_HEATER_VALUE", "%d", unit->mlt_heater.value)) < 0)) {
327 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
328 return 1;
329 }
330 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_HEATER_DELAY", "%d", unit->mlt_heater.delay)) < 0)) {
331 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
332 return 1;
333 }
334
335 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_PUMP_UUID", "%s", unit->mlt_pump.uuid)) < 0)) {
336 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
337 return 1;
338 }
339 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_PUMP_VALUE", "%d", unit->mlt_pump.value)) < 0)) {
340 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
341 return 1;
342 }
343 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_PUMP_DELAY", "%d", unit->mlt_pump.delay)) < 0)) {
344 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
345 return 1;
346 }
347
348 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PUMP_CYCLE", "%d", unit->pump_cycle)) < 0)) {
349 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
350 return 1;
351 }
352 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PUMP_REST", "%d", unit->pump_rest)) < 0)) {
353 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
354 return 1;
355 }
356 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PUMP_PREMASH", "%d", unit->pump_premash)) < 0)) {
357 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
358 return 1;
359 }
360 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PUMP_ONMASH", "%d", unit->pump_onmash)) < 0)) {
361 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
362 return 1;
363 }
364 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PUMP_MASHOUT", "%d", unit->pump_mashout)) < 0)) {
365 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
366 return 1;
367 }
368 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PUMP_ONBOIL", "%d", unit->pump_onboil)) < 0)) {
369 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
370 return 1;
371 }
372 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PUMP_STOP", "%.3f", unit->pump_stop)) < 0)) {
373 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
374 return 1;
375 }
376 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "SKIP_ADD", "%d", unit->skip_add)) < 0)) {
377 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
378 return 1;
379 }
380 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "SKIP_REMOVE", "%d", unit->skip_remove)) < 0)) {
381 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
382 return 1;
383 }
384 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "SKIP_IODINE", "%d", unit->skip_iodine)) < 0)) {
385 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
386 return 1;
387 }
388 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "IODINE_TIME", "%d", unit->iodine_time)) < 0)) {
389 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
390 return 1;
391 }
392 if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "WHIRLPOOL", "%s", WHIRLPOOL_TYPE[unit->whirlpool])) < 0)) {
393 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
394 return 1;
395 }
396
397 if (unit->PID_hlt) {
398 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_HLT_KP", "%lf", PID_getKp(unit->PID_hlt))) < 0) {
399 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
400 return 1;
401 }
402 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_HLT_KI", "%lf", PID_getKi(unit->PID_hlt))) < 0) {
403 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
404 return 1;
405 }
406 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_HLT_KD", "%lf", PID_getKd(unit->PID_hlt))) < 0) {
407 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
408 return 1;
409 }
410 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_HLT_SAMPLETIME", "%d", PID_getSampleTime(unit->PID_hlt))) < 0) {
411 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
412 return 1;
413 }
414 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_HLT_DIRECTION", "%s", PIDDIRECTION[PID_getDirection(unit->PID_hlt)])) < 0) {
415 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
416 return 1;
417 }
418 }
419
420 if (unit->PID_mlt) {
421 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_MLT_KP", "%lf", PID_getKp(unit->PID_mlt))) < 0) {
422 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
423 return 1;
424 }
425 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_MLT_KI", "%lf", PID_getKi(unit->PID_mlt))) < 0) {
426 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
427 return 1;
428 }
429 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_MLT_KD", "%lf", PID_getKd(unit->PID_mlt))) < 0) {
430 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
431 return 1;
432 }
433 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_MLT_SAMPLETIME", "%d", PID_getSampleTime(unit->PID_mlt))) < 0) {
434 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
435 return 1;
436 }
437 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_MLT_DIRECTION", "%s", PIDDIRECTION[PID_getDirection(unit->PID_mlt)])) < 0) {
438 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
439 return 1;
440 }
441 }
442
443 if ((rc = xmlTextWriterEndElement(writer)) < 0) {
444 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterEndElement");
445 return 1;
446 }
447 }
448 if ((rc = xmlTextWriterEndElement(writer)) < 0) {
449 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterEndElement");
450 return 1;
451 }
452 }
453
454 if (Config.devices) {
455 if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "DEVICES")) < 0) {
456 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterStartElement");
457 return 1;
458 }
459 #ifdef HAVE_WIRINGPI_H
460 piLock(LOCK_DEVICES);
461 #endif
462 for (device = Config.devices; device; device = device->next) {
463 if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "DEVICE")) < 0) {
464 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterStartElement");
465 return 1;
466 }
467 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "VERSION", "%d", device->version)) < 0) {
468 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
469 return 1;
470 }
471 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "UUID", "%s", device->uuid)) < 0) {
472 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
473 return 1;
474 }
475 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "TYPE", "%s", DEVTYPE[device->type])) < 0) {
476 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
477 return 1;
478 }
479 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "DIRECTION", "%s", DEVDIR[device->direction])) < 0) {
480 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
481 return 1;
482 }
483 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "VALUE", "%d", device->value)) < 0) {
484 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
485 return 1;
486 }
487 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "OFFSET", "%d", device->offset)) < 0) {
488 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
489 return 1;
490 }
491 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PRESENT", "%s", DEVPRESENT[device->present])) < 0) {
492 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
493 return 1;
494 }
495 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ADDRESS", "%s", device->address)) < 0) {
496 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
497 return 1;
498 }
499 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "SUBDEVICE", "%d", device->subdevice)) < 0) {
500 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
501 return 1;
502 }
503 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "GPIOPIN", "%d", device->gpiopin)) < 0) {
504 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
505 return 1;
506 }
507 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "DESCRIPTION", "%s", device->description)) < 0) {
508 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
509 return 1;
510 }
511 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "INUSE", "%d", device->inuse)) < 0) {
512 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
513 return 1;
514 }
515 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "COMMENT", "%s", device->comment)) < 0) {
516 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
517 return 1;
518 }
519 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "TIMESTAMP", "%d", (int)device->timestamp)) < 0) {
520 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
521 return 1;
522 }
523 if ((rc = xmlTextWriterEndElement(writer)) < 0) {
524 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterEndElement");
525 return 1;
526 }
527 }
528 #ifdef HAVE_WIRINGPI_H
529 piUnlock(LOCK_DEVICES);
530 #endif
531
532 if ((rc = xmlTextWriterEndElement(writer)) < 0) {
533 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterEndElement");
534 return 1;
535 }
536 }
537
538 #ifdef USE_SIMULATOR
539 if (Config.simulator) {
540 if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "SIMULATOR")) < 0) {
541 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterStartElement");
542 return 1;
543 }
544 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ROOM_TEMPERATURE", "%f", Config.simulator->room_temperature)) < 0) {
545 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
546 return 1;
547 }
548 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_TEMPERATURE", "%f", Config.simulator->hlt_temperature)) < 0) {
549 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
550 return 1;
551 }
552 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_HEATER_TEMP", "%f", Config.simulator->hlt_heater_temp)) < 0) {
553 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
554 return 1;
555 }
556 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_HEATER_VOLUME", "%d", Config.simulator->hlt_heater_volume)) < 0) {
557 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
558 return 1;
559 }
560 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_HEATER_POWER", "%d", Config.simulator->hlt_heater_power)) < 0) {
561 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
562 return 1;
563 }
564 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_HEATER_STATE", "%d", Config.simulator->hlt_heater_state)) < 0) {
565 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
566 return 1;
567 }
568
569 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_TEMPERATURE", "%f", Config.simulator->mlt_temperature)) < 0) {
570 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
571 return 1;
572 }
573 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_HEATER_TEMP", "%f", Config.simulator->mlt_heater_temp)) < 0) {
574 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
575 return 1;
576 }
577 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_HEATER_VOLUME", "%d", Config.simulator->mlt_heater_volume)) < 0) {
578 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
579 return 1;
580 }
581 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_HEATER_POWER", "%d", Config.simulator->mlt_heater_power)) < 0) {
582 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
583 return 1;
584 }
585 if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_HEATER_STATE", "%d", Config.simulator->mlt_heater_state)) < 0) {
586 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
587 return 1;
588 }
589
590 if ((rc = xmlTextWriterEndElement(writer)) < 0) {
591 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterEndElement");
592 return 1;
593 }
594 }
595 #endif
596
597 /*
598 * All done, close any open elements
599 */
600 if ((rc = xmlTextWriterEndDocument(writer)) < 0) {
601 syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterEndDocument");
602 return 1;
603 }
604 xmlFreeTextWriter(writer);
605
606 /*
607 * Now write the XML configuration
608 */
609 mypath = xstrcpy(etcpath);
610 mypath = xstrcat(mypath, (char *)"brewco.xml");
611
612 if ((fp = fopen(mypath, "w")) == NULL) {
613 syslog(LOG_NOTICE, "could not rewrite %s", mypath);
614 free(mypath);
615 return 1;
616 }
617 free(mypath);
618
619 fprintf(fp, "%s", (const char *) buf->content);
620 fclose(fp);
621 xmlBufferFree(buf);
622
623 return 0;
624 }
625
626
627
628 int wrconfig(void)
629 {
630 int rc = do_wrconfig();
631 syslog(LOG_NOTICE, "Rewritten configuration, rc=%d", rc);
632 return rc;
633 }
634
635
636
637 /*
638 * Parse one LCD display
639 */
640 int parseLCD(xmlDocPtr doc, xmlNodePtr cur)
641 {
642 xmlChar *key;
643 int ival;
644
645 cur = cur->xmlChildrenNode;
646 while (cur != NULL) {
647 if ((!xmlStrcmp(cur->name, (const xmlChar *)"COLUMNS"))) {
648 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
649 if (sscanf((const char *)key, "%d", &ival) == 1)
650 Config.lcd_cols = ival;
651 xmlFree(key);
652 }
653 if ((!xmlStrcmp(cur->name, (const xmlChar *)"ROWS"))) {
654 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
655 if (sscanf((const char *)key, "%d", &ival) == 1)
656 Config.lcd_rows = ival;
657 xmlFree(key);
658 }
659 if ((!xmlStrcmp(cur->name, (const xmlChar *)"ADDRESS"))) {
660 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
661 if (sscanf((const char *)key, "%x", &ival) == 1)
662 Config.lcd_address = ival;
663 xmlFree(key);
664 }
665 cur = cur->next;
666 }
667
668 return 0;
669 }
670
671
672
673 int parseLCDs(xmlDocPtr doc, xmlNodePtr cur)
674 {
675 cur = cur->xmlChildrenNode;
676 while (cur != NULL) {
677 if ((!xmlStrcmp(cur->name, (const xmlChar *)"LCD"))) {
678 parseLCD(doc, cur);
679 }
680 cur = cur->next;
681 }
682 return 0;
683 }
684
685
686
687 /*
688 * Parse a brewsystem
689 */
690 int parseBrewsystem(xmlDocPtr doc, xmlNodePtr cur)
691 {
692 xmlChar *key;
693 int i, ival;
694 long lval;
695 float fval;
696 double kpval, kival, kdval;
697 units_list *unit, *tmp;
698
699 unit = (units_list *)malloc(sizeof(units_list));
700 unit->next = NULL;
701 unit->version = 1;
702 unit->uuid = unit->name = NULL;
703 unit->number = 0;
704 unit->active = 0;
705 unit->hlt_sensor.uuid = xstrcpy((char *)"00000000-0000-0000-0000-000000000000");
706 unit->hlt_sensor.state = 0;
707 unit->hlt_sensor.value = 0;
708 unit->mlt_sensor.uuid = xstrcpy((char *)"00000000-0000-0000-0000-000000000000");
709 unit->mlt_sensor.state = 0;
710 unit->mlt_sensor.value = 0;
711 unit->hlt_heater.uuid = xstrcpy((char *)"00000000-0000-0000-0000-000000000000");
712 unit->hlt_heater.value = 0;
713 unit->hlt_heater.delay = 0;
714 unit->mlt_heater.uuid = xstrcpy((char *)"00000000-0000-0000-0000-000000000000");
715 unit->mlt_heater.value = 0;
716 unit->mlt_heater.delay = 0;
717 unit->mlt_pump.uuid = xstrcpy((char *)"00000000-0000-0000-0000-000000000000");
718 unit->mlt_pump.value = 0;
719 unit->mlt_pump.delay = 0;
720 unit->hlt_heater_mltfirst = 0;
721 unit->pump_cycle = 7;
722 unit->pump_rest = 2;
723 unit->pump_premash = 1;
724 unit->pump_onmash = 1;
725 unit->pump_mashout = 0;
726 unit->pump_onboil = 0;
727 unit->pump_stop = 90.0;
728 unit->skip_add = 0;
729 unit->skip_remove = 0;
730 unit->skip_iodine = 0;
731 unit->iodine_time = 90;
732 unit->whirlpool = 1;
733 unit->PID_hlt = (pid_var *)malloc(sizeof(pid_var));
734 unit->PID_mlt = (pid_var *)malloc(sizeof(pid_var));
735 PID_init(unit->PID_hlt, NULL, NULL, NULL, 2, 5, 1, P_DIRECT);
736 PID_init(unit->PID_mlt, NULL, NULL, NULL, 2, 5, 1, P_DIRECT);
737
738 cur = cur->xmlChildrenNode;
739 while (cur != NULL) {
740 if ((!xmlStrcmp(cur->name, (const xmlChar *)"VERSION"))) {
741 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
742 if (xmlStrcmp(key, (const xmlChar *)"1")) {
743 xmlFree(key);
744 return 1;
745 }
746 unit->version = 1;
747 xmlFree(key);
748 }
749 if ((!xmlStrcmp(cur->name, (const xmlChar *)"UUID"))) {
750 unit->uuid = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
751 }
752 if ((!xmlStrcmp(cur->name, (const xmlChar *)"NAME"))) {
753 unit->name = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
754 }
755 if ((!xmlStrcmp(cur->name, (const xmlChar *)"NUMBER"))) {
756 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
757 if (sscanf((const char *)key, "%d", &ival) == 1)
758 unit->number = ival;
759 xmlFree(key);
760 }
761 if ((!xmlStrcmp(cur->name, (const xmlChar *)"ACTIVE"))) {
762 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
763 if (sscanf((const char *)key, "%d", &ival) == 1)
764 unit->active = ival;
765 xmlFree(key);
766 }
767
768 if ((!xmlStrcmp(cur->name, (const xmlChar *)"HLT_SENSOR_UUID"))) {
769 unit->hlt_sensor.uuid = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
770 }
771 if ((!xmlStrcmp(cur->name, (const xmlChar *)"HLT_SENSOR_STATE"))) {
772 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
773 if (sscanf((const char *)key, "%d", &ival) == 1)
774 unit->hlt_sensor.state = ival;
775 xmlFree(key);
776 }
777 if ((!xmlStrcmp(cur->name, (const xmlChar *)"HLT_SENSOR_VALUE"))) {
778 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
779 if (sscanf((const char *)key, "%d", &ival) == 1)
780 unit->hlt_sensor.value = ival;
781 xmlFree(key);
782 }
783
784 if ((!xmlStrcmp(cur->name, (const xmlChar *)"HLT_HEATER_UUID"))) {
785 unit->hlt_heater.uuid = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
786 }
787 if ((!xmlStrcmp(cur->name, (const xmlChar *)"HLT_HEATER_VALUE"))) {
788 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
789 if (sscanf((const char *)key, "%d", &ival) == 1)
790 unit->hlt_heater.value = ival;
791 xmlFree(key);
792 }
793 if ((!xmlStrcmp(cur->name, (const xmlChar *)"HLT_HEATER_DELAY"))) {
794 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
795 if (sscanf((const char *)key, "%d", &ival) == 1)
796 unit->hlt_heater.delay = ival;
797 xmlFree(key);
798 }
799
800 if ((!xmlStrcmp(cur->name, (const xmlChar *)"HLT_HEATER_MLTFIRST"))) {
801 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
802 if (sscanf((const char *)key, "%d", &ival) == 1)
803 unit->hlt_heater_mltfirst = ival;
804 xmlFree(key);
805 }
806
807 if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_SENSOR_UUID"))) {
808 unit->mlt_sensor.uuid = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
809 }
810 if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_SENSOR_STATE"))) {
811 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
812 if (sscanf((const char *)key, "%d", &ival) == 1)
813 unit->mlt_sensor.state = ival;
814 xmlFree(key);
815 }
816 if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_SENSOR_VALUE"))) {
817 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
818 if (sscanf((const char *)key, "%d", &ival) == 1)
819 unit->mlt_sensor.value = ival;
820 xmlFree(key);
821 }
822
823 if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_HEATER_UUID"))) {
824 unit->mlt_heater.uuid = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
825 }
826 if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_HEATER_VALUE"))) {
827 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
828 if (sscanf((const char *)key, "%d", &ival) == 1)
829 unit->mlt_heater.value = ival;
830 xmlFree(key);
831 }
832 if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_HEATER_DELAY"))) {
833 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
834 if (sscanf((const char *)key, "%d", &ival) == 1)
835 unit->mlt_heater.delay = ival;
836 xmlFree(key);
837 }
838
839 if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_PUMP_UUID"))) {
840 unit->mlt_pump.uuid = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
841 }
842 if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_PUMP_VALUE"))) {
843 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
844 if (sscanf((const char *)key, "%d", &ival) == 1)
845 unit->mlt_pump.value = ival;
846 xmlFree(key);
847 }
848 if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_PUMP_DELAY"))) {
849 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
850 if (sscanf((const char *)key, "%d", &ival) == 1)
851 unit->mlt_pump.delay = ival;
852 xmlFree(key);
853 }
854
855 if ((!xmlStrcmp(cur->name, (const xmlChar *)"PUMP_CYCLE"))) {
856 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
857 if (sscanf((const char *)key, "%d", &ival) == 1)
858 unit->pump_cycle = ival;
859 xmlFree(key);
860 }
861 if ((!xmlStrcmp(cur->name, (const xmlChar *)"PUMP_REST"))) {
862 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
863 if (sscanf((const char *)key, "%d", &ival) == 1)
864 unit->pump_rest = ival;
865 xmlFree(key);
866 }
867 if ((!xmlStrcmp(cur->name, (const xmlChar *)"PUMP_PREMASH"))) {
868 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
869 if (sscanf((const char *)key, "%d", &ival) == 1)
870 unit->pump_premash = ival;
871 xmlFree(key);
872 }
873 if ((!xmlStrcmp(cur->name, (const xmlChar *)"PUMP_ONMASH"))) {
874 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
875 if (sscanf((const char *)key, "%d", &ival) == 1)
876 unit->pump_onmash = ival;
877 xmlFree(key);
878 }
879 if ((!xmlStrcmp(cur->name, (const xmlChar *)"PUMP_MASHOUT "))) {
880 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
881 if (sscanf((const char *)key, "%d", &ival) == 1)
882 unit->pump_mashout = ival;
883 xmlFree(key);
884 }
885 if ((!xmlStrcmp(cur->name, (const xmlChar *)"PUMP_ONBOIL"))) {
886 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
887 if (sscanf((const char *)key, "%d", &ival) == 1)
888 unit->pump_onboil = ival;
889 xmlFree(key);
890 }
891 if ((!xmlStrcmp(cur->name, (const xmlChar *)"PUMP_STOP"))) {
892 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
893 if (sscanf((const char *)key, "%f", &fval) == 1)
894 unit->pump_stop = fval;
895 xmlFree(key);
896 }
897 if ((!xmlStrcmp(cur->name, (const xmlChar *)"SKIP_ADD"))) {
898 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
899 if (sscanf((const char *)key, "%d", &ival) == 1)
900 unit->skip_add = ival;
901 xmlFree(key);
902 }
903 if ((!xmlStrcmp(cur->name, (const xmlChar *)"SKIP_REMOVE"))) {
904 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
905 if (sscanf((const char *)key, "%d", &ival) == 1)
906 unit->skip_remove = ival;
907 xmlFree(key);
908 }
909 if ((!xmlStrcmp(cur->name, (const xmlChar *)"SKIP_IODINE"))) {
910 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
911 if (sscanf((const char *)key, "%d", &ival) == 1)
912 unit->skip_iodine = ival;
913 xmlFree(key);
914 }
915 if ((!xmlStrcmp(cur->name, (const xmlChar *)"IODINE_TIME"))) {
916 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
917 if (sscanf((const char *)key, "%d", &ival) == 1)
918 unit->iodine_time = ival;
919 xmlFree(key);
920 }
921 if ((!xmlStrcmp(cur->name, (const xmlChar *)"WHIRLPOOL"))) {
922 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
923 for (i = 0; i < 2; i++) {
924 if (! xmlStrcmp(key, (const xmlChar *)WHIRLPOOL_TYPE[i])) {
925 unit->whirlpool = i;
926 break;
927 }
928 }
929 xmlFree(key);
930 }
931
932 if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_HLT_KP"))) {
933 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
934 sscanf((const char *)key, "%lf", &kpval);
935 xmlFree(key);
936 }
937 if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_HLT_KI"))) {
938 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
939 sscanf((const char *)key, "%lf", &kival);
940 xmlFree(key);
941 }
942 if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_HLT_KD"))) {
943 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
944 sscanf((const char *)key, "%lf", &kdval);
945 xmlFree(key);
946 }
947 if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_HLT_SAMPLETIME"))) {
948 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
949 if (sscanf((const char *)key, "%ld", &lval) == 1) {
950 PID_setSampleTime(unit->PID_hlt, lval);
951 PID_setTunings(unit->PID_hlt, kpval, kival, kdval);
952 }
953 xmlFree(key);
954 }
955 if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_HLT_DIRECTION"))) {
956 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
957 for (i = 0; i < 2; i++) {
958 if (! xmlStrcmp(key, (const xmlChar *)PIDDIRECTION[i])) {
959 PID_setDirection(unit->PID_hlt, i);
960 break;
961 }
962 }
963 xmlFree(key);
964 }
965
966 if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_MLT_KP"))) {
967 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
968 sscanf((const char *)key, "%lf", &kpval);
969 xmlFree(key);
970 }
971 if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_MLT_KI"))) {
972 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
973 sscanf((const char *)key, "%lf", &kival);
974 xmlFree(key);
975 }
976 if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_MLT_KD"))) {
977 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
978 sscanf((const char *)key, "%lf", &kdval);
979 xmlFree(key);
980 }
981 if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_MLT_SAMPLETIME"))) {
982 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
983 if (sscanf((const char *)key, "%ld", &lval) == 1) {
984 PID_setSampleTime(unit->PID_mlt, lval);
985 PID_setTunings(unit->PID_mlt, kpval, kival, kdval);
986 }
987 xmlFree(key);
988 }
989 if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_MLT_DIRECTION"))) {
990 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
991 for (i = 0; i < 2; i++) {
992 if (! xmlStrcmp(key, (const xmlChar *)PIDDIRECTION[i])) {
993 PID_setDirection(unit->PID_mlt, i);
994 break;
995 }
996 }
997 xmlFree(key);
998 }
999
1000 cur = cur->next;
1001 }
1002
1003 if (Config.units == NULL) {
1004 Config.units = unit;
1005 } else {
1006 for (tmp = Config.units; tmp; tmp = tmp->next) {
1007 if (tmp->next == NULL) {
1008 tmp->next = unit;
1009 break;
1010 }
1011 }
1012 }
1013
1014 return 0;
1015 }
1016
1017
1018
1019 int parseBrewsystems(xmlDocPtr doc, xmlNodePtr cur)
1020 {
1021 cur = cur->xmlChildrenNode;
1022 while (cur != NULL) {
1023 if ((!xmlStrcmp(cur->name, (const xmlChar *)"BREWSYSTEM"))) {
1024 parseBrewsystem(doc, cur);
1025 }
1026 cur = cur->next;
1027 }
1028 return 0;
1029 }
1030
1031
1032 int parseDevice(xmlDocPtr doc, xmlNodePtr cur)
1033 {
1034 xmlChar *key;
1035 devices_list *device, *tmp;
1036 int i, ival;
1037
1038 device = (devices_list *)malloc(sizeof(devices_list));
1039 device->next = NULL;
1040 device->version = 1;
1041 device->uuid = device->address = device->description = device->comment = NULL;
1042 device->type = device->direction = device->present = device->subdevice = device->inuse = device->offset = 0;
1043 device->gpiopin = -1;
1044 device->timestamp = (time_t)0;
1045
1046 cur = cur->xmlChildrenNode;
1047 while (cur != NULL) {
1048 if ((!xmlStrcmp(cur->name, (const xmlChar *)"VERSION"))) {
1049 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1050 if (xmlStrcmp(key, (const xmlChar *)"1")) {
1051 xmlFree(key);
1052 return 1;
1053 }
1054 device->version = 1;
1055 xmlFree(key);
1056 }
1057 if ((!xmlStrcmp(cur->name, (const xmlChar *)"UUID"))) {
1058 device->uuid = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1059 }
1060 if ((!xmlStrcmp(cur->name, (const xmlChar *)"TYPE"))) {
1061 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1062 for (i = 0; i < 8; i++) {
1063 if (! xmlStrcmp(key, (const xmlChar *)DEVTYPE[i])) {
1064 device->type = i;
1065 break;
1066 }
1067 }
1068 xmlFree(key);
1069 }
1070 if ((!xmlStrcmp(cur->name, (const xmlChar *)"DIRECTION"))) {
1071 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1072 for (i = 0; i < 7; i++) {
1073 if (! xmlStrcmp(key, (const xmlChar *)DEVDIR[i])) {
1074 device->direction = i;
1075 break;
1076 }
1077 }
1078 xmlFree(key);
1079 }
1080 if ((!xmlStrcmp(cur->name, (const xmlChar *)"VALUE"))) {
1081 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1082 if (sscanf((const char *)key, "%d", &ival) == 1)
1083 device->value = ival;
1084 xmlFree(key);
1085 }
1086 if ((!xmlStrcmp(cur->name, (const xmlChar *)"OFFSET"))) {
1087 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1088 if (sscanf((const char *)key, "%d", &ival) == 1)
1089 device->offset = ival;
1090 xmlFree(key);
1091 }
1092 if ((!xmlStrcmp(cur->name, (const xmlChar *)"PRESENT"))) {
1093 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1094 for (i = 0; i < 4; i++) {
1095 if (! xmlStrcmp(key, (const xmlChar *)DEVPRESENT[i])) {
1096 device->present = i;
1097 break;
1098 }
1099 }
1100 xmlFree(key);
1101 }
1102 if ((!xmlStrcmp(cur->name, (const xmlChar *)"ADDRESS"))) {
1103 device->address = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1104 }
1105 if ((!xmlStrcmp(cur->name, (const xmlChar *)"SUBDEVICE"))) {
1106 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1107 if (sscanf((const char *)key, "%d", &ival) == 1)
1108 device->subdevice = ival;
1109 xmlFree(key);
1110 }
1111 if ((!xmlStrcmp(cur->name, (const xmlChar *)"GPIOPIN"))) {
1112 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1113 if (sscanf((const char *)key, "%d", &ival) == 1)
1114 device->gpiopin = ival;
1115 xmlFree(key);
1116 }
1117 if ((!xmlStrcmp(cur->name, (const xmlChar *)"DESCRIPTION"))) {
1118 device->description = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1119 }
1120 if ((!xmlStrcmp(cur->name, (const xmlChar *)"INUSE"))) {
1121 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1122 if (sscanf((const char *)key, "%d", &ival) == 1)
1123 device->inuse = ival;
1124 xmlFree(key);
1125 }
1126 if ((!xmlStrcmp(cur->name, (const xmlChar *)"COMMENT"))) {
1127 device->comment = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1128 }
1129 if ((!xmlStrcmp(cur->name, (const xmlChar *)"TIMESTAMP"))) {
1130 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1131 if (sscanf((const char *)key, "%d", &ival) == 1)
1132 device->timestamp = (time_t)ival;
1133 xmlFree(key);
1134 }
1135
1136 cur = cur->next;
1137 }
1138
1139 if (Config.devices == NULL) {
1140 Config.devices = device;
1141 } else {
1142 for (tmp = Config.devices; tmp; tmp = tmp->next) {
1143 if (tmp->next == NULL) {
1144 tmp->next = device;
1145 break;
1146 }
1147 }
1148 }
1149
1150 return 0;
1151 }
1152
1153
1154
1155 int parseDevices(xmlDocPtr doc, xmlNodePtr cur)
1156 {
1157 cur = cur->xmlChildrenNode;
1158 while (cur != NULL) {
1159 if ((!xmlStrcmp(cur->name, (const xmlChar *)"DEVICE"))) {
1160 parseDevice(doc, cur);
1161 }
1162 cur = cur->next;
1163 }
1164 return 0;
1165 }
1166
1167
1168
1169 #ifdef USE_SIMULATOR
1170 int parseSimulator(xmlDocPtr doc, xmlNodePtr cur)
1171 {
1172 xmlChar *key;
1173 int ival;
1174 float fval;
1175
1176 /*
1177 * First time, allocate memory and set defaults.
1178 */
1179 if (! Config.simulator) {
1180 Config.simulator = (simulator_var *)malloc(sizeof(simulator_var));
1181 Config.simulator->room_temperature = Config.simulator->hlt_temperature = Config.simulator->hlt_heater_temp = \
1182 Config.simulator->mlt_temperature = Config.simulator->mlt_heater_temp = 20.0;
1183 Config.simulator->hlt_heater_volume = Config.simulator->mlt_heater_volume = 20;
1184 Config.simulator->hlt_heater_power = Config.simulator->mlt_heater_power = 2000;
1185 Config.simulator->hlt_heater_state = Config.simulator->mlt_heater_state = 0;
1186 }
1187
1188 cur = cur->xmlChildrenNode;
1189 while (cur != NULL) {
1190 if ((!xmlStrcmp(cur->name, (const xmlChar *)"ROOM_TEMPERATURE"))) {
1191 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1192 if (sscanf((const char *)key, "%f", &fval) == 1)
1193 Config.simulator->room_temperature = fval;
1194 xmlFree(key);
1195 }
1196 if ((!xmlStrcmp(cur->name, (const xmlChar *)"HLT_TEMPERATURE"))) {
1197 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1198 if (sscanf((const char *)key, "%f", &fval) == 1)
1199 Config.simulator->hlt_temperature = fval;
1200 xmlFree(key);
1201 }
1202 if ((!xmlStrcmp(cur->name, (const xmlChar *)"HLT_HEATER_TEMP"))) {
1203 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1204 if (sscanf((const char *)key, "%f", &fval) == 1)
1205 Config.simulator->hlt_heater_temp = fval;
1206 xmlFree(key);
1207 }
1208 if ((!xmlStrcmp(cur->name, (const xmlChar *)"HLT_HEATER_VOLUME"))) {
1209 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1210 if (sscanf((const char *)key, "%d", &ival) == 1)
1211 Config.simulator->hlt_heater_volume = ival;
1212 xmlFree(key);
1213 }
1214 if ((!xmlStrcmp(cur->name, (const xmlChar *)"HLT_HEATER_POWER"))) {
1215 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1216 if (sscanf((const char *)key, "%d", &ival) == 1)
1217 Config.simulator->hlt_heater_power = ival;
1218 xmlFree(key);
1219 }
1220 if ((!xmlStrcmp(cur->name, (const xmlChar *)"HLT_HEATER_STATE"))) {
1221 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1222 if (sscanf((const char *)key, "%d", &ival) == 1)
1223 Config.simulator->hlt_heater_state = ival;
1224 xmlFree(key);
1225 }
1226 if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_TEMPERATURE"))) {
1227 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1228 if (sscanf((const char *)key, "%f", &fval) == 1)
1229 Config.simulator->mlt_temperature = fval;
1230 xmlFree(key);
1231 }
1232 if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_HEATER_TEMP"))) {
1233 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1234 if (sscanf((const char *)key, "%f", &fval) == 1)
1235 Config.simulator->mlt_heater_temp = fval;
1236 xmlFree(key);
1237 }
1238 if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_HEATER_VOLUME"))) {
1239 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1240 if (sscanf((const char *)key, "%d", &ival) == 1)
1241 Config.simulator->mlt_heater_volume = ival;
1242 xmlFree(key);
1243 }
1244 if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_HEATER_POWER"))) {
1245 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1246 if (sscanf((const char *)key, "%d", &ival) == 1)
1247 Config.simulator->mlt_heater_power = ival;
1248 xmlFree(key);
1249 }
1250 if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_HEATER_STATE"))) {
1251 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1252 if (sscanf((const char *)key, "%d", &ival) == 1)
1253 Config.simulator->mlt_heater_state = ival;
1254 xmlFree(key);
1255 }
1256 cur = cur->next;
1257 }
1258
1259 return 0;
1260 }
1261 #endif
1262
1263
1264
1265 int rdconfig(void)
1266 {
1267 int i, ival, rc = 0;
1268 char *mypath, *fpath, *tpath;
1269 xmlDocPtr doc;
1270 xmlNodePtr cur;
1271 xmlChar *key;
1272
1273 killconfig();
1274
1275 /*
1276 * Search config file
1277 */
1278 mypath = xstrcpy(etcpath);
1279 mypath = xstrcat(mypath, (char *)"brewco.xml");
1280
1281 /*
1282 * Make upto 10 backups of the configuration.
1283 */
1284 fpath = calloc(PATH_MAX, sizeof(char));
1285 tpath = calloc(PATH_MAX, sizeof(char));
1286
1287 for (i = 9; i > 0; i--) {
1288 snprintf(tpath, PATH_MAX, "%s.%d", mypath, i+1);
1289 snprintf(fpath, PATH_MAX, "%s.%d", mypath, i);
1290 if (file_exist(fpath, R_OK) == 0) {
1291 unlink(tpath);
1292 if (file_cp(fpath, tpath)) {
1293 syslog(LOG_NOTICE, "rdconfig file_cp(%s, %s): %s", fpath, tpath, strerror(errno));
1294 }
1295 }
1296 }
1297 snprintf(tpath, PATH_MAX, "%s.1", mypath);
1298 snprintf(fpath, PATH_MAX, "%s", mypath);
1299 if (file_exist(fpath, R_OK) == 0) {
1300 unlink(tpath);
1301 if (file_cp(fpath, tpath)) {
1302 syslog(LOG_NOTICE, "rdconfig file_cp(%s, %s): %s", fpath, tpath, strerror(errno));
1303 }
1304 }
1305 free(fpath);
1306 free(tpath);
1307
1308 if ((doc = xmlParseFile(mypath)) == NULL) {
1309 /*
1310 * No config file, create a fresh one
1311 */
1312 syslog(LOG_NOTICE, "rdconfig: %s not found, creating", mypath);
1313 wrconfig();
1314
1315 if ((doc = xmlParseFile(mypath)) == NULL) {
1316 syslog(LOG_NOTICE, "rdconfig: could not create %s", mypath);
1317 free(mypath);
1318 return 1;
1319 }
1320 }
1321 syslog(LOG_NOTICE, "rdconfig: using %s", mypath);
1322
1323 if ((cur = xmlDocGetRootElement(doc)) == NULL) {
1324 syslog(LOG_NOTICE, "XML file %s empty.", mypath);
1325 xmlFreeDoc(doc);
1326 return 1;
1327 }
1328 if (xmlStrcmp(cur->name, (const xmlChar*)"BREWCO")) {
1329 syslog(LOG_NOTICE, "XML file %s is not a valid configuration file.", mypath);
1330 xmlFreeDoc(doc);
1331 return 1;
1332 }
1333
1334 /*
1335 * Parse configuration
1336 */
1337 cur = cur->xmlChildrenNode;
1338 while (cur != NULL) {
1339 if ((!xmlStrcmp(cur->name, (const xmlChar *)"VERSION"))) {
1340 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1341 if (xmlStrcmp(key, (const xmlChar *)"1")) {
1342 xmlFree(key);
1343 syslog(LOG_NOTICE, "XML file %s is not a valid version", mypath);
1344 return 1;
1345 }
1346 xmlFree(key);
1347 }
1348 if ((!xmlStrcmp(cur->name, (const xmlChar *)"NAME"))) {
1349 Config.name = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1350 }
1351 if ((!xmlStrcmp(cur->name, (const xmlChar *)"LISTEN_PORT"))) {
1352 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1353 if (sscanf((const char *)key, "%d", &ival) == 1)
1354 Config.my_port = ival;
1355 xmlFree(key);
1356 }
1357 if ((!xmlStrcmp(cur->name, (const xmlChar *)"TEMPFORMAT"))) {
1358 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1359 Config.tempFormat = key[0];
1360 xmlFree(key);
1361 }
1362 if ((!xmlStrcmp(cur->name, (const xmlChar *)"ROOMTEMP_UUID"))) {
1363 if (Config.roomtemp == NULL) {
1364 Config.roomtemp = (sensor_var *)malloc(sizeof(sensor_var));
1365 Config.roomtemp->uuid[0] = '\0';
1366 Config.roomtemp->state = 1; // missing
1367 Config.roomtemp->value = 0;
1368 }
1369 snprintf(Config.roomtemp->uuid, 36, "%s", xmlNodeListGetString(doc, cur->xmlChildrenNode, 1));
1370 }
1371 if ((!xmlStrcmp(cur->name, (const xmlChar *)"LCDS"))) {
1372 parseLCDs(doc, cur);
1373 }
1374 if ((!xmlStrcmp(cur->name, (const xmlChar *)"BREWSYSTEMS"))) {
1375 parseBrewsystems(doc, cur);
1376 }
1377 if ((!xmlStrcmp(cur->name, (const xmlChar *)"DEVICES"))) {
1378 parseDevices(doc, cur);
1379 }
1380 #ifdef USE_SIMULATOR
1381 if ((!xmlStrcmp(cur->name, (const xmlChar *)"SIMULATOR"))) {
1382 parseSimulator(doc, cur);
1383 }
1384 #endif
1385 cur = cur->next;
1386 }
1387 xmlFreeDoc(doc);
1388
1389 free(mypath);
1390 mypath = NULL;
1391
1392 #ifdef USE_SIMULATOR
1393 /*
1394 * If we didn't find any simulator values, initialize a new simulator.
1395 */
1396 if (! Config.simulator) {
1397 Config.simulator = (simulator_var *)malloc(sizeof(simulator_var));
1398 syslog(LOG_NOTICE, "rdconfig() init a new simulator");
1399 Config.simulator->room_temperature = Config.simulator->hlt_temperature = Config.simulator->hlt_heater_temp = \
1400 Config.simulator->mlt_temperature = Config.simulator->mlt_heater_temp = 20.0;
1401 Config.simulator->hlt_heater_volume = Config.simulator->mlt_heater_volume = 20;
1402 Config.simulator->hlt_heater_power = Config.simulator->mlt_heater_power = 2000;
1403 Config.simulator->hlt_heater_state = Config.simulator->mlt_heater_state = 0;
1404 }
1405 #endif
1406
1407 return rc;
1408 }
1409
1410
1411

mercurial