diff --git a/.github/workflows/default.yml b/.github/workflows/default.yml index 58bb98c8..d649a4e0 100644 --- a/.github/workflows/default.yml +++ b/.github/workflows/default.yml @@ -48,7 +48,7 @@ jobs: file: coverage.out - name: Run Gosec Security Scanner - uses: securego/gosec@11d69032b0856c96afd4c493967ab7a30e20ff5e + uses: securego/gosec@v2.20.0 with: # we let the report trigger content trigger a failure using the GitHub Security features. args: '-no-fail -fmt sarif -out results.sarif ./...' diff --git a/go.mod b/go.mod index 8817ed02..f3bc91e0 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,8 @@ module github.com/enbility/eebus-go go 1.21.1 require ( - github.com/enbility/ship-go v0.5.3 - github.com/enbility/spine-go v0.6.2 + github.com/enbility/ship-go v0.0.0-20240904104254-04d944c4f825 + github.com/enbility/spine-go v0.0.0-20240907194637-0024041a4f36 github.com/stretchr/testify v1.9.0 ) @@ -35,7 +35,3 @@ retract ( v0.2.2 // Contains retractions only. v0.2.1 // Published accidentally. ) - -replace github.com/enbility/ship-go => github.com/enbility/ship-go v0.0.0-20240904104254-04d944c4f825 - -replace github.com/enbility/spine-go => github.com/enbility/spine-go v0.0.0-20240903070433-dd8261993071 diff --git a/go.sum b/go.sum index 076518cb..024a2d12 100644 --- a/go.sum +++ b/go.sum @@ -6,8 +6,8 @@ github.com/enbility/go-avahi v0.0.0-20240829083637-9ae2ef5f5ed2 h1:voP4zFVNvVWxl github.com/enbility/go-avahi v0.0.0-20240829083637-9ae2ef5f5ed2/go.mod h1:KJXUEgg/b4XZzS+OFfqnykHREsinuNSL/IzJ+nU43P8= github.com/enbility/ship-go v0.0.0-20240904104254-04d944c4f825 h1:i/n9UFYf660TyC8Y48P3MDxLaWWKRNW3pFjEOVzPzto= github.com/enbility/ship-go v0.0.0-20240904104254-04d944c4f825/go.mod h1:dzymc1D7BDZUTLVHVt9JRRkFLlBrlUmRKyLJvAe07Mc= -github.com/enbility/spine-go v0.0.0-20240903070433-dd8261993071 h1:rjvpnD3xTrSPdU6AQK4miwl/gZQ84CJ6gv/kEEguBME= -github.com/enbility/spine-go v0.0.0-20240903070433-dd8261993071/go.mod h1:6AbRXzd0fLVGFJdT60YQACe1WskwdjiznCfljQ+Ud6s= +github.com/enbility/spine-go v0.0.0-20240907194637-0024041a4f36 h1:Y44hzp5uIYSEyBMe/zwFzlXKokgZHQ9cv2NiIF1NkZs= +github.com/enbility/spine-go v0.0.0-20240907194637-0024041a4f36/go.mod h1:BDvhbs+XsWDGYwd8eQOzPXc8w/avVFmWKLlSKV/gx9k= github.com/enbility/zeroconf/v2 v2.0.0-20240827101515-f3956627c450 h1:39tnpfiV5OVfYb9sOqYmoivBzTHyNLWSYIxd9Qng1eg= github.com/enbility/zeroconf/v2 v2.0.0-20240827101515-f3956627c450/go.mod h1:1sUbJ+VE7yLNyRzGoCMjoDWtdZ+bW4aYBKx2+Rw+9hs= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= diff --git a/usecases/cem/cevc/events.go b/usecases/cem/cevc/events.go index 1dd07b47..c47e31fd 100644 --- a/usecases/cem/cevc/events.go +++ b/usecases/cem/cevc/events.go @@ -49,8 +49,10 @@ func (e *CEVC) HandleEvent(payload spineapi.EventPayload) { func (e *CEVC) evConnected(entity spineapi.EntityRemoteInterface) { // initialise features, e.g. subscriptions, descriptions if evDeviceConfiguration, err := client.NewDeviceConfiguration(e.LocalEntity, entity); err == nil { - if _, err := evDeviceConfiguration.Subscribe(); err != nil { - logging.Log().Debug(err) + if !evDeviceConfiguration.HasSubscription() { + if _, err := evDeviceConfiguration.Subscribe(); err != nil { + logging.Log().Debug(err) + } } // get device configuration descriptions @@ -60,12 +62,16 @@ func (e *CEVC) evConnected(entity spineapi.EntityRemoteInterface) { } if evTimeSeries, err := client.NewTimeSeries(e.LocalEntity, entity); err == nil { - if _, err := evTimeSeries.Subscribe(); err != nil { - logging.Log().Debug(err) + if !evTimeSeries.HasSubscription() { + if _, err := evTimeSeries.Subscribe(); err != nil { + logging.Log().Debug(err) + } } - if _, err := evTimeSeries.Bind(); err != nil { - logging.Log().Debug(err) + if !evTimeSeries.HasBinding() { + if _, err := evTimeSeries.Bind(); err != nil { + logging.Log().Debug(err) + } } // get time series descriptions @@ -80,12 +86,16 @@ func (e *CEVC) evConnected(entity spineapi.EntityRemoteInterface) { } if evIncentiveTable, err := client.NewIncentiveTable(e.LocalEntity, entity); err == nil { - if _, err := evIncentiveTable.Subscribe(); err != nil { - logging.Log().Debug(err) + if !evIncentiveTable.HasSubscription() { + if _, err := evIncentiveTable.Subscribe(); err != nil { + logging.Log().Debug(err) + } } - if _, err := evIncentiveTable.Bind(); err != nil { - logging.Log().Debug(err) + if !evIncentiveTable.HasBinding() { + if _, err := evIncentiveTable.Bind(); err != nil { + logging.Log().Debug(err) + } } // get incentivetable descriptions diff --git a/usecases/cem/evcc/events.go b/usecases/cem/evcc/events.go index aa35c4b9..0c789827 100644 --- a/usecases/cem/evcc/events.go +++ b/usecases/cem/evcc/events.go @@ -58,8 +58,10 @@ func (e *EVCC) HandleEvent(payload spineapi.EventPayload) { func (e *EVCC) evConnected(payload spineapi.EventPayload) { // initialise features, e.g. subscriptions, descriptions if evDeviceClassification, err := client.NewDeviceClassification(e.LocalEntity, payload.Entity); err == nil { - if _, err := evDeviceClassification.Subscribe(); err != nil { - logging.Log().Debug(err) + if !evDeviceClassification.HasSubscription() { + if _, err := evDeviceClassification.Subscribe(); err != nil { + logging.Log().Debug(err) + } } // get manufacturer details @@ -69,9 +71,12 @@ func (e *EVCC) evConnected(payload spineapi.EventPayload) { } if evDeviceConfiguration, err := client.NewDeviceConfiguration(e.LocalEntity, payload.Entity); err == nil { - if _, err := evDeviceConfiguration.Subscribe(); err != nil { - logging.Log().Debug(err) + if !evDeviceConfiguration.HasSubscription() { + if _, err := evDeviceConfiguration.Subscribe(); err != nil { + logging.Log().Debug(err) + } } + // get ev configuration data if _, err := evDeviceConfiguration.RequestKeyValueDescriptions(nil, nil); err != nil { logging.Log().Debug(err) @@ -79,8 +84,10 @@ func (e *EVCC) evConnected(payload spineapi.EventPayload) { } if evDeviceDiagnosis, err := client.NewDeviceDiagnosis(e.LocalEntity, payload.Entity); err == nil { - if _, err := evDeviceDiagnosis.Subscribe(); err != nil { - logging.Log().Debug(err) + if !evDeviceDiagnosis.HasSubscription() { + if _, err := evDeviceDiagnosis.Subscribe(); err != nil { + logging.Log().Debug(err) + } } // get device diagnosis state @@ -90,8 +97,10 @@ func (e *EVCC) evConnected(payload spineapi.EventPayload) { } if evElectricalConnection, err := client.NewElectricalConnection(e.LocalEntity, payload.Entity); err == nil { - if _, err := evElectricalConnection.Subscribe(); err != nil { - logging.Log().Debug(err) + if !evElectricalConnection.HasSubscription() { + if _, err := evElectricalConnection.Subscribe(); err != nil { + logging.Log().Debug(err) + } } // get electrical connection parameter descriptions @@ -106,8 +115,10 @@ func (e *EVCC) evConnected(payload spineapi.EventPayload) { } if evIdentification, err := client.NewIdentification(e.LocalEntity, payload.Entity); err == nil { - if _, err := evIdentification.Subscribe(); err != nil { - logging.Log().Debug(err) + if !evIdentification.HasSubscription() { + if _, err := evIdentification.Subscribe(); err != nil { + logging.Log().Debug(err) + } } // get identification diff --git a/usecases/cem/evcem/events.go b/usecases/cem/evcem/events.go index 61613190..e26e6556 100644 --- a/usecases/cem/evcem/events.go +++ b/usecases/cem/evcem/events.go @@ -43,8 +43,10 @@ func (e *EVCEM) evConnected(entity spineapi.EntityRemoteInterface) { // initialise features, e.g. subscriptions, descriptions if evElectricalConnection, err := client.NewElectricalConnection(e.LocalEntity, entity); err == nil { - if _, err := evElectricalConnection.Subscribe(); err != nil { - logging.Log().Debug(err) + if !evElectricalConnection.HasSubscription() { + if _, err := evElectricalConnection.Subscribe(); err != nil { + logging.Log().Debug(err) + } } // get electrical connection descriptions @@ -59,8 +61,10 @@ func (e *EVCEM) evConnected(entity spineapi.EntityRemoteInterface) { } if evMeasurement, err := client.NewMeasurement(e.LocalEntity, entity); err == nil { - if _, err := evMeasurement.Subscribe(); err != nil { - logging.Log().Debug(err) + if !evMeasurement.HasSubscription() { + if _, err := evMeasurement.Subscribe(); err != nil { + logging.Log().Debug(err) + } } // get measurement descriptions diff --git a/usecases/cem/opev/events.go b/usecases/cem/opev/events.go index 611d8f49..05a33405 100644 --- a/usecases/cem/opev/events.go +++ b/usecases/cem/opev/events.go @@ -43,12 +43,16 @@ func (e *OPEV) HandleEvent(payload spineapi.EventPayload) { func (e *OPEV) evConnected(entity spineapi.EntityRemoteInterface) { // initialise features, e.g. subscriptions, descriptions if evLoadControl, err := client.NewLoadControl(e.LocalEntity, entity); err == nil { - if _, err := evLoadControl.Subscribe(); err != nil { - logging.Log().Debug(err) + if !evLoadControl.HasSubscription() { + if _, err := evLoadControl.Subscribe(); err != nil { + logging.Log().Debug(err) + } } - if _, err := evLoadControl.Bind(); err != nil { - logging.Log().Debug(err) + if !evLoadControl.HasBinding() { + if _, err := evLoadControl.Bind(); err != nil { + logging.Log().Debug(err) + } } // get descriptions diff --git a/usecases/cem/vabd/events.go b/usecases/cem/vabd/events.go index 46af814d..fa8f9ab9 100644 --- a/usecases/cem/vabd/events.go +++ b/usecases/cem/vabd/events.go @@ -39,8 +39,10 @@ func (e *VABD) HandleEvent(payload spineapi.EventPayload) { // process required steps when a grid device is connected func (e *VABD) inverterConnected(entity spineapi.EntityRemoteInterface) { if electricalConnection, err := client.NewElectricalConnection(e.LocalEntity, entity); err == nil { - if _, err := electricalConnection.Subscribe(); err != nil { - logging.Log().Error(err) + if !electricalConnection.HasSubscription() { + if _, err := electricalConnection.Subscribe(); err != nil { + logging.Log().Error(err) + } } // get electrical connection parameter @@ -54,8 +56,10 @@ func (e *VABD) inverterConnected(entity spineapi.EntityRemoteInterface) { } if measurement, err := client.NewMeasurement(e.LocalEntity, entity); err == nil { - if _, err := measurement.Subscribe(); err != nil { - logging.Log().Error(err) + if !measurement.HasSubscription() { + if _, err := measurement.Subscribe(); err != nil { + logging.Log().Error(err) + } } // get measurement parameters diff --git a/usecases/cem/vapd/events.go b/usecases/cem/vapd/events.go index 2dd03d31..30f94a69 100644 --- a/usecases/cem/vapd/events.go +++ b/usecases/cem/vapd/events.go @@ -45,8 +45,10 @@ func (e *VAPD) HandleEvent(payload spineapi.EventPayload) { // process required steps when a grid device is connected func (e *VAPD) inverterConnected(entity spineapi.EntityRemoteInterface) { if deviceConfiguration, err := client.NewDeviceConfiguration(e.LocalEntity, entity); err == nil { - if _, err := deviceConfiguration.Subscribe(); err != nil { - logging.Log().Error(err) + if !deviceConfiguration.HasSubscription() { + if _, err := deviceConfiguration.Subscribe(); err != nil { + logging.Log().Error(err) + } } // get configuration data @@ -56,8 +58,10 @@ func (e *VAPD) inverterConnected(entity spineapi.EntityRemoteInterface) { } if electricalConnection, err := client.NewElectricalConnection(e.LocalEntity, entity); err == nil { - if _, err := electricalConnection.Subscribe(); err != nil { - logging.Log().Error(err) + if !electricalConnection.HasSubscription() { + if _, err := electricalConnection.Subscribe(); err != nil { + logging.Log().Error(err) + } } // get electrical connection parameter @@ -71,8 +75,10 @@ func (e *VAPD) inverterConnected(entity spineapi.EntityRemoteInterface) { } if measurement, err := client.NewMeasurement(e.LocalEntity, entity); err == nil { - if _, err := measurement.Subscribe(); err != nil { - logging.Log().Error(err) + if !measurement.HasSubscription() { + if _, err := measurement.Subscribe(); err != nil { + logging.Log().Error(err) + } } // get measurement parameters diff --git a/usecases/cs/lpc/events.go b/usecases/cs/lpc/events.go index f2f3ef7b..65aa3a99 100644 --- a/usecases/cs/lpc/events.go +++ b/usecases/cs/lpc/events.go @@ -102,8 +102,10 @@ func (e *LPC) deviceConnected(payload spineapi.EventPayload) { if len(deviceDiagEntities) == 1 { if localDeviceDiag, err := client.NewDeviceDiagnosis(e.LocalEntity, deviceDiagEntities[0]); err == nil { e.heartbeatDiag = localDeviceDiag - if _, err := localDeviceDiag.Subscribe(); err != nil { - logging.Log().Debug(err) + if !localDeviceDiag.HasSubscription() { + if _, err := localDeviceDiag.Subscribe(); err != nil { + logging.Log().Debug(err) + } } if _, err := localDeviceDiag.RequestHeartbeat(); err != nil { @@ -126,8 +128,10 @@ func (e *LPC) subscribeHeartbeatWorkaround(payload spineapi.EventPayload) { if e.heartbeatKeoWorkaround { if localDeviceDiag, err := client.NewDeviceDiagnosis(e.LocalEntity, payload.Entity); err == nil { e.heartbeatDiag = localDeviceDiag - if _, err := localDeviceDiag.Subscribe(); err != nil { - logging.Log().Debug(err) + if !localDeviceDiag.HasSubscription() { + if _, err := localDeviceDiag.Subscribe(); err != nil { + logging.Log().Debug(err) + } } if _, err := localDeviceDiag.RequestHeartbeat(); err != nil { diff --git a/usecases/cs/lpc/public_test.go b/usecases/cs/lpc/public_test.go index 8aceb046..77a5d8e1 100644 --- a/usecases/cs/lpc/public_test.go +++ b/usecases/cs/lpc/public_test.go @@ -81,21 +81,21 @@ func (s *CsLPCSuite) Test_PendingConsumptionLimits() { func (s *CsLPCSuite) Test_Failsafe() { limit, changeable, err := s.sut.FailsafeConsumptionActivePowerLimit() assert.Equal(s.T(), 0.0, limit) - assert.Equal(s.T(), false, changeable) + assert.Equal(s.T(), true, changeable) assert.Nil(s.T(), err) - err = s.sut.SetFailsafeConsumptionActivePowerLimit(10, true) + err = s.sut.SetFailsafeConsumptionActivePowerLimit(10, false) assert.Nil(s.T(), err) limit, changeable, err = s.sut.FailsafeConsumptionActivePowerLimit() assert.Equal(s.T(), 10.0, limit) - assert.Equal(s.T(), true, changeable) + assert.Equal(s.T(), false, changeable) assert.Nil(s.T(), err) // The actual tests of the functionality is located in the util package duration, changeable, err := s.sut.FailsafeDurationMinimum() assert.Equal(s.T(), time.Duration(0), duration) - assert.Equal(s.T(), false, changeable) + assert.Equal(s.T(), true, changeable) assert.Nil(s.T(), err) err = s.sut.SetFailsafeDurationMinimum(time.Duration(time.Hour*1), true) @@ -104,6 +104,9 @@ func (s *CsLPCSuite) Test_Failsafe() { err = s.sut.SetFailsafeDurationMinimum(time.Duration(time.Hour*2), true) assert.Nil(s.T(), err) + err = s.sut.SetFailsafeConsumptionActivePowerLimit(10, true) + assert.Nil(s.T(), err) + limit, changeable, err = s.sut.FailsafeConsumptionActivePowerLimit() assert.Equal(s.T(), 10.0, limit) assert.Equal(s.T(), true, changeable) diff --git a/usecases/cs/lpc/usecase.go b/usecases/cs/lpc/usecase.go index f974a335..1228df92 100644 --- a/usecases/cs/lpc/usecase.go +++ b/usecases/cs/lpc/usecase.go @@ -8,6 +8,7 @@ import ( "github.com/enbility/eebus-go/features/server" ucapi "github.com/enbility/eebus-go/usecases/api" "github.com/enbility/eebus-go/usecases/usecase" + "github.com/enbility/ship-go/logging" spineapi "github.com/enbility/spine-go/api" "github.com/enbility/spine-go/model" "github.com/enbility/spine-go/spine" @@ -124,11 +125,13 @@ func (e *LPC) approveOrDenyConsumptionLimit(msg *spineapi.Message, approve bool, func (e *LPC) loadControlWriteCB(msg *spineapi.Message) { if msg.RequestHeader == nil || msg.RequestHeader.MsgCounter == nil || msg.Cmd.LoadControlLimitListData == nil { + logging.Log().Debug("LPC loadControlWriteCB: invalid message") return } _, limitId, err := e.loadControlServerAndLimitId() if err != nil { + logging.Log().Debug("LPC loadControlWriteCB: error getting limit id") return } @@ -137,6 +140,7 @@ func (e *LPC) loadControlWriteCB(msg *spineapi.Message) { // we assume there is always only one limit if data == nil || data.LoadControlLimitData == nil || len(data.LoadControlLimitData) == 0 { + logging.Log().Debug("LPC loadControlWriteCB: no data") return } @@ -223,7 +227,7 @@ func (e *LPC) AddFeatures() { _ = dcs.UpdateKeyValueDataForFilter( model.DeviceConfigurationKeyValueDataType{ Value: value, - IsValueChangeable: util.Ptr(false), + IsValueChangeable: util.Ptr(true), }, nil, model.DeviceConfigurationKeyValueDescriptionDataType{ @@ -237,7 +241,7 @@ func (e *LPC) AddFeatures() { _ = dcs.UpdateKeyValueDataForFilter( model.DeviceConfigurationKeyValueDataType{ Value: value, - IsValueChangeable: util.Ptr(false), + IsValueChangeable: util.Ptr(true), }, nil, model.DeviceConfigurationKeyValueDescriptionDataType{ diff --git a/usecases/cs/lpc/usecase_test.go b/usecases/cs/lpc/usecase_test.go index 119c9a87..75eda834 100644 --- a/usecases/cs/lpc/usecase_test.go +++ b/usecases/cs/lpc/usecase_test.go @@ -27,11 +27,12 @@ func (s *CsLPCSuite) Test_loadControlServerAndLimitId() { } func (s *CsLPCSuite) Test_loadControlWriteCB() { - msg := &spineapi.Message{} + msg := spineapi.Message{} - s.sut.loadControlWriteCB(msg) + s.sut.loadControlWriteCB(&msg) + assert.False(s.T(), s.eventCalled) - msg = &spineapi.Message{ + msg = spineapi.Message{ RequestHeader: &model.HeaderType{ MsgCounter: util.Ptr(model.MsgCounterType(500)), }, @@ -42,17 +43,23 @@ func (s *CsLPCSuite) Test_loadControlWriteCB() { EntityRemote: s.monitoredEntity, } - s.sut.loadControlWriteCB(msg) + msg0 := msg + s.sut.loadControlWriteCB(&msg0) - msg.Cmd = model.CmdType{ + msg1 := msg + msg1.RequestHeader.MsgCounter = util.Ptr(model.MsgCounterType(501)) + msg1.Cmd = model.CmdType{ LoadControlLimitListData: &model.LoadControlLimitListDataType{ LoadControlLimitData: []model.LoadControlLimitDataType{}, }, } - s.sut.loadControlWriteCB(msg) + s.sut.loadControlWriteCB(&msg1) + assert.False(s.T(), s.eventCalled) - msg.Cmd = model.CmdType{ + msg2 := msg + msg2.RequestHeader.MsgCounter = util.Ptr(model.MsgCounterType(502)) + msg2.Cmd = model.CmdType{ LoadControlLimitListData: &model.LoadControlLimitListDataType{ LoadControlLimitData: []model.LoadControlLimitDataType{ {}, @@ -60,9 +67,12 @@ func (s *CsLPCSuite) Test_loadControlWriteCB() { }, } - s.sut.loadControlWriteCB(msg) + s.sut.loadControlWriteCB(&msg2) + assert.False(s.T(), s.eventCalled) - msg.Cmd = model.CmdType{ + msg3 := msg + msg3.RequestHeader.MsgCounter = util.Ptr(model.MsgCounterType(503)) + msg3.Cmd = model.CmdType{ LoadControlLimitListData: &model.LoadControlLimitListDataType{ LoadControlLimitData: []model.LoadControlLimitDataType{ { @@ -75,7 +85,33 @@ func (s *CsLPCSuite) Test_loadControlWriteCB() { }, } - s.sut.loadControlWriteCB(msg) + s.sut.loadControlWriteCB(&msg3) + assert.True(s.T(), s.eventCalled) + + msg4 := msg + msg4.RequestHeader.MsgCounter = util.Ptr(model.MsgCounterType(504)) + msg4.Cmd = model.CmdType{ + Filter: []model.FilterType{ + { + CmdControl: &model.CmdControlType{ + Partial: util.Ptr(model.ElementTagType{}), + }, + }, + }, + LoadControlLimitListData: &model.LoadControlLimitListDataType{ + LoadControlLimitData: []model.LoadControlLimitDataType{ + { + LimitId: util.Ptr(model.LoadControlLimitIdType(0)), + IsLimitActive: util.Ptr(true), + Value: model.NewScaledNumberType(5000), + TimePeriod: model.NewTimePeriodTypeWithRelativeEndTime(time.Hour * 3), + }, + }, + }, + } + + s.sut.loadControlWriteCB(&msg4) + assert.True(s.T(), s.eventCalled) } func (s *CsLPCSuite) Test_UpdateUseCaseAvailability() { diff --git a/usecases/cs/lpp/events.go b/usecases/cs/lpp/events.go index d7c2541d..ea68cad2 100644 --- a/usecases/cs/lpp/events.go +++ b/usecases/cs/lpp/events.go @@ -102,8 +102,10 @@ func (e *LPP) deviceConnected(payload spineapi.EventPayload) { if len(deviceDiagEntities) == 1 { if localDeviceDiag, err := client.NewDeviceDiagnosis(e.LocalEntity, deviceDiagEntities[0]); err == nil { e.heartbeatDiag = localDeviceDiag - if _, err := localDeviceDiag.Subscribe(); err != nil { - logging.Log().Debug(err) + if !localDeviceDiag.HasSubscription() { + if _, err := localDeviceDiag.Subscribe(); err != nil { + logging.Log().Debug(err) + } } if _, err := localDeviceDiag.RequestHeartbeat(); err != nil { @@ -126,8 +128,10 @@ func (e *LPP) subscribeHeartbeatWorkaround(payload spineapi.EventPayload) { if e.heartbeatKeoWorkaround { if localDeviceDiag, err := client.NewDeviceDiagnosis(e.LocalEntity, payload.Entity); err == nil { e.heartbeatDiag = localDeviceDiag - if _, err := localDeviceDiag.Subscribe(); err != nil { - logging.Log().Debug(err) + if !localDeviceDiag.HasSubscription() { + if _, err := localDeviceDiag.Subscribe(); err != nil { + logging.Log().Debug(err) + } } if _, err := localDeviceDiag.RequestHeartbeat(); err != nil { diff --git a/usecases/cs/lpp/public_test.go b/usecases/cs/lpp/public_test.go index 90442644..6d911172 100644 --- a/usecases/cs/lpp/public_test.go +++ b/usecases/cs/lpp/public_test.go @@ -80,21 +80,21 @@ func (s *CsLPPSuite) Test_PendingProductionLimits() { func (s *CsLPPSuite) Test_Failsafe() { limit, changeable, err := s.sut.FailsafeProductionActivePowerLimit() assert.Equal(s.T(), 0.0, limit) - assert.Equal(s.T(), false, changeable) + assert.Equal(s.T(), true, changeable) assert.Nil(s.T(), err) - err = s.sut.SetFailsafeProductionActivePowerLimit(10, true) + err = s.sut.SetFailsafeProductionActivePowerLimit(10, false) assert.Nil(s.T(), err) limit, changeable, err = s.sut.FailsafeProductionActivePowerLimit() assert.Equal(s.T(), 10.0, limit) - assert.Equal(s.T(), true, changeable) + assert.Equal(s.T(), false, changeable) assert.Nil(s.T(), err) // The actual tests of the functionality is located in the util package duration, changeable, err := s.sut.FailsafeDurationMinimum() assert.Equal(s.T(), time.Duration(0), duration) - assert.Equal(s.T(), false, changeable) + assert.Equal(s.T(), true, changeable) assert.Nil(s.T(), err) err = s.sut.SetFailsafeDurationMinimum(time.Duration(time.Hour*1), true) @@ -103,6 +103,9 @@ func (s *CsLPPSuite) Test_Failsafe() { err = s.sut.SetFailsafeDurationMinimum(time.Duration(time.Hour*2), true) assert.Nil(s.T(), err) + err = s.sut.SetFailsafeProductionActivePowerLimit(10, true) + assert.Nil(s.T(), err) + limit, changeable, err = s.sut.FailsafeProductionActivePowerLimit() assert.Equal(s.T(), 10.0, limit) assert.Equal(s.T(), true, changeable) diff --git a/usecases/cs/lpp/usecase.go b/usecases/cs/lpp/usecase.go index 9d8a6d64..bbdaf02b 100644 --- a/usecases/cs/lpp/usecase.go +++ b/usecases/cs/lpp/usecase.go @@ -8,6 +8,7 @@ import ( "github.com/enbility/eebus-go/features/server" ucapi "github.com/enbility/eebus-go/usecases/api" "github.com/enbility/eebus-go/usecases/usecase" + "github.com/enbility/ship-go/logging" spineapi "github.com/enbility/spine-go/api" "github.com/enbility/spine-go/model" "github.com/enbility/spine-go/spine" @@ -123,11 +124,13 @@ func (e *LPP) approveOrDenyProductionLimit(msg *spineapi.Message, approve bool, func (e *LPP) loadControlWriteCB(msg *spineapi.Message) { if msg.RequestHeader == nil || msg.RequestHeader.MsgCounter == nil || msg.Cmd.LoadControlLimitListData == nil { + logging.Log().Debug("LPC loadControlWriteCB: invalid message") return } _, limitId, err := e.loadControlServerAndLimitId() if err != nil { + logging.Log().Debug("LPC loadControlWriteCB: error getting limit id") return } @@ -223,7 +226,7 @@ func (e *LPP) AddFeatures() { _ = dcs.UpdateKeyValueDataForFilter( model.DeviceConfigurationKeyValueDataType{ Value: value, - IsValueChangeable: util.Ptr(false), + IsValueChangeable: util.Ptr(true), }, nil, model.DeviceConfigurationKeyValueDescriptionDataType{ @@ -237,7 +240,7 @@ func (e *LPP) AddFeatures() { _ = dcs.UpdateKeyValueDataForFilter( model.DeviceConfigurationKeyValueDataType{ Value: value, - IsValueChangeable: util.Ptr(false), + IsValueChangeable: util.Ptr(true), }, nil, model.DeviceConfigurationKeyValueDescriptionDataType{ diff --git a/usecases/eg/lpc/events.go b/usecases/eg/lpc/events.go index 3afbe06f..5d92c4b4 100644 --- a/usecases/eg/lpc/events.go +++ b/usecases/eg/lpc/events.go @@ -43,12 +43,16 @@ func (e *LPC) HandleEvent(payload spineapi.EventPayload) { func (e *LPC) connected(entity spineapi.EntityRemoteInterface) { // initialise features, e.g. subscriptions, descriptions if loadControl, err := client.NewLoadControl(e.LocalEntity, entity); err == nil { - if _, err := loadControl.Subscribe(); err != nil { - logging.Log().Debug(err) + if !loadControl.HasSubscription() { + if _, err := loadControl.Subscribe(); err != nil { + logging.Log().Debug(err) + } } - if _, err := loadControl.Bind(); err != nil { - logging.Log().Debug(err) + if !loadControl.HasBinding() { + if _, err := loadControl.Bind(); err != nil { + logging.Log().Debug(err) + } } // get descriptions @@ -63,12 +67,16 @@ func (e *LPC) connected(entity spineapi.EntityRemoteInterface) { } if deviceConfiguration, err := client.NewDeviceConfiguration(e.LocalEntity, entity); err == nil { - if _, err := deviceConfiguration.Subscribe(); err != nil { - logging.Log().Debug(err) + if !deviceConfiguration.HasSubscription() { + if _, err := deviceConfiguration.Subscribe(); err != nil { + logging.Log().Debug(err) + } } - if _, err := deviceConfiguration.Bind(); err != nil { - logging.Log().Debug(err) + if !deviceConfiguration.HasBinding() { + if _, err := deviceConfiguration.Bind(); err != nil { + logging.Log().Debug(err) + } } // get descriptions @@ -79,8 +87,10 @@ func (e *LPC) connected(entity spineapi.EntityRemoteInterface) { } if deviceDiagnosis, err := client.NewDeviceDiagnosis(e.LocalEntity, entity); err == nil { - if _, err := deviceDiagnosis.Subscribe(); err != nil { - logging.Log().Debug(err) + if !deviceDiagnosis.HasSubscription() { + if _, err := deviceDiagnosis.Subscribe(); err != nil { + logging.Log().Debug(err) + } } if _, err := deviceDiagnosis.RequestHeartbeat(); err != nil { diff --git a/usecases/eg/lpp/events.go b/usecases/eg/lpp/events.go index aff875a8..38798f04 100644 --- a/usecases/eg/lpp/events.go +++ b/usecases/eg/lpp/events.go @@ -44,12 +44,16 @@ func (e *LPP) HandleEvent(payload spineapi.EventPayload) { func (e *LPP) connected(entity spineapi.EntityRemoteInterface) { // initialise features, e.g. subscriptions, descriptions if loadControl, err := client.NewLoadControl(e.LocalEntity, entity); err == nil { - if _, err := loadControl.Subscribe(); err != nil { - logging.Log().Debug(err) + if !loadControl.HasSubscription() { + if _, err := loadControl.Subscribe(); err != nil { + logging.Log().Debug(err) + } } - if _, err := loadControl.Bind(); err != nil { - logging.Log().Debug(err) + if !loadControl.HasBinding() { + if _, err := loadControl.Bind(); err != nil { + logging.Log().Debug(err) + } } // get descriptions @@ -64,12 +68,16 @@ func (e *LPP) connected(entity spineapi.EntityRemoteInterface) { } if deviceConfiguration, err := client.NewDeviceConfiguration(e.LocalEntity, entity); err == nil { - if _, err := deviceConfiguration.Subscribe(); err != nil { - logging.Log().Debug(err) + if !deviceConfiguration.HasSubscription() { + if _, err := deviceConfiguration.Subscribe(); err != nil { + logging.Log().Debug(err) + } } - if _, err := deviceConfiguration.Bind(); err != nil { - logging.Log().Debug(err) + if !deviceConfiguration.HasBinding() { + if _, err := deviceConfiguration.Bind(); err != nil { + logging.Log().Debug(err) + } } // get descriptions @@ -80,8 +88,10 @@ func (e *LPP) connected(entity spineapi.EntityRemoteInterface) { } if deviceDiagnosis, err := client.NewDeviceDiagnosis(e.LocalEntity, entity); err == nil { - if _, err := deviceDiagnosis.Subscribe(); err != nil { - logging.Log().Debug(err) + if !deviceDiagnosis.HasSubscription() { + if _, err := deviceDiagnosis.Subscribe(); err != nil { + logging.Log().Debug(err) + } } if _, err := deviceDiagnosis.RequestHeartbeat(); err != nil { diff --git a/usecases/ma/mgcp/events.go b/usecases/ma/mgcp/events.go index abcf61c3..38a2f81c 100644 --- a/usecases/ma/mgcp/events.go +++ b/usecases/ma/mgcp/events.go @@ -45,8 +45,10 @@ func (e *MGCP) HandleEvent(payload spineapi.EventPayload) { // process required steps when a grid device is connected func (e *MGCP) gridConnected(entity spineapi.EntityRemoteInterface) { if deviceConfiguration, err := client.NewDeviceConfiguration(e.LocalEntity, entity); err == nil { - if _, err := deviceConfiguration.Subscribe(); err != nil { - logging.Log().Error(err) + if !deviceConfiguration.HasSubscription() { + if _, err := deviceConfiguration.Subscribe(); err != nil { + logging.Log().Error(err) + } } // get configuration data @@ -56,8 +58,10 @@ func (e *MGCP) gridConnected(entity spineapi.EntityRemoteInterface) { } if electricalConnection, err := client.NewElectricalConnection(e.LocalEntity, entity); err == nil { - if _, err := electricalConnection.Subscribe(); err != nil { - logging.Log().Error(err) + if !electricalConnection.HasSubscription() { + if _, err := electricalConnection.Subscribe(); err != nil { + logging.Log().Error(err) + } } // get electrical connection parameter @@ -71,8 +75,10 @@ func (e *MGCP) gridConnected(entity spineapi.EntityRemoteInterface) { } if measurement, err := client.NewMeasurement(e.LocalEntity, entity); err == nil { - if _, err := measurement.Subscribe(); err != nil { - logging.Log().Error(err) + if !measurement.HasSubscription() { + if _, err := measurement.Subscribe(); err != nil { + logging.Log().Error(err) + } } // get measurement parameters diff --git a/usecases/ma/mpc/events.go b/usecases/ma/mpc/events.go index 2cf93386..ae13b5b9 100644 --- a/usecases/ma/mpc/events.go +++ b/usecases/ma/mpc/events.go @@ -39,8 +39,10 @@ func (e *MPC) HandleEvent(payload spineapi.EventPayload) { // process required steps when a device is connected func (e *MPC) deviceConnected(entity spineapi.EntityRemoteInterface) { if electricalConnection, err := client.NewElectricalConnection(e.LocalEntity, entity); err == nil { - if _, err := electricalConnection.Subscribe(); err != nil { - logging.Log().Error(err) + if !electricalConnection.HasSubscription() { + if _, err := electricalConnection.Subscribe(); err != nil { + logging.Log().Error(err) + } } // get electrical connection parameter @@ -54,8 +56,10 @@ func (e *MPC) deviceConnected(entity spineapi.EntityRemoteInterface) { } if measurement, err := client.NewMeasurement(e.LocalEntity, entity); err == nil { - if _, err := measurement.Subscribe(); err != nil { - logging.Log().Error(err) + if !measurement.HasSubscription() { + if _, err := measurement.Subscribe(); err != nil { + logging.Log().Error(err) + } } // get measurement parameters