diff --git a/pws2mqtt-qt.pro b/pws2mqtt-qt.pro index dc261e9..df1b2f3 100644 --- a/pws2mqtt-qt.pro +++ b/pws2mqtt-qt.pro @@ -14,10 +14,10 @@ CONFIG -= app_bundle #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ -main.cpp \ -mqtt.cpp \ -pws2mqtt.cpp \ - utcicalculator.cpp +src/main.cpp \ +src/mqtt.cpp \ +src/pws2mqtt.cpp \ +src/utcicalculator.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin @@ -25,9 +25,9 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target HEADERS += \ -httpserver.h \ -mqtt.h \ -pws2mqtt.h \ - utcicalculator.h \ -version.h +src/httpserver.h \ +src/mqtt.h \ +src/pws2mqtt.h \ +src/utcicalculator.h \ +src/version.h diff --git a/src/pws2mqtt.cpp b/src/pws2mqtt.cpp index a998132..ea66283 100644 --- a/src/pws2mqtt.cpp +++ b/src/pws2mqtt.cpp @@ -3,24 +3,36 @@ //#include "httpserver.h" #include #include -#include +//#include #include #include #include #include +/*#include "qhostaddress.h" +#include "qhttpserverrequest.h" +#include "qhttpserverresponse.h" +#include "qhttpserverrouterrule.h"*/ #include -#include +#include +#include +#include #include +#include +#include #include #include #include #include #include "utcicalculator.h" +#include + +using namespace std; extern MqttClient *mqttClient; extern Pws2mqtt *pws2mqtt; extern QHttpServer *httpServer; UtciCalculator calc; +QTcpServer * tcpServer; QStringList previsionList { @@ -34,15 +46,6 @@ QStringList previsionList "Temps stable" }; -// Callback for curl library -static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) -{ - (void)contents; // Évite les warnings de compilation - (void)userp; - return size * nmemb; // On ne traite pas les données reçues -} - - QMap propertyList; QMap precPropertyList; QMap propertiesValue; @@ -51,9 +54,9 @@ QMap > propertyName {"tempf", {"Température extérieure", "°C"}}, {"humidity", {"Humidité extérieure", "%"}}, {"dewptf", {"Point de rosée", "°C"}}, - {"windchill", {"Température ressentie", "°C"}}, + {"windchill", {"Température ressentie", "°C"}}, {"winddir", {"Direction du vent", "°"}}, - {"windspeedmph", {"Vitesse du vent", " km/h"}}, + {"windspeedmph", {"Vitesse du vent", " km/h"}}, {"windgustmph", {"Rafales", " km/h"}}, {"rainin", {"Pluie", " mm/h"}}, {"dailyrainin", {"Pluie de la journée", " mm"}}, @@ -62,7 +65,7 @@ QMap > propertyName {"solarradiation", {"Énergie solaire", " W/m²"}}, {"indoortempf", {"Température intérieure", "°C"}}, {"indoorhumidity", {"Humidité intérieure", "%"}}, - {"baromin", {"Pression atmosphérique", " hPa"}}, + {"baromin", {"Pression atmosphérique", " hPa"}}, {"lowbatt", {"Alerte batterie faible", ""}}, {"UV", {"Alerte UV", ""}} }; @@ -93,20 +96,46 @@ Pws2mqtt::~Pws2mqtt() { } +// Callback for curl library +static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) +{ + (void)contents; // Évite les warnings de compilation + (void)userp; + return size * nmemb; // On ne traite pas les données reçues +} + +void missingHandler(const QHttpServerRequest &request, QHttpServerResponder &responder) +{ + QString message = QString("404 Not Found: %1 n'existe pas").arg(request.url().path()); + responder.sendResponse(QHttpServerResponse("text/plain; charset=utf-8", message.toUtf8(), QHttpServerResponder::StatusCode::NotFound)); +} + void Pws2mqtt::init() { + QHostInfo info; + // QHostAddress address; + QList addresses; +// QHttpServerRouterRule * status; + debug(DEBUGMACRO, "init http server", DEBUG); - httpServer->setMissingHandler([](const QHttpServerRequest &request, QHttpServerResponder &&responder) + addresses = QNetworkInterface::allAddresses(); + for( const auto &i: as_const(addresses)) { - (void) responder; - debug(DEBUGMACRO, "body " + request.url().toString(), WARNING); - return QHttpServerResponse("404 - Page non trouvée. Route par défaut.", QHttpServerResponse::StatusCode::NotFound); - //responder.write(QHttpServerResponse("404 - Page non trouvée. Route par défaut.", QHttpServerResponse::StatusCode::NotFound)); - }); + if (!i.isLoopback() and !i.isNull()) + { + this->localAddress = i; + break; + } + } + debug(DEBUGMACRO, "Locale address : " + this->localAddress.toString (), INFO); + + // server's routes + + httpServer->setMissingHandler(httpServer, missingHandler); httpServer->route("/", [](const QHttpServerRequest &request) { - QList> headersList = request.headers().toList(); + QList> headersList = request.headers().toListOfPairs(); debug(DEBUGMACRO, "Remote address" + request.remoteAddress().toString(), WARNING); return QHttpServerResponse("text/plain", "Failed\n"); }); @@ -134,14 +163,23 @@ void Pws2mqtt::init() void Pws2mqtt::listeningHttp() { - //QByteArray data; debug (DEBUGMACRO, "listening http requests", DEBUG); - const auto port = httpServer->listen(QHostAddress::Any, 5000); - if (!port) + tcpServer = new QTcpServer(); //httpServer.server.listen(QHostAddress::Any, this->port); + if (!tcpServer->listen(QHostAddress::LocalHost, 8001)) { - debug(DEBUGMACRO, "Http Server failed to listen on a port.", ERROR); + delete tcpServer; + debug(DEBUGMACRO, "TCPServer failed to listen on a port.", ERROR); + //return 0; + }else + { + if (!httpServer->bind(tcpServer)) + { + debug(DEBUGMACRO, "Binding tcpserver to httpserver failed ", ERROR); + }else + { + debug(DEBUGMACRO, "Listening on port " + QString::number(tcpServer->serverPort ()), INFO); + } } - debug(DEBUGMACRO, "Listening on port " + QString::number(port)); } void Pws2mqtt::parseData(QList> queryList) @@ -153,11 +191,11 @@ void Pws2mqtt::parseData(QList> queryList) QString notif = ""; QStringList priorityList {"", "min", "low", "default", "High", "urgent"}; QString attachment = ""; - quint8 priority = 2; - double propertyValue = 0; - bool propertyFlag = false; - bool deviceFlag = false; - static QDateTime timer = QDateTime::currentDateTime().addSecs(-2000); + quint8 priority = 2; + double propertyValue = 0; + bool propertyFlag = false; + bool deviceFlag = false; + static QDateTime timer = QDateTime::currentDateTime().addSecs(-2000); debug(DEBUGMACRO, "looping list of query", DEBUG); @@ -215,8 +253,8 @@ void Pws2mqtt::parseData(QList> queryList) //notif += formatNotifString (propertyName[name].first, propertyName[name].second , value); propertyList[name] = formatNotifString(propertyName[name].first, propertyName[name].second, QByteArray::number(propertyValue)); propertiesValue[name] = propertyValue; - } - /*}else if (name == "windchillf") + } + /*}else if (name == "windchillf") { static QDateTime timeWindchill = QDateTime::currentDateTime().addSecs(-600); propertyValue = round(fahrenheitToCelsius(value.toFloat())); @@ -228,27 +266,27 @@ void Pws2mqtt::parseData(QList> queryList) timeWindchill = timeWindchill.currentDateTime().addSecs(300); propertyList[name] = formatNotifString(propertyName[name].first, propertyName[name].second, QByteArray::number(propertyValue)); propertiesValue[name] = propertyValue; - }*/ + }*/ }else if (name == "winddir") { propertyValue = value.toFloat(); rotateAndSaveImage(this->inputPath, this->outputPath, (qreal)propertyValue); debug (DEBUGMACRO, name + " : " + QByteArray::number(propertyValue), DEBUG); propertyList[name] = formatNotifString(propertyName[name].first, propertyName[name].second, QByteArray::number(propertyValue)); - propertiesValue[name] = propertyValue; - }else if (name == "windspeedmph" or name == "windgustmph") + propertiesValue[name] = propertyValue; + }else if (name == "windspeedmph" or name == "windgustmph") { QString msg = ""; static QDateTime timeWind = QDateTime::currentDateTime().addSecs(-600); quint8 windPriority = 1; - propertiesValue["vent"] = round(mphTokmh(value.toFloat())); + propertiesValue["vent"] = round(mphTokmh(value.toFloat())); - debug (DEBUGMACRO, name + " : " + QByteArray::number(propertiesValue["vent"]), DEBUG); + debug (DEBUGMACRO, name + " : " + QByteArray::number(propertiesValue["vent"]), DEBUG); for (quint8 i=0; i> queryList) if (name == "windspeedmph") { //propertyList["forcevent"] = msg; - propertyList[name] = formatNotifString ("Vent - " + msg, propertyName[name].second , QByteArray::number(propertiesValue["vent"])); + propertyList[name] = formatNotifString ("Vent - " + msg, propertyName[name].second , QByteArray::number(propertiesValue["vent"])); }else { - propertyList[name] = formatNotifString (propertyName[name].first, propertyName[name].second , QByteArray::number(propertiesValue["vent"])); + propertyList[name] = formatNotifString (propertyName[name].first, propertyName[name].second , QByteArray::number(propertiesValue["vent"])); } setPriority(priority, windPriority); @@ -356,16 +394,16 @@ void Pws2mqtt::parseData(QList> queryList) propertiesValue[name] = propertyValue; debug (DEBUGMACRO, "Notif = #" + notif + "#", DEBUG); } - }else if (name == "solarradiation") - { - propertiesValue[name] = round(pair.second.toFloat()*100/100); - } + }else if (name == "solarradiation") + { + propertiesValue[name] = round(pair.second.toFloat()*100/100); + } } } - propertiesValue["windchill"] = calc.computeUTCI(propertiesValue["tempf"], propertiesValue["vent"], propertiesValue["solarradiation"], propertiesValue["humidity"]); - propertyList["windchill"] = formatNotifString(propertyName["windchill"].first, propertyName["windchill"].second, QByteArray::number(propertiesValue["windchill"])); - windChill(propertiesValue["tempf"], propertiesValue["vent"]); - calculerHumidex(propertiesValue["tempf"], propertiesValue["humidity"]); + propertiesValue["windchill"] = calc.computeUTCI(propertiesValue["tempf"], propertiesValue["vent"], propertiesValue["solarradiation"], propertiesValue["humidity"]); + propertyList["windchill"] = formatNotifString(propertyName["windchill"].first, propertyName["windchill"].second, QByteArray::number(propertiesValue["windchill"])); + windChill(propertiesValue["tempf"], propertiesValue["vent"]); + calculerHumidex(propertiesValue["tempf"], propertiesValue["humidity"]); if (!jsonString.isEmpty()) { @@ -379,86 +417,86 @@ void Pws2mqtt::parseData(QList> queryList) debug(DEBUGMACRO, "current datetime : " + QDateTime::currentDateTime().toString() + ", timer = " + timer.toString(), DEBUG); - if (priority > 3 or QDateTime::currentDateTime() > timer.addSecs(1800)) + if (priority > 3 or QDateTime::currentDateTime() > timer.addSecs(1800)) { - bool changed = false; - timer = QDateTime::currentDateTime(); - debug(DEBUGMACRO, "looping to fill notif, priority = " + QString::number(priority), DEBUG); + bool changed = false; + timer = QDateTime::currentDateTime(); + debug(DEBUGMACRO, "looping to fill notif, priority = " + QString::number(priority), DEBUG); - if (precPropertyList.size() == 0) - { - changed = true; - } + if (precPropertyList.size() == 0) + { + changed = true; + } for (auto [name, value]: propertyList.asKeyValueRange()) { - if (precPropertyList.contains(name)) - { - if (precPropertyList[name] != propertyList[name]) - { - debug(DEBUGMACRO, "changed = true", DEBUG); - changed = true; - } - } + if (precPropertyList.contains(name)) + { + if (precPropertyList[name] != propertyList[name]) + { + debug(DEBUGMACRO, "changed = true", DEBUG); + changed = true; + } + } - debug(DEBUGMACRO, "Name = " + name + ", value = " + value, DEBUG); - notif += propertyList[name]; + debug(DEBUGMACRO, "Name = " + name + ", value = " + value, DEBUG); + notif += propertyList[name]; } debug(DEBUGMACRO, "calling notify with notif = #" + notif + "#", DEBUG); - if (changed) - { - notify (notif, priorityList[priority], attachment); - precPropertyList = propertyList; - } - } + if (changed) + { + notify (notif, priorityList[priority], attachment); + precPropertyList = propertyList; + } + } debug(DEBUGMACRO, "parseData: Returning", DEBUG); } double calculerUTCI(double temperature, double humiditeRelative, double vitesseVent, double rayonnement) { - double e = (humiditeRelative / 100.0) * 6.105 * exp((17.27 * temperature) / (237.7 + temperature)); - debug(DEBUGMACRO, "UTCI => e = " + QString::number(e), DEBUG); - double V = vitesseVent * 5.0 / 18.0; // Vitesse du vent en m/s - debug(DEBUGMACRO, "UTCI => V = " + QString::number(V), DEBUG); + double e = (humiditeRelative / 100.0) * 6.105 * exp((17.27 * temperature) / (237.7 + temperature)); + debug(DEBUGMACRO, "UTCI => e = " + QString::number(e), DEBUG); + double V = vitesseVent * 5.0 / 18.0; // Vitesse du vent en m/s + debug(DEBUGMACRO, "UTCI => V = " + QString::number(V), DEBUG); - double utci = temperature + - (0.607562 + 0.022437 * e + 7.3869e-4 * temperature * e - 3.5582e-6 * temperature * temperature * e) + - (-11.4 + 0.11 * temperature + 0.55 * V) + - (0.0023 * temperature * temperature - 0.118 * V - 0.0014 * temperature * V); - debug(DEBUGMACRO, "UTCI = " + QString::number(utci), DEBUG); + double utci = temperature + + (0.607562 + 0.022437 * e + 7.3869e-4 * temperature * e - 3.5582e-6 * temperature * temperature * e) + + (-11.4 + 0.11 * temperature + 0.55 * V) + + (0.0023 * temperature * temperature - 0.118 * V - 0.0014 * temperature * V); + debug(DEBUGMACRO, "UTCI = " + QString::number(utci), DEBUG); - // Ajustement simplifié pour le rayonnement - double ref = 200.0; // Rayonnement de référence (W/m²) - double k = 0.02; // Coefficient empirique - utci = utci + k * (rayonnement - ref); - debug(DEBUGMACRO, "UTCI = " + QString::number(utci), DEBUG); - return round(utci * 100) / 100; + // Ajustement simplifié pour le rayonnement + double ref = 200.0; // Rayonnement de référence (W/m²) + double k = 0.02; // Coefficient empirique + utci = utci + k * (rayonnement - ref); + debug(DEBUGMACRO, "UTCI = " + QString::number(utci), DEBUG); + return round(utci * 100) / 100; } double windChill(double airT, double vent) { - double w = 0; + double w = 0; - if (airT > 10 or vent < 4.8) - { - return airT; - } else - { - w = 13.12 + 0.6215 * airT - 11.37 * pow(vent, 0.16) + 0.3965 * airT * pow(vent, 0.16); - debug(DEBUGMACRO, "windChill = " + QString::number(w), DEBUG); - return w; - } + if (airT > 10 or vent < 4.8) + { + return airT; + } else + { + w = 13.12 + 0.6215 * airT - 11.37 * pow(vent, 0.16) + 0.3965 * airT * pow(vent, 0.16); + debug(DEBUGMACRO, "windChill = " + QString::number(w), DEBUG); + return w; + } } double calculerHumidex(double temperature, double humiditeRelative) { - // Calcul de la température du point de rosée (T_rosée) - double T_rosee = (243.04 * (log(humiditeRelative / 100.0) + (17.625 * temperature) / (243.04 + temperature))) / (17.625 - (log(humiditeRelative / 100.0) + (17.625 * temperature) / (243.04 + temperature))); + // Calcul de la température du point de rosée (T_rosée) + double T_rosee = (243.04 * (log(humiditeRelative / 100.0) + (17.625 * temperature) / (243.04 + temperature))) / (17.625 - (log(humiditeRelative / 100.0) + (17.625 * temperature) / (243.04 + temperature))); - // Calcul de l'Humidex (H) - double H = temperature + 0.5555 * (6.11 * exp(5417.7530 * (1.0 / 273.16 - 1.0 / (273.15 + T_rosee))) - 10.0); - debug(DEBUGMACRO, "humidex = " + QString::number(H), DEBUG); + // Calcul de l'Humidex (H) + double H = temperature + 0.5555 * (6.11 * exp(5417.7530 * (1.0 / 273.16 - 1.0 / (273.15 + T_rosee))) - 10.0); + debug(DEBUGMACRO, "humidex = " + QString::number(H), DEBUG); - return H; + return H; } QString getPluviosite(double value, quint8 &priority) @@ -673,7 +711,7 @@ void notify(QString notif, QString priority, QString inputPath) // Exécute la requête - res = curl_easy_perform(curl); + res = curl_easy_perform(curl); // Vérifie les erreurs if (res != CURLE_OK) diff --git a/src/pws2mqtt.h b/src/pws2mqtt.h index 8f15cbc..09f5eec 100644 --- a/src/pws2mqtt.h +++ b/src/pws2mqtt.h @@ -6,6 +6,9 @@ #include #include #include +#include +#include "qhostaddress.h" + #define RED "\e[31m" #define GREEN "\e[32m" @@ -36,6 +39,7 @@ class Pws2mqtt : public QObject QString ProcName = "pws2mqtt"; // name of the proceesus in ps, top, pstree, ...; FILE * logFh = nullptr; QString listenHost = "0.0.0.0"; + QHostAddress localAddress; uint listenPort = 5000; int sockfd = 0; int newsockfd = 0;