PUN: fix api (#17900)
This commit is contained in:
parent
2a2e5760d4
commit
dbb2522295
1 changed files with 52 additions and 73 deletions
125
tariff/pun.go
125
tariff/pun.go
|
|
@ -1,11 +1,12 @@
|
|||
package tariff
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
"net/url"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
|
@ -16,7 +17,6 @@ import (
|
|||
"github.com/evcc-io/evcc/api"
|
||||
"github.com/evcc-io/evcc/util"
|
||||
"github.com/evcc-io/evcc/util/request"
|
||||
"golang.org/x/net/html"
|
||||
)
|
||||
|
||||
type Pun struct {
|
||||
|
|
@ -76,20 +76,18 @@ func (t *Pun) run(done chan error) {
|
|||
var once sync.Once
|
||||
|
||||
for tick := time.Tick(time.Hour); ; <-tick {
|
||||
var today api.Rates
|
||||
if err := backoff.Retry(func() error {
|
||||
var err error
|
||||
|
||||
today, err = t.getData(time.Now())
|
||||
|
||||
return err
|
||||
}, bo()); err != nil {
|
||||
// get today data
|
||||
today, err := backoff.RetryWithData(func() (api.Rates, error) {
|
||||
res, err := t.getData(time.Now())
|
||||
return res, backoffPermanentError(err)
|
||||
}, bo())
|
||||
if err != nil {
|
||||
once.Do(func() { done <- err })
|
||||
|
||||
t.log.ERROR.Println(err)
|
||||
continue
|
||||
}
|
||||
|
||||
// get tomorrow data
|
||||
res, err := backoff.RetryWithData(func() (api.Rates, error) {
|
||||
res, err := t.getData(time.Now().AddDate(0, 0, 1))
|
||||
return res, backoffPermanentError(err)
|
||||
|
|
@ -123,48 +121,54 @@ func (t *Pun) Type() api.TariffType {
|
|||
}
|
||||
|
||||
func (t *Pun) getData(day time.Time) (api.Rates, error) {
|
||||
// Cookie Jar zur Speicherung von Cookies zwischen den Requests
|
||||
client := request.NewClient(t.log)
|
||||
client.Jar, _ = cookiejar.New(nil)
|
||||
|
||||
// Erster Request
|
||||
uri := "https://storico.mercatoelettrico.org/It/WebServerDataStore/MGP_Prezzi/" + day.Format("20060102") + "MGPPrezzi.xml"
|
||||
resp, err := client.Get(uri)
|
||||
// Request the ZIP file
|
||||
uri := "https://gme.mercatoelettrico.org/DesktopModules/GmeDownload/API/ExcelDownload/downloadzipfile?DataInizio=" + day.Format("20060102") + "&DataFine=" + day.Format("20060102") + "&Date=" + day.Format("20060102") + "&Mercato=MGP&Settore=Prezzi&FiltroDate=InizioFine"
|
||||
req, _ := http.NewRequest("GET", uri, nil)
|
||||
req.Header = http.Header{
|
||||
"Referer": {"https://gme.mercatoelettrico.org/en-us/Home/Results/Electricity/MGP/Download?valore=Prezzi"},
|
||||
"moduleid": {"12103"},
|
||||
"sec-ch-ua-mobile": {"?0"},
|
||||
"sec-ch-ua-platform": {"Windows"},
|
||||
"sec-fetch-dest": {"empty"},
|
||||
"sec-fetch-mode": {"cors"},
|
||||
"sec-fetch-site": {"same-origin"},
|
||||
"sec-gpc": {"1"},
|
||||
"tabid": {"1749"},
|
||||
"userid": {"-1"},
|
||||
}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil || resp.StatusCode == http.StatusNotFound {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
body, err := request.ReadBody(resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
formData, err := parseFormFields(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("form fields: %w", err)
|
||||
}
|
||||
|
||||
redirectURL := resp.Request.URL.String()
|
||||
|
||||
// Hinzufügen der spezifizierten Parameter
|
||||
formData.Set("ctl00$ContentPlaceHolder1$CBAccetto1", "on")
|
||||
formData.Set("ctl00$ContentPlaceHolder1$CBAccetto2", "on")
|
||||
formData.Set("ctl00$ContentPlaceHolder1$Button1", "Accetto")
|
||||
|
||||
// Formular senden
|
||||
resp, err = client.PostForm(redirectURL, formData)
|
||||
if err != nil {
|
||||
fmt.Println("Error submitting form:", err)
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Erneuter Request auf die ursprüngliche URL
|
||||
resp, err = client.Get(uri)
|
||||
zipReader, err := zip.NewReader(bytes.NewReader(body), int64(len(body)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Verarbeitung der erhaltenen Daten
|
||||
if len(zipReader.File) != 1 {
|
||||
return nil, fmt.Errorf("unexpected number of files in the ZIP archive")
|
||||
}
|
||||
|
||||
zipFile := zipReader.File[0]
|
||||
f, err := zipFile.Open()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
// Process the received data
|
||||
var dataSet NewDataSet
|
||||
if err := xml.NewDecoder(resp.Body).Decode(&dataSet); err != nil {
|
||||
if err := xml.NewDecoder(f).Decode(&dataSet); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
@ -181,6 +185,12 @@ func (t *Pun) getData(day time.Time) (api.Rates, error) {
|
|||
return nil, fmt.Errorf("parse hour: %w", err)
|
||||
}
|
||||
|
||||
// Adjust hour to handle edge case where p.Ora is "00"
|
||||
if hour == 0 {
|
||||
hour = 24
|
||||
date = date.AddDate(0, 0, -1)
|
||||
}
|
||||
|
||||
location, err := time.LoadLocation("Europe/Rome")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load location: %w", err)
|
||||
|
|
@ -203,34 +213,3 @@ func (t *Pun) getData(day time.Time) (api.Rates, error) {
|
|||
data.Sort()
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func parseFormFields(body io.Reader) (url.Values, error) {
|
||||
data := url.Values{}
|
||||
doc, err := html.Parse(body)
|
||||
if err != nil {
|
||||
return data, err
|
||||
}
|
||||
var f func(*html.Node)
|
||||
f = func(n *html.Node) {
|
||||
if n.Type == html.ElementNode && n.Data == "input" {
|
||||
var inputType, inputName, inputValue string
|
||||
for _, a := range n.Attr {
|
||||
if a.Key == "type" {
|
||||
inputType = a.Val
|
||||
} else if a.Key == "name" {
|
||||
inputName = a.Val
|
||||
} else if a.Key == "value" {
|
||||
inputValue = a.Val
|
||||
}
|
||||
}
|
||||
if inputType == "hidden" && inputName != "" {
|
||||
data.Set(inputName, inputValue)
|
||||
}
|
||||
}
|
||||
for c := n.FirstChild; c != nil; c = c.NextSibling {
|
||||
f(c)
|
||||
}
|
||||
}
|
||||
f(doc)
|
||||
return data, nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue