Added PID implementation and 433 MHz radio control switches. Not reliable yet.

Mon, 04 Aug 2014 23:34:22 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Mon, 04 Aug 2014 23:34:22 +0200
changeset 179
417ee898fb02
parent 178
988a898974f3
child 180
b62644eb442f

Added PID implementation and 433 MHz radio control switches. Not reliable yet.

thermferm/devices.c file | annotate | diff | comparison | revisions
thermferm/devices.h file | annotate | diff | comparison | revisions
thermferm/server.c file | annotate | diff | comparison | revisions
thermferm/thermferm.c file | annotate | diff | comparison | revisions
thermferm/units.c file | annotate | diff | comparison | revisions
--- a/thermferm/devices.c	Mon Aug 04 19:31:03 2014 +0200
+++ b/thermferm/devices.c	Mon Aug 04 23:34:22 2014 +0200
@@ -20,8 +20,9 @@
  * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  *****************************************************************************/
 
+#include "thermferm.h"
 #include "devices.h"
-#include "thermferm.h"
+#include "rc-switch.h"
 #include "xutil.h"
 
 
@@ -31,6 +32,57 @@
 
 
 
+
+int device_out(char *uuid, int value)
+{
+    devices_list	*device;
+    char		buf[40];
+    int			i, rc;
+
+    if (uuid == NULL)
+	return 0;
+
+    for (device = Config.devices; device; device = device->next) {
+	if (strcmp(uuid, device->uuid) == 0) {
+	    if (value != device->value) {
+
+#ifdef HAVE_WIRINGPI_H
+		rc = 0;
+		if ((device->type == DEVTYPE_RC433) && (device->gpiopin != -1) && (device->present == DEVPRESENT_YES)) {
+	            enableTransmit(device->gpiopin);
+		    usleep(10000);
+		    snprintf(buf, 39, "%s,%d", device->address, value ? 1:0);
+		    for (i = 0; i < strlen(buf); i++)
+			if (buf[i] == '-')
+			    buf[i] = ',';	
+		    rc = toggleSwitch(buf);
+		    syslog(LOG_NOTICE, "RC433 command %s rc=%d", buf, rc);
+		    if (debug)
+			fprintf(stdout, "RC433 command %s rc=%d\n", buf, rc);
+		    usleep(50000);
+		    disableTransmit();
+		}
+                device->value = value;
+		device->timestamp = time(NULL);
+		return rc;
+
+		if ((device->type == DEVTYPE_GPIO) && (device->gpiopin != -1) && (device->present == DEVPRESENT_YES)) {
+
+		}
+#endif
+		if ((device->type == DEVTYPE_W1) && (device->direction == DEVDIR_OUT_BIN) && (device->present == DEVPRESENT_YES)) {
+
+		}
+	    } else {
+		return 0;
+	    }
+	}
+    }
+    return 0;
+}	   
+
+
+
 /*
  * Auto detect hotplugged or known to be present devices
  */
--- a/thermferm/devices.h	Mon Aug 04 19:31:03 2014 +0200
+++ b/thermferm/devices.h	Mon Aug 04 23:34:22 2014 +0200
@@ -2,6 +2,7 @@
 #define	MY_DEVICES_H
 
 
+int device_out(char *, int);
 int devices_detect(void);
 
 #ifdef HAVE_WIRINGPI_H
--- a/thermferm/server.c	Mon Aug 04 19:31:03 2014 +0200
+++ b/thermferm/server.c	Mon Aug 04 23:34:22 2014 +0200
@@ -56,11 +56,6 @@
 #define SS_TIMEOUT      300
 
 
-float			cs_heatEstimator = 0.2;
-float			cs_coolEstimator = 5;
-float			cv_beerDiff = 0.0;
-
-
 
 /*
  * Send message to client
@@ -98,6 +93,27 @@
 
 
 /*
+ * Update the device inuse counter.
+ */
+void device_count(int plus, char *uuid)
+{
+    devices_list	*device;
+
+    for (device = Config.devices; device; device = device->next) {
+	if (strcmp(device->uuid, uuid) == 0) {
+	    if (plus == TRUE) {
+		device->inuse++;
+	    } else {
+		if (device->inuse)
+		    device->inuse--;
+	    }
+	}
+    }
+}
+
+
+
+/*
  * ADD PROFILE name
  */
 int unit_add(char *buf)
