EEBus: clarify use case names (#24592)
This commit is contained in:
parent
4c53c74aa0
commit
f15344bb52
6 changed files with 125 additions and 123 deletions
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue