Added device configuration

Thu, 31 Jul 2014 17:44:50 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Thu, 31 Jul 2014 17:44:50 +0200
changeset 158
f1b7e2ef90be
parent 157
259a018758f9
child 159
9ebc2ad9ebfb

Added device configuration

thermferm/Makefile file | annotate | diff | comparison | revisions
thermferm/devices.c file | annotate | diff | comparison | revisions
thermferm/devices.h file | annotate | diff | comparison | revisions
thermferm/rdconfig.c file | annotate | diff | comparison | revisions
thermferm/server.c file | annotate | diff | comparison | revisions
thermferm/thermferm.c file | annotate | diff | comparison | revisions
thermferm/thermferm.h file | annotate | diff | comparison | revisions
--- a/thermferm/Makefile	Thu Jul 31 13:43:09 2014 +0200
+++ b/thermferm/Makefile	Thu Jul 31 17:44:50 2014 +0200
@@ -54,8 +54,9 @@
 
 # DO NOT DELETE THIS LINE - MAKE DEPEND RELIES ON IT
 # Dependencies generated by make depend
-thermferm.o: lock.h logger.h rdconfig.h sensors.h server.h thermferm.h lcd-pcf8574.h lcd-buffer.h futil.h units.h xutil.h
+thermferm.o: lock.h logger.h rdconfig.h sensors.h devices.h server.h thermferm.h lcd-pcf8574.h lcd-buffer.h futil.h units.h xutil.h
 sensors.o: sensors.h thermferm.h xutil.h
+devices.o: devices.h thermferm.h xutil.h
 lcd-buffer.o: thermferm.h lcd-buffer.h lcd-pcf8574.h
 futil.o: thermferm.h futil.h
 lock.o: lock.h thermferm.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/thermferm/devices.c	Thu Jul 31 17:44:50 2014 +0200
