diff --git a/pws2mqtt-qt.pro b/pws2mqtt-qt.pro index fb7e584..b2bd0c1 100644 --- a/pws2mqtt-qt.pro +++ b/pws2mqtt-qt.pro @@ -28,6 +28,7 @@ HEADERS += \ src/barometertrend.h \ #src/httpserver.h \ # src/mqtt.h \ + src/debug.h \ src/pws2mqtt.h \ src/utcicalculator.h \ src/version.h diff --git a/src/barometertrend.h b/src/barometertrend.h index 342876d..0542a6b 100644 --- a/src/barometertrend.h +++ b/src/barometertrend.h @@ -1,6 +1,5 @@ #pragma once -#include "pws2mqtt.h" #include "qjsonarray.h" #include "qjsondocument.h" #include "qjsonobject.h" @@ -10,6 +9,7 @@ #include #include #include +#include "debug.h" struct ForecastResult { @@ -24,6 +24,8 @@ struct ForecastResult quint8 confiance = 50; }; +//#include "pws2mqtt.h" + class BarometerTrend : public QObject { Q_OBJECT @@ -48,6 +50,7 @@ public: { saveHistory(); } + void addPressure(double pressure_hPa) { debug(DEBUGMACRO, "adding pressure " + QByteArray::number(pressure_hPa), DEBUG); @@ -86,30 +89,30 @@ public: } // Retourne la pression moyenne autour d'un instant cible (fenêtre +/- windowSecs) - double pressureAround(const QDateTime &target, int windowSecs = 60) const - { - if (m_values.isEmpty()) return 0.0; - const QDateTime from = target.addSecs(-windowSecs); - const QDateTime to = target.addSecs(+windowSecs); - double sum = 0.0; - int count = 0; - for (int i = 0; i < m_timestamps.size(); ++i) { - if (m_timestamps[i] >= from && m_timestamps[i] <= to) { - sum += m_values[i]; - ++count; - } - } - if (count == 0) { - // pas d'échantillon proche -> fallback sur la valeur la plus proche dans le passé - for (int i = m_timestamps.size() - 1; i >= 0; --i) { - if (m_timestamps[i] <= target) { - return m_values[i]; - } - } - return m_values.first(); - } - return sum / count; - } + double pressureAround(const QDateTime &target, int windowSecs = 60) const + { + if (m_values.isEmpty()) return 0.0; + const QDateTime from = target.addSecs(-windowSecs); + const QDateTime to = target.addSecs(+windowSecs); + double sum = 0.0; + int count = 0; + for (int i = 0; i < m_timestamps.size(); ++i) { + if (m_timestamps[i] >= from && m_timestamps[i] <= to) { + sum += m_values[i]; + ++count; + } + } + if (count == 0) { + // pas d'échantillon proche -> fallback sur la valeur la plus proche dans le passé + for (int i = m_timestamps.size() - 1; i >= 0; --i) { + if (m_timestamps[i] <= target) { + return m_values[i]; + } + } + return m_values.first(); + } + return sum / count; + } // Variation de pression sur N heures (ex: 1 ou 3) double deltaPressureHours(double hours) const @@ -419,7 +422,7 @@ private slots: QFile file("/usr/local/share/pws2mqtt/barometer_history.json"); if (!file.exists()) { - debug(DEBUGMACRO, "File not open : " + file.errorString() , WARNING); + debug(DEBUGMACRO, "File not open : " + file.errorString() + " -> cannot restore history", WARNING); return; } if (file.open(QIODevice::ReadOnly)) diff --git a/src/debug.h b/src/debug.h new file mode 100644 index 0000000..7a2aeca --- /dev/null +++ b/src/debug.h @@ -0,0 +1,14 @@ +#pragma once + +#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__) + " -> " + +#include + +void debug(QString debugHeader, QString msg, uint8_t level=ALL, QByteArray value=""); diff --git a/src/main.cpp b/src/main.cpp index ed2e5e7..b283d98 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,8 +3,9 @@ #include #include #include +#include "debug.h" #include "pws2mqtt.h" -#include "src/barometertrend.h" +//#include "src/barometertrend.h" #include "version.h" #ifdef WITH_MQTT #include @@ -15,7 +16,7 @@ #define CLIENT_ID "Client_ID" -uint debugLevel = INFO | ERROR | ALERT; +uint debugLevel = DEBUG | INFO | NOTICE | WARNING | ERROR | ALERT; QByteArray toFollow; #ifdef WITH_MQTT @@ -27,8 +28,6 @@ using namespace std; //Configuration config; Pws2mqtt *pws2mqtt; -QHttpServer *httpServer; -BarometerTrend *baro; int main(int argc, char *argv[]) { @@ -49,12 +48,7 @@ int main(int argc, char *argv[]) debug(DEBUGMACRO, "declaration of mqttClient", INFO); mqttClient = new MqttClient; #endif - httpServer = new QHttpServer; - - //declaration of debug level pws2mqtt = new Pws2mqtt; - baro = new BarometerTrend; - pws2mqtt->listeningHttp(); a.exec(); diff --git a/src/pws2mqtt.cpp b/src/pws2mqtt.cpp index b18d4dd..d3f78a2 100644 --- a/src/pws2mqtt.cpp +++ b/src/pws2mqtt.cpp @@ -16,12 +16,11 @@ #include #ifdef WITH_MQTT #include "mqtt.h" - /extern MqttClient *mqttClient; + extern MqttClient *mqttClient; #endif -extern Pws2mqtt *pws2mqtt; -extern QHttpServer *httpServer; -extern BarometerTrend *baro; +//extern QHttpServer *httpServer; +//extern BarometerTrend *baro; UtciCalculator calc; using namespace std; @@ -87,11 +86,22 @@ Pws2mqtt::~Pws2mqtt() { } +void Pws2mqtt::handleMissing(const QHttpServerRequest &request, QHttpServerResponder &responder) +{ + debug(DEBUGMACRO, "body " + request.url().toString(), WARNING); + + responder.sendResponse(QHttpServerResponse( + "text/plain; charset=utf-8", + "404 - Page non trouvée. Route par défaut.", + QHttpServerResponder::StatusCode::NotFound)); +} + + void Pws2mqtt::init() { debug(DEBUGMACRO, "init http server", INFO); - - + httpServer.setMissingHandler(this, &Pws2mqtt::handleMissing); +/* #if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) httpServer->setMissingHandler([](const QHttpServerRequest &request, QHttpServerResponder &&responder) { @@ -99,8 +109,9 @@ void Pws2mqtt::init() responder.sendResponse(QHttpServerResponse("text/plain; charset=utf-8", "404 - Page non trouvée. Route par défaut.", QHttpServerResponder::StatusCode::NotFound)); }); #endif +*/ - httpServer->route("/", [](const QHttpServerRequest &request) + httpServer.route("/", [](const QHttpServerRequest &request) { #if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0) QList> headersList = request.headers().toListOfPairs(); @@ -110,7 +121,7 @@ void Pws2mqtt::init() debug(DEBUGMACRO, "Remote address" + request.remoteAddress().toString(), WARNING); return QHttpServerResponse("text/plain", "Failed\n"); }); - httpServer->route("/query", [this](const QHttpServerRequest &request) + httpServer.route("/query", [this](const QHttpServerRequest &request) { QByteArray data; QList> queryList = request.query().queryItems(); @@ -135,11 +146,13 @@ void Pws2mqtt::init() //return QHttpServerResponse("text/plain", "Success\n"); }); + /* for (auto [name, pair]: propertyName.asKeyValueRange()) { propertyList[name].append(formatNotifString(pair, "0")); debug (DEBUGMACRO, "Init " + name + " => " + propertyList[name], DEBUG); }*/ + } void notify(QString notif, QString priority, QString inputPath, QString tag) @@ -170,8 +183,8 @@ void notify(QString notif, QString priority, QString inputPath, QString tag) debug(DEBUGMACRO, "Notification envoyée", INFO); } reply->deleteLater(); - delete(manager); }); + delete(manager); } @@ -180,32 +193,29 @@ void Pws2mqtt::listeningHttp() //QByteArray data; debug (DEBUGMACRO, "listening http requests", DEBUG); -#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0) - this->tcpServer = new QTcpServer(); //httpServer.server.listen(QHostAddress::Any, this->port); - if (!this->tcpServer->listen(QHostAddress::LocalHost, this->listenPort)) + baro = new BarometerTrend; + //auto tcpServer = new QTcpServer(); //httpServer.server.listen(QHostAddress::Any, this->port); + if (!tcpServer.listen(QHostAddress::Any, listenPort)) { - delete this->tcpServer; debug(DEBUGMACRO , "TCPServer failed to listen on a port.", ERROR); //return 0; }else { - if (!httpServer->bind(tcpServer)) + if (!httpServer.bind(&tcpServer)) { debug(DEBUGMACRO, "Binding tcpserver to httpserver failed ", ERROR); }else { - debug(DEBUGMACRO, "Listening on port " + QString::number(this->tcpServer->serverPort ()), INFO); + debug(DEBUGMACRO, "Listening on port " + QString::number(tcpServer.serverPort ()), INFO); } } -#else - const auto listenPort = httpServer->listen(QHostAddress::Any, 5000); -#endif if (!this->listenPort) { debug(DEBUGMACRO, "Http Server failed to listen on a port.", ERROR); } debug(DEBUGMACRO, "Listening on port " + QString::number(listenPort), INFO); + //tcpServer.release(); } void Pws2mqtt::parseData(QList> queryList) @@ -219,7 +229,7 @@ void Pws2mqtt::parseData(QList> queryList) QString notif = ""; QStringList priorityList {"", "min", "low", "default", "High", "urgent"}; QMap propertyList; - QMap propertiesValue; + static QMap propertiesValue; QString attachment = ""; QString tag = ""; double propertyValue = 0; @@ -273,10 +283,17 @@ void Pws2mqtt::parseData(QList> queryList) if (compare (propertiesValue[name], propertyValue, 1)) // and timeTemp < QDateTime::currentDateTime()) { //timeTemp = timeTemp.currentDateTime().addSecs(300); + quint8 valueRounded; propertyList[name] = formatNotifString(propertyName[name], QByteArray::number(propertyValue)); propertiesValue[name] = propertyValue; debug (DEBUGMACRO, name + " : " + QByteArray::number(propertyValue) + " announced = " + QByteArray::number(announced[name]), DEBUG); - quint8 valueRounded = qRound(propertyValue + 0.5); + if ((qRound(propertyValue) - propertyValue) < 0) + { + valueRounded = qRound(propertyValue - 0.5); + }else + { + valueRounded = qRound(propertyValue); + } QString alertString = formatNotifString(propertyName[name], QByteArray::number(valueRounded)); if (valueRounded >= 35) @@ -473,38 +490,46 @@ void Pws2mqtt::parseData(QList> queryList) }else if (name == "UV") { QString msg; - static QDateTime timeUV = QDateTime::currentDateTime().addSecs(-600); + static QDateTime timeUV; + static quint8 oldValue; + //timeUV = QDateTime::currentDateTime().addSecs(600); propertyValue = pair.second.toUInt(); debug (DEBUGMACRO, name + " : " + QByteArray::number(propertyValue), DEBUG); - if (compare (propertiesValue[name], propertyValue, 1) and timeUV < QDateTime::currentDateTime()) - { - //notif += formatNotifString (propertyName[name].first, propertyName[name].second , value); - - /*if (propertyValue == 5 ) - priority[name] = setPriority (priority[name], 4); - if (propertyValue >= 6 ) - priority[name] = setPriority (priority[name], 5); - */ - propertiesValue[name] = propertyValue; - //debug (DEBUGMACRO, "Notif = #" + notif + "#", DEBUG); - propertyList[name] = "- UV - " + QByteArray::number(propertyValue) + "\n"; - - if (propertyValue > 5) + //if (timeUV < QDateTime::currentDateTime()) + //{ + if (compare (oldValue, propertyValue, 1)) { - if (announced[name] != propertyValue) + + //notif += formatNotifString (propertyName[name].first, propertyName[name].second , value); + + /*if (propertyValue == 5 ) + priority[name] = setPriority (priority[name], 4); + if (propertyValue >= 6 ) + priority[name] = setPriority (priority[name], 5); + */ + propertiesValue[name] = propertyValue; + //debug (DEBUGMACRO, "Notif = #" + notif + "#", DEBUG); + propertyList[name] = "- UV - " + QByteArray::number(propertyValue) + "\n"; + + if (propertyValue > 5) + { + if (announced[name] != propertyValue) + { + notify (propertyList[name], priorityList[priority[name]]); + announced[name] = propertyValue; + debug (DEBUGMACRO, "Notifying : " + name + " is " + QString::number(propertyValue), DEBUG); + oldValue = propertyValue; + } + }else { notify (propertyList[name], priorityList[priority[name]]); - announced[name] = propertyValue; + announced[name] = 0; + oldValue = 0; debug (DEBUGMACRO, "Notifying : " + name + " is " + QString::number(propertyValue), DEBUG); } - }else - { - notify (propertyList[name], priorityList[priority[name]]); - announced[name] = 0; - debug (DEBUGMACRO, "Notifying : " + name + " is " + QString::number(propertyValue), DEBUG); } - } + //} }else if (name == "solarradiation") { propertyValue = round(pair.second.toFloat()*100)/100.0; diff --git a/src/pws2mqtt.h b/src/pws2mqtt.h index ecf6743..d6f12f5 100644 --- a/src/pws2mqtt.h +++ b/src/pws2mqtt.h @@ -1,5 +1,11 @@ #pragma once +#define RED "\e[31m" +#define GREEN "\e[32m" +#define BLUE "\e[94m" +#define ORANGE "\e[33m" +#define NORMAL "\e[0m" + #include #include #include @@ -10,23 +16,8 @@ #include #endif -#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__) + " -> " - -void debug(QString debugHeader, QString msg, uint8_t level=ALL, QByteArray value=""); //QString addValue(QByteArray value); +#include "src/barometertrend.h" class Pws2mqtt : public QObject { @@ -36,7 +27,10 @@ class Pws2mqtt : public QObject Pws2mqtt(); ~Pws2mqtt(); - QTcpServer * tcpServer; + QHttpServer httpServer; + QTcpServer tcpServer; + BarometerTrend * baro; + QString ProcName = "pws2mqtt"; // name of the proceesus in ps, top, pstree, ...; FILE * logFh = nullptr; QString listenHost = "0.0.0.0"; @@ -49,6 +43,8 @@ class Pws2mqtt : public QObject void init(); void listeningHttp(); void parseData(QList> queryList); + void handleMissing(const QHttpServerRequest &request, QHttpServerResponder &responder); + }; double fahrenheitToCelsius(double fahrenheit);