From 9762a0ff497c66d1d8288ec1e07a04efee199f4f Mon Sep 17 00:00:00 2001
From: "de@itstall.de" <de@itstall.de>
Date: Mon, 3 Feb 2020 07:33:45 +0100
Subject: [PATCH] Settings saved from frontend. closes #1

---
 MqttClient.h      |  60 ++++++++++++++++++----------------------------
 backend.cpp       |  14 ++++++-----
 backend.vcxproj   |   1 +
 dbSqlite.h        |  32 ++++++++++++++++++++++++-
 openweathermap.h  |   6 ++---
 structs.h         |  48 +++++++++++++++++++------------------
 weatherstation.db | Bin 552960 -> 552960 bytes
 7 files changed, 90 insertions(+), 71 deletions(-)

diff --git a/MqttClient.h b/MqttClient.h
index 0708316..be130a3 100644
--- a/MqttClient.h
+++ b/MqttClient.h
@@ -8,7 +8,7 @@
 #include "structs.h"
 
 #define MAX_PAYLOAD 50
-#define DEBUG true
+#define DEBUG false
 
 class MqttClient : public mosqpp::mosquittopp {
 private:
@@ -19,48 +19,34 @@ public:
 		if (DEBUG) std::cout << "MqttClient::MqttClient()" << std::endl;
 		this->db = db_new;
 		int keepalive = 60;
-		if (DEBUG) std::cout << "MqttClient: Connecting to host: " << db->getSettings().mqtt_host << std::endl;
-		if (DEBUG) std::cout << "MqttClient: With user: " << db->getSettings().mqtt_user << std::endl;
-		if (DEBUG) std::cout << "MqttClient: Backend Topic: " << db->getSettings().mqtt_topic_backend << std::endl;
-		if (DEBUG) std::cout << "MqttClient: Frontend Topic: " << db->getSettings().mqtt_topic_frontend << std::endl;
-		if (DEBUG) std::cout << "MqttClient: port: " << db->getSettings().mqtt_port << std::endl;
-		if (DEBUG) std::cout << "MqttClient: id: " << id_new << std::endl;
-		if (DEBUG) std::cout << "MqttClient: keepalive: " << keepalive << std::endl;
+		if (DEBUG) std::cout << "MqttClient: Connecting to host: " << db->getSettings().mqtt_host << ":" << db->getSettings().mqtt_port << std::endl;
 
 		// Benutzername und Passwort setzen
 		mosquittopp::username_pw_set(db->getSettings().mqtt_user.c_str(), db->getSettings().mqtt_pass.c_str());
-		if (DEBUG) std::cout << "MqttClient: Username and password set: " << std::endl;
 
 		// Asynchrone Verbindung aufbauen
 		mosquittopp::connect(db->getSettings().mqtt_host.c_str(), db->getSettings().mqtt_port, keepalive);
-		if (DEBUG) std::cout << "MqttClient: connect " << std::endl;
 
 		// Subscribe zu Backend Topic
-		mosquittopp::subscribe(NULL, db->getSettings().mqtt_topic_backend.c_str());
-		if (DEBUG) std::cout << "MqttClient: subscribe: " << std::endl;
+		mosquittopp::subscribe(NULL, (db->getSettings().mqtt_topic_backend + "#").c_str());
 
 		// Startet den Thread
 		mosquittopp::loop_start();
-		if (DEBUG) std::cout << "MqttClient: loop start: " << std::endl;
 	}
 
 	~MqttClient() {
 		// Stoppt den Thread
 		loop_stop();
-		if (DEBUG) std::cout << "MqttClient: loop stopped: " << std::endl;
 		// Mosuqitto library cleanup
 		mosqpp::lib_cleanup();
-		if (DEBUG) std::cout << "MqttClient: libs cleaned: " << std::endl;
 	}
 
 	void on_connect(int rc) {
-		if (DEBUG) std::cout << "MqttClient::on_connect()" << std::endl;
-	    if (!rc) std::cout << "Connected - code " << rc << std::endl;
+	    if (!rc) std::cout << "MqttClient::on_connect(): Connected(" << rc << ")" << std::endl;
 	}
 	
 	void on_subscribe(int mid, int qos_count, const int* granted_qos) {
 		if (DEBUG) std::cout << "MqttClient::on_subscribe()" << std::endl;
-		std::cout << "Subscription succeeded." << std::endl;
 	}
 
 	bool send_message(const char* message, const char* topic) {
@@ -74,9 +60,7 @@ public:
 		// * retain (boolean) - indicates if message is retained on broker or not
 		// Should return MOSQ_ERR_SUCCESS
 		int ret = publish(NULL, topic, strlen(message), message, db->getSettings().mqtt_qos, true);
-		if (DEBUG) std::cout << "Published: " << std::endl;
-		if (DEBUG) std::cout << "Topic: " << topic << std::endl;
-		if (DEBUG) std::cout << "Message: " << message << std::endl;
+		if (DEBUG) std::cout << "Published to topic: " << topic << std::endl;
 		return (ret == MOSQ_ERR_SUCCESS);
 	}
 
