EEBus: add heating brands (BC) (#31344)
This commit is contained in:
parent
6fb096f61f
commit
7e9195d0e3
14 changed files with 120 additions and 14 deletions
|
|
@ -49,7 +49,7 @@ type EEBus struct {
|
|||
}
|
||||
|
||||
func init() {
|
||||
registry.AddCtx("eebus", NewEEBusFromConfig)
|
||||
registry.AddCtx("eebus-evse", NewEEBusFromConfig)
|
||||
}
|
||||
|
||||
// NewEEBusFromConfig creates an EEBus charger from generic config
|
||||
|
|
@ -10,6 +10,7 @@ import (
|
|||
eebusapi "github.com/enbility/eebus-go/api"
|
||||
ucapi "github.com/enbility/eebus-go/usecases/api"
|
||||
"github.com/enbility/eebus-go/usecases/cem/ohpcf"
|
||||
"github.com/enbility/eebus-go/usecases/eg/lpc"
|
||||
"github.com/enbility/eebus-go/usecases/ma/mdt"
|
||||
"github.com/enbility/eebus-go/usecases/ma/mpc"
|
||||
spineapi "github.com/enbility/spine-go/api"
|
||||
|
|
@ -30,17 +31,19 @@ type EEBusOHPCF struct {
|
|||
*embed
|
||||
cem *eebus.CustomerEnergyManagement
|
||||
ma *eebus.MonitoringAppliance
|
||||
eg *eebus.EnergyGuard
|
||||
|
||||
ctx context.Context
|
||||
reboost time.Duration
|
||||
|
||||
mu sync.RWMutex
|
||||
log *util.Logger
|
||||
compressor spineapi.EntityRemoteInterface
|
||||
mpcEntity spineapi.EntityRemoteInterface
|
||||
dhwEntity spineapi.EntityRemoteInterface
|
||||
enabled bool
|
||||
reboosting bool
|
||||
mu sync.RWMutex
|
||||
log *util.Logger
|
||||
compressor spineapi.EntityRemoteInterface
|
||||
mpcEntity spineapi.EntityRemoteInterface
|
||||
dhwEntity spineapi.EntityRemoteInterface
|
||||
egLpcEntity spineapi.EntityRemoteInterface
|
||||
enabled bool
|
||||
reboosting bool
|
||||
|
||||
connector *eebus.Connector
|
||||
}
|
||||
|
|
@ -86,6 +89,7 @@ func NewEEBusOHPCF(ctx context.Context, embed *embed, ski, ip string, reboost ti
|
|||
log: util.NewLogger("eebus-ohpcf"),
|
||||
cem: inst.CustomerEnergyManagement(),
|
||||
ma: inst.MonitoringAppliance(),
|
||||
eg: inst.EnergyGuard(),
|
||||
connector: eebus.NewConnector(),
|
||||
ctx: ctx,
|
||||
reboost: reboost,
|
||||
|
|
@ -125,6 +129,7 @@ func (c *EEBusOHPCF) Connect(connected bool) {
|
|||
c.compressor = nil
|
||||
c.mpcEntity = nil
|
||||
c.dhwEntity = nil
|
||||
c.egLpcEntity = nil
|
||||
}
|
||||
|
||||
// UseCaseEvent implements the eebus.Device interface
|
||||
|
|
@ -162,6 +167,15 @@ func (c *EEBusOHPCF) UseCaseEvent(_ spineapi.DeviceRemoteInterface, entity spine
|
|||
c.mu.Lock()
|
||||
c.dhwEntity = entity
|
||||
c.mu.Unlock()
|
||||
|
||||
// Energy Guard LPC carries the §14a/LPC consumption limit
|
||||
case lpc.UseCaseSupportUpdate:
|
||||
c.mu.Lock()
|
||||
// use most specific selector
|
||||
if c.egLpcEntity == nil || len(entity.Address().Entity) < len(c.egLpcEntity.Address().Entity) {
|
||||
c.egLpcEntity = entity
|
||||
}
|
||||
c.mu.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -360,6 +374,50 @@ func (c *EEBusOHPCF) MaxCurrent(int64) error {
|
|||
return c.apply()
|
||||
}
|
||||
|
||||
var _ api.Dimmer = (*EEBusOHPCF)(nil)
|
||||
|
||||
// Dimmed implements the api.Dimmer interface, reporting whether a §14a/LPC
|
||||
// consumption limit is currently active on the heat pump.
|
||||
func (c *EEBusOHPCF) Dimmed() (bool, error) {
|
||||
c.mu.RLock()
|
||||
entity := c.egLpcEntity
|
||||
c.mu.RUnlock()
|
||||
|
||||
if entity == nil || !c.eg.EgLPCInterface.IsScenarioAvailableAtEntity(entity, eebus.LPCLimit) {
|
||||
return false, api.ErrNotAvailable
|
||||
}
|
||||
|
||||
limit, err := c.eg.EgLPCInterface.ConsumptionLimit(entity)
|
||||
if err != nil {
|
||||
// scenario announced but no usable value yet
|
||||
if errors.Is(err, eebusapi.ErrDataNotAvailable) ||
|
||||
errors.Is(err, eebusapi.ErrMetadataNotAvailable) ||
|
||||
errors.Is(err, eebusapi.ErrDataInvalid) {
|
||||
return false, api.ErrNotAvailable
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
||||
return limit.IsActive && limit.Value > 0, nil
|
||||
}
|
||||
|
||||
// Dim implements the api.Dimmer interface. It writes a §14a/LPC consumption
|
||||
// limit (fixed 0W safe limit) to the heat pump while dimmed, releasing it otherwise.
|
||||
func (c *EEBusOHPCF) Dim(dim bool) error {
|
||||
c.mu.RLock()
|
||||
entity := c.egLpcEntity
|
||||
c.mu.RUnlock()
|
||||
|
||||
if entity == nil || !c.eg.EgLPCInterface.IsScenarioAvailableAtEntity(entity, eebus.LPCLimit) {
|
||||
return api.ErrNotAvailable
|
||||
}
|
||||
|
||||
// TODO: change api.Dimmer to make the limit configurable; use a fixed 0W safe limit for now
|
||||
return c.await(func(cb func(model.ResultDataType)) (*model.MsgCounterType, error) {
|
||||
return c.eg.EgLPCInterface.WriteConsumptionLimit(entity, ucapi.LoadLimit{Value: 0, IsActive: dim}, cb)
|
||||
})
|
||||
}
|
||||
|
||||
// apply issues the command to align the optional consumption with the on/off
|
||||
// intent. It is idempotent: ohpcfControlAction only acts on a state transition.
|
||||
func (c *EEBusOHPCF) apply() error {
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@ func TestEEBusOHPCFNotConnected(t *testing.T) {
|
|||
|
||||
require.ErrorIs(t, c.Enable(true), errNotConnected)
|
||||
require.ErrorIs(t, c.MaxCurrent(16), errNotConnected)
|
||||
|
||||
// dimming uses EG LPC, which is unavailable without an LPC entity
|
||||
require.ErrorIs(t, c.Dim(true), api.ErrNotAvailable)
|
||||
}
|
||||
|
||||
// status mapping: running is C, every other connected state (incl. completed
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
template: eebus
|
||||
template: eebus-evse
|
||||
covers: ["eebus"]
|
||||
products:
|
||||
- description:
|
||||
de: EEBUS kompatibel
|
||||
|
|
@ -8,5 +9,6 @@ capabilities: ["mA", "meter", "dim"]
|
|||
params:
|
||||
- preset: eebus
|
||||
render: |
|
||||
type: eebus-evse
|
||||
{{ include "eebus" . }}
|
||||
meter: true
|
||||
38
templates/definition/charger/eebus-ohpcf-wolfvaillant.yaml
Normal file
38
templates/definition/charger/eebus-ohpcf-wolfvaillant.yaml
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
template: eebus-ohpcf-wolfvaillant
|
||||
products:
|
||||
- brand: Wolf
|
||||
description:
|
||||
generic: CHA-Monoblock (07, 10, 16/20, 20/24 with EEBus)
|
||||
- brand: Wolf
|
||||
description:
|
||||
generic: FHA-Monoblock (EEBus)
|
||||
- brand: Wolf
|
||||
description:
|
||||
generic: EEBus
|
||||
- brand: Vaillant
|
||||
description:
|
||||
generic: aroTHERM plus (EEBus)
|
||||
- brand: Vaillant
|
||||
description:
|
||||
generic: EEBus
|
||||
group: heating
|
||||
capabilities: ["meter", "dim"]
|
||||
params:
|
||||
- preset: eebus
|
||||
- name: reboost
|
||||
type: duration
|
||||
default: 10m
|
||||
advanced: true
|
||||
description:
|
||||
de: Reboost-Intervall
|
||||
en: Reboost interval
|
||||
help:
|
||||
de: Wartezeit, nach der eine neu angekündigte optionale Leistungsaufnahme erneut eingeplant wird.
|
||||
en: Wait time after which a newly announced optional power consumption is scheduled again.
|
||||
render: |
|
||||
type: eebus-ohpcf
|
||||
{{ include "eebus" . }}
|
||||
reboost: {{ .reboost }}
|
||||
features:
|
||||
- heating
|
||||
- integrateddevice
|
||||
|
|
@ -3,8 +3,8 @@ products:
|
|||
- description:
|
||||
de: EEBUS Wärmepumpe (OHPCF)
|
||||
en: EEBUS heat pump (OHPCF)
|
||||
group: heating
|
||||
capabilities: ["meter"]
|
||||
group: heatinggeneric
|
||||
capabilities: ["meter", "dim"]
|
||||
params:
|
||||
- preset: eebus
|
||||
- name: reboost
|
||||
|
|
@ -19,8 +19,7 @@ params:
|
|||
en: Wait time after which a newly announced optional power consumption is scheduled again.
|
||||
render: |
|
||||
type: eebus-ohpcf
|
||||
ski: {{ .ski }}
|
||||
{{ if .ip }}ip: {{ .ip }}{{ end }}
|
||||
{{ include "eebus" . }}
|
||||
reboost: {{ .reboost }}
|
||||
features:
|
||||
- heating
|
||||
|
|
|
|||
|
|
@ -43,4 +43,5 @@ params:
|
|||
- preset: eebus
|
||||
- name: ip
|
||||
render: |
|
||||
type: eebus-evse
|
||||
{{ include "eebus" . }}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ params:
|
|||
- preset: eebus
|
||||
- name: ip
|
||||
render: |
|
||||
type: eebus-evse
|
||||
{{ include "eebus" . }}
|
||||
meter: true
|
||||
chargedEnergy: false
|
||||
|
|
|
|||
|
|
@ -11,4 +11,5 @@ requirements:
|
|||
params:
|
||||
- preset: eebus
|
||||
render: |
|
||||
type: eebus-evse
|
||||
{{ include "eebus" . }}
|
||||
|
|
|
|||
|
|
@ -7,5 +7,6 @@ capabilities: ["iso151182", "mA", "meter", "dim"]
|
|||
params:
|
||||
- preset: eebus
|
||||
render: |
|
||||
type: eebus-evse
|
||||
{{ include "eebus" . }}
|
||||
meter: true
|
||||
|
|
|
|||
|
|
@ -7,5 +7,6 @@ capabilities: ["meter", "dim"]
|
|||
params:
|
||||
- preset: eebus
|
||||
render: |
|
||||
type: eebus-evse
|
||||
{{ include "eebus" . }}
|
||||
meter: true
|
||||
|
|
|
|||
|
|
@ -14,5 +14,6 @@ params:
|
|||
choice: ["grid"]
|
||||
- preset: eebus
|
||||
render: |
|
||||
type: eebus
|
||||
{{ include "eebus" . }}
|
||||
usage: {{ .usage }}
|
||||
|
|
|
|||
|
|
@ -15,5 +15,6 @@ params:
|
|||
choice: ["charge"]
|
||||
- preset: eebus
|
||||
render: |
|
||||
type: eebus
|
||||
{{ include "eebus" . }}
|
||||
usage: {{ .usage }}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
{{ define "eebus" }}
|
||||
type: eebus
|
||||
ski: {{ .ski }}
|
||||
{{ if .ip }}ip: {{ .ip }}{{ end }}
|
||||
{{- end}}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue