Skip to content

Chiudere un mese di fatturazione ​

Dal file che arriva dal distributore al CSV che alimenta la fatturazione ci sono cinque passi. Si possono fare tutti dal pannello, e tutti dalle API: qui ci sono entrambe le strade, e soprattutto come si capisce a che punto si è fra un passo e l'altro.

Il passo che si dimentica più facilmente è il terzo.

In breve ​

#passoAPIquando
1Caricare gli archiviPOST /v1/metering/uploadsquando arrivano
2Elaborarliautomatico alle 02:00, o POST /v1/metering/uploads/{id}/elaboradopo il caricamento
3Ricalcolare gli aggregati del mesePOST /v1/metering/reprocess con solo_aggregatiprima di fatturare, sempre
4Verificare che il mese sia chiudibileGET /v1/metering/chiusura?mese=prima di fatturare
5EsportareGET /v1/metering/export/tracciato?mese=a verifica superata

1. Caricare gli archivi ​

Si apre una sessione dichiarando i file, si caricano agli indirizzi ricevuti, si chiude.

http
POST /v1/metering/uploads
X-Tenant-Id: TENANT_NAME

{ "file": ["2026-09-29_2026-09-30.zip", "2026-10-01_2026-10-03.zip"],
  "dimensioni": { "2026-09-29_2026-09-30.zip": 2062548992 } }

La risposta porta un upload_id e, per ogni file, o un url unico oppure — sopra i 100 MB — un elenco di parti da caricare una per una. Gli archivi del SII stanno quasi sempre fra 2 e 3,5 GB, quindi si va quasi sempre a parti.

Caricati i file si chiude la sessione:

http
POST /v1/metering/uploads/{upload_id}/completa

Come si capisce se un caricamento è andato a buon fine ​

Questa è la domanda che il diario da solo non risponde, perché registra la sessione e non i singoli file.

http
GET /v1/metering/uploads

Restituisce, per ogni lotto, una riga per file con uno di quattro stati:

statosignifica
completatoil file è su S3, con i byte che occupa
in_corsosta ancora salendo: byte, parti, percentuale se si conosce l'atteso
interrottofermo da più di cinque minuti senza una parte nuova: va ricaricato
mai_iniziatodichiarato all'apertura ma mai partito

fermo_da_minuti conta dall'ultima parte arrivata, non dall'apertura del caricamento: serve a distinguere un trasferimento lento da uno morto.

Lo stesso si vede nel pannello, in Misure → Caricamenti.

Lo stesso file può comparire in due lotti

Se un trasferimento si pianta e lo si riapre, il file sale in un lotto nuovo e quello vecchio resta mezzo salito. Dopo sei ore la pulizia chiude il trasferimento morto e lo annota nel diario — ma guarda prima se quel file è arrivato per altra via:

  • se non è arrivato, l'evento è fallito: «non è mai stato completato … va ricaricato»;
  • se è arrivato con un altro caricamento, l'evento è saltato: «il file però è arrivato intero con un altro caricamento … non serve ricaricarlo».

Vale la pena saperlo perché il diario e l'elenco dei caricamenti possono sembrare in contraddizione sullo stesso nome di file: il diario racconta un trasferimento, l'elenco riconcilia da S3 e guarda il file. Fino al 2026-10-14 l'avviso diceva «va ricaricato» senza fare quel controllo.

2. Elaborare ​

L'elaborazione parte da sola alle 02:00 (ora di Roma) e prende tutti i file nuovi. Se non si vuole aspettare:

http
POST /v1/metering/uploads/{upload_id}/elabora

Un archivio sopra i 2 GB viene prima scompattato e poi letto, in un'unica corsa: non serve fare nulla di diverso.

Per seguirla:

http
GET /v1/metering/batches/{upload_id}     # quanti file sono stati letti
GET /v1/metering/stato?mese=2026-09      # lo stato della catena, contato sul mese

Il mese qui non è un dettaglio