@@ -85,26 +69,28 @@ public:
 	}
 	
 	void on_message(const mosquitto_message* message) {
-		if (DEBUG) std::cout << "MqttClient::on_message()" << " received message of topic: " << message->topic << " Data: " << reinterpret_cast<char*>(message->payload) << std::endl;
-		const char payload_size = MAX_PAYLOAD + 1;
+		//if (DEBUG) std::cout << "MqttClient::on_message()" << " received message of topic: " << message->topic << " Data: " << reinterpret_cast<char*>(message->payload) << std::endl;
+		if (DEBUG) std::cout << "MqttClient::on_message()" << " received message of topic: " << message->topic << std::endl;
+		const char payload_size = sizeof(message->payload) + 1;
 		char buf[payload_size];
 
-		if (!strcmp(message->topic, db->getSettings().mqtt_topic_backend.c_str())) {
-			memset(buf, 0, payload_size * sizeof(char));
+		std::string topic = message->topic;
+		std::string topicDb = db->getSettings().mqtt_topic_backend + "settings";
+
+		//if (!strcmp(message->topic, (db->getSettings().mqtt_topic_backend + "settings").c_str())) {
+		if(topic.compare(topicDb) == 0) {
+			//memset(buf, 0, message->payloadlen);
 
 			/* Copy N-1 bytes to ensure always 0 terminated. */
-			memcpy(buf, message->payload, MAX_PAYLOAD * sizeof(char));
-
-			std::string str(buf);
-
-			/*if (str.find("Request_") != std::string::npos) {
-				std::cout << "MqttClient::on_message() - Request found" << std::endl;
-				std::string client = str.substr(str.find("_") + 1);
-				std::cout << "Client " + client + " requested update" << std::endl;
-				std::string result = db->getFrontendData().c_str();
-				snprintf(buf, payload_size, result.c_str());
-				publish(NULL, db->getSettings().mqtt_topic_frontend.c_str(), strlen(result.c_str()), result.c_str());
-			}*/
+			//memcpy(buf, message->payload, message->payloadlen);
+
+			if (DEBUG) std::cout << "MqttClient::on_message() - new settings found" << std::endl;
+			db->updateFrontendSettings(reinterpret_cast<char*>(message->payload));
+			//std::string client = str.substr(str.find("_") + 1);
+			//std::cout << "Client " + client + " requested update" << std::endl;
+			//std::string result = db->getFrontendData().c_str();
+			//snprintf(buf, payload_size, result.c_str());
+			//publish(NULL, db->getSettings().mqtt_topic_frontend.c_str(), strlen(result.c_str()), result.c_str());
 		}
 	}
 };
\ No newline at end of file
diff --git a/backend.cpp b/backend.cpp
index b1f07ee..216cfa6 100644
--- a/backend.cpp
+++ b/backend.cpp
@@ -1,3 +1,4 @@
+#pragma once
 #include <iostream>
 #include <thread>
 #include <chrono>
@@ -9,7 +10,7 @@
 #include "dbSqlite.h"
 #include "structs.h"
 
-#define DEBUG true
+#define DEBUG false
 
 using std::string;
 using std::cout;
