EEBus: clarify use case names (#24592)

This commit is contained in:
andig 2025-10-20 21:31:51 +02:00 • committed by GitHub
parent 4c53c74aa0
commit f15344bb52
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 125 additions and 123 deletions

View file

@ -31,8 +31,8 @@ type minMax struct {
}
type EEBus struct {
uc *eebus.UseCasesEVSE
ev spineapi.EntityRemoteInterface
cem *eebus.CustomerEnergyManagement
ev spineapi.EntityRemoteInterface
mux sync.RWMutex
log *util.Logger
@ -85,7 +85,7 @@ func NewEEBus(ctx context.Context, ski, ip string, hasMeter, hasChargedEnergy, v
log: util.NewLogger("eebus"),
current: 6,
vasVW: vasVW,
uc: eebus.Instance.Evse(),
cem: eebus.Instance.CustomerEnergyManagement(),
}
c.Connector = eebus.NewConnector()
@ -137,7 +137,7 @@ func (c *EEBus) isEvConnected() (spineapi.EntityRemoteInterface, bool) {
c.mux.RLock()
defer c.mux.RUnlock()
return c.ev, c.ev != nil && c.uc.EvCC.EVConnected(c.ev)
return c.ev, c.ev != nil && c.cem.EvCC.EVConnected(c.ev)
}
// we assume that if any phase current value is > idleFactor * min Current, then charging is active and enabled is true
@ -163,7 +163,7 @@ func (c *EEBus) isCharging(evEntity spineapi.EntityRemoteInterface) bool {
}
if c.lp == nil {
limitsMin, _, _, err := c.uc.OpEV.CurrentLimits(evEntity)
limitsMin, _, _, err := c.cem.OpEV.CurrentLimits(evEntity)
if err != nil || len(limitsMin) == 0 {
// sometimes a min limit is not provided by the EVSE, and we can't take it from the loadpoint
return false
@ -204,7 +204,7 @@ func (c *EEBus) Status() (res api.ChargeStatus, err error) {
err = c.writeCurrentLimitData(evEntity, current)
}()
currentState, err := c.uc.EvCC.ChargeState(evEntity)
currentState, err := c.cem.EvCC.ChargeState(evEntity)
if err != nil {
return api.StatusA, nil
}
@ -235,7 +235,7 @@ func (c *EEBus) Enabled() (bool, error) {
// if the VW VAS PV mode is active, use PV limits
if c.hasActiveVASVW(evEntity) {
limits, err := c.uc.OscEV.LoadControlLimits(evEntity)
limits, err := c.cem.OscEV.LoadControlLimits(evEntity)
if err != nil {
// there are no limits available, e.g. because the data was not received yet
return c.enabled, nil
@ -251,7 +251,7 @@ func (c *EEBus) Enabled() (bool, error) {
return false, nil
}
limits, err := c.uc.OpEV.LoadControlLimits(evEntity)
limits, err := c.cem.OpEV.LoadControlLimits(evEntity)
if err != nil {
// there are no limits available, e.g. because the data was not received yet
return c.enabled, nil
@ -282,7 +282,7 @@ func (c *EEBus) Enable(enable bool) error {
// if we disable charging with a potential but not yet known communication standard ISO15118
// this would set allowed A value to be 0. And this would trigger ISO connections to switch to IEC!
if !enable {
comStandard, err := c.uc.EvCC.CommunicationStandard(evEntity)
comStandard, err := c.cem.EvCC.CommunicationStandard(evEntity)
if err != nil || comStandard == evcc.EVCCCommunicationStandardUnknown {
return api.ErrMustRetry
}
@ -304,11 +304,11 @@ func (c *EEBus) Enable(enable bool) error {
// send current charging power limits to the EV
func (c *EEBus) writeCurrentLimitData(evEntity spineapi.EntityRemoteInterface, current float64) error {
// check if the EVSE supports overload protection limits
if !c.uc.OpEV.IsScenarioAvailableAtEntity(evEntity, 1) {
if !c.cem.OpEV.IsScenarioAvailableAtEntity(evEntity, 1) {
return api.ErrNotAvailable
}
_, maxLimits, _, err := c.uc.OpEV.CurrentLimits(evEntity)
_, maxLimits, _, err := c.cem.OpEV.CurrentLimits(evEntity)
if err != nil {
c.log.DEBUG.Println("no limits from the EVSE are provided:", err)
}
@ -342,16 +342,16 @@ func (c *EEBus) writeCurrentLimitData(evEntity spineapi.EntityRemoteInterface, c
// make sure the recommendations are inactive, otherwise the EV won't go to sleep
// but only if it supports OSCEV and has required data!
if c.uc.OscEV.IsScenarioAvailableAtEntity(evEntity, 1) {
if _, err := c.uc.OscEV.LoadControlLimits(evEntity); err == nil {
if err := c.disableLimits(evEntity, c.uc.OscEV); err != nil {
if c.cem.OscEV.IsScenarioAvailableAtEntity(evEntity, 1) {
if _, err := c.cem.OscEV.LoadControlLimits(evEntity); err == nil {
if err := c.disableLimits(evEntity, c.cem.OscEV); err != nil {
return err
}
}
}
// set overload protection limits
_, err = c.uc.OpEV.WriteLoadControlLimits(evEntity, limits, nil)
_, err = c.cem.OpEV.WriteLoadControlLimits(evEntity, limits, nil)
if err == nil {
c.mux.Lock()
defer c.mux.Unlock()
@ -371,7 +371,7 @@ func (c *EEBus) hasActiveVASVW(evEntity spineapi.EntityRemoteInterface) bool {
}
// ISO15118-2 has to be used between EVSE and EV
if comStandard, err := c.uc.EvCC.CommunicationStandard(evEntity); err != nil || comStandard != model.DeviceConfigurationKeyValueStringTypeISO151182ED2 {
if comStandard, err := c.cem.EvCC.CommunicationStandard(evEntity); err != nil || comStandard != model.DeviceConfigurationKeyValueStringTypeISO151182ED2 {
return false
}
@ -382,7 +382,7 @@ func (c *EEBus) hasActiveVASVW(evEntity spineapi.EntityRemoteInterface) bool {
}
// Optimization of self consumption use case support has to be available
if !c.uc.EvSoc.IsScenarioAvailableAtEntity(evEntity, 1) {
if !c.cem.EvSoc.IsScenarioAvailableAtEntity(evEntity, 1) {
return false
}
@ -421,17 +421,17 @@ func (c *EEBus) writeLoadControlLimitsVASVW(evEntity spineapi.EntityRemoteInterf
}
// check if the EVSE supports optimization of self consumption limits
if !c.uc.OscEV.IsScenarioAvailableAtEntity(evEntity, 1) {
if !c.cem.OscEV.IsScenarioAvailableAtEntity(evEntity, 1) {
return false
}
// OSCEV requires recommendation limits to be available
if _, err := c.uc.OscEV.LoadControlLimits(evEntity); err != nil {
if _, err := c.cem.OscEV.LoadControlLimits(evEntity); err != nil {
return false
}
// on OSCEV all limits have to be active except they are set to the default value
minLimits, _, _, err := c.uc.OscEV.CurrentLimits(evEntity)
minLimits, _, _, err := c.cem.OscEV.CurrentLimits(evEntity)
if err != nil {
return false
}
@ -445,11 +445,11 @@ func (c *EEBus) writeLoadControlLimitsVASVW(evEntity spineapi.EntityRemoteInterf
}
// set recommendation limits
if _, err := c.uc.OscEV.WriteLoadControlLimits(evEntity, limits, nil); err != nil {
if _, err := c.cem.OscEV.WriteLoadControlLimits(evEntity, limits, nil); err != nil {
return false
}
if err := c.disableLimits(evEntity, c.uc.OpEV); err != nil {
if err := c.disableLimits(evEntity, c.cem.OpEV); err != nil {
return false
}
@ -515,17 +515,17 @@ func (c *EEBus) currentPower() (float64, error) {
// does the EVSE provide power data?
var powers []float64
if c.uc.EvCem.IsScenarioAvailableAtEntity(evEntity, 2) {
if c.cem.EvCem.IsScenarioAvailableAtEntity(evEntity, 2) {
// is power data available for real? Elli Gen1 says it supports it, but doesn't provide any data
if powerData, err := c.uc.EvCem.PowerPerPhase(evEntity); err == nil {
if powerData, err := c.cem.EvCem.PowerPerPhase(evEntity); err == nil {
powers = powerData
}
}
// if no power data is available, and currents are reported to be supported, use currents
if len(powers) == 0 && c.uc.EvCem.IsScenarioAvailableAtEntity(evEntity, 1) {
if len(powers) == 0 && c.cem.EvCem.IsScenarioAvailableAtEntity(evEntity, 1) {
// no power provided, calculate from current
if currents, err := c.uc.EvCem.CurrentPerPhase(evEntity); err == nil {
if currents, err := c.cem.EvCem.CurrentPerPhase(evEntity); err == nil {
for _, current := range currents {
powers = append(powers, current*voltage)
}
@ -547,11 +547,11 @@ func (c *EEBus) chargedEnergy() (float64, error) {
return 0, nil
}
if !c.uc.EvCem.IsScenarioAvailableAtEntity(evEntity, 3) {
if !c.cem.EvCem.IsScenarioAvailableAtEntity(evEntity, 3) {
return 0, api.ErrNotAvailable
}
energy, err := c.uc.EvCem.EnergyCharged(evEntity)
energy, err := c.cem.EvCem.EnergyCharged(evEntity)
if err != nil {
return 0, api.ErrNotAvailable
}
@ -567,7 +567,7 @@ func (c *EEBus) currents() (float64, float64, float64, error) {
}
// check if the EVSE supports currents
if !c.uc.EvCem.IsScenarioAvailableAtEntity(evEntity, 1) {
if !c.cem.EvCem.IsScenarioAvailableAtEntity(evEntity, 1) {
return 0, 0, 0, api.ErrNotAvailable
}
@ -583,7 +583,7 @@ func (c *EEBus) currents() (float64, float64, float64, error) {
return 0, 0, 0, api.ErrNotAvailable
}
res, err := c.uc.EvCem.CurrentPerPhase(evEntity)
res, err := c.cem.EvCem.CurrentPerPhase(evEntity)
if err != nil {
return 0, 0, 0, eebus.WrapError(err)
}
@ -605,7 +605,7 @@ func (c *EEBus) Identify() (string, error) {
return "", nil
}
if identification, err := c.uc.EvCC.Identifications(evEntity); err == nil && len(identification) > 0 {
if identification, err := c.cem.EvCC.Identifications(evEntity); err == nil && len(identification) > 0 {
// return the first identification for now
// later this could be multiple, e.g. MAC Address and PCID
return identification[0].Value, nil
@ -623,11 +623,11 @@ func (c *EEBus) Soc() (float64, error) {
return 0, api.ErrNotAvailable
}
if !c.uc.EvSoc.IsScenarioAvailableAtEntity(evEntity, 1) {
if !c.cem.EvSoc.IsScenarioAvailableAtEntity(evEntity, 1) {
return 0, api.ErrNotAvailable
}
soc, err := c.uc.EvSoc.StateOfCharge(evEntity)
soc, err := c.cem.EvSoc.StateOfCharge(evEntity)
if err != nil {
return 0, api.ErrNotAvailable
}
@ -645,7 +645,7 @@ func (c *EEBus) minMax() (minMax, error) {
return zero, nil
}
minLimits, maxLimits, _, err := c.uc.OpEV.CurrentLimits(evEntity)
minLimits, maxLimits, _, err := c.cem.OpEV.CurrentLimits(evEntity)
if err != nil {
return zero, eebus.WrapError(err)
}

View file

@ -23,7 +23,7 @@ func TestEEBusNoCurrents(t *testing.T) {
evEntity := spinemocks.NewEntityRemoteInterface(t)
eebus := &EEBus{
uc: &eebus.UseCasesEVSE{
cem: &eebus.CustomerEnergyManagement{
EvCC: evcc,
EvCem: evcem,
},
@ -198,7 +198,7 @@ func TestEEBusIsCharging(t *testing.T) {
evEntity := spinemocks.NewEntityRemoteInterface(t)
eebus := &EEBus{
uc: &eebus.UseCasesEVSE{
cem: &eebus.CustomerEnergyManagement{
EvCC: evcc,
EvCem: evcem,
OpEV: opev,
@ -225,7 +225,7 @@ func TestEEBusCurrentPower(t *testing.T) {
evEntity := spinemocks.NewEntityRemoteInterface(t)
eebus := &EEBus{
uc: &eebus.UseCasesEVSE{
cem: &eebus.CustomerEnergyManagement{
EvCC: evcc,
EvCem: evcem,
},
@ -248,7 +248,7 @@ func TestEEBusCurrentPower_Elli(t *testing.T) {
evEntity := spinemocks.NewEntityRemoteInterface(t)
eebus := &EEBus{
uc: &eebus.UseCasesEVSE{
cem: &eebus.CustomerEnergyManagement{
EvCC: evcc,
EvCem: evcem,
},

View file

@ -20,7 +20,8 @@ type EEBus struct {
log *util.Logger
*eebus.Connector
uc *eebus.UseCasesCS
cs *eebus.ControllableSystem
ma *eebus.MonitoringAppliance
root api.Circuit
@ -92,7 +93,8 @@ func NewEEBus(ctx context.Context, ski string, limits Limits, root api.Circuit,
c := &EEBus{
log: util.NewLogger("eebus"),
root: root,
uc: eebus.Instance.ControllableSystem(),
cs: eebus.Instance.ControllableSystem(),
ma: eebus.Instance.MonitoringAppliance(),
Connector: eebus.NewConnector(),
heartbeat: util.NewValue[struct{}](2 * time.Minute), // LPC-031
interval: interval,
@ -119,29 +121,34 @@ func NewEEBus(ctx context.Context, ski string, limits Limits, root api.Circuit,
return nil, err
}
// scenarios
for _, s := range c.uc.LPC.RemoteEntitiesScenarios() {
c.log.DEBUG.Println("LPC RemoteEntitiesScenarios:", s.Scenarios)
// controllable system
for _, s := range c.cs.CsLPCInterface.RemoteEntitiesScenarios() {
c.log.DEBUG.Println("CS LPC RemoteEntitiesScenarios:", s.Scenarios)
}
for _, s := range c.uc.LPP.RemoteEntitiesScenarios() {
c.log.DEBUG.Println("LPP RemoteEntitiesScenarios:", s.Scenarios)
for _, s := range c.cs.CsLPPInterface.RemoteEntitiesScenarios() {
c.log.DEBUG.Println("CS LPP RemoteEntitiesScenarios:", s.Scenarios)
}
for _, s := range c.uc.MGCP.RemoteEntitiesScenarios() {
c.log.DEBUG.Println("MGCP RemoteEntitiesScenarios:", s.Scenarios)
// monitoring appliance
for _, s := range c.ma.MaMPCInterface.RemoteEntitiesScenarios() {
c.log.DEBUG.Println("MA MPC RemoteEntitiesScenarios:", s.Scenarios)
}
for _, s := range c.ma.MaMGCPInterface.RemoteEntitiesScenarios() {
c.log.DEBUG.Println("MA MGCP RemoteEntitiesScenarios:", s.Scenarios)
}
// set initial values
if err := c.uc.LPC.SetConsumptionNominalMax(limits.ContractualConsumptionNominalMax); err != nil {
c.log.ERROR.Println("LPC SetConsumptionNominalMax:", err)
if err := c.cs.CsLPCInterface.SetConsumptionNominalMax(limits.ContractualConsumptionNominalMax); err != nil {
c.log.ERROR.Println("CS LPC SetConsumptionNominalMax:", err)
}
if err := c.uc.LPC.SetConsumptionLimit(*c.consumptionLimit); err != nil {
c.log.ERROR.Println("LPC SetConsumptionLimit:", err)
if err := c.cs.CsLPCInterface.SetConsumptionLimit(*c.consumptionLimit); err != nil {
c.log.ERROR.Println("CS LPC SetConsumptionLimit:", err)
}
if err := c.uc.LPC.SetFailsafeConsumptionActivePowerLimit(c.failsafeLimit, true); err != nil {
c.log.ERROR.Println("LPC SetFailsafeConsumptionActivePowerLimit:", err)
if err := c.cs.CsLPCInterface.SetFailsafeConsumptionActivePowerLimit(c.failsafeLimit, true); err != nil {
c.log.ERROR.Println("CS LPC SetFailsafeConsumptionActivePowerLimit:", err)
}
if err := c.uc.LPC.SetFailsafeDurationMinimum(c.failsafeDuration, true); err != nil {
c.log.ERROR.Println("LPC SetFailsafeDurationMinimum:", err)
if err := c.cs.CsLPCInterface.SetFailsafeDurationMinimum(c.failsafeDuration, true); err != nil {
c.log.ERROR.Println("CS LPC SetFailsafeDurationMinimum:", err)
}
return c, nil

View file

@ -99,9 +99,9 @@ func (c *EEBus) UseCaseEvent(_ spineapi.DeviceRemoteInterface, entity spineapi.E
}
func (c *EEBus) dataUpdateLimit() {
limit, err := c.uc.LPC.ConsumptionLimit()
limit, err := c.cs.CsLPCInterface.ConsumptionLimit()
if err != nil {
c.log.ERROR.Println("LPC.ConsumptionLimit:", err)
c.log.ERROR.Println("CS LPC ConsumptionLimit:", err)
return
}
@ -112,9 +112,9 @@ func (c *EEBus) dataUpdateLimit() {
}
func (c *EEBus) writeApprovalRequired() {
for msg, limit := range c.uc.LPC.PendingConsumptionLimits() {
c.log.DEBUG.Println("LPC.PendingConsumptionLimit:", msg, limit)
c.uc.LPC.ApproveOrDenyConsumptionLimit(msg, true, "")
for msg, limit := range c.cs.CsLPCInterface.PendingConsumptionLimits() {
c.log.DEBUG.Println("CS LPC PendingConsumptionLimit:", msg, limit)
c.cs.CsLPCInterface.ApproveOrDenyConsumptionLimit(msg, true, "")
c.mux.Lock()
defer c.mux.Unlock()
@ -124,9 +124,9 @@ func (c *EEBus) writeApprovalRequired() {
}
func (c *EEBus) dataUpdateFailsafeConsumptionActivePowerLimit() {
limit, _, err := c.uc.LPC.FailsafeConsumptionActivePowerLimit()
limit, _, err := c.cs.CsLPCInterface.FailsafeConsumptionActivePowerLimit()
if err != nil {
c.log.ERROR.Println("LPC.FailsafeConsumptionActivePowerLimit:", err)
c.log.ERROR.Println("CS LPC FailsafeConsumptionActivePowerLimit:", err)
return
}
@ -137,9 +137,9 @@ func (c *EEBus) dataUpdateFailsafeConsumptionActivePowerLimit() {
}
func (c *EEBus) dataUpdateFailsafeDurationMinimum() {
duration, _, err := c.uc.LPC.FailsafeDurationMinimum()
duration, _, err := c.cs.CsLPCInterface.FailsafeDurationMinimum()
if err != nil {
c.log.ERROR.Println("LPC.FailsafeDurationMinimum:", err)
c.log.ERROR.Println("CS LPC FailsafeDurationMinimum:", err)
return
}

View file

@ -22,8 +22,8 @@ type EEBus struct {
log *util.Logger
*eebus.Connector
uc *eebus.UseCasesCS
api monitoringAPI
ma *eebus.MonitoringAppliance
mm measurements
power *util.Value[float64]
energy *util.Value[float64]
@ -31,15 +31,6 @@ type EEBus struct {
voltages *util.Value[[]float64]
}
// monitoringAPI provides a unified interface for MGCP and MPC use cases
type monitoringAPI struct {
measurements
powerEvent eebusapi.EventType
energyEvent eebusapi.EventType
currentEvent eebusapi.EventType
voltageEvent eebusapi.EventType
}
type measurements interface {
Power(entity spineapi.EntityRemoteInterface) (float64, error)
EnergyConsumed(entity spineapi.EntityRemoteInterface) (float64, error)
@ -76,33 +67,21 @@ func NewEEBus(ctx context.Context, ski, ip string, usage *templates.Usage, timeo
return nil, errors.New("eebus not configured")
}
cs := eebus.Instance.ControllableSystem()
ma := eebus.Instance.MonitoringAppliance()
// Use MGCP only for explicit grid usage, MPC for everything else (default)
useCase := "mpc"
api := monitoringAPI{
measurements: cs.MPC,
powerEvent: mpc.DataUpdatePower,
energyEvent: mpc.DataUpdateEnergyConsumed,
currentEvent: mpc.DataUpdateCurrentsPerPhase,
voltageEvent: mpc.DataUpdateVoltagePerPhase,
}
mm := measurements(ma.MaMPCInterface)
if usage != nil && *usage == templates.UsageGrid {
useCase = "mgcp"
api = monitoringAPI{
measurements: cs.MGCP,
powerEvent: mgcp.DataUpdatePower,
energyEvent: mgcp.DataUpdateEnergyConsumed,
currentEvent: mgcp.DataUpdateCurrentPerPhase,
voltageEvent: mgcp.DataUpdateVoltagePerPhase,
}
mm = ma.MaMGCPInterface
}
c := &EEBus{
log: util.NewLogger("eebus-" + useCase),
uc: cs,
api: api,
ma: ma,
mm: mm,
Connector: eebus.NewConnector(),
power: util.NewValue[float64](timeout),
energy: util.NewValue[float64](timeout),
@ -129,19 +108,19 @@ func (c *EEBus) UseCaseEvent(_ spineapi.DeviceRemoteInterface, entity spineapi.E
c.log.TRACE.Printf("recv: %s", event)
switch event {
case c.api.powerEvent:
case mpc.DataUpdatePower, mgcp.DataUpdatePower:
c.dataUpdatePower(entity)
case c.api.energyEvent:
case mpc.DataUpdateEnergyConsumed, mgcp.DataUpdateEnergyConsumed:
c.dataUpdateEnergyConsumed(entity)
case c.api.currentEvent:
case mpc.DataUpdateCurrentsPerPhase, mgcp.DataUpdateCurrentPerPhase:
c.dataUpdateCurrentPerPhase(entity)
case c.api.voltageEvent:
case mpc.DataUpdateVoltagePerPhase, mgcp.DataUpdateVoltagePerPhase:
c.dataUpdateVoltagePerPhase(entity)
}
}
func (c *EEBus) dataUpdatePower(entity spineapi.EntityRemoteInterface) {
data, err := c.api.Power(entity)
data, err := c.mm.Power(entity)
if err != nil {
c.log.ERROR.Println("Power:", err)
return
@ -151,7 +130,7 @@ func (c *EEBus) dataUpdatePower(entity spineapi.EntityRemoteInterface) {
}
func (c *EEBus) dataUpdateEnergyConsumed(entity spineapi.EntityRemoteInterface) {
data, err := c.api.EnergyConsumed(entity)
data, err := c.mm.EnergyConsumed(entity)
if err != nil {
c.log.ERROR.Println("EnergyConsumed:", err)
return
@ -162,7 +141,7 @@ func (c *EEBus) dataUpdateEnergyConsumed(entity spineapi.EntityRemoteInterface)
}
func (c *EEBus) dataUpdateCurrentPerPhase(entity spineapi.EntityRemoteInterface) {
data, err := c.api.CurrentPerPhase(entity)
data, err := c.mm.CurrentPerPhase(entity)
if err != nil {
c.log.ERROR.Println("CurrentPerPhase:", err)
return
@ -171,7 +150,7 @@ func (c *EEBus) dataUpdateCurrentPerPhase(entity spineapi.EntityRemoteInterface)
}
func (c *EEBus) dataUpdateVoltagePerPhase(entity spineapi.EntityRemoteInterface) {
data, err := c.api.VoltagePerPhase(entity)
data, err := c.mm.VoltagePerPhase(entity)
if err != nil {
c.log.ERROR.Println("VoltagePerPhase:", err)
return

View file

@ -38,8 +38,8 @@ type Device interface {
UseCaseEvent(device spineapi.DeviceRemoteInterface, entity spineapi.EntityRemoteInterface, event eebusapi.EventType)
}
// EVSE UseCases
type UseCasesEVSE struct {
// Customer Energy Management
type CustomerEnergyManagement struct {
EvseCC ucapi.CemEVSECCInterface
EvCC ucapi.CemEVCCInterface
EvCem ucapi.CemEVCEMInterface
@ -47,18 +47,25 @@ type UseCasesEVSE struct {
OpEV ucapi.CemOPEVInterface
OscEV ucapi.CemOSCEVInterface
}
type UseCasesCS struct {
LPC ucapi.CsLPCInterface
LPP ucapi.CsLPPInterface
MGCP ucapi.MaMGCPInterface
MPC ucapi.MaMPCInterface
// Controllable System
type ControllableSystem struct {
ucapi.CsLPCInterface
ucapi.CsLPPInterface
}
// Monitoring Appliance
type MonitoringAppliance struct {
ucapi.MaMGCPInterface
ucapi.MaMPCInterface
}
type EEBus struct {
service eebusapi.ServiceInterface
evseUC UseCasesEVSE
csUC UseCasesCS
cem CustomerEnergyManagement
cs ControllableSystem
ma MonitoringAppliance
mux sync.Mutex
log *util.Logger
@ -142,7 +149,7 @@ func NewServer(other Config) (*EEBus, error) {
localEntity := c.service.LocalDevice().EntityForType(model.EntityTypeTypeCEM)
// evse
c.evseUC = UseCasesEVSE{
c.cem = CustomerEnergyManagement{
EvseCC: evsecc.NewEVSECC(localEntity, c.ucCallback),
EvCC: evcc.NewEVCC(c.service, localEntity, c.ucCallback),
EvCem: evcem.NewEVCEM(c.service, localEntity, c.ucCallback),
@ -152,19 +159,24 @@ func NewServer(other Config) (*EEBus, error) {
}
// controllable system
c.csUC = UseCasesCS{
LPC: lpc.NewLPC(localEntity, c.ucCallback),
LPP: lpp.NewLPP(localEntity, c.ucCallback),
MGCP: mgcp.NewMGCP(localEntity, c.ucCallback),
MPC: mpc.NewMPC(localEntity, c.ucCallback),
c.cs = ControllableSystem{
CsLPCInterface: lpc.NewLPC(localEntity, c.ucCallback),
CsLPPInterface: lpp.NewLPP(localEntity, c.ucCallback),
}
// monitoring appliance
c.ma = MonitoringAppliance{
MaMGCPInterface: mgcp.NewMGCP(localEntity, c.ucCallback),
MaMPCInterface: mpc.NewMPC(localEntity, c.ucCallback),
}
// register use cases
for _, uc := range []eebusapi.UseCaseInterface{
c.evseUC.EvseCC, c.evseUC.EvCC,
c.evseUC.EvCem, c.evseUC.OpEV,
c.evseUC.OscEV, c.evseUC.EvSoc,
c.csUC.LPC, c.csUC.LPP, c.csUC.MGCP, c.csUC.MPC,
c.cem.EvseCC, c.cem.EvCC,
c.cem.EvCem, c.cem.OpEV,
c.cem.OscEV, c.cem.EvSoc,
c.cs.CsLPCInterface, c.cs.CsLPPInterface,
c.ma.MaMGCPInterface, c.ma.MaMPCInterface,
} {
c.service.AddUseCase(uc)
}
@ -206,12 +218,16 @@ func (c *EEBus) UnregisterDevice(ski string, device Device) {
}
}
func (c *EEBus) Evse() *UseCasesEVSE {
return &c.evseUC
func (c *EEBus) CustomerEnergyManagement() *CustomerEnergyManagement {
return &c.cem
}
func (c *EEBus) ControllableSystem() *UseCasesCS {
return &c.csUC
func (c *EEBus) ControllableSystem() *ControllableSystem {
return &c.cs
}
func (c *EEBus) MonitoringAppliance() *MonitoringAppliance {
return &c.ma
}
func (c *EEBus) Run() {