diff --git a/features/deviceclassification.go b/features/deviceclassification.go index 16e6544b..04143352 100644 --- a/features/deviceclassification.go +++ b/features/deviceclassification.go @@ -62,6 +62,10 @@ func (d *DeviceClassification) GetManufacturerDetails() (*ManufacturerType, erro } data := rData.(*model.DeviceClassificationManufacturerDataType) + if data == nil { + return nil, ErrDataNotAvailable + } + details := &ManufacturerType{} if data.BrandName != nil { diff --git a/features/deviceconfiguration.go b/features/deviceconfiguration.go index 26d79345..28619cde 100644 --- a/features/deviceconfiguration.go +++ b/features/deviceconfiguration.go @@ -74,6 +74,9 @@ func (d *DeviceConfiguration) GetDescriptionKeyNameSupport(keyName model.DeviceC } data := rData.(*model.DeviceConfigurationKeyValueDescriptionListDataType) + if data == nil { + return false, ErrDataNotAvailable + } for _, item := range data.DeviceConfigurationKeyValueDescriptionData { if item.KeyId == nil || item.KeyName == nil { @@ -104,6 +107,9 @@ func (d *DeviceConfiguration) GetEVCommunicationStandard() (*string, error) { } data := rData.(*model.DeviceConfigurationKeyValueListDataType) + if data == nil { + return nil, ErrDataNotAvailable + } for _, item := range data.DeviceConfigurationKeyValueData { if item.KeyId == nil || item.Value == nil { @@ -138,6 +144,9 @@ func (d *DeviceConfiguration) GetValues() ([]DeviceConfigurationType, error) { return nil, ErrMetadataNotAvailable } descData := rDescData.(*model.DeviceConfigurationKeyValueDescriptionListDataType) + if descData == nil { + return nil, ErrDataNotAvailable + } ref := make(map[model.DeviceConfigurationKeyIdType]model.DeviceConfigurationKeyValueDescriptionDataType) for _, item := range descData.DeviceConfigurationKeyValueDescriptionData { @@ -153,6 +162,10 @@ func (d *DeviceConfiguration) GetValues() ([]DeviceConfigurationType, error) { } data := rData.(*model.DeviceConfigurationKeyValueListDataType) + if data == nil { + return nil, ErrDataNotAvailable + } + var resultSet []DeviceConfigurationType for _, item := range data.DeviceConfigurationKeyValueData { @@ -229,10 +242,16 @@ func (d *DeviceConfiguration) deviceConfigurationKeyValueDescriptionListData() ( return nil, ErrDataNotAvailable } - data := d.featureRemote.Data(model.FunctionTypeDeviceConfigurationKeyValueDescriptionListData).(*model.DeviceConfigurationKeyValueDescriptionListDataType) + rData := d.featureRemote.Data(model.FunctionTypeDeviceConfigurationKeyValueDescriptionListData) + if rData == nil { + return nil, ErrMetadataNotAvailable + } + + data := rData.(*model.DeviceConfigurationKeyValueDescriptionListDataType) if data == nil { return nil, ErrMetadataNotAvailable } + ref := make(deviceConfigurationKeyValueDescriptionMap) for _, item := range data.DeviceConfigurationKeyValueDescriptionData { if item.KeyId == nil { diff --git a/features/devicediagnosis.go b/features/devicediagnosis.go index 97735e3f..928a219a 100644 --- a/features/devicediagnosis.go +++ b/features/devicediagnosis.go @@ -52,6 +52,9 @@ func (d *DeviceDiagnosis) GetState() (*DeviceDiagnosisType, error) { } data := rData.(*model.DeviceDiagnosisStateDataType) + if data == nil { + return nil, ErrDataNotAvailable + } details := &DeviceDiagnosisType{} if data.OperatingState != nil { diff --git a/features/devicediagnosis_test.go b/features/devicediagnosis_test.go new file mode 100644 index 00000000..a014fce7 --- /dev/null +++ b/features/devicediagnosis_test.go @@ -0,0 +1,81 @@ +package features + +import ( + "testing" + + "github.com/enbility/eebus-go/spine" + "github.com/enbility/eebus-go/spine/model" + "github.com/enbility/eebus-go/util" + "github.com/stretchr/testify/assert" +) + +func TestDeviceDiagnosis_GetState(t *testing.T) { + localDevice := spine.NewDeviceLocalImpl("TestBrandName", "TestDeviceModel", "TestSerialNumber", "TestDeviceCode", + "TestDeviceAddress", model.DeviceTypeTypeEnergyManagementSystem, model.NetworkManagementFeatureSetTypeSmart) + localEntity := spine.NewEntityLocalImpl(localDevice, model.EntityTypeTypeCEM, spine.NewAddressEntityType([]uint{1})) + localDevice.AddEntity(localEntity) + + f := spine.NewFeatureLocalImpl(1, localEntity, model.FeatureTypeTypeDeviceDiagnosis, model.RoleTypeServer) + localEntity.AddFeature(f) + + remoteDeviceName := "remoteDevice" + remoteDevice := spine.NewDeviceRemoteImpl(localDevice, "test", nil) + data := &model.NodeManagementDetailedDiscoveryDataType{ + DeviceInformation: &model.NodeManagementDetailedDiscoveryDeviceInformationType{ + Description: &model.NetworkManagementDeviceDescriptionDataType{ + DeviceAddress: &model.DeviceAddressType{ + Device: util.Ptr(model.AddressDeviceType(remoteDeviceName)), + }, + }, + }, + EntityInformation: []model.NodeManagementDetailedDiscoveryEntityInformationType{ + { + Description: &model.NetworkManagementEntityDescriptionDataType{ + EntityAddress: &model.EntityAddressType{ + Device: util.Ptr(model.AddressDeviceType(remoteDeviceName)), + Entity: []model.AddressEntityType{1}, + }, + EntityType: util.Ptr(model.EntityTypeTypeEVSE), + }, + }, + }, + FeatureInformation: []model.NodeManagementDetailedDiscoveryFeatureInformationType{ + { + Description: &model.NetworkManagementFeatureDescriptionDataType{ + FeatureAddress: &model.FeatureAddressType{ + Device: util.Ptr(model.AddressDeviceType(remoteDeviceName)), + Entity: []model.AddressEntityType{1}, + Feature: util.Ptr(model.AddressFeatureType(1)), + }, + FeatureType: util.Ptr(model.FeatureTypeTypeDeviceDiagnosis), + Role: util.Ptr(model.RoleTypeClient), + }, + }, + }, + } + remoteEntities, err := remoteDevice.AddEntityAndFeatures(true, data) + assert.Nil(t, err) + assert.NotNil(t, remoteEntities) + assert.NotEqual(t, 0, len(remoteEntities)) + + remoteEntity := remoteEntities[0] + + d, err := NewDeviceDiagnosis(model.RoleTypeServer, model.RoleTypeClient, localDevice, remoteEntity) + assert.Nil(t, err) + assert.NotNil(t, d) + + result, err := d.GetState() + assert.NotNil(t, err) + assert.Nil(t, result) + + rF := remoteEntity.Feature(util.Ptr(model.AddressFeatureType(1))) + fData := &model.DeviceDiagnosisStateDataType{ + OperatingState: util.Ptr(model.DeviceDiagnosisOperatingStateTypeNormalOperation), + } + rF.UpdateData(model.FunctionTypeDeviceDiagnosisStateData, fData, nil, nil) + + result, err = d.GetState() + assert.Nil(t, err) + assert.NotNil(t, result) + +} diff --git a/features/electricalconnection.go b/features/electricalconnection.go index c9b41a4b..eb8cefee 100644 --- a/features/electricalconnection.go +++ b/features/electricalconnection.go @@ -87,6 +87,9 @@ func (e *ElectricalConnection) GetParamDescriptionListData() (electricalParamDes return nil, nil, ErrDataNotAvailable } data := rData.(*model.ElectricalConnectionParameterDescriptionListDataType) + if data == nil { + return nil, nil, ErrDataNotAvailable + } refMeasurement := make(electricalParamDescriptionMapMeasurementId) refElectrical := make(electricatlParamDescriptionMapParamId) @@ -112,6 +115,9 @@ func (e *ElectricalConnection) GetDescription() ([]ElectricalDescriptionType, er return nil, ErrMetadataNotAvailable } data := rData.(*model.ElectricalConnectionDescriptionListDataType) + if data == nil { + return nil, ErrMetadataNotAvailable + } var resultSet []ElectricalDescriptionType @@ -148,7 +154,11 @@ func (e *ElectricalConnection) GetConnectedPhases() (uint, error) { if rData == nil { return 0, ErrDataNotAvailable } + data := rData.(*model.ElectricalConnectionDescriptionListDataType) + if data == nil { + return 0, ErrDataNotAvailable + } for _, item := range data.ElectricalConnectionDescriptionData { if item.ElectricalConnectionId == nil { @@ -182,7 +192,11 @@ func (e *ElectricalConnection) GetCurrentsLimits() (map[string]float64, map[stri if rData == nil { return nil, nil, nil, ErrDataNotAvailable } + data := rData.(*model.ElectricalConnectionPermittedValueSetListDataType) + if data == nil { + return nil, nil, nil, ErrDataNotAvailable + } resultSetMin := make(map[string]float64) resultSetMax := make(map[string]float64) @@ -237,7 +251,12 @@ func (e *ElectricalConnection) GetEVLimitValues() ([]ElectricalLimitType, error) if rData == nil { return nil, ErrMetadataNotAvailable } + paramDescriptionData := rData.(*model.ElectricalConnectionParameterDescriptionListDataType) + if paramDescriptionData == nil { + return nil, ErrMetadataNotAvailable + } + paramRef := make(map[model.ElectricalConnectionParameterIdType]model.ElectricalConnectionParameterDescriptionDataType) for _, item := range paramDescriptionData.ElectricalConnectionParameterDescriptionData { if item.ParameterId == nil { @@ -250,7 +269,11 @@ func (e *ElectricalConnection) GetEVLimitValues() ([]ElectricalLimitType, error) if rData2 == nil { return nil, ErrDataNotAvailable } + data := rData2.(*model.ElectricalConnectionPermittedValueSetListDataType) + if data == nil { + return nil, ErrDataNotAvailable + } var resultSet []ElectricalLimitType diff --git a/features/identification.go b/features/identification.go index 025d88ae..08b6aca3 100644 --- a/features/identification.go +++ b/features/identification.go @@ -51,6 +51,10 @@ func (i *Identification) GetValues() ([]IdentificationType, error) { } data := rData.(*model.IdentificationListDataType) + if data == nil { + return nil, ErrDataNotAvailable + } + var resultSet []IdentificationType for _, item := range data.IdentificationData { diff --git a/features/loadcontrol.go b/features/loadcontrol.go index 476cd791..c981e2e8 100644 --- a/features/loadcontrol.go +++ b/features/loadcontrol.go @@ -78,7 +78,11 @@ func (l *LoadControl) GetLimitDescription() (loadControlLimitDescriptionMap, err if rData == nil { return nil, ErrMetadataNotAvailable } + data := rData.(*model.LoadControlLimitDescriptionListDataType) + if data == nil { + return nil, ErrDataNotAvailable + } ref := make(loadControlLimitDescriptionMap) for _, item := range data.LoadControlLimitDescriptionData { @@ -145,6 +149,9 @@ func (l *LoadControl) GetLimitValues() ([]LoadControlLimitType, error) { } descriptionData := rData.(*model.LoadControlLimitDescriptionListDataType) + if descriptionData == nil { + return nil, ErrMetadataNotAvailable + } descRef := make(map[model.LoadControlLimitIdType]model.LoadControlLimitDescriptionDataType) for _, item := range descriptionData.LoadControlLimitDescriptionData { diff --git a/features/measurement.go b/features/measurement.go index 47fe5930..1741fa15 100644 --- a/features/measurement.go +++ b/features/measurement.go @@ -82,7 +82,11 @@ func (m *Measurement) GetValueForScope(scope model.ScopeTypeType, electricalConn if rData == nil { return 0, ErrDataNotAvailable } + data := rData.(*model.MeasurementListDataType) + if data == nil { + return 0, ErrDataNotAvailable + } var result float64 for _, item := range data.MeasurementData { @@ -131,7 +135,11 @@ func (m *Measurement) GetValuesPerPhaseForScope(scope model.ScopeTypeType, elect if rData == nil { return nil, ErrDataNotAvailable } + data := rData.(*model.MeasurementListDataType) + if data == nil { + return nil, ErrDataNotAvailable + } resultSet := make(map[string]float64) for _, item := range data.MeasurementData { @@ -174,7 +182,11 @@ func (m *Measurement) GetDescription() (measurementDescriptionMap, error) { if rData == nil { return nil, ErrMetadataNotAvailable } + data := rData.(*model.MeasurementDescriptionListDataType) + if data == nil { + return nil, ErrMetadataNotAvailable + } ref := make(measurementDescriptionMap) for _, item := range data.MeasurementDescriptionData { @@ -230,7 +242,11 @@ func (m *Measurement) GetSoC() (float64, error) { if rData == nil { return 0, ErrDataNotAvailable } + data := rData.(*model.MeasurementListDataType) + if data == nil { + return 0, ErrDataNotAvailable + } for _, item := range data.MeasurementData { if item.MeasurementId == nil || item.Value == nil { @@ -266,7 +282,11 @@ func (m *Measurement) GetConstraints() (measurementConstraintMap, error) { if rData == nil { return nil, ErrMetadataNotAvailable } + data := rData.(*model.MeasurementConstraintsListDataType) + if data == nil { + return nil, ErrDataNotAvailable + } ref := make(measurementConstraintMap) for _, item := range data.MeasurementConstraintsData { @@ -296,7 +316,11 @@ func (m *Measurement) GetValues() ([]MeasurementType, error) { if rData == nil { return nil, ErrDataNotAvailable } + data := rData.(*model.MeasurementListDataType) + if data == nil { + return nil, ErrDataNotAvailable + } var resultSet []MeasurementType for _, item := range data.MeasurementData { diff --git a/features/timeseries.go b/features/timeseries.go index 1f67ada6..2bf6fdfc 100644 --- a/features/timeseries.go +++ b/features/timeseries.go @@ -110,6 +110,10 @@ func (t *TimeSeries) GetValues() ([]TimeSeriesType, error) { } data := rData.(*model.TimeSeriesListDataType) + if data == nil { + return nil, ErrDataNotAvailable + } + var resultSet []TimeSeriesType for _, item := range data.TimeSeriesData { @@ -188,6 +192,10 @@ func (t *TimeSeries) GetDescriptionValues() ([]TimeSeriesDescriptionType, error) } data := rData.(*model.TimeSeriesDescriptionListDataType) + if data == nil { + return nil, ErrDataNotAvailable + } + var resultSet []TimeSeriesDescriptionType for _, item := range data.TimeSeriesDescriptionData { @@ -236,6 +244,10 @@ func (t *TimeSeries) GetConstraintValues() ([]TimeSeriesConstraintsType, error) } data := rData.(*model.TimeSeriesConstraintsListDataType) + if data == nil { + return nil, ErrDataNotAvailable + } + var resultSet []TimeSeriesConstraintsType for _, item := range data.TimeSeriesConstraintsData { diff --git a/service/hub.go b/service/hub.go index ae5e39b3..359c3e20 100644 --- a/service/hub.go +++ b/service/hub.go @@ -358,7 +358,7 @@ func (h *connectionsHub) connectFoundService(remoteService *ServiceDetails, host return nil } - logging.Log.Debugf("initiating connection to %s at %s:%s", remoteService.SKI, host, port) + logging.Log.Debugf("initiating connection to %s at %s:%s", remoteService.SKI(), host, port) dialer := &websocket.Dialer{ Proxy: http.ProxyFromEnvironment, @@ -596,14 +596,14 @@ func (h *connectionsHub) coordinateConnectionInitations(ski string, entry MdnsEn func (h *connectionsHub) initateConnection(remoteService *ServiceDetails, entry MdnsEntry) bool { var err error - logging.Log.Debug("trying to connect to", remoteService.SKI, "at", entry.Host) + logging.Log.Debug("trying to connect to", remoteService.SKI(), "at", entry.Host) if err = h.connectFoundService(remoteService, entry.Host, strconv.Itoa(entry.Port)); err != nil { - logging.Log.Debugf("connection to %s failed: %s", remoteService.SKI, err) + logging.Log.Debugf("connection to %s failed: %s", remoteService.SKI(), err) // connecting via the host failed, so try all of the provided addresses for _, address := range entry.Addresses { - logging.Log.Debug("trying to connect to", remoteService.SKI, "at", address) + logging.Log.Debug("trying to connect to", remoteService.SKI(), "at", address) if err = h.connectFoundService(remoteService, address.String(), strconv.Itoa(entry.Port)); err != nil { - logging.Log.Debug("connection to", remoteService.SKI, "failed: ", err) + logging.Log.Debug("connection to", remoteService.SKI(), "failed: ", err) } else { break }