# HG changeset patch # User Michiel Broek # Date 1531658347 -7200 # Node ID 6d139c21e22c49e9427feaf8dbea44e7b5026dbf # Parent 4eebab50993e7f642fef254e93fbebf0dd2e3581 Versie 0.6.6. Subprojecten mash, rc433 en dht11 verwijderd. diff -r 4eebab50993e -r 6d139c21e22c configure --- a/configure Sun Jul 15 14:08:19 2018 +0200 +++ b/configure Sun Jul 15 14:39:07 2018 +0200 @@ -2031,11 +2031,11 @@ ac_config_headers="$ac_config_headers config.h" -SUBDIRS="dht11 rc433 thermferm brewpanel" +SUBDIRS="thermferm brewpanel" PACKAGE="mbsePi-apps" -VERSION="0.6.5" +VERSION="0.6.6" COPYRIGHT="Copyright (C) 2014-2018 Michiel Broek, All Rights Reserved" CYEARS="2014-2018" diff -r 4eebab50993e -r 6d139c21e22c configure.ac --- a/configure.ac Sun Jul 15 14:08:19 2018 +0200 +++ b/configure.ac Sun Jul 15 14:39:07 2018 +0200 @@ -2,13 +2,13 @@ AC_INIT(thermferm/thermferm.c) AM_CONFIG_HEADER(config.h) -SUBDIRS="dht11 rc433 thermferm brewpanel" +SUBDIRS="thermferm brewpanel" AC_SUBST(SUBDIRS) dnl General settings dnl After changeing the version number, run autoconf! PACKAGE="mbsePi-apps" -VERSION="0.6.5" +VERSION="0.6.6" COPYRIGHT="Copyright (C) 2014-2018 Michiel Broek, All Rights Reserved" CYEARS="2014-2018" AC_SUBST(PACKAGE) diff -r 4eebab50993e -r 6d139c21e22c dht11/Makefile --- a/dht11/Makefile Sun Jul 15 14:08:19 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -# Makefile for the mbsePi-apps/thermometers. - -include ../Makefile.global - -SRCS = dht11.c -HDRS = dht11.h -OBJS = dht11.o -TARGET = dht11 -OTHER = Makefile - -############################################################################# - -.c.o: - ${CC} ${CFLAGS} ${INCLUDES} ${DEFINES} -c $< - -all: ${TARGET} - -dht11: dht11.o ${SLIBS} - ${CC} -o dht11 dht11.o ${LDFLAGS} ${LIBS} ${SLIBS} - -clean: - rm -f ${TARGET} *.o *.h~ *.c~ core filelist Makefile.bak - -install: all - ${INSTALL} -c -s -g root -o root -m 0755 ${TARGET} ${BINDIR} - -filelist: Makefile - BASE=`pwd`; \ - BASE=`basename $${BASE}`; \ - (for f in ${SRCS} ${HDRS} ${OTHER} ;do echo ${PACKAGE}-${VERSION}/$${BASE}/$$f; done) >filelist - -depend: - @rm -f Makefile.bak; \ - mv Makefile Makefile.bak; \ - sed -e '/^# DO NOT DELETE/,$$d' Makefile.bak >Makefile; \ - ${ECHO} '# DO NOT DELETE THIS LINE - MAKE DEPEND RELIES ON IT' \ - >>Makefile; \ - ${ECHO} '# Dependencies generated by make depend' >>Makefile; \ - for f in ${SRCS}; \ - do \ - ${ECHO} "Dependencies for $$f:\c"; \ - ${ECHO} "`basename $$f .c`.o:\c" >>Makefile; \ - for h in `sed -n -e \ - 's/^#[ ]*include[ ]*"\([^"]*\)".*/\1/p' $$f`; \ - do \ - ${ECHO} " $$h\c"; \ - ${ECHO} " $$h\c" >>Makefile; \ - done; \ - ${ECHO} " done."; \ - ${ECHO} "" >>Makefile; \ - done; \ - ${ECHO} '# End of generated dependencies' >>Makefile - -# DO NOT DELETE THIS LINE - MAKE DEPEND RELIES ON IT -# Dependencies generated by make depend -dht11.o: ../config.h dht11.h -# End of generated dependencies diff -r 4eebab50993e -r 6d139c21e22c dht11/dht11.c --- a/dht11/dht11.c Sun Jul 15 14:08:19 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,201 +0,0 @@ -/***************************************************************************** - * Copyright (C) 2014 - * - * Michiel Broek - * - * 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 EC-65K; see the file COPYING. If not, write to the Free - * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - *****************************************************************************/ - -#include "../config.h" -#include -#include -#include -#include -#include -#include - -#include "dht11.h" - -#ifdef HAVE_WIRINGPI_H -#include - -#define MAXTIMINGS 100 - -int dht11_pin = -1; -int dht11_temperature = -1; -int dht11_humidity = -1; -int dht11_valid = FALSE; -int dht11_t_offset = 0; -int dht11_h_offset = 0; - - - -static uint8_t sizecvt(const int read_value) { - /* - * digitalRead() and friends from wiringpi are defined as returning a value - * < 256. However, they are returned as int() types. This is a safety function - */ - if (read_value > 255 || read_value < 0) { - syslog(LOG_NOTICE, "invalid data from wiringPi library"); - } - - return (uint8_t)read_value; -} - - - -/* - * DHT11 sensor read. This should be used in a thread loop. - */ -void dht11Read(void) { - int tries = 5; - unsigned short got_correct_data = 0; - - if (dht11_pin == -1) - return; - - while (tries && !got_correct_data) { - uint8_t laststate = HIGH; - uint8_t counter = 0; - uint8_t j = 0, i = 0; - int dht11_dat[5] = {0,0,0,0,0}; - - /* - * Select output mode to send the start signal. - */ - pinMode(dht11_pin, OUTPUT); - digitalWrite(dht11_pin, HIGH); - usleep(1000); - - /* - * Low for at least 18 milliseconds - */ - digitalWrite(dht11_pin, LOW); - usleep(20000); - digitalWrite(dht11_pin, HIGH); - pinMode(dht11_pin, INPUT); - - /* - * Detect change and read data - */ - for (i=0; i= 4) && (i%2 == 0)) { - - // shove each bit into the storage bytes - dht11_dat[(int)((double)j/8)] <<= 1; - if (counter > 16) - dht11_dat[(int)((double)j/8)] |= 1; - j++; - } - } - - /* - * If there is no sensor, j = 0 - */ - if ((counter == 255) && (j == 0)) { - if (dht11_temperature != -1) { - syslog(LOG_NOTICE, "dht11 sensor disappeared"); - } else { - syslog(LOG_NOTICE, "dht11 sensor not present"); - } - dht11_temperature = -1; - dht11_humidity = -1; - dht11_valid = FALSE; - return; - } - - /* - * check we read 40 bits (8bit x 5 ) + verify checksum in the last byte - * print it out if data is good - */ - if ((j >= 40) && (dht11_dat[4] == ((dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xFF))) { - got_correct_data = 1; - - int h = dht11_dat[0] + dht11_dat[1]; - int t = (dht11_dat[2] & 0x7F) + dht11_dat[3]; - t += dht11_t_offset; - h += dht11_h_offset; - - if ((dht11_dat[2] & 0x80) != 0) - t *= -1; - - dht11_temperature = t; - dht11_humidity = h; - dht11_valid = TRUE; - } else { - tries--; - if (tries == 0) - syslog(LOG_INFO, "dht11 data checksum was wrong 5 times"); - usleep(100000); - } - } -} - - - -void dht11Init(int pin, int t_offset, int h_offset) { - dht11_pin = pin; - dht11_t_offset = t_offset; - dht11_h_offset = h_offset; -} - - - -int main(int argc, char *argv[]) { - - int PIN = 3; - - if (wiringPiSetup() == -1) - return 0; - - dht11Init(PIN, 1, 6); - dht11Read(); - if (dht11_valid) { - fprintf(stdout, "DHT11: temperature %d degrees, humidity %d%%\n", dht11_temperature, dht11_humidity); - } else { - fprintf(stdout, "DHT11: no valid data or sensor not connected\n"); - } - - exit(0); -} - -#else - -int main(int argc, char *argv[]) { - fprintf(stderr, "This program does nothing without the wiringPi library\n"); - return 0; -} - -#endif - diff -r 4eebab50993e -r 6d139c21e22c dht11/dht11.h --- a/dht11/dht11.h Sun Jul 15 14:08:19 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -#ifndef _DHT11_H -#define _DHT11_H - - -#define TRUE 1 -#define FALSE 0 - - -#endif diff -r 4eebab50993e -r 6d139c21e22c mash/Makefile --- a/mash/Makefile Sun Jul 15 14:08:19 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -# Makefile for the mbsePi-apps/thermferm. - -include ../Makefile.global - -SRCS = $(wildcard *.c) -HDRS = $(wildcard *.h) -OBJS = $(SRCS:.c=.o) -SLIBS = -lpthread -TARGET = mash -OTHER = Makefile - -############################################################################# - -.c.o: - ${CC} ${CFLAGS} ${INCLUDES} ${DEFINES} -c $< - -all: ${TARGET} - -mash: ${OBJS} ${SLIBS} - ${CC} -o mash ${OBJS} ${LDFLAGS} ${LIBS} ${SLIBS} - -clean: - rm -f ${TARGET} *.o *.h~ *.c~ core filelist Makefile.bak - -install: all - ${INSTALL} -c -s -g root -o root -m 0755 mash ${BINDIR} - -filelist: Makefile - BASE=`pwd`; \ - BASE=`basename $${BASE}`; \ - (for f in ${SRCS} ${HDRS} ${OTHER} ;do echo ${PACKAGE}-${VERSION}/$${BASE}/$$f; done) >filelist - -depend: - @rm -f Makefile.bak; \ - mv Makefile Makefile.bak; \ - sed -e '/^# DO NOT DELETE/,$$d' Makefile.bak >Makefile; \ - ${ECHO} '# DO NOT DELETE THIS LINE - MAKE DEPEND RELIES ON IT' \ - >>Makefile; \ - ${ECHO} '# Dependencies generated by make depend' >>Makefile; \ - for f in ${SRCS}; \ - do \ - ${ECHO} "Dependencies for $$f:\c"; \ - ${ECHO} "`basename $$f .c`.o:\c" >>Makefile; \ - for h in `sed -n -e \ - 's/^#[ ]*include[ ]*"\([^"]*\)".*/\1/p' $$f`; \ - do \ - ${ECHO} " $$h\c"; \ - ${ECHO} " $$h\c" >>Makefile; \ - done; \ - ${ECHO} " done."; \ - ${ECHO} "" >>Makefile; \ - done; \ - ${ECHO} '# End of generated dependencies' >>Makefile - -# DO NOT DELETE THIS LINE - MAKE DEPEND RELIES ON IT -# Dependencies generated by make depend -sensors.o: mash.h xutil.h -lock.o: mash.h lock.h -beerxml.o: mash.h beerxml.h -lcd-pcf8574.o: mash.h lcd-pcf8574.h -mash.o: mash.h lock.h logger.h xutil.h beerxml.h lcd-pcf8574.h sensors.h -xutil.o: mash.h xutil.h -rdconfig.o: mash.h xutil.h -logger.o: mash.h xutil.h logger.h -# End of generated dependencies diff -r 4eebab50993e -r 6d139c21e22c mash/beerxml.c --- a/mash/beerxml.c Sun Jul 15 14:08:19 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1531 +0,0 @@ -/***************************************************************************** - * Copyright (C) 2014 - * - * Michiel Broek - * - * 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 EC-65K; see the file COPYING. If not, write to the Free - * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - *****************************************************************************/ - -#include "mash.h" -#include "beerxml.h" - - -recipe_rec *recipes = NULL; - - -int parseStyle(xmlDocPtr, xmlNodePtr, style_rec **); -int parseEquipment(xmlDocPtr, xmlNodePtr, equipment_rec **); -int parseMashStep(xmlDocPtr, xmlNodePtr, mash_step **); -int parseMashSteps(xmlDocPtr, xmlNodePtr, mash_step **); -int parseMash(xmlDocPtr, xmlNodePtr, mash_profile **); -int parseFermentable(xmlDocPtr, xmlNodePtr, fermentable_rec **); -int parseFermentables(xmlDocPtr, xmlNodePtr, fermentable_rec **); - - - - -/* - * Parse style - */ -int parseStyle(xmlDocPtr doc, xmlNodePtr cur, style_rec **style) -{ - xmlChar *key; - style_rec *item; - float val; - - item = (style_rec *)malloc(sizeof(style_rec)); - item->name = item->category = item->category_number = item->style_letter = item-> style_guide = - item->type = item->notes = item->profile = item->ingredients = item->examples = NULL; - item->og_min = item->og_max = item->fg_min = item->fg_max = item->ibu_min = item->ibu_max = - item->color_min = item->color_max = item->carb_min = item->carb_max = - item->abv_min = item->abv_max = 0.0; - - 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); - return 1; - } - item->version = 1; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"NAME"))) { - item->name = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"CATEGORY"))) { - item->category = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"CATEGORY_NUMBER"))) { - item->category_number = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"STYLE_LETTER"))) { - item->style_letter = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"STYLE_GUIDE"))) { - item->style_guide = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"TYPE"))) { - item->type = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"OG_MIN"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->og_min = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"OG_MAX"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->og_max = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"FG_MIN"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->fg_min = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"FG_MAX"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->fg_max = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"IBU_MIN"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->ibu_min = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"IBU_MAX"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->ibu_max = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"COLOR_MIN"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->color_min = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"COLOR_MAX"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->color_max = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"CARB_MIN"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->carb_min = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"CARB_MAX"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->carb_max = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"ABV_MIN"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->abv_min = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"ABV_MAX"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->abv_max = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"NOTES"))) { - item->notes = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"PROFILE"))) { - item->profile = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"INGREDIENTS"))) { - item->ingredients = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"EXAMPLES"))) { - item->examples = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - cur = cur->next; - } - - *style = item; - return 0; -} - - - -/* - * Parse equipment - */ -int parseEquipment(xmlDocPtr doc, xmlNodePtr cur, equipment_rec **equipment) -{ - xmlChar *key; - equipment_rec *item; - float val; - - item = (equipment_rec *)malloc(sizeof(equipment_rec)); - item->name = item->notes = NULL; - item->version = 0; - item->boil_size = item->batch_size = item->tun_volume = item->tun_weight = - item->tun_specific_heat = item->top_up_water = item->trub_chiller_loss = - item->evap_rate = item->boil_time = item->lauter_deadspace = - item->top_up_kettle = item->hop_utilization = 0.0; - item->calc_boil_volume = FALSE; - - 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); - return 1; - } - xmlFree(key); - item->version = 1; - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"NAME"))) { - item->name = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"BOIL_SIZE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->boil_size = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"BATCH_SIZE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->batch_size = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"TUN_VOLUME"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->tun_volume = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"TUN_WEIGHT"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->tun_weight = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"TUN_SPECIFIC_HEAT"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->tun_specific_heat = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"TOP_UP_WATER"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->top_up_water = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"TRUB_CHILLER_LOSS"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->trub_chiller_loss = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"EVAP_RATE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->evap_rate = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"BOIL_TIME"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->boil_time = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"CALC_BOIL_VOLUME"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (! xmlStrcmp(key, (const xmlChar *)"TRUE")) - item->calc_boil_volume = TRUE; - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"LAUTER_DEADSPACE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->lauter_deadspace = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"HOP_UTILIZATION"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->hop_utilization = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"NOTES"))) { - item->notes = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - cur = cur->next; - } - - *equipment = item; - return 0; -} - - - -/* - * Parse a Mash step and add it to the linked list - */ -int parseMashStep(xmlDocPtr doc, xmlNodePtr cur, mash_step **mashstep) -{ - xmlChar *key; - mash_step *step, *tmp; - float val; - - cur = cur->xmlChildrenNode; - - step = (mash_step *)malloc(sizeof(mash_step)); - step->next = NULL; - step->name = NULL; - step->type = NULL; - step->infuse_amount = 0.0; - step->step_temp = 0.0; - step->end_temp = 0.0; - step->step_time = 0.0; - step->ramp_time = 0.0; - step->version = 0; - - while (cur != NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"VERSION"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (xmlStrcmp(key, (const xmlChar *)"1")) { - xmlFree(key); - return 1; - } - step->version = 1; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"NAME"))) { - step->name = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"TYPE"))) { - step->type = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"INFUSE_AMOUNT"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - step->infuse_amount = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"STEP_TEMP"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - step->step_temp = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"STEP_TIME"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - step->step_time = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"END_TEMP"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - step->end_temp = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"RAMP_TIME"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - step->ramp_time = val; - xmlFree(key); - } - - cur = cur->next; - } - - if (*mashstep == NULL) { - *mashstep = step; - } else { - for (tmp = *mashstep; tmp; tmp = tmp->next) { - if (tmp->next == NULL) { - tmp->next = step; - break; - } - } - } - return 0; -} - - - -/* - * Parse all Mash steps - */ -int parseMashSteps(xmlDocPtr doc, xmlNodePtr cur, mash_step **step) -{ - int rc; - - cur = cur->xmlChildrenNode; - while (cur != NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"MASH_STEP"))) { - if ((rc = parseMashStep(doc, cur, step))) - return 1; - } - cur = cur->next; - } - return 0; -} - - - -/* - * Parse Mash profile - */ -int parseMash(xmlDocPtr doc, xmlNodePtr cur, mash_profile **mash) -{ - xmlChar *key; - mash_profile *mashprofile; - float val; - - mashprofile = (mash_profile *)malloc(sizeof(mash_profile)); - mashprofile->name = NULL; - mashprofile->version = 0; - mashprofile->notes = NULL; - mashprofile->grain_temp = 0.0; - mashprofile->mash_steps = NULL; - mashprofile->tun_temp = 0.0; - mashprofile->sparge_temp = 0.0; - mashprofile->ph = 0.0; - mashprofile->tun_weight = 0.0; - mashprofile->tun_specific_heat = 0.0; - mashprofile->equip_adjust = FALSE; - - 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); - return 1; - } - mashprofile->version = 1; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"NAME"))) { - mashprofile->name = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"NOTES"))) { - mashprofile->notes = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"GRAIN_TEMP"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - mashprofile->grain_temp = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"TUN_TEMP"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - mashprofile->tun_temp = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"SPARGE_TEMP"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - mashprofile->sparge_temp = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"PH"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - mashprofile->ph = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"TUN_WEIGHT"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - mashprofile->tun_weight = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"TUN_SPECIFIC_HEAT"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - mashprofile->tun_specific_heat = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"EQUIP_ADJUST"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (! xmlStrcmp(key, (const xmlChar *)"TRUE")) - mashprofile->equip_adjust = TRUE; - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"MASH_STEPS"))) { - parseMashSteps(doc, cur, &(mashprofile)->mash_steps); - } - cur = cur->next; - } - - *mash = mashprofile; - return 0; -} - - - -/* - * Parse fermentable - */ -int parseFermentable(xmlDocPtr doc, xmlNodePtr cur, fermentable_rec **fr) -{ - xmlChar *key; - fermentable_rec *item, *tmp; - float val; - - item = (fermentable_rec *)malloc(sizeof(fermentable_rec)); - item->next = NULL; - item->name = item->type = item->notes = item->origin = item->supplier = NULL; - item->version = 0; - item->amount = item->yield = item->color = item->coarse_fine_diff = item->moisture = - item->diastatic_power = item->protein = item->max_in_batch = 0.0; - item->add_after_boil = item->recommend_mash = FALSE; - - 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); - return 1; - } - item->version = 1; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"NAME"))) { - item->name = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"NOTES"))) { - item->notes = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"TYPE"))) { - item->type = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"ORIGIN"))) { - item->origin = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"SUPPLIER"))) { - item->supplier = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"AMOUNT"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->amount = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"YIELD"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->yield = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"COLOR"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->color = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"ADD_AFTER_BOIL"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (! xmlStrcmp(key, (const xmlChar *)"TRUE")) - item->add_after_boil = TRUE; - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"COARSE_FINE_DIFF"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->coarse_fine_diff = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"MOISTURE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->moisture = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"DIASTATIC_POWER"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->diastatic_power = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"PROTEIN"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->protein = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"MAX_IN_BATCH"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->max_in_batch = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"RECOMMEND_MASH"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (! xmlStrcmp(key, (const xmlChar *)"TRUE")) - item->recommend_mash = TRUE; - } - cur = cur->next; - } - - if (*fr == NULL) { - *fr = item; - } else { - for (tmp = *fr; tmp; tmp = tmp->next) { - if (tmp->next == NULL) { - tmp->next = item; - break; - } - } - } - - return 0; -} - - - -/* - * Parse fermentables - */ -int parseFermentables(xmlDocPtr doc, xmlNodePtr cur, fermentable_rec **fr) -{ - cur = cur->xmlChildrenNode; - while (cur != NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"FERMENTABLE"))) { - parseFermentable(doc, cur, fr); - } - cur = cur->next; - } - return 0; -} - - - -/* - * Parse hop - */ -int parseHop(xmlDocPtr doc, xmlNodePtr cur, hop_rec **hr) -{ - xmlChar *key; - hop_rec *item, *tmp; - float val; - - item = (hop_rec *)malloc(sizeof(hop_rec)); - item->next = NULL; - item->name = item->use = item->notes = item->type = item->form = - item->origin = item->substitutes = NULL; - item->version = 0; - item->alpha = item->amount = item->time = item->beta = item->hsi = - item->humulene = item->caryophyllene = item->cohumulone = item->myrcene = 0.0; - - 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); - return 1; - } - item->version = 1; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"NAME"))) { - item->name = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"ALPHA"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->alpha = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"AMOUNT"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->amount = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"USE"))) { - item->use = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"TIME"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->time = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"NOTES"))) { - item->notes = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"TYPE"))) { - item->type = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"FORM"))) { - item->form = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"BETA"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->beta = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"HSI"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->hsi = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"ORIGIN"))) { - item->origin = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"SUBSTITITES"))) { - item->substitutes = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"HUMULENE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->humulene = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"CARYOPHYLLENE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->caryophyllene = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"COHUMULONE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->cohumulone = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"MYRCENE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->myrcene = val; - xmlFree(key); - } - cur = cur->next; - } - - if (*hr == NULL) { - *hr = item; - } else { - for (tmp = *hr; tmp; tmp = tmp->next) { - if (tmp->next == NULL) { - tmp->next = item; - break; - } - } - } - - return 0; -} - - - -/* - * Parse hops - */ -int parseHops(xmlDocPtr doc, xmlNodePtr cur, hop_rec **hr) -{ - cur = cur->xmlChildrenNode; - while (cur != NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"HOP"))) { - parseHop(doc, cur, hr); - } - cur = cur->next; - } - return 0; -} - - - -/* - * Parse Yeast - */ -int parseYeast(xmlDocPtr doc, xmlNodePtr cur, yeast_rec **yr) -{ - xmlChar *key; - yeast_rec *item, *tmp; - float val; - int ival; - - item = (yeast_rec *)malloc(sizeof(yeast_rec)); - item->next = NULL; - item->name = item->type = item->form = item->laboratory = item->product_id = item->flocculation = item->notes = item->best_for = NULL; - item->amount = item->min_temperature = item->max_temperature = item->attenuation = 0.0; - item->amount_is_weight = item->add_to_secondary = FALSE; - item->version = item->times_cultured = item->max_reuse = 0; - - 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); - return 1; - } - item->version = 1; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"NAME"))) { - item->name = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"TYPE"))) { - item->type = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"FORM"))) { - item->form = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"AMOUNT"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->amount = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"AMOUNT_IS_WEIGHT"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (! xmlStrcmp(key, (const xmlChar *)"TRUE")) - item->amount_is_weight = TRUE; - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"LABORATORY"))) { - item->laboratory = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"PRODUCT_ID"))) { - item->product_id = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"MIN_TEMPERATURE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->min_temperature = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"MAX_TEMPERATURE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->max_temperature = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"FLOCCULATION"))) { - item->flocculation = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"ATTENUATION"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->attenuation = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"NOTES"))) { - item->notes = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"BEST_FOR"))) { - item->best_for = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"TIMES_CULTURED"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - item->times_cultured = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"MAX_REUSE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - item->max_reuse = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"ADD_TO_SECONDARY"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (! xmlStrcmp(key, (const xmlChar *)"TRUE")) - item->add_to_secondary = TRUE; - } - cur = cur->next; - } - - if (*yr == NULL) { - *yr = item; - } else { - for (tmp = *yr; tmp; tmp = tmp->next) { - if (tmp->next == NULL) { - tmp->next = item; - break; - } - } - } - - return 0; -} - - - -/* - * Parse Yeasts - */ -int parseYeasts(xmlDocPtr doc, xmlNodePtr cur, yeast_rec **yr) -{ - cur = cur->xmlChildrenNode; - while (cur != NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"YEAST"))) { - parseYeast(doc, cur, yr); - } - cur = cur->next; - } - return 0; -} - - - -/* - * Parse Misc - */ -int parseMisc(xmlDocPtr doc, xmlNodePtr cur, misc_rec **mr) -{ - xmlChar *key; - misc_rec *item, *tmp; - float val; - - item = (misc_rec *)malloc(sizeof(misc_rec)); - item->next = NULL; - item->name = item->type = item->use = item->use_for = item->notes = NULL; - item->amount = item->time = 0.0; - item->amount_is_weight = FALSE; - item->version = 0; - - 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); - return 1; - } - item->version = 1; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"NAME"))) { - item->name = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"TYPE"))) { - item->type = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"USE"))) { - item->use = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"TIME"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->time = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"AMOUNT"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->amount = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"AMOUNT_IS_WEIGHT"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (! xmlStrcmp(key, (const xmlChar *)"TRUE")) - item->amount_is_weight = TRUE; - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"USE_FOR"))) { - item->use_for = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"NOTES"))) { - item->notes = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - cur = cur->next; - } - - if (*mr == NULL) { - *mr = item; - } else { - for (tmp = *mr; tmp; tmp = tmp->next) { - if (tmp->next == NULL) { - tmp->next = item; - break; - } - } - } - - return 0; -} - - - -/* - * Parse Miscs - */ -int parseMiscs(xmlDocPtr doc, xmlNodePtr cur, misc_rec **mr) -{ - cur = cur->xmlChildrenNode; - while (cur != NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"MISC"))) { - parseMisc(doc, cur, mr); - } - cur = cur->next; - } - return 0; -} - - - -/* - * Parse Water - */ -int parseWater(xmlDocPtr doc, xmlNodePtr cur, water_rec **wr) -{ - xmlChar *key; - water_rec *item, *tmp; - float val; - - item = (water_rec *)malloc(sizeof(water_rec)); - item->next = NULL; - item->name = item->notes = NULL; - item->amount = item->calcium = item->bicarbonate = item->sulfate = item->chloride = item->sodium = item->magnesium = item->ph = 0.0; - item->version = 0; - - 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); - return 1; - } - item->version = 1; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"NAME"))) { - item->name = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"AMOUNT"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->amount = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"CALCIUM"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->calcium = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"BICARBONATE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->bicarbonate = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"SULFATE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->sulfate = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"CHLORIDE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->chloride = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"SODIUM"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->sodium = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"MAGNESIUM"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->magnesium = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"PH"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - item->ph = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"NOTES"))) { - item->notes = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - cur = cur->next; - } - - if (*wr == NULL) { - *wr = item; - } else { - for (tmp = *wr; tmp; tmp = tmp->next) { - if (tmp->next == NULL) { - tmp->next = item; - break; - } - } - } - - return 0; -} - - - -/* - * Parse Waters - */ -int parseWaters(xmlDocPtr doc, xmlNodePtr cur, water_rec **wr) -{ - cur = cur->xmlChildrenNode; - while (cur != NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"WATER"))) { - parseWater(doc, cur, wr); - } - cur = cur->next; - } - return 0; -} - - - -/* - * Parse a recipe - */ -void parseRecipe(xmlDocPtr doc, xmlNodePtr cur) -{ - xmlChar *key; - recipe_rec *recipe, *tmp; - float val; - int ival; - - recipe = (recipe_rec *)malloc(sizeof(recipe_rec)); - recipe->next = NULL; - recipe->name = NULL; - recipe->brewer = NULL; - recipe->asst_brewer = NULL; - recipe->type = NULL; - recipe->style = NULL; - recipe->equipment = NULL; - recipe->batch_size = 0.0; - recipe->boil_time = 0.0; - recipe->efficiency = 0.0; - recipe->hops = NULL; - recipe->fermentables = NULL; - recipe->miscs = NULL; - recipe->yeasts = NULL; - recipe->waters = NULL; - recipe->notes = NULL; - recipe->taste_notes = NULL; - recipe->taste_rating = 0.0; - recipe->og = 0.0; - recipe->fg = 0.0; - recipe->fermentation_stages = 0; - recipe->primary_age = recipe->secondary_age = recipe->tertiary_age = recipe->age = 0; - recipe->primary_temp = recipe->secondary_temp = recipe->tertiary_temp = recipe->age_temp = 0.0; - recipe->date = NULL; - recipe->carbonation = 0.0; - recipe->forced_carbonation = FALSE; - recipe->priming_sugar_name = NULL; - recipe->carbonation_temp = 0.0; - recipe->priming_sugar_equiv = recipe->keg_priming_factor = 0.0; - - cur = cur->xmlChildrenNode; - while (cur != NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"NAME"))) { - recipe->name = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"TYPE"))) { - recipe->type = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"STYLE"))) { - parseStyle(doc, cur, &(recipe)->style); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"EQUIPMENT"))) { - parseEquipment(doc, cur, &(recipe)->equipment); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"BREWER"))) { - recipe->brewer = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"ASST_BREWER"))) { - recipe->asst_brewer = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"BATCH_SIZE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - recipe->batch_size = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"BOIL_SIZE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - recipe->boil_size = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"BOIL_TIME"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - recipe->boil_time = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"EFFICIENCY"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - recipe->efficiency = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"HOPS"))) { - parseHops(doc, cur, &(recipe)->hops); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"FERMENTABLES"))) { - parseFermentables(doc, cur, &(recipe)->fermentables); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"MISCS"))) { - parseMiscs(doc, cur, &(recipe)->miscs); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"YEASTS"))) { - parseYeasts(doc, cur, &(recipe)->yeasts); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"WATERS"))) { - parseWaters(doc, cur, &(recipe)->waters); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"MASH"))) { - parseMash(doc, cur, &(recipe)->mash); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"NOTES"))) { - recipe->notes = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"TASTE_NOTES"))) { - recipe->taste_notes = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"TASTE_RATING"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - recipe->taste_rating = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"OG"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - recipe->og = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"FG"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - recipe->fg = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"FERMENTATION_STAGES"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - recipe->fermentation_stages = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"PRIMARY_AGE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - recipe->primary_age = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"PRIMARY_TEMP"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - recipe->primary_temp = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"SECONDARY_AGE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - recipe->secondary_age = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"SECONDARY_TEMP"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - recipe->secondary_temp = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"TERTIARY_AGE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - recipe->tertiary_age = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"TERTIARY_TEMP"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - recipe->tertiary_temp = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"AGE"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%d", &ival) == 1) - recipe->age = ival; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"AGE_TEMP"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - recipe->age_temp = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"DATE"))) { - recipe->date = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"CARBONATION"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - recipe->carbonation = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"FORCED_CARBONATION"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (! xmlStrcmp(key, (const xmlChar *)"TRUE")) - recipe->forced_carbonation = TRUE; - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"PRIMING_SUGAR_NAME"))) { - recipe->priming_sugar_name = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"CARBONATION_TEMP"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - recipe->carbonation_temp = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"PRIMING_SUGAR_EQUIV"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - recipe->priming_sugar_equiv = val; - xmlFree(key); - } - if ((!xmlStrcmp(cur->name, (const xmlChar *)"KEG_PRIMING_FACTOR"))) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - if (sscanf((const char *)key, "%f", &val) == 1) - recipe->keg_priming_factor = val; - xmlFree(key); - } - cur = cur->next; - } - - if (recipes == NULL) { - recipes = recipe; - } else { - for (tmp = recipes; tmp; tmp = tmp->next) { - if (tmp->next == NULL) { - tmp->next = recipe; - break; - } - } - } -} - - - -int parseBeerXML(char *docname) -{ - xmlDocPtr doc; - xmlNodePtr cur; - - if ((doc = xmlParseFile(docname)) == NULL) { - fprintf(stderr, "XML file %s errors.\n", docname); - return 1; - } - - if ((cur = xmlDocGetRootElement(doc)) == NULL) { - fprintf(stderr, "XML file %s empty.\n", docname); - xmlFreeDoc(doc); - return 1; - } - - if (xmlStrcmp(cur->name, (const xmlChar*)"RECIPES")) { - fprintf(stderr, "XML file %s is not a BeerXML file.\n", docname); - xmlFreeDoc(doc); - return 1; - } - - /* - * Parse all recipes - */ - cur = cur->xmlChildrenNode; - while (cur != NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"RECIPE"))) { - parseRecipe(doc, cur); - } - cur = cur->next; - } - - xmlFreeDoc(doc); - return 0; -} - - - -/* - * For debugging purposes, dump the recipes - */ -void printBeerXML(void) -{ - recipe_rec *tmp0; - mash_step *tmp1; - fermentable_rec *tmp2; - equipment_rec *tmp3; - style_rec *tmp4; - hop_rec *tmp5; - yeast_rec *tmp6; - misc_rec *tmp7; - water_rec *tmp8; - int mashstep = 0; - float grain_weight = 0.0, water_grain_ratio, tun_water = 0.0, temp; - - for (tmp0 = recipes; tmp0; tmp0 = tmp0->next) { - printf("--------------------------------------------------------------------------------\n"); - printf("Recipe: %s\n", tmp0->name); - printf("Type: %s\n", tmp0->type); - if (tmp0->notes) - printf("Notes: %s\n", tmp0->notes); - if (tmp0->brewer || tmp0->asst_brewer) - printf("Brewer: %s Assistent brewer: %s\n", tmp0->brewer, tmp0->asst_brewer); - printf("Batch size: %5.1f Boil time: %5.1f Efficiency: %5.1f\n", tmp0->batch_size, tmp0->boil_time, tmp0->efficiency); - printf("Taste rate: %5.1f Taste notes: %s\n", tmp0->taste_rating, tmp0->taste_notes); - printf("Original G: %5.3f Final G: %5.3f\n", tmp0->og, tmp0->fg); - printf("\n"); - - if (tmp0->equipment) { - tmp3 = tmp0->equipment; - printf("Equipment: %s\n", tmp3->name); - if (tmp3->notes) - printf(" Notes: %s\n", tmp3->notes); - printf(" Boil size: %5.1f Batch size: %5.1f Boil time: %5.1f\n", tmp3->boil_size, tmp3->batch_size, tmp3->boil_time); - printf(" Tun volume: %5.1f Tun weight: %5.1f Specific heat: %5.1f\n", tmp3->tun_volume, tmp3->tun_weight, tmp3->tun_specific_heat); - printf(" TopUp: %5.1f Chiller loss: %5.1f Evaporation rate: %5.1f\n", tmp3->top_up_water, tmp3->trub_chiller_loss, tmp3->evap_rate); - printf(" Tun loss: %5.1f TopUp kettle: %5.1f Hop utilization: %5.1f\n", tmp3->lauter_deadspace, tmp3->top_up_kettle, tmp3->hop_utilization); - printf(" CalcBoilVol: %s\n", tmp3->calc_boil_volume ? "YES":"NO"); - printf("\n"); - } - - if (tmp0->style) { - tmp4 = tmp0->style; - printf("Style: %s-%s Type: %s\n", tmp4->style_letter, tmp4->name, tmp4->type); - if (tmp4->category || tmp4->category_number || tmp4->style_guide) - printf(" Category: %s Cat nr: %s Guide: %s\n", tmp4->category, tmp4->category_number, tmp4->style_guide); - printf(" OG: %5.3f - %5.3f\n", tmp4->og_min, tmp4->og_max); - printf(" FG: %5.3f - %5.3f\n", tmp4->fg_min, tmp4->fg_max); - printf(" Bittern: %5.1f - %5.1f IBU\n", tmp4->ibu_min, tmp4->ibu_max); - printf(" Color: %5.1f - %5.1f SRM\n", tmp4->color_min, tmp4->color_max); - printf(" Carb: %5.1f - %5.1f V-CO2\n", tmp4->carb_min, tmp4->carb_max); - printf(" ABV: %5.1f - %5.1f %%\n", tmp4->abv_min, tmp4->abv_max); - if (tmp4->notes) - printf(" Notes: %s\n", tmp4->notes); - if (tmp4->profile) - printf(" Profile: %s\n", tmp4->profile); - if (tmp4->examples) - printf(" Examples: %s\n", tmp4->examples); - printf("\n"); - } - - printf("Fermentables:\n"); - printf(" Type Name Kg Mash Moist\n"); - for (tmp2 = tmp0->fermentables; tmp2; tmp2 = tmp2->next) { - printf(" %-12s %-25s %6.3f %-5s %5.1f\n", tmp2->type, tmp2->name, tmp2->amount, - tmp2->recommend_mash ? "TRUE":"FALSE", tmp2->moisture); - if (tmp2->recommend_mash) - grain_weight += tmp2->amount; - } - printf("\n"); - - if (tmp0->hops) { - printf("Hops:\n"); - // 123456789 1234567890 1234567890123456789012345 123456 12345 12345 - printf(" Type Use Name Kg Time Alpha\n"); - for (tmp5 = tmp0->hops; tmp5; tmp5 = tmp5->next) { - printf(" %-9s %-10s %-25s %6.3f %5.1f %5.1f\n", tmp5->type, tmp5->use, tmp5->name, tmp5->amount, tmp5->time, tmp5->alpha); - } - printf("\n"); - } - - if (tmp0->miscs) { - printf("Miscs:\n"); - // 12345678901 123456789 1234567890123456789012345 123456 12345 12345 - printf(" Type Use Name Kg Time\n"); - for (tmp7 = tmp0->miscs; tmp7; tmp7 = tmp7->next) { - printf(" %-11s %-9s %-25s %6.3f %5.1f\n", tmp7->type, tmp7->use, tmp7->name, tmp7->amount, tmp7->time); - } - printf("\n"); - } - - if (tmp0->waters) { - printf("Wateren:\n"); - // 1234567890123456789012345 12345 12345 1234... - printf(" Name Ltrs PH Notes\n"); - for (tmp8 = tmp0->waters; tmp8; tmp8 = tmp8->next) { - printf(" %-25s %5.1f %5.1f %s\n", tmp8->name, tmp8->amount, tmp8->ph, tmp8->notes); - } - printf("\n"); - } - - printf("Mash profile: %s\n", tmp0->mash->name); - if (tmp0->mash->notes) - printf(" Notes: %s\n", tmp0->mash->notes); - printf(" Grain temp: %5.1f Tun temp: %5.1f Sparge temp: %5.1f\n", tmp0->mash->grain_temp, tmp0->mash->tun_temp, tmp0->mash->sparge_temp); - printf(" PH: %5.1f Tun weight: %6.2f Tun specific heat: %6.2f\n", tmp0->mash->ph, tmp0->mash->tun_weight, tmp0->mash->tun_specific_heat); - printf(" Equip adjust: %s\n", tmp0->mash->equip_adjust ? "TRUE":"FALSE"); - printf("\n"); - - if (tmp0->mash->mash_steps) { - mashstep = 0; - printf("st Name Type Temp Endtmp Dur Rmp Inf/Dec L/Kg\n"); - for (tmp1 = tmp0->mash->mash_steps; tmp1; tmp1 = tmp1->next) { - mashstep++; - tun_water += tmp1->infuse_amount; - water_grain_ratio = tun_water / grain_weight; - temp = tmp1->infuse_amount; -// if ((tmp1->infuse_amount == 0.0) && (tmp1->decotion_amt > 0.0)) -// temp = tmp1->decotion_amt; - printf("%2d %-16s %-12s %6.1f %6.1f %3.0f %3.0f %6.1f %6.2f\n", mashstep, tmp1->name, tmp1->type, - tmp1->step_temp, tmp1->end_temp, tmp1->step_time, tmp1->ramp_time, temp, water_grain_ratio); - } - printf("\n"); - } - - if (tmp0->yeasts) { - for (tmp6 = tmp0->yeasts; tmp6; tmp6 = tmp6->next) { - printf("Yeast: %s\n", tmp6->name); - printf(" Type: %-20s Form: %-20s Amount: %7.4f %s\n", - tmp6->type, tmp6->form, tmp6->amount, tmp6->amount_is_weight ? "Kg":"L"); - printf(" Lab: %-20s Product id: %-20s Flocculation: %s\n", tmp6->laboratory, tmp6->product_id, tmp6->flocculation); - printf(" Min temp: %5.1f Max temp: %5.1f Attenuation: %5.1f\n", - tmp6->min_temperature, tmp6->max_temperature, tmp6->attenuation); - if (tmp6->notes) - printf(" Notes: %s\n", tmp6->notes); - printf("\n"); - } - } - - printf("\n"); - } -} - - diff -r 4eebab50993e -r 6d139c21e22c mash/beerxml.h --- a/mash/beerxml.h Sun Jul 15 14:08:19 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,262 +0,0 @@ -#ifndef _BEERXML_H -#define _BEERXML_H - - -/* - * See http://www.beerxml.com/beerxml.htm for more information. - * This standard isn't perfect, but it works. Note that some - * fields are not well defined. Some precentages are safe if you - * declare them as float instead of intergers. - * - * The function parseBeerXML() reads the file and puts the - * contents in the following tree: - * - * recipes recipe hops hop - * hop - * fermentables fermentable - * fermentable - * yeasts yeast - * yeast - * miscs misc - * misc - * waters water - * water - * style - * mash mash_step - * mash_step - * equipment - * recipe hops hop - * and so on. - */ - -typedef struct _hop_rec { - struct _hop_rec *next; - char *name; /* Name of the hops */ - int version; /* Should be 1 for this version of the standard */ - float alpha; /* Percent alpha of hops */ - float amount; /* Weight in Kilograms of the hops used. */ - char *use; /* "Boil", "Dry Hop", "Mash", "First Wort" or "Aroma" */ - float time; /* The time as measured in minutes. */ - char *notes; /* Textual notes about the hops. */ - char *type; /* "Bittering", "Aroma" or "Both" */ - char *form; /* "Pellet", "Plug" or "Leaf" */ - float beta; /* Hop beta percentage. */ - float hsi; /* Hop Stability Index */ - char *origin; /* Place of origin for the hops */ - char *substitutes; /* Substitutes that can be used for this hops */ - float humulene; /* Humulene level in percent. */ - float caryophyllene; /* Caryophyllene level in percent. */ - float cohumulone; /* Cohumulone level in percent */ - float myrcene; /* Myrcene level in percent */ -} hop_rec; - -typedef struct _fermentable_rec { - struct _fermentable_rec *next; - char *name; /* Name */ - int version; /* Record version */ - char *type; /* "Grain", "Sugar", "Extract", "Dry Extract" or "Adjunct" */ - char *notes; /* Notes */ - float amount; /* Weight in KG */ - float yield; /* Percent dry yield (fine grain) */ - float color; /* The color of the item in Lovibond */ - int add_after_boil; /* May be TRUE. */ - char *origin; /* Country or place of origin */ - char *supplier; /* Supplier of the grain/extract/sugar */ - float coarse_fine_diff; /* Percent difference between the coarse grain yield and fine grain yield. */ - float moisture; /* Percent moisture in the grain. */ - float diastatic_power; /* The diastatic power of the grain */ - float protein; /* The percent protein in the grain. */ - float max_in_batch; /* The recommended maximum percentage */ - int recommend_mash; /* TRUE if it is recommended to mash */ -} fermentable_rec; - -typedef struct _equipment_rec { - char *name; /* Name of the equipment profile */ - int version; /* Version of the equipment record. */ - float boil_size; /* The pre-boil volume used. */ - float batch_size; /* The target volume of the batch. */ - float tun_volume; /* Volume of the mash tun in liters. */ - float tun_weight; /* Weight of the mash tun in kilograms. */ - float tun_specific_heat; /* The specific heat of the mash tun. */ - float top_up_water; /* The amount of top up water normally added. */ - float trub_chiller_loss; /* The amount of wort normally lost. */ - float evap_rate; /* Perc of wort lost to evaporation per hour. */ - float boil_time; /* The normal amount of time one boils */ - int calc_boil_volume; /* Flag denoting to calculate the boil size. */ - float lauter_deadspace; /* Amount lost to the lauter tun. */ - float top_up_kettle; /* Amount normally added to the boil */ - float hop_utilization; /* Large batch hop utilization. */ - char *notes; /* Notes associated with the equipment. */ -} equipment_rec; - -typedef struct _yeast_rec { - struct _yeast_rec *next; - char *name; /* Name of the yeast. */ - int version; /* Version of the standard. */ - char *type; /* “Ale”, “Lager”, “Wheat”, “Wine”, “Champagne” */ - char *form; /* “Liquid”, “Dry”, “Slant” or “Culture” */ - float amount; /* The amount of yeast, measured in liters. */ - int amount_is_weight; /* TRUE if the amount measurement is a weight */ - char *laboratory; /* The laboratory that produced the yeast. */ - char *product_id; /* The manufacturer’s product ID label */ - float min_temperature; /* The minimum recommended temperature */ - float max_temperature; /* The maximum recommended temperature */ - char *flocculation; /* “Low”, “Medium”, “High” or “Very High” */ - float attenuation; /* Average attenuation for this yeast strain. */ - char *notes; /* Notes on this yeast strain. */ - char *best_for; /* Beerstyle this yeast is best suited for. */ - int times_cultured; /* Number of times this yeast has been reused */ - int max_reuse; /* Recommended maximum reuse times */ - int add_to_secondary; /* Flag this yeast was added for a secondary */ -} yeast_rec; - -typedef struct _misc_rec { - struct _misc_rec *next; - char *name; /* Name of the misc item. */ - int version; /* Version number of this element. */ - char *type; /* “Spice”, “Fining”, “Water Agent”, “Herb”, “Flavor”, “Other” */ - char *use; /* “Boil”, “Mash”, “Primary”, “Secondary”, “Bottling” */ - float time; /* Time the misc was boiled, steeped, mashed, etc in minutes. */ - float amount; /* Amount of item used. Liters or Weight */ - int amount_is_weight; /* TRUE if amount is weight */ - char *use_for; /* Desc. of what the ingredient is used for */ - char *notes; /* Detailed notes on the item including usage. */ -} misc_rec; - -typedef struct _water_rec { - struct _water_rec *next; - char *name; /* Name of the water profile */ - int version; /* Version of the water record. */ - float amount; /* Volume of water to use in a recipe in liters */ - float calcium; /* The amount of calcium (Ca) in ppm */ - float bicarbonate; /* The amount of bicarbonate (HCO3) in ppm. */ - float sulfate; /* The amount of Sulfate (SO4) in ppm. */ - float chloride; /* The amount of Chloride (Cl) in ppm. */ - float sodium; /* The amount of Sodium (Na) in ppm. */ - float magnesium; /* The amount of Magnesium (Mg) in ppm. */ - float ph; /* The PH of the water. */ - char *notes; /* Notes about the water profile. */ -} water_rec; - -typedef struct _style_rec { - char *name; /* Name of the style profile */ - char *category; /* Category that this style belongs to */ - int version; /* Version of the style record. */ - char *category_number; /* Number or identifier for this style category */ - char *style_letter; /* The specific style number or subcategory */ - char *style_guide; /* The name of the style guide */ - char *type; /* “Lager”, “Ale”, “Mead”, “Wheat”, “Mixed” or “Cider” */ - float og_min; /* Original gracity */ - float og_max; - float fg_min; /* Final gravity */ - float fg_max; - float ibu_min; /* Bitterness for this style as measured */ - float ibu_max; /* in International Bitterness Units (IBUs) */ - float color_min; /* The recommended color in SRM */ - float color_max; - float carb_min; /* The recommended carbonation for this style */ - float carb_max; /* in volumes of CO2 */ - float abv_min; /* Alcohol by volume as a percentage. */ - float abv_max; - char *notes; /* Description of the style, history */ - char *profile; /* Flavor and aroma profile for this style */ - char *ingredients; /* Suggested ingredients for this style */ - char *examples; /* Example beers of this style. */ -} style_rec; - -typedef struct _mash_step { - struct _mash_step *next; - char *name; /* Name of this step */ - int version; /* Record version */ - char *type; /* “Infusion”, “Temperature” or “Decoction” */ - float infuse_amount; /* Wateri vol. in liters to infuse in this step */ - float infuse_temp; /* niet officieel - berekenen */ - float step_temp; /* The target temperature for this step */ - float end_temp; /* The final temperature you can expect */ - float step_time; /* The number of minutes to spend */ - float ramp_time; /* Time to achieve the desired step temperature */ - float water_grain_ratio; /* niet officieel - berekenen */ - float decotion_amt; /* niet officieel */ -} mash_step; - -typedef struct _mash_profile { - char *name; /* Name of mash method */ - int version; /* Record version */ - char *notes; /* Additional notes */ - float grain_temp; /* The temperature of the grain */ - mash_step *mash_steps; /* List of mash steps */ - float tun_temp; /* Grain tun temperature */ - float sparge_temp; /* Temperature of the sparge water */ - float ph; /* PH of the sparge. */ - float tun_weight; /* Weight of the mash tun in kilograms */ - float tun_specific_heat; /* Specific heat of the tun material */ - int equip_adjust; /* Adjust for tun heat loss */ -} mash_profile; - -typedef struct _brew_equipment { - char *name; /* Name of the equipment profile */ - float boil_size; /* The pre-boil volume for this equipment setup */ - float batch_size; /* The target volume of the batch */ - float tun_volume; /* Volume of the mash tun in liters. */ - float tun_weight; /* Weight of the mash tun in kilograms. */ - float tun_specific_heat; /* The specific heat of the mash tun. */ - float top_up_water; /* The amount of top up water b4 fermenting */ - float trub_chiller_loss; /* Amount of wort lost during cooling */ - float evap_rate; /* Perc of wort lost to evaporation per hour. */ - float boil_time; /* The normal amount of boil time for this eq. */ - int calc_boil_volume; /* Should the program calculate the boil size. */ - float lauter_dead_space; /* Amount lost to the lauter tun. */ - float top_up_kettle; /* Amount added to the boil kettle b4 the boil. */ - float hop_utilization; /* Large batch hop utilization. */ - char *notes; /* Notes for this equipment. */ -} brew_equipment; - -typedef struct _recipe_rec { - struct _recipe_rec *next; - int version; /* Current version is 1 */ - char *name; /* Name of the recipe */ - char *type; /* “Extract”, “Partial Mash” or “All Grain” */ - style_rec *style; /* style record */ - equipment_rec *equipment; /* equipemnt record */ - char *brewer; /* Name of the brewer */ - char *asst_brewer; /* Name of the assistent brewer */ - float batch_size; /* Target size of the finished batch in liters. */ - float boil_size; /* Starting size for the main boil in liters */ - float boil_time; /* The total time to boil the wort in minutes. */ - float efficiency; /* The percent brewhouse efficiency */ - hop_rec *hops; /* hops */ - fermentable_rec *fermentables; /* Fermentables list */ - misc_rec *miscs; /* Misc ingredients */ - yeast_rec *yeasts; /* Yeasts */ - water_rec *waters; /* Water profiles */ - mash_profile *mash; /* Mash profile */ - char *notes; /* Notes associated with this recipe */ - char *taste_notes; /* Tasting notes – may be multiline. */ - float taste_rating; /* Number between zero and 50.0 (BJCP system) */ - float og; /* The measured original specific gravity. */ - float fg; /* The measured final gravity of the beer. */ - int fermentation_stages; /* The number of fermentation stages used */ - int primary_age; /* Time spent in the primary in days */ - float primary_temp; /* Temp in Celsius for the primary fermentation */ - int secondary_age; /* Time spent in the secondary in days. */ - float secondary_temp; /* Temp in C for the secondary fermentation. */ - int tertiary_age; /* Time spent in the third fermenter in days. */ - float tertiary_temp; /* Temperature in the tertiary fermenter. */ - int age; /* Time to age the beer in days after bottling. */ - float age_temp; /* Temperature for aging after bottling. */ - char *date; /* Date brewed in a easily recognizable format. */ - float carbonation; /* Volume of CO2 used to carbonate this beer. */ - int forced_carbonation; /* TRUE if forced carbonated using CO2 pressure */ - char *priming_sugar_name; /* Text describing the priming agent. */ - float carbonation_temp; /* Temp for either bottling/forced carbonation. */ - float priming_sugar_equiv; /* Factor used to convert this priming agent */ - float keg_priming_factor; /* Used 2 factor amount of sugar for containers */ -} recipe_rec; - - -int parseBeerXML(char *); -void printBeerXML(void); - - -#endif - diff -r 4eebab50993e -r 6d139c21e22c mash/lcd-pcf8574.c --- a/mash/lcd-pcf8574.c Sun Jul 15 14:08:19 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,144 +0,0 @@ -/* - * lcd-pcf8574.c: - * Text-based LCD driver library code - * This is designed to drive the HD44780U LCD display connected via - * a "LCM1602 IIC A0 A1 A2" board with a PCF8574 I2C controller. - * - * Copyright (c) 2012-2013 Gordon Henderson. - * Copyright (c) 2014 Michiel Broek. - *********************************************************************** - * - * mbsePi is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * mbsePi 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with wiringPi. If not, see . - *********************************************************************** - */ - -#include "mash.h" -#include "lcd-pcf8574.h" - - -#ifdef HAVE_WIRINGPI_H - -int lcdHandle; -unsigned char lcdbuf[MAX_LCDS][20][4]; - -struct lcdDataStruct -{ - int bits, rows, cols ; - int rsPin, strbPin ; - int dataPins [8] ; - int cx, cy ; -}; -extern struct lcdDataStruct *lcds [MAX_LCDS]; - - -/* - * Some LCD functions are extended shadow copies of the wiringPi functions. - * The difference is that the lcdbuf will be updated with the contents on - * the hardware display. This copy can then be used for a remote display - */ - - -/* - * setBacklight: - ********************************************************************************* - */ - -void setBacklight (int value) -{ - pinMode (AF_BACKLIGHT, OUTPUT) ; - digitalWrite (AF_BACKLIGHT, (value & 1)) ; -} - - - -/* - * initLCD: - ********************************************************************************* - */ - -int initLCD (int cols, int rows) -{ - int x, y; - - if (!((rows == 1) || (rows == 2) || (rows == 4))) { - fprintf (stderr, "rows must be 1, 2 or 4\n") ; - return EXIT_FAILURE ; - } - - if (!((cols == 16) || (cols == 20))) { - fprintf (stderr, "cols must be 16 or 20\n") ; - return EXIT_FAILURE ; - } - - pcf8574Setup(AF_BASE, 0x27) ; - pinMode (AF_RW, OUTPUT) ; - digitalWrite (AF_RW, LOW) ; // Not used with wiringPi - always in write mode - - /* - * The other control pins are initialised with lcdInit () - */ - lcdHandle = lcdInit (rows, cols, 4, AF_RS, AF_E, AF_DB4, AF_DB5, AF_DB6, AF_DB7, 0, 0, 0, 0) ; - if (lcdHandle < 0) { - fprintf (stderr, "lcdInit failed\n") ; - return -1 ; - } - - lcdClear (lcdHandle) ; - for (x = 0; x < 20; x++) - for (y = 0; y < 4; y++) - lcdbuf[lcdHandle][x][y] = ' '; - - setBacklight (1) ; - - return 0 ; -} - - - -void mb_lcdPutchar(const int fd, unsigned char data) -{ - struct lcdDataStruct *lcd = lcds[fd]; - - /* - * Write to our buffer first, then to the wiringPi driver. - * Writing to wiringPi updates the cursor position. - */ - lcdbuf[fd][lcd->cx][lcd->cy] = data; - lcdPutchar(fd, data); -} - - - -void mb_lcdPuts(const int fd, const char *string) -{ - while (*string) - mb_lcdPutchar (fd, *string++); -} - - - -void mb_lcdClear(const int fd) -{ - int x, y; - - lcdClear(fd); - for (x = 0; x < 20; x++) - for (y = 0; y < 4; y++) - lcdbuf[fd][x][y] = ' '; -} - - - -#endif - diff -r 4eebab50993e -r 6d139c21e22c mash/lcd-pcf8574.h --- a/mash/lcd-pcf8574.h Sun Jul 15 14:08:19 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -#ifndef _LCD_PCF8574_H -#define _LCD_PCF8574_H - - -#ifdef HAVE_WIRINGPI_H -/* wiringPi */ -#include -#include -#include - - -// Defines for the pcf8574 Pi LCD interface board -#define AF_BASE 100 - -#define AF_RS (AF_BASE + 0) -#define AF_RW (AF_BASE + 1) -#define AF_E (AF_BASE + 2) -#define AF_BACKLIGHT (AF_BASE + 3) -#define AF_DB4 (AF_BASE + 4) -#define AF_DB5 (AF_BASE + 5) -#define AF_DB6 (AF_BASE + 6) -#define AF_DB7 (AF_BASE + 7) - - -void setBacklight (int); -int initLCD (int, int); -void mb_lcdPutchar(const int, unsigned char); -void mb_lcdPuts(const int, const char *); -void mb_lcdClear(const int); - -#endif - -#endif diff -r 4eebab50993e -r 6d139c21e22c mash/lock.c --- a/mash/lock.c Sun Jul 15 14:08:19 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,134 +0,0 @@ -/***************************************************************************** - * Copyright (C) 2014 - * - * Michiel Broek - * - * 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 EC-65K; see the file COPYING. If not, write to the Free - * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - *****************************************************************************/ - -#include "mash.h" -#include "lock.h" - - -/* - * Put a lock on this program. - */ -int lockprog(char *name) -{ - char *tempfile, *lockfile; - FILE *fp; - pid_t oldpid; - - tempfile = calloc(PATH_MAX, sizeof(char)); - lockfile = calloc(PATH_MAX, sizeof(char)); - - snprintf(tempfile, PATH_MAX, "/var/run/%s.tmp", name); - snprintf(lockfile, PATH_MAX, "/var/run/%s.pid", name); - - if ((fp = fopen(tempfile, "w")) == NULL) { - perror(name); - printf("Can't create lockfile \"%s\"\n", tempfile); - free(tempfile); - free(lockfile); - return 1; - } - fprintf(fp, "%10u\n", getpid()); - fclose(fp); - - while (TRUE) { - if (link(tempfile, lockfile) == 0) { - unlink(tempfile); - free(tempfile); - free(lockfile); - return 0; - } - if ((fp = fopen(lockfile, "r")) == NULL) { - perror(name); - printf("Can't open lockfile \"%s\"\n", tempfile); - unlink(tempfile); - free(tempfile); - free(lockfile); - return 1; - } - if (fscanf(fp, "%u", &oldpid) != 1) { - perror(name); - printf("Can't read old pid from \"%s\"\n", tempfile); - fclose(fp); - unlink(tempfile); - free(tempfile); - free(lockfile); - return 1; - } - fclose(fp); - if (kill(oldpid,0) == -1) { - if (errno == ESRCH) { - printf("Stale lock found for pid %u\n", oldpid); - unlink(lockfile); - /* no return, try lock again */ - } else { - perror(name); - printf("Kill for %u failed\n",oldpid); - unlink(tempfile); - free(tempfile); - free(lockfile); - return 1; - } - } else { - printf("Another %s is already running, pid=%u\n", name, oldpid); - unlink(tempfile); - free(tempfile); - free(lockfile); - return 1; - } - } -} - - - -void ulockprog(char *name) -{ - char *lockfile; - pid_t oldpid; - FILE *fp; - - lockfile = calloc(PATH_MAX, sizeof(char)); - snprintf(lockfile, PATH_MAX, "/var/run/%s.pid", name); - - if ((fp = fopen(lockfile, "r")) == NULL) { - syslog(LOG_NOTICE, "Can't open lockfile \"%s\"", lockfile); - free(lockfile); - return; - } - - if (fscanf(fp, "%u", &oldpid) != 1) { - syslog(LOG_NOTICE, "Can't read old pid from \"%s\"", lockfile); - fclose(fp); - unlink(lockfile); - free(lockfile); - return; - } - - fclose(fp); - - if (oldpid == getpid()) { - (void)unlink(lockfile); - } - - free(lockfile); -} - - diff -r 4eebab50993e -r 6d139c21e22c mash/lock.h --- a/mash/lock.h Sun Jul 15 14:08:19 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -#ifndef _LOCK_H -#define _LOCK_H - - -int lockprog(char *); -void ulockprog(char *); - -#endif diff -r 4eebab50993e -r 6d139c21e22c mash/logger.c --- a/mash/logger.c Sun Jul 15 14:08:19 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/***************************************************************************** - * Copyright (C) 2014 - * - * Michiel Broek - * - * 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 EC-65K; see the file COPYING. If not, write to the Free - * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - *****************************************************************************/ - -#include "mash.h" -#include "xutil.h" -#include "logger.h" - - -void logger(char *filename, char *progname, char *data) -{ - struct timeval now; - struct tm ptm; - char *outstr = NULL, *name = NULL; - FILE *logfile; - - name = xstrcpy((char *)"/var/local/log/"); - name = xstrcat(name, progname); - name = xstrcat(name, (char *)"/"); - name = xstrcat(name, filename); - - gettimeofday(&now, NULL); - localtime_r(&now.tv_sec, &ptm); - - if ((logfile = fopen(name, "a+"))) { - outstr = calloc(10240, sizeof(char)); - snprintf(outstr, 10239, "%04d-%02d-%02d %02d:%02d,%s\n", ptm.tm_year + 1900, ptm.tm_mon + 1, ptm.tm_mday, ptm.tm_hour, ptm.tm_min, data); - fprintf(logfile, outstr); - fclose(logfile); - free(outstr); - outstr = NULL; - } else { - syslog(LOG_NOTICE, "logger: cannot open %s for writing", name); - } - - free(name); - name = NULL; -} - - diff -r 4eebab50993e -r 6d139c21e22c mash/logger.h --- a/mash/logger.h Sun Jul 15 14:08:19 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ -#ifndef _LOGGER_H -#define _LOGGER_H - -void logger(char *, char *, char *); - -#endif diff -r 4eebab50993e -r 6d139c21e22c mash/mash.c --- a/mash/mash.c Sun Jul 15 14:08:19 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,337 +0,0 @@ -/***************************************************************************** - * Copyright (C) 2014 - * - * Michiel Broek - * - * 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 EC-65K; see the file COPYING. If not, write to the Free - * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - *****************************************************************************/ - -#include "mash.h" -#include "lock.h" -#include "logger.h" -#include "xutil.h" -#include "beerxml.h" -#include "lcd-pcf8574.h" -#include "sensors.h" - - -#ifdef HAVE_WIRINGPI_H - -/* wiringPi */ -#include -#include -#include - -int tempA = 80; -int tempB = 80; -int coolerA = 0; -int coolerB = 0; - -int my_shutdown = FALSE; -static pid_t pgrp, mypid; - -extern int debug; -extern sys_config Config; -extern int lcdHandle; -extern unsigned char lcdbuf[MAX_LCDS][20][4]; -int lcdupdate; - - -void help(void); -void die(int); -void stopLCD(void); -int server(void); - - -void help(void) -{ - fprintf(stdout, "mbsePi-apps mash v%s starting\n\n", VERSION); - fprintf(stdout, "Usage: mash [-d] [-h]\n"); - fprintf(stdout, " -d --debug Debug and run in foreground\n"); - fprintf(stdout, " -h --help Display this help\n"); -} - - - -void die(int onsig) -{ - switch (onsig) { - case SIGHUP: syslog(LOG_NOTICE, "Got SIGHUP, shutting down"); - break; - case SIGINT: syslog(LOG_NOTICE, "Keyboard interrupt, shutting down"); - break; - case SIGTERM: syslog(LOG_NOTICE, "Got SIGTERM, shutting down"); - break; - default: syslog(LOG_NOTICE, "die() on signal %d", onsig); - } - - my_shutdown = TRUE; -} - - - -void stopLCD(void) -{ - mb_lcdClear(lcdHandle); - setBacklight(0); -} - - - -int main(int argc, char *argv[]) -{ - int rc, c, i; - pid_t frk; - char buf[80]; - - while (1) { - int option_index = 0; - static struct option long_options[] = { - {"debug", 0, 0, 'c'}, - {"help", 0, 0, 'h'}, - {0, 0, 0, 0} - }; - - c = getopt_long(argc, argv, "dh", long_options, &option_index); - if (c == -1) - break; - - switch (c) { - case 'd': debug = TRUE; - break; - case 'h': help(); - return 1; - } - } - - - parseBeerXML((char *)"/home/mbroek/Downloads/SalmoGold.xml"); - - return 0; - - openlog("mash", LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_USER); - syslog(LOG_NOTICE, "mbsePi-apps mash v%s starting", VERSION); - if (debug) - fprintf(stdout, "mbsePi-apps mash v%s starting\n", VERSION); - - if (rdconfig((char *)"mash.conf")) { - fprintf(stderr, "Error reading configuration\n"); - syslog(LOG_NOTICE, "halted"); - return 1; - } - - /* - * Catch all the signals we can, and ignore the rest. Note that SIGKILL can't be ignored - * but that's live. This daemon should only be stopped by SIGTERM. - * Don't catch SIGCHLD. - */ - for (i = 0; i < NSIG; i++) { - if ((i != SIGCHLD) && (i != SIGKILL) && (i != SIGSTOP)) - signal(i, (void (*))die); - } - - if (wiringPiSetup () ) - return 1; - - if ((rc = initLCD (16, 2))) { - fprintf(stderr, "Cannot initialize LCD display, rc=%d\n", rc); - return 1; - } - - lcdPosition(lcdHandle, 0, 0); - sprintf(buf, " Mash"); - mb_lcdPuts(lcdHandle, buf); - lcdPosition(lcdHandle, 0, 1); - sprintf(buf, " Version %s", VERSION); - mb_lcdPuts(lcdHandle, buf); - - if (debug) { - /* - * For debugging run in foreground. - */ - rc = server(); - } else { - /* - * Server initialization is complete. Now we can fork the - * daemon and return to the user. We need to do a setpgrp - * so that the daemon will no longer be assosiated with the - * users control terminal. This is done before the fork, so - * that the child will not be a process group leader. Otherwise, - * if the child were to open a terminal, it would become - * associated with that terminal as its control terminal. - */ - if ((pgrp = setpgid(0, 0)) == -1) { - syslog(LOG_NOTICE, "setpgpid failed"); - } - - frk = fork(); - switch (frk) { - case -1: - syslog(LOG_NOTICE, "Daemon fork failed: %s", strerror(errno)); - syslog(LOG_NOTICE, "Finished, rc=1"); - stopLCD(); - exit(1); - case 0: /* - * Run the daemon - */ - fclose(stdin); - if (open("/dev/null", O_RDONLY) != 0) { - syslog(LOG_NOTICE, "Reopen of stdin to /dev/null failed"); - _exit(2); - } - fclose(stdout); - if (open("/dev/null", O_WRONLY | O_APPEND | O_CREAT,0600) != 1) { - syslog(LOG_NOTICE, "Reopen of stdout to /dev/null failed"); - _exit(2); - } - fclose(stderr); - if (open("/dev/null", O_WRONLY | O_APPEND | O_CREAT,0600) != 2) { - syslog(LOG_NOTICE, "Reopen of stderr to /dev/null failed"); - _exit(2); - } - mypid = getpid(); - rc = server(); - break; - /* Not reached */ - default: - /* - * Here we detach this process and let the child - * run the deamon process. - */ - syslog(LOG_NOTICE, "Starting daemon with pid %d", frk); - exit(0); - } - } - - syslog(LOG_NOTICE, "Finished, rc=%d", rc); - return rc; -} - - - -int server(void) -{ - char buf[1024]; - w1_therm *tmp1; - int rc, run = 1, temp; - - if (lockprog((char *)"mash")) { - syslog(LOG_NOTICE, "Can't lock"); - return 1; - } - - rc = piThreadCreate(my_sensors_loop); - if (rc) { - fprintf(stderr, "my_sensors_loop thread didn't start rc=%d\n", rc); - syslog(LOG_NOTICE, "my_sensors_loop thread didn't start rc=%d", rc); - } - -// rc = piThreadCreate(my_server_loop); -// if (rc) { -// fprintf(stderr, "my_server_loop thread didn't start rc=%d\n", rc); -// syslog(LOG_NOTICE, "my_server_loop thread didn't start rc=%d", rc); -// } - - snprintf(buf, 1023, "temp,step,description"); - logger((char *)"mash.log", (char *)"mash", buf); - - do { - lcdupdate = FALSE; - - if (my_shutdown) - run = 0; - - tmp1 = Config.w1therms; -// if (((tmp1->lastval / 100) < (tempA - 5)) && (coolerA == 1)) { -// syslog(LOG_NOTICE, "Temperature A is %.1f, switched cooler off", (tmp1->lastval / 1000.0)); -// lcdupdate = TRUE; -// } -// if (((tmp1->lastval / 100) > (tempA + 5)) && (coolerA == 0)) { -// syslog(LOG_NOTICE, "Temperature A is %.1f, switched cooler on", (tmp1->lastval / 1000.0)); -// lcdupdate = TRUE; -// } - if (tmp1->update) { - tmp1->update = FALSE; - lcdupdate = TRUE; - } -// old1 = tmp1->next; -// tmp1 = old1; -// if (((tmp1->lastval / 100) < (tempB - 5)) && (coolerB == 1)) { -// syslog(LOG_NOTICE, "Temperature B is %.1f, switched cooler off", (tmp1->lastval / 1000.0)); -// lcdupdate = TRUE; -// } -// if (((tmp1->lastval / 100) > (tempB + 5)) && (coolerB == 0)) { -// syslog(LOG_NOTICE, "Temperature B is %.1f, switched cooler on", (tmp1->lastval / 1000.0)); -// lcdupdate = TRUE; -// } -// if (tmp1->update) { -// tmp1->update = FALSE; -// lcdupdate = TRUE; -// } - - if (run && lcdupdate) { - lcdPosition(lcdHandle, 0, 0); - tmp1 = Config.w1therms; - snprintf(buf, 16, "%4.1f %cC %s ", tmp1->lastval / 1000.0, 0xdf, tmp1->alias); - mb_lcdPuts(lcdHandle, buf); - temp = tmp1->lastval; -// old1 = tmp1->next; -// tmp1 = old1; - lcdPosition(lcdHandle, 0, 1); - snprintf(buf, 16, " "); - mb_lcdPuts(lcdHandle, buf); - snprintf(buf, 1023, "%.1f,%d,%s", temp / 1000.0, 1, (char *)"step description"); - logger((char *)"mash.log", (char *)"mash", buf); - } - usleep(100000); - - } while (run); - - if (debug) - fprintf(stdout, (char *)"Out of loop\n"); - - /* - * Give threads time to cleanup - */ - usleep(1500000); - - stopLCD(); - -// wrconfig((char *)"mash.conf"); - - ulockprog((char *)"mash"); - - if (debug) - fprintf(stdout, "Goodbye\n"); - - return 0; -} - -#else - - -int main(int argc, char *argv[]) -{ - parseBeerXML((char *)"/home/mbroek/Downloads/beerxml.xml"); - printBeerXML(); -// fprintf(stderr, "Compiled on a system without a wiringPi library.\n"); -// fprintf(stderr, "This program is useless and will do nothing.\n"); - return 0; -} - - -#endif diff -r 4eebab50993e -r 6d139c21e22c mash/mash.h --- a/mash/mash.h Sun Jul 15 14:08:19 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -#ifndef _MASH_H -#define _MASH_H - - -#define TRUE 1 -#define FALSE 0 - -#include "../config.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define MBSE_SS(x) (x)?(x):"(null)" - - -/* rdconfig.c */ -typedef struct _key_list { - char *key; - int (*prc)(char **); - char **dest; -} key_list; - -typedef struct _w1_therm { - struct _w1_therm *next; - char *master; /* Master for this device */ - int bus; /* Reserved for ds2482-800 */ - char *name; /* Name of this device */ - char *alias; /* Friendly name */ - int present; /* 1=present, 0=absent */ - int lastval; /* Last valid value */ - int update; /* Value updated */ -} w1_therm; - -typedef struct _sys_config { - char *name; /* Configuration name */ - int my_port; /* my client/server port */ - w1_therm *w1therms; /* 1-wire temp sensors */ - int lcd_cols; /* LCD display columns */ - int lcd_rows; /* LCD display rows */ -} sys_config; - - -void killconfig(void); -int rdconfig(char *); -int wrconfig(char *); - - - - -#endif - diff -r 4eebab50993e -r 6d139c21e22c mash/rdconfig.c --- a/mash/rdconfig.c Sun Jul 15 14:08:19 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,286 +0,0 @@ -/***************************************************************************** - * Copyright (C) 2014 - * - * Michiel Broek - * - * 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 EC-65K; see the file COPYING. If not, write to the Free - * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - *****************************************************************************/ - -#include "mash.h" -#include "xutil.h" - - -int debug = FALSE; -static char *mypath; -static char *k, *v; -static int linecnt = 0; -sys_config Config; /* System configuration */ - - - -static int getint(char **); -static int getw1(char **); - - -#define XSTR(x) #x -#define STR(x) XSTR(x) - -/* - * System configuration table - */ -key_list keytab[] = { - {(char *)"w1therm", getw1, (char **)&Config.w1therms}, - {(char *)"lcd_cols", getint, (char **)&Config.lcd_cols}, - {(char *)"lcd_rows", getint, (char **)&Config.lcd_rows}, - {NULL, NULL, NULL} -}; - - - -void killconfig(void) -{ - w1_therm *tmp1, *old1; - - if (Config.name) - free(Config.name); - Config.name = NULL; - - for (tmp1 = Config.w1therms; tmp1; tmp1 = old1) { - old1 = tmp1->next; - if (tmp1->master) - free(tmp1->master); - if (tmp1->name) - free(tmp1->name); - if (tmp1->alias) - free(tmp1->alias); - free(tmp1); - } - Config.w1therms = NULL; - Config.my_port = 6554; - - Config.lcd_cols = 16; - Config.lcd_rows = 2; -} - - - -int wrconfig(char *config) -{ - int rc = 0; - FILE *fp; - w1_therm *tmp1; - - if (getenv((char *)"USER") == NULL) { - mypath = xstrcpy((char *)"/root"); - } else { - mypath = xstrcpy(getenv((char *)"HOME")); - } - mypath = xstrcat(mypath, (char *)"/mbsepi-apps/"); - mypath = xstrcat(mypath, config); - - if (debug) - fprintf(stdout, "Writing %s\n", mypath); - - if ((fp = fopen(mypath, "w")) == NULL) { - syslog(LOG_NOTICE, "could not rewrite %s", mypath); - return 1; - } - - fprintf(fp, "# Configuration file for thermferm %s\n", VERSION); - fprintf(fp, "\n"); - - fprintf(fp, "# LCD display\n"); - fprintf(fp, "#\n"); - fprintf(fp, "lcd_cols %d\n", Config.lcd_cols); - fprintf(fp, "lcd_rows %d\n", Config.lcd_rows); - fprintf(fp, "\n"); - - fprintf(fp, "# DS18B20 temperature sensors on the 1-wire bus.\n"); - fprintf(fp, "#\n"); - fprintf(fp, "# kwd master bus name alias\n"); - for (tmp1 = Config.w1therms; tmp1; tmp1 = tmp1->next) { - fprintf(fp, "w1therm %s %d %s %s\n", tmp1->master, tmp1->bus, tmp1->name, tmp1->alias); - } - fprintf(fp, "\n"); - - fprintf(fp, "# End of generated configuration\n"); - fclose(fp); - syslog(LOG_NOTICE, "Written %s rc=%d", mypath, rc); - free(mypath); - mypath = NULL; - - return rc; -} - - - -int rdconfig(char *config) -{ - char buf[256], *p; - FILE *fp; - int i, rc = 0; - - 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 *)"/mbsepi-apps/"); - mypath = xstrcat(mypath, config); - if ((fp = fopen(mypath, "r")) == NULL) { - /* - * Not in the users home directory - */ - free(mypath); - mypath = xstrcpy((char *)"/etc/mbsepi-apps/"); - mypath = xstrcat(mypath, config); - if ((fp = fopen(mypath, "r")) == NULL) { - /* - * Try /usr/local/etc - */ - free(mypath); - mypath = xstrcpy((char *)"/usr/local/etc/mbsepi-apps/"); - mypath = xstrcat(mypath, config); - if ((fp = fopen(mypath, "r")) == NULL) { - syslog(LOG_NOTICE, "rdconfig: could find %s", config); - return 1; - } - } - } - syslog(LOG_NOTICE, "rdconfig: using %s", mypath); - - linecnt = 0; - while (fgets(buf, sizeof(buf) -1, fp)) { - linecnt++; - if (*(p = buf + strlen(buf) -1) != '\n') { - syslog(LOG_NOTICE, "rdconfig: %s(%d): \"%s\" - line too long", mypath, linecnt, buf); - rc = 1; - break; - } - *p-- = '\0'; - while ((p >= buf) && isspace(*p)) - *p-- = '\0'; - k = buf; - while (*k && isspace(*k)) - k++; - p = k; - while (*p && !isspace(*p)) - p++; - *p++='\0'; - v = p; - while (*v && isspace(*v)) - v++; - - if ((*k == '\0') || (*k == '#')) { - continue; - } - - for (i = 0; keytab[i].key; i++) - if (strcasecmp(k,keytab[i].key) == 0) - break; - - if (keytab[i].key == NULL) { - syslog(LOG_NOTICE, "rdconfig: %s(%d): %s %s - unknown keyword", mypath, linecnt, MBSE_SS(k), MBSE_SS(v)); - rc = 1; - break; - } else if ((keytab[i].prc(keytab[i].dest))) { - rc = 1; - break; - } - - } - fclose(fp); - - free(mypath); - mypath = NULL; - - return rc; -} - - - -static int getint(char **dest) -{ - if (debug) - syslog(LOG_NOTICE, "rdconfig: getint: %s(%d): %s %s", mypath, linecnt, MBSE_SS(k), MBSE_SS(v)); - - if (strspn(v,"0123456789") != strlen(v)) - syslog(LOG_NOTICE, "rdconfig: %s(%d): %s %s - bad numeric", mypath, linecnt, MBSE_SS(k), MBSE_SS(v)); - else - *((int*)dest)=atoi(v); - return 0; -} - - - -static int getw1(char **dest) -{ - char *p, *q = NULL, *r = NULL; - w1_therm **tmpm; - int rc = 0, tmpp; - - for (p = v; *p && !isspace(*p); p++); - if (*p) - *p++ = '\0'; - while (*p && isspace(*p)) - p++; - if (*p == '\0') { - syslog(LOG_NOTICE, "rdconfig: %s(%d): less then two tokens", mypath, linecnt); - return 1; - } - - for (q = p; *q && !isspace(*q); q++); - if (*q && isspace(*q)) { - if (*q) - *q++ = '\0'; - while (*q && isspace(*q)) - q++; - - for (r = q; *r && !isspace(*r); r++); - if (*r) - *r++ = '\0'; - rc = sscanf(p, "%d", &tmpp); - if (rc != 1) { - syslog(LOG_NOTICE, "rdconfig: getw1: %s(%d): %s is not a integer value", mypath, linecnt, p); - return 1; - } - if (debug) - syslog(LOG_NOTICE, "rdconfig: getw1: %s(%d): %s %d %s %s", mypath, linecnt, v, tmpp, q, r); - } - - for (tmpm = (w1_therm**)dest; *tmpm; tmpm=&((*tmpm)->next)); - (*tmpm) = (w1_therm *) xmalloc(sizeof(w1_therm)); - (*tmpm)->next = NULL; - (*tmpm)->master = xstrcpy(v); - (*tmpm)->bus = tmpp; - (*tmpm)->name = xstrcpy(q); - (*tmpm)->alias = xstrcpy(r); - (*tmpm)->present = 0; - (*tmpm)->lastval = 0; - (*tmpm)->update = 0; - - return 0; -} - - diff -r 4eebab50993e -r 6d139c21e22c mash/sensors.c --- a/mash/sensors.c Sun Jul 15 14:08:19 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,140 +0,0 @@ -/***************************************************************************** - * Copyright (C) 2014 - * - * Michiel Broek - * - * 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 EC-65K; see the file COPYING. If not, write to the Free - * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - *****************************************************************************/ - -#include "mash.h" -#include "xutil.h" - - -#ifdef HAVE_WIRINGPI_H - -/* wiringPi */ -#include -#include -#include - -extern int debug; -extern sys_config Config; -extern int my_shutdown; - - - -PI_THREAD (my_sensors_loop) -{ - w1_therm *tmp1, *old1; - char *device, line[60], *p = NULL; - FILE *fp; - int temp, rc, deviation; - - syslog(LOG_NOTICE, "Thread my_sensors_loop started"); - if (debug) - fprintf(stdout, "Thread my_sensors_loop started\n"); - - /* - * Loop forever until the external shutdown variable is set. - */ - for (;;) { - /* - * Here send our 1-wire sensors values - */ - for (tmp1 = Config.w1therms; tmp1; tmp1 = old1) { - old1 = tmp1->next; - - if (my_shutdown) { - syslog(LOG_NOTICE, "Thread my_sensors_loop stopped"); - if (debug) - fprintf(stdout, "Thread my_sensors_loop stopped\n"); - return 0; - } - - /* - * Build path to the on-wire sensor - */ - device = xstrcpy((char *)"/sys/bus/w1/devices/"); - device = xstrcat(device, tmp1->master); - device = xstrcat(device, (char *)"/"); - device = xstrcat(device, tmp1->name); - device = xstrcat(device, (char *)"/w1_slave"); - - /* - * Read sensor data - */ - if ((fp = fopen(device, "r"))) { - /* - * The output looks like: - * 72 01 4b 46 7f ff 0e 10 57 : crc=57 YES - * 72 01 4b 46 7f ff 0e 10 57 t=23125 - */ - fgets(line, 50, fp); - line[strlen(line)-1] = '\0'; - if ((line[36] == 'Y') && (line[37] == 'E')) { - /* - * CRC is Ok, continue - */ - fgets(line, 50, fp); - line[strlen(line)-1] = '\0'; - strtok(line, (char *)"="); - p = strtok(NULL, (char *)"="); - rc = sscanf(p, "%d", &temp); - if ((rc == 1) && (tmp1->lastval != temp)) { - /* - * It is possible to have read errors or extreme values. - * This can happen with bad connections so we compare the - * value with the previous one. If the difference is too - * much, we don't send that value. That also means that if - * the next value is ok again, it will be marked invalid too. - * Maximum error is 20 degrees for now. - */ - deviation = 20000; - if ( (tmp1->lastval == 0) || - (tmp1->lastval && (temp > (tmp1->lastval - deviation)) && (temp < (tmp1->lastval + deviation))) ) { - /* - * Temperature is changed and valid, set flag. - */ - tmp1->update = TRUE; - } else { - syslog(LOG_NOTICE, "deviation error deviation=%d, old=%d new=%d", deviation, tmp1->lastval, temp); - if (debug) { - fprintf(stdout, "deviation error deviation=%d, old=%d new=%d\n", deviation, tmp1->lastval, temp); - } - } - tmp1->lastval = temp; - } - } else { - syslog(LOG_NOTICE, "sensor %s/%s CRC error", tmp1->master, tmp1->name); - } - fclose(fp); - tmp1->present = 1; - } else { - tmp1->present = 0; - if (debug) - printf("sensor %s is missing\n", tmp1->name); - } - - free(device); - device = NULL; - } - } -} - - - -#endif diff -r 4eebab50993e -r 6d139c21e22c mash/sensors.h --- a/mash/sensors.h Sun Jul 15 14:08:19 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ -#ifndef _SENSORS_H -#define _SENSORS_H - - -#ifdef HAVE_WIRINGPI_H - -PI_THREAD (my_sensors_loop); - -#endif - -#endif diff -r 4eebab50993e -r 6d139c21e22c mash/xutil.c --- a/mash/xutil.c Sun Jul 15 14:08:19 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/***************************************************************************** - * Copyright (C) 2008-2014 - * - * Michiel Broek - * - * 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 EC-65K; see the file COPYING. If not, write to the Free - * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - *****************************************************************************/ - -#include "mash.h" -#include "xutil.h" - - -char *xmalloc(size_t size) -{ - char *tmp; - - tmp = malloc(size); - if (!tmp) - abort(); - - return tmp; -} - - - -char *xstrcpy(char *src) -{ - char *tmp; - - if (src == NULL) - return(NULL); - tmp = xmalloc(strlen(src)+1); - strcpy(tmp, src); - return tmp; -} - - - -char *xstrcat(char *src, char *add) -{ - char *tmp; - size_t size = 0; - - if ((add == NULL) || (strlen(add) == 0)) - return src; - if (src) - size = strlen(src); - size += strlen(add); - tmp = xmalloc(size + 1); - *tmp = '\0'; - if (src) { - strcpy(tmp, src); - free(src); - } - strcat(tmp, add); - return tmp; -} - - diff -r 4eebab50993e -r 6d139c21e22c mash/xutil.h --- a/mash/xutil.h Sun Jul 15 14:08:19 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -#ifndef _XUTIL_H -#define _XUTIL_H - -char *xmalloc(size_t); -char *xstrcpy(char *); -char *xstrcat(char *, char *); - -#endif diff -r 4eebab50993e -r 6d139c21e22c rc433/Makefile --- a/rc433/Makefile Sun Jul 15 14:08:19 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -# Makefile for the mbsePi-apps/thermometers. - -include ../Makefile.global - -SRCS = $(wildcard *.c) -HDRS = $(wildcard *.h) -OBJS = $(SRCS:.c=.o) -SLIBS = rc-switch.o xutil.o -TARGET = recv send sniffer -OTHER = Makefile - -############################################################################# - -.c.o: - ${CC} ${CFLAGS} ${INCLUDES} ${DEFINES} -c $< - -all: ${TARGET} - -recv: recv.o ${SLIBS} - ${CC} -o recv recv.o ${LDFLAGS} ${LIBS} ${SLIBS} - -send: send.o ${SLIBS} - ${CC} -o send send.o ${LDFLAGS} ${LIBS} ${SLIBS} - -sniffer: sniffer.o ${SLIBS} - ${CC} -o sniffer sniffer.o ${LDFLAGS} ${LIBS} ${SLIBS} -clean: - rm -f ${TARGET} *.o *.h~ *.c~ core filelist Makefile.bak - -install: all - ${INSTALL} -c -s -g root -o root -m 0755 ${TARGET} ${BINDIR} - -filelist: Makefile - BASE=`pwd`; \ - BASE=`basename $${BASE}`; \ - (for f in ${SRCS} ${HDRS} ${OTHER} ;do echo ${PACKAGE}-${VERSION}/$${BASE}/$$f; done) >filelist - -depend: - @rm -f Makefile.bak; \ - mv Makefile Makefile.bak; \ - sed -e '/^# DO NOT DELETE/,$$d' Makefile.bak >Makefile; \ - ${ECHO} '# DO NOT DELETE THIS LINE - MAKE DEPEND RELIES ON IT' \ - >>Makefile; \ - ${ECHO} '# Dependencies generated by make depend' >>Makefile; \ - for f in ${SRCS}; \ - do \ - ${ECHO} "Dependencies for $$f:\c"; \ - ${ECHO} "`basename $$f .c`.o:\c" >>Makefile; \ - for h in `sed -n -e \ - 's/^#[ ]*include[ ]*"\([^"]*\)".*/\1/p' $$f`; \ - do \ - ${ECHO} " $$h\c"; \ - ${ECHO} " $$h\c" >>Makefile; \ - done; \ - ${ECHO} " done."; \ - ${ECHO} "" >>Makefile; \ - done; \ - ${ECHO} '# End of generated dependencies' >>Makefile - -# DO NOT DELETE THIS LINE - MAKE DEPEND RELIES ON IT -# Dependencies generated by make depend -recv.o: rc433.h -sniffer.o: rc433.h -rc-switch.o: rc433.h -xutil.o: rc433.h -send.o: rc433.h -# End of generated dependencies diff -r 4eebab50993e -r 6d139c21e22c rc433/README --- a/rc433/README Sun Jul 15 14:08:19 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -A few demo programs for 433 MHz transmitters and receivers that I have -found on the internet and adapted for this project. - diff -r 4eebab50993e -r 6d139c21e22c rc433/rc-switch.c --- a/rc433/rc-switch.c Sun Jul 15 14:08:19 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,955 +0,0 @@ -/***************************************************************************** - * Copyright (C) 2014 - * - * Michiel Broek - * - * This file is part of the mbsePi-apps - * - * Based on the Arduino libary for remote control outlet switches. - * Project home: http://code.google.com/p/rc-switch/ - * - * 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 EC-65K; see the file COPYING. If not, write to the Free - * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - *****************************************************************************/ - -#include "rc433.h" - -#ifdef HAVE_WIRINGPI_H - - -#define TYPE_UNDEF 0 -#define TYPE_MINIMUM 0 -#define TYPE_A 1 -#define TYPE_B 2 -#define TYPE_C 3 -#define TYPE_D 4 -#define TYPE_E 3 // TODO: Which Protocol does REV use? -#define TYPE_MAXIMUM 4 - -// Number of maximum High/Low changes per packet. -// We can handle up to (unsigned long) => 32 bit * 2 H/L changes per bit + 2 for sync -#define RCSWITCH_MAX_CHANGES 67 - -// i.e. ProtocolCount + 1 (for TYPE_UNDEF) -#define MAX_PROTOCOLS 5 - -#define PROTOCOL_A_SYNC_FACTOR 31 -#define PROTOCOL_A_ZERO_FIRST_CYCLES 1 -#define PROTOCOL_A_ZERO_SECOND_CYCLES 3 -#define PROTOCOL_A_ONE_FIRST_CYCLES 3 -#define PROTOCOL_A_ONE_SECOND_CYCLES 1 -#define PROTOCOL_A_HIGH_FIRST true - -#define PROTOCOL_B_SYNC_FACTOR 10 -#define PROTOCOL_B_ZERO_FIRST_CYCLES 1 -#define PROTOCOL_B_ZERO_SECOND_CYCLES 2 -#define PROTOCOL_B_ONE_FIRST_CYCLES 2 -#define PROTOCOL_B_ONE_SECOND_CYCLES 1 -#define PROTOCOL_B_HIGH_FIRST true - -#define PROTOCOL_C_SYNC_FACTOR 71 -#define PROTOCOL_C_ZERO_FIRST_CYCLES 4 -#define PROTOCOL_C_ZERO_SECOND_CYCLES 11 -#define PROTOCOL_C_ONE_FIRST_CYCLES 9 -#define PROTOCOL_C_ONE_SECOND_CYCLES 6 -#define PROTOCOL_C_HIGH_FIRST true - -// I think, this will work for receive, however, I haven't tested, as I don't own a receiver... -// As Type D doesn't sync acc. to https://github.com/d-a-n/433-codes/blob/master/database.md#quigg -// the sync factor is totally undetermined. -// Malte Diers, 22.11.2013 -#define PROTOCOL_D_SYNC_FACTOR 1 -#define PROTOCOL_D_ZERO_FIRST_CYCLES 1 -#define PROTOCOL_D_ZERO_SECOND_CYCLES 2 -#define PROTOCOL_D_ONE_FIRST_CYCLES 2 -#define PROTOCOL_D_ONE_SECOND_CYCLES 1 -#define PROTOCOL_D_HIGH_FIRST false - - -#define PROTOCOL3_SYNC_FACTOR 71 -#define PROTOCOL3_0_HIGH_CYCLES 4 -#define PROTOCOL3_0_LOW_CYCLES 11 -#define PROTOCOL3_1_HIGH_CYCLES 9 -#define PROTOCOL3_1_LOW_CYCLES 6 - - - -unsigned long rcReceivedValue = 0; -unsigned int rcReceivedBitlength = 0; -unsigned int rcReceivedDelay = 0; -unsigned int rcReceivedProtocol = 0; -int rcReceiveTolerance = 60; -int rcReceiverInterruptPin = -1; - -unsigned int timings[RCSWITCH_MAX_CHANGES]; -int rcTransmitterPin = -1; -int rcPulseLength = 350; // thermometers 2.4 msec = 2400 -int rcRepeatTransmit = 10; -int rcProtocol = 1; - -int backupProtocol; -int backupPulseLength; -int backupRepeatTransmit; - - -//const char TYPE_A_CODE[ 6][6] = { "00000", "10000", "01000", "00100", "00010", "00001"}; -const char TYPE_B_CODE[ 5][5] = { "FFFF", "0FFF", "F0FF", "FF0F", "FFF0" }; -const char TYPE_C_CODE[16][5] = { "0000", "F000", "0F00", "FF00", "00F0", "F0F0", "0FF0", "FFF0", - "000F", "F00F", "0F0F", "FF0F", "00FF", "F0FF", "0FFF", "FFFF" }; -const char TYPE_D_CODE[5][2][9] = { { "11100001", "11110000" }, { "00000000", "00010001" }, { "10000010", "10010011" }, - { "11000011", "11010010" }, { "01000001", "01010000" } }; - /* Type A Type D */ -const int PULSE_LENGTH[MAX_PROTOCOLS] = { 0, 350, 650, 100, 666, }; -const int REPEAT_TRANSMIT[MAX_PROTOCOLS] = { 0, 10, 10, 10, 4, }; -const int SYNC_FACTOR[MAX_PROTOCOLS] = { 0, PROTOCOL_A_SYNC_FACTOR, PROTOCOL_B_SYNC_FACTOR, PROTOCOL_C_SYNC_FACTOR, PROTOCOL_D_SYNC_FACTOR, }; -const int ZERO_FIRST_CYCLES[MAX_PROTOCOLS] = { 0, PROTOCOL_A_ZERO_FIRST_CYCLES, PROTOCOL_B_ZERO_FIRST_CYCLES, PROTOCOL_C_ZERO_FIRST_CYCLES, PROTOCOL_D_ZERO_FIRST_CYCLES, }; -const int ZERO_SECOND_CYCLES[MAX_PROTOCOLS] = { 0, PROTOCOL_A_ZERO_SECOND_CYCLES, PROTOCOL_B_ZERO_SECOND_CYCLES, PROTOCOL_C_ZERO_SECOND_CYCLES, PROTOCOL_D_ZERO_SECOND_CYCLES, }; -const int ONE_FIRST_CYCLES[MAX_PROTOCOLS] = { 0, PROTOCOL_A_ONE_FIRST_CYCLES, PROTOCOL_B_ONE_FIRST_CYCLES, PROTOCOL_C_ONE_FIRST_CYCLES, PROTOCOL_D_ONE_FIRST_CYCLES, }; -const int ONE_SECOND_CYCLES[MAX_PROTOCOLS] = { 0, PROTOCOL_A_ONE_SECOND_CYCLES, PROTOCOL_B_ONE_SECOND_CYCLES, PROTOCOL_C_ONE_SECOND_CYCLES, PROTOCOL_D_ONE_SECOND_CYCLES, }; -const bool HIGH_FIRST[MAX_PROTOCOLS] = { 0, PROTOCOL_A_HIGH_FIRST, PROTOCOL_B_HIGH_FIRST, PROTOCOL_C_HIGH_FIRST, PROTOCOL_D_HIGH_FIRST, }; - - -char *getCodeWordA(char*, char*, bool); -char *getCodeWordB(int, int, bool); -char *getCodeWordC(char, int, int, bool); - -char *getCodeWordE(char, int, bool); -void sendTriState(char*); -void transmit(int, int, bool); -void send0(void); -void send1(void); -void sendT0(void); -void sendT1(void); -void sendTF(void); -void sendSync(void); -bool receiveProtocol(int, unsigned int); -void handleInterrupt(void); -char *dec2binWcharfill(unsigned long, unsigned int, char); - -void setReceiveTolerance(int); -void setProtocol(int); - -void saveProtocol(int); -void loadProtocol(void); - - - -/* - * Sets the protocol to send. - */ -void setProtocol(int nProtocol) { - - if ((nProtocol < TYPE_MINIMUM) || (nProtocol > TYPE_MAXIMUM)) { - return; - } - - rcProtocol = nProtocol; - rcPulseLength = PULSE_LENGTH[nProtocol]; - rcRepeatTransmit = REPEAT_TRANSMIT[nProtocol]; -} - - - -/* - * Set Receiving Tolerance - */ -void setReceiveTolerance(int nPercent) { - rcReceiveTolerance = nPercent; -} - - - -/* - * Enable transmissions - * - * @param nTransmitterPin Pin to which the sender is connected to - */ -void enableTransmit(int nTransmitterPin) { - rcTransmitterPin = nTransmitterPin; - pinMode(rcTransmitterPin, OUTPUT); -} - - - -/* - * Disable transmissions - */ -void disableTransmit(void) { - rcTransmitterPin = -1; -} - - - -/* - * Toggle switch, a command looks like B,3,2,1 which means switch type B, - * group 3, device 2, status on. - */ -int toggleSwitch(char *command) -{ - static char *cmd = NULL; - char *s, cType; - int rc, iGroup, iDevice, iState; - - cmd = xstrcpy(command); - s = strtok(cmd, ",\0"); - cType = s[0]; - - if (cType == 'A') { - - } else if (cType == 'B') { - s = strtok(NULL, ",\0"); - rc = sscanf(s, "%d", &iGroup); - if (rc != 1) - return 1; - s = strtok(NULL, ",\0"); - rc = sscanf(s, "%d", &iDevice); - if (rc != 1) - return 1; - s = strtok(NULL, ",\0"); - rc = sscanf(s, "%d", &iState); - if (rc != 1) - return 1; - free(cmd); - return toggleTypeB(iGroup, iDevice, iState); - } - - free(cmd); - return 1; -} - - - -/* - * Switch a remote switch on (Type E REV) - * - * @param sGroup Code of the switch group (A,B,C,D) - * @param nDevice Number of the switch itself (1..3) - * @param bStatus Status to toggle to - */ -int toggleTypeE(char sGroup, int nDevice, bool bStatus) { - sendTriState( getCodeWordE(sGroup, nDevice, bStatus) ); - return 0; -} - - - -/* - * Switch a remote switch on (Type C Intertechno) - * - * @param sFamily Familycode (a..f) - * @param nGroup Number of group (1..4) - * @param nDevice Number of device (1..4) - * @param bStatus Status to toggle to - */ -int toggleTypeC(char sFamily, int nGroup, int nDevice, bool bStatus) { - char *str = xstrcpy(getCodeWordC(sFamily, nGroup, nDevice, bStatus)); - - if (strlen(str) == 0) - return 1; - - saveProtocol(TYPE_A); // ??? - sendTriState( str ); - loadProtocol(); - free(str); - return 0; -} - - - -/* - * Switch a remote switch on/off (Type B with two rotary/sliding switches) - * - * @param iGroup Number of the switch group (1..4) - * @param iDevice Number of the switch itself (1..4) - * @param bStatus Status to toggle to - */ -int toggleTypeB(int iGroup, int iDevice, bool bStatus) -{ - char *str = xstrcpy(getCodeWordB(iGroup, iDevice, bStatus)); - - if (strlen(str) == 0) - return 1; - - saveProtocol(TYPE_A); // They do better with protocol A timings. - sendTriState( str ); - loadProtocol(); - free(str); - return 0; -} - - - -/* - * Switch a remote switch on (Type A with 10 pole DIP switches) - * - * @param sGroup Code of the switch group (refers to DIP switches 1..5 where "1" = on and "0" = off, if all DIP switches are on it's "11111") - * @param sDevice Code of the switch device (refers to DIP switches 6..10 (A..E) where "1" = on and "0" = off, if all DIP switches are on it's "11111") - * @param bStatus Status to toggle to - */ -int toggleTypeA(char* sGroup, char* sDevice, bool bStatus) { - char *str = xstrcpy(getCodeWordA(sGroup, sDevice, bStatus)); - - if (strlen(str) == 0) - return 1; - - saveProtocol(TYPE_A); - sendTriState( str ); - loadProtocol(); - free(str); - return 0; -} - - - -/* - * Returns a char[13], representing the Code Word to be send. - * A Code Word consists of 9 address bits, 3 data bits and one sync bit but in our case only the first 8 address bits and the last 2 data bits were used. - * A Code Bit can have 4 different states: "F" (floating), "0" (low), "1" (high), "S" (synchronous bit) - * - * +-------------------------------+--------------------------------+-----------------------------------------+-----------------------------------------+----------------------+------------+ - * | 4 bits address (switch group) | 4 bits address (switch number) | 1 bit address (not used, so never mind) | 1 bit address (not used, so never mind) | 2 data bits (on|off) | 1 sync bit | - * | 1=0FFF 2=F0FF 3=FF0F 4=FFF0 | 1=0FFF 2=F0FF 3=FF0F 4=FFF0 | F | F | on=FF off=F0 | S | - * +-------------------------------+--------------------------------+-----------------------------------------+-----------------------------------------+----------------------+------------+ - * - * @param nAddressCode Number of the switch group (1..4) - * @param nChannelCode Number of the switch itself (1..4) - * @param bStatus Wether to switch on (true) or off (false) - * - * @return char[13] - */ -char *getCodeWordB(int nAddressCode, int nChannelCode, bool bStatus) -{ - int i, nReturnPos = 0; - static char sReturn[13]; - - if (nAddressCode < 1 || nAddressCode > 4 || nChannelCode < 1 || nChannelCode > 4) { - return '\0'; - } - for (i = 0; i<4; i++) { - sReturn[nReturnPos++] = TYPE_B_CODE[nAddressCode][i]; - } - - for (i = 0; i<4; i++) { - sReturn[nReturnPos++] = TYPE_B_CODE[nChannelCode][i]; - } - - sReturn[nReturnPos++] = 'F'; - sReturn[nReturnPos++] = 'F'; - sReturn[nReturnPos++] = 'F'; - sReturn[nReturnPos++] = bStatus ? 'F' : '0'; - sReturn[nReturnPos] = '\0'; - - return sReturn; -} - - - -/* - * Returns a char[13], representing the Code Word to be send. - * - * getCodeWordA(char*, char*) - * - */ -char *getCodeWordA(char* sGroup, char* sDevice, bool bOn) -{ - static char sDipSwitches[13]; - int i, j = 0; - - for (i=0; i < 5; i++) { - sDipSwitches[j++] = (sGroup[i] == '0') ? 'F' : '0'; - } - - for (i=0; i < 5; i++) { - sDipSwitches[j++] = (sDevice[i] == '0') ? 'F' : '0'; - } - - if ( bOn ) { - sDipSwitches[j++] = '0'; - sDipSwitches[j++] = 'F'; - } else { - sDipSwitches[j++] = 'F'; - sDipSwitches[j++] = '0'; - } - - sDipSwitches[j] = '\0'; - return sDipSwitches; -} - - - -/* - * Like getCodeWord (Type C = Intertechno) - */ -char *getCodeWordC(char sFamily, int nGroup, int nDevice, bool bStatus) -{ - static char sReturn[13]; - int i, nReturnPos = 0; - - if (sFamily < 'a') { - // To also enable capital 'A' to 'F' - sFamily += 32; - } - - if ( sFamily < 'a' || sFamily > 'f' || nGroup < 1 || nGroup > 4 || nDevice < 1 || nDevice > 4) { - return '\0'; - } - - for (i = 0; i<4; i++) { - sReturn[nReturnPos++] = TYPE_C_CODE[ sFamily - 'a' ][i]; - } - - char *sDeviceGroupCode = dec2binWzerofill( (nDevice-1) + (nGroup-1)*4, 4 ); - for (i = 0; i<4; i++) { - sReturn[nReturnPos++] = (sDeviceGroupCode[3-i] == '1' ? 'F' : '0'); - } - - sReturn[nReturnPos++] = '0'; - sReturn[nReturnPos++] = 'F'; - sReturn[nReturnPos++] = 'F'; - sReturn[nReturnPos++] = bStatus ? 'F' : '0'; - sReturn[nReturnPos] = '\0'; - - return sReturn; -} - - - -/* - * Decoding for the Quigg Switch Type - * - * Returns a char[22], representing the States to be send. - * A Code Word consists of 1 start bit, 12 address bits and 8 command data bits. - * A Code Bit can have 2 different states: "0" (low), "1" (high) - * - * +--------------+--------------------------------+------------------------------+ - * | 1 bits start | 12 bits address (device group) | 8 bits (command/switch data) | - * | 1 | 110011001100 | 00010001 | - * +--------------+--------------------------------+------------------------------+ - * - * Source: https://github.com/d-a-n/433-codes/blob/master/database.md#quigg - * - * @param sGroup 12-bit Binary ID of the Device Group - * @param nDevice Number of the switch itself (1..4, or 0 to switch the entire Group) - * @param bStatus Wether to switch on (true) or off (false) - * - * @return char[22] - */ -char *getCodeWordD(char *sGroup, int nDevice, bool bStatus) -{ - static char sReturn[22]; - int i, nReturnPos = 0; - - /* Startbit */ - sReturn[nReturnPos++] = '1'; - - /* 12 bit Group */ - for (i = 0; i < 12; ++i) { - sReturn[nReturnPos++] = sGroup[i]; - } - - /* 8 Bit Device Identifier + Status (undividable!) */ - for (i = 0; i < 8; ++i) { - sReturn[nReturnPos++] = TYPE_D_CODE[nDevice][bStatus][i]; - } - sReturn[nReturnPos] = 0; - - return sReturn; -} - - - -/* - * Decoding for the REV Switch Type - * - * Returns a char[13], representing the Tristate to be send. - * A Code Word consists of 7 address bits and 5 command data bits. - * A Code Bit can have 3 different states: "F" (floating), "0" (low), "1" (high) - * - * +-------------------------------+--------------------------------+-----------------------+ - * | 4 bits address (switch group) | 3 bits address (device number) | 5 bits (command data) | - * | A=1FFF B=F1FF C=FF1F D=FFF1 | 1=0FFF 2=F0FF 3=FF0F 4=FFF0 | on=00010 off=00001 | - * +-------------------------------+--------------------------------+-----------------------+ - * - * Source: http://www.the-intruder.net/funksteckdosen-von-rev-uber-arduino-ansteuern/ - * - * @param sGroup Name of the switch group (A..D, resp. a..d) - * @param nDevice Number of the switch itself (1..3) - * @param bStatus Wether to switch on (true) or off (false) - * - * @return char[13] - */ -char *getCodeWordE(char sGroup, int nDevice, bool bStatus){ - static char sReturn[13]; - int i, nReturnPos = 0; - - // Building 4 bits address - // (Potential problem if dec2binWcharfill not returning correct string) - char *sGroupCode; - switch(sGroup){ - case 'a': - case 'A': - sGroupCode = dec2binWcharfill(8, 4, 'F'); break; - case 'b': - case 'B': - sGroupCode = dec2binWcharfill(4, 4, 'F'); break; - case 'c': - case 'C': - sGroupCode = dec2binWcharfill(2, 4, 'F'); break; - case 'd': - case 'D': - sGroupCode = dec2binWcharfill(1, 4, 'F'); break; - default: - return '\0'; - } - - for (i = 0; i<4; i++) { - sReturn[nReturnPos++] = sGroupCode[i]; - } - - - // Building 3 bits address - // (Potential problem if dec2binWcharfill not returning correct string) - char *sDevice; - switch(nDevice) { - case 1: - sDevice = dec2binWcharfill(4, 3, 'F'); break; - case 2: - sDevice = dec2binWcharfill(2, 3, 'F'); break; - case 3: - sDevice = dec2binWcharfill(1, 3, 'F'); break; - default: - return '\0'; - } - - for (i = 0; i<3; i++) - sReturn[nReturnPos++] = sDevice[i]; - - // fill up rest with zeros - for (i = 0; i<5; i++) - sReturn[nReturnPos++] = '0'; - - // encode on or off - if (bStatus) - sReturn[10] = '1'; - else - sReturn[11] = '1'; - - // last position terminate string - sReturn[12] = '\0'; - return sReturn; - -} - - - -/* - * @param sCodeWord /^[10FS]*$/ -> see getCodeWord - */ -void sendTriState(char* sCodeWord) { - int nRepeat; - - for (nRepeat = 0; nRepeat < rcRepeatTransmit; nRepeat++) { - int i = 0; - while (sCodeWord[i] != '\0') { - switch(sCodeWord[i]) { - case '0': - sendT0(); - break; - case 'F': - sendTF(); - break; - case '1': - sendT1(); - break; - } - i++; - } - sendSync(); - } -} - - - -/* -void RCSwitch::send(unsigned long Code, unsigned int length) { - this->send( this->dec2binWzerofill(Code, length) ); -} - -void RCSwitch::send(char* sCodeWord) { - for (int nRepeat=0; nRepeatsend0(); - break; - case '1': - this->send1(); - break; - } - i++; - } - this->sendSync(); - } -} -*/ - - -void transmit(int nFirstPulses, int nSecondPulses, bool bHighFirst) -{ - bool disabled_Receive = false; - int nReceiverInterrupt_backup = rcReceiverInterruptPin; - - if (rcTransmitterPin != -1) { - if (rcReceiverInterruptPin != -1) { - disableReceive(); - disabled_Receive = true; - } - digitalWrite(rcTransmitterPin, bHighFirst ? HIGH : LOW); - delayMicroseconds( rcPulseLength * nFirstPulses); - digitalWrite(rcTransmitterPin, bHighFirst ? LOW : HIGH); - delayMicroseconds( rcPulseLength * nSecondPulses); - - if (disabled_Receive) { - enableReceiveIRQ(nReceiverInterrupt_backup); - } - } -} - - - -/* - * Sends a "0" Bit - * _ - * Waveform Protocol 1: | |___ - * _ - * Waveform Protocol 2: | |__ - * ____ - * Waveform Protocol 3: | |___________ - */ -//void send0(void) { -// if (rcProtocol == 1){ -// transmit(1,3); -// } -// else if (rcProtocol == 2) { -// transmit(1,2); -// } -// else if (rcProtocol == 3) { -// transmit(4,11); -// } -//} - - - -/* - * Sends a "1" Bit - * ___ - * Waveform Protocol 1: | |_ - * __ - * Waveform Protocol 2: | |_ - * _________ - * Waveform Protocol 3: | |______ - */ -//void send1(void) { -// if (rcProtocol == 1){ -// transmit(3,1); -// } -// else if (rcProtocol == 2) { -// transmit(2,1); -// } -// else if (rcProtocol == 3) { -// transmit(9,6); -// } -//} - - - -/* - * Sends a Tri-State "0" Bit - * _ _ - * Waveform: | |___| |___ - */ -void sendT0(void) { - transmit(ZERO_FIRST_CYCLES[rcProtocol], ZERO_SECOND_CYCLES[rcProtocol], HIGH_FIRST[rcProtocol]); - transmit(ZERO_FIRST_CYCLES[rcProtocol], ZERO_SECOND_CYCLES[rcProtocol], HIGH_FIRST[rcProtocol]); -// transmit(1,3,true); -// transmit(1,3,true); -} - - - -/* - * Sends a Tri-State "1" Bit - * ___ ___ - * Waveform: | |_| |_ - */ -void sendT1(void) { - transmit(ONE_FIRST_CYCLES[rcProtocol], ONE_SECOND_CYCLES[rcProtocol], HIGH_FIRST[rcProtocol]); - transmit(ONE_FIRST_CYCLES[rcProtocol], ONE_SECOND_CYCLES[rcProtocol], HIGH_FIRST[rcProtocol]); -// transmit(3,1,true); -// transmit(3,1,true); -} - - - -/* - * Sends a Tri-State "F" Bit - * _ ___ - * Waveform: | |___| |_ - */ -void sendTF(void) { - transmit(ZERO_FIRST_CYCLES[rcProtocol], ZERO_SECOND_CYCLES[rcProtocol], HIGH_FIRST[rcProtocol]); - transmit(ONE_FIRST_CYCLES[rcProtocol], ONE_SECOND_CYCLES[rcProtocol], HIGH_FIRST[rcProtocol]); -// transmit(1,3,true); -// transmit(3,1,true); -} - - - -/* - * Sends a "Sync" Bit - * _ - * Waveform Protocol 1: | |_______________________________ - * _ - * Waveform Protocol 2: | |__________ - * ____ - * Waveform Protocol 3: | |_______________________________________________________________________ - * - * Waveform Protocol D: (none, just pause 80 msecs) - */ -void sendSync(void) { - - if (rcProtocol == TYPE_A) { - transmit(1,31,true); - } else if (rcProtocol == TYPE_B) { - transmit(1,10,true); - } else if (rcProtocol == TYPE_C) { - transmit(4,71,true); - } else if (rcProtocol == TYPE_D) { - transmit(0,1,false); - delayMicroseconds(80000); - } -} - - - -/* - * Enable receiving data - */ -void enableReceiveIRQ(int Pin) { - rcReceiverInterruptPin = Pin; - enableReceive(); -} - -void enableReceive(void) { - if (rcReceiverInterruptPin != -1) { - rcReceivedValue = 0; - rcReceivedBitlength = 0; - wiringPiISR(rcReceiverInterruptPin, INT_EDGE_BOTH, &handleInterrupt); - } -} - - - -/* - * Disable receiving data - */ -void disableReceive() { - // wiringPi disable interrupts ??? - rcReceiverInterruptPin = -1; -} - - - -bool available(void) { - return rcReceivedValue != 0; -} - - - -void resetAvailable(void) { - rcReceivedValue = 0; -} - - - -unsigned long getReceivedValue(void) { - return rcReceivedValue; -} - - - -unsigned int getReceivedBitlength(void) { - return rcReceivedBitlength; -} - - - -unsigned int getReceivedDelay(void) { - return rcReceivedDelay; -} - - - -unsigned int getReceivedProtocol(void) { - return rcReceivedProtocol; -} - - - -unsigned int* getReceivedRawdata(void) { - return timings; -} - - - -/* - * ASK protool 1 - */ -bool receiveProtocol(int prot, unsigned int changeCount) -{ - unsigned long code = 0; - unsigned long ldelay = timings[0] / SYNC_FACTOR[prot]; - unsigned long delayTolerance = ldelay * rcReceiveTolerance * 0.01; - int i; - - if (prot < TYPE_MINIMUM || prot > TYPE_MAXIMUM) { - return false; - } - - for (i = 1; i ldelay * ZERO_FIRST_CYCLES[prot] - delayTolerance && - timings[i] < ldelay * ZERO_FIRST_CYCLES[prot] + delayTolerance && - timings[i+1] > ldelay * ZERO_SECOND_CYCLES[prot] - delayTolerance && - timings[i+1] < ldelay * ZERO_SECOND_CYCLES[prot] + delayTolerance) { - code = code << 1; - } else if (timings[i] > ldelay * ONE_FIRST_CYCLES[prot] - delayTolerance && - timings[i] < ldelay * ONE_FIRST_CYCLES[prot] + delayTolerance && - timings[i+1] > ldelay * ONE_SECOND_CYCLES[prot] - delayTolerance && - timings[i+1] < ldelay * ONE_SECOND_CYCLES[prot] + delayTolerance) { - code+=1; - code = code << 1; - } else { - // Failed - i = changeCount; - code = 0; - } - } - code = code >> 1; - if (changeCount > 6) { // ignore < 4bit values as there are no devices sending 4bit values => noise - rcReceivedValue = code; - rcReceivedBitlength = changeCount / 2; - rcReceivedDelay = ldelay; - rcReceivedProtocol = prot; - } - - return (code != 0); -} - - - -void handleInterrupt() { - - static unsigned int duration; - static unsigned int changeCount; - static unsigned long lastTime; - static unsigned int repeatCount; - - - long thistime = micros(); - duration = thistime - lastTime; - - if (duration > 5000 && duration > timings[0] - 200 && duration < timings[0] + 200) { - repeatCount++; - changeCount--; - if (repeatCount == 2) { - if (receiveProtocol(TYPE_A, changeCount) == false) { - if (receiveProtocol(TYPE_B, changeCount) == false) { - if (receiveProtocol(TYPE_C, changeCount) == false) { - if (receiveProtocol(TYPE_D, changeCount) == false) { - //failed - } - } - } - } - repeatCount = 0; - } - changeCount = 0; - } else if (duration > 5000) { - changeCount = 0; - } - - if (changeCount >= RCSWITCH_MAX_CHANGES) { - changeCount = 0; - repeatCount = 0; - } - timings[changeCount++] = duration; - lastTime = thistime; -} - - - -/* - * Turns a decimal value to its binary representation - */ -char *dec2binWzerofill(unsigned long Dec, unsigned int bitLength) -{ - return dec2binWcharfill(Dec, bitLength, '0'); -} - -char *dec2binWcharfill(unsigned long Dec, unsigned int bitLength, char fill) -{ - static char bin[64]; - unsigned int i = 0, j; - - while (Dec > 0) { - bin[32+i++] = ((Dec & 1) > 0) ? '1' : fill; - Dec = Dec >> 1; - } - - for (j = 0; j< bitLength; j++) { - if (j >= bitLength - i) { - bin[j] = bin[ 31 + i - (j - (bitLength - i)) ]; - } else { - bin[j] = fill; - } - } - bin[bitLength] = '\0'; - - return bin; -} - - -void saveProtocol(int prot) -{ - backupProtocol = rcProtocol; - backupPulseLength = rcPulseLength; - backupRepeatTransmit = rcRepeatTransmit; - - setProtocol(prot); -} - - - -void loadProtocol(void) -{ - rcProtocol = backupProtocol; - rcPulseLength = backupPulseLength; - rcRepeatTransmit = backupRepeatTransmit; -} - - -#endif - diff -r 4eebab50993e -r 6d139c21e22c rc433/rc433.h --- a/rc433/rc433.h Sun Jul 15 14:08:19 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -#ifndef _RC433_H -#define _RC433_H - -#define TRUE 1 -#define FALSE 0 - -#include "../config.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_WIRINGPI_H - -/* wiringPi */ -#include - - -/* rc-switch.c */ -int toggleSwitch(char *); -int toggleTypeA(char *, char *, bool); -int toggleTypeB(int, int, bool); -int toggleTypeC(char, int, int, bool); -int toggleTypeE(char, int, bool); - -void enableReceiveIRQ(int interrupt); -void enableReceive(void); -void disableReceive(void); -bool available(void); -void resetAvailable(void); - -unsigned long getReceivedValue(void); -unsigned int getReceivedBitlength(void); -unsigned int getReceivedDelay(void); -unsigned int getReceivedProtocol(void); -unsigned int *getReceivedRawdata(void); - -void enableTransmit(int); -void disableTransmit(void); - -char *dec2binWzerofill(unsigned long, unsigned int); - - -/* xutil.c */ -char *xmalloc(size_t); -char *xstrcpy(char *); -char *xstrcat(char *, char *); - -#endif - - -#endif diff -r 4eebab50993e -r 6d139c21e22c rc433/recv.c --- a/rc433/recv.c Sun Jul 15 14:08:19 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +0,0 @@ -/***************************************************************************** - * Copyright (C) 2014 - * - * Michiel Broek - * - * 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 EC-65K; see the file COPYING. If not, write to the Free - * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - *****************************************************************************/ - -#include "rc433.h" - - -#ifdef HAVE_WIRINGPI_H - -int main(int argc, char *argv[]) { - - /* - input PIN is hardcoded for testing purposes - see https://projects.drogon.net/raspberry-pi/wiringpi/pins/ - for pin mapping of the raspberry pi GPIO connector - */ - int PIN = 2; - - if (wiringPiSetup () ) - return 1; - - enableReceiveIRQ(PIN); - - while (1) { - if (available()) { - - unsigned long int value = getReceivedValue(); - int bitlen = getReceivedBitlength(); - - if (value == 0) { - printf("Unknown encoding\n"); - } else { - if (bitlen == 24) { - printf("Received 0x%06lx/24 bit %s Protocol: %d", value, dec2binWzerofill(value, bitlen), getReceivedProtocol() ); - if ((value & 0x00000000000003f0) == 0x0000000000000150) { - printf(" Type A "); - printf("%c%c%c%c%c ", (value & 0xc00000) ? '0' : '1', (value & 0x300000) ? '0' : '1', (value & 0x0c0000) ? '0' : '1', (value & 0x030000) ? '0' : '1', (value & 0x00c000) ? '0' : '1'); - printf("%c%c%c%c%c ", (value & 0x003000) ? '0' : '1', (value & 0x000c00) ? '0' : '1', (value & 0x000300) ? '0' : '1', (value & 0x0000c0) ? '0' : '1', (value & 0x000030) ? '0' : '1'); - } - if ((value & 0x000000000000001c) == 0x0000000000000000) { - printf(" Type E"); - } - printf("\n"); - } else { - printf("Received 0x%lx/%d bit %s Protocol: %d\n", value, bitlen, dec2binWzerofill(value, bitlen), getReceivedProtocol() ); - } - } - - resetAvailable(); - } else { - /* - * Don't hog the CPU. - */ - delay(10); - } - } - - return 0; -} - -#else - -int main(int argc, char *argv[]) { - fprintf(stderr, "This program does nothing without the wiringPi library\n"); - return 0; -} - -#endif - diff -r 4eebab50993e -r 6d139c21e22c rc433/send.c --- a/rc433/send.c Sun Jul 15 14:08:19 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,225 +0,0 @@ -/***************************************************************************** - * Copyright (C) 2014 - * - * Michiel Broek - * - * 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 EC-65K; see the file COPYING. If not, write to the Free - * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - *****************************************************************************/ - -#include "rc433.h" - -#ifdef HAVE_WIRINGPI_H - -void help(void) -{ - fprintf(stdout, "mbsePi-apps send v%s\n\n", VERSION); - fprintf(stdout, "Usage: send [-t type ] [-f family ] [-g group ] [-d device] [-s state ] [-h]\n"); - fprintf(stdout, " send -t A -g 00001 -d 00001 -s 1\n"); - fprintf(stdout, " send -t B -g 2 -d 2 -s 0\n"); - fprintf(stdout, " send -t C -f c -g 3 -d 3 -s 1\n"); - fprintf(stdout, "\n"); - fprintf(stdout, " send -t E -g A -d 2 -s 0\n"); -} - - - -int isAcode(char *s) -{ - int i; - - if (strlen(s) != 5) - return FALSE; - for (i = 0; i < 5; i++) { - if ((s[i] < '0') || (s[i] > '1')) - return FALSE; - } - - return TRUE; -} - - - -/* - * A - char group, char device (2 x 5 binary) - * B - int system, int unit - * C - char family, int group, int device - * D - char group, int device - */ - -int main(int argc, char *argv[]) { - char buf[127], *endptr; - int c; - char cType = '0', *sGroup = NULL, *sDevice = NULL, cFamily = '0', cGroup = '0'; - int iState = -1, iGroup = -1, iDevice = -1; - - while (1) { - int option_index = 0; - static struct option long_options[] = { - {"device", 1, 0, 'd'}, - {"family", 1, 0, 'f'}, - {"group", 1, 0, 'g'}, - {"help", 0, 0, 'h'}, - {"state", 1, 0, 's'}, - {"type", 1, 0, 't'}, - {0, 0, 0, 0} - }; - - c = getopt_long(argc, argv, "d:f:g:hs:t:", long_options, &option_index); - if (c == -1) - break; - - switch (c) { - case 'd': snprintf(buf, 127, "%s", optarg); - if (cType == 'A') { - sDevice = xstrcpy(buf); - } else { - iDevice = strtol(buf, &endptr, 10); - } - break; - case 'f': snprintf(buf, 127, "%s", optarg); - if (cType == 'C') { - cFamily = tolower(buf[0]); - } - break; - case 'g': snprintf(buf, 127, "%s", optarg); - if (cType == 'A') { - sGroup = xstrcpy(buf); - } else if (cType == 'E') { - cGroup = toupper(buf[0]); - } else { - iGroup = strtol(buf, &endptr, 10); - } - break; - case 'h': help(); - return 1; - case 's': snprintf(buf, 127, "%s", optarg); - iState = strtol(buf, &endptr, 10); - break; - case 't': snprintf(buf, 127, "%s", optarg); - cType = toupper(buf[0]); - break; - } - } - - /* - * Check all option and combinations - */ - if ((cType < 'A') || (cType > 'E')) { - fprintf(stderr, "Type must be A, B, C or E\n"); - return 1; - } - if ((iState < 0) || (iState > 1)) { - fprintf(stderr, "State must be 0 or 1\n"); - return 1; - } - if (cType == 'A') { - if (sGroup == NULL) { - fprintf(stderr, "Group not set\n"); - return 1; - } - if (sDevice == NULL) { - fprintf(stderr, "Device not set\n"); - return 1; - } - if (isAcode(sGroup) == FALSE) { - fprintf(stderr, "Group must be 5 binary digits like 10000\n"); - return 1; - } - if (isAcode(sDevice) == FALSE) { - fprintf(stderr, "Device must be 5 binary digits like 10000\n"); - return 1; - } - } else { - if (iDevice == -1) { - fprintf(stderr, "Device not set\n"); - return 1; - } - } - if ((cType == 'B') || (cType == 'C')) { - if (iGroup == -1) { - fprintf(stderr, "Group not set\n"); - return 1; - } - if ((iGroup < 1) || (iGroup > 4)) { - fprintf(stderr, "Group must be 1..4\n"); - return 1; - } - if ((iDevice < 1) || (iDevice > 4)) { - fprintf(stderr, "Device must be 1..4\n"); - return 1; - } - } - if (cType == 'E') { - if ((iDevice < 1) || (iDevice > 3)) { - fprintf(stderr, "Device must be 1..3\n"); - return 1; - } - if ((cGroup < 'A') || (cGroup > 'D')) { - fprintf(stderr, "Group must be A..D\n"); - return 1; - } - } - if (cType == 'C') { - if ((cFamily < 'a') || (cFamily > 'f')) { - fprintf(stderr, "Family must be a..f\n"); - return 1; - } - } - - /* - output PIN is hardcoded for testing purposes - see https://projects.drogon.net/raspberry-pi/wiringpi/pins/ - for pin mapping of the raspberry pi GPIO connector - */ - int PIN = 0; - - if (wiringPiSetup () ) - return 1; - - enableTransmit(PIN); - switch (cType) { - case 'A': - printf("Type A sending group[%s] device[%s] command[%d]\n", sGroup, sDevice, iState); - toggleTypeA(sGroup, sDevice, iState); - break; - case 'B': - printf("Type B sending group[%d] device[%i] command[%i]\n", iGroup, iDevice, iState); - toggleTypeB(iGroup, iDevice, iState); - break; - case 'C': - printf("Type C sending family[%c] group[%d] device[%i] command[%i]\n", cFamily, iGroup, iDevice, iState); - toggleTypeC(cFamily, iGroup, iDevice, iState); - break; - case 'E': - printf("Type E sending group[%c] device[%i] command[%i]\n", cGroup, iDevice, iState); - toggleTypeE(cGroup, iDevice, iState); - break; - } - disableTransmit(); - - return 0; -} - -#else - -int main(int argc, char *argv[]) { - fprintf(stderr, "This program does nothing without the wiringPi library\n"); - return 0; -} - -#endif - diff -r 4eebab50993e -r 6d139c21e22c rc433/sniffer.c --- a/rc433/sniffer.c Sun Jul 15 14:08:19 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -/***************************************************************************** - * Copyright (C) 2014 - * - * Michiel Broek - * - * 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 EC-65K; see the file COPYING. If not, write to the Free - * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - *****************************************************************************/ - -#include "rc433.h" - -#ifdef HAVE_WIRINGPI_H - -int main(int argc, char *argv[]) { - - // This pin is not the first pin on the RPi GPIO header! - // Consult https://projects.drogon.net/raspberry-pi/wiringpi/pins/ - // for more information. - int PIN = 2; - - if (wiringPiSetup() == -1) - return 0; - - enableReceiveIRQ(PIN); // Receiver on inerrupt 0 => that is pin #2 - - while(1) { - - if (available()) { - unsigned long value = getReceivedValue(); - - if (value == 0) { - printf("Unknown encoding\n"); - } else { - printf("Protocol %d received 0x%lx\n", getReceivedProtocol(), value); - } - resetAvailable(); - - } else { - /* - * Don't hog the CPU - */ - delay(10); - } - } - - exit(0); -} - -#else - -int main(int argc, char *argv[]) { - fprintf(stderr, "This program does nothing without the wiringPi library\n"); - return 0; -} - -#endif - diff -r 4eebab50993e -r 6d139c21e22c rc433/xutil.c --- a/rc433/xutil.c Sun Jul 15 14:08:19 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/***************************************************************************** - * Copyright (C) 2008-2014 - * - * Michiel Broek - * - * 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 EC-65K; see the file COPYING. If not, write to the Free - * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - *****************************************************************************/ - -#include "rc433.h" - - -char *xmalloc(size_t size) -{ - char *tmp; - - tmp = malloc(size); - if (!tmp) - abort(); - - return tmp; -} - - - -char *xstrcpy(char *src) -{ - char *tmp; - - if (src == NULL) - return(NULL); - tmp = xmalloc(strlen(src)+1); - strcpy(tmp, src); - return tmp; -} - - - -char *xstrcat(char *src, char *add) -{ - char *tmp; - size_t size = 0; - - if ((add == NULL) || (strlen(add) == 0)) - return src; - if (src) - size = strlen(src); - size += strlen(add); - tmp = xmalloc(size + 1); - *tmp = '\0'; - if (src) { - strcpy(tmp, src); - free(src); - } - strcat(tmp, add); - return tmp; -} - -