# HG changeset patch # User Michiel Broek # Date 1407188062 -7200 # Node ID 417ee898fb0250eaad5c7687b00e3832c6b828ca # Parent 988a898974f3c34577ebe2dcff2fbb3c350e330b Added PID implementation and 433 MHz radio control switches. Not reliable yet. diff -r 988a898974f3 -r 417ee898fb02 thermferm/devices.c --- 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 */ diff -r 988a898974f3 -r 417ee898fb02 thermferm/devices.h --- 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 diff -r 988a898974f3 -r 417ee898fb02 thermferm/server.c --- 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)) { diff -r 988a898974f3 -r 417ee898fb02 thermferm/thermferm.c --- 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"); diff -r 988a898974f3 -r 417ee898fb02 thermferm/units.c --- 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); }