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:
commit
b412d51658
46 files changed
+10608
No files matched your search
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
||||
<rect width="512" height="512" rx="112" fill="#1f7a4d"/>
|
||||
<path d="M256 400V214" stroke="#dcf0e4" stroke-width="26" stroke-linecap="round"/>
|
||||
<path d="M256 246c0-58 44-104 104-112 6 62-38 112-104 112z" fill="#7ed6a4"/>
|
||||
<path d="M256 300c0-52-40-94-94-101-5 56 34 101 94 101z" fill="#3fae7a"/>
|
||||
<path d="M168 400h176" stroke="#e8a33d" stroke-width="26" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 454 B |
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "Pollice Verde — orto e frutteto",
|
||||
"short_name": "Pollice Verde",
|
||||
"description": "Gestione dell'orto e del frutteto con piano di irrigazione calcolato sul meteo reale.",
|
||||
"start_url": "/",
|
||||
"scope": "/",
|
||||
"display": "standalone",
|
||||
"orientation": "portrait",
|
||||
"background_color": "#f7f8f5",
|
||||
"theme_color": "#1f7a4d",
|
||||
"lang": "it",
|
||||
"icons": [
|
||||
{ "src": "/icon.svg", "sizes": "any", "type": "image/svg+xml", "purpose": "any" },
|
||||
{ "src": "/icon-192.png", "sizes": "192x192", "type": "image/png", "purpose": "any" },
|
||||
{ "src": "/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "any" },
|
||||
{ "src": "/icon-maskable.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
|
||||
]
|
||||
}
|
||||
@@ -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
|
||||
})
|
||||
)
|
||||
})
|
||||
Reference in new issue
Block a user