PUN: add zone parameter (#31388)

This commit is contained in:
Petapton 2026-07-01 21:53:10 +02:00 • committed by GitHub
parent 0299650c31
commit 56513e3489
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 44 additions and 7 deletions

View file

@ -28,6 +28,7 @@ var romeLocation *time.Location
type Pun struct { type Pun struct {
*embed *embed
zone string
log *util.Logger log *util.Logger
data *util.Monitor[api.Rates] data *util.Monitor[api.Rates]
} }
@ -37,10 +38,15 @@ type NewDataSet struct {
Prezzi []Prezzo `xml:"Prezzi"` Prezzi []Prezzo `xml:"Prezzi"`
} }
type Zone struct {
XMLName xml.Name
Value string `xml:",chardata"`
}
type Prezzo struct { type Prezzo struct {
Data string `xml:"Data"` Data string `xml:"Data"`
Ora string `xml:"Ora"` Ora string `xml:"Ora"`
PUN string `xml:"PUN"` Zones []Zone `xml:",any"`
} }
type Rate struct { type Rate struct {
@ -57,7 +63,12 @@ func init() {
} }
func NewPunFromConfig(other map[string]any) (api.Tariff, error) { func NewPunFromConfig(other map[string]any) (api.Tariff, error) {
var cc embed var cc struct {
embed `mapstructure:",squash"`
Zone string
}
logger := util.NewLogger("pun")
if err := util.DecodeOther(other, &cc); err != nil { if err := util.DecodeOther(other, &cc); err != nil {
return nil, err return nil, err
@ -67,9 +78,15 @@ func NewPunFromConfig(other map[string]any) (api.Tariff, error) {
return nil, err return nil, err
} }
var zone = strings.ToUpper(strings.TrimSpace(cc.Zone))
if cc.Zone == "" {
zone = "PUN"
}
t := &Pun{ t := &Pun{
log: util.NewLogger("pun"), log: logger,
embed: &cc, zone: zone,
embed: &cc.embed,
data: util.NewMonitor[api.Rates](2 * time.Hour), data: util.NewMonitor[api.Rates](2 * time.Hour),
} }
@ -131,6 +148,16 @@ func (t *Pun) Type() api.TariffType {
return api.TariffTypePriceForecast return api.TariffTypePriceForecast
} }
func (t *Pun) priceForZone(p Prezzo) (float64, error) {
for _, z := range p.Zones {
if strings.ToUpper(strings.TrimSpace(z.XMLName.Local)) == t.zone {
price, err := strconv.ParseFloat(strings.ReplaceAll(z.Value, ",", "."), 64)
return price, err
}
}
return 0, fmt.Errorf("zone %s not found for hour %s", t.zone, p.Ora)
}
func (t *Pun) getData(day time.Time) (api.Rates, error) { func (t *Pun) getData(day time.Time) (api.Rates, error) {
client := request.NewClient(t.log) client := request.NewClient(t.log)
client.Jar, _ = cookiejar.New(nil) client.Jar, _ = cookiejar.New(nil)
@ -213,7 +240,7 @@ func (t *Pun) getData(day time.Time) (api.Rates, error) {
date = date.AddDate(0, 0, -1) date = date.AddDate(0, 0, -1)
} }
price, err := strconv.ParseFloat(strings.ReplaceAll(p.PUN, ",", "."), 64) price, err := t.priceForZone(p)
if err != nil { if err != nil {
return nil, fmt.Errorf("parse price: %w", err) return nil, fmt.Errorf("parse price: %w", err)
} }

View file

@ -10,6 +10,16 @@ group: price
countries: ["IT"] countries: ["IT"]
params: params:
- preset: tariff-base - preset: tariff-base
- name: zone
type: choice
choice: ["NORD", "CNOR", "CSUD", "SUD", "CALA", "SICI", "SARD"]
description:
de: Marktzone
en: Market zone
help:
de: Italienische Strommarktzone. Wenn keine Zone angegeben wird, wird der nationale Einheitspreis (PUN) verwendet.
en: Italian electricity market zone. If no zone is specified, the national unit price (PUN) is used.
render: | render: |
type: pun type: pun
{{ include "tariff-base" . }} {{ include "tariff-base" . }}
zone: {{ .zone }}