Backup automatico script del 2026-02-15 07:00

This commit is contained in:
2026-02-15 07:00:02 +01:00
parent 812bcd002c
commit 11b6768fa3
@@ -1828,12 +1828,11 @@ def analyze_irrigation(
if rain_veto:
veto_lines.append(f"🌧️ **VETO PIOGGIA**: Ultime 24h ≥ {PRECIP_VETO_MM_24H:.0f} mm — non avviare irrigazione.")
# Colpo d'occhio (box informazioni chiave)
# Colpo d'occhio
glance = [
status.strip(),
f"📍 {location_name} · {now.strftime('%d/%m/%Y %H:%M')}",
"",
"**Umidità (layer irrigazione)**",
moisture_summary_line.strip(),
"",
]
@@ -1848,123 +1847,72 @@ def analyze_irrigation(
# Costruisci report completo (strutturato)
report_parts = [
"\n".join(glance),
""*30,
"",
"**📋 CONSIGLIO**",
"",
""*24,
"**Consiglio**",
advice,
"",
]
if timing_advice:
report_parts.append("**Orario / Radiazione**\n")
report_parts.append("\n".join("" + t for t in timing_advice))
report_parts.append("**Orario** " + " · ".join(timing_advice))
report_parts.append("")
if planning_8d_line:
report_parts.append(planning_8d_line)
report_parts.append(planning_8d_line.strip())
report_parts.append("")
report_parts.append(""*24)
# Dettagli tecnici (organizzati)
# Dettagli tecnici (compatti, at a glance)
details = []
# Temperatura suolo: 0, 6, 18, 54 cm (ICON Seamless / EU)
soil_temp_0cm = _at(current_idx, soil_temp_0cm_list)
soil_temp_54cm = _at(current_idx, soil_temp_54cm_list)
temp_found = False
for label, val in [
("0cm", soil_temp_0cm),
("6cm", soil_temp_6cm),
("18cm", soil_temp_18cm),
("54cm", soil_temp_54cm),
]:
temp_parts = []
for label, val in [("0cm", soil_temp_0cm), ("6cm", soil_temp_6cm), ("18cm", soil_temp_18cm), ("54cm", soil_temp_54cm)]:
if val is not None:
temp_class = classify_soil_temp(val)
trend_str = f" | trend 7gg: {temp_trend}" if (temp_trend and label == "6cm") else ""
details.append(f"🌡️ T° suolo ({label}): {val:.1f}°C ({temp_class}){trend_str}")
temp_found = True
if not temp_found:
for i in range(current_idx, min(current_idx + 48, len(soil_temp_0cm_list or []))):
if i < len(soil_temp_0cm_list) and soil_temp_0cm_list[i] is not None:
details.append(f"🌡️ T° suolo (0cm): {float(soil_temp_0cm_list[i]):.1f}°C (prossime ore)")
temp_found = True
break
# Umidità suolo: 0-1, 3-9, 9-27, 27-81 cm (ICON Seamless / EU). Mostriamo sempre tutti i layer.
moisture_found = False
for label, val in [
("0-1cm", soil_moisture_0_1cm),
("3-9cm", soil_moisture_3_9cm),
("9-27cm", soil_moisture_9_27cm),
("27-81cm", soil_moisture_27_81cm),
]:
temp_parts.append(f"{label} {val:.1f}°C")
if temp_parts:
trend_str = f" · trend 7gg: {temp_trend}" if temp_trend else ""
details.append("🌡️ T° suolo: " + " · ".join(temp_parts) + trend_str)
elif soil_temp_0cm_list and current_idx < len(soil_temp_0cm_list) and soil_temp_0cm_list[current_idx] is not None:
details.append(f"🌡️ T° suolo 0cm: {float(soil_temp_0cm_list[current_idx]):.1f}°C")
moist_parts = []
any_at_fc = False
for label, val in [("0-1", soil_moisture_0_1cm), ("3-9", soil_moisture_3_9cm), ("9-27", soil_moisture_9_27cm), ("27-81", soil_moisture_27_81cm)]:
if val is not None:
moisture_class = classify_soil_moisture(val)
line = f"💧 Umidità ({label}): {val*100:.0f}% ({moisture_class})"
moist_parts.append(f"{label} {val*100:.0f}%")
if val >= SOIL_MOISTURE_FIELD_CAPACITY:
line += " — terreno pieno, possibile fanghiglia/ristagno"
details.append(line)
moisture_found = True
any_at_fc = True
else:
details.append(f"💧 Umidità ({label}): — (non disponibile)")
if not moisture_found:
for i in range(current_idx, min(current_idx + 48, len(soil_moisture_0_1_list or []))):
if i < len(soil_moisture_0_1_list) and soil_moisture_0_1_list[i] is not None:
v = float(soil_moisture_0_1_list[i])
details.append(f"💧 Umidità (0-1cm): {v*100:.0f}% (prossime ore)")
moisture_found = True
break
if not temp_found and not moisture_found:
details.append("️ Dati suolo non disponibili per questa località")
# ET₀ e parametri evapotraspirazione
moist_parts.append(f"{label}")
if moist_parts:
line = "💧 Umidità: " + " · ".join(moist_parts)
if any_at_fc:
line += " — terreno pieno"
details.append(line)
if not details:
details.append("️ Dati suolo non disponibili")
# Una riga: ET₀, VPD, sole, umidità aria
meteo_parts = []
if et0_avg is not None:
et0_class = classify_et0(et0_avg)
details.append(f"☀️ ET₀ medio (24h): {et0_avg:.1f} mm/d ({et0_class})")
# Vapour Pressure Deficit (stress idrico)
meteo_parts.append(f"ET₀ {et0_avg:.1f} mm/d")
if vpd_avg is not None:
vpd_class = classify_vpd(vpd_avg)
# VPD alto = stress idrico alto
vpd_status = ""
if vpd_avg > 1.5:
vpd_status = " (stress idrico elevato)"
elif vpd_avg > 1.0:
vpd_status = " (stress moderato)"
details.append(f"💨 VPD medio (24h): {vpd_avg:.2f} kPa ({vpd_class}){vpd_status}")
# Ore di sole previste
meteo_parts.append(f"VPD {vpd_avg:.2f} kPa")
if sunshine_hours is not None:
sunshine_class = classify_sunshine(sunshine_hours)
details.append(f"☀️ Ore sole previste (24h): {sunshine_hours:.1f}h ({sunshine_class})")
# Umidità relativa aria
meteo_parts.append(f"Sole {sunshine_hours:.1f}h")
if humidity_avg is not None:
# Classifica umidità relativa (bassa < 40%, media 40-70%, alta > 70%)
if humidity_avg < 40:
humidity_class = "basso (secco)"
elif humidity_avg < 70:
humidity_class = "medio"
else:
humidity_class = "alto (umido)"
details.append(f"💨 Umidità relativa aria (24h): {humidity_avg:.0f}% ({humidity_class})")
# Precipitazioni previste (include neve)
meteo_parts.append(f"UR {humidity_avg:.0f}%")
if meteo_parts:
details.append("☀️ " + " · ".join(meteo_parts))
# Precipitazioni: una riga
if future_rain_total > 0:
# Classifica come totale su 5 giorni (media giornaliera approssimativa)
avg_daily = future_rain_total / 5.0
precip_class = classify_precip_daily(avg_daily)
precip_str = f"🌧️ Precipitazioni previste (5gg): {future_rain_total:.1f}mm ({precip_class}, media ~{avg_daily:.1f}mm/giorno)"
if rainy_days:
precip_str += f"\n Giorni: {', '.join(rainy_days[:3])}" # Primi 3 giorni
if len(rainy_days) > 3:
precip_str += f" +{len(rainy_days)-3} altri"
details.append(precip_str)
elif len(rainy_days) == 0:
details.append("🌧️ Precipitazioni previste (5gg): 0mm (basso)")
days_short = ", ".join(rainy_days[:3]) if rainy_days else ""
details.append(f"🌧️ Precip 5gg: {future_rain_total:.1f} mm — {days_short}")
else:
details.append("🌧️ Precip 5gg: 0 mm")
if details:
report_parts.append(""*30)
report_parts.append("**📊 Dettagli tecnici**")
report_parts.append("")
report_parts.append("**Dettagli**")
report_parts.append("\n".join(details))
# Salva stato