Merge "ROVER - changes to Hono interaction API adressing recent Hono 0.5-M9 Update Buzzer functionality improved, Driving modes are extended, Proper shutdown function is written."
diff --git a/rover/src/RaspberryTest.cpp b/rover/src/RaspberryTest.cpp
index 7883328..04b3444 100644
--- a/rover/src/RaspberryTest.cpp
+++ b/rover/src/RaspberryTest.cpp
@@ -45,6 +45,7 @@
 #include "tasks/srf02_task.h"
 #include "tasks/bluetooth_task.h"
 #include "tasks/external_gpio_task.h"
+#include "tasks/image_processing_task.h"
 
 #include "interfaces.h"
 #include "pthread_monitoring/collect_thread_name.h"
@@ -122,6 +123,9 @@
 timing_interface extgpio_task_ti;
 pthread_mutex_t extgpio_task_ti_l;
 
+timing_interface imgproc_task_ti;
+pthread_mutex_t imgproc_task_ti_l;
+
 //Shared data between threads
 
 float temperature_shared;
diff --git a/rover/src/hono_interaction/hono_interaction.cpp b/rover/src/hono_interaction/hono_interaction.cpp
index 352b937..edf7f6a 100644
--- a/rover/src/hono_interaction/hono_interaction.cpp
+++ b/rover/src/hono_interaction/hono_interaction.cpp
@@ -12,6 +12,9 @@
  *    M. Ozcelikors,            R.Hottger
  *    <mozcelikors@gmail.com>   <robert.hoettger@fh-dortmund.de>
  *
+ * Version Summary:
+ *     v1.2: Compliance changes for Hono Instance 0.5-M9
+ *
  * Usage:
  * 		To test the hono interaction library:
  *
@@ -87,7 +90,7 @@
 		case 406:
 		case 407:
 		case 408:
-			fprintf(stderr, ("Error\n"));
+			fprintf(stderr, ("Error in Hono connection. \n"));
 			status = 0;
 			break;
 		default:
@@ -116,10 +119,10 @@
 	int status;
 
 	//Prepare command as string
-	//Example: "curl -X POST -i -d 'device_id=AStringID' http://localhost:28080/registration/DEFAULT_TENANT"
-	sprintf(buffer, "curl -X POST -i -d 'device_id=");
+	//Example: "curl -X POST -i -H 'Content-Type: application/json' -d '{"device-id": "4711"}' http://idial.institute:28080/registration/DEFAULT_TENANT"
+	sprintf(buffer, "curl -X POST -i -H 'Content-Type: application/json' -d '{\"device-id\":\"");
 	strcat(buffer, device_id);
-	strcat(buffer, "' http://");
+	strcat(buffer, "\"}' http://");
 	strcat(buffer, host_name);
 	strcat(buffer, ":");
 	snprintf(num_buffer, sizeof(num_buffer), "%d", port);
@@ -187,25 +190,29 @@
 	//Prepare command as string
 	//Example: "curl -X PUT -i -H 'Content-Type: application/json' --data-binary '{"Bearing": 0.5}' http://idial.institute:8080/telemetry/DEFAULT_TENANT/4711"
 
+	//For Hono 0.5-M9
+	//Example: "curl -X POST -i -u sensor1@DEFAULT_TENANT:hono-secret -H 'Content-Type: application/json' --data-binary '{"temp": 5}' http://idial.institute:8080/telemetry"
+
 	//To get the information in dashboard, we use device ID as the entry name, and "value" as field.
 	//Example: "curl -X PUT -i -H 'Content-Type: application/json' --data-binary '{"value": 0.5}' http://idial.institute:8080/telemetry/DEFAULT_TENANT/roverRearSensor"
 
-	sprintf(buffer, "curl -X PUT -i -H 'Content-Type: application/json' --data-binary '{\"");
+	sprintf(buffer, "curl -X POST -i -u sensor1@");
+	strcat(buffer, tenant_name);
+	strcat(buffer, ":hono-secret -H 'Content-Type: application/json' --data-binary '{\"");
+
 	strcat(buffer, field);
 	strcat(buffer, "\": ");
 	snprintf(num_buffer, sizeof(num_buffer), "%f", value);
 	strcat(buffer, num_buffer);
 	num_buffer[0] = 0; //Clear array
+
 	strcat(buffer, "}' http://");
 	strcat(buffer, host_name);
 	strcat(buffer, ":");
 	snprintf(num_buffer, sizeof(num_buffer), "%d", port);
 	strcat(buffer, num_buffer);
 	num_buffer[0] = 0; //Clear array
