Updated simulator with more simulated devices.

Wed, 25 Jul 2018 20:08:13 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Wed, 25 Jul 2018 20:08:13 +0200
changeset 553
4091d4fe217f
parent 552
8b56f1b4e7ec
child 554
ab9f22ab57b5

Updated simulator with more simulated devices.

INSTALL file | annotate | diff | comparison | revisions
thermferm/devices.c file | annotate | diff | comparison | revisions
thermferm/rdconfig.c file | annotate | diff | comparison | revisions
thermferm/server.c file | annotate | diff | comparison | revisions
thermferm/simulator.c file | annotate | diff | comparison | revisions
thermferm/thermferm.h file | annotate | diff | comparison | revisions
www-thermferm/simulator.php file | annotate | diff | comparison | revisions
--- a/INSTALL	Wed Jul 25 14:18:39 2018 +0200
+++ b/INSTALL	Wed Jul 25 20:08:13 2018 +0200
@@ -1,10 +1,37 @@
 
-Compiling and building on a Raspberry runing Debian Stretch:
+	Debian Stretch.
+	---------------
 
-Install the packages libjson-c-dev, libxml2-dev, mosquitto-clients,
-	libmosquitto-dev, wiringpi, i2c-tools, nginx, php-fpm, uuid-dev.
+All extra libraries and packages are since Debian Strech present in the
+standard repository. There is no need for manual downloading and building
+packages, only thermferm needs to be build manually.
 
+Using sudo apt-get install the following packages:
+    libjson-c-dev, libxml2-dev, mosquitto-clients, libmosquitto-dev, wiringpi,
+    i2c-tools, nginx, php-fpm, uuid-dev.
 
 If running over WiFi consider running a local mosquitto server that runs as a
 bridge to the main mosquitto server. Install mosquitto.
 
+
+	Compiling and install.
+	----------------------
+
+In the main mbsePi-apps directory run:
+    make clean
+    ./configure
+
+After configure, see that wiringPi and MQTT are included. Then run:
+    make
+    sudo make install
+    systemctl enable thermferm
+    systemctl start thermferm
+
+
+	Configure nginx.
+	----------------
+
+	Configure local mosquitto.
+	--------------------------
+
+
--- a/thermferm/devices.c	Wed Jul 25 14:18:39 2018 +0200
+++ b/thermferm/devices.c	Wed Jul 25 20:08:13 2018 +0200
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2014..2017
+ * Copyright (C) 2014..2018
  *   
  * Michiel Broek <mbroek at mbse dot eu>
  *
@@ -35,6 +35,8 @@
 
 extern int	SIMcooling;
 extern int	SIMheating;
+extern int	SIMfan;
+extern int	SIMlight;
 
 #endif
 