@@ -0,0 +1,229 @@
+/*****************************************************************************
+ * Copyright (C) 2014
+ *   
+ * Michiel Broek <mbroek at mbse dot eu>
+ *
+ * This file is part of the mbsePi-apps
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * mbsePi-apps is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with thermferm; see the file COPYING.  If not, write to the Free
+ * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *****************************************************************************/
+
+#include "devices.h"
+#include "thermferm.h"
+#include "xutil.h"
+
+
+extern int		debug;
+extern sys_config	Config;
+extern int		my_shutdown;
+
+
+
+/*
+ * Auto detect hotplugged or known to be present devices
+ */
+int devices_detect(void)
+{
+    struct dirent	*de;
+//    FILE		*fp;
+    DIR			*fd;
+    devices_list	*device, *ndev;
+    int			found, subdevices, i, rc = 0;
+    char		*family;
+    uuid_t		uu;
+
+    /*
+     * Scan for 1-wire devices
+     */
+    if ((fd = opendir((char *)"/sys/bus/w1/devices"))) {
+	while ((de = readdir(fd))) {
+	    if (de->d_name[0] != '.') {
+		found = FALSE;
+		for (device = Config.devices; device; device = device->next) {
+		    if (strcmp(device->address ,de->d_name) == 0) {
+			found = TRUE;
+			break;
+		    }
+		}
+
+		if (found == FALSE) {
+		    family = malloc(3);
+		    strncpy(family, de->d_name, 2);
+		    subdevices = 1;
+		    if (strcmp(family, (char *)"29") == 0)
+			subdevices = 8;
+		    if (strcmp(family, (char *)"3a") == 0)
+			subdevices = 2;
+		    for (i = 0; i < subdevices; i++) {
+			ndev = (devices_list *)malloc(sizeof(devices_list));
+			ndev->next = NULL;
+			ndev->version = 1;
+			ndev->uuid = malloc(37);
+			uuid_generate(uu);
+			uuid_unparse(uu, ndev->uuid);
+			ndev->type = DEVTYPE_W1;
+			ndev->direction = DEVDIR_UNDEF;
+			if (strcmp(family, (char *)"10") == 0) {
+			    ndev->direction = DEVDIR_IN_ANALOG;
+			    ndev->description = xstrcpy((char *)"18S20,Digital thermometer");
+			} else if (strcmp(family, (char *)"28") == 0) {
+			    ndev->direction = DEVDIR_IN_ANALOG;
+			    ndev->description = xstrcpy((char *)"18B20,Digital thermometer");
+			} else if (strcmp(family, (char *)"29") == 0) {
+			    ndev->description = xstrcpy((char *)"2408,8 Channel addressable switch/LCD");
+			} else if (strcmp(family, (char *)"3a") == 0) {
+			    ndev->description = xstrcpy((char *)"2413,Dual channel addressable switch");
+			} else if (strcmp(family, (char *)"w1") == 0) {
+			    ndev->description = xstrcpy((char *)"Master System device");
+			} else {
+			    ndev->description = xstrcpy((char *)"Unknown device family ");
+			    ndev->description = xstrcat(ndev->description, family);
+			}
+			ndev->value = ndev->inuse = 0;
+			ndev->present = DEVPRESENT_YES;
+			ndev->address = xstrcpy(de->d_name);
+			ndev->subdevice = i;
+			ndev->gpiopin = -1;
+			ndev->comment = xstrcpy((char *)"Auto detected device");
+			ndev->timestamp = time(NULL);
+
+			if (Config.devices == NULL) {
+			    Config.devices = ndev;
+			} else {
+			    for (device = Config.devices; device; device = device->next) {
+				if (device->next == NULL)
+				    device->next = ndev;
+				break;
+			    }
+			}
+			rc++;
+		    }
+		}
+	    }
+	}
+    }
+
+    return rc;
+}
+
+
+
+#ifdef HAVE_WIRINGPI_H
+PI_THREAD (my_devices_loop)
+#else
+void *my_devices_loop(void *threadid)
+#endif
+{
+    devices_list	*device;
+//    char		line[60], *p = NULL;
+  //  FILE		*fp;
+//    int			temp, rc, deviation;
+
+    syslog(LOG_NOTICE, "Thread my_devices_loop started");
+    if (debug)
+	fprintf(stdout, "Thread my_devices_loop started\n");
+
+    /*
+     * Loop forever until the external shutdown variable is set.
+     */
+    for (;;) {
+
+    	/*
+    	 * Here send our 1-wire sensors values
+    	 */
+    	for (device = Config.devices; device; device = device->next) {
+
+	    if (my_shutdown)
+		break;
+
+	    /*
+	     * 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;
+    	}
+	usleep(10000);
+    }
+
+    syslog(LOG_NOTICE, "Thread my_devices_loop stopped");
+    if (debug)
+	fprintf(stdout, "Thread my_devices_loop stopped\n");
+
+    return 0;
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/thermferm/devices.h	Thu Jul 31 17:44:50 2014 +0200
@@ -0,0 +1,13 @@
+#ifndef MY_DEVICES_H
+#define	MY_DEVICES_H
+
+
+int devices_detect(void);
+
+#ifdef HAVE_WIRINGPI_H
+PI_THREAD (my_devices_loop);
+#else
+void *my_devices_loop(void *);
+#endif
+
+#endif
--- a/thermferm/rdconfig.c	Thu Jul 31 13:43:09 2014 +0200
+++ b/thermferm/rdconfig.c	Thu Jul 31 17:44:50 2014 +0200
@@ -35,7 +35,9 @@
 const char      UNITMODE[5][8]	= { "OFF", "NONE", "FRIDGE", "BEER", "PROFILE" };
 const char	UNITmode[5]  = { 'o', 'n', 'f', 'b', 'p' };
 const char	PROFSTATE[4][6]	= { "OFF", "PAUSE", "RUN", "DONE" };
-
+const char	DEVTYPE[7][6] = { "NA", "W1", "GPIO", "RC433", "DHT", "I2C", "SPI" };
+const char	DEVPRESENT[4][6] = { "UNDEF", "NO", "YES", "ERROR" };
+const char	DEVDIR[6][11] = { "UNDEF", "IN_BIN", "OUT_BIN", "IN_ANALOG", "OUT_ANALOG", "OUT_PWM" };
 
 
 
@@ -119,6 +121,7 @@
     units_list		*tmp3;
     profiles_list	*tmp4;
     prof_step		*tmp5;
+    devices_list	*device;
 
     /* 
      * Create a new XML buffer, to which the XML document will be written
@@ -495,6 +498,80 @@
 	}
     }
 
+    if (Config.devices) {
+	if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "DEVICES")) < 0) {
+	    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterStartElement");
+	    return 1;
+	}
+	for (device = Config.devices; device; device = device->next) {
+	    if ((rc = xmlTextWriterStartElement(writer, BAD_CAST "DEVICE")) < 0) {
+		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterStartElement");
+		return 1;
+	    }
+	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "VERSION", "%d", device->version)) < 0) {
+		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
+		return 1;
+	    }
+	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "UUID", "%s", device->uuid)) < 0) {
+		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+		return 1;
+	    }
+	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "TYPE", "%s", DEVTYPE[device->type])) < 0) {
+		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+		return 1;
+	    }
+	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "DIRECTION", "%s", DEVDIR[device->direction])) < 0) {
+		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+		return 1;
+	    }
+	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "VALUE", "%d", device->value)) < 0) {
+		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
+		return 1;
+	    }
+	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PRESENT", "%s", DEVPRESENT[device->present])) < 0) {
+		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+		return 1;                           
+	    }
+	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ADDRESS", "%s", device->address)) < 0) {
+		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
+		return 1;                           
+	    }
+	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "SUBDEVICE", "%d", device->subdevice)) < 0) {
+		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
+		return 1;                           
+	    }
+	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "GPIOPIN", "%d", device->gpiopin)) < 0) {
+		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
+		return 1;                           
+	    }
+	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "DESCRIPTION", "%s", device->description)) < 0) {
+		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
+		return 1;                           
+	    }
+	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "INUSE", "%d", device->inuse)) < 0) {
+		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
+		return 1;                           
+	    }
+	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "COMMENT", "%s", device->comment)) < 0) {
+		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
+		return 1;                           
+	    }
+	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "TIMESTAMP", "%d", (int)device->timestamp)) < 0) {
+		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
+		return 1;                           
+	    }
+	    if ((rc = xmlTextWriterEndElement(writer)) < 0) {
+		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterEndElement");
+		return 1;
+	    }
+	}
+
+	if ((rc = xmlTextWriterEndElement(writer)) < 0) {
+	    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterEndElement");
+	    return 1;
+	}
+    }
+
     /*
      * All done, close any open elements
      */
@@ -1000,6 +1077,137 @@
 
 
 
+int parseDevice(xmlDocPtr doc, xmlNodePtr cur)
+{
+    xmlChar             *key;
+    devices_list	*device, *tmp;
+    int                 i, ival;
+
+    device = (devices_list *)malloc(sizeof(devices_list));
+    device->next = NULL;
+    device->version = 1;
+    device->uuid = device->address = device->description = device->comment = NULL;
+    device->type = device->direction = device->present = device->subdevice = device->inuse = 0;
+    device->gpiopin = -1;
+    device->timestamp = (time_t)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;
+	    }
+	    device->version = 1;
+	    xmlFree(key);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"UUID"))) {
+	    device->uuid = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"TYPE"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    for (i = 0; i < 7; i++) {
+		if (! xmlStrcmp(key, (const xmlChar *)DEVTYPE[i])) {
+		    device->type = i;
+		    break;
+		}
+	    }
+	    xmlFree(key);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"DIRECTION"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    for (i = 0; i < 6; i++) {
+		if (! xmlStrcmp(key, (const xmlChar *)DEVDIR[i])) {
+		    device->direction = i;
+		    break;
+		}
+	    }
+	    xmlFree(key);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"VALUE"))) {
+		key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+		if (sscanf((const char *)key, "%d", &ival) == 1)
+			device->value = ival;
+		xmlFree(key);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"PRESENT"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    for (i = 0; i < 4; i++) {
+		if (! xmlStrcmp(key, (const xmlChar *)DEVDIR[i])) {
+		    device->present = i;
+		    break;
+		}
+	    }
+	    xmlFree(key);                           
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"ADDRESS"))) {
+	    device->address = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"SUBDEVICE"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (sscanf((const char *)key, "%d", &ival) == 1)
+		device->subdevice = ival;
+	    xmlFree(key);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"GPIOPIN"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (sscanf((const char *)key, "%d", &ival) == 1)
+		device->gpiopin = ival;
+	    xmlFree(key);                                       
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"DESCRPTION"))) {
+	    device->description = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"INUSE"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (sscanf((const char *)key, "%d", &ival) == 1)
+		device->inuse = ival;
+	    xmlFree(key);                                       
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"COMMENT"))) {
+	    device->comment = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"TIMESTAMP"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (sscanf((const char *)key, "%d", &ival) == 1)
+		device->timestamp = (time_t)ival;
+	    xmlFree(key);                                   
+	}
+
+	cur = cur->next;
+    }
+
+    if (Config.devices == NULL) {
+	Config.devices = device;
+    } else {
+	for (tmp = Config.devices; tmp; tmp = tmp->next) {
+	    if (tmp->next == NULL) {
+		tmp->next = device;
+		break;
+	    }
+	}
+    }
+
+    return 0;
+}
+
+
+
+int parseDevices(xmlDocPtr doc, xmlNodePtr cur)
+{
+    cur = cur->xmlChildrenNode;
+    while (cur != NULL) {
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"DEVICE"))) {
+	    parseDevice(doc, cur);
+	}
+	cur = cur->next;
+    }
+    return 0;
+}
+
+
+
 int rdconfig(void) 
 {
     int		rc = 0, ival;
@@ -1094,6 +1302,9 @@
 	if ((!xmlStrcmp(cur->name, (const xmlChar *)"PROFILES"))) {
 	    parseProfiles(doc, cur);
 	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"DEVICES"))) {
+	    parseDevices(doc, cur);
+	}
 	cur = cur->next;
     }
     xmlFreeDoc(doc);
