Open moddroid94 opened 6 months ago
Ciao, ho notato che e' online il nuovo sito di GME.
Ciao, non l'avevo notato... certo che sono riusciti a fare uno pure peggio del precedente....
Il nuovo sito utilizza un endpoint API per scaricare il file zip, e ho pensato che si potesse semplificare la parte di download dal sito in quanto particolarmente convoluta.
Almeno questo sì è migliorato.
Dopo un po' di tinkering sono riuscito a emulare una request che ci consente di scaricare lo zip senza fare scraping di valori sul sito con BeautifulSoup.
Molto bene, di là (sul vecchio) non c'ero riuscito.
Quando la richiesta viene effettuata dal browser, vi e' un campo aggiuntivo:
requestverificationtoken
. Ma anche omettendo il token l'API sembra funzionare da terminale o codice.
Da browser c'ho messo un bel po' a ritrovare il link (QUESTO) da dove scaricare lo ZIP. Per fortuna non hanno cambiato il formato interno.
PS. Ho forkato la repo e sto facendo un po' di clean up / spostamento di classi nei rispettivi moduli cosi' da seguire meglio le linee guida per le integrazioni di HA e rendere il codice un po' piu' leggibile,
Ho visto, purtroppo io non sono del mestiere 😉 ma più un hobbista, quindi mi sono arrangiato un po' con Google per risolvere il problema (no IA).
I match case ad esempio li avevo evitati perché mi sembravano meno leggibili... 😮 però effettivamente mi pare che la tua versione vada molto bene. Il chaining degli operatori ((a and b) > 0
) invece ignoravo proprio esistesse!
Vabbè, sono qui per imparare!
e possibilmente rendere piu' semplice l'adattamento ad un cambiamento come quello descritto qua #38
Intendi il discorso che facevo sotto del calcolo del totale della bolletta (sperando che nel frattempo non ci cambino il PUN)?
non appena avro' testato le modifiche faccio una draft per una PR cosi da poter vedere insieme i cambiamenti.
Certamente, grazie!
Ciao @virtualdj ,
Per quanto riguarda le API si avevo provato anche io con la tua repo in locale ma era troppo complicato usare bs4, per quanto hobbista hai escogitato un metodo non banale per emulare quel download! 👌
Ad ogni modo si i match li ho usati con parsimonia perche' comunque prediligo la leggibilita' del codice alla pura performance, ma dove si puo 😁
Per il futuro intendevo sia l'integrazione della bolletta, che ho "simulato" anche io con helper & Co. e vorrei aiutare a integrare, e sia per quanto riguarda la questione delle zonali, che sul sito nuovo sembra oltretutto essere gia' disponibile, anche se non ho capito assolutamente nulla di come funzioni 😂
Comunque ho testato il fork e sembra funzionare, magari proviamo a farlo girare un paio di giorni, magari anche su qualche altra istanza giusto per sicurezza, ho fatto altre due modifiche che ora committo e per ora lo sto facendo girare su docker e ha recuperato zip e settato tutto correttamente.
Comunque giusto per provare ho buttato su sulla seconda istanza Docker il tuo fork e c'è qualcosa che non va sul calcolo delle fasce.
Dal log vedo questo:
2024-05-07 23:28:22.988 WARNING (SyncWorker_3) [homeassistant.loader] We found a custom integration pun_sensor which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant
2024-05-07 23:28:30.576 DEBUG (MainThread) [custom_components.pun_sensor.coordinator] Coordinator inizializzato (con 'usa dati reali' = False).
2024-05-07 23:28:30.577 DEBUG (MainThread) [custom_components.pun_sensor.coordinator] Ora corrente sistema: Tue 07/05/2024 23:28:30 +0200
2024-05-07 23:28:30.577 DEBUG (MainThread) [custom_components.pun_sensor.coordinator] Ora corrente fuso orario italiano: Tue 07/05/2024 23:28:30 +0200
2024-05-07 23:28:30.579 INFO (MainThread) [custom_components.pun_sensor.coordinator] Nuova fascia corrente: F1 (prossima: Tue 07/05/2024 19:00:00 +0200)
2024-05-07 23:28:30.579 DEBUG (MainThread) [custom_components.pun_sensor.coordinator] Manually updated pun_sensor data
2024-05-07 23:28:30.579 DEBUG (MainThread) [custom_components.pun_sensor.coordinator] Ora corrente sistema: Tue 07/05/2024 23:28:30 +0200
2024-05-07 23:28:30.580 DEBUG (MainThread) [custom_components.pun_sensor.coordinator] Ora corrente fuso orario italiano: Tue 07/05/2024 23:28:30 +0200
2024-05-07 23:28:30.581 INFO (MainThread) [custom_components.pun_sensor.coordinator] Nuova fascia corrente: F1 (prossima: Tue 07/05/2024 19:00:00 +0200)
2024-05-07 23:28:30.581 DEBUG (MainThread) [custom_components.pun_sensor.coordinator] Manually updated pun_sensor data
2024-05-07 23:28:30.582 DEBUG (MainThread) [custom_components.pun_sensor.coordinator] Ora corrente sistema: Tue 07/05/2024 23:28:30 +0200
2024-05-07 23:28:30.582 DEBUG (MainThread) [custom_components.pun_sensor.coordinator] Ora corrente fuso orario italiano: Tue 07/05/2024 23:28:30 +0200
2024-05-07 23:28:30.583 INFO (MainThread) [custom_components.pun_sensor.coordinator] Nuova fascia corrente: F1 (prossima: Tue 07/05/2024 19:00:00 +0200)
...
Come vedi sbaglia a calcolare la prossima fascia (la mette nel passato) e questo causa un loop continuo che blocca tutto. Ora però non riesco a fare il debug, sono troppo stanco dalla giornata 😪
Si avevo notato 😂
Mi era fatto prendere la mano con quei comparison e ne ho messo uno che non poteva ritornare vero nemmeno se pregavo 🤣
In teoria ho fixato tutto, quando poi hai tempo puoi provare ad aggiornarlo da hacs :)
Scusate se mi intrometto ma vorrei seguire la discussione perché avendomi fatto scoprire che il sito è cambiato ho paura che prima o poi dovrò rimettere mano al codice per scaricare i prezzi zonali, che avevo realizzato con il componente multiscrape, e in questa discussione vedo la possibilità di trarre spunti utili.
Se posso dare il mio piccolo contributo (ne so mooooolto meno di voi), se utile e non indiscreto, credo che l'endpoint per accedere ai prezzi zonali in XML sia il seguente https://gme.mercatoelettrico.org/DesktopModules/GmeEsitiPrezziME/API/item/GetMEPrezzi?DataInizio=20240509&DataFine=20240509&Granularita=h&Mercato=MGP&Zona=NORD&Tipologia=PrezziZonali
Ovviamente usato così nudo e crudo non funziona, restituisce un errore, ma non se se è una problematica di referrer come menzionato sopra, o di cookie (tramite l'accettazione delle condizioni di uso nella videata che ora è un pop-up).
Pagina web con i prezzi zonali: https://gme.mercatoelettrico.org/it-it/Home/Esiti/Elettricita/MGP/Esiti/PrezziZonali#IntestazioneGrafico
Se posso dare il mio piccolo contributo (ne so mooooolto meno di voi), se utile e non indiscreto, credo che l'endpoint per accedere ai prezzi zonali in XML sia il seguente https://gme.mercatoelettrico.org/DesktopModules/GmeEsitiPrezziME/API/item/GetMEPrezzi?DataInizio=20240509&DataFine=20240509&Granularita=h&Mercato=MGP&Zona=NORD&Tipologia=PrezziZonali
Domanda, visto che non me ne intendo invece di prezzi zonali... ma questi non sono dentro nel file XML che scarica già l'integrazione come ZIP (uno XML per ogni giorno)?
Ogni ora dell'XML ha questi dati:
<Prezzi>
<Data>20240509</Data>
<Mercato>MGP</Mercato>
<Ora>1</Ora>
<PUN>94,320000</PUN>
<NAT>94,320000</NAT>
<CALA>94,320000</CALA>
<CNOR>94,320000</CNOR>
<CSUD>94,320000</CSUD>
<NORD>94,320000</NORD>
<SARD>94,320000</SARD>
<SICI>94,320000</SICI>
<SUD>94,320000</SUD>
<AUST>94,320000</AUST>
<COAC>94,320000</COAC>
<COUP>94,320000</COUP>
<CORS>94,320000</CORS>
<FRAN>94,320000</FRAN>
<GREC>94,320000</GREC>
<SLOV>94,320000</SLOV>
<SVIZ>94,320000</SVIZ>
<BSP>94,320000</BSP>
<MALT>94,320000</MALT>
<XAUS>94,320000</XAUS>
<XFRA>94,320000</XFRA>
<MONT>94,320000</MONT>
<XGRE>94,320000</XGRE>
</Prezzi>
E noi di questi prendiamo solo il <PUN>94,320000</PUN>
. A te quali servono? Immagino siano già qui...
Se posso dare il mio piccolo contributo (ne so mooooolto meno di voi), se utile e non indiscreto, credo che l'endpoint per accedere ai prezzi zonali in XML sia il seguente https://gme.mercatoelettrico.org/DesktopModules/GmeEsitiPrezziME/API/item/GetMEPrezzi?DataInizio=20240509&DataFine=20240509&Granularita=h&Mercato=MGP&Zona=NORD&Tipologia=PrezziZonali
Ovviamente usato così nudo e crudo non funziona, restituisce un errore, ma non se se è una problematica di referrer come menzionato sopra, o di cookie (tramite l'accettazione delle condizioni di uso nella videata che ora è un pop-up).
Ho testato la API e non funziona nemmeno con il referrer, pero' penso che potrebbe essere un API interna del sito, quell'item mi sembra una route di react. dove l'hai trovata? 😂
In compenso il pulsante che scarica l'excel con i dati sembra essere un endpoint pubblico, regolando la granularita' penso che si possano ottenere dati di un mese o piu', per l'estrazione dei dati probabilmente un excel e' anche meglio di un XML👌 https://gme.mercatoelettrico.org/DesktopModules/GmeEsitiPrezziME/API/ExcelDownload/download?DataInizio=20240509&DataFine=20240509&Granularita=h&Mercato=MGP&Zona=Nord&Tipologia=PrezziZonali
Domanda, visto che non me ne intendo invece di prezzi zonali... ma questi non sono dentro nel file XML che scarica già l'integrazione come ZIP (uno XML per ogni giorno)?
Ogni ora dell'XML ha questi dati:
<Prezzi> <Data>20240509</Data> <Mercato>MGP</Mercato> <Ora>1</Ora> <PUN>94,320000</PUN> <NAT>94,320000</NAT> <CALA>94,320000</CALA> <CNOR>94,320000</CNOR> <CSUD>94,320000</CSUD> <NORD>94,320000</NORD> <SARD>94,320000</SARD> <SICI>94,320000</SICI> <SUD>94,320000</SUD> <AUST>94,320000</AUST> <COAC>94,320000</COAC> <COUP>94,320000</COUP> <CORS>94,320000</CORS> <FRAN>94,320000</FRAN> <GREC>94,320000</GREC> <SLOV>94,320000</SLOV> <SVIZ>94,320000</SVIZ> <BSP>94,320000</BSP> <MALT>94,320000</MALT> <XAUS>94,320000</XAUS> <XFRA>94,320000</XFRA> <MONT>94,320000</MONT> <XGRE>94,320000</XGRE> </Prezzi>
E noi di questi prendiamo solo il
<PUN>94,320000</PUN>
. A te quali servono? Immagino siano già qui...
Sono loro, allora il file zippato contiene già tutto. Io utilizzo i prezzi zonali NORD, ma possono variare a seconda della zona geografica in cui ti trovi. Per vostra informazione i dati zonali di un giorno vengono resi disponibili nel primo pomeriggio del giorno precedente, generalmente entro le 14-15. (per necessità mie io mi scarico sia quelli di oggi che quelli di domani - fintanto che quelli di domani mancano li sostituisco con quelli di oggi)
Ho testato la API e non funziona nemmeno con il referrer, pero' penso che potrebbe essere un API interna del sito, quell'item mi sembra una route di react. dove l'hai trovata? 😂
Con Firefox, analizzando la pagina, con l'inspector, nella sezione "rete" mostra le chiamate che vengono effettuate. Selezionando poi questa chiamata GET specifica mostra pure l'header della chiamata e risposta. Magari copiando i paramentri dal browser riesci a replicarla con Powershell e capire se è un endpoint pubblico o meno.
In compenso il pulsante che scarica l'excel con i dati sembra essere un endpoint pubblico, regolando la granularita' penso che si possano ottenere dati di un mese o piu', per l'estrazione dei dati probabilmente un excel e' anche meglio di un XML👌 https://gme.mercatoelettrico.org/DesktopModules/GmeEsitiPrezziME/API/ExcelDownload/download?DataInizio=20240509&DataFine=20240509&Granularita=h&Mercato=MGP&Zona=Nord&Tipologia=PrezziZonali
Ho sempre cercato di non dover scaricare file in locale, ma probabilmente l'approccio è diverso/la necessità è differente quando si sviluppa un component per homeassistant.
Mannaggia a loro che nel vecchio sito hanno il pulsante per ottenere l'XML direttamente e qui invece è stato tolto :|
Ho testato la API e non funziona nemmeno con il referrer, pero' penso che potrebbe essere un API interna del sito, quell'item mi sembra una route di react. dove l'hai trovata? 😂
Con Firefox, analizzando la pagina, con l'inspector, nella sezione "rete" mostra le chiamate che vengono effettuate. Selezionando poi questa chiamata GET specifica mostra pure l'header della chiamata e risposta. Magari copiando i paramentri dal browser riesci a replicarla con Powershell e capire se è un endpoint pubblico o meno.
In compenso il pulsante che scarica l'excel con i dati sembra essere un endpoint pubblico, regolando la granularita' penso che si possano ottenere dati di un mese o piu', per l'estrazione dei dati probabilmente un excel e' anche meglio di un XML👌 https://gme.mercatoelettrico.org/DesktopModules/GmeEsitiPrezziME/API/ExcelDownload/download?DataInizio=20240509&DataFine=20240509&Granularita=h&Mercato=MGP&Zona=Nord&Tipologia=PrezziZonali
Ho sempre cercato di non dover scaricare file in locale, ma probabilmente l'approccio è diverso/la necessità è differente quando si sviluppa un component per homeassistant.
Mannaggia a loro che nel vecchio sito hanno il pulsante per ottenere l'XML direttamente e qui invece è stato tolto :|
sisi ma ho provato da powershell con referrer e mi restituisce errore di auth, per quello penso sia interna, sicuramente non e' pubblica 😂 In ogni caso se nel file attuale abbiamo gia' i valori non penso che questa serva
l'excel in realta' si potrebbe caricare in memoria direttamente quindi non sarebbe comunque un problema :)
l'excel in realta' si potrebbe caricare in memoria direttamente quindi non sarebbe comunque un problema :)
Ma è già così, in memoria, mica fa un file... https://github.com/virtualdj/pun_sensor/blob/master/custom_components%2Fpun_sensor%2F__init__.py#L209-L211
l'excel in realta' si potrebbe caricare in memoria direttamente quindi non sarebbe comunque un problema :)
Ma è già così, in memoria, mica fa un file... https://github.com/virtualdj/pun_sensor/blob/master/custom_components%2Fpun_sensor%2F__init__.py#L209-L211
sisi lo so, era in risposta al commento di @g1za 😂
Ho sempre cercato di non dover scaricare file in locale, ma probabilmente l'approccio è diverso/la necessità è differente quando si sviluppa un component per homeassistant.
@moddroid94 Ah ok, il potrebbe mi ha tratto in inganno...
Da qualche tempo riscontro un problema sul download dei dati:
2024-07-17 01:00:04.243 WARNING (MainThread) [custom_components.pun_sensor] Errore durante l'aggiornamento via web, nuovo tentativo tra 1 minuto.
Traceback (most recent call last):
File "/config/custom_components/pun_sensor/__init__.py", line 335, in update_pun
await self._async_update_data()
File "/config/custom_components/pun_sensor/__init__.py", line 185, in _async_update_data
viewstate = soup.find('input',{'name':'__VIEWSTATE'})['value']
Da qualche tempo riscontro un problema sul download dei dati:
@Tagliax
Il fatto che usi soup.find
significa che stai usando la versione "stabile" e non quella di questa issue (che è invece la beta).
Tuttavia non cambia: anch'io se guardo nei log vedo errori sporadici del genere, sia con la vecchia API (quella che ti dà problemi) che con la nuova (quella della beta).
Semplicemente, il sito fa abbastanza schifo e quindi capita che non risponda... Ma niente paura, se leggi bene i log vedrai che c'è il meccanismo di retry che raramente fallisce completamente. Prova a leggere sotto quella riga, se non ci sono altri warning significa che il successivo tentativo è andato a buon fine.
Quindi prendi il log per quello che è, un warning, che non pregiudica affatto il funzionamento dell'integrazione. Certo, si potrebbe silenziare, ma non credo abbia senso: io preferisco sapere se e quando il download fallisce.
Ciao @virtualdj si ho notato i retry, ma anche quello di 1 ora sembra andare KO, ho preso il primo log. Ho notato che ogni tanto fa le bizze l’endpoint…se è tutto nella norma, come non detto :)
@Tagliax Nella norma per loro! Io direi che qualcosa lo dovrebbero pure sistemare 😄 Guarda qui sotto il mio log di stanotte:
2024-07-17 01:00:00.000 DEBUG (MainThread) [custom_components.pun_sensor] Connessione a URL login.
2024-07-17 01:00:04.502 WARNING (MainThread) [custom_components.pun_sensor] Errore durante l'aggiornamento via web, nuovo tentativo tra 1 minuto.
Traceback (most recent call last):
File "/config/custom_components/pun_sensor/__init__.py", line 330, in update_pun
await self._async_update_data()
File "/config/custom_components/pun_sensor/__init__.py", line 180, in _async_update_data
viewstate = soup.find('input',{'name':'__VIEWSTATE'})['value']
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
TypeError: 'NoneType' object is not subscriptable
2024-07-17 01:01:04.638 DEBUG (MainThread) [custom_components.pun_sensor] Connessione a URL login.
2024-07-17 01:01:05.956 WARNING (MainThread) [custom_components.pun_sensor] Errore durante l'aggiornamento via web, nuovo tentativo tra 10 minuti.
Traceback (most recent call last):
File "/config/custom_components/pun_sensor/__init__.py", line 330, in update_pun
await self._async_update_data()
File "/config/custom_components/pun_sensor/__init__.py", line 180, in _async_update_data
viewstate = soup.find('input',{'name':'__VIEWSTATE'})['value']
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
TypeError: 'NoneType' object is not subscriptable
2024-07-17 01:11:05.960 DEBUG (MainThread) [custom_components.pun_sensor] Connessione a URL login.
2024-07-17 01:11:07.562 WARNING (MainThread) [custom_components.pun_sensor] Errore durante l'aggiornamento via web, nuovo tentativo tra 60 minuti.
Traceback (most recent call last):
File "/config/custom_components/pun_sensor/__init__.py", line 330, in update_pun
await self._async_update_data()
File "/config/custom_components/pun_sensor/__init__.py", line 180, in _async_update_data
viewstate = soup.find('input',{'name':'__VIEWSTATE'})['value']
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
TypeError: 'NoneType' object is not subscriptable
2024-07-17 02:11:07.566 DEBUG (MainThread) [custom_components.pun_sensor] Connessione a URL login.
2024-07-17 02:11:08.694 WARNING (MainThread) [custom_components.pun_sensor] Errore durante l'aggiornamento via web, nuovo tentativo tra 120 minuti.
Traceback (most recent call last):
File "/config/custom_components/pun_sensor/__init__.py", line 330, in update_pun
await self._async_update_data()
File "/config/custom_components/pun_sensor/__init__.py", line 180, in _async_update_data
viewstate = soup.find('input',{'name':'__VIEWSTATE'})['value']
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
TypeError: 'NoneType' object is not subscriptable
2024-07-17 04:11:07.919 DEBUG (MainThread) [custom_components.pun_sensor] Connessione a URL login.
2024-07-17 04:11:10.967 DEBUG (MainThread) [custom_components.pun_sensor] Invio credenziali a URL login.
2024-07-17 04:11:18.977 DEBUG (MainThread) [custom_components.pun_sensor] Inizio download file ZIP con XML.
... cut ...
Come puoi leggere ha fallito il primo tentativo, quello dopo 1 minuto, quello dopo 10 minuti, quello dopo 60 minuti e quello dopo 120 minuti e dall'1 di notte siamo andati a finire alle 04:11! Però alla fine, alla sesta volta, ce l'ha fatta 😄
Vedi @moddroid94 che il sistema di retry fatto così aveva il suo perché? 🤣
@virtualdj Io sospetto che loro in quel lasso di tempo eseguono operazioni di backup notturno, altrimenti non si spiegano questi down… 😅
Ciao @virtualdj Avevi visto questa? https://gme.mercatoelettrico.org/it-it/Home/FTP
Avevi visto questa? https://gme.mercatoelettrico.org/it-it/Home/FTP
Mi pareva di averla notata, sì, quando si parlava del nuovo sito. Tecnicamente l'FTP c'era già prima, solo che non credo offra molti vantaggi... prima di tutto, tocca fare tutta quella trafila con "carte bollate" 😄 e poi mi pare molto più semplice pescare i dati giornalieri direttamente dall'endpoint HTTP, posto di aver spuntato le caselle di esonero responsabilità.
Tecnicamente l'FTP c'era già prima, solo che non credo offra molti vantaggi...
L’ho segnalato perché ho l’impressione che poi tutto sarà sul nuovo sito e spegneranno il vecchio. Magari c’è il modo di adattare già sul nuovo lo stesso metodo con endpoint HTTP
Magari c’è il modo di adattare già sul nuovo lo stesso metodo con endpoint HTTP
È già stato fatto nella PR #45 solo che non l'ho ancora unita perché stavo aspettando che l'autore sistemasse le rifiniture al codice.
È disponibile in "alfa" nella pre-release 0.9.1 (sì, antecedente all'ultima proprio perché bisognava sistemare il codice). Purtroppo in questo momento non ho il tempo sufficiente per dedicarmi a questo progetto, ma fintanto che funziona teniamo duro.
Appena possibile sistemerò tutto, ma mi serve tempo e calma.
È già stato fatto nella PR #45 solo che non l'ho ancora unita perché stavo aspettando che l'autore sistemasse le rifiniture al codice.
Allora perfetto! :) ottimo così! Grazie!
l'excel in realta' si potrebbe caricare in memoria direttamente quindi non sarebbe comunque un problema :)
Ma è già così, in memoria, mica fa un file... https://github.com/virtualdj/pun_sensor/blob/master/custom_components%2Fpun_sensor%2F__init__.py#L209-L211
sisi lo so, era in risposta al commento di @g1za 😂
Ho sempre cercato di non dover scaricare file in locale, ma probabilmente l'approccio è diverso/la necessità è differente quando si sviluppa un component per homeassistant.
forse si potrebbe impostare un selettore all'interno dell'integrazione in modo che l'utente scelga il prezzo zonale orario della zona di mercato elettrico in cui è connesso l'impianto fotovoltaico :) e quindi lo script lo vada a leggere dall'xml già scaricato ed impostare nel sensore del "prezzo zonale orario". Io fino ad oggi l'ho fatto con multiscrape ma ormai il sito è andato e non ho tempo (e forse non saprei nemmeno come :( ) di rifare tutto con il sito che in ogni caso andrà avanti fino a dicembre 2024 :(, il lavoro nell'integrazione invece è già fatto o quasi :), il problema maggiore è che avremmo da n. 0 a 23 prezzi orari (n. 24 prezzi in totale) e non più uno come nel caso del PUN quindi dovrebbero essere inviati al sensore con il tempo giusto per aggiornare lo stato ogni ora (io facevo così con un trigger), HA non permette di creare stati "futuri" quindi il sensore del prezzo zonale orario per le successive 24 ore credo sia impossibile da fare dato che i prezzi del "giorno dopo" vengono pubblicati intorno alle 14 del giorno precedente. il prezzo zonale sarebbe utile da indicare in plancia energia per il rendimento del fotovoltaico e per avere un'idea del prezzo dell'energia immessa durante il giorno (io facevo anche una tabella con le 24 ore con un valore per ogni sensore del "giorno dopo" per sopperire all'impossibilità di avere un sensore con "stati futuri :) mentre per il prezzo zonale del giorno corrente non ci sarebbero problemi.
@MicheleMercuri per un fix veloce valido fino al 31/12 basta che aggiorni le resources del multiscrape come indicato qui
Se il prezzo zonale non verrà implementato nella nuova versione del componente (alla fine non ho capito se sta venendo valutata come possibilità) un'opzione è usare il portale ENTSO-E e appoggiarsi alle loro API (bisogna richiedere accesso), a meno di non studiare come fare scraping dal novo sito GME (oppure farsi una fork di questo progetto e riadattarla per i prezzi zonali).
Ok grazie, proverò ad aggiornare. Ho provato a fare uno scarpe sul nuovo sito del gme ma non è possibile selezionare le zone di mercato elettrico, non è nemmeno possibile effettuare il download del file xml (sarebbe la cosa migliore) con tutti i dati perché mi rifiuta la connessione (ho provato velocemente con uno script in ha ma nisba) ho provato anche con uno script in una pagina HTML e nemmeno così ne vuole sapere, credo sia un problema di autorizzazione che non credo sia facile superare.
@g1za
alla fine non ho capito se sta venendo valutata come possibilità
Non era nei miei piani perché principalmente non lo uso e non so come funziona. Ma, dato che alla fine quei prezzi ci sono già nel file XML che viene scaricato, estrarli non è un problema! Solo vorrei capire - non me ne intendo - come poi li utilizzereste.
Supponiamo ad esempio che io imposti l'ora di download alle 16. Se oggi è il 3/10, alle 16 scarico l'XML e poi tengo in memoria i prezzi delle 24 ore relative al giorno 4/10 (cioè il successivo). Il 4/10, ogni ora, aggiorno il valore di un sensore (es. "Prezzo zonale") con quello tenuto in memoria nel precedente download per quell'ora. È questo quello che state chiedendo?
Solo vorrei capire - non me ne intendo - come poi li utilizzereste.
Il prezzo zonale orario è il prezzo con cui viene remunerata l'energia immessa in rete (da un impianto fotovoltaico), per chi ha un contratto RID (ritiro dedicato) con il GSE. L'energia immessa in rete ogni ora (-10% di perdite di rete) viene moltiplicata per il prezzo zonale orario = prezzo al quale verrà pagata l'energia immessa (- tassazione Irpef). Io faccio così (cioè facevo visto che tra poco non funzionerà più 😁): il 03/10/2024 alle 16:00 scarico i prezzi del giorno dopo dal gme es del 04/10/2024, con un trigger dalle ore 00:00 del 04/10/2024 ogni ora aggiorno un sensore con nello stato il prezzo zonale dell'ora di riferimento, con un utility Meter mi calcolo l'energia immessa ogni ora, alla fine: Sensor.gme.prezzozonale * sensor.kwh.immessi = guadagno prima delle imposte da fotovoltaico 😁 (per essere precisi tolgo il 10% di perdite di rete). Volendo il sensore del prezzo zonale può andare anche in plancia energia dato che lo prevede HA di default. Spero si capisca 😁.
Premetto che conosco la tua posizione, che hai espresso anche in passato e che non posso chiedere nulla oltre a quanto stai già facendo (utilissimo e comodissimo peraltro). Sono conscio dell'impegno che lo sviluppo comporta, quindi accetto tutto quello che verrà prodotto. :) Stavo giusto vedendo che direzione decidete di prendere con lo sviluppo per capire io come muovermi di conseguenza visto che in seguito ad un paio di commenti che avevo letto non mi era più chiaro.
Detto ciò...
Il prezzo zonale è alla base del calcolo della remunerazione su base oraria dell'energia prodotta dagli impianti fotovoltaici privati ed immessa in rete. In realtà per il Ritiro Dedicato (RID - per lo scambio sul posto SSP è differente e più complicato con prezzi definiti dall'autorità) ci sono dei conti e formule dietro da fare che nemmeno ricordo più ma restiamo sul facile senza scendere in dettagli. Il valore è differente per area geografica, da cui "prezzi zonali".
Sicuramente il caso d'uso più semplice è inserire questo dato nella dashboard di homeassistant per farsi calcolare o stimare il valore monetario dell'energia venduta.
Io personalmente utilizzo un addon (EMHASS) che in base a consumi previsti, costo di acquisto dell'energia, prezzo di vendita (prezzo zonale) e previsione di produzione fotovoltaica ottimizza la gestione energetica dell'abitazione permettendoti di comandare acquisto/vendita da/alla rete, carica/scarica batterie, accensione/spegnimento di carichi variabili. Il tutto per massimizzando una funzione di autoconsumo o profitto. Per questo add-on io utilizzo i prezzi zonali di oggi e di domani (appena resi disponibili, di solito fra le 14 e le 15, altrimenti continuo ad usare quelli di oggi), in quanto faccio fare l'elaborazione su 24h rolling.
Spero di essere stato esauriente e sufficientemente chiaro, altrimenti chiedimi pure.
@MicheleMercuri
Sensor.gme.prezzozonale * sensor.kwh.immessi = guadagno prima delle imposte da fotovoltaico 😁 (per essere precisi tolgo il 10% di perdite di rete)
Quindi sarebbe opportuno esporre direttamente PrezzoZonale * 0.9
nel valore del sensore, per tenere in considerazione le perdite di rete?
@g1za
Per questo add-on io utilizzo i prezzi zonali di oggi e di domani (appena resi disponibili, di solito fra le 14 e le 15, altrimenti continuo ad usare quelli di oggi)
Cioè intendi dire che se non sono disponibili domani userai i prezzi di oggi?
Premetto che conosco la tua posizione
Intanto mi basta capire il concetto, poi appena potrò lo implementerò. Se adesso non fossi preso per il collo l'avrei già fatto 😄
Quindi sarebbe opportuno esporre direttamente
PrezzoZonale * 0.9
nel valore del sensore, per tenere in considerazione le perdite di rete?
Se posso io direi che sarebbe più opportuno recuperare il dato grezzo e poi lasciare all'utente la responsabilità di utilizzarlo nel modo corretto o come più preferisce.
Cioè intendi dire che se non sono disponibili domani userai i prezzi di oggi?
Per forza, altrimenti l'elaborazione si blocca, avendo io sempre bisogno di 24h di dati. Quelli di oggi sono una buona approssimazione (anche l'unica) di quelli di domani e comunque nel mio caso l'impatto è limitato dal fatto che l'elaborazione è in là nel tempo oltre il cambio di data. Quindi quando sarò effettivamente al punto di aver bisogno di una previsione precisa (a quel punto a breve termine) oramai i dati effettivi per la giornata saranno già stati resi disponibili.
EDIT: no intendo che io ho bisogno di 24h di dati (fra dati reali e previsioni/dati futuri). I dati di domani saranno sicuramente disponibili ma solo dopo le 14-15 di oggi. Fino ad allora, avendo comunque sempre bisogno di 24h di dati (uso una finestra di 24h rolling), utilizzo i prezzi zonali (ma anche i PUN a dirla tutta) di oggi in quanto ne sono una buona approssimazione (anche l'unica). Nel mio caso l'impatto è limitato dal fatto che l'elaborazione è in là nel tempo, oltre il cambio di data. Quindi quando sarò effettivamente al punto di aver bisogno di una elaborazione precisa con dati reali (un'elaborazione a breve termine) oramai i dati effettivi per la giornata saranno già stati resi disponibili (saranno oramai già trascorse le 14-15).
@MicheleMercuri
Sensor.gme.prezzozonale * sensor.kwh.immessi = guadagno prima delle imposte da fotovoltaico 😁 (per essere precisi tolgo il 10% di perdite di rete)
Quindi sarebbe opportuno esporre direttamente
PrezzoZonale * 0.9
nel valore del sensore, per tenere in considerazione le perdite di rete?
il prezzo zonale orario pubblicato dal GME dalle 14:00 del giorno corrente in poi lo utilizzo dalla mezzanotte del giorno successivo moltiplicandolo per l'energia immessa nell'ora di riferimento calcolata con utility meter orario di HA, mai accaduto che non venisse pubblicato :).
perchè il GME pubblica con un giorno di anticipo il prezzo dell'energia oraria, quindi devo per forza usare il giorno successivo quella pubblicata alle 14:00 del giorno corrente (spero di essere riuscito a spiegarmi :) )
ho ricontrollato i calcoli fatti dal GSE per il RID (in RID ci sono gli impianti al 110% e gli impianti oltre i 20 kW e da non sottovalutare le comunità energetiche perché incompatibili con lo scambio sul posto-SSP)
la formula per il calcolo del prezzo di vendita è la seguente: energia coeff_perd prz_ora
con energia = kWh immessi nell'ora di riferimento coeff_perd = 1,052 prz_ora = prezzo zonale orario GME nell'ora di rif.
le perdite vengono sommate e non tolte (ho sbagliato a scrivere perchè mi sono confuso con il prezzo di acquisto dell'energia :))
ecco gli screen a prova della correttezza dei calcoli che ti ho illustrato e dei corrispettivi pagati per l'energia immessa dal mio impianto:
questo lo screen da sito GME dell'ora 14 e 15 zona immissione calabria del prezzo zonale orario:
questo è il foglio di calcolo che scarico dal sito del GSE con i dettagli delle cifre che avrò dal GSE, l'ora 14 e 15 corrispondono alle 13 e alle 14 perchè il sito del GME nella tabella inizia dall'ora 1 a contare le ore dalla mezzanotte :)
questo è l'importo che mi verrà pagato per agosto 2024 (ho optato per la liquidazione mensile senza il minimo garantito, perchè tanto è 0,04€/kWh e mi verrebbe pagato dopo quasi 6 mesi dalla fine dell'anno di riferimento, e perché immetto poco in quanto ho una Tesla e riesco a consumare gran parte degli 8.000 kWh prodotti :)
e questo è la prova sommando le celle del calcolo dell'energia immessa sul foglio di excel con il dettaglio orario:
spero si capisca tutto :)
Interessante, sono riuscito a fare questa cosa dopo mesi di studio (l'ostacolo principale è stato il cookie...). Più che altro mi serviva per decidere quando immettere da batteria (ovvero i picchi del prezzo zonale), ma stavo cercando di calcolare anche il valore di immissione per inserirlo nella plancia energia. Non so a che punto si arrivato, ma lascio il mio script se può essere utile (lo so, il mio codice non è molto elegante):
#!/bin/bash
curl -b cookie.txt -c cookie.txt "https://www.mercatoelettrico.org/it-it/" > /dev/null
COOKIE=$(sed 's/Token\t/\n/;s/.*\n//' cookie.txt | cut -d '#' -f 1 | sed '/^$/d')
#echo "COOKIE: "$COOKIE
DATE=$(date '+%Y%m%d')
DATE="https://www.mercatoelettrico.org/DesktopModules/GmeEsitiPrezziME/API/ExcelDownload/download?DataInizio=$DATE&DataFine=$DATE&Granularita=h&Mercato=MGP&Zona=CNOR&Tipologia=PrezziZonali&TutteZone=0"
#echo "DATA: |"$DATE"|"
curl $DATE \
-H 'accept: application/json, text/plain, */*' \
-H 'accept-language: it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7,ja;q=0.6,de;q=0.5' \
-H 'cookie: dnn_IsMobile=False; .ASPXANONYMOUS=7l2zAezlkn0_4uMxdZhXuDHWhRjLPhphzJgKUfOvJdykj0T8PHrWTTmwtCWzdEg6_UY9BlvM2TNdCeojqhrOVauwWwPOlwSvr3M-ln6zjiZPvF170; language=it-IT; __RequestVerificationToken=$>
-H 'moduleid: 518' \
-H 'priority: u=1, i' \
-H 'referer: https://www.mercatoelettrico.org/it-it/Home/Esiti/Elettricita/MGP/Esiti/PrezziZonali' \
-H 'requestverificationtoken: $COOKIE' \
-H 'sec-ch-ua: "Chromium";v="128", "Not;A=Brand";v="24", "Google Chrome";v="128"' \
-H 'sec-ch-ua-mobile: ?0' \
-H 'sec-ch-ua-platform: "Linux"' \
-H 'sec-fetch-dest: empty' \
-H 'sec-fetch-mode: cors' \
-H 'sec-fetch-site: same-origin' \
-H 'tabid: 55' \
-H 'user-agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36' \
-H 'userid: -1' --output gme.xlsx
rm cookie.txt -rf
mv gme.xlsx gme.zip
unzip gme.zip
mv xl/worksheets/sheet1.xml ./gme.xml
rm _rels/ -rf
rm xl/ -rf
rm "[Content_Types].xml"
rm gme.zip
sed -e s/x://g -i gme.xml
sed -e s/,/./g -i gme.xml
mv gme.xml ./www/
file coockie.txt:
# Netscape HTTP Cookie File
# http://curl.haxx.se/rfc/cookie_spec.html
# This is a generated file! Do not edit.
www.mercatoelettrico.org FALSE / TRUE 0 ASP.NET_SessionId 5jojkem0y4imkuxrtenld1q0
www.mercatoelettrico.org FALSE / TRUE 0 GmeItaliano 4EB33DD384A9C912E264E5A8A66C8F717AA6C36F38FA2FD4A26794FEAE846471F13E1D2787FD422E44A26058E8330EBD9E00C1171729909C66241D03A12E0750>
e questo lo yaml:
#/hass-config/packages/ict/gme.yaml
shell_command:
gme: /home/andbad/.homeassistant/bash_scripts/gme.sh
rest:
- scan_interval: 86400 #si aggiornano in automatico 1 volta al giorno, ma l'automazione forza l'aggiornamento dopo aver scaricato i dati.
resource: https://192.168.0.2:8123/local/gme.xml
verify_ssl: false
sensor:
- name: "GME 0-1"
value_template: "{{ (value_json.worksheet.sheetData.row[1].c[2].v|float/1000)|round(3) }}"
state_class: measurement
unit_of_measurement: "€/kWh"
json_attributes_path: "$.worksheet.sheetData.row[1].c[0]"
json_attributes:
- "v"
- name: "GME 1-2"
value_template: "{{ (value_json.worksheet.sheetData.row[2].c[2].v|float/1000)|round(3) }}"
state_class: measurement
unit_of_measurement: "€/kWh"
json_attributes_path: "$.worksheet.sheetData.row[2].c[0]"
json_attributes:
- "v"
- name: "GME 2-3"
value_template: "{{ (value_json.worksheet.sheetData.row[3].c[2].v|float/1000)|round(3) }}"
state_class: measurement
unit_of_measurement: "€/kWh"
json_attributes_path: "$.worksheet.sheetData.row[3].c[0]"
json_attributes:
- "v"
- name: "GME 3-4"
value_template: "{{ (value_json.worksheet.sheetData.row[4].c[2].v|float/1000)|round(3) }}"
state_class: measurement
unit_of_measurement: "€/kWh"
json_attributes_path: "$.worksheet.sheetData.row[4].c[0]"
json_attributes:
- "v"
- name: "GME 4-5"
value_template: "{{ (value_json.worksheet.sheetData.row[5].c[2].v|float/1000)|round(3) }}"
state_class: measurement
unit_of_measurement: "€/kWh"
json_attributes_path: "$.worksheet.sheetData.row[5].c[0]"
json_attributes:
- "v"
- name: "GME 5-6"
value_template: "{{ (value_json.worksheet.sheetData.row[6].c[2].v|float/1000)|round(3) }}"
state_class: measurement
unit_of_measurement: "€/kWh"
json_attributes_path: "$.worksheet.sheetData.row[6].c[0]"
json_attributes:
- "v"
- name: "GME 6-7"
value_template: "{{ (value_json.worksheet.sheetData.row[7].c[2].v|float/1000)|round(3) }}"
state_class: measurement
unit_of_measurement: "€/kWh"
json_attributes_path: "$.worksheet.sheetData.row[7].c[0]"
json_attributes:
- "v"
- name: "GME 7-8"
value_template: "{{ (value_json.worksheet.sheetData.row[8].c[2].v|float/1000)|round(3) }}"
state_class: measurement
unit_of_measurement: "€/kWh"
json_attributes_path: "$.worksheet.sheetData.row[8].c[0]"
json_attributes:
- "v"
- name: "GME 8-9"
value_template: "{{ (value_json.worksheet.sheetData.row[9].c[2].v|float/1000)|round(3) }}"
state_class: measurement
unit_of_measurement: "€/kWh"
json_attributes_path: "$.worksheet.sheetData.row[9].c[0]"
json_attributes:
- "v"
- name: "GME 9-10"
value_template: "{{ (value_json.worksheet.sheetData.row[10].c[2].v|float/1000)|round(3) }}"
state_class: measurement
unit_of_measurement: "€/kWh"
json_attributes_path: "$.worksheet.sheetData.row[10].c[0]"
json_attributes:
- "v"
- name: "GME 10-11"
value_template: "{{ (value_json.worksheet.sheetData.row[11].c[2].v|float/1000)|round(3) }}"
state_class: measurement
unit_of_measurement: "€/kWh"
json_attributes_path: "$.worksheet.sheetData.row[11].c[0]"
json_attributes:
- "v"
- name: "GME 11-12"
value_template: "{{ (value_json.worksheet.sheetData.row[12].c[2].v|float/1000)|round(3) }}"
state_class: measurement
unit_of_measurement: "€/kWh"
json_attributes_path: "$.worksheet.sheetData.row[12].c[0]"
json_attributes:
- "v"
- name: "GME 12-13"
value_template: "{{ (value_json.worksheet.sheetData.row[13].c[2].v|float/1000)|round(3) }}"
state_class: measurement
unit_of_measurement: "€/kWh"
json_attributes_path: "$.worksheet.sheetData.row[13].c[0]"
json_attributes:
- "v"
- name: "GME 13-14"
value_template: "{{ (value_json.worksheet.sheetData.row[14].c[2].v|float/1000)|round(3) }}"
state_class: measurement
unit_of_measurement: "€/kWh"
json_attributes_path: "$.worksheet.sheetData.row[14].c[0]"
json_attributes:
- "v"
- name: "GME 14-15"
value_template: "{{ (value_json.worksheet.sheetData.row[15].c[2].v|float/1000)|round(3) }}"
state_class: measurement
unit_of_measurement: "€/kWh"
json_attributes_path: "$.worksheet.sheetData.row[15].c[0]"
json_attributes:
- "v"
- name: "GME 15-16"
value_template: "{{ (value_json.worksheet.sheetData.row[16].c[2].v|float/1000)|round(3) }}"
state_class: measurement
unit_of_measurement: "€/kWh"
json_attributes_path: "$.worksheet.sheetData.row[16].c[0]"
json_attributes:
- "v"
- name: "GME 16-17"
value_template: "{{ (value_json.worksheet.sheetData.row[17].c[2].v|float/1000)|round(3) }}"
state_class: measurement
unit_of_measurement: "€/kWh"
json_attributes_path: "$.worksheet.sheetData.row[17].c[0]"
json_attributes:
- "v"
- name: "GME 17-18"
value_template: "{{ (value_json.worksheet.sheetData.row[18].c[2].v|float/1000)|round(3) }}"
state_class: measurement
unit_of_measurement: "€/kWh"
json_attributes_path: "$.worksheet.sheetData.row[18].c[0]"
json_attributes:
- "v"
- name: "GME 18-19"
value_template: "{{ (value_json.worksheet.sheetData.row[19].c[2].v|float/1000)|round(3) }}"
state_class: measurement
unit_of_measurement: "€/kWh"
json_attributes_path: "$.worksheet.sheetData.row[19].c[0]"
json_attributes:
- "v"
- name: "GME 19-20"
value_template: "{{ (value_json.worksheet.sheetData.row[20].c[2].v|float/1000)|round(3) }}"
state_class: measurement
unit_of_measurement: "€/kWh"
json_attributes_path: "$.worksheet.sheetData.row[20].c[0]"
json_attributes:
- "v"
- name: "GME 20-21"
value_template: "{{ (value_json.worksheet.sheetData.row[21].c[2].v|float/1000)|round(3) }}"
state_class: measurement
unit_of_measurement: "€/kWh"
json_attributes_path: "$.worksheet.sheetData.row[21].c[0]"
json_attributes:
- "v"
- name: "GME 21-22"
value_template: "{{ (value_json.worksheet.sheetData.row[22].c[2].v|float/1000)|round(3) }}"
state_class: measurement
unit_of_measurement: "€/kWh"
json_attributes_path: "$.worksheet.sheetData.row[22].c[0]"
json_attributes:
- "v"
- name: "GME 22-23"
value_template: "{{ (value_json.worksheet.sheetData.row[23].c[2].v|float/1000)|round(3) }}"
state_class: measurement
unit_of_measurement: "€/kWh"
json_attributes_path: "$.worksheet.sheetData.row[23].c[0]"
json_attributes:
- "v"
- name: "GME 23-24"
value_template: "{{ (value_json.worksheet.sheetData.row[24].c[2].v|float/1000)|round(3) }}"
state_class: measurement
unit_of_measurement: "€/kWh"
json_attributes_path: "$.worksheet.sheetData.row[24].c[0]"
json_attributes:
- "v"
automation:
#Aggiorna gli orari di massimo valore GME
- id: gme_aggiornamento
alias: GME Update
description: ""
trigger:
- platform: time
at: "00:00:00"
condition: []
action:
- action: shell_command.gme
data: {}
- delay:
seconds: 30
- service: homeassistant.update_entity
entity_id: sensor.gme_0_1
- service: homeassistant.update_entity
entity_id: sensor.gme_1_2
- service: homeassistant.update_entity
entity_id: sensor.gme_2_3
- service: homeassistant.update_entity
entity_id: sensor.gme_3_4
- service: homeassistant.update_entity
entity_id: sensor.gme_4_5
- service: homeassistant.update_entity
entity_id: sensor.gme_5_6
- service: homeassistant.update_entity
entity_id: sensor.gme_6_7
- service: homeassistant.update_entity
entity_id: sensor.gme_7_8
- service: homeassistant.update_entity
entity_id: sensor.gme_8_9
- service: homeassistant.update_entity
entity_id: sensor.gme_9_10
- service: homeassistant.update_entity
entity_id: sensor.gme_10_11
- service: homeassistant.update_entity
entity_id: sensor.gme_11_12
- service: homeassistant.update_entity
entity_id: sensor.gme_12_13
- service: homeassistant.update_entity
entity_id: sensor.gme_13_14
- service: homeassistant.update_entity
entity_id: sensor.gme_14_15
- service: homeassistant.update_entity
entity_id: sensor.gme_15_16
- service: homeassistant.update_entity
entity_id: sensor.gme_16_17
- service: homeassistant.update_entity
entity_id: sensor.gme_17_18
- service: homeassistant.update_entity
entity_id: sensor.gme_18_19
- service: homeassistant.update_entity
entity_id: sensor.gme_19_20
- service: homeassistant.update_entity
entity_id: sensor.gme_20_21
- service: homeassistant.update_entity
entity_id: sensor.gme_21_22
- service: homeassistant.update_entity
entity_id: sensor.gme_22_23
- service: homeassistant.update_entity
entity_id: sensor.gme_23_24
- service: input_number.set_value
data_template:
entity_id: input_number.ora_picco_pun
value: >
{{ (state_attr('sensor.gme_max_mattino','max_entity_id').split('_')[1])|int }}
- service: input_number.set_value
data_template:
entity_id: input_number.ora_picco_pun_sera
value: >
{{ (state_attr('sensor.gme_max_sera','max_entity_id').split('_')[1])|int }}
mode: single
By(t)e
@g1za nello script bash uso la variabile "DATE" come inizio e fine per i dati. Ma come vedi dall'URL che richiamo sono valorizzabili a piacere: https://www.mercatoelettrico.org/DesktopModules/GmeEsitiPrezziME/API/ExcelDownload/download?DataInizio=$DATE&DataFine=$DATE&Granularita=h&Mercato=MGP&Zona=CNOR&Tipologia=PrezziZonali&TutteZone=0
DATE è in formato AAAAMMGG e dopo le 13 ( mi pare) sono disponibili anche i dati del giorno dopo.
By(t)e
Se volete iniziare a testarla, ho pubblicato la v1.0.0 come pre-release qui. In HACS è sufficiente attivare la spunta Show beta versions per vederla comparire nell'elenco.
Non contiene ancora nessuna nuova funzionalità (a parte il download ad un minuto specifico anziché lo scoccare dell'ora), ma sarà la base di partenza per le prossime e soprattutto usa i dati dal nuovo sito GME.
Intanto la metto in funzione nel mio sistema HA di test per una settimana, per vedere se ci sono problemi, per poi renderla ufficiale per tutti.
Perfetto, grazie, lo metto sul mio server pure io ;).
Anche io, con modalità debug abilitata; volevo mettere su un HA di test ma poi non avrei avuto la possibilità di verificarne bene il funzionamento :)
Ciao, ho notato che e' online il nuovo sito di GME. Il nuovo sito utilizza un endpoint API per scaricare il file zip, e ho pensato che si potesse semplificare la parte di download dal sito in quanto particolarmente convoluta.
Dopo un po' di tinkering sono riuscito a emulare una request che ci consente di scaricare lo zip senza fare scraping di valori sul sito con BeautifulSoup.
L'endpoint sembra essere di libero accesso, ovvero l'unico parametro che sembra essere importante per la request e' il referrer, che dev'essere la pagina di download del sito GME dov'e' situato il pulsante.
La request con la quale sono riuscito a scaricare lo zip e' la seguente: Su Powershell
Quando la richiesta viene effettuata dal browser, vi e' un campo aggiuntivo:
requestverificationtoken
. Ma anche omettendo il token l'API sembra funzionare da terminale o codice.Con python basta impostare gli headers di una request con i seguenti valori e puntare all'url con i parametri giusti.
Endpoint:
"https://gme.mercatoelettrico.org/DesktopModules/GmeDownload/API/ExcelDownload/downloadzipfile?DataInizio=20240507&DataFine=20240507&Date=20240506&Mercato=MGP&Settore=Prezzi&FiltroDate=InizioFine"
headers:
Non so se e' un problema di auth da parte loro o se e' inteso per essere pubblico, ad ogni modo anche dovessimo recuperare il token dai cookie/response dovrebbe essere decisamente piu' comodo.
PS. Ho forkato la repo e sto facendo un po' di clean up / spostamento di classi nei rispettivi moduli cosi' da seguire meglio le linee guida per le integrazioni di HA e rendere il codice un po' piu' leggibile, e possibilmente rendere piu' semplice l'adattamento ad un cambiamento come quello descritto qua #38
Se vuoi intanto dare un occhiata puoi trovarla tra le mie repo, non appena avro' testato le modifiche faccio una draft per una PR cosi da poter vedere insieme i cambiamenti.