diff --git a/MqttClient.h b/MqttClient.h index 070831623919fb59dcafdbc2eca93b701a62346e..be130a313ff828d45f1f261a9c766f1960aace71 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 b1f07eeec7c83cdf5c79a6f87c840ef82853dcc6..216cfa6a4de4dd12a00caefae4f69f55c7779770 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 bd8672c953ea5c434a50e9e77f76eb7ab8250d83..72c635d69e00efa8f53906f8fc01b846e6e9edb4 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 ff71ca56ebcca05d3116cbf419c98551ee9877cf..fd921c0b4f15d61d7da493cfc93e096f98c2cc85 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 d33fb0d738ef5fce58088dce0bfc86408ebd1748..1277605554b4b0ad533a95e2335d787ebe59d36b 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 63e03d4ddbd8245223986305a1e02649dbb5f4af..6a30bdb9c4792a785b6a9f93703a16e32b208a9b 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 Binary files a/weatherstation.db and b/weatherstation.db differ