Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nuova API sito GME #42

Open
moddroid94 opened this issue May 6, 2024 · 13 comments
Open

Nuova API sito GME #42

moddroid94 opened this issue May 6, 2024 · 13 comments
Labels
enhancement New feature or request

Comments

@moddroid94
Copy link
Collaborator

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.

@virtualdj
Copy link
Owner

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 virtualdj added the enhancement New feature or request label May 6, 2024
@moddroid94
Copy link
Collaborator Author

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.

@virtualdj
Copy link
Owner

virtualdj commented May 7, 2024

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 😪

@moddroid94
Copy link
Collaborator Author

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

@g1za
Copy link

g1za commented May 8, 2024

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

@virtualdj
Copy link
Owner

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

@moddroid94
Copy link
Collaborator Author

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

@g1za
Copy link

g1za commented May 8, 2024

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
Copy link

g1za commented May 8, 2024

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

@moddroid94
Copy link
Collaborator Author

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

@virtualdj
Copy link
Owner

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

@moddroid94
Copy link
Collaborator Author

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.

@virtualdj
Copy link
Owner

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants