Pollice Verde: gestione dell'orto e del frutteto con irrigazione calcolata

App PWA che dice cosa fare nell'orto e, soprattutto, quanta acqua dare a ogni
coltura, calcolandolo sul meteo reale invece che su un calendario fisso.

Motore idrico (metodo FAO-56)
- il terreno come serbatoio: capacità dal tipo di suolo per la profondità
  radicale, prelievo giornaliero pari a ET0 × Kc, ricarica da pioggia efficace e
  irrigazioni al netto dell'efficienza del metodo
- bilancio ricostruito su 21 giorni reali e proiettato su 10 di previsione, così
  si sa anche fra quanti giorni servirà il prossimo turno e quando saltarlo
- soglia di intervento dipendente dal metodo: con la goccia si bagna al 55%
  della riserva utile, con l'aspersione all'85%, a mano si sfrutta tutto
- correzioni per pacciamatura, serra e coltura in vaso

Dati
- 58 schede fra ortaggi, frutta e aromatiche con coefficienti colturali,
  profondità radicali e fattori di deplezione da FAO-56, più calendario, sesti,
  consociazioni, cure e problemi tipici
- ricerca che capisce i nomi dialettali: cocomero, popone, petonciano, ramerino
- meteo ed evapotraspirazione da Open-Meteo, senza chiave API, con cache offline

Automazione
- generatore di programma per centraline a settori: ritmo di regime da impostare
  e giorni esatti con le piogge già scontate
- agente Node che custodisce lo stato, esegue i turni un settore alla volta e
  registra nel diario quello che ha davvero erogato
- driver per ESP32, Shelly Gen1/Gen2, Tasmota, più modalità simulata predefinita
- sonde Watermark: veto sui turni, riancoraggio del bilancio su misura reale,
  confronto fra sonda e calcolo
- sicurezze: tetti su minuti e litri, blocchi gelo/vento/pioggia, chiusura
  all'avvio e all'uscita, doppia chiusura a tempo lato dispositivo, un settore
  per volta, sospensione dei settori con sonda muta o guasta

Firmware ESP32 incluso, con schema di collegamento e istruzioni di posa.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GFnqupGt8T5HNNhPPHCjKs
This commit is contained in:
lucianoandClaude Opus 5 committed 2026-09-07 14:40:49 +02:00
commit b412d51658
46 files changed
+10608

No files matched your search

+52
View File
@@ -0,0 +1,52 @@
/* Service worker minimale: l'app deve aprirsi anche in fondo all'orto senza campo.
- guscio dell'app: cache-first, aggiornata in sottofondo
- meteo: rete per prima, con l'ultima risposta buona come rete di sicurezza */
const CACHE = "pollice-verde-v1"
const GUSCIO = ["/", "/index.html", "/manifest.webmanifest", "/icon.svg"]
self.addEventListener("install", (e) => {
e.waitUntil(caches.open(CACHE).then((c) => c.addAll(GUSCIO)).then(() => self.skipWaiting()))
})
self.addEventListener("activate", (e) => {
e.waitUntil(
caches.keys().then((chiavi) => Promise.all(chiavi.filter((k) => k !== CACHE).map((k) => caches.delete(k))))
.then(() => self.clients.claim())
)
})
self.addEventListener("fetch", (e) => {
const req = e.request
if (req.method !== "GET") return
const url = new URL(req.url)
if (url.hostname.endsWith("open-meteo.com")) {
e.respondWith(
fetch(req)
.then((r) => {
const copia = r.clone()
caches.open(CACHE).then((c) => c.put(req, copia))
return r
})
.catch(() => caches.match(req))
)
return
}
if (url.origin !== location.origin) return
e.respondWith(
caches.match(req).then((colpo) => {
const rete = fetch(req)
.then((r) => {
if (r.ok) {
const copia = r.clone()
caches.open(CACHE).then((c) => c.put(req, copia))
}
return r
})
.catch(() => colpo || caches.match("/index.html"))
return colpo || rete
})
)
})