Senza mese, /stato conta su tutti i mesi presenti: su tutto l'archivio i POD-mese che quadrano sono il 34,7%, su settembre 2026 da solo il 15,6%. Chiudendo un mese si guarda quel mese — il totale risponde a un'altra domanda. Vedi su quale periodo contano quei numeri.

3. Ricalcolare gli aggregati del mese ​

È il passo obbligatorio, ed è quello che si dimentica.

http
POST /v1/metering/reprocess
{ "da": "2026-09", "a": "2026-09", "solo_aggregati": true }

Pochi minuti. Non rilegge nessun file: ricalcola il mensile dal giornaliero già a terra.

Perché serve sempre ​

Gli aggregati mensili vengono costruiti durante la corsa che trasforma i file. Se nella stessa corsa arrivano più archivi — ed è la norma, se ne caricano quattro o cinque alla volta — i primi aggregati nascono su un mese ancora incompleto e restano così.

Non è un'ipotesi. Il 13 ottobre 2026, dopo aver elaborato gli archivi che completavano settembre:

prima del ricalcolodopo
MWh del mese9.06129.324
POD fatturabili1.99025.214
giorni coperti, media per POD7,422,1

Tre volte il consumo. Il sistema non stava sbagliando in silenzio — teneva quei POD fuori dai fatturabili — ma nessuna schermata diceva che bastavano pochi minuti per sistemarli.

4. Verificare che il mese sia chiudibile ​

http
GET /v1/metering/chiusura?mese=2026-09

Due cose nella risposta contano più delle altre.

coerenza confronta il totale degli aggregati con la somma del giornaliero:

json
"coerenza": {
  "mwh_mensile": 29323.939,
  "mwh_giornaliero": 27522.315,
  "rapporto": 0.94,
  "aggregato_da_ricalcolare": false
}

Se aggregato_da_ricalcolare è true, lo scarto supera il 15 % e il passo 3 non è stato fatto, o è stato fatto prima che arrivassero altri file. La risposta dice anche come rimediare.

pronto è true solo se tutti i POD-mese sono in stato quadrato e la coerenza regge. Un mese il cui aggregato non concorda con il giornaliero non è pronto nemmeno se i conteggi tornano: si starebbe fatturando un numero costruito su meno dati di quelli disponibili.

Gli stati intermedi, e cosa farci ​

Ogni POD-mese ha uno stato. Solo quadrato è fatturabile.

statocosa è successocosa fare
quadratoil consumo viene dalla curva, oppure registri e curva coincidono entro tolleranzaniente: è fatturabile
periodo_incompletocalcolato dai registri, ma la finestra di lettura è più corta del meseservono le letture mancanti: caricare gli archivi del periodo
periodo_estesola finestra è più lunga: tira dentro giorni del mese precedenteva corretto a mano: fattura di più del dovuto
curva_incompletanon quadra e la curva copre pochi giornicaricare gli archivi mancanti, poi rifare il passo 3
da_verificareregistri e curva divergono oltre tolleranzaserve un controllo: le due fonti non raccontano la stessa cosa

periodo_incompleto e periodo_esteso sono errori opposti e vanno distinti. Il primo fattura meno del dovuto, il secondo di più. Il secondo è meno intuitivo ma più grave davanti a un cliente.

La finestra giusta è dall'ultimo giorno del mese precedente all'ultimo giorno del mese: è la convenzione con cui fattura il distributore, verificata su bollette reali.

Su settembre 2026, dopo il ricalcolo:

periodo_incompleto    89.351     ← mancano letture
da_verificare         46.533     ← registri e curva divergono
quadrato              25.214     ← fatturabili
curva_incompleta         566
periodo_esteso            30     ← da correggere a mano

La regola: certo e stimato ​

Dal primo giorno del mese successivo si fattura, ci siano o no tutti i consumi. I giorni misurati sono certi; quelli che mancano si stimano. Le due cose restano separate fino alla bolletta.

L'esportazione estesa porta sei colonne che applicano questa regola:

colonnacosa contiene
giorni_certigiorni con misura vera nel mese
giorni_stimati_calci restanti
kwh_certiconsumo dei giorni misurati
kwh_stimatistima dei giorni mancanti
kwh_mese_regolail totale da fatturare
quota_stimata_pctquanta parte del totale è stimata
base_certezzain parole, su cosa poggia la riga