-	strcat(buffer, "/telemetry/");
-	strcat(buffer, tenant_name);
-	strcat(buffer, "/");
-	strcat(buffer, device_id);
+	strcat(buffer, "/telemetry");
 
 	//To redirect pipe to prevent stdout showing all outputs generated by curl
 	strcat(buffer, " 2>/dev/null"); //2>&1 would redirect to stderr, we choose to be able to parse returned code
@@ -266,24 +273,29 @@
 	//Prepare command as string
 	//Example: "curl -X PUT -i -H 'Content-Type: application/json' --data-binary '{"Bearing": 0.5}' http://idial.institute:8080/event/DEFAULT_TENANT/4711"
 
+	//For Hono 0.5-M9
+	//Example: "curl -X POST -i -u sensor1@DEFAULT_TENANT:hono-secret -H 'Content-Type: application/json' --data-binary '{"temp": 5}' http://idial.institute:8080/event"
+
 	//To get the information in dashboard, we use device ID as the entry name, and "value" as field.
 	//Example: "curl -X PUT -i -H 'Content-Type: application/json' --data-binary '{"value": 0.5}' http://idial.institute:8080/event/DEFAULT_TENANT/roverRearSensor"
-	sprintf(buffer, "curl -X PUT -i -H 'Content-Type: application/json' --data-binary '{\"");
+
+	sprintf(buffer, "curl -X POST -i -u sensor1@");
+	strcat(buffer, tenant_name);
+	strcat(buffer, ":hono-secret -H 'Content-Type: application/json' --data-binary '{\"");
+
 	strcat(buffer, field);
 	strcat(buffer, "\": ");
 	snprintf(num_buffer, sizeof(num_buffer), "%f", value);
 	strcat(buffer, num_buffer);
 	num_buffer[0] = 0; //Clear array
+
 	strcat(buffer, "}' http://");
 	strcat(buffer, host_name);
 	strcat(buffer, ":");
 	snprintf(num_buffer, sizeof(num_buffer), "%d", port);
 	strcat(buffer, num_buffer);
 	num_buffer[0] = 0; //Clear array
-	strcat(buffer, "/event/");
-	strcat(buffer, tenant_name);
-	strcat(buffer, "/");
-	strcat(buffer, device_id);
+	strcat(buffer, "/event");
 
 	//To redirect pipe to prevent stdout showing all outputs generated by curl
 	strcat(buffer, " 2>/dev/null"); //2>&1 would redirect to stderr, we choose to be able to parse returned code
@@ -329,18 +341,19 @@
  */
 int registerEntriesToHonoInstance (void)
 {
-	registerDeviceToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "roverFront");
-	registerDeviceToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "roverFrontLeft");
-	registerDeviceToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "roverFrontRight");
-	registerDeviceToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "roverRear");
-	registerDeviceToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "roverRearLeft");
-	registerDeviceToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "roverRearRight");
-	registerDeviceToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "roverBearing");
-	registerDeviceToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "roverUtilCpu1");
-	registerDeviceToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "roverUtilCpu2");
-	registerDeviceToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "roverUtilCpu3");
-	registerDeviceToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "roverUtilCpu4");
-	registerDeviceToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "connectionCheck");
+	/*registerDeviceToHonoInstance("idial.institute",28080,"DEFAULT_TENANT", "roverFront");
+	registerDeviceToHonoInstance("idial.institute",28080,"DEFAULT_TENANT", "roverFrontLeft");
+	registerDeviceToHonoInstance("idial.institute",28080,"DEFAULT_TENANT", "roverFrontRight");
+	registerDeviceToHonoInstance("idial.institute",28080,"DEFAULT_TENANT", "roverRear");
+	registerDeviceToHonoInstance("idial.institute",28080,"DEFAULT_TENANT", "roverRearLeft");
+	registerDeviceToHonoInstance("idial.institute",28080,"DEFAULT_TENANT", "roverRearRight");
+	registerDeviceToHonoInstance("idial.institute",28080,"DEFAULT_TENANT", "roverBearing");
+	registerDeviceToHonoInstance("idial.institute",28080,"DEFAULT_TENANT", "roverUtilCpu1");
+	registerDeviceToHonoInstance("idial.institute",28080,"DEFAULT_TENANT", "roverUtilCpu2");
+	registerDeviceToHonoInstance("idial.institute",28080,"DEFAULT_TENANT", "roverUtilCpu3");
+	registerDeviceToHonoInstance("idial.institute",28080,"DEFAULT_TENANT", "roverUtilCpu4");
+	registerDeviceToHonoInstance("idial.institute",28080,"DEFAULT_TENANT", "connectionCheck");*/
+	registerDeviceToHonoInstance("idial.institute",28080,"DEFAULT_TENANT", "4711");
 
 	return 1;
 }
