diff --git a/src/barometertrend.h b/src/barometertrend.h index b0a70ac..bfe170a 100644 --- a/src/barometertrend.h +++ b/src/barometertrend.h @@ -10,13 +10,13 @@ struct ForecastResult { QString message; int urgency = 0; // 0-5 - QString colorCode = ""; // "vert", "jaune", ... - bool snowRisk; - bool rainRisk; - bool stormRisk; - bool blackIce; - QString prevision1h; - quint8 confiance; + 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 @@ -25,7 +25,10 @@ class BarometerTrend : public QObject public: explicit BarometerTrend(QObject *parent = nullptr) : QObject(parent) - {} + { + m_values.reserve(360 + 16); // évite reallocs fréquentes + m_timestamps.reserve(360 + 16); + } void addPressure(double pressure_hPa) { @@ -64,162 +67,175 @@ public: } - // Variation de pression sur les dernières 3h - double deltaPressure3h() const - { - if (m_values.size() < 2) - { - return 0.0; - } - QDateTime now = QDateTime::currentDateTime(); - QDateTime target = now.addSecs(-3 * 3600); - - // Cherche la valeur la plus proche d’il y a 3 heures - int idx = -1; - for (int i = 0; i < m_timestamps.size(); ++i) - { - if (m_timestamps[i] >= target) - { - idx = i; - break; - } - } - - if (idx == -1) - { - idx = 0; // Pas assez vieux, on prend la plus ancienne - } - double p_now = smoothedPressure(); - double p_past = m_values[idx]; - debug(DEBUGMACRO, "delta pressure : " + QByteArray::number(p_now - p_past), DEBUG); - return p_now - p_past; - } - - ForecastResult forecast(double temperatureC, double humidityPercent) const + // 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(); - - r.snowRisk = false; - r.rainRisk = false; - r.stormRisk = false; - r.blackIce = false; + 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 >= 1020 && d >= +3) + if (p < 990 && d3 <= -3.0) + { + r.message = "- Tempête ou orage \n"; + 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.urgency = 0; - r.colorCode = "sunny"; + icons << "sunny"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1020 && d >= +1) + }else if (p >= 1020 && d3 >= +1.0) { r.message = "- Beau temps durable \n"; r.urgency = 0; - r.colorCode = "sunny"; + icons << "sunny"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1020 && d < -3) + }else if (p >= 1020 && d3 < -3.0) { r.message = "- Beau, mais rapide dégradation \n"; r.urgency = 4; - r.colorCode = "sun_behind_large_cloud"; + icons << "sun_behind_large_cloud"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1020 && d < -1) + }else if (p >= 1020 && d3 < -1.0) { r.message = "- Beau, mais possible dégradation \n"; r.urgency = 1; - r.colorCode = "sun_behind_small_cloud"; + icons << "sun_behind_small_cloud"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); - /*}else if (p >= 1020 && d < 0.5) + /*}else if (p >= 1020 && d3 < 0.5.0) { r.message = "- Beau temps \n"; r.urgency = 0; - r.colorCode = "sunny"; + icons << "sunny"; debug(DEBUGMACRO, "message : " + r.message, DEBUG);*/ - }else if (p >= 1010 && d >= +3) + }else if (p >= 1010 && d3 >= +3.0) { r.message = "- Nuageux, rapide amélioration \n"; r.urgency = 4; - r.colorCode = "sun_behind_small_cloud"; + icons << "sun_behind_small_cloud"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1010 && d >= +1) + }else if (p >= 1010 && d3 >= +1.0) { r.message = "- Nuageux, en amélioration \n"; r.urgency = 0; - r.colorCode = "sun_behind_large_cloud"; + icons << "sun_behind_large_cloud"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1010 && d <= -3) + }else if (p >= 1010 && d3 <= -3.0) { r.message = "- Nuageux, fort risque de pluie ou vent \n"; r.urgency = 4; - r.colorCode = "sun_behind_rain_cloud"; + icons << "sun_behind_rain_cloud"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1010 && d <= -1) + }else if (p >= 1010 && d3 <= -1.0) { r.message = "- nuageux, risque de pluie ou vent \n"; r.urgency = 2; - r.colorCode = "sun_behind_rain_cloud"; + icons << "sun_behind_rain_cloud"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1010 && d <= 0.5) + }else if (p >= 1010 && d3 <= 0.5) { r.message = "- Nuageux avec des éclaircies \n"; r.urgency = 2; - r.colorCode = "sun_behind_large_cloud"; + icons << "sun_behind_large_cloud"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1000 && d >= +3) + }else if (p >= 1000 && d3 >= +3.0) { r.message = "- Variable, amélioration rapide \n"; r.urgency = 4; - r.colorCode = "sun_behind_large_cloud"; + icons << "sun_behind_large_cloud"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1000 && d >= +1) + }else if (p >= 1000 && d3 >= +1.0) { r.message = "- Variable, tendance au beau \n"; r.urgency = 0; - r.colorCode = "sun_behind_large_cloud"; + icons << "sun_behind_large_cloud"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1000 && d <= -3) + }else if (p >= 1000 && d3 <= -3.0) { r.message = "- Pluie ou perturbation, dégradation rapide \n"; r.urgency = 4; - r.colorCode = "cloud_with_rain"; + icons << "cloud_with_rain"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p >= 1000 && d <= -1) + }else if (p >= 1000 && d3 <= -1.0) { r.message = "- Pluie ou perturbation \n"; r.urgency = 2; - r.colorCode = "cloud_with_rain"; + icons << "cloud_with_rain"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p < 990 && d <= -3) - { - r.message = "- Tempête ou orage \n"; - r.urgency = 5; - r.colorCode = "cloud_with_lightning"; - debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p < 1000 && d >= +3) + }else if (p < 1000 && d3 >= +3.0) { r.message = "- Pluie avec accalmie temporaire, amélioration rapide \n"; r.urgency = 1; - r.colorCode = "sun_behind_rain_cloud"; + icons << "sun_behind_rain_cloud"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p < 1000 && d >= +1) + }else if (p < 1000 && d3 >= +1.0) { r.message = "- Pluie avec accalmie temporaire \n"; r.urgency = 1; - r.colorCode = "sun_behind_rain_cloud"; + icons << "sun_behind_rain_cloud"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); - }else if (p < 1000 && d <= -1) + }else if (p < 1000 && d3 <= -1.0) { r.message = "- Mauvais temps durable \n"; r.urgency = 4; - r.colorCode = "cloud_with_rain"; + icons << "cloud_with_rain"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); } - if (qAbs(d) < 1) + if (qAbs(d3) < 1) { r.message += "- Stable, pas de changement significatif \n"; r.urgency = 0; @@ -227,38 +243,38 @@ public: } // Risque de neige - if (p < 1000 && d < -1 && temperatureC <= 1.0 && humidityPercent > 80.0) + if (p < 1000 && d3 < -1.0 && temperatureC <= 1.0 && humidityPercent > 80.0) { r.snowRisk = true; r.message += "- Risque de neige \n"; r.urgency = qMax(r.urgency, 3); - r.colorCode += "snowflake,"; + icons << "snowflake"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); } // Risque de pluie - else if (p < 1010 && d < -1 && temperatureC > 1.0 && humidityPercent > 70.0) + else if (p < 1010 && d3 < -1.0 && temperatureC > 1.0 && humidityPercent > 70.0) { r.rainRisk = true; r.message += "- Risque de pluie \n"; r.urgency = qMax(r.urgency, 2); - r.colorCode += "cloud_with_rain,"; + icons << "cloud_with_rain"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); } // Risque d’orage - if (p < 995 && d < -3 && temperatureC > 20.0 && humidityPercent > 70.0) + if (p < 995 && d3 < -3.0 && temperatureC > 20.0 && humidityPercent > 70.0) { r.stormRisk = true; r.message += "- Risque d’orage \n"; r.urgency = qMax(r.urgency, 4); - r.colorCode += "cloud_with_lightning,"; + icons << "cloud_with_lightning"; debug(DEBUGMACRO, "message : " + r.message, DEBUG); } if (temperatureC <= 0.5 && humidityPercent >= 85.0) { // conditions classiques de gel - if (d >= -1 && d <= +1) + if (d3 >= -1.0 && d3 <= +1.0) { r.blackIce = true; // temps stable = ciel clair = refroidissement }else if (d < -1 && p > 995) @@ -270,13 +286,13 @@ public: if (r.blackIce) { r.message += "- Risque de verglas \n"; - r.colorCode += "ice_cube,"; + 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) + if (d <= -1.5 && p < 1010 && humidityPercent > 80.0) { r.prevision1h = "☔ Pluie probable dans l’heure \n"; r.urgency = qMax(r.urgency, 4); @@ -285,7 +301,7 @@ public: { r.prevision1h = "🌤 Amélioration probable dans l’heure \n"; r.confiance = 85; - }else if (qAbs(d) < 0.3 && qAbs(temperatureC) < 0.5) + }else if (qAbs(d1) < 0.3 && qAbs(temperatureC) < 0.5) { r.prevision1h = "⛅ Conditions stables pour la prochaine heure \n"; r.confiance = 70; @@ -321,6 +337,8 @@ public: } debug(DEBUGMACRO, "message : " + r.message, DEBUG); + if (!icons.isEmpty()) r.icons = icons.join(","); + return r; } diff --git a/src/pws2mqtt.cpp b/src/pws2mqtt.cpp index 8267f0d..e20e673 100644 --- a/src/pws2mqtt.cpp +++ b/src/pws2mqtt.cpp @@ -325,7 +325,7 @@ void Pws2mqtt::parseData(QList> queryList) prevision = newPrevision; propertyList["prevision"] = prevision; priority = setPriority(priority, ret.urgency); - tag += ret.colorCode; + tag += ret.icons; } debug (DEBUGMACRO, "priority = " + QString::number(priority), DEBUG); }else if (name == "UV")