tariff/octopus: Support non-Direct Debit tariffs (#20306)

This commit is contained in:
duck. 2025-04-03 08:13:42 +01:00 • committed by GitHub
parent 0c6a2446b8
commit 167124bfa3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 50 additions and 14 deletions

View file

@ -16,11 +16,12 @@ import (
)
type Octopus struct {
log *util.Logger
region string
productCode string
apikey string
data *util.Monitor[api.Rates]
log *util.Logger
region string
productCode string
apikey string
paymentMethod string
data *util.Monitor[api.Rates]
}
var _ api.Tariff = (*Octopus)(nil)
@ -34,6 +35,7 @@ func NewOctopusFromConfig(other map[string]interface{}) (api.Tariff, error) {
Region string
Tariff string // DEPRECATED: use ProductCode
ProductCode string
DirectDebit bool
ApiKey string
}
@ -65,13 +67,18 @@ func NewOctopusFromConfig(other map[string]interface{}) (api.Tariff, error) {
return nil, errors.New("invalid apikey format")
}
}
paymentMethod := octoRest.RatePaymentMethodDirectDebit
if !cc.DirectDebit {
// Not using Direct Debit, filter by non-Direct Debit tariff entries
paymentMethod = octoRest.RatePaymentMethodNotDirectDebit
}
t := &Octopus{
log: logger,
region: cc.Region,
productCode: cc.ProductCode,
apikey: cc.ApiKey,
data: util.NewMonitor[api.Rates](2 * time.Hour),
log: logger,
region: cc.Region,
productCode: cc.ProductCode,
apikey: cc.ApiKey,
paymentMethod: paymentMethod,
data: util.NewMonitor[api.Rates](2 * time.Hour),
}
done := make(chan error)
@ -122,9 +129,21 @@ func (t *Octopus) run(done chan error) {
data := make(api.Rates, 0, len(res.Results))
for _, r := range res.Results {
if t.paymentMethod != "" && r.PaymentMethod != t.paymentMethod {
// A Payment Method filter is set, and this Tariff entry does not match our filter.
continue
}
// ValidityEnd can be zero (wonderful) which just means that the tariff has no present expected end.
// We need to catch that and set the date to something way in the future.
rateEnd := r.ValidityEnd
if rateEnd.IsZero() {
t.log.DEBUG.Printf("handling rate with indefinite length: %v", r.ValidityStart)
// Currently adds a year from the start date
rateEnd = r.ValidityStart.AddDate(1, 0, 0)
}
ar := api.Rate{
Start: r.ValidityStart,
End: r.ValidityEnd,
End: rateEnd,
// UnitRates are supplied inclusive of tax, though this could be flipped easily with a config flag.
Price: r.PriceInclusiveTax / 1e2,
}

View file

@ -40,9 +40,17 @@ type UnitRates struct {
Results []Rate `json:"results"`
}
// RatePaymentMethodDirectDebit is set when the rate only applies when the customer is paying with Direct Debit.
const RatePaymentMethodDirectDebit = "DIRECT_DEBIT"
// RatePaymentMethodNotDirectDebit is set when the rate only applies when the customer is paying with
// any payment means that ISN'T Direct Debit (say, pre-payment meters)
const RatePaymentMethodNotDirectDebit = "NON_DIRECT_DEBIT"
type Rate struct {
ValidityStart time.Time `json:"valid_from"`
ValidityEnd time.Time `json:"valid_to"`
PriceInclusiveTax float64 `json:"value_inc_vat"`
PriceExclusiveTax float64 `json:"value_exc_vat"`
PaymentMethod string `json:"payment_method"`
}

View file

@ -12,8 +12,9 @@ func TestOctopusConfigParse(t *testing.T) {
// This test will start failing if you remove the deprecated "tariff" config var.
validTariffConfig := map[string]interface{}{
"region": "H",
"tariff": "GO-22-03-29",
"region": "H",
"tariff": "GO-22-03-29",
"directDebit": "True",
}
_, err := NewOctopusFromConfig(validTariffConfig)
@ -22,6 +23,7 @@ func TestOctopusConfigParse(t *testing.T) {
validProductCodeConfig := map[string]interface{}{
"region": "H",
"productcode": "GO-22-03-29",
"directDebit": "False",
}
_, err = NewOctopusFromConfig(validProductCodeConfig)

View file

@ -20,7 +20,14 @@ params:
help:
de: "Die DNO-Region, in der Sie sich befinden. Weitere Informationen: https://www.energy-stats.uk/dno-region-codes-explained/"
en: "The DNO region you are located in. More information: https://www.energy-stats.uk/dno-region-codes-explained/"
- name: directDebit
type: bool
default: true
help:
de: "Ich benutze den BACS-Lastschrifttarif."
en: "Use Direct Debit tariff rates."
render: |
type: octopusenergy
productCode: {{ .productCode }}
region: {{ .region }}
directDebit: {{ .directDebit }}