@@ -33,6 +34,7 @@ void schedulerWeather(int time) {
         region = db->queryRegions();
         frontend = db->queryFrontends();
         for (int i = 0; i < region.size(); i++) {
+            cout << "Weather new RUN(" << region[i].plz <<") ";
             if (DEBUG) cout << "Wetterstation::schedulerWeather(" + region[i].plz + ")" << endl;
             owmw->getWeather(region[i].plz, region[i].lngCode);
             weather = db->getFrontendDataWeather().c_str();
@@ -43,7 +45,6 @@ void schedulerWeather(int time) {
                     std::this_thread::sleep_for(std::chrono::milliseconds(50));
                 }
             }
-            std::this_thread::sleep_for(std::chrono::milliseconds(100));
         }
         std::this_thread::sleep_for(std::chrono::milliseconds(time));
     }
@@ -61,6 +62,7 @@ void schedulerForecast(int time) {
         region = db->queryRegions();
         frontend = db->queryFrontends();
         for (int i = 0; i < region.size(); i++) {
+            cout << "Forecast new RUN(" << region[i].plz << ") ";
             if (DEBUG) cout << "Wetterstation::schedulerForecast(" + region[i].plz + ")" << endl;
             owmw->getForecast(region[i].plz, region[i].lngCode);
             forecast = db->getFrontendDataForecast().c_str();
@@ -71,7 +73,6 @@ void schedulerForecast(int time) {
                     std::this_thread::sleep_for(std::chrono::milliseconds(50));
                 }
             }
-            std::this_thread::sleep_for(std::chrono::milliseconds(100));
         }
         std::this_thread::sleep_for(std::chrono::milliseconds(time));
     }
