Updated to add support for lights in a fermenter unit and a Power Supply status.

Sat, 07 Feb 2015 23:12:55 +0100

author
Michiel Broek <mbroek@mbse.eu>
date
Sat, 07 Feb 2015 23:12:55 +0100
changeset 306
97602274eb58
parent 305
fc2fae36f4ba
child 307
249e7d506069

Updated to add support for lights in a fermenter unit and a Power Supply status.

configure file | annotate | diff | comparison | revisions
configure.ac file | annotate | diff | comparison | revisions
thermferm/rdconfig.c file | annotate | diff | comparison | revisions
thermferm/server.c file | annotate | diff | comparison | revisions
thermferm/thermferm.h file | annotate | diff | comparison | revisions
www-thermferm/units.php file | annotate | diff | comparison | revisions
--- a/configure	Wed Jan 14 13:20:16 2015 +0100
+++ b/configure	Sat Feb 07 23:12:55 2015 +0100
@@ -2034,9 +2034,9 @@
 
 
 PACKAGE="mbsePi-apps"
-VERSION="0.2.7"
-COPYRIGHT="Copyright (C) 2014 Michiel Broek, All Rights Reserved"
-CYEARS="2014"
+VERSION="0.2.8"
+COPYRIGHT="Copyright (C) 2014-2015 Michiel Broek, All Rights Reserved"
+CYEARS="2014-2015"
 
 
 
--- a/configure.ac	Wed Jan 14 13:20:16 2015 +0100
+++ b/configure.ac	Sat Feb 07 23:12:55 2015 +0100
@@ -8,9 +8,9 @@
 dnl General settings
 dnl After changeing the version number, run autoconf!
 PACKAGE="mbsePi-apps"
-VERSION="0.2.7"
-COPYRIGHT="Copyright (C) 2014 Michiel Broek, All Rights Reserved"
-CYEARS="2014"
+VERSION="0.2.8"
+COPYRIGHT="Copyright (C) 2014-2015 Michiel Broek, All Rights Reserved"
+CYEARS="2014-2015"
 AC_SUBST(PACKAGE)
 AC_SUBST(VERSION)
 AC_SUBST(COPYRIGHT)
--- a/thermferm/rdconfig.c	Wed Jan 14 13:20:16 2015 +0100
+++ b/thermferm/rdconfig.c	Sat Feb 07 23:12:55 2015 +0100
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2014
+ * Copyright (C) 2014-2015
  *   
  * Michiel Broek <mbroek at mbse dot eu>
  *
@@ -80,8 +80,12 @@
 	    free(tmp2->cooler_address);
 	if (tmp2->fan_address)
 	    free(tmp2->fan_address);
+	if (tmp2->light_address)
+	    free(tmp2->light_address);
 	if (tmp2->door_address)
 	    free(tmp2->door_address);
+	if (tmp2->psu_address)
+	    free(tmp2->psu_address);
 	if (tmp2->profile)
 	    free(tmp2->profile);
 	free(tmp2);
@@ -399,6 +403,24 @@
 		    return 1;
 		}
 	    }
+	    if (tmp3->light_address) {
+		if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "LIGHT_ADDRESS", "%s", tmp3->light_address)) < 0)) {
+		    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+		    return 1;
+		}
+		if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "LIGHT_STATE", "%d", tmp3->light_state)) < 0)) {
+		    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+		    return 1;
+		}
+		if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "LIGHT_DELAY", "%d", tmp3->light_delay)) < 0)) {
+		    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+		    return 1;
+		}
+		if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "LIGHT_USAGE", "%d", tmp3->light_usage)) < 0)) {
+		    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+		    return 1;
+		}
+	    }
 	    if (tmp3->door_address) {
 		if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "DOOR_ADDRESS", "%s", tmp3->door_address)) < 0)) {
 		    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
@@ -409,6 +431,16 @@
 		return 1;
 		}
 	    }