@@ -458,9 +474,10 @@
 
 			    } else if (strcmp(kwd, (char *)"PRESENT") == 0) {
 				for (i = 0; i < 4; i++) {
-				    if (strcmp(val, DEVPRESENT[i]) == 0)
+				    if (strcmp(val, DEVPRESENT[i]) == 0) {
 					device->present = i;
 				        break;
+				    }
 				}
 
 			    } else if (strcmp(kwd, (char *)"ADDRESS") == 0) {
@@ -1174,7 +1191,6 @@
 			kwd = strtok(ibuf, ",\0");
 			val = strtok(NULL, "\0");
 			if (kwd) {
-				fprintf(stdout, "strlen(%s) %d\n", val, strlen(val));
 			    /*
 			     * Accept writable data. The client can sent just one line,
 			     * but may also sent everything. Simply ignore things we
@@ -1190,27 +1206,36 @@
 				    unit->volume = fval;
 
 			    } else if (strcmp(kwd, (char *)"AIR_ADDRESS") == 0) {
-				if (unit->air_address)
+				if (unit->air_address) {
+				    device_count(FALSE, unit->air_address);
 				    free(unit->air_address);
-				if (val)
+				}
+				if (val) {
 				    unit->air_address  = xstrcpy(val);
-				else
+				    device_count(TRUE, unit->air_address);
+				} else
 				    unit->air_address  = NULL;
 
 			    } else if (strcmp(kwd, (char *)"BEER_ADDRESS") == 0) {
-				if (unit->beer_address)
+				if (unit->beer_address) {
+				    device_count(FALSE, unit->beer_address);
 				    free(unit->beer_address);
-				if (val)
+				}
+				if (val) {
 				    unit->beer_address = xstrcpy(val);
-				else
+				    device_count(TRUE, unit->beer_address);
+				} else
 				    unit->beer_address = NULL;
 
 			    } else if (strcmp(kwd, (char *)"HEATER_ADDRESS") == 0) {
-				if (unit->heater_address)
+				if (unit->heater_address) {
+				    device_count(FALSE, unit->heater_address);
 				    free(unit->heater_address);
-				if (val)
+				}
+				if (val) {
 				    unit->heater_address = xstrcpy(val);
-				else
+				    device_count(TRUE, unit->heater_address);
+				} else
 				    unit->heater_address = NULL;
 
 			    } else if (val && (strcmp(kwd, (char *)"HEATER_STATE") == 0)) {
@@ -1218,11 +1243,14 @@
 				    unit->heater_state = ival;
 
 			    } else if (strcmp(kwd, (char *)"COOLER_ADDRESS") == 0) {
-				if (unit->cooler_address)
+				if (unit->cooler_address) {
+				    device_count(FALSE, unit->cooler_address);
 				    free(unit->cooler_address);
-				if (val)
+				}
+				if (val) {
 				    unit->cooler_address = xstrcpy(val);
-				else
+				    device_count(TRUE, unit->cooler_address);
+				} else
 				    unit->cooler_address = NULL;
 
 			    } else if (val && (strcmp(kwd, (char *)"COOLER_STATE") == 0)) {
@@ -1230,11 +1258,14 @@
 				    unit->cooler_state = ival;
 
 			    } else if (strcmp(kwd, (char *)"FAN_ADDRESS") == 0) {
-				if (unit->fan_address)
+				if (unit->fan_address) {
+				    device_count(FALSE, unit->fan_address);
 				    free(unit->fan_address);
-				if (val)
+				}
+				if (val) {
 				    unit->fan_address = xstrcpy(val);
-				else
+				    device_count(TRUE, unit->fan_address);
+				} else
 				    unit->fan_address = NULL;
 			   
 			    } else if (val && (strcmp(kwd, (char *)"FAN_STATE") == 0)) {
@@ -1242,11 +1273,14 @@
 				    unit->fan_state = ival;
 			    
 			    } else if (strcmp(kwd, (char *)"DOOR_ADDRESS") == 0) {
-				if (unit->door_address)
+				if (unit->door_address) {
+				    device_count(FALSE, unit->door_address);
 				    free(unit->door_address);
-				if (val)
+				}
+				if (val) {
 				    unit->door_address = xstrcpy(val);
-				else
+				    device_count(TRUE, unit->door_address);
+				} else
 				    unit->door_address = NULL;
 
 			    } else if (val && (strcmp(kwd, (char *)"MODE") == 0)) {
--- a/thermferm/thermferm.c	Mon Aug 04 19:31:03 2014 +0200
+++ b/thermferm/thermferm.c	Mon Aug 04 23:34:22 2014 +0200
@@ -232,7 +232,7 @@
     time_t		now, last = (time_t)0;
     units_list		*unit;
     int			rc, run = 1, seconds = 0, minutes = 0;
-    float		err = 0.0, sp, pv, P_err, I_err, D_err, Out;
+    float		err = 0.0, sp, pv, P_err, I_err = 0.0, D_err, Out;
 #ifdef HAVE_WIRINGPI_H
     struct tm		*tm;
     int			row;
@@ -346,15 +346,15 @@
 		for (unit = Config.units; unit; unit = unit->next) {
 		    if (unit->mode != UNITMODE_OFF) {
 
-			if (0) {
+			if (unit->mode != UNITMODE_NONE) {
 			    /*
 			     * PID controller
 			     */
 			    sp = unit->beer_set;
-			    pv = unit->beer_temperature;
+			    pv = unit->beer_temperature / 1000.0;
 			    if (unit->mode == UNITMODE_FRIDGE) {
 				sp = unit->fridge_set;
-				pv = unit->air_temperature;
+				pv = unit->air_temperature / 1000.0;
 			    } else if (unit->mode == UNITMODE_PROFILE) {
 				sp = unit->prof_target;
 			    }
@@ -367,11 +367,28 @@
 			    I_err += unit->PID_err_old;
 			    D_err = err - unit->PID_err_old;
 
-			    Out = (0.1*P_err) + (0.3*I_err) + (0.02*D_err);
-			    //     Kp            Ki            Kd
+			    /*
+			     * A postive value means heating, a negative value cooling.
+			     */
+			    Out = (5.0*P_err) + (0.25*I_err) + (-1.5*D_err);
+			    //     Kp 0.1        Ki 0.3        Kd 0.02
 			    if (debug)
 				fprintf(stdout, "sp=%.2f pv=%.2f err_old=%.2f err=%.2f P_err=%.2f I_err=%.2f D_err=%.2f Out=%.2f\n",
 						sp, pv, unit->PID_err_old, err, P_err, I_err, D_err, Out);
+			    if (unit->heater_address) {
+				if (Out >= 2)
+				    unit->heater_state = 100;
+				else
+				    unit->heater_state = 0;
+				device_out(unit->heater_address, unit->heater_state);
+			    }
+			    if (unit->cooler_address) {
+				if (Out <= -2)
+				    unit->cooler_state = 100;
+				else
+				    unit->cooler_state = 0;
+				device_out(unit->cooler_address, unit->cooler_state);
+			    }
 			}
 
 			snprintf(target, 39, "NA");
--- a/thermferm/units.c	Mon Aug 04 19:31:03 2014 +0200
+++ b/thermferm/units.c	Mon Aug 04 23:34:22 2014 +0200
@@ -58,6 +58,7 @@
 #endif
 {
     units_list		*unit;
+    devices_list	*device;
     int			rc, temp, deviation;
 
     /*
@@ -155,7 +156,15 @@
 	    if (my_shutdown)
 		break;
 
-
+	    device_out(unit->heater_address, unit->heater_state);
+	    if (my_shutdown)
+		break;
+	    device_out(unit->cooler_address, unit->cooler_state);
+	    if (my_shutdown)
+		break;
+	    device_out(unit->fan_address, unit->fan_state);
+	    if (my_shutdown)
+		break;
     	}
 	usleep(10000);
     }

mercurial