From 4f5998cf5fecdab5c560546075e2af67be9dd169 Mon Sep 17 00:00:00 2001 From: JDierkse Date: Tue, 16 Jun 2020 09:43:20 +0200 Subject: [PATCH] Initial commit --- .gitignore | 15 +++ .gitmodules | 3 + Application/Makefile | 1 + Application/ToonBridge.cc | 85 +++++++++++++++++ Libraries/Http | 1 + Libraries/Logging | 1 + Libraries/MQTT | 1 + Libraries/SimpleSignal | 1 + Libraries/Utilities | 1 + Libraries/clipp | 1 + Libraries/inih | 1 + Libraries/json | 1 + Makefile | 1 + Makefile.conf | 31 ++++++ Makefile.target | 13 +++ Makefiles | 1 + Toon/Bridge.cpp | 81 ++++++++++++++++ Toon/Bridge.h | 45 +++++++++ Toon/MQTTSettings.h | 21 ++++ Toon/Makefile | 1 + Toon/MessageHandler.cpp | 169 +++++++++++++++++++++++++++++++++ Toon/MessageHandler.h | 46 +++++++++ Toon/ToonSettings.h | 22 +++++ Toon/WebSocketSubscription.cpp | 102 ++++++++++++++++++++ Toon/WebSocketSubscription.h | 36 +++++++ ToonBridge.ini | 15 +++ 26 files changed, 696 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 120000 Application/Makefile create mode 100644 Application/ToonBridge.cc create mode 120000 Libraries/Http create mode 120000 Libraries/Logging create mode 120000 Libraries/MQTT create mode 120000 Libraries/SimpleSignal create mode 120000 Libraries/Utilities create mode 120000 Libraries/clipp create mode 120000 Libraries/inih create mode 120000 Libraries/json create mode 120000 Makefile create mode 100644 Makefile.conf create mode 100644 Makefile.target create mode 160000 Makefiles create mode 100644 Toon/Bridge.cpp create mode 100644 Toon/Bridge.h create mode 100644 Toon/MQTTSettings.h create mode 120000 Toon/Makefile create mode 100644 Toon/MessageHandler.cpp create mode 100644 Toon/MessageHandler.h create mode 100644 Toon/ToonSettings.h create mode 100644 Toon/WebSocketSubscription.cpp create mode 100644 Toon/WebSocketSubscription.h create mode 100644 ToonBridge.ini diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c0bddc8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +*.o.* +*.d.* +*.a.* +.*.swp +.AppleDouble +.debug +.gdbinit* +gdb* +core-* +*-core +core.* +*.core +ToonBridge* +!ToonBridge.cc +!ToonBridge.ini diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..876e403 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "Makefiles"] + path = Makefiles + url = https://gogs.dierkse.nl/JDierkse/Makefiles diff --git a/Application/Makefile b/Application/Makefile new file mode 120000 index 0000000..d0b0e8e --- /dev/null +++ b/Application/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/Application/ToonBridge.cc b/Application/ToonBridge.cc new file mode 100644 index 0000000..4f12562 --- /dev/null +++ b/Application/ToonBridge.cc @@ -0,0 +1,85 @@ +#include "Toon/Bridge.h" +#include +#include +#include +#include +#include +#include + + +int main(int argc, char** argv) +{ + try + { + Logging::OpenLog(); + Logging::SetLogMask(Logging::Severity::Debug); + + INIReader iniReader("ToonBridge.ini"); + if (iniReader.ParseError() != 0) + throw std::runtime_error("Can't read ToonBridge.ini."); + + Logging::Log(Logging::Severity::Info, "Starting ToonBridge"); + + int port = iniReader.GetInteger("ToonBridge", "Port", 0); + if (port == 0) + throw std::runtime_error("Port directive missing in ini file."); + + ToonBridge::Toon::ToonSettings toonSettings; + toonSettings.agreementId = iniReader.Get("Toon", "AgreementID", ""); + if (toonSettings.agreementId.empty()) + throw std::runtime_error("Toon AgreementID directive missing in ini file."); + + toonSettings.accessToken = iniReader.Get("Toon", "AccessToken", ""); + if (toonSettings.accessToken.empty()) + throw std::runtime_error("Toon AccessToken directive missing in ini file."); + + toonSettings.displayCommonName = iniReader.Get("Toon", "DisplayCommonName", ""); + if (toonSettings.displayCommonName.empty()) + throw std::runtime_error("Toon DisplayCommonName directive missing in ini file."); + + toonSettings.applicationId = iniReader.Get("Toon", "ApplicationID", ""); + if (toonSettings.applicationId.empty()) + throw std::runtime_error("Toon ApplicationID directive missing in ini file."); + + toonSettings.callbackUrl = iniReader.Get("Toon", "CallbackURL", ""); + if (toonSettings.callbackUrl.empty()) + throw std::runtime_error("Toon CallbackURL directive missing in ini file."); + + ToonBridge::Toon::MQTTSettings mqttSettings; + mqttSettings.hostname = iniReader.Get("MQTT", "Hostname", ""); + if (mqttSettings.hostname.empty()) + throw std::runtime_error("MQTT Hostname directive missing in ini file."); + + mqttSettings.port = iniReader.GetInteger("MQTT", "Port", 0); + if (mqttSettings.port == 0) + throw std::runtime_error("MQTT Port directive missing in ini file."); + + mqttSettings.topic = iniReader.Get("MQTT", "Topic", ""); + if (mqttSettings.topic.empty()) + throw std::runtime_error("MQTT Topic directive missing in ini file."); + + ToonBridge::Toon::Bridge bridge(port, toonSettings, mqttSettings); + + Logging::Log(Logging::Severity::Info, "Startup Complete"); + bridge.Wait(); + + Logging::Log(Logging::Severity::Info, "Stopping ToonBridge..."); + Logging::CloseLog(); + } + catch (const std::exception& e) + { + std::cerr << "Exception caught" << std::endl; + + std::stringstream ss; + ss << "Type : " << typeid(e).name() << std::endl; + ss << "ERROR: " << e.what() << std::endl; + + Logging::Log(Logging::Severity::Error, ss.str()); + + Logging::CloseLog(); + + return -1; + } + + return 0; +} diff --git a/Libraries/Http b/Libraries/Http new file mode 120000 index 0000000..5fe3319 --- /dev/null +++ b/Libraries/Http @@ -0,0 +1 @@ +../../Libraries/Http \ No newline at end of file diff --git a/Libraries/Logging b/Libraries/Logging new file mode 120000 index 0000000..2b4f659 --- /dev/null +++ b/Libraries/Logging @@ -0,0 +1 @@ +../../Libraries/Logging \ No newline at end of file diff --git a/Libraries/MQTT b/Libraries/MQTT new file mode 120000 index 0000000..8d68416 --- /dev/null +++ b/Libraries/MQTT @@ -0,0 +1 @@ +../../Libraries/MQTT \ No newline at end of file diff --git a/Libraries/SimpleSignal b/Libraries/SimpleSignal new file mode 120000 index 0000000..6f49fe8 --- /dev/null +++ b/Libraries/SimpleSignal @@ -0,0 +1 @@ +../../Libraries/SimpleSignal \ No newline at end of file diff --git a/Libraries/Utilities b/Libraries/Utilities new file mode 120000 index 0000000..88f16bc --- /dev/null +++ b/Libraries/Utilities @@ -0,0 +1 @@ +../../Libraries/Utilities \ No newline at end of file diff --git a/Libraries/clipp b/Libraries/clipp new file mode 120000 index 0000000..ffe3902 --- /dev/null +++ b/Libraries/clipp @@ -0,0 +1 @@ +../../Libraries/clipp \ No newline at end of file diff --git a/Libraries/inih b/Libraries/inih new file mode 120000 index 0000000..f48979f --- /dev/null +++ b/Libraries/inih @@ -0,0 +1 @@ +../../Libraries/inih \ No newline at end of file diff --git a/Libraries/json b/Libraries/json new file mode 120000 index 0000000..e497e2b --- /dev/null +++ b/Libraries/json @@ -0,0 +1 @@ +../../Libraries/json \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 120000 index 0000000..6aa5187 --- /dev/null +++ b/Makefile @@ -0,0 +1 @@ +Makefiles/Makefile \ No newline at end of file diff --git a/Makefile.conf b/Makefile.conf new file mode 100644 index 0000000..2a30c16 --- /dev/null +++ b/Makefile.conf @@ -0,0 +1,31 @@ +# +# Makefile.conf +# + +LFLAGS += -lHttp -lcrypto -lcurl -lssl -lz +LFLAGS += -L$(ROOTPATH)/Libraries/Http/lib/$(ARCH) +CFLAGS += -I$(ROOTPATH)/Libraries/Http/include + +LFLAGS += -lLogging +LFLAGS += -L$(ROOTPATH)/Libraries/Logging/lib/$(ARCH) +CFLAGS += -I$(ROOTPATH)/Libraries/Logging/include + +LFLAGS += -lUtilities +LFLAGS += -L$(ROOTPATH)/Libraries/Utilities/lib/$(ARCH) +CFLAGS += -I$(ROOTPATH)/Libraries/Utilities/include + +LFLAGS += -lMQTT -lmosquitto +LFLAGS += -L$(ROOTPATH)/Libraries/MQTT/lib/$(ARCH) +CFLAGS += -I$(ROOTPATH)/Libraries/MQTT/include + +CFLAGS += -I$(ROOTPATH)/Libraries/clipp/include +CFLAGS += -I$(ROOTPATH)/Libraries/inih +CFLAGS += -I$(ROOTPATH)/Libraries/json/include/nlohmann -I$(ROOTPATH)/Libraries/json/include + +CFLAGS += -I$(ROOTPATH)/Libraries/SimpleSignal + +LFLAGS += -pthread + +CFLAGS += -I$(ROOTPATH) -I$(ROOTPATH)/Libraries + +DEBUGDIR := .debug diff --git a/Makefile.target b/Makefile.target new file mode 100644 index 0000000..a00dad6 --- /dev/null +++ b/Makefile.target @@ -0,0 +1,13 @@ +# +# Makefile.target +# + +ToonBridge.$(ARCH): $(OBJECTS) Application/ToonBridge.o.$(ARCH) + $(call build_target_arch,$@,$^) + +ToonBridge: + $(call build_target,$@) + +.DEFAULT_GOAL := ToonBridge + +TARGETS += ToonBridge diff --git a/Makefiles b/Makefiles new file mode 160000 index 0000000..cd9ef1a --- /dev/null +++ b/Makefiles @@ -0,0 +1 @@ +Subproject commit cd9ef1a1b0f7b88f36b0c51b4209d1859aca83aa diff --git a/Toon/Bridge.cpp b/Toon/Bridge.cpp new file mode 100644 index 0000000..d52e7f1 --- /dev/null +++ b/Toon/Bridge.cpp @@ -0,0 +1,81 @@ +#include "Bridge.h" +#include +#include +#include + + +namespace ToonBridge { +namespace Toon { + +Bridge::Bridge(int port, const ToonSettings& toonSettings, const MQTTSettings& mqttSettings) : + m_mqttClient(mqttSettings.hostname, mqttSettings.port), + m_messageHandler(m_mqttClient), + m_port(port), + m_toonSettings(toonSettings), + m_mqttSettings(mqttSettings) +{ + Start(); +} + +Bridge::~Bridge() +{ + MQTT::MQTTMessage message; + message.topic = m_mqttSettings.topic; + message.payload = "ToonBridge Stop"; + m_mqttClient.Send(message); +} + +void Bridge::Wait() +{ + m_pHttpServer->Wait(); +} + +void Bridge::Start() +{ + Http::HttpServer::CallbackMethod httpCallback = std::bind(&Bridge::HttpCallback, this, std::placeholders::_1, std::placeholders::_2); + + m_pHttpServer.reset(new Http::HttpServer(m_port, httpCallback)); + + m_pWebSocketSubscription.reset(new WebSocketSubscription(m_toonSettings)); + m_messageHandler.Connect(std::bind(&Bridge::TimeToLiveCallback, this, m_pWebSocketSubscription.get(), std::placeholders::_1)); + + MQTT::MQTTMessage message; + message.topic = m_mqttSettings.topic; + message.payload = "ToonBridge Start"; + m_mqttClient.Send(message); +} + +Http::HttpServer::HttpReply Bridge::HttpCallback(const std::string& uri, const std::vector& postData) +{ + Http::HttpServer::HttpReply reply; + reply.status = Http::HttpServer::HttpReply::Status::Ok; + + try + { + if (postData.size() > 0) + { + for (auto& data : postData) + { + if (data.name == "data") + m_messageHandler.HandleMessage(data.value); + } + } + } + catch (const std::exception& e) + { + std::stringstream ss; + ss << "Bridge::HttpCallback() - Error: " << e.what() << std::endl; + Logging::Log(Logging::Severity::Error, ss.str()); + } + + return reply; +} + +void Bridge::TimeToLiveCallback(ToonBridge::Toon::WebSocketSubscription* pSubscription, int timeToLive) +{ + if (timeToLive < 20) + pSubscription->Reconnect(); +} + +} // namespace Toon +} // namespace ToonBridge diff --git a/Toon/Bridge.h b/Toon/Bridge.h new file mode 100644 index 0000000..cc65c45 --- /dev/null +++ b/Toon/Bridge.h @@ -0,0 +1,45 @@ +#ifndef TOON_BRIDGE_H +#define TOON_BRIDGE_H + +#include "MessageHandler.h" +#include "MQTTSettings.h" +#include "ToonSettings.h" +#include "WebSocketSubscription.h" +#include +#include +#include +#include + + +namespace ToonBridge { +namespace Toon { + +class Bridge +{ +public: + Bridge(int port, const ToonSettings& toonSettings, const MQTTSettings& mqttSettings); + ~Bridge(); + + void Wait(); + +private: + void Start(); + + Http::HttpServer::HttpReply HttpCallback(const std::string& uri, const std::vector& postData); + void TimeToLiveCallback(WebSocketSubscription* pSubscription, int timeToLive); + +private: + std::unique_ptr m_pHttpServer; + MQTT::MQTT m_mqttClient; + MessageHandler m_messageHandler; + + int m_port; + ToonSettings m_toonSettings; + MQTTSettings m_mqttSettings; + std::unique_ptr m_pWebSocketSubscription; +}; + +} // namespace Toon +} // namespace ToonBridge + +#endif // TOON_BRIDGE_H diff --git a/Toon/MQTTSettings.h b/Toon/MQTTSettings.h new file mode 100644 index 0000000..6f250ad --- /dev/null +++ b/Toon/MQTTSettings.h @@ -0,0 +1,21 @@ +#ifndef TOON_MQTTSETTINGS_H +#define TOON_MQTTSETTINGS_H + +#include + + +namespace ToonBridge { +namespace Toon { + + +struct MQTTSettings +{ + std::string hostname; + int port; + std::string topic; +}; + +} // namespace Toon +} // namespace ToonBridge + +#endif // TOON_MQTTSETTINGS_H diff --git a/Toon/Makefile b/Toon/Makefile new file mode 120000 index 0000000..d0b0e8e --- /dev/null +++ b/Toon/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/Toon/MessageHandler.cpp b/Toon/MessageHandler.cpp new file mode 100644 index 0000000..5c0b74d --- /dev/null +++ b/Toon/MessageHandler.cpp @@ -0,0 +1,169 @@ +#include "MessageHandler.h" +#include +#include + + +namespace ToonBridge { +namespace Toon { + +MessageHandler::MessageHandler(MQTT::MQTT& mqtt) : + m_mqtt(mqtt) +{ +} + +MessageHandler::~MessageHandler() +{ +} + +void MessageHandler::HandleMessage(const std::string& message) +{ + nlohmann::json data = nlohmann::json::parse(message); + auto updateDataSet = data["updateDataSet"]; + + if (updateDataSet.contains("powerUsage")) + HandlePowerUsageMessage(updateDataSet["powerUsage"]); + if (updateDataSet.contains("gasUsage")) + HandleGasUsageMessage(updateDataSet["gasUsage"]); + if (updateDataSet.contains("waterUsage")) + HandleWaterUsageMessage(updateDataSet["waterUsage"]); + if (updateDataSet.contains("thermostatInfo")) + HandleThermostatInfoMessage(updateDataSet["thermostatInfo"]); + if (updateDataSet.contains("thermostatStates")) + HandleThermostatStatesMessage(updateDataSet["thermostatStates"]); + + m_signal.emit(data["timeToLiveSeconds"]); +} + +size_t MessageHandler::Connect(TTLCallbackMethod function) +{ + return m_signal.connect(function); +} + +void MessageHandler::Disconnect(size_t connection) +{ + m_signal.disconnect(connection); +} + +void MessageHandler::HandlePowerUsageMessage(const nlohmann::json& data) +{ + MQTT::MQTTMessage message; + message.topic = "ToonBridge/PowerUsage"; + message.payload = data.dump(); + m_mqtt.Send(message); +/* + {"value":419, + "dayCost":1.21, + "valueProduced":0, + "valueSolar":0, + "maxSolar":0, + "avgValue":493.92, + "avgDayValue":11854.00, + "avgProduValue":0, + "meterReading":5528208, + "meterReadingLow":6886191, + "meterReadingProdu":2, + "meterReadingLowProdu":87, + "dayUsage":5268, + "dayLowUsage":2860, + "isSmart":1, + "lowestDayValue":301, + "solarProducedToday":0, + "lastUpdatedFromDisplay":1591801516233} +*/ +} + +void MessageHandler::HandleGasUsageMessage(const nlohmann::json& data) +{ + MQTT::MQTTMessage message; + message.topic = "ToonBridge/GasUsage"; + message.payload = data.dump(); + m_mqtt.Send(message); +/* + {"value":0, + "dayCost":0.32, + "avgValue":26.48, + "meterReading":2613589, + "avgDayValue":635.43, + "dayUsage":389, + "isSmart":1, + "lastUpdatedFromDisplay":1591801517950} +*/ +} + +void MessageHandler::HandleWaterUsageMessage(const nlohmann::json& data) +{ + MQTT::MQTTMessage message; + message.topic = "ToonBridge/WaterUsage"; + message.payload = data.dump(); + m_mqtt.Send(message); +/* + {"installed":0, + "value":0, + "dayCost":0, + "dayUsage":0, + "meterReading":0, + "isSmart":0, + "lastUpdatedFromDisplay":1591801517802} +*/ +} + +void MessageHandler::HandleThermostatInfoMessage(const nlohmann::json& data) +{ + MQTT::MQTTMessage message; + message.topic = "ToonBridge/ThermostatInfo"; + message.payload = data.dump(); + m_mqtt.Send(message); +/* + {"currentSetpoint":1750, + "currentDisplayTemp":2100, + "programState":0, + "activeState":1, + "nextProgram":-1, + "nextState":-1, + "nextTime":0, + "nextSetpoint":0, + "hasBoilerFault":0, + "errorFound":255, + "boilerModuleConnected":1, + "realSetpoint":1750, + "burnerInfo":"0", + "otCommError":"0", + "currentModulationLevel":0, + "haveOTBoiler":1, + "lastUpdatedFromDisplay":1591801515921, + "setByLoadShifting":0} +*/ +} + + +void MessageHandler::HandleThermostatStatesMessage(const nlohmann::json& data) +{ + MQTT::MQTTMessage message; + message.topic = "ToonBridge/ThermostatStates"; + message.payload = data.dump(); + m_mqtt.Send(message); + /* + thermostatStates + {"currentSetpoint":1750, + "currentDisplayTemp":2100, + "programState":0, + "activeState":1, + "nextProgram":-1, + "nextState":-1, + "nextTime":0, + "nextSetpoint":0, + "hasBoilerFault":0, + "errorFound":255, + "boilerModuleConnected":1, + "realSetpoint":1750, + "burnerInfo":"0", + "otCommError":"0", + "currentModulationLevel":0, + "haveOTBoiler":1, + "lastUpdatedFromDisplay":1591801515921, + "setByLoadShifting":0} + */ +} + +} // namespace Toon +} // namespace ToonBridge diff --git a/Toon/MessageHandler.h b/Toon/MessageHandler.h new file mode 100644 index 0000000..0e0cc60 --- /dev/null +++ b/Toon/MessageHandler.h @@ -0,0 +1,46 @@ +#ifndef TOON_MESSAGEHANDLER_H +#define TOON_MESSAGEHANDLER_H + +#include +#include +#include +#include + + +namespace ToonBridge { +namespace Toon { + +class MessageHandler +{ +public: + MessageHandler(MQTT::MQTT& mqtt); + ~MessageHandler(); + + void HandleMessage(const std::string& message); + +public: + typedef std::function TTLCallbackMethod; + +public: + size_t Connect(TTLCallbackMethod function); + void Disconnect(size_t connection); + +private: + typedef Simple::Signal TTLMessage; + +private: + void HandlePowerUsageMessage(const nlohmann::json& data); + void HandleGasUsageMessage(const nlohmann::json& data); + void HandleWaterUsageMessage(const nlohmann::json& data); + void HandleThermostatInfoMessage(const nlohmann::json& data); + void HandleThermostatStatesMessage(const nlohmann::json& data); + +private: + MQTT::MQTT& m_mqtt; + TTLMessage m_signal; +}; + +} // namespace Toon +} // namespace ToonBridge + +#endif // DEVICE_ACTIVITYDEVICE_H diff --git a/Toon/ToonSettings.h b/Toon/ToonSettings.h new file mode 100644 index 0000000..4ff5325 --- /dev/null +++ b/Toon/ToonSettings.h @@ -0,0 +1,22 @@ +#ifndef TOON_TOONSETTINGS_H +#define TOON_TOONSETTINGS_H + +#include + + +namespace ToonBridge { +namespace Toon { + +struct ToonSettings +{ + std::string agreementId; + std::string accessToken; + std::string displayCommonName; + std::string applicationId; + std::string callbackUrl; +}; + +} // namespace Toon +} // namespace ToonBridge + +#endif // TOON_TOONSETTINGS_H diff --git a/Toon/WebSocketSubscription.cpp b/Toon/WebSocketSubscription.cpp new file mode 100644 index 0000000..62e682b --- /dev/null +++ b/Toon/WebSocketSubscription.cpp @@ -0,0 +1,102 @@ +#include "WebSocketSubscription.h" +#include +#include + + +namespace ToonBridge { +namespace Toon { + +WebSocketSubscription::WebSocketSubscription(const ToonSettings& toonSettings) : + m_toonSettings(toonSettings) +{ + OpenWebSocket(); +} + +WebSocketSubscription::~WebSocketSubscription() +{ + CloseWebSocket(); +} + +void WebSocketSubscription::Reconnect() +{ + CloseWebSocket(); + OpenWebSocket(); +} + +void WebSocketSubscription::OpenWebSocket() +{ + std::stringstream url; + url << "https://api.toon.eu/toon/v3/"; + url << m_toonSettings.agreementId; + url << "/webhooks"; + + std::vector subscribedActions; + subscribedActions.push_back("Thermostat"); + subscribedActions.push_back("PowerUsage"); + subscribedActions.push_back("BoilerError"); + + nlohmann::json data; + data["applicationId"] = m_toonSettings.applicationId; + data["callbackUrl"] = m_toonSettings.callbackUrl; + data["subscribedActions"] = subscribedActions; + + Http::HttpRequest request(url.str()); + request.Method(Http::HttpRequest::Method::POST); + request.Headers(RequestHeaders()); + request.Data(data.dump()); + + m_httpClient.Open(request); +} + +void WebSocketSubscription::WebSocketStatus() +{ + std::stringstream url; + url << "https://api.toon.eu/toon/v3/"; + url << m_toonSettings.agreementId; + url << "/webhooks/"; + + Http::HttpRequest request(url.str()); + request.Headers(RequestHeaders()); + + nlohmann::json answer = nlohmann::json::parse(m_httpClient.Open(request)); +} + +void WebSocketSubscription::CloseWebSocket() +{ + std::stringstream url; + url << "https://api.toon.eu/toon/v3/"; + url << m_toonSettings.agreementId; + url << "/webhooks/"; + url << m_toonSettings.applicationId; + + Http::HttpRequest request(url.str()); + request.Method(Http::HttpRequest::Method::DELETE); + request.Headers(RequestHeaders()); + + m_httpClient.Open(request); +} + +std::vector WebSocketSubscription::RequestHeaders() +{ + std::vector headers; + headers.push_back("cache-control: no-cache"); + headers.push_back("accept: application/json"); + headers.push_back("content-type: application/json"); + + std::stringstream header; + header << "authorization: Bearer " << m_toonSettings.accessToken; + headers.push_back(header.str()); + + header.str(""); + header << "X-CommonName: " << m_toonSettings.displayCommonName; + headers.push_back(header.str()); + + header.str(""); + header << "X-Agreement-ID: " << m_toonSettings.agreementId; + headers.push_back(header.str()); + + return headers; +} + +} // namespace Toon +} // namespace ToonBridge diff --git a/Toon/WebSocketSubscription.h b/Toon/WebSocketSubscription.h new file mode 100644 index 0000000..a44072f --- /dev/null +++ b/Toon/WebSocketSubscription.h @@ -0,0 +1,36 @@ +#ifndef TOON_WEBSOCKETSUBSCRIPTION_H +#define TOON_WEBSOCKETSUBSCRIPTION_H + +#include "ToonSettings.h" +#include +#include +#include + + +namespace ToonBridge { +namespace Toon { + +class WebSocketSubscription +{ +public: + WebSocketSubscription(const ToonSettings& toonSettings); + ~WebSocketSubscription(); + + void Reconnect(); + +private: + void OpenWebSocket(); + void WebSocketStatus(); + void CloseWebSocket(); + + std::vector RequestHeaders(); + +private: + Http::HttpClient m_httpClient; + ToonSettings m_toonSettings; +}; + +} // namespace Toon +} // namespace ToonBridge + +#endif // TOON_WEBSOCKETSUBSCRIPTION_H diff --git a/ToonBridge.ini b/ToonBridge.ini new file mode 100644 index 0000000..05eb496 --- /dev/null +++ b/ToonBridge.ini @@ -0,0 +1,15 @@ +[ToonBridge] +Port = + +[Toon] +AgreementID = +AccessToken = +DisplayCommonName = +ApplicationID = +CallbackURL = + +[MQTT] +Hostname = +Port = +Topic = +