diff --git a/src/barometertrend.h b/src/barometertrend.h index 2fb5a29..bf61599 100644 --- a/src/barometertrend.h +++ b/src/barometertrend.h @@ -123,7 +123,7 @@ public: double deltaPressure3h() const { return deltaPressureHours(3.0); } double deltaPressure1h() const { return deltaPressureHours(1.0); } - ForecastResult forecast(double temperatureC, double humidityPercent) const + ForecastResult forecast(double temperatureC, double humidityPercent) const { ForecastResult r; @@ -141,116 +141,116 @@ public: // Logique combinée pression / tendance if (p < 990 && d3 <= -3.0) { - r.message = "- Tempête ou orage \n"; + 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 \n"; + 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 \n"; + r.message = "- Beau temps durable"; 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 \n"; + 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 \n"; + 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) { - r.message = "- Beau temps \n"; + r.message = "- Beau temps"; r.urgency = 0; - icons << "sunny"; + icons << "sunny"; debug(DEBUGMACRO, "message : " + r.message, DEBUG);*/ }else if (p >= 1010 && d3 >= +3.0) { - r.message = "- Nuageux, rapide amélioration \n"; + 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 \n"; + 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 \n"; + 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 \n"; + 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 <= 0.5) { - r.message = "- Nuageux avec des éclaircies \n"; + 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 \n"; + 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 \n"; + 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 \n"; + 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 \n"; + 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 \n"; + r.message = "- Pluie avec accalmie temporaire, amélioration rapide"; r.urgency = 1; - icons << "sun_behind_rain_cloud"; + icons << "sun_behind_rain_cloud"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); }else if (p < 1000 && d3 >= +1.0) { - r.message = "- Pluie avec accalmie temporaire \n"; + 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 \n"; + r.message = "- Mauvais temps durable"; r.urgency = 4; icons << "cloud_with_rain"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); } if (qAbs(d3) < 1) { - r.message += "- Stable, pas de changement significatif \n"; + r.message += "- Stable, pas de changement significatif"; r.urgency = 0; debug(DEBUGMACRO, "message : " + r.message, DEBUG); } @@ -259,7 +259,7 @@ public: if (p < 1000 && d3 < -1.0 && temperatureC <= 1.0 && humidityPercent > 80.0) { r.snowRisk = true; - r.message += "- Risque de neige \n"; + r.message += "- Risque de neige"; r.urgency = qMax(r.urgency, 3); icons << "snowflake"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); @@ -269,7 +269,7 @@ public: else if (p < 1010 && d3 < -1.0 && temperatureC > 1.0 && humidityPercent > 70.0) { r.rainRisk = true; - r.message += "- Risque de pluie \n"; + r.message += "- Risque de pluie"; r.urgency = qMax(r.urgency, 2); icons << "cloud_with_rain"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); @@ -279,7 +279,7 @@ public: if (p < 995 && d3 < -3.0 && temperatureC > 20.0 && humidityPercent > 70.0) { r.stormRisk = true; - r.message += "- Risque d’orage \n"; + r.message += "- Risque d’orage"; r.urgency = qMax(r.urgency, 4); icons << "cloud_with_lightning"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); @@ -298,7 +298,7 @@ public: if (r.blackIce) { - r.message += "- Risque de verglas \n"; + r.message += "- Risque de verglas"; icons << "ice_cube"; r.urgency = qMax(r.urgency, 4); debug(DEBUGMACRO, "message : " + r.message, DEBUG); @@ -307,25 +307,25 @@ public: // --- Prévision à 1 heure --- if (d <= -1.5 && p < 1010 && humidityPercent > 80.0) { - r.prevision1h = "- ☔ Pluie probable dans l’heure \n"; + r.prevision1h = "- Pluie probable dans l'heure"; r.urgency = qMax(r.urgency, 4); r.confiance = 80; }else if (d >= +1.5 && p > 1015) { - r.prevision1h = "- 🌤 Amélioration probable dans l’heure \n"; + 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 \n"; + 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 \n"; + 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 \n"; + r.prevision1h = "- pas de changements dans l'heure"; r.urgency = qMax(r.urgency, 2); r.confiance = 85; } @@ -349,9 +349,9 @@ public: // --- Résultat complet --- if (!r.prevision1h.isEmpty()) { - //r.message += "**Prévision dans l'heure** \n"; - r.message += r.prevision1h; - //r.message += "- Probabilité " + QByteArray::number(r.confiance) + "% \n"; + 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); diff --git a/src/pws2mqtt.cpp b/src/pws2mqtt.cpp index 09c810f..454d8b4 100644 --- a/src/pws2mqtt.cpp +++ b/src/pws2mqtt.cpp @@ -39,15 +39,6 @@ QStringList previsionList "Temps stable" }; -// Callback for curl library -static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) -{ - (void)contents; // Évite les warnings de compilation - (void)userp; - return size * nmemb; // On ne traite pas les données reçues -} - - QMap propertyList; QMap precPropertyList; QMap propertiesValue; @@ -62,13 +53,13 @@ QMap > propertyName {"windgustmph", {"Rafales", " km/h"}}, {"rainin", {"Pluie", " mm/h"}}, {"dailyrainin", {"Pluie de la journée", " mm"}}, - {"monthlyrainin", {"Pluie du mois", " mm"}}, - {"yearlyrainin", {"Pluie de l'année", " mm"}}, - {"solarradiation", {"Énergie solaire", " W/m²"}}, - {"indoortempf", {"Température intérieure", "°C"}}, - {"indoorhumidity", {"Humidité intérieure", "%"}}, +// {"monthlyrainin", {"Pluie du mois", " mm"}}, +// {"yearlyrainin", {"Pluie de l'année", " mm"}}, +// {"solarradiation", {"Énergie solaire", " W/m²"}}, +// {"indoortempf", {"Température intérieure", "°C"}}, +// {"indoorhumidity", {"Humidité intérieure", "%"}}, {"baromin", {"Pression atmosphérique", " hPa"}}, - {"lowbatt", {"Alerte batterie faible", ""}}, +// {"lowbatt", {"Alerte batterie faible", ""}}, {"UV", {"Alerte UV", ""}} }; @@ -135,6 +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); + } } void Pws2mqtt::listeningHttp() @@ -257,7 +253,7 @@ void Pws2mqtt::parseData(QList> queryList) attachment = this->outputPath; } - if (propertiesValue["forcevent"] != i or propertiesValue["rafales"] != i) + if (propertiesValue["forcevent"] != i) { priority = qMax(priority, windPriority); } @@ -296,7 +292,7 @@ void Pws2mqtt::parseData(QList> queryList) QString pluviosite = getPluviosite(propertyValue, raininPriority); priority = setPriority (priority, 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); @@ -316,8 +312,8 @@ void Pws2mqtt::parseData(QList> queryList) { //priority = setPriority (priority, 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") @@ -327,20 +323,19 @@ 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].first, "", QByteArray::number(propertyValue)); propertiesValue[name] = propertyValue; - static QString prevision; + static QString prevision; auto ret = baro->forecast(propertiesValue["tempf"], propertiesValue["humidity"]); - QString newPrevision = ret.message; - if (prevision != newPrevision) - { - prevision = newPrevision; - propertyList["prevision"] = prevision; - priority = setPriority(priority, ret.urgency); - tag += ret.icons; - } + prevision = ret.message; + //if (prevision != newPrevision) + //{ + priority = setPriority(priority, ret.urgency); + tag += ret.icons; + + propertyList["prevision"] = prevision; debug (DEBUGMACRO, "priority = " + QString::number(priority), DEBUG); }else if (name == "UV") { @@ -356,10 +351,10 @@ void Pws2mqtt::parseData(QList> queryList) if (propertyValue >= 6 ) priority = setPriority (priority, 5); timeUV = timeUV.currentDateTime().addSecs(300); - propertyList[name] = formatNotifString(propertyName[name].first, "", QByteArray::number(propertyValue)); propertiesValue[name] = propertyValue; debug (DEBUGMACRO, "Notif = #" + notif + "#", DEBUG); - } + propertyList[name] = formatNotifString(propertyName[name].first, "", QByteArray::number(propertyValue)); + } debug (DEBUGMACRO, "priority = " + QString::number(priority), DEBUG); }else if (name == "solarradiation") @@ -412,13 +407,16 @@ void Pws2mqtt::parseData(QList> queryList) notif += propertyList[name]; } } - notif += "**Prévisions à 12/24h** \n" + propertyList["prevision"]; - debug(DEBUGMACRO, "calling notify with notif = #" + notif + "#", DEBUG); if (changed) { notify (notif, priorityList[priority], attachment, tag); precPropertyList = propertyList; } + + notif = "**Prévisions à 12/24h**\n" + propertyList["prevision"]; + notify (notif, priorityList[priority], attachment, tag); + debug(DEBUGMACRO, "calling notify with notif = #" + notif + "#", DEBUG); + } debug(DEBUGMACRO, "parseData: Returning", DEBUG); } @@ -444,33 +442,6 @@ double calculerUTCI(double temperature, double humiditeRelative, double vitesseV return round(utci * 100) / 100; } -/*double windChill(double airT, double vent) -{ - double w = 0; - - if (airT > 10 or vent < 4.8) - { - return airT; - } else - { - w = 13.12 + 0.6215 * airT - 11.37 * pow(vent, 0.16) + 0.3965 * airT * pow(vent, 0.16); - debug(DEBUGMACRO, "windChill = " + QString::number(w), DEBUG); - return w; - } -}*/ - -/*double calculerHumidex(double temperature, double humiditeRelative) -{ - // Calcul de la température du point de rosée (T_rosée) - double T_rosee = (243.04 * (log(humiditeRelative / 100.0) + (17.625 * temperature) / (243.04 + temperature))) / (17.625 - (log(humiditeRelative / 100.0) + (17.625 * temperature) / (243.04 + temperature))); - - // Calcul de l'Humidex (H) - double H = temperature + 0.5555 * (6.11 * exp(5417.7530 * (1.0 / 273.16 - 1.0 / (273.15 + T_rosee))) - 10.0); - debug(DEBUGMACRO, "humidex = " + QString::number(H), DEBUG); - - return H; -}*/ - QString getPluviosite(double value, quint8 &priority) { if (value < 1) @@ -494,94 +465,6 @@ QString getPluviosite(double value, quint8 &priority) } } -QString previsionMeteo(double currentPressure, double variation3h, quint8 &priority) -{ - QString variation = ""; - - priority = 3; - debug (DEBUGMACRO, "begin", DEBUG); - - if (variation3h == 0.0) - { - variation = " - temps stable"; - }else if (variation3h > 0.2) - { - variation = " en amélioration rapide"; - }else if (variation3h < -2.0) - { - variation = "en dégradation rapide"; - }else if (variation3h > 0) - { - variation = " en amélioration"; - }else if (variation3h <0) - { - variation = " en dégradation"; - } - - if (currentPressure > 1020.0) - { - return "Beau temps (anticyclone)" + variation; - } else if (currentPressure > 1010.0 && currentPressure <= 1020.0) - { - return "Éclaircies" + variation; - } else if (currentPressure > 1000.0 && currentPressure < 1009.0) - { - priority = 3; - return "Temps variable, risque de pluie légère" + variation; - } else if (currentPressure >=990 && currentPressure <= 1000.0) - { - priority = 5; - return "Pluie/vent/orage" + variation; - } else if (currentPressure < 990.0) - { - priority = 5; - return "Tempête ou dépression forte (vigilance)" + variation; - } - return variation; -} - -/*QString pressureVariation(double currentPressure, quint8 &priority) -{ - const int NB_MESURES_3H = 360; // 3h × 120 mesures/heure (1 mesure toutes les 30s) - static QVector historiquePressions; - debug(DEBUGMACRO, "PressureVariation : current pressure = " + QByteArray::number(currentPressure), DEBUG); - - historiquePressions.append(currentPressure); - - // Si on a assez de mesures pour couvrir 3h - if (historiquePressions.size() > NB_MESURES_3H) - { - debug(DEBUGMACRO, "historiquePressions > " + QByteArray::number(NB_MESURES_3H), DEBUG); - historiquePressions.erase(historiquePressions.begin()); - } - debug(DEBUGMACRO, "taille de historiquePression : " + QByteArray::number(historiquePressions.size()), DEBUG); - // Calcul de la variation sur 3h si on a assez de mesures - if (historiquePressions.size() == NB_MESURES_3H) - { - double pressionInitiale = historiquePressions.front(); - double pressionFinale = historiquePressions.back(); - double variation = pressionFinale - pressionInitiale; - - debug(DEBUGMACRO, "Pression actuelle : " + QString::number(pressionFinale) + " hPa", DEBUG); - debug(DEBUGMACRO, "Variation sur 3h : " + QString::number(variation) + " hPa", DEBUG); - - // Prévision météo - QString prevision = previsionMeteo(pressionFinale, variation, priority); - debug(DEBUGMACRO, "Prévision : " + prevision, DEBUG); - - // Exemple : Envoi d'une alerte si nécessaire - - debug(DEBUGMACRO, "ending pressureVariation with result", DEBUG); - return prevision; - }else - { - static QTime time = QTime::currentTime().addSecs(NB_MESURES_3H * 30); - return "Première prévision à " + time.toString(); - } - debug(DEBUGMACRO, "ending pressureVariation no result", DEBUG); - return ""; -}*/ - quint8 setPriority (quint8 currentPriority, quint8 newPriority) { if (newPriority > currentPriority) @@ -630,9 +513,9 @@ QString formatNotifString (QString name, QString unit ,QByteArray value) if (!unit.isEmpty()) { text += unit; - //"- " + propertyName[name].first + " : " + value + " " + propertyName[name].second + " \n"; + //"- " + 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) { @@ -641,6 +524,14 @@ static size_t ReadFile(void *ptr, size_t size, size_t nmemb, void *stream) { 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; @@ -657,30 +548,34 @@ void notify(QString notif, QString priority, QString inputPath, QString tag) { // Définis les en-têtes pour le titre et les priorités struct curl_slist *headers = NULL; - headers = curl_slist_append(headers, ("Tags: " + tag).toStdString().c_str()); + + 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, "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 - /*curl_mime *mime; - curl_mimepart *part; + struct curl_slist *h = headers; + while (h) { + debug(DEBUGMACRO, "Header: " + QString(h->data), DEBUG); + h = h->next; + } + debug(DEBUGMACRO, "Notif: " + notif, DEBUG); - // Initialise la structure mime - mime = curl_mime_init(curl); - - // Ajoute le champ "message" (ton texte de notification) - part = curl_mime_addpart(mime); - curl_mime_name(part, "message"); - curl_mime_data(part, notif.toUtf8().constData(), CURL_ZERO_TERMINATED); -*/ // 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 @@ -692,7 +587,7 @@ void notify(QString notif, QString priority, QString inputPath, QString tag) debug(DEBUGMACRO, "Erreur libcurl :" + QString(curl_easy_strerror(res)), DEBUG); } else { - debug(DEBUGMACRO, "Notification envoyée avec succès", DEBUG); + debug(DEBUGMACRO, "Réponse du serveur: " + QString::fromStdString(readBuffer), DEBUG); } // Nettoie les ressources @@ -720,7 +615,7 @@ void notify(QString notif, QString priority, QString inputPath, QString tag) 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, "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");