Sat, 07 Nov 2015 22:04:17 +0100
Added a new brewpanel program that runs on an SDL/X screen. It will be an emulator for the hardware panels. Development version 0.5.0
/***************************************************************************** * Copyright (C) 2015 * * Michiel Broek <mbroek at mbse dot eu> * * This file is part of the mbsePi-apps * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * mbsePi-apps is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ThermFerm; see the file COPYING. If not, write to the Free * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *****************************************************************************/ #include "rdconfig.h" #include "brewco.h" #include "futil.h" #include "xutil.h" int debug = FALSE; sys_config Config; /* System configuration */ #define MY_ENCODING "utf-8" const char TEMPSTATE[3][8] = { "OK", "MISSING", "ERROR" }; //const char DEVTYPE[8][6] = { "NA", "W1", "GPIO", "RC433", "DHT", "I2C", "SPI", "SIM" }; //const char DEVPRESENT[4][6] = { "UNDEF", "NO", "YES", "ERROR" }; //const char DEVDIR[7][11] = { "UNDEF", "IN_BIN", "OUT_BIN", "IN_ANALOG", "OUT_ANALOG", "OUT_PWM", "INTERN" }; //const char PIDMODE[3][5] = { "NONE", "AUTO", "BOO" }; void killconfig(void) { if (Config.name) free(Config.name); Config.name = NULL; Config.tempFormat = 'C'; if (Config.hlt_sensor_address) free(Config.hlt_sensor_address); if (Config.mlt_sensor_address) free(Config.mlt_sensor_address); Config.hlt_sensor_address = Config.mlt_sensor_address = NULL; Config.hlt_sensor_value = Config.mlt_sensor_value = 20000; Config.hlt_sensor_state = Config.mlt_sensor_state = 1; // missing #ifdef HAVE_WIRINGPI_H Config.lcd_cols = 16; Config.lcd_rows = 2; #endif } int do_wrconfig(void); int do_wrconfig(void) { int rc = 0; FILE *fp; char *mypath = NULL; xmlTextWriterPtr writer; xmlBufferPtr buf; /* * Create a new XML buffer, to which the XML document will be written */ if ((buf = xmlBufferCreate()) == NULL) { syslog(LOG_NOTICE, "wrconfig: error creating the xml buffer"); return 1; } /* * Create a new XmlWriter for memory, with no compression. */ if ((writer = xmlNewTextWriterMemory(buf, 0)) == NULL) { syslog(LOG_NOTICE, "wrconfig: error creating the xml writer"); return 1; } /* * Use indentation instead of one long line */ if ((rc = xmlTextWriterSetIndent(writer, 2)) < 0) { syslog(LOG_NOTICE, "wrconfig: error setting Indent"); return 1; } /* * Start the document with the xml default for the version, * encoding ISO 8859-1 and the default for the standalone * declaration. */ if ((rc = xmlTextWriterStartDocument(writer, NULL, MY_ENCODING, NULL)) < 0) { syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterStartDocument"); return 1; } /* * Start an element named "BREWCO". Since thist is the first * element, this will be the root element of the document. */ if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "BREWCO")) < 0) { syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterStartElement"); return 1; } /* * Add an attribute with name "VERSION" and value "1" to BRWCO. */ if ((rc = xmlTextWriterWriteElement(writer, BAD_CAST "VERSION", BAD_CAST "1")) < 0) { syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement"); return 1; } if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "NAME", "%s", Config.name)) < 0) { syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); return 1; } if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "TEMPFORMAT", "%c", Config.tempFormat)) < 0) { syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); return 1; } if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_SENSOR_ADDRESS", "%s", Config.hlt_sensor_address)) < 0) { syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); return 1; } if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_SENSOR_STATE", "%d", Config.hlt_sensor_state)) < 0) { syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); return 1; } if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "HLT_SENSOR_VALUE", "%d", Config.hlt_sensor_value)) < 0) { syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); return 1; } if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_SENSOR_ADDRESS", "%s", Config.mlt_sensor_address)) < 0) { syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); return 1; } if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_SENSOR_STATE", "%d", Config.mlt_sensor_state)) < 0) { syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); return 1; } if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MLT_SENSOR_VALUE", "%d", Config.mlt_sensor_value)) < 0) { syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); return 1; } #ifdef HAVE_WIRINGPI_H /* * Start an element named "LCDS" as child of BREWCO. */ if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "LCDS")) < 0) { syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterStartElement"); return 1; } /* * Start one LCD. It is possible to connect 7 LCD displays on the i2c bus. * However this program doesn't use more then one yet. */ if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "LCD")) < 0) { syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterStartElement"); return 1; } if ((rc = xmlTextWriterWriteElement(writer, BAD_CAST "VERSION", BAD_CAST "1")) < 0) { syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement"); return 1; } if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ADDRESS", "0x%x", Config.lcd_address)) < 0) { syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); return 1; } if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "COLUMNS", "%d", Config.lcd_cols)) < 0) { syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); return 1; } if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ROWS", "%d", Config.lcd_rows)) < 0) { syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement"); return 1; } /* * Close the element named LCD. */ if ((rc = xmlTextWriterEndElement(writer)) < 0) { syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterEndElement"); return 1; } /* * Close the element LCDS. */ if ((rc = xmlTextWriterEndElement(writer)) < 0) { syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterEndElement"); return 1; } #endif /* * All done, close any open elements */ if ((rc = xmlTextWriterEndDocument(writer)) < 0) { syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterEndDocument"); return 1; } xmlFreeTextWriter(writer); /* * Now write the XML configuration */ if (getenv((char *)"USER") == NULL) { mypath = xstrcpy((char *)"/root"); } else { mypath = xstrcpy(getenv((char *)"HOME")); } mypath = xstrcat(mypath, (char *)"/.brewco/etc/"); mkdirs(mypath, 0755); mypath = xstrcat(mypath, (char *)"brewco.xml"); if (debug) fprintf(stdout, "Writing %s\n", mypath); if ((fp = fopen(mypath, "w")) == NULL) { syslog(LOG_NOTICE, "could not rewrite %s", mypath); free(mypath); return 1; } free(mypath); fprintf(fp, "%s", (const char *) buf->content); fclose(fp); xmlBufferFree(buf); return 0; } int wrconfig(void) { int rc; rc = do_wrconfig(); syslog(LOG_NOTICE, "Rewritten configuration, rc=%d", rc); return rc; } /* * Parse one LCD display */ #ifdef HAVE_WIRINGPI_H int parseLCD(xmlDocPtr doc, xmlNodePtr cur) { xmlChar *key; int ival; cur = cur->xmlChildrenNode; while (cur != NULL) { if ((!xmlStrcmp(cur->name, (const xmlChar *)"COLUMNS"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (sscanf((const char *)key, "%d", &ival) == 1) Config.lcd_cols = ival; xmlFree(key); } if ((!xmlStrcmp(cur->name, (const xmlChar *)"ROWS"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (sscanf((const char *)key, "%d", &ival) == 1) Config.lcd_rows = ival; xmlFree(key); } if ((!xmlStrcmp(cur->name, (const xmlChar *)"ADDRESS"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (sscanf((const char *)key, "%x", &ival) == 1) Config.lcd_address = ival; xmlFree(key); } cur = cur->next; } return 0; } int parseLCDs(xmlDocPtr doc, xmlNodePtr cur) { cur = cur->xmlChildrenNode; while (cur != NULL) { if ((!xmlStrcmp(cur->name, (const xmlChar *)"LCD"))) { parseLCD(doc, cur); } cur = cur->next; } return 0; } #endif int rdconfig(void) { int rc = 0; char *mypath; xmlDocPtr doc; xmlNodePtr cur; xmlChar *key; killconfig(); syslog(LOG_NOTICE, "HOME='%s' USER='%s' LOGNAME='%s'", MBSE_SS(getenv((char *)"HOME")), MBSE_SS(getenv((char *)"USER")), MBSE_SS(getenv((char *)"LOGNAME"))); /* * Search config file */ if (getenv((char *)"USER") == NULL) { mypath = xstrcpy((char *)"/root"); } else { mypath = xstrcpy(getenv((char *)"HOME")); } mypath = xstrcat(mypath, (char *)"/.brewco/etc/"); mkdirs(mypath, 0755); mypath = xstrcat(mypath, (char *)"brewco.xml"); if ((doc = xmlParseFile(mypath)) == NULL) { /* * No config file, create a fresh one */ syslog(LOG_NOTICE, "rdconfig: %s not found, creating", mypath); wrconfig(); if ((doc = xmlParseFile(mypath)) == NULL) { syslog(LOG_NOTICE, "rdconfig: could not create %s", mypath); free(mypath); return 1; } } syslog(LOG_NOTICE, "rdconfig: using %s", mypath); if ((cur = xmlDocGetRootElement(doc)) == NULL) { syslog(LOG_NOTICE, "XML file %s empty.", mypath); xmlFreeDoc(doc); return 1; } if (xmlStrcmp(cur->name, (const xmlChar*)"BREWCO")) { syslog(LOG_NOTICE, "XML file %s is not a valid configuration file.", mypath); xmlFreeDoc(doc); return 1; } /* * Parse configuration */ cur = cur->xmlChildrenNode; while (cur != NULL) { if ((!xmlStrcmp(cur->name, (const xmlChar *)"VERSION"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (xmlStrcmp(key, (const xmlChar *)"1")) { xmlFree(key); syslog(LOG_NOTICE, "XML file %s is not a valid version", mypath); return 1; } xmlFree(key); } if ((!xmlStrcmp(cur->name, (const xmlChar *)"NAME"))) { Config.name = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); } if ((!xmlStrcmp(cur->name, (const xmlChar *)"TEMPFORMAT"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); Config.tempFormat = key[0]; xmlFree(key); } if ((!xmlStrcmp(cur->name, (const xmlChar *)"HLT_SENSOR_ADDRESS"))) { Config.hlt_sensor_address = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); } if ((!xmlStrcmp(cur->name, (const xmlChar *)"MLT_SENSOR_ADDRESS"))) { Config.mlt_sensor_address = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); } #ifdef HAVE_WIRINGPI_H if ((!xmlStrcmp(cur->name, (const xmlChar *)"LCDS"))) { parseLCDs(doc, cur); } #endif cur = cur->next; } xmlFreeDoc(doc); free(mypath); mypath = NULL; return rc; }