ALAMDIENG commited on
Commit
f5271b7
·
1 Parent(s): 0508bc4

fix(weather): align weather interpretation with BMKG rainfall threshold standards

Browse files
Files changed (1) hide show
  1. frontend/app.js +58 -37
frontend/app.js CHANGED
@@ -414,38 +414,41 @@ async function fetchLiveWeather(loc) {
414
  const precipList = dailyData.precipitation_sum || [];
415
  const precipToday = precipList[2] || 0;
416
 
417
- let cond = "Cloudy";
418
- if (code === 0) cond = "Clear Sky";
419
- else if (code > 0 && code < 4) cond = "Partly Cloudy";
420
- else if (code >= 51 && code <= 67) cond = "Rainy";
421
- else if (code >= 80 && code <= 82) cond = "Showers";
 
 
 
422
 
423
  if (weatherForecastText) weatherForecastText.textContent = `${temp}°C - ${cond}`;
424
  if (weatherLocationText) weatherLocationText.textContent = `${loc} (${coord.city})`;
425
  if (weatherPrecip) weatherPrecip.textContent = `${precipToday.toFixed(1)} mm`;
426
 
427
  if (weatherAlert) {
428
- if (precipToday > 30) {
429
- weatherAlert.textContent = "HEAVY RAIN 🟡";
430
- weatherAlert.className = "highlight text-warning";
431
- } else if (precipToday > 50) {
432
  weatherAlert.textContent = "FLOOD DANGER 🔴";
433
  weatherAlert.className = "highlight text-red";
 
 
 
434
  } else {
435
- weatherAlert.textContent = "Normal conditions";
436
  weatherAlert.className = "highlight";
437
  }
438
  }
439
  } catch (err) {
440
  console.warn("Weather fetch timed out/failed. Using fallback forecast.", err);
441
  // Instant Fallback Weather Data
442
- const fallbackTemp = 28.5 + Math.random() * 3.0;
443
  const fallbackPrecip = 0.0;
444
- if (weatherForecastText) weatherForecastText.textContent = `${fallbackTemp.toFixed(1)}°C - Partly Cloudy`;
445
  if (weatherLocationText) weatherLocationText.textContent = `${loc} (${coord.city})`;
446
  if (weatherPrecip) weatherPrecip.textContent = `${fallbackPrecip.toFixed(1)} mm`;
447
  if (weatherAlert) {
448
- weatherAlert.textContent = "Normal conditions";
449
  weatherAlert.className = "highlight";
450
  }
451
  }
