From eb346b104ca0ad8f733627e87e97fd863b09d46a Mon Sep 17 00:00:00 2001 From: Daniel TARTAVEL Date: Sat, 1 Nov 2025 14:08:39 +0100 Subject: [PATCH 01/10] debug --- src/barometertrend.h | 43 +++++++++++++++++++++++---------- src/main.cpp | 2 +- src/mqtt.h | 57 -------------------------------------------- src/pws2mqtt.cpp | 18 +++++++------- 4 files changed, 41 insertions(+), 79 deletions(-) diff --git a/src/barometertrend.h b/src/barometertrend.h index bf61599..2e2e138 100644 --- a/src/barometertrend.h +++ b/src/barometertrend.h @@ -139,7 +139,7 @@ public: QStringList icons; // Logique combinée pression / tendance - if (p < 990 && d3 <= -3.0) + if (p < 990 && d3 <= -3.0) { r.message = "- Tempête ou orage"; r.urgency = 5; @@ -157,24 +157,30 @@ public: r.urgency = 0; icons << "sunny"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1020 && d3 < -3.0) + }else if (p >= 1020 && (d3 <= +0.5 && d3 >= -0.5)) + { + r.message = "- Beau temps stable"; + r.urgency = 0; + icons << "sunny"; + debug(DEBUGMACRO, "message : " + r.message, DEBUG); + }else if (p >= 1020 && d3 < -3.0) { r.message = "- Beau, mais rapide dégradation"; r.urgency = 4; icons << "sun_behind_large_cloud"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1020 && d3 < -1.0) + }else if (p >= 1020 && d3 < -1.0) { r.message = "- Beau, mais possible dégradation"; r.urgency = 1; icons << "sun_behind_small_cloud"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); - /*}else if (p >= 1020 && d3 < 0.5.0) + }else if (p >= 1020 && (d3 <= 0.5 && d3 >= -0.5)) { - r.message = "- Beau temps"; + r.message = "- Beau temps stable"; r.urgency = 0; icons << "sunny"; - debug(DEBUGMACRO, "message : " + r.message, DEBUG);*/ + debug(DEBUGMACRO, "message : " + r.message, DEBUG); }else if (p >= 1010 && d3 >= +3.0) { r.message = "- Nuageux, rapide amélioration"; @@ -199,7 +205,7 @@ public: r.urgency = 2; icons << "sun_behind_rain_cloud"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1010 && d3 <= 0.5) + }else if (p >= 1010 && (d3 <= 0.5 && d3 >= 0.5)) { r.message = "- Nuageux avec des éclaircies"; r.urgency = 2; @@ -225,11 +231,17 @@ public: debug(DEBUGMACRO, "message : " + r.message, DEBUG); }else if (p >= 1000 && d3 <= -1.0) { - r.message = "- Pluie ou perturbation"; + r.message = "- Pluie ou perturbation stable"; r.urgency = 2; icons << "cloud_with_rain"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p < 1000 && d3 >= +3.0) + }else if (p >= 1000 && (d3 <= 0.5 && d3 >= -0.5)) + { + r.message = "- Pluie ou perturbation"; + r.urgency = 2; + icons << "cloud_with_rain"; + debug(DEBUGMACRO, "message : " + r.message, DEBUG); + }else if (p < 1000 && d3 >= +3.0) { r.message = "- Pluie avec accalmie temporaire, amélioration rapide"; r.urgency = 1; @@ -247,13 +259,20 @@ public: r.urgency = 4; icons << "cloud_with_rain"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); - } - if (qAbs(d3) < 1) + }else if (p < 1000 && (d3 <= 0.5 && d3 >= -0.5)) + { + r.message = "- Mauvais temps stable"; + r.urgency = 4; + icons << "cloud_with_rain"; + debug(DEBUGMACRO, "message : " + r.message, DEBUG); + } + + /*if (qAbs(d3) < 1) { r.message += "- Stable, pas de changement significatif"; r.urgency = 0; debug(DEBUGMACRO, "message : " + r.message, DEBUG); - } + }*/ // Risque de neige if (p < 1000 && d3 < -1.0 && temperatureC <= 1.0 && humidityPercent > 80.0) diff --git a/src/main.cpp b/src/main.cpp index 4a04fac..04a9a09 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -26,7 +26,7 @@ #define BROKER_ADDRESS "localhost" #define MQTT_PORT 1883; -uint debugLevel = DEBUG | INFO | NOTICE | INFO | WARNING | ERROR | ALERT; +uint debugLevel = INFO | NOTICE | INFO | WARNING | ERROR | ALERT; QByteArray toFollow; //class MqttClient; diff --git a/src/mqtt.h b/src/mqtt.h index 1b494b9..d84fd96 100644 --- a/src/mqtt.h +++ b/src/mqtt.h @@ -11,63 +11,6 @@ #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 diff --git a/src/pws2mqtt.cpp b/src/pws2mqtt.cpp index 454d8b4..0de750c 100644 --- a/src/pws2mqtt.cpp +++ b/src/pws2mqtt.cpp @@ -46,8 +46,8 @@ QMap > propertyName { {"tempf", {"Température extérieure", "°C"}}, {"humidity", {"Humidité extérieure", "%"}}, - {"dewptf", {"Point de rosée", "°C"}}, - {"windchill", {"Température ressentie", "°C"}}, +// {"dewptf", {"Point de rosée", "°C"}}, + {"windchill", {"Température ressentie", "°C"}}, {"winddir", {"Direction du vent", "°"}}, {"windspeedmph", {"Vitesse du vent", " km/h"}}, {"windgustmph", {"Rafales", " km/h"}}, @@ -232,13 +232,13 @@ void Pws2mqtt::parseData(QList> queryList) static QDateTime timeWind = QDateTime::currentDateTime().addSecs(-600); quint8 windPriority = 1; - propertiesValue["vent"] = round(mphTokmh(value.toFloat())); + propertiesValue[name] = round(mphTokmh(value.toFloat())); - debug (DEBUGMACRO, name + " : " + QByteArray::number(propertiesValue["vent"]), DEBUG); + debug (DEBUGMACRO, name + " : " + QByteArray::number(propertiesValue[name]), DEBUG); for (i=0; i> queryList) } } - propertyList[name] = formatNotifString ("Vent - " + msg, propertyName[name].second , QByteArray::number(propertiesValue["vent"])); + propertyList[name] = formatNotifString ("Vent - " + msg, propertyName[name].second , QByteArray::number(propertiesValue[name])); propertiesValue["forcevent"] = i; if (i >= 5) { @@ -265,11 +265,11 @@ void Pws2mqtt::parseData(QList> queryList) propertiesValue[name] = round(mphTokmh(value.toFloat())); - debug (DEBUGMACRO, name + " : " + QByteArray::number(propertiesValue["rafale"]), DEBUG); + debug (DEBUGMACRO, name + " : " + QByteArray::number(propertiesValue[name]), DEBUG); propertyList[name] = formatNotifString (propertyName[name].first, propertyName[name].second , QByteArray::number(propertiesValue[name])); - if (propertiesValue["rafales"] > 50) + if (propertiesValue[name] > 50) { priority = qMax(priority, (quint8)4); } @@ -414,7 +414,7 @@ void Pws2mqtt::parseData(QList> queryList) } notif = "**Prévisions à 12/24h**\n" + propertyList["prevision"]; - notify (notif, priorityList[priority], attachment, tag); + notify (notif, priorityList[priority], "", tag); debug(DEBUGMACRO, "calling notify with notif = #" + notif + "#", DEBUG); } From c07db58a7e7121801b54e83af4ce8d66d9dd09ff Mon Sep 17 00:00:00 2001 From: Daniel TARTAVEL Date: Wed, 5 Nov 2025 13:29:14 +0100 Subject: [PATCH 02/10] modif priority of rain in hour --- src/barometertrend.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/barometertrend.h b/src/barometertrend.h index 2e2e138..7b53aab 100644 --- a/src/barometertrend.h +++ b/src/barometertrend.h @@ -157,7 +157,7 @@ public: r.urgency = 0; icons << "sunny"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1020 && (d3 <= +0.5 && d3 >= -0.5)) + }else if (p >= 1020 && (d3 <= +1.0 && d3 >= -1.0)) { r.message = "- Beau temps stable"; r.urgency = 0; @@ -175,7 +175,7 @@ public: r.urgency = 1; icons << "sun_behind_small_cloud"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1020 && (d3 <= 0.5 && d3 >= -0.5)) + }else if (p >= 1020 && (d3 <= 1.0 && d3 >= -1.0)) { r.message = "- Beau temps stable"; r.urgency = 0; @@ -205,7 +205,7 @@ public: r.urgency = 2; icons << "sun_behind_rain_cloud"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1010 && (d3 <= 0.5 && d3 >= 0.5)) + }else if (p >= 1010 && (d3 <= 1.0 && d3 >= 1.0)) { r.message = "- Nuageux avec des éclaircies"; r.urgency = 2; @@ -231,13 +231,13 @@ public: debug(DEBUGMACRO, "message : " + r.message, DEBUG); }else if (p >= 1000 && d3 <= -1.0) { - r.message = "- Pluie ou perturbation stable"; + r.message = "- Pluie ou perturbation"; r.urgency = 2; icons << "cloud_with_rain"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1000 && (d3 <= 0.5 && d3 >= -0.5)) + }else if (p >= 1000 && (d3 <= 1.0 && d3 >= -1.0)) { - r.message = "- Pluie ou perturbation"; + r.message = "- Pluie ou perturbation stable"; r.urgency = 2; icons << "cloud_with_rain"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); @@ -259,7 +259,7 @@ public: r.urgency = 4; icons << "cloud_with_rain"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p < 1000 && (d3 <= 0.5 && d3 >= -0.5)) + }else if (p < 1000 && (d3 <= 1.0 && d3 >= -1.0)) { r.message = "- Mauvais temps stable"; r.urgency = 4; @@ -289,7 +289,7 @@ public: { r.rainRisk = true; r.message += "- Risque de pluie"; - r.urgency = qMax(r.urgency, 2); + r.urgency = qMax(r.urgency, 3); icons << "cloud_with_rain"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); } @@ -327,7 +327,7 @@ public: if (d <= -1.5 && p < 1010 && humidityPercent > 80.0) { r.prevision1h = "- Pluie probable dans l'heure"; - r.urgency = qMax(r.urgency, 4); + r.urgency = qMax(r.urgency, 3); r.confiance = 80; }else if (d >= +1.5 && p > 1015) { From ca5e6b479e74fdc9e51d13015dd817764f00e9ea Mon Sep 17 00:00:00 2001 From: Daniel TARTAVEL Date: Tue, 18 Nov 2025 10:14:45 +0100 Subject: [PATCH 03/10] debbug --- src/pws2mqtt.cpp | 317 +++++++++++++++++++++-------------------- src/pws2mqtt.h | 1 + src/utcicalculator.cpp | 242 +++++++++++++++---------------- 3 files changed, 287 insertions(+), 273 deletions(-) diff --git a/src/pws2mqtt.cpp b/src/pws2mqtt.cpp index 0de750c..abd670e 100644 --- a/src/pws2mqtt.cpp +++ b/src/pws2mqtt.cpp @@ -49,7 +49,7 @@ QMap > propertyName // {"dewptf", {"Point de rosée", "°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"}}, @@ -58,7 +58,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", ""}} }; @@ -74,7 +74,7 @@ QList > forceVent {38, "Bonne brise", 1}, {49, "Vent frais", 3}, {61, "Grand vent", 4}, - {74, "Vent fort", 4}, + {74, "Vent fort", 4}, {88, "Vent violent", 5}, {117, "Tempête", 5}, {1000, "Ouragan", 5} @@ -126,11 +126,11 @@ void Pws2mqtt::init() return QHttpServerResponse("text/plain", "Success\n"); }); - for (auto [name, pair]: propertyName.asKeyValueRange()) - { - propertyList[name].append(formatNotifString(pair.first, pair.second, "0")); - debug (DEBUGMACRO, "Init " + name + " => " + propertyList[name], DEBUG); - } + for (auto [name, pair]: propertyName.asKeyValueRange()) + { + propertyList[name].append(formatNotifString(pair.first, pair.second, "0")); + debug (DEBUGMACRO, "Init " + name + " => " + propertyList[name], DEBUG); + } } void Pws2mqtt::listeningHttp() @@ -154,12 +154,14 @@ void Pws2mqtt::parseData(QList> queryList) QString notif = ""; QStringList priorityList {"", "min", "low", "default", "High", "urgent"}; QString attachment = ""; - QString tag = ""; - quint8 priority = 2; - double propertyValue = 0; - bool propertyFlag = false; - bool deviceFlag = false; - static QDateTime timer = QDateTime::currentDateTime().addSecs(-2000); + QString tag = ""; + double propertyValue = 0; + bool propertyFlag = false; + bool deviceFlag = false; + static QDateTime timer = QDateTime::currentDateTime().addSecs(-2000); + static QHash priority = {}; + static QHash announced = {}; + static bool start = false; debug(DEBUGMACRO, "looping list of query", DEBUG); @@ -206,6 +208,13 @@ void Pws2mqtt::parseData(QList> queryList) timeTemp = timeTemp.currentDateTime().addSecs(300); propertyList[name] = formatNotifString(propertyName[name].first, propertyName[name].second, QByteArray::number(propertyValue)); propertiesValue[name] = propertyValue; + if (propertyValue > 35) + { + priority[name] = 4; + }else if (propertyValue > 27) + { + priority[name] = 3; + } } }else if (name == "humidity") { @@ -217,26 +226,26 @@ 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 == "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") + propertiesValue[name] = propertyValue; + }else if (name == "windspeedmph") { QString msg = ""; - quint8 i; - static QDateTime timeWind = QDateTime::currentDateTime().addSecs(-600); + quint8 i; + static QDateTime timeWind = QDateTime::currentDateTime().addSecs(-600); quint8 windPriority = 1; propertiesValue[name] = round(mphTokmh(value.toFloat())); debug (DEBUGMACRO, name + " : " + QByteArray::number(propertiesValue[name]), DEBUG); - for (i=0; i> queryList) } propertyList[name] = formatNotifString ("Vent - " + msg, propertyName[name].second , QByteArray::number(propertiesValue[name])); - propertiesValue["forcevent"] = i; - if (i >= 5) - { - attachment = this->outputPath; - } - - if (propertiesValue["forcevent"] != i) - { - priority = qMax(priority, windPriority); + propertiesValue["forcevent"] = i; + if (i >= 5) + { + attachment = this->outputPath; } - debug (DEBUGMACRO, "priority = " + QString::number(priority), DEBUG); - }else if (name == "windgustmph") - { - QString msg = ""; - static QDateTime timeWind = QDateTime::currentDateTime().addSecs(-600); - propertiesValue[name] = round(mphTokmh(value.toFloat())); + if (propertiesValue["forcevent"] != i) + { + priority[name] = qMax(priority[name], windPriority); + } + debug (DEBUGMACRO, "priority = " + QString::number(priority[name]), DEBUG); + }else if (name == "windgustmph") + { + QString msg = ""; + static QDateTime timeWind = QDateTime::currentDateTime().addSecs(-600); + + propertiesValue[name] = round(mphTokmh(value.toFloat())); debug (DEBUGMACRO, name + " : " + QByteArray::number(propertiesValue[name]), DEBUG); - propertyList[name] = formatNotifString (propertyName[name].first, propertyName[name].second , QByteArray::number(propertiesValue[name])); + propertyList[name] = formatNotifString (propertyName[name].first, propertyName[name].second , QByteArray::number(propertiesValue[name])); if (propertiesValue[name] > 50) - { - priority = qMax(priority, (quint8)4); - } - debug (DEBUGMACRO, "priority = " + QString::number(priority), DEBUG); - }else if (name == "rainin") + { + priority[name] = qMax(priority[name], (quint8)4); + } + debug (DEBUGMACRO, "priority = " + QString::number(priority[name]), DEBUG); + }else if (name == "rainin") { static double ecart; quint8 raininPriority = 1; @@ -290,13 +299,13 @@ void Pws2mqtt::parseData(QList> queryList) if (compare (propertiesValue[name], propertyValue, ecart)) { QString pluviosite = getPluviosite(propertyValue, raininPriority); - priority = setPriority (priority, raininPriority); + priority[name] = setPriority (priority[name], raininPriority); //debug (DEBUGMACRO, "Notif = #" + notif + "#", DEBUG); - propertyList[name] = formatNotifString(pluviosite, propertyName[name].second, QByteArray::number(propertyValue)); + propertyList[name] = formatNotifString(pluviosite, propertyName[name].second, QByteArray::number(propertyValue)); propertiesValue[name] = propertyValue; } - debug (DEBUGMACRO, "priority = " + QString::number(priority), DEBUG); - }else if (name == "dailyrainin") + debug (DEBUGMACRO, "priority = " + QString::number(priority[name]), DEBUG); + }else if (name == "dailyrainin") { static double ecart; propertyValue = round(pair.second.toFloat()*100)/100; @@ -310,63 +319,63 @@ void Pws2mqtt::parseData(QList> queryList) debug (DEBUGMACRO, name + " : " + QByteArray::number(propertyValue), DEBUG); if (compare (propertiesValue[name], propertyValue, ecart)) { - //priority = setPriority (priority, 3); + //priority[name] = setPriority (priority[name], 3); //debug (DEBUGMACRO, "Notif = #" + notif + "#", DEBUG); - propertyList[name] = formatNotifString(propertyName[name].first, propertyName[name].second, QByteArray::number(propertyValue)); - propertiesValue[name] = propertyValue; + propertyList[name] = formatNotifString(propertyName[name].first, propertyName[name].second, QByteArray::number(propertyValue)); + propertiesValue[name] = propertyValue; } - debug (DEBUGMACRO, "priority = " + QString::number(priority), DEBUG); - }else if (name == "baromin") + debug (DEBUGMACRO, "priority = " + QString::number(priority[name]), DEBUG); + }else if (name == "baromin") { //static QDateTime timePrevision = QDateTime::currentDateTime().addSecs(-1000); - propertyValue = round(tohPa(pair.second.toFloat()) * 100) / 100; - debug (DEBUGMACRO, "Barometre en hPa : " + QByteArray::number(propertyValue), DEBUG); - baro->addPressure(propertyValue); - propertyList[name] = formatNotifString(propertyName[name].first, "", QByteArray::number(propertyValue)); - propertiesValue[name] = propertyValue; + propertyValue = round(tohPa(pair.second.toFloat()) * 100) / 100; + debug (DEBUGMACRO, "Barometre en hPa : " + QByteArray::number(propertyValue), DEBUG); + baro->addPressure(propertyValue); + propertyList[name] = formatNotifString(propertyName[name].first, "", QByteArray::number(propertyValue)); + propertiesValue[name] = propertyValue; - static QString prevision; - auto ret = baro->forecast(propertiesValue["tempf"], propertiesValue["humidity"]); + static QString prevision; + auto ret = baro->forecast(propertiesValue["tempf"], propertiesValue["humidity"]); - prevision = ret.message; - //if (prevision != newPrevision) - //{ - priority = setPriority(priority, ret.urgency); - tag += ret.icons; + prevision = ret.message; + //if (prevision != newPrevision) + //{ + priority[name] = setPriority(priority[name], ret.urgency); + tag += ret.icons; - propertyList["prevision"] = prevision; - debug (DEBUGMACRO, "priority = " + QString::number(priority), DEBUG); - }else if (name == "UV") + propertyList["prevision"] = prevision; + debug (DEBUGMACRO, "priority = " + QString::number(priority[name]), DEBUG); + }else if (name == "UV") { static QDateTime timeUV = QDateTime::currentDateTime().addSecs(-600); - propertyValue = pair.second.toUInt(); + 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 = setPriority (priority, 4); + priority[name] = setPriority (priority[name], 4); if (propertyValue >= 6 ) - priority = setPriority (priority, 5); + priority[name] = setPriority (priority[name], 5); timeUV = timeUV.currentDateTime().addSecs(300); propertiesValue[name] = propertyValue; debug (DEBUGMACRO, "Notif = #" + notif + "#", DEBUG); - propertyList[name] = formatNotifString(propertyName[name].first, "", QByteArray::number(propertyValue)); - } - debug (DEBUGMACRO, "priority = " + QString::number(priority), DEBUG); + propertyList[name] = formatNotifString(propertyName[name].first, "", QByteArray::number(propertyValue)); + } + debug (DEBUGMACRO, "priority = " + QString::number(priority[name]), 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()) { @@ -380,66 +389,70 @@ 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)) + + //bool changed = false; + quint8 aPriority= 0; + + debug(DEBUGMACRO, "looping to fill notif", DEBUG); + + for (auto [name, value]: propertyList.asKeyValueRange()) { - bool changed = false; - timer = QDateTime::currentDateTime(); - debug(DEBUGMACRO, "looping to fill notif, priority = " + QString::number(priority), DEBUG); - - if (precPropertyList.size() == 0) - { - changed = true; - } - for (auto [name, value]: propertyList.asKeyValueRange()) + if (precPropertyList.contains(name)) { - if (precPropertyList.contains(name)) - { - if (precPropertyList[name] != propertyList[name]) - { - debug(DEBUGMACRO, "changed = true", DEBUG); - changed = true; - } - } + if (precPropertyList[name] != propertyList[name]) + { + if (announced.contains(name) and priority.contains(name)) + { + if (announced[name] != priority[name]) + { + debug(DEBUGMACRO, "changed = true", DEBUG); + announced[name] = priority[name]; + //changed = true; + aPriority = qMax(aPriority, priority[name]); + } + } + } + } - debug(DEBUGMACRO, "Name = " + name + ", value = " + value, DEBUG); - if (! (name == "prevision")) - { - notif += propertyList[name]; - } - } - if (changed) - { - notify (notif, priorityList[priority], attachment, tag); - precPropertyList = propertyList; - } + debug(DEBUGMACRO, "Name = " + name + ", value = " + value, DEBUG); + if (name != "prevision") + { + notif += propertyList[name]; + } + } + if (QDateTime::currentDateTime() > timer.addSecs(3600) or start == false or aPriority >= 3) + { + timer = QDateTime::currentDateTime(); + start = true; + notify (notif, priorityList[aPriority], attachment, tag); + precPropertyList = propertyList; - notif = "**Prévisions à 12/24h**\n" + propertyList["prevision"]; - notify (notif, priorityList[priority], "", tag); - debug(DEBUGMACRO, "calling notify with notif = #" + notif + "#", DEBUG); - - } + notif = "**Prévisions à 12/24h**\n" + propertyList["prevision"]; + notify (notif, priorityList[aPriority], "", tag); + debug(DEBUGMACRO, "calling notify with notif = #" + notif + "#", DEBUG); + } 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; } QString getPluviosite(double value, quint8 &priority) @@ -509,13 +522,13 @@ bool compare (double value, double currentValue, double ecart) QString formatNotifString (QString name, QString unit ,QByteArray value) { - QString text = "- " + name + " : " + value; + QString text = "- " + name + " : " + value; if (!unit.isEmpty()) { text += unit; - //"- " + propertyName[name].first + " : " + value + " " + propertyName[name].second + " "; + //"- " + propertyName[name].first + " : " + value + " " + propertyName[name].second + " "; } - return text += "\n"; + return text += "\n"; } static size_t ReadFile(void *ptr, size_t size, size_t nmemb, void *stream) { @@ -527,9 +540,9 @@ static size_t ReadFile(void *ptr, size_t size, size_t nmemb, void *stream) { // Callback for curl library static size_t WriteCallback(void *contents, size_t size, size_t nmemb, std::string *output) { - size_t total_size = size * nmemb; - output->append((char*)contents, total_size); - return total_size; + size_t total_size = size * nmemb; + output->append((char*)contents, total_size); + return total_size; } void notify(QString notif, QString priority, QString inputPath, QString tag) @@ -539,35 +552,35 @@ void notify(QString notif, QString priority, QString inputPath, QString tag) std::string readBuffer; priority = "Priority: " + priority; - debug (DEBUGMACRO, "notifying at priority " + priority + "with tag : " + tag + " - message : " + notif, DEBUG); + debug (DEBUGMACRO, "notifying at priority " + priority + "with tag : " + tag + " - message : " + notif, DEBUG); // Initialise libcurl curl_global_init(CURL_GLOBAL_DEFAULT); curl = curl_easy_init(); - if (curl) + if (curl) { // Définis les en-têtes pour le titre et les priorités struct curl_slist *headers = NULL; - notif.replace("\\", "\\\\\\'"); // Échappe les apostrophes + notif.replace("\\", "\\\\\\'"); // Échappe les apostrophes - if (!tag.isEmpty()) - { - headers = curl_slist_append(headers, ("Tags: " + tag).toStdString().c_str()); - } - headers = curl_slist_append(headers, "Title: Météo"); + if (!tag.isEmpty()) + { + headers = curl_slist_append(headers, ("Tags: " + tag).toStdString().c_str()); + } + headers = curl_slist_append(headers, "Title: Météo"); headers = curl_slist_append(headers, priority.toStdString().c_str()); - headers = curl_slist_append(headers, "Markdown: yes"); + headers = curl_slist_append(headers, "Markdown: yes"); // headers = curl_slist_append(headers, "Config: /etc/ntfy.client.yml"); headers = curl_slist_append(headers, "Firebase: no"); // headers = curl_slist_append(headers, "Content-Type: charset=UTF-8; text/markdown"); // Ajout de l'encodage - struct curl_slist *h = headers; - while (h) { - debug(DEBUGMACRO, "Header: " + QString(h->data), DEBUG); - h = h->next; - } - debug(DEBUGMACRO, "Notif: " + notif, DEBUG); + struct curl_slist *h = headers; + while (h) { + debug(DEBUGMACRO, "Header: " + QString(h->data), DEBUG); + h = h->next; + } + debug(DEBUGMACRO, "Notif: " + notif, DEBUG); // Configure la requête POST curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:81/Meteo"); @@ -575,11 +588,11 @@ void notify(QString notif, QString priority, QString inputPath, QString tag) curl_easy_setopt(curl, CURLOPT_POSTFIELDS, notif.toUtf8().constData()); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); // Exécute la requête - res = curl_easy_perform(curl); + res = curl_easy_perform(curl); // Vérifie les erreurs if (res != CURLE_OK) @@ -587,7 +600,7 @@ void notify(QString notif, QString priority, QString inputPath, QString tag) debug(DEBUGMACRO, "Erreur libcurl :" + QString(curl_easy_strerror(res)), DEBUG); } else { - debug(DEBUGMACRO, "Réponse du serveur: " + QString::fromStdString(readBuffer), DEBUG); + debug(DEBUGMACRO, "Réponse du serveur: " + QString::fromStdString(readBuffer), DEBUG); } // Nettoie les ressources diff --git a/src/pws2mqtt.h b/src/pws2mqtt.h index f9f497d..dc05356 100644 --- a/src/pws2mqtt.h +++ b/src/pws2mqtt.h @@ -5,6 +5,7 @@ #include #include #include +#include #define RED "\e[31m" #define GREEN "\e[32m" diff --git a/src/utcicalculator.cpp b/src/utcicalculator.cpp index 6449985..ec2c923 100644 --- a/src/utcicalculator.cpp +++ b/src/utcicalculator.cpp @@ -5,7 +5,7 @@ #include UtciCalculator::UtciCalculator(QObject *parent) - : QObject(parent) + : QObject(parent) { } @@ -14,165 +14,165 @@ UtciCalculator::UtciCalculator(QObject *parent) // appear in the same order as in the official table (210 coefficients). bool UtciCalculator::loadCoefficientsFromFile(const QString &path) { - QFile f(path); - if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) - return false; + QFile f(path); + if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) + return false; - QTextStream in(&f); - QVector coeffs; - coeffs.reserve(300); + QTextStream in(&f); + QVector coeffs; + coeffs.reserve(300); - while (!in.atEnd()) { - QString line = in.readLine().trimmed(); - if (line.isEmpty()) continue; - // Allow lines with comments or 'term coefficient' headings: - // We try to extract numbers from the line. - QStringList parts = line.split(QRegularExpression("[\\s,\\t]+"), Qt::SkipEmptyParts); - for (const QString &p : parts) { - bool ok = false; - double val = p.toDouble(&ok); - if (ok) coeffs.append(val); - } - } - if (coeffs.isEmpty()) return false; + while (!in.atEnd()) { + QString line = in.readLine().trimmed(); + if (line.isEmpty()) continue; + // Allow lines with comments or 'term coefficient' headings: + // We try to extract numbers from the line. + QStringList parts = line.split(QRegularExpression("[\\s,\\t]+"), Qt::SkipEmptyParts); + for (const QString &p : parts) { + bool ok = false; + double val = p.toDouble(&ok); + if (ok) coeffs.append(val); + } + } + if (coeffs.isEmpty()) return false; - m_coeffs = coeffs; - return true; + m_coeffs = coeffs; + return true; } */ // Magnus formula to estimate saturation vapour pressure (hPa) then return pa in kPa double UtciCalculator::vapourPressureFromRH(double Ta, double rh) { - // Magnus-Tetens approximation for saturation vapour pressure (hPa) - // valid roughly for -45C..+60C - // constants for water over liquid - double a = 17.27; - double b = 237.7; // °C - double es = 6.112 * qExp((a * Ta) / (Ta + b)); - double ea = es * (rh / 100.0); - return ea / 10.0; // hPa -> kPa + // Magnus-Tetens approximation for saturation vapour pressure (hPa) + // valid roughly for -45C..+60C + // constants for water over liquid + double a = 17.27; + double b = 237.7; // °C + double es = 6.112 * qExp((a * Ta) / (Ta + b)); + double ea = es * (rh / 100.0); + return ea / 10.0; // hPa -> kPa } double UtciCalculator::computeUTCI(double Ta, double va, double Tr, double rh) const { - double pa = vapourPressureFromRH(Ta, rh); - double tm = Tr - Ta; - double offset = evalOffset(Ta, va, tm, pa); - return Ta + offset; + double pa = vapourPressureFromRH(Ta, rh); + double tm = Tr - Ta; + double offset = evalOffset(Ta, va, tm, pa); + return Ta + offset; } double UtciCalculator::evalOffset(double Ta, double va, double tm, double pa) const { - if (m_coeffs.size() < 210) - return 0.0; + if (m_coeffs.size() < 210) + return 0.0; - // Pré-calcul des puissances - double Ta2 = Ta*Ta, Ta3 = Ta2*Ta, Ta4 = Ta3*Ta, Ta5 = Ta4*Ta, Ta6 = Ta5*Ta; - double va2 = va*va, va3 = va2*va, va4 = va3*va, va5 = va4*va, va6 = va5*va; - double tm2 = tm*tm, tm3 = tm2*tm, tm4 = tm3*tm, tm5 = tm4*tm, tm6 = tm5*tm; - double pa2 = pa*pa, pa3 = pa2*pa, pa4 = pa3*pa, pa5 = pa4*pa, pa6 = pa5*pa; + // Pré-calcul des puissances + double Ta2 = Ta*Ta, Ta3 = Ta2*Ta, Ta4 = Ta3*Ta, Ta5 = Ta4*Ta, Ta6 = Ta5*Ta; + double va2 = va*va, va3 = va2*va, va4 = va3*va, va5 = va4*va, va6 = va5*va; + double tm2 = tm*tm, tm3 = tm2*tm, tm4 = tm3*tm, tm5 = tm4*tm, tm6 = tm5*tm; + double pa2 = pa*pa, pa3 = pa2*pa, pa4 = pa3*pa, pa5 = pa4*pa, pa6 = pa5*pa; - QVector terms(210, 0.0); + QVector terms(210, 0.0); - // Construire les termes dans le même ordre que les coefficients ESM_3 - terms[0] = 1.0; // constante - terms[1] = Ta; - terms[2] = Ta2; - terms[3] = Ta3; - terms[4] = Ta4; - terms[5] = Ta5; - terms[6] = Ta6; + // Construire les termes dans le même ordre que les coefficients ESM_3 + terms[0] = 1.0; // constante + terms[1] = Ta; + terms[2] = Ta2; + terms[3] = Ta3; + terms[4] = Ta4; + terms[5] = Ta5; + terms[6] = Ta6; - terms[7] = va; - terms[8] = Ta*va; - terms[9] = Ta2*va; - terms[10] = Ta3*va; - terms[11] = Ta4*va; - terms[12] = Ta5*va; + terms[7] = va; + terms[8] = Ta*va; + terms[9] = Ta2*va; + terms[10] = Ta3*va; + terms[11] = Ta4*va; + terms[12] = Ta5*va; - terms[13] = va2; - terms[14] = Ta*va2; - terms[15] = Ta2*va2; - terms[16] = Ta3*va2; - terms[17] = Ta4*va2; + terms[13] = va2; + terms[14] = Ta*va2; + terms[15] = Ta2*va2; + terms[16] = Ta3*va2; + terms[17] = Ta4*va2; - terms[18] = va3; - terms[19] = Ta*va3; - terms[20] = Ta2*va3; - terms[21] = Ta3*va3; + terms[18] = va3; + terms[19] = Ta*va3; + terms[20] = Ta2*va3; + terms[21] = Ta3*va3; - terms[22] = va4; - terms[23] = Ta*va4; - terms[24] = Ta2*va4; + terms[22] = va4; + terms[23] = Ta*va4; + terms[24] = Ta2*va4; - terms[25] = va5; - terms[26] = Ta*va5; + terms[25] = va5; + terms[26] = Ta*va5; - terms[27] = va6; + terms[27] = va6; - terms[28] = tm; - terms[29] = Ta*tm; - terms[30] = Ta2*tm; - terms[31] = Ta3*tm; - terms[32] = Ta4*tm; - terms[33] = Ta5*tm; - terms[34] = Ta6*tm; + terms[28] = tm; + terms[29] = Ta*tm; + terms[30] = Ta2*tm; + terms[31] = Ta3*tm; + terms[32] = Ta4*tm; + terms[33] = Ta5*tm; + terms[34] = Ta6*tm; - terms[35] = va*tm; - terms[36] = Ta*va*tm; - terms[37] = Ta2*va*tm; - terms[38] = Ta3*va*tm; - terms[39] = Ta4*va*tm; + terms[35] = va*tm; + terms[36] = Ta*va*tm; + terms[37] = Ta2*va*tm; + terms[38] = Ta3*va*tm; + terms[39] = Ta4*va*tm; - terms[40] = va2*tm; - terms[41] = Ta*va2*tm; - terms[42] = Ta2*va2*tm; - terms[43] = Ta3*va2*tm; + terms[40] = va2*tm; + terms[41] = Ta*va2*tm; + terms[42] = Ta2*va2*tm; + terms[43] = Ta3*va2*tm; - terms[44] = va3*tm; - terms[45] = Ta*va3*tm; - terms[46] = Ta2*va3*tm; + terms[44] = va3*tm; + terms[45] = Ta*va3*tm; + terms[46] = Ta2*va3*tm; - terms[47] = va4*tm; - terms[48] = Ta*va4*tm; + terms[47] = va4*tm; + terms[48] = Ta*va4*tm; - terms[49] = va5*tm; + terms[49] = va5*tm; - // tm^2 à tm^6 - terms[50] = tm2; terms[51] = Ta*tm2; terms[52] = Ta2*tm2; terms[53] = Ta3*tm2; terms[54] = Ta4*tm2; - terms[55] = va*tm2; terms[56] = Ta*va*tm2; terms[57] = Ta2*va*tm2; terms[58] = Ta3*va*tm2; - terms[59] = va2*tm2; terms[60] = Ta*va2*tm2; terms[61] = Ta2*va2*tm2; - terms[62] = va3*tm2; - terms[63] = tm3; terms[64] = Ta*tm3; terms[65] = Ta2*tm3; - terms[66] = va*tm3; terms[67] = Ta*va*tm3; terms[68] = va2*tm3; - terms[69] = tm4; terms[70] = Ta*tm4; terms[71] = va*tm4; - terms[72] = tm5; - terms[73] = tm6; + // tm^2 à tm^6 + terms[50] = tm2; terms[51] = Ta*tm2; terms[52] = Ta2*tm2; terms[53] = Ta3*tm2; terms[54] = Ta4*tm2; + terms[55] = va*tm2; terms[56] = Ta*va*tm2; terms[57] = Ta2*va*tm2; terms[58] = Ta3*va*tm2; + terms[59] = va2*tm2; terms[60] = Ta*va2*tm2; terms[61] = Ta2*va2*tm2; + terms[62] = va3*tm2; + terms[63] = tm3; terms[64] = Ta*tm3; terms[65] = Ta2*tm3; + terms[66] = va*tm3; terms[67] = Ta*va*tm3; terms[68] = va2*tm3; + terms[69] = tm4; terms[70] = Ta*tm4; terms[71] = va*tm4; + terms[72] = tm5; + terms[73] = tm6; - // pa et combinaisons - terms[74] = pa; terms[75] = Ta*pa; terms[76] = Ta2*pa; terms[77] = Ta3*pa; terms[78] = Ta4*pa; terms[79] = Ta5*pa; - terms[80] = va*pa; terms[81] = Ta*va*pa; terms[82] = Ta2*va*pa; terms[83] = Ta3*va*pa; - terms[84] = va2*pa; terms[85] = Ta*va2*pa; terms[86] = Ta2*va2*pa; - terms[87] = va3*pa; terms[88] = Ta*va3*pa; - terms[89] = va4*pa; + // pa et combinaisons + terms[74] = pa; terms[75] = Ta*pa; terms[76] = Ta2*pa; terms[77] = Ta3*pa; terms[78] = Ta4*pa; terms[79] = Ta5*pa; + terms[80] = va*pa; terms[81] = Ta*va*pa; terms[82] = Ta2*va*pa; terms[83] = Ta3*va*pa; + terms[84] = va2*pa; terms[85] = Ta*va2*pa; terms[86] = Ta2*va2*pa; + terms[87] = va3*pa; terms[88] = Ta*va3*pa; + terms[89] = va4*pa; - terms[90] = pa2; terms[91] = Ta*pa2; terms[92] = Ta2*pa2; + terms[90] = pa2; terms[91] = Ta*pa2; terms[92] = Ta2*pa2; - // Remplir le reste avec 0.0 pour simplifier (les 210 coefficients réels peuvent être affectés directement) - for (int i = 93; i < 210; ++i) terms[i] = 0.0; + // Remplir le reste avec 0.0 pour simplifier (les 210 coefficients réels peuvent être affectés directement) + for (int i = 93; i < 210; ++i) terms[i] = 0.0; - // Calcul de l'offset - double offset = 0.0; - for (int i = 0; i < 210; ++i) - offset += m_coeffs[i] * terms[i]; + // Calcul de l'offset + double offset = 0.0; + for (int i = 0; i < 210; ++i) + offset += m_coeffs[i] * terms[i]; - return offset; + return offset; } void UtciCalculator::initCoefficients() { - // Coefficients ESM_3 (exemple simplifié, à remplacer par la liste complète 210 valeurs) - m_coeffs = { - 6.07562052E-01, -2.27712343E-02, 8.06470249E-04, -1.54271372E-04, -3.24651735E-06, 7.32602852E-08, 1.35959073E-09, -2.25836520E+00, 8.80326035E-02, 2.16844454E-03, -1.53347087E-05, -5.72983704E-07, -2.55090145E-09, -7.51269505E-01, -4.08350271E-03, -5.21670675E-05, 1.94544667E-06, 1.14099531E-08, 1.58137256E-01, -6.57263143E-05, 2.22697524E-07, -4.16117031E-08, -1.27762753E-02, 9.66891875E-06, 2.52785852E-09, 4.56306672E-04, -1.74202546E-07, -5.91491269E-06, 3.98374029E-01, 1.83945314E-04, -1.73754510E-04, -7.60781159E-07, 3.77830287E-08, 5.43079673E-10, -2.00518269E-02, 8.92859837E-04, 3.45433048E-06, -3.77925774E-07, -1.69699377E-09, 1.69992415E-04, -4.99204314E-05, 2.47417178E-07, 1.07596466E-08, 8.49242932E-05, 1.35191328E-06, -6.21531254E-09, -4.99410301E-06, -1.89489258E-08, 8.15300114E-08, 7.55043090E-04, -3.69476348E-02, 1.62325322E-03, -3.14279680E-05, 2.59835559E-06, -4.77136523E-08, 8.64203390E-03, -6.87405181E-04, -9.13863872E-06, 5.15916806E-07, -3.59217476E-05, 3.28696511E-05, -7.10542454E-07, -1.24382300E-05, -7.38584400E-09, 2.20609296E-07, -7.32469180E-04, -1.87381964E-05, 4.80925239E-06, -8.75492040E-08, 2.77862930E-05, -5.06004592E-06, 1.14325367E-07, 2.53016723E-06, -1.72857035E-08, -3.95079398E-08, -3.59413173E-07, 7.04388046E-07, -1.89309167E-08, -4.79768731E-07, 7.96079978E-09, 1.62897058E-09, 3.94367674E-08, -1.18566247E-09, 3.34678041E-10, -1.15606447E-10, -2.80626406E+00, 5.48712484E-01, -3.99428410E-03, -9.54009191E-04, 1.93090978E-05, -3.08806365E-01, 1.16952364E-02, 4.95271903E-04, -1.90710882E-05, 2.10787756E-03, -6.98445738E-04, 2.30109073E-05, 4.17856590E-04, -1.27043871E-05, -3.04620472E-06, -5.65095215E-05, -4.52166564E-07, 2.46688878E-08, 2.42674348E-10, 1.54547250E-04, 5.24110970E-06, -8.75874982E-08, -1.50743064E-09, -1.56236307E-05, -1.33895614E-07, 2.49709824E-09, 6.51711721E-07, 1.94960053E-09, -1.00361113E-08, -1.21206673E-05, -2.18203660E-07, 7.51269482E-09, 9.79063848E-11, 1.25006734E-06, -1.81584736E-09, -3.52197671E-10, -3.36514630E-08, 1.35908359E-10, 4.17032620E-10, -1.30369025E-09, 4.13908461E-10, 9.22652254E-12, -5.08220384E-09, -2.24730961E-11, 1.17139133E-10, 6.62154879E-10, 4.03863260E-13, 1.95087203E-12, -4.73602469E-12, 5.12733497E+00, -3.12788561E-01, -1.96701861E-02, 9.99690870E-04, 9.51738512E-06, -4.66426341E-07, 5.48050612E-01, -3.30552823E-03, -1.64119440E-03, -5.16670694E-06, 9.52692432E-07, -4.29223622E-02, 5.00845667E-03, 1.00601257E-06, -1.81748644E-06, -1.25813502E-03, -1.79330391E-04, 2.34994441E-06, 1.29735808E-04, 1.29064870E-06, -2.28558686E-06, 5.14507424E-02, -4.32510997E-03, 8.99281156E-05, -7.14663943E-07, -2.66016305E-04, 2.63789586E-04, -7.01199003E-06, -1.06823306E-04, 3.61341136E-06, 2.29748967E-07, 3.04788893E-04, -6.42070836E-05, 1.16257971E-06, 7.68023384E-06, -5.47446896E-07, -3.59937910E-08, -4.36497725E-06, 1.68737969E-07, 2.67489271E-08, 3.23926897E-09, -3.53874123E-02, -2.21201190E-01, 1.55126038E-02, -2.63917279E-04, 4.53433455E-02, -4.32943862E-03, 1.45389826E-04, 2.17508610E-04, -6.66724702E-05, 3.33217140E-05, -2.26921615E-03, 3.80261982E-04, -5.45314314E-09, -7.96355448E-04, 2.53458034E-05, -6.31223658E-06, 3.02122035E-04, -4.77403547E-06, 1.73825715E-06, -4.09087898E-07, 6.14155345E-01, -6.16755931E-02, 1.33374846E-03, 3.55375387E-03, -5.13027851E-04, 1.02449757E-04, -1.48526421E-03, -4.11469183E-05, -6.80434415E-06, -9.77675906E-06, 8.82773108E-02, -3.01859306E-03, 1.04452989E-03, 2.47090539E-04, 1.48348065E-03 - }; + // Coefficients ESM_3 (exemple simplifié, à remplacer par la liste complète 210 valeurs) + m_coeffs = { + 6.07562052E-01, -2.27712343E-02, 8.06470249E-04, -1.54271372E-04, -3.24651735E-06, 7.32602852E-08, 1.35959073E-09, -2.25836520E+00, 8.80326035E-02, 2.16844454E-03, -1.53347087E-05, -5.72983704E-07, -2.55090145E-09, -7.51269505E-01, -4.08350271E-03, -5.21670675E-05, 1.94544667E-06, 1.14099531E-08, 1.58137256E-01, -6.57263143E-05, 2.22697524E-07, -4.16117031E-08, -1.27762753E-02, 9.66891875E-06, 2.52785852E-09, 4.56306672E-04, -1.74202546E-07, -5.91491269E-06, 3.98374029E-01, 1.83945314E-04, -1.73754510E-04, -7.60781159E-07, 3.77830287E-08, 5.43079673E-10, -2.00518269E-02, 8.92859837E-04, 3.45433048E-06, -3.77925774E-07, -1.69699377E-09, 1.69992415E-04, -4.99204314E-05, 2.47417178E-07, 1.07596466E-08, 8.49242932E-05, 1.35191328E-06, -6.21531254E-09, -4.99410301E-06, -1.89489258E-08, 8.15300114E-08, 7.55043090E-04, -3.69476348E-02, 1.62325322E-03, -3.14279680E-05, 2.59835559E-06, -4.77136523E-08, 8.64203390E-03, -6.87405181E-04, -9.13863872E-06, 5.15916806E-07, -3.59217476E-05, 3.28696511E-05, -7.10542454E-07, -1.24382300E-05, -7.38584400E-09, 2.20609296E-07, -7.32469180E-04, -1.87381964E-05, 4.80925239E-06, -8.75492040E-08, 2.77862930E-05, -5.06004592E-06, 1.14325367E-07, 2.53016723E-06, -1.72857035E-08, -3.95079398E-08, -3.59413173E-07, 7.04388046E-07, -1.89309167E-08, -4.79768731E-07, 7.96079978E-09, 1.62897058E-09, 3.94367674E-08, -1.18566247E-09, 3.34678041E-10, -1.15606447E-10, -2.80626406E+00, 5.48712484E-01, -3.99428410E-03, -9.54009191E-04, 1.93090978E-05, -3.08806365E-01, 1.16952364E-02, 4.95271903E-04, -1.90710882E-05, 2.10787756E-03, -6.98445738E-04, 2.30109073E-05, 4.17856590E-04, -1.27043871E-05, -3.04620472E-06, -5.65095215E-05, -4.52166564E-07, 2.46688878E-08, 2.42674348E-10, 1.54547250E-04, 5.24110970E-06, -8.75874982E-08, -1.50743064E-09, -1.56236307E-05, -1.33895614E-07, 2.49709824E-09, 6.51711721E-07, 1.94960053E-09, -1.00361113E-08, -1.21206673E-05, -2.18203660E-07, 7.51269482E-09, 9.79063848E-11, 1.25006734E-06, -1.81584736E-09, -3.52197671E-10, -3.36514630E-08, 1.35908359E-10, 4.17032620E-10, -1.30369025E-09, 4.13908461E-10, 9.22652254E-12, -5.08220384E-09, -2.24730961E-11, 1.17139133E-10, 6.62154879E-10, 4.03863260E-13, 1.95087203E-12, -4.73602469E-12, 5.12733497E+00, -3.12788561E-01, -1.96701861E-02, 9.99690870E-04, 9.51738512E-06, -4.66426341E-07, 5.48050612E-01, -3.30552823E-03, -1.64119440E-03, -5.16670694E-06, 9.52692432E-07, -4.29223622E-02, 5.00845667E-03, 1.00601257E-06, -1.81748644E-06, -1.25813502E-03, -1.79330391E-04, 2.34994441E-06, 1.29735808E-04, 1.29064870E-06, -2.28558686E-06, 5.14507424E-02, -4.32510997E-03, 8.99281156E-05, -7.14663943E-07, -2.66016305E-04, 2.63789586E-04, -7.01199003E-06, -1.06823306E-04, 3.61341136E-06, 2.29748967E-07, 3.04788893E-04, -6.42070836E-05, 1.16257971E-06, 7.68023384E-06, -5.47446896E-07, -3.59937910E-08, -4.36497725E-06, 1.68737969E-07, 2.67489271E-08, 3.23926897E-09, -3.53874123E-02, -2.21201190E-01, 1.55126038E-02, -2.63917279E-04, 4.53433455E-02, -4.32943862E-03, 1.45389826E-04, 2.17508610E-04, -6.66724702E-05, 3.33217140E-05, -2.26921615E-03, 3.80261982E-04, -5.45314314E-09, -7.96355448E-04, 2.53458034E-05, -6.31223658E-06, 3.02122035E-04, -4.77403547E-06, 1.73825715E-06, -4.09087898E-07, 6.14155345E-01, -6.16755931E-02, 1.33374846E-03, 3.55375387E-03, -5.13027851E-04, 1.02449757E-04, -1.48526421E-03, -4.11469183E-05, -6.80434415E-06, -9.77675906E-06, 8.82773108E-02, -3.01859306E-03, 1.04452989E-03, 2.47090539E-04, 1.48348065E-03 + }; } From 5260442aecbc0ae4809f19d5b9af3adaddd02ac6 Mon Sep 17 00:00:00 2001 From: Daniel TARTAVEL Date: Sat, 4 Apr 2026 13:33:02 +0200 Subject: [PATCH 04/10] disabled debugging messages --- src/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 04a9a09..c7665c7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -26,7 +26,7 @@ #define BROKER_ADDRESS "localhost" #define MQTT_PORT 1883; -uint debugLevel = INFO | NOTICE | INFO | WARNING | ERROR | ALERT; +uint debugLevel = ERROR | ALERT; QByteArray toFollow; //class MqttClient; @@ -61,7 +61,7 @@ int main(int argc, char *argv[]) //declaration of debug level pws2mqtt = new Pws2mqtt; - baro = new BarometerTrend; + baro = new BarometerTrend; pws2mqtt->listeningHttp(); @@ -108,7 +108,7 @@ void debug(QString debugHeader, QString msg, uint8_t level, QByteArray property) if ((debugLevel & level) == 4) { qInfo("%s%s WARNING: %s%s", debugHeader.toStdString().c_str(), ORANGE, msg.toStdString().c_str(), NORMAL); - notify (debugHeader + " - " + msg); + notify (debugHeader + " - " + msg); } if ((debugLevel & level) == 8) { From 0d353b4d61c494312067701061bce6d08c64c8fa Mon Sep 17 00:00:00 2001 From: Daniel TARTAVEL Date: Sat, 4 Apr 2026 22:43:59 +0200 Subject: [PATCH 05/10] curl code replaced by qt code --- pws2mqtt-qt.pro | 20 ++++++------- src/main.cpp | 24 ++++++++-------- src/pws2mqtt.cpp | 73 +++++++++++++++++++++++++++++++++++++----------- src/pws2mqtt.h | 2 +- 4 files changed, 79 insertions(+), 40 deletions(-) diff --git a/pws2mqtt-qt.pro b/pws2mqtt-qt.pro index 5f83235..5e5d34b 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 += \ - src/main.cpp \ - src/mqtt.cpp \ - src/pws2mqtt.cpp \ - src/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,10 +25,10 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target HEADERS += \ - src/barometertrend.h \ - src/httpserver.h \ - src/mqtt.h \ - src/pws2mqtt.h \ - src/utcicalculator.h \ - src/version.h +src/barometertrend.h \ +src/httpserver.h \ +# src/mqtt.h \ +src/pws2mqtt.h \ + src/utcicalculator.h \ + src/version.h diff --git a/src/main.cpp b/src/main.cpp index c7665c7..43e6adf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,14 +7,14 @@ #include #include #include -#include -#include -#include -#include +//#include +//#include +//#include +//#include #include #include #include "pws2mqtt.h" -#include "mqtt.h" +//#include "mqtt.h" #include "src/barometertrend.h" #include "version.h" #include @@ -23,8 +23,8 @@ #include #define CLIENT_ID "Client_ID" -#define BROKER_ADDRESS "localhost" -#define MQTT_PORT 1883; +//#define BROKER_ADDRESS "localhost" +//#define MQTT_PORT 1883; uint debugLevel = ERROR | ALERT; QByteArray toFollow; @@ -35,7 +35,7 @@ using namespace std; //Configuration config; Pws2mqtt *pws2mqtt; -MqttClient *mqttClient; +//MqttClient *mqttClient; QHttpServer *httpServer; BarometerTrend *baro; @@ -51,11 +51,11 @@ int main(int argc, char *argv[]) exit(0); } } - // Enable logging to journald + // Enable logging to ••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••journald qputenv("QT_FORCE_STDERR_LOGGING", QByteArray("0")); debug(DEBUGMACRO, "declaration of mqttClient", DEBUG); - mqttClient = new MqttClient; + //mqttClient = new MqttClient; httpServer = new QHttpServer; @@ -70,8 +70,8 @@ int main(int argc, char *argv[]) //notify (QString("Program started"), "default"); a.exec(); - mqttClient->qmqttClient->unsubscribe(mqttClient->topic); - mqttClient->qmqttClient->disconnectFromHost(); + //mqttClient->qmqttClient->unsubscribe(mqttClient->topic); + //mqttClient->qmqttClient->disconnectFromHost(); debug(DEBUGMACRO, "exiting", DEBUG); notify ("Program exiting \n", "high"); //Closing http server diff --git a/src/pws2mqtt.cpp b/src/pws2mqtt.cpp index abd670e..5cbdc99 100644 --- a/src/pws2mqtt.cpp +++ b/src/pws2mqtt.cpp @@ -1,25 +1,27 @@ #include "pws2mqtt.h" #include "barometertrend.h" -#include "mqtt.h" +//#include "mqtt.h" //#include "httpserver.h" #include -#include +//#include #include #include #include -#include -#include +//#include +//#include #include #include #include #include #include #include -#include +//#include #include #include "utcicalculator.h" +#include +#include -extern MqttClient *mqttClient; +//extern MqttClient *mqttClient; extern Pws2mqtt *pws2mqtt; extern QHttpServer *httpServer; extern BarometerTrend *baro; @@ -119,13 +121,21 @@ void Pws2mqtt::init() }else { debug(DEBUGMACRO, "Request query :" + request.query().toString() , DEBUG); - this->parseData(queryList); + QMetaObject::invokeMethod(this, [this, query = request.query()]() { + this->parseData(query.queryItems()); + }, Qt::QueuedConnection); + //QThreadPool::globalInstance()->start([this, query = request.query()]() { + // this->parseData(query.queryItems()); + //}); + //this->parseData(queryList); debug(DEBUGMACRO, "Returning 'success'", DEBUG); } //mqttClient.send_message(jsonString); + return QHttpServerResponse("text/plain", "Requête traitée en arrière-plan\n"); - return QHttpServerResponse("text/plain", "Success\n"); + //return QHttpServerResponse("text/plain", "Success\n"); }); + for (auto [name, pair]: propertyName.asKeyValueRange()) { propertyList[name].append(formatNotifString(pair.first, pair.second, "0")); @@ -133,6 +143,35 @@ void Pws2mqtt::init() } } +void notify(QString notif, QString priority, QString inputPath, QString tag) +{ + QNetworkAccessManager *manager = new QNetworkAccessManager(pws2mqtt); + QNetworkRequest request(QUrl("http://localhost:81/Meteo")); + request.setRawHeader("Content-Type", "charset=UTF-8; text/markdown"); + if (!tag.isEmpty()) + { + request.setRawHeader("Tags", tag.toUtf8()); + } + request.setRawHeader("Title", "Vidéo"); + request.setRawHeader("Priority", priority.toUtf8()); + request.setRawHeader("Markdown", "yes"); + request.setRawHeader("Config", "/etc/ntfy.client.yml"); + request.setRawHeader("Firebase", "no"); + + + QNetworkReply *reply = manager->post(request, notif.toUtf8()); + QObject::connect(reply, &QNetworkReply::finished, [reply, &manager]() { + if (reply->error() != QNetworkReply::NoError) { + debug(DEBUGMACRO, "Erreur réseau : " + reply->errorString(), ERROR); + } else { + debug(DEBUGMACRO, "Notification envoyée", DEBUG); + } + reply->deleteLater(); + manager->deleteLater(); + }); +} + + void Pws2mqtt::listeningHttp() { //QByteArray data; @@ -150,7 +189,7 @@ void Pws2mqtt::parseData(QList> queryList) debug(DEBUGMACRO, "Parsing Datas", DEBUG); QString jsonString = "{"; - QString deviceString = "\"device\": {\"ieeeAddress\": \"" + mqttClient->macAddress + "\", \"type\": \"" + mqttClient->type + "\", \"powerSource\": \"Battery\""; + //QString deviceString = "\"device\": {\"ieeeAddress\": \"" + mqttClient->macAddress + "\", \"type\": \"" + mqttClient->type + "\", \"powerSource\": \"Battery\""; QString notif = ""; QStringList priorityList {"", "min", "low", "default", "High", "urgent"}; QString attachment = ""; @@ -177,12 +216,12 @@ void Pws2mqtt::parseData(QList> queryList) if(deviceFlag == false) { deviceFlag = true; - }else + }/*else { deviceString.append(", "); } deviceString += "\"" + name + "\": "; - deviceString += pair.second; + deviceString += pair.second;*/ }else { if(propertyFlag == false) @@ -377,7 +416,7 @@ void Pws2mqtt::parseData(QList> queryList) //windChill(propertiesValue["tempf"], propertiesValue["vent"]); //calculerHumidex(propertiesValue["tempf"], propertiesValue["humidity"]); - if (!jsonString.isEmpty()) + /*if (!jsonString.isEmpty()) { debug(DEBUGMACRO, "json string : " + jsonString, DEBUG); jsonString = jsonString +", " + deviceString + "}}"; @@ -385,7 +424,7 @@ void Pws2mqtt::parseData(QList> queryList) }else { debug(DEBUGMACRO, "No values to send", DEBUG); - } + }*/ debug(DEBUGMACRO, "current datetime : " + QDateTime::currentDateTime().toString() + ", timer = " + timer.toString(), DEBUG); @@ -531,7 +570,7 @@ QString formatNotifString (QString name, QString unit ,QByteArray value) return text += "\n"; } -static size_t ReadFile(void *ptr, size_t size, size_t nmemb, void *stream) { +/*static size_t ReadFile(void *ptr, size_t size, size_t nmemb, void *stream) { FILE *f = (FILE *)stream; size_t n = fread(ptr, size, nmemb, f); return n; @@ -544,8 +583,8 @@ static size_t WriteCallback(void *contents, size_t size, size_t nmemb, std::stri output->append((char*)contents, total_size); return total_size; } - -void notify(QString notif, QString priority, QString inputPath, QString tag) +*/ +/*void notify(QString notif, QString priority, QString inputPath, QString tag) { CURL *curl; CURLcode res; @@ -667,7 +706,7 @@ void notify(QString notif, QString priority, QString inputPath, QString tag) curl_global_cleanup(); } } - +*/ void rotateAndSaveImage(const QString &inputPath, const QString &outputPath, qreal angle) { QImage image(inputPath); diff --git a/src/pws2mqtt.h b/src/pws2mqtt.h index dc05356..59bfd12 100644 --- a/src/pws2mqtt.h +++ b/src/pws2mqtt.h @@ -56,7 +56,6 @@ double tohPa(double value); bool compare (double value=0, double testValue=0, double ecart = 0.5); QString formatNotifString (QString name, QString unit, QByteArray value=""); double mphTokmh (double value); -void notify (QString notif, QString priority = "low", QString inputPath = "", QString tag = ""); quint8 setPriority (quint8 currentPriority, quint8 newPriority); QString previsionMeteo(double currentPressure, double variation3h, quint8 &priority); QString pressureVariation(double currentPressure, quint8 &priority); @@ -64,4 +63,5 @@ QString getPluviosite(double value, quint8 &priority); void rotateAndSaveImage(const QString &inputPath, const QString &outputPath, qreal angle=0); double windChill(double airT, double vent); double calculerHumidex(double temperature, double humiditeRelative); +void notify (QString notif, QString priority = "low", QString inputPath = "", QString tag = ""); From ada4d7ed99321acd57b6eef480433e7bf98bfa4f Mon Sep 17 00:00:00 2001 From: Daniel TARTAVEL Date: Sat, 4 Apr 2026 22:54:01 +0200 Subject: [PATCH 06/10] nettoyage --- src/pws2mqtt.cpp | 140 ----------------------------------------------- 1 file changed, 140 deletions(-) diff --git a/src/pws2mqtt.cpp b/src/pws2mqtt.cpp index 5cbdc99..5988fb3 100644 --- a/src/pws2mqtt.cpp +++ b/src/pws2mqtt.cpp @@ -124,10 +124,6 @@ void Pws2mqtt::init() QMetaObject::invokeMethod(this, [this, query = request.query()]() { this->parseData(query.queryItems()); }, Qt::QueuedConnection); - //QThreadPool::globalInstance()->start([this, query = request.query()]() { - // this->parseData(query.queryItems()); - //}); - //this->parseData(queryList); debug(DEBUGMACRO, "Returning 'success'", DEBUG); } //mqttClient.send_message(jsonString); @@ -570,143 +566,7 @@ QString formatNotifString (QString name, QString unit ,QByteArray value) return text += "\n"; } -/*static size_t ReadFile(void *ptr, size_t size, size_t nmemb, void *stream) { - FILE *f = (FILE *)stream; - size_t n = fread(ptr, size, nmemb, f); - return n; -} -// Callback for curl library -static size_t WriteCallback(void *contents, size_t size, size_t nmemb, std::string *output) -{ - size_t total_size = size * nmemb; - output->append((char*)contents, total_size); - return total_size; -} -*/ -/*void notify(QString notif, QString priority, QString inputPath, QString tag) -{ - CURL *curl; - CURLcode res; - std::string readBuffer; - - priority = "Priority: " + priority; - debug (DEBUGMACRO, "notifying at priority " + priority + "with tag : " + tag + " - message : " + notif, DEBUG); - - // Initialise libcurl - curl_global_init(CURL_GLOBAL_DEFAULT); - curl = curl_easy_init(); - if (curl) - { - // Définis les en-têtes pour le titre et les priorités - struct curl_slist *headers = NULL; - - notif.replace("\\", "\\\\\\'"); // Échappe les apostrophes - - if (!tag.isEmpty()) - { - headers = curl_slist_append(headers, ("Tags: " + tag).toStdString().c_str()); - } - headers = curl_slist_append(headers, "Title: Météo"); - headers = curl_slist_append(headers, priority.toStdString().c_str()); - headers = curl_slist_append(headers, "Markdown: yes"); -// headers = curl_slist_append(headers, "Config: /etc/ntfy.client.yml"); - headers = curl_slist_append(headers, "Firebase: no"); -// headers = curl_slist_append(headers, "Content-Type: charset=UTF-8; text/markdown"); // Ajout de l'encodage - - struct curl_slist *h = headers; - while (h) { - debug(DEBUGMACRO, "Header: " + QString(h->data), DEBUG); - h = h->next; - } - debug(DEBUGMACRO, "Notif: " + notif, DEBUG); - - // Configure la requête POST - curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:81/Meteo"); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, notif.toUtf8().constData()); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); - - // Exécute la requête - - res = curl_easy_perform(curl); - - // Vérifie les erreurs - if (res != CURLE_OK) - { - debug(DEBUGMACRO, "Erreur libcurl :" + QString(curl_easy_strerror(res)), DEBUG); - } else - { - debug(DEBUGMACRO, "Réponse du serveur: " + QString::fromStdString(readBuffer), DEBUG); - } - - // Nettoie les ressources - //curl_mime_free(mime); - curl_slist_free_all(headers); - curl_easy_cleanup(curl); - } - // Nettoie libcurl - curl_global_cleanup(); - - if (!inputPath.isEmpty()) - { - FILE *fd = fopen(inputPath.toStdString().c_str(), "rb"); - - if (!fd) { - perror("Erreur lors de l'ouverture du fichier"); - return; - } - // Initialise libcurl - curl_global_init(CURL_GLOBAL_DEFAULT); - curl = curl_easy_init(); - if (curl) - { - // Définis les en-têtes pour le titre et les priorités - struct curl_slist *headers = NULL; - headers = curl_slist_append(headers, "Title: Météo"); - headers = curl_slist_append(headers, priority.toStdString().c_str()); -// headers = curl_slist_append(headers, "Config: /etc/ntfy.client.yml"); - headers = curl_slist_append(headers, "Firebase: no"); - headers = curl_slist_append(headers, "Content-Type: image/png"); - headers = curl_slist_append(headers, "X-Original-Size: true"); - headers = curl_slist_append(headers, "X-Filename: fleche.png"); - - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); // Configurer l'URL - curl_easy_setopt(curl, CURLOPT_URL, "localhost:81/Meteo"); - - // Utiliser la méthode PUT (comme `curl -T`) - curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); - - // Lire le fichier et l'envoyer en tant que body - curl_easy_setopt(curl, CURLOPT_READFUNCTION, ReadFile); - curl_easy_setopt(curl, CURLOPT_READDATA, fd); - - // Définir la taille du fichier (optionnel mais recommandé) - struct stat file_info; - fstat(fileno(fd), &file_info); - curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file_info.st_size); - - // Exécuter la requête - res = curl_easy_perform(curl); - // Vérifie les erreurs - if (res != CURLE_OK) - { - debug(DEBUGMACRO, "Erreur libcurl :" + QString(curl_easy_strerror(res)), DEBUG); - } else - { - debug(DEBUGMACRO, "Notification envoyée avec succès", DEBUG); - } - // Nettoyer - fclose(fd); - curl_easy_cleanup(curl); - } - // Nettoie libcurl - curl_global_cleanup(); - } -} -*/ void rotateAndSaveImage(const QString &inputPath, const QString &outputPath, qreal angle) { QImage image(inputPath); From d4a6942ec4ceb18561594c3bac7e80a1682c33f9 Mon Sep 17 00:00:00 2001 From: Daniel TARTAVEL Date: Sun, 5 Apr 2026 14:23:08 +0200 Subject: [PATCH 07/10] move mqtt in compilation's option --- src/main.cpp | 64 ++++++++++++++++-------------------------- src/pws2mqtt.cpp | 43 ++++++++++++++++------------ src/utcicalculator.cpp | 27 ------------------ 3 files changed, 49 insertions(+), 85 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 43e6adf..9c52c04 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,41 +1,42 @@ #include #include -//#include #include #include #include #include #include #include -//#include -//#include -//#include -//#include #include #include #include "pws2mqtt.h" -//#include "mqtt.h" +#ifdef WITH_MQTT + #include "mqtt.h" +#endif #include "src/barometertrend.h" #include "version.h" -#include #include #include #include - +#ifdef WITH_MQTT + #include + #include + #include + #include +#endif #define CLIENT_ID "Client_ID" -//#define BROKER_ADDRESS "localhost" -//#define MQTT_PORT 1883; -uint debugLevel = ERROR | ALERT; +uint debugLevel = INFO | ERROR | ALERT; QByteArray toFollow; -//class MqttClient; +#ifdef WITH_MQTT + class MqttClient; + MqttClient *mqttClient; +#endif using namespace std; //Configuration config; Pws2mqtt *pws2mqtt; -//MqttClient *mqttClient; QHttpServer *httpServer; BarometerTrend *baro; @@ -51,12 +52,13 @@ int main(int argc, char *argv[]) exit(0); } } - // Enable logging to ••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••journald + // Enable logging to journald qputenv("QT_FORCE_STDERR_LOGGING", QByteArray("0")); - debug(DEBUGMACRO, "declaration of mqttClient", DEBUG); - //mqttClient = new MqttClient; - + debug(DEBUGMACRO, "declaration of mqttClient", INFO); +#ifdef WITH_MQTT + mqttClient = new MqttClient; +#endif httpServer = new QHttpServer; //declaration of debug level @@ -65,34 +67,16 @@ int main(int argc, char *argv[]) pws2mqtt->listeningHttp(); - - - //notify (QString("Program started"), "default"); a.exec(); - //mqttClient->qmqttClient->unsubscribe(mqttClient->topic); - //mqttClient->qmqttClient->disconnectFromHost(); - debug(DEBUGMACRO, "exiting", DEBUG); +#ifdef WITH_MQTT + mqttClient->qmqttClient->unsubscribe(mqttClient->topic); + mqttClient->qmqttClient->disconnectFromHost(); +#endif + debug(DEBUGMACRO, "exiting", INFO); notify ("Program exiting \n", "high"); - //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) { diff --git a/src/pws2mqtt.cpp b/src/pws2mqtt.cpp index 5988fb3..5c69c8e 100644 --- a/src/pws2mqtt.cpp +++ b/src/pws2mqtt.cpp @@ -1,27 +1,24 @@ #include "pws2mqtt.h" #include "barometertrend.h" -//#include "mqtt.h" -//#include "httpserver.h" #include -//#include #include #include #include -//#include -//#include #include #include #include #include #include #include -//#include #include #include "utcicalculator.h" #include #include +#ifdef WITH_MQTT + #include "mqtt.h" + /extern MqttClient *mqttClient; +#endif -//extern MqttClient *mqttClient; extern Pws2mqtt *pws2mqtt; extern QHttpServer *httpServer; extern BarometerTrend *baro; @@ -57,7 +54,7 @@ QMap > propertyName {"dailyrainin", {"Pluie de la journée", " mm"}}, // {"monthlyrainin", {"Pluie du mois", " mm"}}, // {"yearlyrainin", {"Pluie de l'année", " mm"}}, -// {"solarradiation", {"Énergie solaire", " W/m²"}}, + {"solarradiation", {"Énergie solaire", " W/m²"}}, // {"indoortempf", {"Température intérieure", "°C"}}, // {"indoorhumidity", {"Humidité intérieure", "%"}}, {"baromin", {"Pression atmosphérique", " hPa"}}, @@ -93,7 +90,7 @@ Pws2mqtt::~Pws2mqtt() void Pws2mqtt::init() { - debug(DEBUGMACRO, "init http server", DEBUG); + debug(DEBUGMACRO, "init http server", INFO); httpServer->setMissingHandler([](const QHttpServerRequest &request, QHttpServerResponder &&responder) { (void) responder; @@ -141,6 +138,7 @@ void Pws2mqtt::init() void notify(QString notif, QString priority, QString inputPath, QString tag) { + (void) inputPath; QNetworkAccessManager *manager = new QNetworkAccessManager(pws2mqtt); QNetworkRequest request(QUrl("http://localhost:81/Meteo")); request.setRawHeader("Content-Type", "charset=UTF-8; text/markdown"); @@ -148,7 +146,7 @@ void notify(QString notif, QString priority, QString inputPath, QString tag) { request.setRawHeader("Tags", tag.toUtf8()); } - request.setRawHeader("Title", "Vidéo"); + request.setRawHeader("Title", "Météo"); request.setRawHeader("Priority", priority.toUtf8()); request.setRawHeader("Markdown", "yes"); request.setRawHeader("Config", "/etc/ntfy.client.yml"); @@ -177,15 +175,17 @@ void Pws2mqtt::listeningHttp() { debug(DEBUGMACRO, "Http Server failed to listen on a port.", ERROR); } - debug(DEBUGMACRO, "Listening on port " + QString::number(port)); + debug(DEBUGMACRO, "Listening on port " + QString::number(port), INFO); } void Pws2mqtt::parseData(QList> queryList) { debug(DEBUGMACRO, "Parsing Datas", DEBUG); +#ifdef WITH_MQTT QString jsonString = "{"; - //QString deviceString = "\"device\": {\"ieeeAddress\": \"" + mqttClient->macAddress + "\", \"type\": \"" + mqttClient->type + "\", \"powerSource\": \"Battery\""; + QString deviceString = "\"device\": {\"ieeeAddress\": \"" + mqttClient->macAddress + "\", \"type\": \"" + mqttClient->type + "\", \"powerSource\": \"Battery\""; +#endif QString notif = ""; QStringList priorityList {"", "min", "low", "default", "High", "urgent"}; QString attachment = ""; @@ -212,24 +212,29 @@ void Pws2mqtt::parseData(QList> queryList) if(deviceFlag == false) { deviceFlag = true; - }/*else + } +#ifdef WITH_MQTT + else { deviceString.append(", "); } deviceString += "\"" + name + "\": "; - deviceString += pair.second;*/ + deviceString += pair.second; +#endif }else { if(propertyFlag == false) { propertyFlag = true; - }else + } +#ifdef WITH_MQTT + else { jsonString.append(", "); } jsonString.append("\"" + name + "\": "); jsonString.append(pair.second); - +#endif if (name == "tempf") { static QDateTime timeTemp = QDateTime::currentDateTime().addSecs(-600); @@ -412,7 +417,8 @@ void Pws2mqtt::parseData(QList> queryList) //windChill(propertiesValue["tempf"], propertiesValue["vent"]); //calculerHumidex(propertiesValue["tempf"], propertiesValue["humidity"]); - /*if (!jsonString.isEmpty()) +#ifdef WITH_MQTT + if (!jsonString.isEmpty()) { debug(DEBUGMACRO, "json string : " + jsonString, DEBUG); jsonString = jsonString +", " + deviceString + "}}"; @@ -420,7 +426,8 @@ void Pws2mqtt::parseData(QList> queryList) }else { debug(DEBUGMACRO, "No values to send", DEBUG); - }*/ + } +#endif debug(DEBUGMACRO, "current datetime : " + QDateTime::currentDateTime().toString() + ", timer = " + timer.toString(), DEBUG); diff --git a/src/utcicalculator.cpp b/src/utcicalculator.cpp index ec2c923..aad1ff7 100644 --- a/src/utcicalculator.cpp +++ b/src/utcicalculator.cpp @@ -12,33 +12,6 @@ UtciCalculator::UtciCalculator(QObject *parent) /*// Loads coefficients from a simple text file containing one coefficient per line or tab-separated. // The expected file is the ESM_3 coefficients table exported to a plain text file where the coefficients // appear in the same order as in the official table (210 coefficients). -bool UtciCalculator::loadCoefficientsFromFile(const QString &path) -{ - QFile f(path); - if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) - return false; - - QTextStream in(&f); - QVector coeffs; - coeffs.reserve(300); - - while (!in.atEnd()) { - QString line = in.readLine().trimmed(); - if (line.isEmpty()) continue; - // Allow lines with comments or 'term coefficient' headings: - // We try to extract numbers from the line. - QStringList parts = line.split(QRegularExpression("[\\s,\\t]+"), Qt::SkipEmptyParts); - for (const QString &p : parts) { - bool ok = false; - double val = p.toDouble(&ok); - if (ok) coeffs.append(val); - } - } - if (coeffs.isEmpty()) return false; - - m_coeffs = coeffs; - return true; -} */ // Magnus formula to estimate saturation vapour pressure (hPa) then return pa in kPa double UtciCalculator::vapourPressureFromRH(double Ta, double rh) From 60327e11de1758de92e163c3febdd99e7eed1b9f Mon Sep 17 00:00:00 2001 From: Daniel TARTAVEL Date: Sun, 5 Apr 2026 17:32:17 +0200 Subject: [PATCH 08/10] modification du moment des notifications(heures pleines) --- src/pws2mqtt.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/pws2mqtt.cpp b/src/pws2mqtt.cpp index 5c69c8e..5ab0b18 100644 --- a/src/pws2mqtt.cpp +++ b/src/pws2mqtt.cpp @@ -109,7 +109,7 @@ void Pws2mqtt::init() { QByteArray data; QList> queryList = request.query().queryItems(); - + debug(DEBUGMACRO, "Réception des données", INFO); //QTextStream result(&data); if (queryList.isEmpty()) @@ -117,7 +117,8 @@ void Pws2mqtt::init() debug(DEBUGMACRO, "Request query is empty", WARNING); }else { - debug(DEBUGMACRO, "Request query :" + request.query().toString() , DEBUG); + debug(DEBUGMACRO, "Request query :" + request.query().toString() , INFO + ); QMetaObject::invokeMethod(this, [this, query = request.query()]() { this->parseData(query.queryItems()); }, Qt::QueuedConnection); @@ -368,7 +369,6 @@ void Pws2mqtt::parseData(QList> queryList) }else if (name == "baromin") { //static QDateTime timePrevision = QDateTime::currentDateTime().addSecs(-1000); - propertyValue = round(tohPa(pair.second.toFloat()) * 100) / 100; debug (DEBUGMACRO, "Barometre en hPa : " + QByteArray::number(propertyValue), DEBUG); baro->addPressure(propertyValue); @@ -405,10 +405,12 @@ void Pws2mqtt::parseData(QList> queryList) propertyList[name] = formatNotifString(propertyName[name].first, "", QByteArray::number(propertyValue)); } debug (DEBUGMACRO, "priority = " + QString::number(priority[name]), DEBUG); - }else if (name == "solarradiation") { + propertyValue = pair.second.toFloat()*100/100; + propertyList[name] = formatNotifString(propertyName[name].first, "", QByteArray::number(propertyValue)); propertiesValue[name] = round(pair.second.toFloat()*100/100); + debug (DEBUGMACRO, "SolarRadiations = " + QByteArray::number(propertyValue), DEBUG); } } } @@ -462,7 +464,8 @@ void Pws2mqtt::parseData(QList> queryList) notif += propertyList[name]; } } - if (QDateTime::currentDateTime() > timer.addSecs(3600) or start == false or aPriority >= 3) + QTime currentTime = QTime::currentTime(); + if (currentTime.minute() == 0 or start == false or aPriority >= 3) { timer = QDateTime::currentDateTime(); start = true; @@ -471,7 +474,7 @@ void Pws2mqtt::parseData(QList> queryList) notif = "**Prévisions à 12/24h**\n" + propertyList["prevision"]; notify (notif, priorityList[aPriority], "", tag); - debug(DEBUGMACRO, "calling notify with notif = #" + notif + "#", DEBUG); + debug(DEBUGMACRO, "calling notify with notif = #" + notif + "#", INFO); } debug(DEBUGMACRO, "parseData: Returning", DEBUG); } From b3fe7881210fb69ebf847ee70676919b4be6645f Mon Sep 17 00:00:00 2001 From: Daniel TARTAVEL Date: Sun, 12 Apr 2026 21:16:24 +0200 Subject: [PATCH 09/10] mqtt en option de complilation --- pws2mqtt-qt.pro | 4 +- src/main.cpp | 15 +++--- src/pws2mqtt.cpp | 135 +++++++++++++++++++++++++++-------------------- src/pws2mqtt.h | 5 +- 4 files changed, 90 insertions(+), 69 deletions(-) diff --git a/pws2mqtt-qt.pro b/pws2mqtt-qt.pro index 5e5d34b..fb7e584 100644 --- a/pws2mqtt-qt.pro +++ b/pws2mqtt-qt.pro @@ -26,9 +26,9 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin HEADERS += \ src/barometertrend.h \ -src/httpserver.h \ +#src/httpserver.h \ # src/mqtt.h \ src/pws2mqtt.h \ - src/utcicalculator.h \ +src/utcicalculator.h \ src/version.h diff --git a/src/main.cpp b/src/main.cpp index 9c52c04..99907a2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,11 +1,9 @@ #include #include -#include +//#include #include -#include -#include -#include -#include +//#include +//#include #include #include #include "pws2mqtt.h" @@ -14,9 +12,8 @@ #endif #include "src/barometertrend.h" #include "version.h" -#include -#include -#include +//#include +//#include #ifdef WITH_MQTT #include #include @@ -55,8 +52,8 @@ int main(int argc, char *argv[]) // Enable logging to journald qputenv("QT_FORCE_STDERR_LOGGING", QByteArray("0")); - debug(DEBUGMACRO, "declaration of mqttClient", INFO); #ifdef WITH_MQTT + debug(DEBUGMACRO, "declaration of mqttClient", INFO); mqttClient = new MqttClient; #endif httpServer = new QHttpServer; diff --git a/src/pws2mqtt.cpp b/src/pws2mqtt.cpp index 5ab0b18..e044ebf 100644 --- a/src/pws2mqtt.cpp +++ b/src/pws2mqtt.cpp @@ -1,16 +1,15 @@ #include "pws2mqtt.h" #include "barometertrend.h" -#include +//#include #include -#include +//#include #include #include #include -#include #include #include #include -#include +//#include #include "utcicalculator.h" #include #include @@ -59,7 +58,7 @@ QMap > propertyName // {"indoorhumidity", {"Humidité intérieure", "%"}}, {"baromin", {"Pression atmosphérique", " hPa"}}, // {"lowbatt", {"Alerte batterie faible", ""}}, - {"UV", {"Alerte UV", ""}} + {"UV", {"UV", ""}} }; QList > forceVent @@ -119,9 +118,10 @@ void Pws2mqtt::init() { debug(DEBUGMACRO, "Request query :" + request.query().toString() , INFO ); - QMetaObject::invokeMethod(this, [this, query = request.query()]() { +/* QMetaObject::invokeMethod(this, [this, query = request.query()]() { this->parseData(query.queryItems()); - }, Qt::QueuedConnection); + }, Qt::QueuedConnection);*/ + parseData(request.query().queryItems()); debug(DEBUGMACRO, "Returning 'success'", DEBUG); } //mqttClient.send_message(jsonString); @@ -132,7 +132,7 @@ void Pws2mqtt::init() for (auto [name, pair]: propertyName.asKeyValueRange()) { - propertyList[name].append(formatNotifString(pair.first, pair.second, "0")); + propertyList[name].append(formatNotifString(pair, "0")); debug (DEBUGMACRO, "Init " + name + " => " + propertyList[name], DEBUG); } } @@ -140,7 +140,7 @@ void Pws2mqtt::init() void notify(QString notif, QString priority, QString inputPath, QString tag) { (void) inputPath; - QNetworkAccessManager *manager = new QNetworkAccessManager(pws2mqtt); + QNetworkAccessManager *manager = new QNetworkAccessManager(); QNetworkRequest request(QUrl("http://localhost:81/Meteo")); request.setRawHeader("Content-Type", "charset=UTF-8; text/markdown"); if (!tag.isEmpty()) @@ -153,17 +153,19 @@ void notify(QString notif, QString priority, QString inputPath, QString tag) request.setRawHeader("Config", "/etc/ntfy.client.yml"); request.setRawHeader("Firebase", "no"); - QNetworkReply *reply = manager->post(request, notif.toUtf8()); - QObject::connect(reply, &QNetworkReply::finished, [reply, &manager]() { - if (reply->error() != QNetworkReply::NoError) { + QObject::connect(reply, &QNetworkReply::finished, [reply]() + { + if (reply->error() != QNetworkReply::NoError) + { debug(DEBUGMACRO, "Erreur réseau : " + reply->errorString(), ERROR); - } else { + } else + { debug(DEBUGMACRO, "Notification envoyée", DEBUG); } reply->deleteLater(); - manager->deleteLater(); }); + delete(manager); } @@ -196,7 +198,6 @@ void Pws2mqtt::parseData(QList> queryList) bool deviceFlag = false; static QDateTime timer = QDateTime::currentDateTime().addSecs(-2000); static QHash priority = {}; - static QHash announced = {}; static bool start = false; debug(DEBUGMACRO, "looping list of query", DEBUG); @@ -247,7 +248,7 @@ void Pws2mqtt::parseData(QList> queryList) //notif += formatNotifString (propertyName[name].first, propertyName[name].second, QByteArray::number(qPow(propertyValue, 1.0))); //debug (DEBUGMACRO, "", DEBUG); timeTemp = timeTemp.currentDateTime().addSecs(300); - propertyList[name] = formatNotifString(propertyName[name].first, propertyName[name].second, QByteArray::number(propertyValue)); + propertyList[name] = formatNotifString(propertyName[name], QByteArray::number(propertyValue)); propertiesValue[name] = propertyValue; if (propertyValue > 35) { @@ -265,7 +266,7 @@ void Pws2mqtt::parseData(QList> queryList) if (compare (propertiesValue[name], propertyValue, 3)) { //notif += formatNotifString (propertyName[name].first, propertyName[name].second , value); - propertyList[name] = formatNotifString(propertyName[name].first, propertyName[name].second, QByteArray::number(propertyValue)); + propertyList[name] = formatNotifString(propertyName[name], QByteArray::number(propertyValue)); propertiesValue[name] = propertyValue; } }else if (name == "winddir") @@ -273,7 +274,7 @@ void Pws2mqtt::parseData(QList> queryList) 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)); + propertyList[name] = formatNotifString(propertyName[name], QByteArray::number(propertyValue)); propertiesValue[name] = propertyValue; }else if (name == "windspeedmph") { @@ -296,7 +297,7 @@ void Pws2mqtt::parseData(QList> queryList) } } - propertyList[name] = formatNotifString ("Vent - " + msg, propertyName[name].second , QByteArray::number(propertiesValue[name])); + propertyList[name] = "- Vent - " + msg + " : " + QByteArray::number(propertiesValue[name]) + "Km/h" + "\n"; propertiesValue["forcevent"] = i; if (i >= 5) { @@ -317,7 +318,7 @@ void Pws2mqtt::parseData(QList> queryList) debug (DEBUGMACRO, name + " : " + QByteArray::number(propertiesValue[name]), DEBUG); - propertyList[name] = formatNotifString (propertyName[name].first, propertyName[name].second , QByteArray::number(propertiesValue[name])); + propertyList[name] = formatNotifString (propertyName[name], QByteArray::number(propertiesValue[name])); if (propertiesValue[name] > 50) { @@ -342,7 +343,7 @@ void Pws2mqtt::parseData(QList> queryList) QString pluviosite = getPluviosite(propertyValue, raininPriority); priority[name] = setPriority (priority[name], raininPriority); //debug (DEBUGMACRO, "Notif = #" + notif + "#", DEBUG); - propertyList[name] = formatNotifString(pluviosite, propertyName[name].second, QByteArray::number(propertyValue)); + propertyList[name] = formatNotifString(propertyName[name], QByteArray::number(propertyValue)); propertiesValue[name] = propertyValue; } debug (DEBUGMACRO, "priority = " + QString::number(priority[name]), DEBUG); @@ -362,7 +363,7 @@ void Pws2mqtt::parseData(QList> queryList) { //priority[name] = setPriority (priority[name], 3); //debug (DEBUGMACRO, "Notif = #" + notif + "#", DEBUG); - propertyList[name] = formatNotifString(propertyName[name].first, propertyName[name].second, QByteArray::number(propertyValue)); + propertyList[name] = formatNotifString(propertyName[name], QByteArray::number(propertyValue)); propertiesValue[name] = propertyValue; } debug (DEBUGMACRO, "priority = " + QString::number(priority[name]), DEBUG); @@ -372,7 +373,7 @@ void Pws2mqtt::parseData(QList> queryList) propertyValue = round(tohPa(pair.second.toFloat()) * 100) / 100; debug (DEBUGMACRO, "Barometre en hPa : " + QByteArray::number(propertyValue), DEBUG); baro->addPressure(propertyValue); - propertyList[name] = formatNotifString(propertyName[name].first, "", QByteArray::number(propertyValue)); + propertyList[name] = formatNotifString(propertyName[name], QByteArray::number(propertyValue)); propertiesValue[name] = propertyValue; static QString prevision; @@ -388,6 +389,7 @@ void Pws2mqtt::parseData(QList> queryList) debug (DEBUGMACRO, "priority = " + QString::number(priority[name]), DEBUG); }else if (name == "UV") { + QString msg; static QDateTime timeUV = QDateTime::currentDateTime().addSecs(-600); propertyValue = pair.second.toUInt(); @@ -402,20 +404,20 @@ void Pws2mqtt::parseData(QList> queryList) timeUV = timeUV.currentDateTime().addSecs(300); propertiesValue[name] = propertyValue; debug (DEBUGMACRO, "Notif = #" + notif + "#", DEBUG); - propertyList[name] = formatNotifString(propertyName[name].first, "", QByteArray::number(propertyValue)); + propertyList[name] = "- UV - " + QByteArray::number(propertyValue) + "\n"; } debug (DEBUGMACRO, "priority = " + QString::number(priority[name]), DEBUG); }else if (name == "solarradiation") { propertyValue = pair.second.toFloat()*100/100; - propertyList[name] = formatNotifString(propertyName[name].first, "", QByteArray::number(propertyValue)); + propertyList[name] = formatNotifString(propertyName[name], QByteArray::number(propertyValue)); propertiesValue[name] = round(pair.second.toFloat()*100/100); debug (DEBUGMACRO, "SolarRadiations = " + QByteArray::number(propertyValue), DEBUG); } } } 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"])); + propertyList["windchill"] = formatNotifString(propertyName["windchill"], QByteArray::number(propertiesValue["windchill"])); //windChill(propertiesValue["tempf"], propertiesValue["vent"]); //calculerHumidex(propertiesValue["tempf"], propertiesValue["humidity"]); @@ -439,46 +441,67 @@ void Pws2mqtt::parseData(QList> queryList) debug(DEBUGMACRO, "looping to fill notif", DEBUG); - for (auto [name, value]: propertyList.asKeyValueRange()) - { - if (precPropertyList.contains(name)) - { - if (precPropertyList[name] != propertyList[name]) - { - if (announced.contains(name) and priority.contains(name)) - { - if (announced[name] != priority[name]) - { - debug(DEBUGMACRO, "changed = true", DEBUG); - announced[name] = priority[name]; - //changed = true; - aPriority = qMax(aPriority, priority[name]); - } - } - } - } - - debug(DEBUGMACRO, "Name = " + name + ", value = " + value, DEBUG); - if (name != "prevision") - { - notif += propertyList[name]; - } - } QTime currentTime = QTime::currentTime(); - if (currentTime.minute() == 0 or start == false or aPriority >= 3) + if (currentTime.minute() == 0 or start == false) { timer = QDateTime::currentDateTime(); start = true; + notif = listProperties2notify (propertyList, priority, 0); notify (notif, priorityList[aPriority], attachment, tag); precPropertyList = propertyList; + debug(DEBUGMACRO, "calling notify with notif = #" + notif + "#", INFO); notif = "**Prévisions à 12/24h**\n" + propertyList["prevision"]; notify (notif, priorityList[aPriority], "", tag); debug(DEBUGMACRO, "calling notify with notif = #" + notif + "#", INFO); } + if (aPriority >= 3) + { + notif = "**ALERTES**\n" + listProperties2notify (propertyList, priority, 3); + precPropertyList = propertyList; + notify (notif, priorityList[aPriority], attachment, tag); + } debug(DEBUGMACRO, "parseData: Returning", DEBUG); } +QString listProperties2notify (QMap propertyList, QHash priority, quint8 minAlert) +{ + static QHash announced = {}; + QString notif = ""; + for (auto [name, value]: propertyList.asKeyValueRange()) + { + if (name != "prevision") + { + //if (precPropertyList.contains(name)) + //{ + //if (precPropertyList[name] != propertyList[name]) + //{ + if (minAlert == 0) + { + notif += propertyList[name]; + }else if (priority[name] >= minAlert) + { + if (announced.contains(name) and priority.contains(name)) + { + if (announced[name] != priority[name]) + { + notif += propertyList[name]; + announced[name] = priority[name]; + }else + { + debug (DEBUGMACRO, name + " : déjà annoncé = " + announced[name] + " nouvelle valeur = " + priority[name], INFO); + } + } + } + //} + //} + + debug(DEBUGMACRO, "Name = " + name + ", value = " + value, DEBUG); + } + } + return notif; +} + double calculerUTCI(double temperature, double humiditeRelative, double vitesseVent, double rayonnement) { double e = (humiditeRelative / 100.0) * 6.105 * exp((17.27 * temperature) / (237.7 + temperature)); @@ -565,12 +588,12 @@ bool compare (double value, double currentValue, double ecart) } } -QString formatNotifString (QString name, QString unit ,QByteArray value) +QString formatNotifString (QPair property ,QByteArray value) { - QString text = "- " + name + " : " + value; - if (!unit.isEmpty()) + QString text = "- " + property.first + " : " + value; + if (!property.second.isEmpty()) { - text += unit; + text += property.second; //"- " + propertyName[name].first + " : " + value + " " + propertyName[name].second + " "; } return text += "\n"; diff --git a/src/pws2mqtt.h b/src/pws2mqtt.h index 59bfd12..9976c14 100644 --- a/src/pws2mqtt.h +++ b/src/pws2mqtt.h @@ -5,7 +5,7 @@ #include #include #include -#include +//#include #define RED "\e[31m" #define GREEN "\e[32m" @@ -54,7 +54,7 @@ class Pws2mqtt : public QObject double fahrenheitToCelsius(double fahrenheit); double tohPa(double value); bool compare (double value=0, double testValue=0, double ecart = 0.5); -QString formatNotifString (QString name, QString unit, QByteArray value=""); +QString formatNotifString (QPair property ,QByteArray value); double mphTokmh (double value); quint8 setPriority (quint8 currentPriority, quint8 newPriority); QString previsionMeteo(double currentPressure, double variation3h, quint8 &priority); @@ -64,4 +64,5 @@ void rotateAndSaveImage(const QString &inputPath, const QString &outputPath, qre double windChill(double airT, double vent); double calculerHumidex(double temperature, double humiditeRelative); void notify (QString notif, QString priority = "low", QString inputPath = "", QString tag = ""); +QString listProperties2notify (QMap propertyList, QHash priority, quint8 minAlert = 0); From 2b25674e5d138dacf863febc4d2bc3a1161fa0bb Mon Sep 17 00:00:00 2001 From: Daniel TARTAVEL Date: Sun, 12 Apr 2026 22:07:44 +0200 Subject: [PATCH 10/10] =?UTF-8?q?ajustement=20des=20pr=C3=A9visions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/barometertrend.h | 764 +++++++++++++++++++++---------------------- 1 file changed, 382 insertions(+), 382 deletions(-) diff --git a/src/barometertrend.h b/src/barometertrend.h index 7b53aab..6e6467f 100644 --- a/src/barometertrend.h +++ b/src/barometertrend.h @@ -8,233 +8,233 @@ struct ForecastResult { - QString message; - int urgency = 0; // 0-5 - QString icons = ""; // "vert", "jaune", ... - bool snowRisk = false; - bool rainRisk = false; - bool stormRisk = false; - bool blackIce = false; - QString prevision1h =""; - quint8 confiance = 50; + QString message; + int urgency = 0; // 0-5 + QString icons = ""; // "vert", "jaune", ... + bool snowRisk = false; + bool rainRisk = false; + bool stormRisk = false; + bool blackIce = false; + QString prevision1h =""; + quint8 confiance = 50; }; class BarometerTrend : public QObject { - Q_OBJECT + Q_OBJECT public: - explicit BarometerTrend(QObject *parent = nullptr) - : QObject(parent) - { - m_values.reserve(360 + 16); // évite reallocs fréquentes - m_timestamps.reserve(360 + 16); - restoreHistory(); - // Sauvegarde automatique toutes les 10 minutes - m_saveTimer = new QTimer(this); - connect(m_saveTimer, &QTimer::timeout, this, &BarometerTrend::saveHistory); - m_saveTimer->start(10 * 60 * 1000); - if (!m_saveTimer->isActive()) - { - debug(DEBUGMACRO, "Le timer n'est pas démarré", ERROR); - } - } + explicit BarometerTrend(QObject *parent = nullptr) + : QObject(parent) + { + m_values.reserve(360 + 16); // évite reallocs fréquentes + m_timestamps.reserve(360 + 16); + restoreHistory(); + // Sauvegarde automatique toutes les 10 minutes + m_saveTimer = new QTimer(this); + connect(m_saveTimer, &QTimer::timeout, this, &BarometerTrend::saveHistory); + m_saveTimer->start(10 * 60 * 1000); + if (!m_saveTimer->isActive()) + { + debug(DEBUGMACRO, "Le timer n'est pas démarré", ERROR); + } + } - ~BarometerTrend() - { - saveHistory(); - } - void addPressure(double pressure_hPa) - { - debug(DEBUGMACRO, "adding pressure " + QByteArray::number(pressure_hPa), DEBUG); - // Enregistrement de la nouvelle mesure - m_values.append(pressure_hPa); - m_timestamps.append(QDateTime::currentDateTime()); + ~BarometerTrend() + { + saveHistory(); + } + void addPressure(double pressure_hPa) + { + debug(DEBUGMACRO, "adding pressure " + QByteArray::number(pressure_hPa), DEBUG); + // Enregistrement de la nouvelle mesure + m_values.append(pressure_hPa); + m_timestamps.append(QDateTime::currentDateTime()); - // Limiter la taille de l’historique à 3 heures (360 mesures à 30s d’intervalle) - const int maxSamples = 360; - while (m_values.size() > maxSamples) - { - m_values.removeFirst(); - m_timestamps.removeFirst(); - } - } + // Limiter la taille de l’historique à 3 heures (360 mesures à 30s d’intervalle) + const int maxSamples = 360; + while (m_values.size() > maxSamples) + { + m_values.removeFirst(); + m_timestamps.removeFirst(); + } + } - double currentPressure() const - { - return m_values.isEmpty() ? 0.0 : m_values.last(); - } + double currentPressure() const + { + return m_values.isEmpty() ? 0.0 : m_values.last(); + } - // Moyenne glissante sur les dernières N mesures (par ex. 5 minutes) - double smoothedPressure(int samples = 10) const - { - if (m_values.isEmpty()) - { - return 0.0; - } - int n = qMin(samples, m_values.size()); - double sum = 0.0; - for (int i = m_values.size() - n; i < m_values.size(); ++i) - sum += m_values[i]; - debug(DEBUGMACRO, "smoothed pressure : " + QByteArray::number(sum/n), DEBUG); - return sum / n; + // Moyenne glissante sur les dernières N mesures (par ex. 5 minutes) + double smoothedPressure(int samples = 10) const + { + if (m_values.isEmpty()) + { + return 0.0; + } + int n = qMin(samples, m_values.size()); + double sum = 0.0; + for (int i = m_values.size() - n; i < m_values.size(); ++i) + sum += m_values[i]; + debug(DEBUGMACRO, "smoothed pressure : " + QByteArray::number(sum/n), DEBUG); + return sum / n; - } + } - // 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; - } - - // Variation de pression sur N heures (ex: 1 ou 3) - double deltaPressureHours(double hours) const - { - if (m_values.size() < 2) return 0.0; - QDateTime now = QDateTime::currentDateTime(); - QDateTime past = now.addSecs(-qRound(hours * 3600.0)); - double p_now = smoothedPressure(); // moyenne récente (~5 min) - double p_past = pressureAround(past, 60); // moyenne autour de l'instant passé - double delta = p_now - p_past; - // debug(DEBUGMACRO, "delta " + QByteArray::number(hours) + "h : " + QByteArray::number(delta), DEBUG); - return delta; - } - - // helpers spécifiques - double deltaPressure3h() const { return deltaPressureHours(3.0); } - double deltaPressure1h() const { return deltaPressureHours(1.0); } - - ForecastResult forecast(double temperatureC, double humidityPercent) const - { - ForecastResult r; - - r.confiance = 50; - double p = currentPressure(); - double d = deltaPressure3h(); - double d3 = deltaPressure3h(); - double d1 = deltaPressure1h(); + // 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; + } - debug(DEBUGMACRO, "current pressure : " + QByteArray::number(p) + " - delta pressure 3h" + QByteArray::number(d), DEBUG); + // Variation de pression sur N heures (ex: 1 ou 3) + double deltaPressureHours(double hours) const + { + if (m_values.size() < 2) return 0.0; + QDateTime now = QDateTime::currentDateTime(); + QDateTime past = now.addSecs(-qRound(hours * 3600.0)); + double p_now = smoothedPressure(); // moyenne récente (~5 min) + double p_past = pressureAround(past, 60); // moyenne autour de l'instant passé + double delta = p_now - p_past; + // debug(DEBUGMACRO, "delta " + QByteArray::number(hours) + "h : " + QByteArray::number(delta), DEBUG); + return delta; + } - // build icon list to produce colorCode - QStringList icons; + // helpers spécifiques + double deltaPressure3h() const { return deltaPressureHours(3.0); } + double deltaPressure1h() const { return deltaPressureHours(1.0); } - // Logique combinée pression / tendance + ForecastResult forecast(double temperatureC, double humidityPercent) const + { + ForecastResult r; + + r.confiance = 50; + double p = currentPressure(); + double d = deltaPressure3h(); + double d3 = deltaPressure3h(); + double d1 = deltaPressure1h(); + + debug(DEBUGMACRO, "current pressure : " + QByteArray::number(p) + " - delta pressure 3h" + QByteArray::number(d), DEBUG); + + // build icon list to produce colorCode + QStringList icons; + + // Logique combinée pression / tendance if (p < 990 && d3 <= -3.0) - { - r.message = "- Tempête ou orage"; - r.urgency = 5; - icons << "cloud_with_lightning"; - debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1020 && d3 >= +3.0) - { - r.message = "- Très beau temps durable"; - r.urgency = 0; - icons << "sunny"; - debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1020 && d3 >= +1.0) - { - r.message = "- Beau temps durable"; - r.urgency = 0; - icons << "sunny"; - debug(DEBUGMACRO, "message : " + r.message, DEBUG); + { + r.message = "- Tempête ou orage"; + r.urgency = 5; + icons << "cloud_with_lightning"; + debug(DEBUGMACRO, "message : " + r.message, DEBUG); + }else if (p >= 1020 && d3 >= +3.0) + { + r.message = "- Très beau temps durable"; + r.urgency = 0; + icons << "sunny"; + debug(DEBUGMACRO, "message : " + r.message, DEBUG); + }else if (p >= 1020 && d3 >= +1.0) + { + r.message = "- Beau temps durable"; + r.urgency = 0; + icons << "sunny"; + debug(DEBUGMACRO, "message : " + r.message, DEBUG); }else if (p >= 1020 && (d3 <= +1.0 && d3 >= -1.0)) { r.message = "- Beau temps stable"; r.urgency = 0; icons << "sunny"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1020 && d3 < -3.0) - { - r.message = "- Beau, mais rapide dégradation"; - r.urgency = 4; - icons << "sun_behind_large_cloud"; - debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1020 && d3 < -1.0) - { - r.message = "- Beau, mais possible dégradation"; - r.urgency = 1; - icons << "sun_behind_small_cloud"; - debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1020 && (d3 <= 1.0 && d3 >= -1.0)) - { - r.message = "- Beau temps stable"; - r.urgency = 0; - icons << "sunny"; + }else if (p >= 1015 && d3 < -3.0) + { + r.message = "- Beau, mais rapide dégradation"; + r.urgency = 4; + icons << "sun_behind_large_cloud"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1010 && d3 >= +3.0) - { - r.message = "- Nuageux, rapide amélioration"; - r.urgency = 4; - icons << "sun_behind_small_cloud"; - debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1010 && d3 >= +1.0) - { - r.message = "- Nuageux, en amélioration"; - r.urgency = 0; - icons << "sun_behind_large_cloud"; - debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1010 && d3 <= -3.0) - { - r.message = "- Nuageux, fort risque de pluie ou vent"; - r.urgency = 4; - icons << "sun_behind_rain_cloud"; - debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1010 && d3 <= -1.0) - { - r.message = "- nuageux, risque de pluie ou vent"; - r.urgency = 2; - icons << "sun_behind_rain_cloud"; - debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1010 && (d3 <= 1.0 && d3 >= 1.0)) - { - r.message = "- Nuageux avec des éclaircies"; - r.urgency = 2; - icons << "sun_behind_large_cloud"; - debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1000 && d3 >= +3.0) - { - r.message = "- Variable, amélioration rapide"; - r.urgency = 4; - icons << "sun_behind_large_cloud"; - debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1000 && d3 >= +1.0) - { - r.message = "- Variable, tendance au beau"; - r.urgency = 0; - icons << "sun_behind_large_cloud"; - debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1000 && d3 <= -3.0) - { - r.message = "- Pluie ou perturbation, dégradation rapide"; - r.urgency = 4; - icons << "cloud_with_rain"; - debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1000 && d3 <= -1.0) - { + }else if (p >= 1015 && d3 < -1.0) + { + r.message = "- Beau, mais possible dégradation"; + r.urgency = 1; + icons << "sun_behind_small_cloud"; + debug(DEBUGMACRO, "message : " + r.message, DEBUG); + }else if (p >= 1015 && (d3 <= 1.0 && d3 >= -1.0)) + { + r.message = "- Beau temps stable"; + r.urgency = 0; + icons << "sunny"; + debug(DEBUGMACRO, "message : " + r.message, DEBUG); + }else if (p >= 1005 && d3 >= +3.0) + { + r.message = "- Nuageux, rapide amélioration"; + r.urgency = 4; + icons << "sun_behind_small_cloud"; + debug(DEBUGMACRO, "message : " + r.message, DEBUG); + }else if (p >= 1005 && d3 >= +1.0) + { + r.message = "- Nuageux, en amélioration"; + r.urgency = 0; + icons << "sun_behind_large_cloud"; + debug(DEBUGMACRO, "message : " + r.message, DEBUG); + }else if (p >= 1005 && d3 <= -3.0) + { + r.message = "- Nuageux, fort risque de pluie ou vent"; + r.urgency = 4; + icons << "sun_behind_rain_cloud"; + debug(DEBUGMACRO, "message : " + r.message, DEBUG); + }else if (p >= 1005 && d3 <= -1.0) + { + r.message = "- nuageux, risque de pluie ou vent"; + r.urgency = 2; + icons << "sun_behind_rain_cloud"; + debug(DEBUGMACRO, "message : " + r.message, DEBUG); + }else if (p >= 1005 && (d3 <= 1.0 && d3 >= 1.0)) + { + r.message = "- Nuageux avec des éclaircies"; + r.urgency = 2; + icons << "sun_behind_large_cloud"; + debug(DEBUGMACRO, "message : " + r.message, DEBUG); + }else if (p >= 1000 && d3 >= +3.0) + { + r.message = "- Variable, amélioration rapide"; + r.urgency = 4; + icons << "sun_behind_large_cloud"; + debug(DEBUGMACRO, "message : " + r.message, DEBUG); + }else if (p >= 1000 && d3 >= +1.0) + { + r.message = "- Variable, tendance au beau"; + r.urgency = 0; + icons << "sun_behind_large_cloud"; + debug(DEBUGMACRO, "message : " + r.message, DEBUG); + }else if (p >= 1000 && d3 <= -3.0) + { + r.message = "- Pluie ou perturbation, dégradation rapide"; + r.urgency = 4; + icons << "cloud_with_rain"; + debug(DEBUGMACRO, "message : " + r.message, DEBUG); + }else if (p >= 1000 && d3 <= -1.0) + { r.message = "- Pluie ou perturbation"; - r.urgency = 2; - icons << "cloud_with_rain"; - debug(DEBUGMACRO, "message : " + r.message, DEBUG); + r.urgency = 2; + icons << "cloud_with_rain"; + debug(DEBUGMACRO, "message : " + r.message, DEBUG); }else if (p >= 1000 && (d3 <= 1.0 && d3 >= -1.0)) { r.message = "- Pluie ou perturbation stable"; @@ -242,23 +242,23 @@ public: icons << "cloud_with_rain"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); }else if (p < 1000 && d3 >= +3.0) - { - r.message = "- Pluie avec accalmie temporaire, amélioration rapide"; - r.urgency = 1; - icons << "sun_behind_rain_cloud"; - debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p < 1000 && d3 >= +1.0) - { - r.message = "- Pluie avec accalmie temporaire"; - r.urgency = 1; - icons << "sun_behind_rain_cloud"; - debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p < 1000 && d3 <= -1.0) - { - r.message = "- Mauvais temps durable"; - r.urgency = 4; - icons << "cloud_with_rain"; - debug(DEBUGMACRO, "message : " + r.message, DEBUG); + { + r.message = "- Pluie avec accalmie temporaire, amélioration rapide"; + r.urgency = 1; + icons << "sun_behind_rain_cloud"; + debug(DEBUGMACRO, "message : " + r.message, DEBUG); + }else if (p < 1000 && d3 >= +1.0) + { + r.message = "- Pluie avec accalmie temporaire"; + r.urgency = 1; + icons << "sun_behind_rain_cloud"; + debug(DEBUGMACRO, "message : " + r.message, DEBUG); + }else if (p < 1000 && d3 <= -1.0) + { + r.message = "- Mauvais temps durable"; + r.urgency = 4; + icons << "cloud_with_rain"; + debug(DEBUGMACRO, "message : " + r.message, DEBUG); }else if (p < 1000 && (d3 <= 1.0 && d3 >= -1.0)) { r.message = "- Mauvais temps stable"; @@ -268,185 +268,185 @@ public: } /*if (qAbs(d3) < 1) - { - r.message += "- Stable, pas de changement significatif"; - r.urgency = 0; - debug(DEBUGMACRO, "message : " + r.message, DEBUG); + { + r.message += "- Stable, pas de changement significatif"; + r.urgency = 0; + debug(DEBUGMACRO, "message : " + r.message, DEBUG); }*/ - // Risque de neige - if (p < 1000 && d3 < -1.0 && temperatureC <= 1.0 && humidityPercent > 80.0) - { - r.snowRisk = true; - r.message += "- Risque de neige"; - r.urgency = qMax(r.urgency, 3); - icons << "snowflake"; - debug(DEBUGMACRO, "message : " + r.message, DEBUG); - } - - // Risque de pluie - else if (p < 1010 && d3 < -1.0 && temperatureC > 1.0 && humidityPercent > 70.0) - { - r.rainRisk = true; - r.message += "- Risque de pluie"; + // Risque de neige + if (p < 1000 && d3 < -1.0 && temperatureC <= 1.0 && humidityPercent > 80.0) + { + r.snowRisk = true; + r.message += "- Risque de neige"; r.urgency = qMax(r.urgency, 3); - icons << "cloud_with_rain"; - debug(DEBUGMACRO, "message : " + r.message, DEBUG); - } + icons << "snowflake"; + debug(DEBUGMACRO, "message : " + r.message, DEBUG); + } - // Risque d’orage - if (p < 995 && d3 < -3.0 && temperatureC > 20.0 && humidityPercent > 70.0) - { - r.stormRisk = true; - r.message += "- Risque d’orage"; - r.urgency = qMax(r.urgency, 4); - icons << "cloud_with_lightning"; - debug(DEBUGMACRO, "message : " + r.message, DEBUG); - } - - if (temperatureC <= 0.5 && humidityPercent >= 85.0) { - // conditions classiques de gel - if (d3 >= -1.0 && d3 <= +1.0) - { - r.blackIce = true; // temps stable = ciel clair = refroidissement - }else if (d < -1 && p > 995) - { - r.blackIce = true; // arrivée d'air humide froid - } - } - - if (r.blackIce) - { - r.message += "- Risque de verglas"; - icons << "ice_cube"; - r.urgency = qMax(r.urgency, 4); - debug(DEBUGMACRO, "message : " + r.message, DEBUG); - } - - // --- Prévision à 1 heure --- - if (d <= -1.5 && p < 1010 && humidityPercent > 80.0) - { - r.prevision1h = "- Pluie probable dans l'heure"; + // Risque de pluie + else if (p < 1010 && d3 < -1.0 && temperatureC > 1.0 && humidityPercent > 70.0) + { + r.rainRisk = true; + r.message += "- Risque de pluie"; r.urgency = qMax(r.urgency, 3); - r.confiance = 80; - }else if (d >= +1.5 && p > 1015) - { - r.prevision1h = "- mélioration probable dans l'heure"; - r.confiance = 85; - }else if (qAbs(d1) < 0.3 && qAbs(temperatureC) < 0.5) - { - r.prevision1h = "- Conditions stables pour la prochaine heure"; - r.confiance = 70; - }else if (temperatureC < 0 && humidityPercent > 85) - { - r.prevision1h = "- Possible formation de givre ou verglas dans l'heure"; - r.urgency = qMax(r.urgency, 4); - r.confiance = 75; - }else - { - r.prevision1h = "- pas de changements dans l'heure"; - r.urgency = qMax(r.urgency, 2); - r.confiance = 85; - } + icons << "cloud_with_rain"; + debug(DEBUGMACRO, "message : " + r.message, DEBUG); + } + + // Risque d’orage + if (p < 995 && d3 < -3.0 && temperatureC > 20.0 && humidityPercent > 70.0) + { + r.stormRisk = true; + r.message += "- Risque d’orage"; + r.urgency = qMax(r.urgency, 4); + icons << "cloud_with_lightning"; + debug(DEBUGMACRO, "message : " + r.message, DEBUG); + } + + if (temperatureC <= 0.5 && humidityPercent >= 85.0) { + // conditions classiques de gel + if (d3 >= -1.0 && d3 <= +1.0) + { + r.blackIce = true; // temps stable = ciel clair = refroidissement + }else if (d < -1 && p > 995) + { + r.blackIce = true; // arrivée d'air humide froid + } + } + + if (r.blackIce) + { + r.message += "- Risque de verglas"; + icons << "ice_cube"; + r.urgency = qMax(r.urgency, 4); + debug(DEBUGMACRO, "message : " + r.message, DEBUG); + } + + // --- Prévision à 1 heure --- + if (d <= -1.5 && p < 1010 && humidityPercent > 80.0) + { + r.prevision1h = "- Pluie probable dans l'heure"; + r.urgency = qMax(r.urgency, 3); + r.confiance = 80; + }else if (d >= +1.5 && p > 1015) + { + r.prevision1h = "- mélioration probable dans l'heure"; + r.confiance = 85; + }else if (qAbs(d1) < 0.3 && qAbs(temperatureC) < 0.5) + { + r.prevision1h = "- Conditions stables pour la prochaine heure"; + r.confiance = 70; + }else if (temperatureC < 0 && humidityPercent > 85) + { + r.prevision1h = "- Possible formation de givre ou verglas dans l'heure"; + r.urgency = qMax(r.urgency, 4); + r.confiance = 75; + }else + { + r.prevision1h = "- pas de changements dans l'heure"; + r.urgency = qMax(r.urgency, 2); + r.confiance = 85; + } - // --- Ajustement de confiance selon stabilité barométrique --- - if (qAbs(d) > 3.0) - { - r.confiance -= 15; // variations trop fortes → prévision moins fiable - } - if (p < 990 || p > 1030) - { - r.confiance -= 10; // situations extrêmes, moins prédictibles - } - if (r.blackIce) - { - r.confiance += 5; // phénomène local très probable - } - r.confiance = qBound((quint8)0, r.confiance, (quint8)100); // borne entre 0 et 100 + // --- Ajustement de confiance selon stabilité barométrique --- + if (qAbs(d) > 3.0) + { + r.confiance -= 15; // variations trop fortes → prévision moins fiable + } + if (p < 990 || p > 1030) + { + r.confiance -= 10; // situations extrêmes, moins prédictibles + } + if (r.blackIce) + { + r.confiance += 5; // phénomène local très probable + } + r.confiance = qBound((quint8)0, r.confiance, (quint8)100); // borne entre 0 et 100 - // --- Résultat complet --- - if (!r.prevision1h.isEmpty()) - { - r.message += "\n**Prévision dans l'heure**"; - r.message += "\n" + r.prevision1h; - r.message += "\n- Probabilité " + QByteArray::number(r.confiance) + "%"; - } - debug(DEBUGMACRO, "message : " + r.message, DEBUG); + // --- Résultat complet --- + if (!r.prevision1h.isEmpty()) + { + r.message += "\n**Prévision dans l'heure**"; + r.message += "\n" + r.prevision1h; + r.message += "\n- Probabilité " + QByteArray::number(r.confiance) + "%"; + } + debug(DEBUGMACRO, "message : " + r.message, DEBUG); - if (!icons.isEmpty()) r.icons = icons.join(","); + if (!icons.isEmpty()) r.icons = icons.join(","); - return r; - } + return r; + } private: - QVector m_values; - QVector m_timestamps; - QTimer *m_saveTimer; + QVector m_values; + QVector m_timestamps; + QTimer *m_saveTimer; private slots: - void saveHistory() - { - QJsonArray array; - for (int i = 0; i < m_values.size(); ++i) - { - QJsonObject obj; - obj["timestamp"] = m_timestamps[i].toString(Qt::ISODate); - obj["pressure"] = m_values[i]; - array.append(obj); - } + void saveHistory() + { + QJsonArray array; + for (int i = 0; i < m_values.size(); ++i) + { + QJsonObject obj; + obj["timestamp"] = m_timestamps[i].toString(Qt::ISODate); + obj["pressure"] = m_values[i]; + array.append(obj); + } - QJsonDocument doc(array); - QFile file("/usr/local/share/pws2mqtt/barometer_history.json"); - if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) - { - file.write(doc.toJson()); - file.close(); - debug(DEBUGMACRO, "Barometer history saved (" + QByteArray::number(m_values.size()) + " samples)", DEBUG); - }else - { - debug(DEBUGMACRO, "File not open : " + file.errorString() , WARNING); - } - } + QJsonDocument doc(array); + QFile file("/usr/local/share/pws2mqtt/barometer_history.json"); + if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) + { + file.write(doc.toJson()); + file.close(); + debug(DEBUGMACRO, "Barometer history saved (" + QByteArray::number(m_values.size()) + " samples)", DEBUG); + }else + { + debug(DEBUGMACRO, "File not open : " + file.errorString() , WARNING); + } + } - void restoreHistory() - { - QFile file("/usr/local/share/pws2mqtt/barometer_history.json"); - if (!file.exists()) - { - debug(DEBUGMACRO, "File not open : " + file.errorString() , WARNING); - return; - } - if (file.open(QIODevice::ReadOnly)) - { - QByteArray data = file.readAll(); - file.close(); + void restoreHistory() + { + QFile file("/usr/local/share/pws2mqtt/barometer_history.json"); + if (!file.exists()) + { + debug(DEBUGMACRO, "File not open : " + file.errorString() , WARNING); + return; + } + if (file.open(QIODevice::ReadOnly)) + { + QByteArray data = file.readAll(); + file.close(); - QJsonDocument doc = QJsonDocument::fromJson(data); - if (!doc.isArray()) return; + QJsonDocument doc = QJsonDocument::fromJson(data); + if (!doc.isArray()) return; - QJsonArray array = doc.array(); - for (const QJsonValue &val : array) - { - QJsonObject obj = val.toObject(); - double pressure = obj["pressure"].toDouble(); - QDateTime ts = QDateTime::fromString(obj["timestamp"].toString(), Qt::ISODate); - if (ts.isValid()) - { - m_values.append(pressure); - m_timestamps.append(ts); - } - } + QJsonArray array = doc.array(); + for (const QJsonValue &val : array) + { + QJsonObject obj = val.toObject(); + double pressure = obj["pressure"].toDouble(); + QDateTime ts = QDateTime::fromString(obj["timestamp"].toString(), Qt::ISODate); + if (ts.isValid()) + { + m_values.append(pressure); + m_timestamps.append(ts); + } + } - // On ne garde que les 3 dernières heures - QDateTime limit = QDateTime::currentDateTime().addSecs(-3 * 3600); - while (!m_timestamps.isEmpty() && m_timestamps.first() < limit) - { - m_timestamps.removeFirst(); - m_values.removeFirst(); - } + // On ne garde que les 3 dernières heures + QDateTime limit = QDateTime::currentDateTime().addSecs(-3 * 3600); + while (!m_timestamps.isEmpty() && m_timestamps.first() < limit) + { + m_timestamps.removeFirst(); + m_values.removeFirst(); + } - debug(DEBUGMACRO, "Barometer history restored (" + QByteArray::number(m_values.size()) + " samples)", DEBUG); - } - } + debug(DEBUGMACRO, "Barometer history restored (" + QByteArray::number(m_values.size()) + " samples)", DEBUG); + } + } };