+	    if (tmp3->psu_address) {
+		if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PSU_ADDRESS", "%s", tmp3->psu_address)) < 0)) {
+		    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+		    return 1;
+		}
+		if (((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PSU_STATE", "%d", tmp3->psu_state)) < 0)) {
+		    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+		    return 1;
+		}
+	    }
 	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MODE", "%s", UNITMODE[tmp3->mode] )) < 0) {
 		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
 		return 1;
@@ -872,14 +904,17 @@
     unit->next = NULL;
     unit->version = 1;
     unit->uuid = unit->name = unit->air_address = unit->beer_address = unit->heater_address = \
-		 unit->cooler_address = unit->fan_address = unit->door_address = unit->profile = NULL;
+		 unit->cooler_address = unit->fan_address = unit->door_address = \
+		 unit->light_address = unit->psu_address = unit->profile = NULL;
     unit->volume = unit->prof_peak_abs = unit->prof_peak_rel = 0.0;
     unit->air_temperature = unit->beer_temperature = unit->beer_set = unit->fridge_set = 20.0;
     unit->air_state = unit->beer_state = 1; // missing
-    unit->heater_state = unit->cooler_state = unit->fan_state = unit->door_state = unit->mode = unit->prof_state = 0;
+    unit->heater_state = unit->cooler_state = unit->fan_state = unit->door_state = \
+			 unit->light_state = unit->psu_state = unit->mode = unit->prof_state = 0;
     unit->heater_delay = unit->cooler_delay = unit->fan_delay = 20;	/* 5 minutes delay */
-    unit->heater_wait = unit->cooler_wait = unit->fan_wait = 0;
-    unit->heater_usage = unit->cooler_usage = unit->fan_usage = 0;
+    unit->light_delay = 1;						/* 15 seconds delay	*/
+    unit->heater_wait = unit->cooler_wait = unit->fan_wait = unit->light_wait = 0;
+    unit->heater_usage = unit->cooler_usage = unit->fan_usage = unit->light_usage = 0;
     unit->temp_set_min = 1.0;
     unit->temp_set_max = 30.0;
     unit->idle_rangeH = 1.0;
@@ -986,9 +1021,27 @@
 		unit->fan_usage = ival;
 	    xmlFree(key);
 	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"LIGHT_ADDRESS"))) {
+	    unit->light_address = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"LIGHT_DELAY"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (sscanf((const char *)key, "%d", &ival) == 1)
+		unit->light_delay = ival;
+	    xmlFree(key);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"LIGHT_USAGE"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (sscanf((const char *)key, "%d", &ival) == 1)
+		unit->light_usage = ival;
+	    xmlFree(key);
+	}
 	if ((!xmlStrcmp(cur->name, (const xmlChar *)"DOOR_ADDRESS"))) {
 	    unit->door_address = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
 	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"PSU_ADDRESS"))) {
+	    unit->psu_address = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	}
 	if ((!xmlStrcmp(cur->name, (const xmlChar *)"MODE"))) {
 	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
 	    for (i = 0; i < 5; i++) {
--- a/thermferm/server.c	Wed Jan 14 13:20:16 2015 +0100
+++ b/thermferm/server.c	Sat Feb 07 23:12:55 2015 +0100
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2008-2014
+ * Copyright (C) 2008-2015
  *   
  * Michiel Broek <mbroek at mbse dot eu>
  *
@@ -1378,9 +1378,15 @@
 		if (current->fan_address)
 		    free(current->fan_address);
 		current->fan_address = NULL;
+		if (current->light_address)
+		    free(current->light_address);
+		current->light_address = NULL;
 		if (current->door_address)
 		    free(current->door_address);
 		current->door_address = NULL;
+		if (current->psu_address)
+		    free(current->psu_address);
+		current->psu_address = NULL;
 		if (current->profile)
 		    free(current->profile);
 		current->profile = NULL;
@@ -1409,6 +1415,12 @@
 		if (current->door_address)
 		    free(current->door_address);
 		current->door_address = NULL;
+		if (current->light_address)
+		    free(current->light_address);
+		current->light_address = NULL;
+		if (current->psu_address)
+		    free(current->psu_address);
+		current->psu_address = NULL;
 		if (current->profile)
 		    free(current->profile);
 		current->profile = NULL;
@@ -1475,15 +1487,18 @@
 	uuid_unparse(uu, unit->uuid);
 	unit->name = xstrcpy(param);
 	unit->air_address = unit->beer_address = unit->heater_address = unit->cooler_address = \
-			    unit->fan_address = unit->door_address = unit->profile = NULL;
+			    unit->fan_address = unit->door_address = unit->light_address = \
+			    unit->psu_address = unit->profile = NULL;
 	unit->volume = unit->prof_peak_abs = unit->prof_peak_rel = 0.0;
 	unit->air_state = unit->beer_state = 1;
 	unit->air_temperature = unit->beer_temperature = 20000;
 	unit->beer_set = unit->fridge_set = 20.0;
-	unit->heater_state = unit->cooler_state = unit->fan_state = unit->door_state = unit->mode = unit->prof_state = 0;
-	unit->heater_delay = unit->cooler_delay = unit->fan_delay = 20;     /* 5 minutes delay */
-	unit->heater_wait = unit->cooler_wait = unit->fan_wait = 0;
-	unit->heater_usage = unit->cooler_usage = unit->fan_usage = 0;
+	unit->heater_state = unit->cooler_state = unit->fan_state = unit->door_state = unit->mode = \
+			     unit->light_state = unit->psu_state = unit->prof_state = 0;
+	unit->heater_delay = unit->cooler_delay = unit->fan_delay = 20;	/* 5 minutes delay	*/
+	unit->light_delay = 1;						/* 15 seconds delay	*/
+	unit->heater_wait = unit->cooler_wait = unit->fan_wait = unit->light_wait = 0;
+	unit->heater_usage = unit->cooler_usage = unit->fan_usage = unit->light_usage = 0;
 	unit->temp_set_min = 1.0;
 	unit->temp_set_max = 30.0;
 	unit->idle_rangeH = 1.0;
@@ -1574,8 +1589,14 @@
 		srv_send((char *)"FAN_STATE,%d", unit->fan_state);
 		srv_send((char *)"FAN_DELAY,%d", unit->fan_delay);
 		srv_send((char *)"FAN_USAGE,%d", unit->fan_usage);
+		srv_send((char *)"LIGHT_ADDRESS,%s", unit->light_address);
+		srv_send((char *)"LIGHT_STATE,%d", unit->light_state);
+		srv_send((char *)"LIGHT_DELAY,%d", unit->light_delay);
+		srv_send((char *)"LIGHT_USAGE,%d", unit->light_usage);
 		srv_send((char *)"DOOR_ADDRESS,%s", unit->door_address);
 		srv_send((char *)"DOOR_STATE,%d", unit->door_state);
+		srv_send((char *)"PSU_ADDRESS,%s", unit->psu_address);
+		srv_send((char *)"PSU_STATE,%d", unit->psu_state);
 		srv_send((char *)"MODE,%s", UNITMODE[unit->mode]);
 		srv_send((char *)"FRIDGE_SET,%.1f", unit->fridge_set);
 		srv_send((char *)"BEER_SET,%.1f", unit->beer_set);
@@ -1765,6 +1786,33 @@
 				    unit->fan_delay = ival;
 				}
 
+			    } else if (strcmp(kwd, (char *)"LIGHT_ADDRESS") == 0) {
+				if (val && unit->light_address && (strcmp(val, unit->light_address)))
+				    syslog(LOG_NOTICE, "Fermenter unit %s light address `%s' to `%s'", unit->uuid, unit->light_address, val);
+				if (unit->light_address) {
+				    device_count(FALSE, unit->light_address);
+				    free(unit->light_address);
+				}
+				if (val) {
+				    unit->light_address = xstrcpy(val);
+				    device_count(TRUE, unit->light_address);
+				} else
+				    unit->light_address = NULL;
+
+			    } else if (val && (strcmp(kwd, (char *)"LIGHT_STATE") == 0)) {
+				if ((sscanf(val, "%d", &ival) == 1) && ((ival == 0) || (ival == 100))) {
+				    if (unit->light_state != ival)
+					syslog(LOG_NOTICE, "Fermenter unit %s light state %d to %d", unit->uuid, unit->light_state, ival);
+				    unit->light_state = ival;
+				}
+
+			    } else if (val && (strcmp(kwd, (char *)"LIGHT_DELAY") == 0)) {
+				if (sscanf(val, "%d", &ival) == 1) {
+				    if (unit->light_delay != ival)
+					syslog(LOG_NOTICE, "Fermenter unit %s light delay %d to %d", unit->uuid, unit->light_delay, ival);
+				    unit->light_delay = ival;
+				}
+
 			    } else if (strcmp(kwd, (char *)"DOOR_ADDRESS") == 0) {
 				if (val && unit->door_address && (strcmp(val, unit->door_address)))
 				    syslog(LOG_NOTICE, "Fermenter unit %s door address `%s' to `%s'", unit->uuid, unit->door_address, val);
@@ -1778,6 +1826,19 @@
 				} else
 				    unit->door_address = NULL;
 