@@ -779,29 +782,47 @@ async function openWeatherModal(loc) {
779
  const tMin = Math.round(tempMin[idx] || 25);
780
 
781
  let icon = "☀️";
782
- let condition = "Berawan";
783
-
784
- if (wCode === 0) {
785
- icon = "☀️"; condition = "Cerah";
786
- } else if (wCode >= 1 && wCode <= 3) {
787
- icon = (wCode === 1) ? "☀️" : (wCode === 2) ? "⛅" : "☁️"; condition = "Berawan";
788
- } else if (wCode >= 51 && wCode <= 57) {
789
- icon = "🌧️"; condition = "Gerimis";
790
- } else if (wCode >= 61 && wCode <= 65) {
791
- icon = "🌧️"; condition = (pVal > 5.0) ? "Hujan Deras" : "Hujan Sedang";
792
- } else if (wCode >= 80 && wCode <= 82) {
793
- icon = "🌧️"; condition = (pVal > 6.0) ? "Hujan Deras" : "Hujan Lokal";
794
- } else if (wCode >= 95) {
795
- icon = "⛈️"; condition = "Badai Petir";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
796
  }
797
 
 
 
798
  const row = document.createElement("div");
799
  row.className = "weather-forecast-row";
800
  row.innerHTML = `
801
  <span class="w-row-day">${dayName}</span>
802
  <span class="w-row-icon">${icon}</span>
803
  <span class="w-row-cond">${condition}</span>
804
- <span class="w-row-precip">${pVal > 0 ? `${pVal.toFixed(1)}mm` : ''}</span>
805
  <div class="w-row-temp">
806
  <span class="w-temp-max">${tMax}°</span>
807
  <span class="w-temp-min">${tMin}°</span>
@@ -815,17 +836,17 @@ async function openWeatherModal(loc) {
815
  console.warn("Open-Meteo weather modal fallback:", err);
816
  // Fallback matching real Jakarta climate baseline
817
  const fallbackData = [
818
- { day: "Kam", icon: "🌧️", cond: "Hujan Deras", precip: "7.4mm", max: 33, min: 25 },
819
- { day: "Jum", icon: "🌧️", cond: "Gerimis", precip: "1.3mm", max: 33, min: 25 },
820
- { day: "Sab", icon: "☀️", cond: "Berawan", precip: "", max: 35, min: 24 },
821
- { day: "Min", icon: "🌧️", cond: "Gerimis", precip: "0.2mm", max: 34, min: 25 },
822
- { day: "Sen", icon: "🌧️", cond: "Gerimis", precip: "1.5mm", max: 34, min: 26 },
823
- { day: "Sel", icon: "☁️", cond: "Berawan", precip: "", max: 35, min: 26 },
824
- { day: "Rab", icon: "🌧️", cond: "Gerimis", precip: "3.6mm", max: 36, min: 27 }
825
  ];
826
 
827
- if (modalSumTotal) modalSumTotal.textContent = "14.0mm";
828
- if (modalSumAvg) modalSumAvg.textContent = "2.0mm/hr";
829
  if (modalSumBadge) {
830
  modalSumBadge.textContent = "KERING";
831
  modalSumBadge.className = "weather-dryness-badge dry";
 
414
  const precipList = dailyData.precipitation_sum || [];
415
  const precipToday = precipList[2] || 0;
416
 
417
+ let cond = "Cerah Berawan";
418
+ if (code === 0 && precipToday < 0.5) cond = "Cerah";
419
+ else if (code <= 2 && precipToday < 0.5) cond = "Cerah Berawan";
420
+ else if (code <= 3 && precipToday < 0.5) cond = "Berawan";
421
+ else if (precipToday >= 20.0) cond = "Hujan Lebat";
422
+ else if (precipToday >= 5.0) cond = "Hujan Sedang";
423
+ else if (precipToday >= 0.5) cond = "Hujan Ringan";
424
+ else cond = "Berawan";
425
 
426
  if (weatherForecastText) weatherForecastText.textContent = `${temp}°C - ${cond}`;
427
  if (weatherLocationText) weatherLocationText.textContent = `${loc} (${coord.city})`;
428
  if (weatherPrecip) weatherPrecip.textContent = `${precipToday.toFixed(1)} mm`;
429
 
430
  if (weatherAlert) {
431
+ if (precipToday >= 50) {
 
 
 
432
  weatherAlert.textContent = "FLOOD DANGER 🔴";
433
  weatherAlert.className = "highlight text-red";
434
+ } else if (precipToday >= 20) {
435
+ weatherAlert.textContent = "HEAVY RAIN 🟡";
436
+ weatherAlert.className = "highlight text-warning";
437
  } else {
438
+ weatherAlert.textContent = "Normal / Aman";
439
  weatherAlert.className = "highlight";
440
  }
441
  }
442
  } catch (err) {
443
  console.warn("Weather fetch timed out/failed. Using fallback forecast.", err);
444
  // Instant Fallback Weather Data
445
+ const fallbackTemp = 32.5 + Math.random() * 2.0;
446
  const fallbackPrecip = 0.0;
447
+ if (weatherForecastText) weatherForecastText.textContent = `${fallbackTemp.toFixed(1)}°C - Cerah Berawan`;
448
  if (weatherLocationText) weatherLocationText.textContent = `${loc} (${coord.city})`;
449
  if (weatherPrecip) weatherPrecip.textContent = `${fallbackPrecip.toFixed(1)} mm`;
450
  if (weatherAlert) {
451
+ weatherAlert.textContent = "Normal / Aman";
452
  weatherAlert.className = "highlight";
453
  }
454
  }
 
782
  const tMin = Math.round(tempMin[idx] || 25);
783
 
784
  let icon = "☀️";
785
+ let condition = "Cerah";
786
+
787
+ // BMKG Meteorological Standard Interpretation
788
+ if (wCode >= 95 || (wCode >= 80 && pVal >= 20.0)) {
789
+ icon = "⛈️";
790
+ condition = "Badai Petir";
791
+ } else if (pVal >= 20.0) {
792
+ icon = "🌧️";
793
+ condition = "Hujan Lebat";
794
+ } else if (pVal >= 5.0) {
795
+ icon = "🌧️";
796
+ condition = "Hujan Sedang";
797
+ } else if (pVal >= 1.5) {
798
+ icon = "🌦️";
799
+ condition = "Hujan Ringan";
800
+ } else if (pVal >= 0.5) {
801
+ icon = "⛅";
802
+ condition = "Berawan";
803
+ } else {
804
+ // Under 0.5mm is non-rainy (Cerah / Cerah Berawan)
805
+ if (wCode === 0) {
806
+ icon = "☀️";
807
+ condition = "Cerah";
808
+ } else if (wCode <= 2) {
809
+ icon = "🌤️";
810
+ condition = "Cerah Berawan";
811
+ } else {
812
+ icon = "⛅";
813
+ condition = "Berawan";
814
+ }
815
  }
816
 
817
+ const precipDisplay = pVal >= 0.5 ? `${pVal.toFixed(1)}mm` : '';
818
+
819
  const row = document.createElement("div");
820
  row.className = "weather-forecast-row";
821
  row.innerHTML = `
822
  <span class="w-row-day">${dayName}</span>
823
  <span class="w-row-icon">${icon}</span>
824
  <span class="w-row-cond">${condition}</span>
825
+ <span class="w-row-precip">${precipDisplay}</span>
826
  <div class="w-row-temp">
827
  <span class="w-temp-max">${tMax}°</span>
828
  <span class="w-temp-min">${tMin}°</span>
 
836
  console.warn("Open-Meteo weather modal fallback:", err);
837
  // Fallback matching real Jakarta climate baseline
838
  const fallbackData = [
839
+ { day: "Kam", icon: "🌦️", cond: "Hujan Ringan", precip: "1.3mm", max: 33, min: 25 },
840
+ { day: "Jum", icon: "⛅", cond: "Berawan", precip: "", max: 35, min: 25 },
841
+ { day: "Sab", icon: "🌤️", cond: "Cerah Berawan", precip: "", max: 36, min: 25 },
842
+ { day: "Min", icon: "☀️", cond: "Cerah", precip: "", max: 34, min: 26 },
843
+ { day: "Sen", icon: "🌦️", cond: "Hujan Ringan", precip: "1.5mm", max: 33, min: 26 },
844
+ { day: "Sel", icon: "🌤️", cond: "Cerah Berawan", precip: "", max: 35, min: 26 },
845
+ { day: "Rab", icon: "🌧️", cond: "Hujan Sedang", precip: "3.6mm", max: 35, min: 27 }
846
  ];
847
 
848
+ if (modalSumTotal) modalSumTotal.textContent = "6.4mm";
849
+ if (modalSumAvg) modalSumAvg.textContent = "0.9mm/hr";
850
  if (modalSumBadge) {
851
  modalSumBadge.textContent = "KERING";
852
  modalSumBadge.className = "weather-dryness-badge dry";