diff --git a/rover/src/interfaces.h b/rover/src/interfaces.h
index 5a96d7a..bb76b81 100644
--- a/rover/src/interfaces.h
+++ b/rover/src/interfaces.h
@@ -30,6 +30,8 @@
 #define ACC    1
 #define PARKING_LEFT 2
 #define PARKING_RIGHT 3
+#define BOOTH1 4
+#define BOOTH2 5
 
 typedef struct  {
    char * task_id;
@@ -104,6 +106,9 @@
 extern timing_interface extgpio_task_ti;
 extern pthread_mutex_t extgpio_task_ti_l;
 
+extern timing_interface imgproc_task_ti;
+extern pthread_mutex_t imgproc_task_ti_l;
+
 //---
 
 extern float temperature_shared;
diff --git a/rover/src/status_library/status_library.cpp b/rover/src/status_library/status_library.cpp
index 9e5acd9..3611738 100644
--- a/rover/src/status_library/status_library.cpp
+++ b/rover/src/status_library/status_library.cpp
@@ -136,7 +136,7 @@
 	int status = 0;
 
 	/* Execute the command */
-	fp = popen("curl -X PUT -i -H 'Content-Type: application/json' --data-binary '{\"check\": 1.0}' http://idial.institute:8080/telemetry/DEFAULT_TENANT/connectionCheck 2>/dev/null","r");
+	fp = popen("curl -X POST -i -u sensor1@DEFAULT_TENANT:hono-secret -H 'Content-Type: application/json' --data-binary '{\"connection_check\": 1}' http://idial.institute:8080/telemetry 2>/dev/null","r");
 
 	/* Read from pipe */
 	fgets(buffer, 13, fp); //Get the string HTTP/1.1 XXX
diff --git a/rover/src/tasks/external_gpio_task.cpp b/rover/src/tasks/external_gpio_task.cpp
index 12bd57e..0cf929c 100644
--- a/rover/src/tasks/external_gpio_task.cpp
+++ b/rover/src/tasks/external_gpio_task.cpp
@@ -44,6 +44,17 @@
 	{
 		softToneWrite (BUZZER_PIN, BUZZER_ON_FREQ);
 	}
+
+
+	if (distance_sr04_front_shared < 10)
+	{
+		softToneWrite (BUZZER_PIN, (int) ((10 - distance_sr04_front_shared)*500));
+	}
+	else
+	{
+		softToneWrite (BUZZER_PIN, BUZZER_OFF_FREQ);
+	}
+
 }
 
 void turnBuzzerOn (void)
diff --git a/rover/src/tasks/hono_interaction_task.cpp b/rover/src/tasks/hono_interaction_task.cpp
index 33c4304..09201a1 100644
--- a/rover/src/tasks/hono_interaction_task.cpp
+++ b/rover/src/tasks/hono_interaction_task.cpp
@@ -48,17 +48,18 @@
 
 		// Send everything to Hono every second in this task using the following functions
 		// TODO: This can be done with one curl command, probably a better way.