+			    } else if (strcmp(kwd, (char *)"PSU_ADDRESS") == 0) {
+				if (val && unit->psu_address && (strcmp(val, unit->psu_address)))
+				    syslog(LOG_NOTICE, "Fermenter unit %s psu address `%s' to `%s'", unit->uuid, unit->psu_address, val);
+				if (unit->psu_address) {
+				    device_count(FALSE, unit->psu_address);
+				    free(unit->psu_address);
+				}
+				if (val) {
+				    unit->psu_address = xstrcpy(val);
+				    device_count(TRUE, unit->psu_address);
+				} else
+				    unit->psu_address = NULL;
+
 			    } else if (val && (strcmp(kwd, (char *)"MODE") == 0)) {
 				for (i = 0; i < 5; i++) {
 				    if (strcmp(val, UNITMODE[i]) == 0) {
@@ -1788,11 +1849,12 @@
 					unit->mode = i;
 					/* Allways turn everything off after a mode change */
 					unit->PID_I_err = unit->PID_err_old = 0.0;
-					unit->heater_state = unit->cooler_state = unit->fan_state = 0;
-					unit->heater_wait = unit->cooler_wait = unit->fan_wait = 0;
+					unit->heater_state = unit->cooler_state = unit->fan_state = unit->light_state = 0;
+					unit->heater_wait = unit->cooler_wait = unit->fan_wait = unit->light_wait = 0;
 					device_out(unit->heater_address, unit->heater_state);
 					device_out(unit->cooler_address, unit->cooler_state);
 					device_out(unit->fan_address, unit->fan_state);
+					device_out(unit->light_address, unit->light_state);
 					if (unit->mode == UNITMODE_PROFILE) {
 					    /*
 					     * Set a sane default until it will be overruled by the
@@ -1836,11 +1898,12 @@
 				     * Reset all output devices
 				     */
 				    unit->PID_I_err = unit->PID_err_old = 0.0;
-				    unit->heater_state = unit->cooler_state = unit->fan_state = 0;
-				    unit->heater_wait = unit->cooler_wait = unit->fan_wait = 0;
+				    unit->heater_state = unit->cooler_state = unit->fan_state = unit->light_state = 0;
+				    unit->heater_wait = unit->cooler_wait = unit->fan_wait = unit->light_wait = 0;
 				    device_out(unit->heater_address, unit->heater_state);
 				    device_out(unit->cooler_address, unit->cooler_state);
 				    device_out(unit->fan_address, unit->fan_state);
+				    device_out(unit->light_address, unit->light_state);
 				}
 
 			    } else if (val && (strcmp(kwd, (char *)"PROF_STATE") == 0)) {
--- a/thermferm/thermferm.h	Wed Jan 14 13:20:16 2015 +0100
+++ b/thermferm/thermferm.h	Sat Feb 07 23:12:55 2015 +0100
@@ -96,9 +96,8 @@
  * Fermenter units. These units are connected via the 1-wire bus.
  * Each unit can have:
  *  a DS18B20 sensor to measure the air temperature inside the unit.
- *  a DS18B20 sensor to measure the beer temperature.
- *  a DS2413 to turn the cooler and heater on or off.
- *  a DS2413 to switch the fan and sense the door.
+ *  a DS18B20 sensor(s) to measure the beer temperature.
+ *  a DS2408 to turn the cooler, heater and fans on or off. Sense door and PSU state.
  */
 typedef struct _units_list {
     struct _units_list	*next;
@@ -127,8 +126,15 @@
     int			fan_delay;		/* Fan delay time /15 sec	*/
     int			fan_wait;		/* Fan wait counter		*/
     int			fan_usage;		/* Fan usage in seconds		*/
+    char		*light_address;		/* Lights relay			*/
+    int			light_state;		/* Lights state 0..100		*/
+    int			light_delay;		/* Lights delay time /15 sec	*/
+    int			light_wait;		/* Lights wait counter		*/
+    int			light_usage;		/* Lights usage in seconds	*/
     char		*door_address;		/* Door input address		*/
-    int			door_state;		/* Door and light status	*/
+    int			door_state;		/* Door status			*/
+    char		*psu_address;		/* Power Supply input address	*/
+    int			psu_state;		/* Power Supply status		*/
     int			mode;			/* Unit mode			*/
     float		beer_set;		/* Beer temperature setting	*/
     float		fridge_set;		/* Fridge temperature setting	*/
--- a/www-thermferm/units.php	Wed Jan 14 13:20:16 2015 +0100
+++ b/www-thermferm/units.php	Sat Feb 07 23:12:55 2015 +0100
@@ -1,6 +1,6 @@
 <?php
 /*****************************************************************************
- * Copyright (C) 2014
+ * Copyright (C) 2014-2015
  *   
  * Michiel Broek <mbroek at mbse dot eu>
  *
@@ -99,7 +99,10 @@
 	$cmd[] = "COOLER_ADDRESS,".$_POST['CoolerAddress'];
 	$cmd[] = "COOLER_DELAY,".$_POST['CoolerDelay'];
 	$cmd[] = "FAN_ADDRESS,".$_POST['FanAddress'];
+	$cmd[] = "LIGHT_ADDRESS,".$_POST['LightAddress'];
+	$cmd[] = "LIGHT_DELAY,".$_POST['LightDelay'];
 	$cmd[] = "DOOR_ADDRESS,".$_POST['DoorAddress'];
+	$cmd[] = "PSU_ADDRESS,".$_POST['PSUAddress'];
 	$cmd[] = "TEMP_SET_MIN,".$_POST['TempSetMin'];
 	$cmd[] = "TEMP_SET_MAX,".$_POST['TempSetMax'];
 	$cmd[] = "IDLE_RANGE_L,".$_POST['IdleRangeL'];
@@ -119,8 +122,11 @@
     unset($_POST['HeaterDelay']);
     unset($_POST['CoolerAddress']);
     unset($_POST['CoolerDelay']);
+    unset($_POST['LightAddress']);
+    unset($_POST['LightDelay']);
     unset($_POST['FanAddress']);
     unset($_POST['DoorAddress']);
+    unset($_POST['PSUAddress']);
     unset($_POST['TempSetMin']);
     unset($_POST['TempSetMax']);
     unset($_POST['IdleRangeL']);
@@ -147,6 +153,9 @@
  *         6 = TempSetMin < -5 or > 15
  *         7 = HeaterDelay out of range
  *         8 = CoolerDelay out of range
+ *         9 = IdleRangeL out of range
+ *        10 = IdleRangeH out of range
+ *        11 = LightDelay out of range
  *        99 = Cancel key
  */
 function test_thedata() {
@@ -154,8 +163,8 @@
     global $arr;
 
     if (isset($_POST['UUID']) && isset($_POST['Name']) && isset($_POST['Volume']) && isset($_POST['AirAddress']) &&
-	isset($_POST['BeerAddress']) && isset($_POST['HeaterAddress']) && isset($_POST['CoolerAddress']) &&
-	isset($_POST['HeaterDelay']) && isset($_POST['CoolerDelay']) &&
+	isset($_POST['BeerAddress']) && isset($_POST['HeaterAddress']) && isset($_POST['CoolerAddress']) && isset($_POST['LightAddress']) &&
+	isset($_POST['HeaterDelay']) && isset($_POST['CoolerDelay']) && isset($_POST['LightDelay']) && isset($_POST['PSUAddress']) &&
 	isset($_POST['FanAddress']) && isset($_POST['DoorAddress']) && isset($_POST['TempSetMin']) && isset($_POST['TempSetMax']) &&
 	isset($_POST['IdleRangeL']) && isset($_POST['IdleRangeH']) && isset($_POST['key']) && isset($_POST['command'])) {
 
@@ -199,6 +208,9 @@
 	if (($_POST['IdleRangeH'] < 0) || ($_POST['IdleRangeH'] > 5))
 	    return 10;
 
+	if (($_POST['LightDelay'] < 0) || ($_POST['LightDelay'] > 45))
+	    return 11;
+
     } else {
 	return 1;
     }
@@ -245,6 +257,8 @@
 		break;
 	case 10: $error = 'Idle Range High must be between 0 and 5';
 		break;
+	case 11: $error = 'Light Delay must be bewteen 0 and 45';
+		break;
 	case 99:        
 		load('units.php');
 		break;
@@ -427,6 +441,33 @@
 		$outstr .= '        </select></td>'.PHP_EOL;
 		$outstr .= '       </tr>'.PHP_EOL;
 	    }
+	    if ($f[0] == "LIGHT_ADDRESS") {
+		$outstr .= '       <tr class="editor">'.PHP_EOL;
+		$outstr .= '        <td class="editname">Lights Address</td>'.PHP_EOL;
+		$outstr .= '        <td class="editfield"><select name="LightAddress">'.PHP_EOL;
+		$outstr .= '         <option value="">Not Assigned</option>'.PHP_EOL;
+		if (startsWith($devices[0], "212")) {
+		    $j = 1;
+		    while (1) {
+			if (strcmp($devices[$j], ".") == 0)
+			    break;
+			$g = explode(",", $devices[$j]);
+			if (($g[5] == "OUT_ANALOG") || ($g[5] == "OUT_BIN")) {
+			    ($f[1] == $g[0]) ? $se = " selected" : $se = "";
+			    $outstr .= '         <option value="'.$g[0].'"'.$se.'>'.$g[1].' '.$g[4].'</option>'.PHP_EOL;
+			}
+			$j++;
+		    }
+		}
+		$outstr .= '        </select></td>'.PHP_EOL;
+		$outstr .= '       </tr>'.PHP_EOL;
+	    }
+	    if ($f[0] == "LIGHT_DELAY") {
+		$outstr .= '       <tr class="editor">'.PHP_EOL;
+		$outstr .= '        <td class="editname">Lights Delay</td>'.PHP_EOL;
+		$outstr .= '        <td class="editfield"><input type="text" name="LightDelay" size="5" value="'.$f[1].'"> * 15 seconds</td>'.PHP_EOL;
+		$outstr .= '       </tr>'.PHP_EOL;
+	    }
 	    if ($f[0] == "DOOR_ADDRESS") {
 		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">Door Sensor Address</td>'.PHP_EOL;
@@ -448,6 +489,27 @@
 		$outstr .= '        </select></td>'.PHP_EOL;                        
 		$outstr .= '       </tr>'.PHP_EOL;                                  
 	    }
+	    if ($f[0] == "PSU_ADDRESS") {
+		$outstr .= '       <tr class="editor">'.PHP_EOL;
+		$outstr .= '        <td class="editname">Power Supply Sensor Address</td>'.PHP_EOL;
+		$outstr .= '        <td class="editfield"><select name="PSUAddress">'.PHP_EOL;
+		$outstr .= '         <option value="">Not Assigned</option>'.PHP_EOL;
+		if (startsWith($devices[0], "212")) {
+		    $j = 1;
+		    while (1) {
+			if (strcmp($devices[$j], ".") == 0)
+			    break;
+			$g = explode(",", $devices[$j]);
+			if ($g[5] == "IN_BIN") {
+			    ($f[1] == $g[0]) ? $se = " selected" : $se = "";
+			    $outstr .= '         <option value="'.$g[0].'"'.$se.'>'.$g[1].' '.$g[4].'</option>'.PHP_EOL;
+			}
+			$j++;
+		    }
+		}
+		$outstr .= '        </select></td>'.PHP_EOL;
+		$outstr .= '       </tr>'.PHP_EOL;
+	    }
 	    if ($f[0] == "TEMP_SET_MIN") {
 		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">Min. temp setting</td>'.PHP_EOL;
@@ -568,7 +630,10 @@
     $outstr .= '<input type="hidden" value="" name="CoolerAddress">';
     $outstr .= '<input type="hidden" value="20" name="CoolerDelay">';
     $outstr .= '<input type="hidden" value="" name="FanAddress">';
+    $outstr .= '<input type="hidden" value="" name="LightAddress">';
+    $outstr .= '<input type="hidden" value="1" name="LightDelay">';
     $outstr .= '<input type="hidden" value="" name="DoorAddress">';
+    $outstr .= '<input type="hidden" value="" name="PSUAdress">';
     $outstr .= '<input type="hidden" value="1.0" name="TempSetMin">';
     $outstr .= '<input type="hidden" value="30.0" name="TempSetMax">';
     $outstr .= '<input type="hidden" value="-1.0" name="IdleRangeL">';

mercurial