--- a/thermferm/server.c	Thu Jul 31 13:43:09 2014 +0200
+++ b/thermferm/server.c	Thu Jul 31 17:44:50 2014 +0200
@@ -413,7 +413,7 @@
 			    if (unit->io2_address && (strncmp((char *)"3a", unit->io2_address, 2) == 0))
 				ref++;
 			}
-			srv_send((char *)"%s,%d,2413,Dual channel addressable switchs", de->d_name, ref);
+			srv_send((char *)"%s,%d,2413,Dual channel addressable switch", de->d_name, ref);
 		    } else {
 			srv_send((char *)"%s,0,NA,Unknown device", de->d_name);
 		    }
--- a/thermferm/thermferm.c	Thu Jul 31 13:43:09 2014 +0200
+++ b/thermferm/thermferm.c	Thu Jul 31 17:44:50 2014 +0200
@@ -24,6 +24,7 @@
 #include "logger.h"
 #include "rdconfig.h"
 #include "sensors.h"
+#include "devices.c"
 #include "server.h"
 #include "thermferm.h"
 #include "lcd-pcf8574.h"
@@ -245,6 +246,14 @@
 	return 1;
     }
 
+    rc = devices_detect();
+    if (rc) {
+	syslog(LOG_NOTICE, "Detected %d new devices", rc);
+	if (debug)
+	    fprintf(stdout, "Detected %d new devices\n", rc);
+	wrconfig();
+    }
+
 #ifdef HAVE_WIRINGPI_H
     rc = piThreadCreate(my_sensors_loop);
 #else