-		sendTelemetryDataToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "roverFront","value", distance_sr04_front_shared);
-		sendTelemetryDataToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "roverFrontLeft","value",infrared_shared[3]);
-		sendTelemetryDataToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "roverFrontRight","value", infrared_shared[2]);
-		sendTelemetryDataToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "roverRear","value", distance_sr04_back_shared);
-		sendTelemetryDataToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "roverRearLeft","value", infrared_shared[1]);
-		sendTelemetryDataToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "roverRearRight","value", infrared_shared[0]);
-		sendTelemetryDataToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "roverBearing","value", bearing_shared);
-		sendTelemetryDataToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "roverUtilCpu1","value", cpu_util_shared[0]);
-		sendTelemetryDataToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "roverUtilCpu2","value", cpu_util_shared[1]);
-		sendTelemetryDataToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "roverUtilCpu3","value", cpu_util_shared[2]);
-		sendTelemetryDataToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "roverUtilCpu4","value", cpu_util_shared[3]);
+		sendTelemetryDataToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "4711","roverFront", distance_sr04_front_shared);
+		sendTelemetryDataToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "4711","roverFrontLeft",infrared_shared[3]);
+		sendTelemetryDataToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "4711","roverFrontRight", infrared_shared[2]);
+		sendTelemetryDataToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "4711","roverRear", distance_sr04_back_shared);
+		sendTelemetryDataToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "4711","roverRearLeft", infrared_shared[1]);
+		sendTelemetryDataToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "4711","roverRearRight", infrared_shared[0]);
+		sendTelemetryDataToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "4711","roverBearing", bearing_shared);
+		sendTelemetryDataToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "4711","roverUtilCpu1", cpu_util_shared[0]);
+		sendTelemetryDataToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "4711","roverUtilCpu2", cpu_util_shared[1]);
+		sendTelemetryDataToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "4711","roverUtilCpu3", cpu_util_shared[2]);
+		sendTelemetryDataToHonoInstance("idial.institute",8080,"DEFAULT_TENANT", "4711","roverUtilCpu4", cpu_util_shared[3]);
+
 
 		//Task content ends here -------------------------------------------------
 
diff --git a/rover/src/tasks/motordriver_task.cpp b/rover/src/tasks/motordriver_task.cpp
index 8c2a515..4db7c2b 100644
--- a/rover/src/tasks/motordriver_task.cpp
+++ b/rover/src/tasks/motordriver_task.cpp
@@ -35,9 +35,11 @@
 
 #include "../pthread_monitoring/collect_thread_name.h"
 
