Skip to content

Commit

Permalink
Refactor features (#80)
Browse files Browse the repository at this point in the history
- Add local server features API at features/server
- Move previous features API to features/client
- Add interfaces and mocks for all features
- Aligned function names
  • Loading branch information
DerAndereAndi authored May 28, 2024
2 parents c205430 + 1db0856 commit 0cc2064
Show file tree
Hide file tree
Showing 112 changed files with 14,602 additions and 2,963 deletions.
1 change: 0 additions & 1 deletion .mockery.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,3 @@ filename: "{{.InterfaceName}}.go"
all: True
packages:
github.com/enbility/eebus-go/api:
github.com/enbility/eebus-go/features:
2 changes: 2 additions & 0 deletions api/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ var ErrFunctionNotSupported = errors.New("function is not supported")
var ErrOperationOnFunctionNotSupported = errors.New("operation is not supported on function")

var ErrMissingData = errors.New("missing data")

var ErrDeviceDisconnected = errors.New("device is disconnected")
244 changes: 244 additions & 0 deletions api/features.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
package api

import (
"time"

"github.com/enbility/spine-go/api"
"github.com/enbility/spine-go/model"
)

// Feature client interface were the local feature role is client and the remote feature role is server
type FeatureClientInterface interface {
// check if there is a subscription to the remote feature
HasSubscription() bool

// subscribe to the feature of the entity
Subscribe() (*model.MsgCounterType, error)

// check if there is a binding to the remote feature
HasBinding() bool

// bind to the feature of the entity
Bind() (*model.MsgCounterType, error)

// add a callback function to be invoked once a result or reply message for a msgCounter came in
AddResponseCallback(msgCounterReference model.MsgCounterType, function func(msg api.ResponseMessage)) error

// add a callback function to be invoked once a result came in
AddResultCallback(function func(msg api.ResponseMessage))
}

// Feature server interface were the local feature role is a server
type FeatureServerInterface interface {
}

// Common interface for DeviceClassificationClientInterface and DeviceClassificationServerInterface
type DeviceClassificationCommonInterface interface {
// get the current manufacturer details for a remote device entity
GetManufacturerDetails() (*model.DeviceClassificationManufacturerDataType, error)
}

// Common interface for DeviceConfigurationClientInterface and DeviceConfigurationServerInterface
type DeviceConfigurationCommonInterface interface {
// check if spine.EventPayload Data contains data for a given filter
//
// data type will be checked for model.DeviceConfigurationKeyValueListDataType,
// filter type will be checked for model.DeviceConfigurationKeyValueDescriptionDataType
CheckEventPayloadDataForFilter(payloadData any, filter any) bool

// Get the description for a given keyId
//
// Will return nil if no matching description was found
GetKeyValueDescriptionFoKeyId(keyId model.DeviceConfigurationKeyIdType) (*model.DeviceConfigurationKeyValueDescriptionDataType, error)

// Get the description for a given value combination
//
// Returns an error if no matching description was found
GetKeyValueDescriptionsForFilter(filter model.DeviceConfigurationKeyValueDescriptionDataType) ([]model.DeviceConfigurationKeyValueDescriptionDataType, error)

// Get the key value data for a given keyId
//
// Will return nil if no matching data was found
GetKeyValueDataForKeyId(keyId model.DeviceConfigurationKeyIdType) (*model.DeviceConfigurationKeyValueDataType, error)

// Get key value data for a given filter
//
// Will return nil if no matching data was found
GetKeyValueDataForFilter(filter model.DeviceConfigurationKeyValueDescriptionDataType) (*model.DeviceConfigurationKeyValueDataType, error)
}

// Common interface for DeviceDiagnosisClientInterface and DeviceDiagnosisServerInterface
type DeviceDiagnosisCommonInterface interface {
// get the current diagnosis state for an device entity
GetState() (*model.DeviceDiagnosisStateDataType, error)

// check if the currently available heartbeat data is within a time duration
IsHeartbeatWithinDuration(duration time.Duration) bool
}

// Common interface for ElectricalConnectionClientInterface and ElectricalConnectionServerInterface
type ElectricalConnectionCommonInterface interface {
// check if spine.EventPayload Data contains data for a given filter
//
// data type will be checked for model.ElectricalConnectionPermittedValueSetListDataType,
// filter type will be checked for model.ElectricalConnectionParameterDescriptionDataType
CheckEventPayloadDataForFilter(payloadData any, filter any) bool

// Get the description for a given filter
//
// Returns an error if no matching description is found
GetDescriptionsForFilter(
filter model.ElectricalConnectionDescriptionDataType,
) ([]model.ElectricalConnectionDescriptionDataType, error)

// Get the description for a given parameter description
//
// Returns an error if no matching description is found
GetDescriptionForParameterDescriptionFilter(
filter model.ElectricalConnectionParameterDescriptionDataType) (
*model.ElectricalConnectionDescriptionDataType, error)

// Get the description for a given filter
//
// Returns an error if no matching description is found
GetParameterDescriptionsForFilter(
filter model.ElectricalConnectionParameterDescriptionDataType,
) ([]model.ElectricalConnectionParameterDescriptionDataType, error)

// return permitted values for all Electrical Connections
GetPermittedValueSetForFilter(filter model.ElectricalConnectionPermittedValueSetDataType) (
[]model.ElectricalConnectionPermittedValueSetDataType, error)

// returns minimum, maximum, default/pause limit values
GetPermittedValueDataForFilter(filter model.ElectricalConnectionPermittedValueSetDataType) (
float64, float64, float64, error)

// Get the min, max, default current limits for each phase
GetPhaseCurrentLimits() (
resultMin []float64, resultMax []float64, resultDefault []float64, resultErr error)

// Adjust a value to be within the permitted value range
AdjustValueToBeWithinPermittedValuesForParameterId(
value float64, parameterId model.ElectricalConnectionParameterIdType) float64

// Get the characteristics for a given filter
//
// Returns an error if no matching description is found
GetCharacteristicsForFilter(
filter model.ElectricalConnectionCharacteristicDataType,
) ([]model.ElectricalConnectionCharacteristicDataType, error)
}

// Common interface for LoadControlClientInterface and LoadControlServerInterface
type LoadControlCommonInterface interface {
// check if spine.EventPayload Data contains data for a given filter
//
// data type will be checked for model.LoadControlLimitListDataType,
// filter type will be checked for model.LoadControlLimitDescriptionDataType
CheckEventPayloadDataForFilter(payloadData any, filter any) bool

// Get the description for a given limitId
//
// Will return nil if no matching description is found
GetLimitDescriptionForId(limitId model.LoadControlLimitIdType) (
*model.LoadControlLimitDescriptionDataType, error)

// Get the description for a given filter
//
// Returns an error if no matching description is found
GetLimitDescriptionsForFilter(
filter model.LoadControlLimitDescriptionDataType,
) ([]model.LoadControlLimitDescriptionDataType, error)

// Get the description for a given limitId
//
// Will return nil if no data is available
GetLimitDataForId(limitId model.LoadControlLimitIdType) (*model.LoadControlLimitDataType, error)

// Get limit data for a given filter
//
// Will return nil if no data is available
GetLimitDataForFilter(filter model.LoadControlLimitDescriptionDataType) ([]model.LoadControlLimitDataType, error)
}

// Common interface for MeasurementClientInterface and MeasurementServerInterface
type MeasurementCommonInterface interface {
// check if spine.EventPayload Data contains data for a given filter
//
// data type will be checked for model.MeasurementListDataType,
// filter type will be checked for model.MeasurementDescriptionDataType
CheckEventPayloadDataForFilter(payloadData any, filter any) bool

// Get the description for a given id
//
// Returns an error if no matching description is found
GetDescriptionForId(
measurementId model.MeasurementIdType,
) (*model.MeasurementDescriptionDataType, error)

// Get the description for a given filter
//
// Returns an error if no matching description is found
GetDescriptionsForFilter(
filter model.MeasurementDescriptionDataType,
) ([]model.MeasurementDescriptionDataType, error)

// Get the constraints for a given filter
//
// Returns an error if no matching constraint is found
GetConstraintsForFilter(
filter model.MeasurementConstraintsDataType,
) ([]model.MeasurementConstraintsDataType, error)

// Get the measuement data for a given measurementId
//
// Will return nil if no data is available
GetDataForId(measurementId model.MeasurementIdType) (*model.MeasurementDataType, error)

// Get measuement data for a given filter
//
// Will return nil if no data is available
GetDataForFilter(filter model.MeasurementDescriptionDataType) (
[]model.MeasurementDataType, error)
}

// Common interface for IdentificationClientInterface and IdentificationServerInterface
type IdentificationCommonInterface interface {
// check if spine.EventPayload Data contains identification data
//
// data type will be checked for model.IdentificationListDataType
CheckEventPayloadDataForFilter(payloadData any) bool

// return current values for Identification
GetDataForFilter(filter model.IdentificationDataType) ([]model.IdentificationDataType, error)
}

// Common interface for IncentiveTableClientInterface and IncentiveTableServerInterface
type IncentiveTableCommonInterface interface {
// return list of descriptions for a given filter
GetDescriptionsForFilter(filter model.TariffDescriptionDataType) ([]model.IncentiveTableDescriptionType, error)

// return list of constraints
GetConstraints() ([]model.IncentiveTableConstraintsType, error)

// return current data for Time Series
GetData() ([]model.IncentiveTableType, error)
}

// Common interface for SmartEnergyManagementPsClientInterface and SmartEnergyManagementPsServerInterface
type SmartEnergyManagementPsCommonInterface interface {
// return current data for FunctionTypeSmartEnergyManagementPsData
GetData() (*model.SmartEnergyManagementPsDataType, error)
}

// Common interface for TimeSeriesClientInterface and TimeSeriesServerInterface
type TimeSeriesCommonInterface interface {
// return list of descriptions for a given filter
GetDescriptionsForFilter(filter model.TimeSeriesDescriptionDataType) ([]model.TimeSeriesDescriptionDataType, error)

// return current constraints for Time Series
GetConstraints() ([]model.TimeSeriesConstraintsDataType, error)

// return current data for Time Series for a given filter
GetDataForFilter(filter model.TimeSeriesDescriptionDataType) ([]model.TimeSeriesDataType, error)
}
118 changes: 118 additions & 0 deletions api/featuresclient.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package api

import "github.com/enbility/spine-go/model"

type DeviceClassificationClientInterface interface {
// request DeviceClassificationManufacturerData from a remote device entity
RequestManufacturerDetails() (*model.MsgCounterType, error)
}

type DeviceConfigurationClientInterface interface {
DeviceConfigurationCommonInterface

// request DeviceConfigurationDescriptionListData from a remote entity
RequestDescriptions() (*model.MsgCounterType, error)

// request DeviceConfigurationKeyValueListData from a remote entity
RequestKeyValues() (*model.MsgCounterType, error)

// write key values
// returns an error if this failed
WriteKeyValues(data []model.DeviceConfigurationKeyValueDataType) (*model.MsgCounterType, error)
}

type DeviceDiagnosisClientInterface interface {
// request DeviceDiagnosisStateData from a remote entity
RequestState() (*model.MsgCounterType, error)

// request FunctionTypeDeviceDiagnosisHeartbeatData from a remote device
RequestHeartbeat() (*model.MsgCounterType, error)
}

type ElectricalConnectionClientInterface interface {
// request ElectricalConnectionDescriptionListDataType from a remote entity
RequestDescriptions() (*model.MsgCounterType, error)

// request FunctionTypeElectricalConnectionParameterDescriptionListData from a remote entity
RequestParameterDescriptions() (*model.MsgCounterType, error)

// request FunctionTypeElectricalConnectionPermittedValueSetListData from a remote entity
RequestPermittedValueSets() (*model.MsgCounterType, error)

// request FunctionTypeElectricalConnectionCharacteristicListData from a remote entity
RequestCharacteristics() (*model.MsgCounterType, error)
}

type IdentificationClientInterface interface {
// request FunctionTypeIdentificationListData from a remote entity
RequestValues() (*model.MsgCounterType, error)
}

type IncentiveTableClientInterface interface {
// request FunctionTypeIncentiveTableDescriptionData from a remote entity
RequestDescriptions() (*model.MsgCounterType, error)

// request FunctionTypeIncentiveTableConstraintsData from a remote entity
RequestConstraints() (*model.MsgCounterType, error)

// request FunctionTypeIncentiveTableData from a remote entity
RequestValues() (*model.MsgCounterType, error)

// write incentivetable descriptions
// returns an error if this failed
WriteDescriptions(data []model.IncentiveTableDescriptionType) (*model.MsgCounterType, error)

// write incentivetable descriptions
// returns an error if this failed
WriteValues(data []model.IncentiveTableType) (*model.MsgCounterType, error)
}

type LoadControlClientInterface interface {
// request FunctionTypeLoadControlLimitDescriptionListData from a remote device
RequestLimitDescriptions() (*model.MsgCounterType, error)

// request FunctionTypeLoadControlLimitConstraintsListData from a remote device
RequestLimitConstraints() (*model.MsgCounterType, error)

// request FunctionTypeLoadControlLimitListData from a remote device
RequestLimitData() (*model.MsgCounterType, error)

// write load control limits
// returns an error if this failed
WriteLimitData(data []model.LoadControlLimitDataType) (*model.MsgCounterType, error)
}

type MeasurementClientInterface interface {
// request FunctionTypeMeasurementDescriptionListData from a remote device
RequestDescriptions() (*model.MsgCounterType, error)

// request FunctionTypeMeasurementConstraintsListData from a remote entity
RequestConstraints() (*model.MsgCounterType, error)

// request FunctionTypeMeasurementListData from a remote entity
RequestData() (*model.MsgCounterType, error)
}

type SmartEnergyManagementPsClientInterface interface {
// request FunctionTypeSmartEnergyManagementPsData from a remote entity
RequestData() (*model.MsgCounterType, error)

// write SmartEnergyManagementPsData
// returns an error if this failed
WriteData(data *model.SmartEnergyManagementPsDataType) (*model.MsgCounterType, error)
}

type TimeSeriesClientInterface interface {
// request FunctionTypeTimeSeriesDescriptionListData from a remote entity
RequestDescriptions() (*model.MsgCounterType, error)

// request FunctionTypeTimeSeriesConstraintsListData from a remote entity
RequestConstraints() (*model.MsgCounterType, error)

// request FunctionTypeTimeSeriesListData from a remote device
RequestData() (*model.MsgCounterType, error)

// write Time Series values
// returns an error if this failed
WriteData(data []model.TimeSeriesDataType) (*model.MsgCounterType, error)
}
Loading

0 comments on commit 0cc2064

Please sign in to comment.