diff --git a/httpserver.h b/httpserver.h new file mode 100644 index 0000000..531aeea --- /dev/null +++ b/httpserver.h @@ -0,0 +1,14 @@ +#ifndef HTTPSERVER_H +#define HTTPSERVER_H + +#include + +class HttpServer : QObject +{ + Q_OBJECT + public: + int port = 5000; +}; + + +#endif // HTTPSERVER_H diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..5e607db --- /dev/null +++ b/main.cpp @@ -0,0 +1,118 @@ +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pws2mqtt.h" +#include "mqtt.h" +//#include "version.h" + +#include +#include +#include + +#define CLIENT_ID "Client_ID" +#define BROKER_ADDRESS "localhost" +#define MQTT_PORT 1883; + +uint debugLevel = ALL; +QByteArray toFollow; + +//class MqttClient; + +using namespace std; + +//Configuration config; +Pws2mqtt *pws2mqtt; +MqttClient *mqttClient; +QHttpServer *httpServer; + +int main(int argc, char *argv[]) +{ + + debug(DEBUGMACRO, "QcoreApplication", DEBUG); + QCoreApplication a(argc, argv); + + // Enable logging to journald + qputenv("QT_FORCE_STDERR_LOGGING", QByteArray("0")); + + debug(DEBUGMACRO, "declaration of mqttClient", DEBUG); + mqttClient = new MqttClient; + + httpServer = new QHttpServer; + + // declaration of debug level + pws2mqtt = new Pws2mqtt; + + pws2mqtt->listeningHttp(); + + a.exec(); + + mqttClient->qmqttClient->unsubscribe(mqttClient->topic); + mqttClient->qmqttClient->disconnectFromHost(); + debug(DEBUGMACRO, "exiting", DEBUG); + //Closing http server +} + + + +QString addValue(QByteArray value) +{ + bool ok; + QString str; + + value.toFloat(&ok); + if (ok) + { + str = (value); + }else + { + str = ("\"" + value + "\"" ); + } + return str; +} + +void debug(QString debugHeader, QString msg, uint8_t level, QByteArray property) +{ + + if ((debugLevel & level) == 1) + { + qInfo("%s%sINFO: %s%s", debugHeader.toStdString().c_str(), GREEN, msg.toStdString().c_str(), NORMAL); + } + if ((debugLevel & level) == 2) + { + qInfo("%s%s NOTICE: %s%s", debugHeader.toStdString().c_str(), GREEN, msg.toStdString().c_str(), NORMAL); + } + if ((debugLevel & level) == 4) + { + qInfo("%s%s WARNING: %s%s", debugHeader.toStdString().c_str(), ORANGE, msg.toStdString().c_str(), NORMAL); + } + if ((debugLevel & level) == 8) + { + qInfo("%s%s ERROR: %s%s", debugHeader.toStdString().c_str(), RED, msg.toStdString().c_str(), NORMAL); + exit(1); + } + if ((debugLevel & level) == 16) + { + qInfo("%s%s DEBUG: %s%s", debugHeader.toStdString().c_str(), GREEN, msg.toStdString().c_str(), NORMAL); + } + if ((debugLevel & level) == 32) + { + qInfo("%s%s ALERT: %s%s", debugHeader.toStdString().c_str(), RED, msg.toStdString().c_str(), NORMAL); + exit(2); + } + if (toFollow == property and !toFollow.isEmpty()) + { + qInfo("%s%s FOLLOWING %s => %s%s", debugHeader.toStdString().c_str(), GREEN, property.toStdString().c_str(), msg.toStdString().c_str(), NORMAL); + } +} diff --git a/mqtt.cpp b/mqtt.cpp new file mode 100644 index 0000000..d7b5932 --- /dev/null +++ b/mqtt.cpp @@ -0,0 +1,142 @@ +#include "mqtt.h" +#include "pws2mqtt.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +extern MqttClient *mqttClient; + +MqttClient::MqttClient() +{ + // init mqtt connexion to server + debug(DEBUGMACRO, "declaration of qmqttClient", DEBUG); + this->qmqttClient = new QMqttClient(this); + + debug(DEBUGMACRO, "setting hostname of mqtt server", DEBUG); + this->qmqttClient->setHostname(this->server); + debug(DEBUGMACRO, "setting port of mqtt server", DEBUG); + this->qmqttClient->setPort(this->serverPort); //this->serverPort); + + debug(DEBUGMACRO, "Connecting 'messageReceived'", DEBUG); + QObject::connect(this->qmqttClient, &QMqttClient::messageReceived, this, &MqttClient::on_message); + debug (DEBUGMACRO, "Connecting 'disconnect'", DEBUG); + QObject::connect(this->qmqttClient, &QMqttClient::disconnected, this, &MqttClient::on_disconnect); + debug (DEBUGMACRO, "Connecting 'connected'", DEBUG); + QObject::connect(this->qmqttClient, &QMqttClient::connected, this, &MqttClient::on_connect); + debug (DEBUGMACRO, "Connecting 'errorChanged", DEBUG); + QObject::connect(this->qmqttClient, &QMqttClient::errorChanged, this, &MqttClient::on_error); + debug (DEBUGMACRO, "Connecting 'messageSent'", DEBUG); + QObject::connect(this->qmqttClient, &QMqttClient::messageSent, this, &MqttClient::on_messageSent); + debug (DEBUGMACRO, "Connecting 'messageStatusChanged'", DEBUG); + QObject::connect(this->qmqttClient, &QMqttClient::messageStatusChanged, this, &MqttClient::on_messageSentStatusChanged); + debug (DEBUGMACRO, "Connecting 'stateChanged'", DEBUG); + QObject::connect(this->qmqttClient, &QMqttClient::stateChanged, this, &MqttClient::on_stateChanged); + +// qmqttClient->setClientId("pws2mqtt"); +// qmqttClient->setProtocolVersion(QMqttClient::MQTT_3_1_1); + + debug(DEBUGMACRO, "connecting to mqtt server", DEBUG); + this->qmqttClient->connectToHost(); + + //debug(DEBUGMACRO, "error status => " + this->qmqttErrors[this->qmqttClient->error()], DEBUG); +} + +MqttClient::~MqttClient() +{ +} + +qint32 MqttClient::send_message(QString message) +{ + qint32 mid; + + debug(DEBUGMACRO, "send_message() for topic: " + this->topic + " => " + message , DEBUG); + mid = this->qmqttClient->publish(this->topic, message.toUtf8(), this->qos, true); + if (mid == -1) + { + debug(DEBUGMACRO, "Error, can't publish message : " + this->qmqttErrors[this->qmqttClient->error()], ERROR); + } + messagesList.insert(mid, message); + return (mid); +} + +void MqttClient::on_connect() +{ + //this->connected = true; + debug(DEBUGMACRO, "Connected to broker", DEBUG); + this->subscription = this->qmqttClient->subscribe(this->topic, this->qos); + debug (DEBUGMACRO, "Connecting sign 'subscription state Changed'", DEBUG); + QObject::connect(this->subscription, &QMqttSubscription::stateChanged, mqttClient, &MqttClient::updateStatus); +} + +void MqttClient::on_messageSentStatusChanged(qint32 id, QMqtt::MessageStatus s, const QMqttMessageStatusProperties &properties) +{ + (void) properties; + + if ( id == 0) + { + debug(DEBUGMACRO, "message id = " + QString::number(id) + this->messageStatus[static_cast(s)], DEBUG); + } +} + +void MqttClient::on_error(QMqttClient::ClientError error) +{ + debug(DEBUGMACRO, "Error " + qmqttErrors[error], ERROR); +} + +void MqttClient::on_message(const QByteArray &message, const QMqttTopicName &topic) +{ + (void) message; + (void) topic; + debug(DEBUGMACRO, "Message : " + message, DEBUG); +} + +void MqttClient::on_disconnect() +{ + debug(DEBUGMACRO, "Unexpected disconnect", DEBUG); + this->qmqttClient->connectToHost(); +} + + +void MqttClient::on_messageSent(int mid) +{ + debug(DEBUGMACRO, "published(" + QString::number(mid) + ")", DEBUG); + messagesList.remove(mid); +} + +void MqttClient::updateStatus(QMqttSubscription::SubscriptionState state) +{ + switch (state) + { + case QMqttSubscription::Unsubscribed: + debug(DEBUGMACRO, "Unsubscribed", INFO); + break; + case QMqttSubscription::SubscriptionPending: + debug(DEBUGMACRO, "Pending subscription", DEBUG); + break; + case QMqttSubscription::Subscribed: + debug(DEBUGMACRO, "Subscribed", INFO); + break; + case QMqttSubscription::Error: + debug(DEBUGMACRO, "Subscription error" + this->subscription->reason(), ERROR); + break; + case QMqttSubscription::UnsubscriptionPending: + debug(DEBUGMACRO, "Pending Unsubscription", DEBUG); + break; + default: + debug(DEBUGMACRO, "--Unknown--", DEBUG); + break; + } +} + +void MqttClient::on_stateChanged(QMqttClient::ClientState state) +{ + debug(DEBUGMACRO, QLatin1String("State Change : ") + this->clientStateString[state], DEBUG ); +} diff --git a/mqtt.h b/mqtt.h new file mode 100644 index 0000000..f4afff8 --- /dev/null +++ b/mqtt.h @@ -0,0 +1,191 @@ +#ifndef MQTT_H +#define MQTT_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MQTT_TOPIC "pws2mqtt" + + +/*{128, "Unspecified error: The Server does not wish to reveal the reason for the failure, or none of the other Reason Codes apply."}, +{129, "Malformed Packet; Data within the CONNECT packet could not be correctly parsed."}, +{130, "Protocol Error: Data in the CONNECT packet does not conform to this specification."}, +{131, "Implementation specific error: The CONNECT is valid but is not accepted by this Server."}, +{132, "Unsupported Protocol Version: The Server does not support the version of the MQTT protocol requested by the Client."}, +{133, "Client Identifier not valid: The Client Identifier is a valid string but is not allowed by the Server."}, +{134, "Bad User Name or Password: The Server does not accept the User Name or Password specified by the Client."}, +{135, "Not authorized: The Client is not authorized to connect."}, +{136, "Server unavailable: The MQTT Server is not available."}, +{137, "Server busy: The Server is busy. Try again later."}, +{138, "Banned: This Client has been banned by administrative action. Contact the server administrator."}, +{140, "Bad authentication method: The authentication method is not supported or does not match the authentication method currently in use."}, +{144, "Topic Name invalid: The Will Topic Name is not malformed, but is not accepted by this Server."}, +{149, "Packet too large: The CONNECT packet exceeded the maximum permissible size."}, +{151, "Quota exceeded: An implementation or administrative imposed limit has been exceeded."}, +{153, "Payload format invalid: The Will Payload does not match the specified Payload Format Indicator."}, +{154, "Retain not supported: The Server does not support retained messages, and Will Retain was set to 1."}, +{155, "QoS not supported: The Server does not support the QoS set in Will QoS."}, +{156, "Use another server: The Client should temporarily use another server."}, +{157, "Server moved: The Client should permanently use another server."}, +{159, "Connection rate exceeded: The connection rate limit has been exceeded."}, + + +QHash mosq_error +{ + {MOSQ_ERR_ERRNO, "System return error"}, + {MOSQ_ERR_INVAL, "Input parameters were invalid."}, + {MOSQ_ERR_NOMEM, "Out of memory condition occurred."}, + {MOSQ_ERR_PAYLOAD_SIZE, "Payloadlen is too large."}, + {MOSQ_ERR_MALFORMED_UTF8, "The topic is not valid UTF-8."}, + {MOSQ_ERR_NOT_SUPPORTED, "Properties is not NULL and the client is not using MQTT v5"}, + {MOSQ_ERR_NO_CONN, "if the client isn’t connected to a broker."}, + {MOSQ_ERR_DUPLICATE_PROPERTY, "A property is duplicated where it is forbidden."}, + {MOSQ_ERR_PROTOCOL, "Any property is invalid for use with DISCONNECT."}, + {MOSQ_ERR_QOS_NOT_SUPPORTED, "The QoS is greater than that supported by the broker."}, + {MOSQ_ERR_OVERSIZE_PACKET, "The resulting packet would be larger than supported by the broker."}, + {MOSQ_ERR_CONN_LOST, "The connection to the broker was lost."}, + {MOSQ_ERR_PROTOCOL, "There is a protocol error communicating with the broker."}, +}; +*/ + +/*class MqttSub : public QMqttSubscription +{ + Q_OBJECT; + + + + public: + explicit MqttSub(); + ~MqttSub(); + + public slots: + void updateStatus({ , "SubscriptionState state); + +};*/ + +class MqttClient : public QObject +{ + Q_OBJECT + + public: + MqttClient (); + ~MqttClient(); + + QString topic = "pws2mqtt/wh2650a"; + QString host = "127.0.0.1"; + QString friendlyName = "WH2650A"; // friendly name of the device in mqtt + QString macAddress = "0x483fda53cbcb"; // lan mac address as lan identity TODO get from device + QString type = "Meteo"; + int qos = 0; + QString server = "127.0.0.1"; //"127.0.0.1"; + int serverPort = 1883; + int keepAlive = 60; + int protocolVersion = 4; + int retryConnectionDelay = 10; // in seconds + int retrySubscribeDelay = 10; // in seconds + QMqttClient *qmqttClient; + + QHash messagesList; + QMqttSubscription *subscription = nullptr; + QMqttSubscription::SubscriptionState subscriptionState; + QMqttClient::ClientState clientState; + + qint32 send_message(QString message); + + QHash messageStatus = + { + {0, "Unknown : The message status is unknown."}, + {1, "Published : The client received a message for one of its subscriptions. This applies to QoS levels 1 and 2."}, + {2, "Acknowledged A message has been acknowledged. This applies to QoS 1 and states that the message handling has been finished from the client side."}, + {3, "Received : A message has been received. This applies to QoS 2."}, + {4, "Released : A message has been released. This applies to QoS 2. For a publisher the message handling has been finished."}, + {5, "Completed : A message has been completed. This applies to QoS 2 and states that the message handling has been finished from the client side."} + }; + + QHash connectReasonCode = + { + {0, "SubscriptionQoSLevel0 : subscription with QoS level 0 has been created."}, + {1 , "SubscriptionQoSLevel1 0x01 A subscription with QoS level 1 has been created."}, + {2 , "SubscriptionQoSLevel2 0x02 A subscription with QoS level 2 has been created."}, + {16 , "NoMatchingSubscriber 0x10 The message has been accepted by the server, but there are no subscribers to receive this message. A broker may send this reason code instead of Success."}, + {17 , "NoSubscriptionExisted (since Qt 5.15) 0x11 No matching Topic Filter is being used by the Client."}, + {24 , "ContinueAuthentication (since Qt 5.15) 0x18 Continue the authentication with another step."}, + {25 , "ReAuthenticate (since Qt 5.15) 0x19 Initiate a re-authentication."}, + {128 , "UnspecifiedError 0x80 An unspecified error occurred."}, + {129 , "MalformedPacket 0x81 The packet sent to the server is invalid."}, + {130 , "ProtocolError 0x82 A protocol error has occurred. In most cases, this will cause the server to disconnect the client."}, + {131 , "ImplementationSpecificError 0x83 The packet is valid, but the recipient rejects it."}, + {132 , "UnsupportedProtocolVersion 0x84 The requested protocol version is not supported by the server."}, + {133 , "InvalidClientId 0x85 The client ID is invalid."}, + {134 , "InvalidUserNameOrPassword 0x86 The username or password specified is invalid."}, + {135 , "NotAuthorized 0x87 The client is not authorized for the specified action."}, + {136 , "ServerNotAvailable 0x88 The server to connect to is not available."}, + {137 , "ServerBusy 0x89 The server to connect to is not available. The client is asked to try at a later time."}, + {138 , "ClientBanned 0x8A The client has been banned from the server."}, + {139 , "InvalidAuthenticationMethod 0x8C The authentication method specified is invalid."}, + {143 , "InvalidTopicFilter 0x8F The topic filter specified is invalid."}, + {144 , "InvalidTopicName 0x90 The topic name specified is invalid."}, + {145 , "MessageIdInUse 0x91 The message ID used in the previous packet is already in use."}, + {146 , "MessageIdNotFound 0x92 The message ID used in the previous packet has not been found."}, + {149 , "PacketTooLarge 0x95 The packet received is too large. See also QMqttServerConnectionProperties::maximumPacketSize()."}, + {151 , "QuotaExceeded 0x97 An administratively imposed limit has been exceeded."}, + {153 , "InvalidPayloadFormat 0x99 The payload format is invalid. See also QMqttPublishProperties::payloadFormatIndicator()."}, + {154 , "RetainNotSupported 0x9A The server does not support retained messages. See also QMqttServerConnectionProperties::retainAvailable()."}, + {155 , "QoSNotSupported 0x9B The QoS level requested is not supported. See also QMqttServerConnectionProperties::maximumQoS()."}, + {156 , "UseAnotherServer 0x9C The server the client tries to connect to is not available. See also QMqttServerConnectionProperties::serverReference()."}, + {157 , "ServerMoved 0x9D The server the client tries to connect to has moved to a new address. See also QMqttServerConnectionProperties::serverReference()."}, + {158 , "SharedSubscriptionsNotSupported 0x9E Shared subscriptions are not supported. See also QMqttServerConnectionProperties::sharedSubscriptionSupported()."}, + {159 , "ExceededConnectionRate 0x9F The connection rate limit has been exceeded."}, + {161 , "SubscriptionIdsNotSupported 0xA1 Subscription IDs are not supported. See also QMqttServerConnectionProperties::subscriptionIdentifierSupported()."}, + {162 , "WildCardSubscriptionsNotSupported 0xA2 Subscriptions using wildcards are not supported by the server. See also QMqttServerConnectionProperties::wildcardSupported()."}, + }; + + QHash qmqttErrors = + { + {1, "InvalidProtocolVersion : The broker does not accept a connection using the specified protocol version."}, + {2, "IdRejected ; The client ID is malformed. This might be related to its length."}, + {3, "ServerUnavailable :The network connection has been established, but the service is unavailable on the broker side."}, + {4, "QMqttClient::Bad Username Or Password : The data in the username or password is malformed."}, + {5, "NotAuthorized : The client is not authorized to connect."}, + {256, "TransportInvalid : The underlying transport caused an error. For example, the connection might have been interrupted unexpectedly."}, + {257, "ProtocolViolation : The client encountered a protocol violation, and therefore closed the connection."}, + {258, "UnknownError : An unknown error occurred."}, + {259, "Mqtt5SpecificError : The error is related to MQTT protocol level 5. A reason code might provide more details."} + }; + + QHash clientStateString + { + {0, "Disconnected : The client is disconnected from the broker."}, + {1, "Connecting : A connection request has been made, but the broker has not approved the connection yet."}, + {2, "Connected : The client is connected to the broker."} + }; + + QHash subscriptionStateString + { + {0, "Unsubscribed : The topic has been unsubscribed from."}, + {1, "SubscriptionPending : A request for a subscription has been sent, but is has not been confirmed by the broker yet."}, + {2, "Subscribed : The subscription was successful and messages will be received."}, + {3, "UnsubscriptionPending : A request to unsubscribe from a topic has been sent, but it has not been confirmed by the broker yet."}, + {4, "Error : An error occured."} + }; + + public slots: + void on_message(const QByteArray &message, const QMqttTopicName &topic); + void on_connect(); + void on_disconnect(); + void on_error(QMqttClient::ClientError error); + void on_messageSentStatusChanged(qint32 id, QMqtt::MessageStatus s, const QMqttMessageStatusProperties &properties); + void on_messageSent(int mid); + void updateStatus(QMqttSubscription::SubscriptionState state); + void on_stateChanged(QMqttClient::ClientState state); +// void updateMessage(); +}; + + +#endif //MQTT_H diff --git a/pws2mqtt-qt.pro b/pws2mqtt-qt.pro new file mode 100644 index 0000000..e05df73 --- /dev/null +++ b/pws2mqtt-qt.pro @@ -0,0 +1,29 @@ +QT -= gui +QT += network +QT += core +QT += mqtt +QT += httpserver + +CONFIG += c++17 console +CONFIG -= app_bundle + +# You can make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ +main.cpp \ +mqtt.cpp \ +pws2mqtt.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +HEADERS += \ +httpserver.h \ +mqtt.h \ + pws2mqtt.h \ + version.h + diff --git a/pws2mqtt-qt.pro.user b/pws2mqtt-qt.pro.user new file mode 100644 index 0000000..ca68089 --- /dev/null +++ b/pws2mqtt-qt.pro.user @@ -0,0 +1,344 @@ + + + + + + EnvironmentId + {db2284ae-177e-4753-8e1e-1e0e73c52ae1} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + false + true + false + 0 + true + true + 0 + 8 + true + false + 1 + true + true + true + *.md, *.MD, Makefile + false + true + true + + + + ProjectExplorer.Project.PluginSettings + + + true + false + true + true + true + true + + + 0 + true + + true + true + Builtin.DefaultTidyAndClazy + 1 + + + + true + + + + + ProjectExplorer.Project.Target.0 + + Desktop + Desktop + Desktop + {96ba01cf-98b6-46f1-b1a8-6cf5d7804e77} + 0 + 0 + 0 + + 0 + /home/daniel/develop/pws2mqtt-qt/../build-pws2mqtt-qt-Desktop-Debug + /home/daniel/develop/build-pws2mqtt-qt-Desktop-Debug + + + true + QtProjectManager.QMakeBuildStep + false + + + + true + Qt4ProjectManager.MakeStep + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + clean + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + /home/daniel/develop/pws2mqtt-qt/../build-pws2mqtt-qt-Desktop-Release + /home/daniel/develop/build-pws2mqtt-qt-Desktop-Release + + + true + QtProjectManager.QMakeBuildStep + true + + + + true + Qt4ProjectManager.MakeStep + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + clean + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + 0 + + + 0 + /home/daniel/develop/pws2mqtt-qt/../build-pws2mqtt-qt-Desktop-Profile + /home/daniel/develop/build-pws2mqtt-qt-Desktop-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + + + true + Qt4ProjectManager.MakeStep + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + clean + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + 0 + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ProjectExplorer.DefaultDeployConfiguration + + 1 + + true + true + true + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:/home/daniel/develop/pws2mqtt-qt/pws2mqtt-qt.pro + /home/daniel/develop/pws2mqtt-qt/pws2mqtt-qt.pro + false + true + true + false + true + /home/daniel/develop/build-pws2mqtt-qt-Desktop-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop + Qt 6.4.1 (qt6) + Qt 6.4.1 (qt6) + {17b0ba8e-e6fe-4c71-98eb-9b4d3bcc4307} + 0 + 0 + 0 + + 0 + /home/daniel/develop/build-pws2mqtt-qt-Desktop-Debug + /home/daniel/develop/build-pws2mqtt-qt-Desktop-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + + + true + Qt4ProjectManager.MakeStep + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + clean + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + 1 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ProjectExplorer.DefaultDeployConfiguration + + 1 + + true + true + true + + 2 + + ProjectExplorer.CustomExecutableRunConfiguration + + false + true + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/pws2mqtt.cpp b/pws2mqtt.cpp new file mode 100644 index 0000000..76cab7c --- /dev/null +++ b/pws2mqtt.cpp @@ -0,0 +1,124 @@ +#include "pws2mqtt.h" +#include "mqtt.h" +//#include "httpserver.h" +#include +#include +#include +#include +#include +#include +#include + +extern MqttClient *mqttClient; +extern Pws2mqtt *pws2mqtt; +extern QHttpServer *httpServer; + + +Pws2mqtt::Pws2mqtt() +{ + this->init(); +} + +Pws2mqtt::~Pws2mqtt() +{ + +} + +void Pws2mqtt::init() +{ + debug(DEBUGMACRO, "init http server", DEBUG); + httpServer->route("/query", [this](const QHttpServerRequest &request) + { + //QString data; + //QTextStream result(&data); + debug(DEBUGMACRO, "Request body :" + request.body() , DEBUG); + /* debug(DEBUGMACRO, "Request value :" + request.query().toString() , DEBUG); + debug(DEBUGMACRO, "Request value :" + request.url().toString() , DEBUG); + for (auto pair : request.query().queryItems()) + { + if (!data.isEmpty()) + { + result << "\n"; + } + debug(DEBUGMACRO, pair.first + "=" + pair.second, DEBUG); + }*/ + + this->parseData(request.body()); + debug(DEBUGMACRO, "Returning 'success'", DEBUG); + + //mqttClient.send_message(jsonString); + + return QHttpServerResponse("text/plain", "Success\n"); + }); +} + +void Pws2mqtt::listeningHttp() +{ + //QByteArray data; + debug (DEBUGMACRO, "listening http requests", DEBUG); + const auto port = httpServer->listen(QHostAddress::Any, 5000); + if (!port) + { + debug(DEBUGMACRO, "Http Server failed to listen on a port.", ERROR); + //return 0; + } + debug(DEBUGMACRO, "Listening on port " + QString::number(port)); + +} + +void Pws2mqtt::parseData(QByteArray data) +{ + QList dataList; + QString jsonString = "{"; + QString deviceString = "\"device\": {\"ieeeAddress\": \"" + mqttClient->macAddress + "\", \"type\": \"" + mqttClient->type + "\", " + "\"powerSource\": \"Battery\", "; + QList dataSplitted; + QString str; + uint j; + uint listSize; + bool propertyFlag = false; + bool deviceFlag = false; + QString topic; + + debug(DEBUGMACRO, "Parsing Datas", DEBUG); + + dataList = data.split('&'); + listSize = dataList.size() - 1; + for (j=2;jdeviceProperties.contains(str)) + { + if(deviceFlag == false) + { + deviceFlag = true; + }else + { + deviceString.append(", "); + } + deviceString.append("\"" + str + "\": "); + deviceString.append(addValue(dataSplitted[1])); + }else + { + if(propertyFlag == false) + { + propertyFlag = true; + }else + { + jsonString.append(", "); + } + jsonString.append("\"" + str + "\": "); + jsonString.append(addValue(dataSplitted[1])); + //mqttClient.send_message(topic, jsonString); + } + } + jsonString = jsonString +", " + deviceString + "}}"; + mqttClient->send_message(jsonString); + + debug(DEBUGMACRO, "sent => " + jsonString, DEBUG); + debug(DEBUGMACRO, "parseData: Returning", DEBUG); + //return jsonString; +} diff --git a/pws2mqtt.h b/pws2mqtt.h new file mode 100644 index 0000000..16141b6 --- /dev/null +++ b/pws2mqtt.h @@ -0,0 +1,52 @@ +#ifndef PWS2MQTT_H +#define PWS2MQTT_H + +#include +#include +#include +#include +#include + +#define RED "\e[31m" +#define GREEN "\e[32m" +#define BLUE "\e[94m" +#define ORANGE "\e[33m" +#define NORMAL "\e[0m" + +#define DEBUG 16 // => 16 +#define INFO 1 // => 1 +#define NOTICE 2 // => 2 +#define WARNING 4 // => 4 +#define ERROR 8 // => 8 +#define ALERT 32 +#define ALL DEBUG | INFO | NOTICE | WARNING | ERROR | ALERT +#define DEBUGMACRO QString(__FILE__) + ": " + QString::number(__LINE__) + " -> " + QString(Q_FUNC_INFO) + +void debug(QString debugHeader, QString msg, uint8_t level=ALL, QByteArray value=""); +QString addValue(QByteArray value); + +class Pws2mqtt : public QObject +{ + Q_OBJECT + + public: + Pws2mqtt(); + ~Pws2mqtt(); + + QString ProcName = "pws2mqtt"; // name of the proceesus in ps, top, pstree, ...; + FILE * logFh = nullptr; + QString listenHost = "0.0.0.0"; + uint listenPort = 5000; + int sockfd; + int newsockfd; + QList deviceProperties = + { + "ieeeAddress", "type", "dateutc", "softwaretype", "action", "realtime", "freq", "wh65batt", "wh25batt", "runtime" + }; + + void init(); + void listeningHttp(); + void parseData(QByteArray data); +}; + +#endif // PWS2MQTT_H diff --git a/version.h b/version.h new file mode 100644 index 0000000..0ab4d05 --- /dev/null +++ b/version.h @@ -0,0 +1,8 @@ +#ifndef VERSION_H +#define VERSION_H + +#include + +QString version = "0.1"; + +#endif // VERSION_H