+#include "oled_task.h"
+
 void ExitAutomaticModes(void)
 {
-	if (driving_mode == ACC || driving_mode == PARKING_LEFT || driving_mode == PARKING_RIGHT)
+	if (driving_mode == ACC || driving_mode == PARKING_LEFT || driving_mode == PARKING_RIGHT || driving_mode == BOOTH1 || driving_mode == BOOTH2)
 	{
 		stop(); //Stop the rover first.
 		pthread_mutex_lock(&driving_mode_lock);
@@ -48,7 +50,7 @@
 
 void ManualModeSet(void)
 {
-	if (driving_mode == ACC || driving_mode == PARKING_LEFT || driving_mode == PARKING_RIGHT)
+	if (driving_mode == ACC || driving_mode == PARKING_LEFT || driving_mode == PARKING_RIGHT || driving_mode == BOOTH1 || driving_mode == BOOTH2)
 	{
 		stop(); //Stop the rover first.
 	}
@@ -62,7 +64,7 @@
 
 void ParkingRightModeSet(void)
 {
-	if (driving_mode == ACC || driving_mode == MANUAL)
+	if (driving_mode == ACC || driving_mode == MANUAL || driving_mode == BOOTH1 || driving_mode == BOOTH2)
 	{
 		stop(); //Stop the rover first.
 	}
@@ -76,7 +78,7 @@
 
 void ParkingLeftModeSet(void)
 {
-	if (driving_mode == ACC || driving_mode == MANUAL)
+	if (driving_mode == ACC || driving_mode == MANUAL || driving_mode == BOOTH1 || driving_mode == BOOTH2)
 	{
 		stop(); //Stop the rover first.
 	}
@@ -90,7 +92,7 @@
 
 void ACCModeSet(void)
 {
-	if (driving_mode == PARKING_LEFT || driving_mode == PARKING_RIGHT || driving_mode == MANUAL)
+	if (driving_mode == PARKING_LEFT || driving_mode == PARKING_RIGHT || driving_mode == MANUAL || driving_mode == BOOTH1 || driving_mode == BOOTH2   )
 	{
 		stop(); //Stop the rover first.
 	}
@@ -102,6 +104,34 @@
 	pthread_mutex_unlock(&keycommand_lock);
 }
 
+void BoothMode1Set(void)
+{
+	if (driving_mode == PARKING_LEFT || driving_mode == PARKING_RIGHT || driving_mode == MANUAL || driving_mode == BOOTH2  || driving_mode == ACC)
+	{
+		stop(); //Stop the rover first.
+	}
+	pthread_mutex_lock(&driving_mode_lock);
+		driving_mode = BOOTH1;
+	pthread_mutex_unlock(&driving_mode_lock);
+	pthread_mutex_lock(&keycommand_lock);
+		keycommand_shared = 'f';
+	pthread_mutex_unlock(&keycommand_lock);
+}
+
+void BoothMode2Set(void)
+{
+	if (driving_mode == PARKING_LEFT || driving_mode == PARKING_RIGHT || driving_mode == MANUAL || driving_mode == BOOTH1 || driving_mode == ACC)
+	{
+		stop(); //Stop the rover first.
+	}
+	pthread_mutex_lock(&driving_mode_lock);
+		driving_mode = BOOTH2;
+	pthread_mutex_unlock(&driving_mode_lock);
+	pthread_mutex_lock(&keycommand_lock);
+		keycommand_shared = 'f';
+	pthread_mutex_unlock(&keycommand_lock);
+}
+
 
 void *MotorDriver_Task(void * arg)
 {
@@ -177,6 +207,10 @@
 			case 'u':
 				//Calibration mode
 				break;
+			case 'r':
+				//Shutdown hook from web server
+				shutdownOSwithDisplay();
+				break;
 			case 'm':
 				//ACC mode set
 				ACCModeSet();
@@ -185,6 +219,14 @@
 				//Manual mode set
 				ManualModeSet();
 				break;
+			case 'l':
+				//Booth mode (Demo 1) set
+				BoothMode1Set();
+				break;
+			case 'n':
+				//Booth mode (Demo 2) set
+				BoothMode2Set();
+				break;
 			case 'f':
 				stop();
 				break;
diff --git a/rover/src/tasks/oled_task.cpp b/rover/src/tasks/oled_task.cpp
index a292e3a..94aaa0b 100644
--- a/rover/src/tasks/oled_task.cpp
+++ b/rover/src/tasks/oled_task.cpp
@@ -87,6 +87,36 @@
 	display.clearDisplay();   // clears the screen and buffer
 }
 
+/* Proper shutdown function, including showing message in the OLED display */
+void shutdownOSwithDisplay(void)
+{
+	/* Prepare "Shutting Down..." */
+	display.clearDisplay();
+
+	display.setTextSize(2);
+	display.setTextColor(WHITE);
+
+	display.setCursor(20,10);
+	display.print("Shutting");
+
+	display.setTextColor(WHITE);
+
+	display.setCursor(20,32);
+	display.print("Down...");
+
+	/* Display everything earlier this time*/
+	display.display();
+
+	/* Play the shutdown tone..*/
+	playShutdownTone();
+
+	/* Here we're shutting Raspberry Pi down.. */
+	shutdownOS();
+
+	/* Abort the application for safety reasons */
+	abort();
+}
+
 void *OLED_Task (void * arg)
 {
 	timing oled_task_tmr;
@@ -284,31 +314,8 @@
 		}
 		else
 		{
-			/* Prepare "Shutting Down..." */
-			display.clearDisplay();
-
-			display.setTextSize(2);
-			display.setTextColor(WHITE);
-
-			display.setCursor(20,10);
-			display.print("Shutting");
-
-			display.setTextColor(WHITE);
-
-			display.setCursor(20,32);
-			display.print("Down...");
-
-			/* Display everything earlier this time*/
-			display.display();
-
-			/* Play the shutdown tone..*/
-			playShutdownTone();
-
-			/* Here we're shutting Raspberry Pi down.. */
-			shutdownOS();
-
-			/* Abort the application for safety reasons */
-			abort();
+			// Proper shutdown function, including showing message in the OLED display
+			shutdownOSwithDisplay();
 		}
 
 		/* Display the stuff NOW */
diff --git a/rover/src/tasks/oled_task.h b/rover/src/tasks/oled_task.h
index f526062..3afc6b7 100644
--- a/rover/src/tasks/oled_task.h
+++ b/rover/src/tasks/oled_task.h
@@ -50,5 +50,6 @@
 
 /* Intefaces */
 void *OLED_Task(void * arg);
+void shutdownOSwithDisplay(void);
 
 #endif /* TASKS_OLED_TASK_H_ */
diff --git a/rover/src/tasks/parking_task.cpp b/rover/src/tasks/parking_task.cpp
index 8603914..ffb9b5c 100644
--- a/rover/src/tasks/parking_task.cpp
+++ b/rover/src/tasks/parking_task.cpp
@@ -45,6 +45,7 @@
     pthread_mutex_unlock(&driving_mode_lock);
     return 1;
 }
+
 void *Parking_Task(void * arg)
 {
 	timing parking_task_tmr;