pun_sensor icon indicating copy to clipboard operation
pun_sensor copied to clipboard

Nuova API sito GME

Open moddroid94 opened this issue 1 year ago • 32 comments

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

Invoke-WebRequest -UseBasicParsing -Uri "https://gme.mercatoelettrico.org/DesktopModules/GmeDownload/API/ExcelDownload/downloadzipfile?DataInizio=20240507&DataFine=20240507&Date=20240506&Mercato=MGP&Settore=Prezzi&FiltroDate=InizioFine" `
-WebSession $session `
-Headers @{
"authority"="gme.mercatoelettrico.org"
  "method"="GET"
  "path"="/DesktopModules/GmeDownload/API/ExcelDownload/downloadzipfile?DataInizio=20240507&DataFine=20240507&Date=20240506&Mercato=MGP&Settore=Prezzi&FiltroDate=InizioFine"
  "scheme"="https"
  "accept"="application/json, text/plain, */*"
  "accept-encoding"="gzip, deflate, br, zstd"
  "accept-language"="en-US,en;q=0.9"
  "cache-control"="no-cache"
  "dnt"="1"
  "moduleid"="12103"
  "pragma"="no-cache"
  "priority"="u=1, i"
  "referer"="https://gme.mercatoelettrico.org/en-us/Home/Results/Electricity/MGP/Download?valore=Prezzi"
  "sec-ch-ua"="`"Not-A.Brand`";v=`"99`", `"Chromium`";v=`"124`""
  "sec-ch-ua-mobile"="?0"
  "sec-ch-ua-platform"="`"Windows`""
  "sec-fetch-dest"="empty"
  "sec-fetch-mode"="cors"
  "sec-fetch-site"="same-origin"
  "tabid"="1749"
  "userid"="-1"
} 

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:

{
    "accept": "application/json, text/plain, */*",
    "accept-language": "en-US,en;q=0.9",
    "cache-control": "no-cache",
    "moduleid": "12103",
    "pragma": "no-cache",
    "priority": "u=1, i",
    "referrer": "https://gme.mercatoelettrico.org/en-us/Home/Results/Electricity/MGP/Download?valore=Prezzi",
    "sec-ch-ua": '"Not-A.Brand";v="99", "Chromium";v="124"',
    "sec-ch-ua-mobile": "?0",
    "sec-ch-ua-platform": '"Windows"',
    "sec-fetch-dest": "empty",
    "sec-fetch-mode": "cors",
    "sec-fetch-site": "same-origin",
    "tabid": "1749",
    "userid": "-1",
}

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.

moddroid94 avatar May 06 '24 15:05 moddroid94

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!

virtualdj avatar May 06 '24 18:05 virtualdj

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.

moddroid94 avatar May 06 '24 23:05 moddroid94

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 😪

virtualdj avatar May 07 '24 21:05 virtualdj

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 :)

moddroid94 avatar May 07 '24 22:05 moddroid94

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

g1za avatar May 08 '24 15:05 g1za

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...

virtualdj avatar May 08 '24 16:05 virtualdj

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

moddroid94 avatar May 08 '24 22:05 moddroid94

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)

g1za avatar May 08 '24 22:05 g1za

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 :|

g1za avatar May 08 '24 22:05 g1za

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 :)

moddroid94 avatar May 09 '24 00:05 moddroid94

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

virtualdj avatar May 09 '24 05:05 virtualdj

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 avatar May 09 '24 08:05 moddroid94

@moddroid94 Ah ok, il potrebbe mi ha tratto in inganno...

virtualdj avatar May 09 '24 10:05 virtualdj

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']

Tagliax avatar Jul 17 '24 13:07 Tagliax

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.

virtualdj avatar Jul 17 '24 18:07 virtualdj

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 avatar Jul 17 '24 18:07 Tagliax

@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 avatar Jul 17 '24 19:07 virtualdj

@virtualdj Io sospetto che loro in quel lasso di tempo eseguono operazioni di backup notturno, altrimenti non si spiegano questi down… 😅

Tagliax avatar Jul 17 '24 19:07 Tagliax

Ciao @virtualdj Avevi visto questa? https://gme.mercatoelettrico.org/it-it/Home/FTP

Tagliax avatar Sep 11 '24 12:09 Tagliax

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à.

virtualdj avatar Sep 11 '24 20:09 virtualdj

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

Tagliax avatar Sep 11 '24 23:09 Tagliax

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.

virtualdj avatar Sep 12 '24 05:09 virtualdj

È 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!

Tagliax avatar Sep 12 '24 07:09 Tagliax

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 avatar Oct 03 '24 17:10 MicheleMercuri

@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).

g1za avatar Oct 03 '24 18:10 g1za

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.

MicheleMercuri avatar Oct 03 '24 18:10 MicheleMercuri

@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?

virtualdj avatar Oct 03 '24 20:10 virtualdj

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 😁.

MicheleMercuri avatar Oct 03 '24 21:10 MicheleMercuri

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.

g1za avatar Oct 03 '24 21:10 g1za

@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 😄

virtualdj avatar Oct 04 '24 16:10 virtualdj