@@ -99,18 +100,19 @@ int main() {
     // Initialisieren der Datenbank
     db = new dbSqlite();
 
+    // Initialisieren der Openweathermap
     owmw = new openweathermap(db);
 
     // MQTT starten
     mqttStart();
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
 
     // Thread für getWeather starten
     thread thrWeather{ schedulerWeather, 60000 };
-    std::this_thread::sleep_for(std::chrono::milliseconds(50));
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
 
     // Thread für getForecast starten
-    thread thrForecast{ schedulerForecast, 90000 };
-    std::this_thread::sleep_for(std::chrono::milliseconds(50));
+    thread thrForecast{ schedulerForecast, 600000 };
 
     while (1) {
         Sleep(1000);
diff --git a/backend.vcxproj b/backend.vcxproj
index bd8672c..72c635d 100644
--- a/backend.vcxproj
+++ b/backend.vcxproj
@@ -144,6 +144,7 @@
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
       <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalOptions>/Force:Multiple %(AdditionalOptions)</AdditionalOptions>
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>
diff --git a/dbSqlite.h b/dbSqlite.h
index ff71ca5..fd921c0 100644
--- a/dbSqlite.h
+++ b/dbSqlite.h
@@ -7,6 +7,7 @@
 #include "nlohmann/json.hpp"
 #include "influxdb.h"
 #include "structs.h"
+#include "json.h"
 
 using namespace Poco::Data::Keywords;
 using Poco::Data::Session;
@@ -15,7 +16,7 @@ using std::string;
 using std::cout;
 using std::endl;
 
-#define DEBUG true
+#define DEBUG false
 
 class dbSqlite {
 private:
@@ -216,6 +217,7 @@ public:
 
     std::vector<Frontend> queryFrontends() {
         if (DEBUG) cout << "dbSqlite::queryFrontends()" << endl;
+        
         Session session("SQLite", this->dbFile);
         std::vector<Frontend> result;
         Frontend frontend;
@@ -234,4 +236,32 @@ public:
 
         return result;
     }
+
+    void updateFrontendSettings(string settingsData) {
+        if (DEBUG) cout << "dbSqlite::updateSettings" << endl;
+        
+        Session session("SQLite", this->dbFile);
+        json::JSON jObj = json::JSON::Load(settingsData);
+
+        Frontend frontend;
+        frontend.frontendId = jObj["frontendId"].ToString();
+        frontend.plz = jObj["plz"].ToString();
+        frontend.lngCode = jObj["lngCode"].ToString();
+
+        if (frontend.frontendId.size() > 0 && frontend.plz.size() > 0 && frontend.lngCode.size() > 0) {
+            Statement insert(session);
+            insert << "INSERT OR IGNORE INTO settings_frontend(frontendId, plz, lngCode) VALUES(?, ?, ?);",
+                use(frontend.frontendId),
+                use(frontend.plz),
+                use(frontend.lngCode);
+            insert.execute();
+
+            Statement update(session);
+            update << "UPDATE settings_frontend SET plz=?, lngCode=? WHERE frontendId = ?;",
+                use(frontend.plz),
+                use(frontend.lngCode),
+                use(frontend.frontendId);
+            update.execute();
+        }
+    }
 };
diff --git a/openweathermap.h b/openweathermap.h
index d33fb0d..1277605 100644
--- a/openweathermap.h
+++ b/openweathermap.h
@@ -20,7 +20,7 @@
 #include "json.h"
 #include "structs.h"
 
-#define DEBUG true
+#define DEBUG false
 
 class openweathermap {
 private:
@@ -39,8 +39,7 @@ public:
 
     std::string str_tolower(std::string s) {
         if (DEBUG) std::cout << "openweathermap::str_tolower()" << std::endl;
-        std::transform(s.begin(), s.end(), s.begin(),
-            [](unsigned char c) { return std::tolower(c); }
+        std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) { return std::tolower(c); }
         );
         return s;
     }
@@ -121,7 +120,6 @@ public:
     }
 
     std::string getResponse(std::string url) {
-        if (DEBUG) std::cout << "openweathermap::getResponse()" << std::endl;
         try {
             // prepare session
             Poco::URI uri(url);
diff --git a/structs.h b/structs.h
index 63e03d4..6a30bdb 100644
--- a/structs.h
+++ b/structs.h
@@ -1,28 +1,30 @@
 #pragma once
 #include <iostream>
 
+using std::string;
+
 struct Settings {
-    std::string owm_appid;
-    std::string owm_plz;
-    std::string owm_lngCode;
-    std::string influx_host;
+    string owm_appid;
+    string owm_plz;
+    string owm_lngCode;
+    string influx_host;
     int influx_port;
-    std::string influx_db;
-    std::string influx_user;
-    std::string influx_pass;
-    std::string mqtt_host;
-    std::string mqtt_user;
-    std::string mqtt_pass;
-    std::string mqtt_topic_frontend;
-    std::string mqtt_topic_backend;
+    string influx_db;
+    string influx_user;
+    string influx_pass;
+    string mqtt_host;
+    string mqtt_user;
+    string mqtt_pass;
+    string mqtt_topic_frontend;
+    string mqtt_topic_backend;
     int mqtt_qos;
-    std::string mqtt_timeout;
+    string mqtt_timeout;
     int mqtt_port;
 };
 
 struct WeatherData {
-    std::string plz;
-    std::string lngCode;
+    string plz;
+    string lngCode;
     int sunrise;
     int sunset;
     int visibility;
@@ -40,19 +42,19 @@ struct WeatherData {
     double snow1h;
     double snow3h;
     int icon1Id;
-    std::string icon1;
+    string icon1;
     int icon2Id;
-    std::string icon2;
-    std::string from;
+    string icon2;
+    string from;
 };
 
 struct Frontend {
-    std::string frontendId;
-    std::string plz;
-    std::string lngCode;
+    string frontendId;
+    string plz;
+    string lngCode;
 };
 
 struct Region {
-    std::string plz;
-    std::string lngCode;
+    string plz;
+    string lngCode;
 };
\ No newline at end of file
diff --git a/weatherstation.db b/weatherstation.db
index ab058e1b6b1f02359d4a1a033614290c92cc6b8e..add15d1515561f52593a6357af54a7a56fc90fe9 100644
GIT binary patch
delta 145
zcmZp8pxE$0ae_3X(L@<%RwD*I>yH~#7V&ePV&MPE|DOL8|LM(w0=xKGRG57kC!d#B
z5Mp6v=4Ui!29ZWg3=9mcESnTK71&<!-{;@NKmB3@tLA0}fhvABZ59?^aY2xl$v6C!
v*jQLtczJo70@?x?+X9%{0+`zZSlR+u+XC3y0@$|&aA?RgGECRZ=eQ04mbE6_

delta 136
zcmZp8pxE$0ae_3X)<hX+RxJiSjm(WHi}*QCGw^@qf6sq<v!KFWeimhBU(U(r<P`*2
znfV!wnL(rx69WSStKlXEP6gIY{IB@$Zx$3-!q2A7$l@z52vR%whQAV<p{2Qrsc}<4
lTL5EQ08?84b6WsQTL5cY09#uC`?dfM4S7cK>6-Z**8%;^B&q-a

-- 
GitLab