diff --git a/.gitignore b/.gitignore index 925e5bfd501c0a9f3b61ffe1c41f46e4fd04fbae..3ea3afbc541e350dc8225c67a1220a2786adbdab 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ /.vs /Debug /x64/Release +/Release diff --git a/MqttClient.h b/MqttClient.h new file mode 100644 index 0000000000000000000000000000000000000000..423413a0b6fb8971cfe1720692ebe8b7a3231d2a --- /dev/null +++ b/MqttClient.h @@ -0,0 +1,60 @@ +#pragma once + +#include <mosquittopp.h> +#include <cstring> +#include <cstdio> + +#define MAX_PAYLOAD 50 +#define DEFAULT_KEEP_ALIVE 60 +#define PUBLISH_TOPIC "EXAMPLE_TOPIC" + +class MqttClient : public mosqpp::mosquittopp { +public: + MqttClient(const char* id, const char* host, int port) : mosquittopp(id) { + int keepalive = DEFAULT_KEEP_ALIVE; + connect(host, port, keepalive); + } + + ~MqttClient() {} + + void on_connect(int rc) { + if (!rc) std::cout << "Connected - code " << rc << std::endl; + } + + void on_subscribe(int mid, int qos_count, const int* granted_qos){ + std::cout << "Subscription succeeded." << std::endl; + } + + void on_message(const struct mosquitto_message* message) { + int payload_size = MAX_PAYLOAD + 1; + char buf[payload_size]; + + if (!strcmp(message->topic, PUBLISH_TOPIC)) { + memset(buf, 0, payload_size * sizeof(char)); + + /* Copy N-1 bytes to ensure always 0 terminated. */ + memcpy(buf, message->payload, MAX_PAYLOAD * sizeof(char)); + + std::cout << buf << std::endl; + + // Examples of messages for M2M communications... + if (!strcmp(buf, "STATUS")) { + snprintf(buf, payload_size, "This is a Status Message..."); + publish(NULL, PUBLISH_TOPIC, strlen(buf), buf); + std::cout << "Status Request Recieved." << std::endl; + } + + if (!strcmp(buf, "ON")) { + snprintf(buf, payload_size, "Turning on..."); + publish(NULL, PUBLISH_TOPIC, strlen(buf), buf); + std::cout << "Request to turn on." << std::endl; + } + + if (!strcmp(buf, "OFF")) { + snprintf(buf, payload_size, "Turning off..."); + publish(NULL, PUBLISH_TOPIC, strlen(buf), buf); + std::cout << "Request to turn off." << std::endl; + } + } + } +} \ No newline at end of file diff --git a/backend.cpp b/backend.cpp index fbb0aa904f61ec1e9ea37ffba4e000bffcd80211..310bb339e2f2b4d86e10af20da6ee22082b7cc67 100644 --- a/backend.cpp +++ b/backend.cpp @@ -1,13 +1,17 @@ #include <iostream> #include <thread> +#include <vector> +#include "compatibility.h" #include "openweathermap.h" #include "dbSqlite.h" -#include <vector> +#include "MqttClient.h" using namespace std; +// Database object dbSqlite* db; +// Thread for openweathermap:getWeather void schedulerWeather(int time) { std::cout << "Wetterstation::schedulerWeather" << std::endl; while (1) { @@ -18,6 +22,7 @@ void schedulerWeather(int time) { } } +// Thread for openweathermap:getForecast void schedulerForecast(int time) { std::cout << "Wetterstation::schedulerForecast" << std::endl; while (1) { @@ -28,29 +33,27 @@ void schedulerForecast(int time) { } } +// Main method int main() { std::cout << "Wetterstation::main" << std::endl; - WSADATA wsaData; + // Sockets aktivieren + WSADATA wsaData; int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); if (iResult != 0) { printf("WSAStartup failed: %d\n", iResult); return 1; } - db = new dbSqlite(); std::thread thrWeather{ schedulerWeather, 60000 }; - Sleep(50); + csleep(50); std::thread thrForecast{ schedulerForecast, 900000 }; + csleep(100); - std::vector<WeatherConditions> cond = db->getConditions(); + //mqttStart(); - /*for (int i = 0; i < cond.size(); i++) { - cout << cond[i].condition_id << endl; - cout << cond[i].description << endl; - cout << "------------------------" << endl; - }*/ + std::vector<WeatherConditions> cond = db->getConditions(); while (1) { Sleep(1000); diff --git a/backend.vcxproj b/backend.vcxproj index afb55363e343867d9178f2fcaf6de3257951f2a8..f54a234d2d1933724943a44164b2a78ed495fa50 100644 --- a/backend.vcxproj +++ b/backend.vcxproj @@ -148,12 +148,13 @@ </ItemDefinitionGroup> <ItemGroup> <ClCompile Include="backend.cpp" /> + <ClCompile Include="MqttClient.h" /> </ItemGroup> <ItemGroup> <None Include="README.md" /> - <None Include="weatherstation.db" /> </ItemGroup> <ItemGroup> + <ClInclude Include="compatibility.h" /> <ClInclude Include="dbSqlite.h" /> <ClInclude Include="influxdb.h" /> <ClInclude Include="json.h" /> diff --git a/backend.vcxproj.filters b/backend.vcxproj.filters index 4436b5fdb5a329d4bbf7ea3ca72b039a7819bae8..659c0a4f5e7b3173d6b4f20b93e23f9bc398fe9c 100644 --- a/backend.vcxproj.filters +++ b/backend.vcxproj.filters @@ -18,12 +18,14 @@ <ClCompile Include="backend.cpp"> <Filter>Quelldateien</Filter> </ClCompile> + <ClCompile Include="MqttClient.h"> + <Filter>Quelldateien</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <None Include="README.md"> <Filter>Quelldateien</Filter> </None> - <None Include="weatherstation.db" /> </ItemGroup> <ItemGroup> <ClInclude Include="dbSqlite.h"> @@ -38,5 +40,8 @@ <ClInclude Include="openweathermap.h"> <Filter>Quelldateien</Filter> </ClInclude> + <ClInclude Include="compatibility.h"> + <Filter>Quelldateien</Filter> + </ClInclude> </ItemGroup> </Project> \ No newline at end of file diff --git a/compatibility.h b/compatibility.h new file mode 100644 index 0000000000000000000000000000000000000000..2b9134a42bbe5398756e3e87c8437c3973652c17 --- /dev/null +++ b/compatibility.h @@ -0,0 +1,7 @@ +void csleep(int time) { +#if defined(WIN32) || defined(WIN64) + Sleep(time); +#else + usleep((long) time); +#endif +} \ No newline at end of file diff --git a/dbSqlite.h b/dbSqlite.h index 696fefa5f5f1db8d98af2079e064dd3435357692..19d439c94d5e3ce90240b5b6fa866906b97dc96a 100644 --- a/dbSqlite.h +++ b/dbSqlite.h @@ -26,6 +26,13 @@ struct Settings { 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; + int mqtt_qos; + std::string mqtt_timeout; }; class dbSqlite { @@ -45,8 +52,7 @@ public: }; Settings getSettings() { - std::cout << "dbSqlite::getSettings()" << std::endl; - std::cout << "owm_plz: " << this->settings.owm_plz << std::endl; + std::cout << "dbSqlite::getSettings()" << std::endl; return this->settings; } @@ -68,6 +74,13 @@ public: into(this->settings.influx_db), into(this->settings.influx_user), into(this->settings.influx_pass), + into(this->settings.mqtt_host), + into(this->settings.mqtt_user), + into(this->settings.mqtt_pass), + into(this->settings.mqtt_topic_frontend), + into(this->settings.mqtt_topic_backend), + into(this->settings.mqtt_qos), + into(this->settings.mqtt_timeout), range(0, 1); // iterate over result set one row at a time select.execute(); } @@ -75,6 +88,7 @@ public: std::vector<WeatherConditions> queryConditions() { std::cout << "dbSqlite::queryConditions()" << std::endl; Session session("SQLite", this->dbFile); + std::vector<WeatherConditions> result; WeatherConditions wc; Statement select(session); @@ -86,9 +100,9 @@ public: while (!select.done()) { select.execute(); - weatherConditions.push_back(wc); + result.push_back(wc); } - return weatherConditions; + return result; } -}; \ No newline at end of file +}; diff --git a/influxdb.h b/influxdb.h index 9c0c57d2a901ce65ad785df62bacc98caf484802..380f744da5c2f2fbe817ace38e9f933e02767b89 100644 --- a/influxdb.h +++ b/influxdb.h @@ -6,6 +6,7 @@ Please see LICENSE file or visit https://github.com/orca-zhang/influxdb-cpp for details. */ +#pragma once #include <sstream> #include <cstring> #include <cstdio> diff --git a/openweathermap.h b/openweathermap.h index 6c29de010c99186343d7edc69b9693cc38d42058..79202679ebf828e643face02d7b263fcb891de1e 100644 --- a/openweathermap.h +++ b/openweathermap.h @@ -75,7 +75,7 @@ public: } void setSWeather(json::JSON jObj, std::string plz, std::string lngCode) { - std::cout << "openweathermap::setSWeather()" << std::endl; + std::cout << "openweathermap::setSWeather(" << plz << ")" << std::endl; this->sWeather.plz = plz; this->sWeather.lngCode = lngCode; this->sWeather.visibility = jObj["visibility"].ToInt(); @@ -98,7 +98,7 @@ public: } void setSForecast(json::JSON jObj, std::string plz, std::string lngCode) { - std::cout << "openweathermap::setSForecast()" << std::endl; + std::cout << "openweathermap::setSForecast(" << plz << ")" << std::endl; for (int i = 0; i < jObj["cnt"].ToInt(); i++) { weatherData item; item.plz = plz; @@ -157,14 +157,14 @@ public: } void getWeather(std::string plz, std::string lngCode) { - std::cout << "openweathermap::getWeather" << std::endl; + std::cout << "openweathermap::getWeather(" << plz << ", " << lngCode << ")" << std::endl; lngCode = str_tolower(lngCode); this->setSWeather(json::JSON::Load(this->getResponse("http://api.openweathermap.org/data/2.5/weather?zip=" + plz + "," + lngCode + "&appid=" + db->getSettings().owm_appid + "&mode=json&units=metric&lang=de")), plz, lngCode); std::cout << "owm_appid: " << db->getSettings().owm_appid << std::endl; influxdb_cpp::server_info si(db->getSettings().influx_host, db->getSettings().influx_port, db->getSettings().influx_db, db->getSettings().influx_user, db->getSettings().influx_pass); - std::cout << "Influx Result: " << influxdb_cpp::builder() + influxdb_cpp::builder() .meas("Weather") .tag("plz", this->sWeather.plz) .tag("lngCode", this->sWeather.lngCode) @@ -189,7 +189,7 @@ public: } void getForecast(std::string plz, std::string lngCode) { - std::cout << "openweathermap::getForecast" << std::endl; + std::cout << "openweathermap::getForecast(" << plz << ", " << lngCode << ")" << std::endl; lngCode = str_tolower(lngCode); this->setSForecast(json::JSON::Load(this->getResponse("http://api.openweathermap.org/data/2.5/forecase?zip=" + plz + "," + lngCode + "&appid=" + db->getSettings().owm_appid + "&mode=json&units=metric&lang=de")), plz, lngCode); } diff --git a/weatherstation.db b/weatherstation.db index ab4b5ba99922863f1b38c96767d0377c2af23997..a8ae43969964530748227b2ae3656c445b4e2a2a 100644 Binary files a/weatherstation.db and b/weatherstation.db differ