Skip to content

Commit

Permalink
PUN: fix api (#17900)
Browse files Browse the repository at this point in the history
  • Loading branch information
MobilettoSoft authored Dec 30, 2024
1 parent 2a2e576 commit dbb2522
Showing 1 changed file with 46 additions and 67 deletions.
113 changes: 46 additions & 67 deletions tariff/pun.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package tariff

import (
"archive/zip"
"bytes"
"encoding/xml"
"fmt"
"io"
"net/http"
"net/http/cookiejar"
"net/url"
"slices"
"strconv"
"strings"
Expand All @@ -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 {
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
if err != nil {
// 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
}
defer resp.Body.Close()

formData, err := parseFormFields(resp.Body)
body, err := request.ReadBody(resp)
if err != nil {
return nil, fmt.Errorf("form fields: %w", err)
return nil, 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)
zipReader, err := zip.NewReader(bytes.NewReader(body), int64(len(body)))
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)
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 resp.Body.Close()
defer f.Close()

// Verarbeitung der erhaltenen Daten
// 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
}

Expand All @@ -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)
Expand All @@ -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
}

0 comments on commit dbb2522

Please sign in to comment.