I tre casi ​

Il totale è già certo quando i registri aprono l'ultimo giorno del mese precedente e chiudono l'ultimo del mese: è quanto ha contato il contatore. Non si stima niente, anche se la curva ha buchi — il contatore accumula lo stesso. Vale anche quando è il distributore a dichiarare i totali.

A settembre 2026 sono 70.965 POD su 161.694, il 44 %.

Parzialmente misurato: i giorni con misura sono certi, i mancanti si stimano con la media giornaliera di quel POD in quel mese. Non una media di categoria, non un profilo standard: la media del POD stesso, che ne rispetta la taglia e la stagione.

Nessun giorno misurato: non si stima dal POD stesso, perché non c'è niente da cui partire. La riga esce con totale vuoto e base_certezza lo dichiara. A settembre sono 9.497 righe.

Quanto è affidabile la stima ​

Verificata sul dato vero, non assunta. Su 387 POD che avevano il totale certo dai contatori e solo 10–25 giorni di curva, la stima per media giornaliera sbaglia in media il 4,3 %, e sta entro il 15 % nel 94,3 % dei casi.

Su settembre 2026 nel complesso:

kWh certi        27.522 MWh
kWh stimati      10.512 MWh
totale           38.795 MWh      ← 27,1 % stimato

Perché le colonne sono in più e non al posto delle altre ​

delivery_net_total resta quello che era: il totale calcolato dal metodo scelto dal sistema. kwh_mese_regola applica questa regola. Tenerle entrambe permette di confrontarle su fatture vere prima di spostare la fatturazione sulla seconda — e sull'esempio reale differiscono del 21 %, che è esattamente la settimana mancante.

5. Esportare ​

http
GET /v1/metering/export/tracciato?mese=2026-09
→ { "job": "…", "stato": "in_coda" }

GET /v1/metering/export/tracciato?job=…
→ { "stato": "pronto", "scarica": "/v1/metering/export/scarica/…", "righe": 168222 }

GET /v1/metering/export/scarica/{job}
→ { "url": "https://…", "vale_secondi": 300 }

Il collegamento si firma al momento della richiesta e vale cinque minuti. I file restano disponibili sessanta giorni, poi si cancellano da soli; dal pannello si possono eliminare prima.

Nel pannello: Esportazioni.

Il giro completo, in sequenza ​

bash
T="X-Tenant-Id: TENANT_NAME"
A="Authorization: Bearer $TOKEN"

# 3 — ricalcolo degli aggregati del mese
curl -X POST https://api.base9.app/v1/metering/reprocess -H "$T" -H "$A" \
     -H 'Content-Type: application/json' \
     -d '{"da":"2026-09","a":"2026-09","solo_aggregati":true}'

# 4 — il mese è chiudibile?
curl "https://api.base9.app/v1/metering/chiusura?mese=2026-09" -H "$T" -H "$A" \
  | jq '{pronto, fatturabili, coerenza}'

# 5 — esportazione
JOB=$(curl -s "https://api.base9.app/v1/metering/export/tracciato?mese=2026-09" \
        -H "$T" -H "$A" | jq -r .data.job)
curl -s "https://api.base9.app/v1/metering/export/tracciato?job=$JOB" -H "$T" -H "$A" | jq .data

Errori che si fanno, in ordine di frequenza ​

Saltare il passo 3. È il più comune e il più silenzioso: i numeri ci sono, sono solo più bassi del vero. Dalla versione del 13 ottobre 2026 GET /chiusura lo dice da solo, nel blocco coerenza.

Fidarsi del diario per sapere se un caricamento è finito. Il diario registra la sessione; i file li dice GET /v1/metering/uploads.

Leggere fatturabili senza guardare coerenza. Si può avere un numero alto di POD quadrati su un aggregato costruito a metà.

Fatturare righe in periodo_esteso. Sono poche — trenta su centosessantamila a settembre — ma ognuna fattura più del dovuto.