@@ -359,7 +361,8 @@
 
 #ifdef USE_SIMULATOR
 		if ((device->type == DEVTYPE_SIM) && (device->direction == DEVDIR_OUT_BIN) && (device->present == DEVPRESENT_YES)) {
-		    if ((strcmp((char *)"SimCooler", device->address) == 0) || (strcmp((char *)"SimHeater", device->address) == 0)) {
+		    if ((strcmp((char *)"SimCooler", device->address) == 0) || (strcmp((char *)"SimHeater", device->address) == 0) ||
+			(strcmp((char *)"SimFan"   , device->address) == 0) || (strcmp((char *)"SimLight" , device->address) == 0)) {
 			if (value != device->value) {
 			    syslog(LOG_NOTICE, "SIM %s value=%d", device->address, value);
 			    if (debug)
@@ -371,6 +374,10 @@
 			    SIMcooling = value;
 			if (strcmp((char *)"SimHeater", device->address) == 0)
 			    SIMheating = value;
+			if (strcmp((char *)"SimFan", device->address) == 0)
+			    SIMfan = value;
+			if (strcmp((char *)"SimLight", device->address) == 0)
+			    SIMlight = value;
 		    }
 		}
 #endif
@@ -621,66 +628,82 @@
 #endif
 
 #ifdef USE_SIMULATOR
-    found = FALSE;
+    found = 0;
     for (device = Config.devices; device; device = device->next) {
 	if (device->type == DEVTYPE_SIM) {
-	    found = TRUE;
-	    break;
+	    found++;
 	}
     }
 
-    if (found == FALSE) {
-	subdevices = 5;
-	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_SIM;
-	    ndev->value = ndev->offset = 0;
-	    ndev->present = DEVPRESENT_YES;
-	    ndev->subdevice = i;
-	    ndev->gpiopin = -1;
-	    ndev->comment = xstrcpy((char *)"Auto detected device");
-	    ndev->timestamp = time(NULL);
-	    ndev->inuse = 0;
-	    switch (i) {
-		case 0:	ndev->direction = DEVDIR_IN_ANALOG;
+    /*
+     * Create simulated devices, or upgrade with new devices.
+     */
+    subdevices = 9;
+    for (i = found; 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_SIM;
+	ndev->value = ndev->offset = 0;
+	ndev->present = DEVPRESENT_YES;
+	ndev->subdevice = i;
+	ndev->gpiopin = -1;
+	ndev->comment = xstrcpy((char *)"Auto detected device");
+	ndev->timestamp = time(NULL);
+	ndev->inuse = 0;
+	switch (i) {
+	    case 0:	ndev->direction = DEVDIR_IN_ANALOG;
 			ndev->address = xstrcpy((char *)"SimRoomTemp");
 			ndev->description = xstrcpy((char *)"Simulated room temperature");
 			break;
-		case 1:	ndev->direction = DEVDIR_IN_ANALOG;
+	    case 1:	ndev->direction = DEVDIR_IN_ANALOG;
 			ndev->address = xstrcpy((char *)"SimAirTemp");
 			ndev->description = xstrcpy((char *)"Simulated air temperature");
 			break;
-		case 2:	ndev->direction = DEVDIR_IN_ANALOG;
+	    case 2:	ndev->direction = DEVDIR_IN_ANALOG;
 			ndev->address = xstrcpy((char *)"SimBeerTemp");
 			ndev->description = xstrcpy((char *)"Simulated beer temperature");
 			break;
-		case 3:	ndev->direction = DEVDIR_OUT_BIN;
+	    case 3:	ndev->direction = DEVDIR_OUT_BIN;
 			ndev->address = xstrcpy((char *)"SimHeater");
 			ndev->description = xstrcpy((char *)"Simulated heater");
 			break;
-		case 4:	ndev->direction = DEVDIR_OUT_BIN;
+	    case 4:	ndev->direction = DEVDIR_OUT_BIN;
 			ndev->address = xstrcpy((char *)"SimCooler");
 			ndev->description = xstrcpy((char *)"Simulated cooler");
 			break;
-	    }
+	    case 5:	ndev->direction = DEVDIR_IN_ANALOG;
+			ndev->address = xstrcpy((char *)"SimRoomHum");
+			ndev->description = xstrcpy((char *)"Simulated room humidity");
+			break;
+	    case 6:	ndev->direction = DEVDIR_IN_ANALOG;
+			ndev->address = xstrcpy((char *)"SimChillerTemp");
+			ndev->description = xstrcpy((char *)"Simulated Chiller temperature");
+			break;
+	    case 7:	ndev->direction = DEVDIR_OUT_BIN;
+			ndev->address = xstrcpy((char *)"SimFan");
+			ndev->description = xstrcpy((char *)"Simulated fan");
+			break;
+	    case 8:	ndev->direction = DEVDIR_OUT_BIN;
+			ndev->address = xstrcpy((char *)"SimLight");
+			ndev->description = xstrcpy((char *)"Simulated light");
+			break;
+	}
 
-	    if (Config.devices == NULL) {
-		Config.devices = ndev;
-	    } else {
-		for (device = Config.devices; device; device = device->next) {
-		    if (device->next == NULL) {
-			device->next = ndev;
-			break;
-		    }
+	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++;
 	}
+    	rc++;
     }
 #endif
 
@@ -744,16 +767,6 @@
 				fgets(line1, 50, fp);	// Read 2 lines
 				fgets(line2, 50, fp);
 				fclose(fp);
-//				if (device->present != DEVPRESENT_YES) {
-//				     syslog(LOG_NOTICE, "sensor %s is back", device->address);
-//#ifdef HAVE_WIRINGPI_H
-//				     piLock(LOCK_DEVICES);
-//#endif
-//				     device->present = DEVPRESENT_YES;
-//#ifdef HAVE_WIRINGPI_H
-//				     piUnlock(LOCK_DEVICES);
-//#endif
-//				}
 				/*
 				 * The output looks like:
 				 * 72 01 4b 46 7f ff 0e 10 57 : crc=57 YES
@@ -949,6 +962,12 @@
 			    } else if (device->subdevice == 2) {
 			    	device->value = (int)((int)(simulator->beer_temperature * 1000) / 62.5) * 62.5;
 			    	device->timestamp = time(NULL);
+			    } else if (device->subdevice == 5) {
+				device->value = (int)((int)(simulator->room_humidity * 1000) / 500) * 500;
+				device->timestamp = time(NULL);
+			    } else if (device->subdevice == 6) {
+				device->value = (int)((int)(simulator->chiller_temperature * 1000) / 62.5) * 62.5;
+				device->timestamp = time(NULL);
 			    }
 			}
 #ifdef HAVE_WIRINGPI_H
--- a/thermferm/rdconfig.c	Wed Jul 25 14:18:39 2018 +0200
+++ b/thermferm/rdconfig.c	Wed Jul 25 20:08:13 2018 +0200
@@ -914,6 +914,10 @@
 	   	syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
 	   	return 1;
 	    }
+	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ROOM_HUMIDITY", "%.1f", simulator->room_humidity)) < 0) {
+		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
+		return 1;
+	    }
 	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "AIR_TEMPERATURE", "%f", simulator->air_temperature)) < 0) {
 	    	syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
 	    	return 1;
@@ -922,6 +926,10 @@
 	    	syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
 	    	return 1;
 	    }
+	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "CHILLER_TEMPERATURE", "%f", simulator->chiller_temperature)) < 0) {
+		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
+		return 1;
+	    }
 	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "COOLER_TEMP", "%f", simulator->cooler_temp)) < 0) {
 	    	syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteElement");
 	    	return 1;
@@ -1935,6 +1943,8 @@
     simulator->uuid = simulator->name = NULL;
     simulator->volume_air = simulator->volume_beer = 0;
     simulator->room_temperature = simulator->air_temperature = simulator->beer_temperature = simulator->s_cool_temp = simulator->s_heat_temp = 20.0;
+    simulator->chiller_temperature = 1.5;
+    simulator->room_humidity = 49.2;
     simulator->cooler_temp = simulator->cooler_size = simulator->heater_temp = simulator->heater_size = simulator->frigo_isolation = 0.0;
     simulator->cooler_time = simulator->heater_time = simulator->cooler_state = simulator->heater_state = 0;
     simulator->s_yeast_started = simulator->s_cool_changed = simulator->s_heat_changed = (time_t)0;
@@ -1975,6 +1985,12 @@
 		simulator->room_temperature = fval;
 	    xmlFree(key);
 	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"ROOM_GUMIDITY"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (sscanf((const char *)key, "%f", &fval) == 1)
+		simulator->room_humidity= fval;
+	    xmlFree(key);
+	}
 	if ((!xmlStrcmp(cur->name, (const xmlChar *)"AIR_TEMPERATURE"))) {
 	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
 	    if (sscanf((const char *)key, "%f", &fval) == 1)
@@ -1987,6 +2003,12 @@
 		simulator->beer_temperature = fval;
 	    xmlFree(key);
 	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"CHILLER_TEMPERATURE"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (sscanf((const char *)key, "%f", &fval) == 1)
+		simulator->chiller_temperature = fval;
+	    xmlFree(key);
+	}
 	if ((!xmlStrcmp(cur->name, (const xmlChar *)"COOLER_TEMP"))) {
 	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
 	    if (sscanf((const char *)key, "%f", &fval) == 1)
--- a/thermferm/server.c	Wed Jul 25 14:18:39 2018 +0200
+++ b/thermferm/server.c	Wed Jul 25 20:08:13 2018 +0200
@@ -1575,7 +1575,9 @@
 	simulator->volume_air = 150;
 	simulator->volume_beer = 50;
 	simulator->room_temperature = simulator->air_temperature = simulator->beer_temperature = simulator->s_cool_temp = simulator->s_heat_temp = 20.0;
-	simulator->cooler_temp = -3.0;	/* Cooling temperature */
+	simulator->room_humidity = 48.6;
+	simulator->chiller_temperature = 1.5;	/* Chiller temperature */
+	simulator->cooler_temp =  1.5;	/* Cooling temperature */
 	simulator->cooler_time = 720;	/* About 12 minutes for the cooler plate */
 	simulator->cooler_size = 0.8;	/* 0.8 square meter cooler plate */
 	simulator->heater_temp = 150.0;	/* Heating temperature */
@@ -1622,8 +1624,10 @@
 		srv_send((char *)"VOLUME_AIR,%d", simulator->volume_air);
 		srv_send((char *)"VOLUME_BEER,%d", simulator->volume_beer);
 		srv_send((char *)"ROOM_TEMPERATURE,%.1f", simulator->room_temperature);
+		srv_send((char *)"ROOM_HUMIDITY,%.1f", simulator->room_humidity);
 		srv_send((char *)"AIR_TEMPERATURE,%.3f", simulator->air_temperature);
 		srv_send((char *)"BEER_TEMPERATURE,%.3f", simulator->beer_temperature);
+		srv_send((char *)"CHILLER_TEMPERATURE,%.3f", simulator->chiller_temperature);
 		srv_send((char *)"COOLER_TEMP,%.1f", simulator->cooler_temp);
 		srv_send((char *)"COOLER_TIME,%d", simulator->cooler_time);
 		srv_send((char *)"COOLER_SIZE,%.3f", simulator->cooler_size);
@@ -1687,6 +1691,13 @@
 				    simulator->room_temperature = fval;
 				}
 
+			    } else if (strcmp(kwd, (char *)"ROOM_HUMIDITY") == 0) {
+				if (sscanf(val, "%f", &fval) == 1) {
+				    if (simulator->room_humidity != fval)
+					syslog(LOG_NOTICE, "Simulator %s room hunidity %.1f to %.1f", simulator->uuid, simulator->room_humidity, fval);
+				    simulator->room_humidity = fval;
+				}
+
 			    } else if (strcmp(kwd, (char *)"AIR_TEMPERATURE") == 0) {
 				if (sscanf(val, "%f", &fval) == 1) {
 				    if (simulator->air_temperature != fval)
@@ -1701,6 +1712,13 @@
 				    simulator->beer_temperature = fval;
 				}
 
+			    } else if (strcmp(kwd, (char *)"CHILLER_TEMPERATURE") == 0) {
+				if (sscanf(val, "%f", &fval) == 1) {
+				    if (simulator->chiller_temperature != fval)
+					syslog(LOG_NOTICE, "Simulator %s chiller temperature %.1f to %.1f", simulator->uuid, simulator->chiller_temperature, fval);
+				    simulator->chiller_temperature = fval;
+				}
+
 			    } else if (strcmp(kwd, (char *)"COOLER_TEMP") == 0) {
 				if (sscanf(val, "%f", &fval) == 1) {
 				    if (simulator->cooler_temp != fval)
--- a/thermferm/simulator.c	Wed Jul 25 14:18:39 2018 +0200
+++ b/thermferm/simulator.c	Wed Jul 25 20:08:13 2018 +0200
@@ -31,6 +31,8 @@
 
 int SIMcooling = 0;
 int SIMheating = 0;
+int SIMfan = 0;
+int SIMlight = 0;
 
 
 #ifdef HAVE_WIRINGPI_H
@@ -124,6 +126,7 @@
 		// Cheap trick, just follow slowly the air temp.
 		simulator->beer_temperature += ((simulator->air_temperature - simulator->beer_temperature) / 500.0);
 		simulator->air_temperature += ((simulator->beer_temperature - simulator->air_temperature) / 2500.0);
+		simulator->chiller_temperature = simulator->cooler_temp;	// Libk these
 
 		if ((seconds % 15) == 0)
 		    syslog(LOG_NOTICE, "air=%.3f beer=%.3f heater=%.3f cooler=%.3f", simulator->air_temperature, simulator->beer_temperature,
--- a/thermferm/thermferm.h	Wed Jul 25 14:18:39 2018 +0200
+++ b/thermferm/thermferm.h	Wed Jul 25 20:08:13 2018 +0200
@@ -318,8 +318,10 @@
     int			volume_air;		/* Volume air of the frigo	*/
     int			volume_beer;		/* Volume beer inside frigo	*/
     double		room_temperature;	/* Temp outside frigo		*/
+    double		room_humidity;		/* Humidity outside frigo	*/
     double		air_temperature;	/* Simulated air temperature	*/
     double		beer_temperature;	/* Simulated beer temperature	*/
+    double		chiller_temperature;	/* Simulated chiller temp.	*/
     double		cooler_temp;		/* Lowest cooler temperature	*/
     int			cooler_time;		/* Time to reach temperature	*/
     float		cooler_size;		/* Size of cooler in square mtr	*/
--- a/www-thermferm/simulator.php	Wed Jul 25 14:18:39 2018 +0200
+++ b/www-thermferm/simulator.php	Wed Jul 25 20:08:13 2018 +0200
@@ -1,6 +1,6 @@
 <?php
 /*****************************************************************************
- * Copyright (C) 2014
+ * Copyright (C) 2014-2018
  *   
  * Michiel Broek <mbroek at mbse dot eu>
  *
@@ -78,6 +78,7 @@
  * @param string $_POST['VolumeAir'] The simulator Air volume
  * @param string $_POST['VolumeBeer'] The simulator Beer volume
  * @param string $_POST['RoomTemperature'] The simulator room temp
+ * @param string $_POST['RoomHumidity'] The simulator room humidity
  * @param string $_POST['CoolerTemp'] The simulator cold temp
  * @param string $_POST['CoolerTime'] The simulator time to reach this
  * @param string $_POST['CoolerSize'] The simulator plate size
@@ -101,6 +102,7 @@
 	$cmd[] = "VOLUME_AIR,".$_POST['VolumeAir'];
 	$cmd[] = "VOLUME_BEER,".$_POST['VolumeBeer'];
 	$cmd[] = "ROOM_TEMPERATURE,".$_POST['RoomTemperature'];
+	$cmd[] = "ROOM_HUMIDITY,".$_POST['RoomHumidity'];
 	$cmd[] = "COOLER_TEMP,".$_POST['CoolerTemp'];
 	$cmd[] = "COOLER_TIME,".$_POST['CoolerTime'];
 	$cmd[] = "COOLER_SIZE,".$_POST['CoolerSize'];
@@ -117,6 +119,7 @@
     unset($_POST['VolumeAir']);
     unset($_POST['VolumeBeer']);
     unset($_POST['RoomTemperature']);
+    unset($_POST['RoomHumidity']);
     unset($_POST['CoolerTemp']);
     unset($_POST['CoolerTime']);
     unset($_POST['CoolerSize']);
@@ -139,6 +142,7 @@
  * @param string $_POST['VolumeAir'] The simulator Air volume
  * @param string $_POST['VolumeBeer'] The simulator Beer volume
  * @param string $_POST['RoomTemperature'] The simulator room temp
+ * @param string $_POST['RoomHumidity'] The simulator room humidity
  * @param string $_POST['CoolerTemp'] The simulator cold temp
  * @param string $_POST['CoolerTime'] The simulator time to reach this
  * @param string $_POST['CoolerSize'] The simulator plate size
@@ -160,7 +164,7 @@
     global $arr;
 
     if (isset($_POST['UUID']) && isset($_POST['Name']) && isset($_POST['VolumeAir']) && isset($_POST['VolumeBeer']) && 
-	isset($_POST['RoomTemperature']) && isset($_POST['CoolerTemp']) && isset($_POST['CoolerTime']) &&
+	isset($_POST['RoomTemperature']) && isset($_POST['RoomHumidity']) && isset($_POST['CoolerTemp']) && isset($_POST['CoolerTime']) &&
 	isset($_POST['CoolerSize']) && isset($_POST['HeaterTemp']) && isset($_POST['HeaterTime']) && isset($_POST['HeaterSize']) && 
 	isset($_POST['FrigoIsolation']) && isset($_POST['key']) && isset($_POST['command'])) {
 
@@ -282,6 +286,12 @@
 		$outstr .= '        <td class="editfield"><input type="text" name="RoomTemperature" size="5" value="'.$f[1].'"></td>'.PHP_EOL;
 		$outstr .= '       </tr>'.PHP_EOL;
 	    }
+	    if ($f[0] == "ROOM_HUMIDITY") {
+		$outstr .= '       <tr class="editor">'.PHP_EOL;
+		$outstr .= '        <td class="editname">Room Humidity</td>'.PHP_EOL;
+		$outstr .= '        <td class="editfield"><input type="text" name="RoomHumidity" size="5" value="'.$f[1].'"></td>'.PHP_EOL;
+		$outstr .= '       </tr>'.PHP_EOL;
+	    }
 	    if ($f[0] == "COOLER_TEMP") {
 		$outstr .= '       <tr class="editor">'.PHP_EOL;
 		$outstr .= '        <td class="editname">Cooler Temperature</td>'.PHP_EOL;
@@ -417,6 +427,7 @@
     $outstr .= '<input type="hidden" value="150" name="VolumeAir">';
     $outstr .= '<input type="hidden" value="50" name="VolumeBeer">';
     $outstr .= '<input type="hidden" value="20.0" name="RoomTemperature">';
+    $outstr .= '<input type="hidden" value="48.5" name="RoomHumidity">';
     $outstr .= '<input type="hidden" value="-3.0" name="CoolerTemp">';
     $outstr .= '<input type="hidden" value="720" name="CoolerTime">';
     $outstr .= '<input type="hidden" value="0.8" name="CoolerSize">';

mercurial