Initial commit
This commit is contained in:
+15
@@ -0,0 +1,15 @@
|
|||||||
|
*.o.*
|
||||||
|
*.d.*
|
||||||
|
*.a.*
|
||||||
|
.*.swp
|
||||||
|
.AppleDouble
|
||||||
|
.debug
|
||||||
|
.gdbinit*
|
||||||
|
gdb*
|
||||||
|
core-*
|
||||||
|
*-core
|
||||||
|
core.*
|
||||||
|
*.core
|
||||||
|
ToonBridge*
|
||||||
|
!ToonBridge.cc
|
||||||
|
!ToonBridge.ini
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "Makefiles"]
|
||||||
|
path = Makefiles
|
||||||
|
url = https://gogs.dierkse.nl/JDierkse/Makefiles
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../Makefile
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
#include "Toon/Bridge.h"
|
||||||
|
#include <INIReader.h>
|
||||||
|
#include <Logging.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../../Libraries/Http
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../../Libraries/Logging
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../../Libraries/MQTT
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../../Libraries/SimpleSignal
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../../Libraries/Utilities
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../../Libraries/clipp
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../../Libraries/inih
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../../Libraries/json
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
Submodule
+1
Submodule Makefiles added at cd9ef1a1b0
@@ -0,0 +1,81 @@
|
|||||||
|
#include "Bridge.h"
|
||||||
|
#include <Logging.h>
|
||||||
|
#include <functional>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
|
||||||
|
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<Http::HttpPostData>& 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
|
||||||
@@ -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 <HttpServer.h>
|
||||||
|
#include <MQTT.h>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
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<Http::HttpPostData>& postData);
|
||||||
|
void TimeToLiveCallback(WebSocketSubscription* pSubscription, int timeToLive);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<Http::HttpServer> m_pHttpServer;
|
||||||
|
MQTT::MQTT m_mqttClient;
|
||||||
|
MessageHandler m_messageHandler;
|
||||||
|
|
||||||
|
int m_port;
|
||||||
|
ToonSettings m_toonSettings;
|
||||||
|
MQTTSettings m_mqttSettings;
|
||||||
|
std::unique_ptr<WebSocketSubscription> m_pWebSocketSubscription;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Toon
|
||||||
|
} // namespace ToonBridge
|
||||||
|
|
||||||
|
#endif // TOON_BRIDGE_H
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
#ifndef TOON_MQTTSETTINGS_H
|
||||||
|
#define TOON_MQTTSETTINGS_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
namespace ToonBridge {
|
||||||
|
namespace Toon {
|
||||||
|
|
||||||
|
|
||||||
|
struct MQTTSettings
|
||||||
|
{
|
||||||
|
std::string hostname;
|
||||||
|
int port;
|
||||||
|
std::string topic;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Toon
|
||||||
|
} // namespace ToonBridge
|
||||||
|
|
||||||
|
#endif // TOON_MQTTSETTINGS_H
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../Makefile
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
#include "MessageHandler.h"
|
||||||
|
#include <Logging.h>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
#ifndef TOON_MESSAGEHANDLER_H
|
||||||
|
#define TOON_MESSAGEHANDLER_H
|
||||||
|
|
||||||
|
#include <MQTT.h>
|
||||||
|
#include <SimpleSignal.h>
|
||||||
|
#include <json.hpp>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
namespace ToonBridge {
|
||||||
|
namespace Toon {
|
||||||
|
|
||||||
|
class MessageHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MessageHandler(MQTT::MQTT& mqtt);
|
||||||
|
~MessageHandler();
|
||||||
|
|
||||||
|
void HandleMessage(const std::string& message);
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef std::function<void(int timeToLive)> TTLCallbackMethod;
|
||||||
|
|
||||||
|
public:
|
||||||
|
size_t Connect(TTLCallbackMethod function);
|
||||||
|
void Disconnect(size_t connection);
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef Simple::Signal<void(int timeToLive)> 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
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#ifndef TOON_TOONSETTINGS_H
|
||||||
|
#define TOON_TOONSETTINGS_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
#include "WebSocketSubscription.h"
|
||||||
|
#include <json.hpp>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
|
||||||
|
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<std::string> 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<std::string> WebSocketSubscription::RequestHeaders()
|
||||||
|
{
|
||||||
|
std::vector<std::string> 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
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#ifndef TOON_WEBSOCKETSUBSCRIPTION_H
|
||||||
|
#define TOON_WEBSOCKETSUBSCRIPTION_H
|
||||||
|
|
||||||
|
#include "ToonSettings.h"
|
||||||
|
#include <HttpClient.h>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
namespace ToonBridge {
|
||||||
|
namespace Toon {
|
||||||
|
|
||||||
|
class WebSocketSubscription
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WebSocketSubscription(const ToonSettings& toonSettings);
|
||||||
|
~WebSocketSubscription();
|
||||||
|
|
||||||
|
void Reconnect();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void OpenWebSocket();
|
||||||
|
void WebSocketStatus();
|
||||||
|
void CloseWebSocket();
|
||||||
|
|
||||||
|
std::vector<std::string> RequestHeaders();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Http::HttpClient m_httpClient;
|
||||||
|
ToonSettings m_toonSettings;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Toon
|
||||||
|
} // namespace ToonBridge
|
||||||
|
|
||||||
|
#endif // TOON_WEBSOCKETSUBSCRIPTION_H
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
[ToonBridge]
|
||||||
|
Port =
|
||||||
|
|
||||||
|
[Toon]
|
||||||
|
AgreementID =
|
||||||
|
AccessToken =
|
||||||
|
DisplayCommonName =
|
||||||
|
ApplicationID =
|
||||||
|
CallbackURL =
|
||||||
|
|
||||||
|
[MQTT]
|
||||||
|
Hostname =
|
||||||
|
Port =
|
||||||
|
Topic =
|
||||||
|
|
||||||
Reference in New Issue
Block a user