--- a/thermferm/thermferm.h	Thu Jul 31 13:43:09 2014 +0200
+++ b/thermferm/thermferm.h	Thu Jul 31 17:44:50 2014 +0200
@@ -135,6 +135,46 @@
 #define	PROFILE_RUN		2		/* Profile is running		*/
 #define	PROFILE_DONE		3		/* Profile is finished		*/
 
+/*
+ * External devices like sensors, relays.
+ */
+typedef struct _dev_list {
+    struct _dev_list	*next;
+    int			version;		/* Version 1			*/
+    char		*uuid;			/* UUID of this device		*/
+    int			type;			/* Device type			*/
+    int			direction;		/* Device direction		*/
+    int			value;			/* Device value			*/
+    int			present;		/* Device present		*/
+    char		*address;		/* Device address		*/
+    int			subdevice;		/* Device sub address		*/
+    int			gpiopin;		/* Device GPIO pin or -1	*/
+    char		*description;		/* Device description		*/
+    int			inuse;			/* In use counter		*/
+    char		*comment;		/* What we think it is		*/
+    time_t		timestamp;		/* Last updated			*/
+} devices_list;
+
+#define	DEVTYPE_NA		0		/* Unknown device type		*/
+#define	DEVTYPE_W1		1		/* 1-Wire bus			*/
+#define	DEVTYPE_GPIO		2		/* GPIO I/O device		*/
+#define	DEVTYPE_RC433		3		/* 433 MHz device		*/
+#define	DEVTYPE_DHT		4		/* DHT type device on GPIO	*/
+#define	DEVTYPE_I2C		5		/* I2C bus device		*/
+#define	DEVTYPE_SPI		6		/* SPI bus device		*/
+
+#define	DEVPRESENT_UNDEF	0		/* Precence not testable	*/
+#define	DEVPRESENT_NO		1		/* Device is missing		*/
+#define	DEVPRESENT_YES		2		/* Device is detected		*/
+#define	DEVPRESENT_ERROR	3		/* Device is in error		*/
+
+#define	DEVDIR_UNDEF		0		/* Undefined			*/
+#define	DEVDIR_IN_BIN		1		/* Binary input			*/
+#define	DEVDIR_OUT_BIN		2		/* Binary output		*/
+#define	DEVDIR_IN_ANALOG	3		/* Temperature input etc.	*/
+#define	DEVDIR_OUT_ANALOG	4		/* Analog steering		*/
+#define	DEVDIR_OUT_PWM		5		/* PWM outout			*/
+
 
 typedef struct _w1_therm {
     struct _w1_therm    *next;
@@ -162,6 +202,7 @@
 #endif
     units_list		*units;			/* Fermenter units		*/
     profiles_list	*profiles;		/* Ferment profiles		*/
+    devices_list	*devices;		/* Sensors and switches		*/
 } sys_config;
 
 

mercurial