Skip to content

Commit

Permalink
Merge branch 'dev' into feature/update-multiple-datapoints
Browse files Browse the repository at this point in the history
# Conflicts:
#	usecases/cs/lpc/usecase_test.go
  • Loading branch information
DerAndereAndi committed Oct 15, 2024
2 parents f0551e2 + 2a6167e commit 14255b5
Show file tree
Hide file tree
Showing 77 changed files with 1,475 additions and 90 deletions.
4 changes: 4 additions & 0 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ type ServiceInterface interface {
// Returns if the service has auto accept enabled or not
IsAutoAcceptEnabled() bool

// Returns the QR code text for the service
// as defined in SHIP Requirements for Installation Process V1.0.0
QRCodeText() string

// Returns the Service detail of a remote SKI
RemoteServiceForSKI(ski string) *shipapi.ServiceDetails

Expand Down
79 changes: 72 additions & 7 deletions api/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"time"

shipapi "github.com/enbility/ship-go/api"
"github.com/enbility/ship-go/mdns"
"github.com/enbility/spine-go/model"
)
Expand All @@ -14,47 +15,69 @@ const defaultPort int = 4711
// defines requires meta information about this service
type Configuration struct {
// The vendors IANA PEN, optional but highly recommended.
//
// If not set, brand will be used instead
//
// Used for the Device Address: SPINE - Protocol Specification 7.1.1.2
vendorCode string

// The deviceBrand of the device, required
// The deviceBrand of the device, required (may not be longer than 32 UTF8 characters)
//
// Used for the Device Address: SPINE - Protocol Specification 7.1.1.2
//
// Used for mDNS txt record: SHIP - Specification 7.3.2
deviceBrand string

// The device model, required
// The device model, required (may not be longer than 32 UTF8 characters)
//
// Used for the Device Address: SPINE - Protocol Specification 7.1.1.2
//
// Used for mDNS txt record: SHIP - Specification 7.3.2
deviceModel string

// Serial number of the device, required
// Serial number of the device, required (may not be longer than 32 UTF8 characters)
//
// Used for the Device Address: SPINE - Protocol Specification 7.1.1.2
//
// Used for mDNS txt record: SHIP - Requirements for Installation Process V1.0.0
deviceSerialNumber string

// Device categories of the device model, required
//
// Used for mDNS txt record: SHIP - Requirements for Installation Process V1.0.0
deviceCategories []shipapi.DeviceCategoryType

// An alternate mDNS service identifier
//
// Optional, if not set will be generated using "Brand-Model-SerialNumber"
//
// Used for mDNS service and SHIP identifier: SHIP - Specification 7.2
alternateIdentifier string

// An alternate mDNS service name
//
// Optional, if not set will be identical to alternateIdentifier or generated using "Brand-Model-SerialNumber"
alternateMdnsServiceName string

// SPINE device type of the device model, required
//
// Used for SPINE device type
//
// Used for mDNS txt record: SHIP - Specification 7.3.2
deviceType model.DeviceTypeType

// SPINE device network feature set type, optional
//
// SPINE Protocol Specification 6
featureSet model.NetworkManagementFeatureSetType

// SPINE entity types for each entity that should be created
// SPINE entity types for each entity that should automatically be created, can be empty
//
// Each entity has to have a different type!
entityTypes []model.EntityTypeType

// Network interface to use for the service
//
// Optional, if not set all detected interfaces will be used
interfaces []string

Expand All @@ -65,19 +88,37 @@ type Configuration struct {
certificate tls.Certificate

// The timeout to be used for sending heartbeats and applied to all
// local entities created on setup the service
// local entities created on setup of the service
heartbeatTimeout time.Duration

// Optional set which mDNS providers should be used
mdnsProviderSelection mdns.MdnsProviderSelection
}

// Setup a Configuration with the required parameters
//
// Parameters:
// - vendorCode: The vendors IANA PEN, optional but highly recommended.
// - deviceBrand: The deviceBrand of the device, required (may not be longer than 32 UTF8 characters)
// - deviceModel: The device model, required (may not be longer than 32 UTF8 characters)
// - serialNumber: Serial number of the device, required (may not be longer than 32 UTF8 characters)
// - deviceCategories: Device categories of the device model, required
// - deviceType: SPINE device type of the device model, required
// - entityTypes: SPINE entity types for each entity that should automatically be created, can be empty
// - port: The port address of the websocket server, required
// - certificate: The certificate used for the service and its connections, required
// - heartbeatTimeout: The timeout to be used for sending heartbeats and applied to all local entities created on setup of the service
// - mdnsProviderSelection: Optional set which mDNS providers should be used, default is `mdns.MdnsProviderSelectionAll`
//
// Returns:
// - *Configuration: The created configuration
// - error: An error if the configuration could not be created
func NewConfiguration(
vendorCode,
deviceBrand,
deviceModel,
serialNumber string,
deviceCategories []shipapi.DeviceCategoryType,
deviceType model.DeviceTypeType,
entityTypes []model.EntityTypeType,
port int,
Expand Down Expand Up @@ -117,6 +158,11 @@ func NewConfiguration(
}
configuration.deviceSerialNumber = serialNumber

if len(deviceCategories) == 0 {
return nil, fmt.Errorf("deviceCategories %s", isRequired)
}
configuration.deviceCategories = deviceCategories

if len(deviceType) == 0 {
return nil, fmt.Errorf("deviceType %s", isRequired)
}
Expand All @@ -133,55 +179,70 @@ func NewConfiguration(
return configuration, nil
}

// Returns the configuration vendor code
func (s *Configuration) VendorCode() string {
return s.vendorCode
}

// Returns the configuration device brand
func (s *Configuration) DeviceBrand() string {
return s.deviceBrand
}

// Returns the configuration device model
func (s *Configuration) DeviceModel() string {
return s.deviceModel
}

// Returns the configuration device serial number
func (s *Configuration) DeviceSerialNumber() string {
return s.deviceSerialNumber
}

// define an alternative mDNS and SHIP identifier
// Returns the configuration device categories
func (c *Configuration) DeviceCategories() []shipapi.DeviceCategoryType {
return c.deviceCategories
}

// set an alternative mDNS and SHIP identifier
// usually this is only used when no deviceCode is available or identical to the brand
// if this is not set, generated identifier is used
func (s *Configuration) SetAlternateIdentifier(identifier string) {
s.alternateIdentifier = identifier
}

// define an alternative mDNS service name
// set an alternative mDNS service name
// this is normally not needed or used
func (s *Configuration) SetAlternateMdnsServiceName(name string) {
s.alternateMdnsServiceName = name
}

// set the mDNS provider selection
func (s *Configuration) SetMdnsProviderSelection(providerSelection mdns.MdnsProviderSelection) {
s.mdnsProviderSelection = providerSelection
}

// Returns the mDNS provider selection
func (s *Configuration) MdnsProviderSelection() mdns.MdnsProviderSelection {
return s.mdnsProviderSelection
}

// Returns the configuration device type
func (s *Configuration) DeviceType() model.DeviceTypeType {
return s.deviceType
}

// Returns the configuration network management feature set type
func (s *Configuration) FeatureSet() model.NetworkManagementFeatureSetType {
return s.featureSet
}

// Returns the configuration entity types
func (s *Configuration) EntityTypes() []model.EntityTypeType {
return s.entityTypes
}

// Returns the configuration network interfaces
func (s *Configuration) Interfaces() []string {
return s.interfaces
}
Expand Down Expand Up @@ -224,18 +285,22 @@ func (s *Configuration) MdnsServiceName() string {
return s.generateIdentifier()
}

// Returns the certificate
func (s *Configuration) Certificate() tls.Certificate {
return s.certificate
}

// Returns the port
func (s *Configuration) Port() int {
return s.port
}

// Set the certificate
func (s *Configuration) SetCertificate(cert tls.Certificate) {
s.certificate = cert
}

// Returns the heartbeat timeout
func (s *Configuration) HeartbeatTimeout() time.Duration {
return s.heartbeatTimeout
}
45 changes: 37 additions & 8 deletions api/configuration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"testing"
"time"

shipapi "github.com/enbility/ship-go/api"
"github.com/enbility/ship-go/cert"
"github.com/enbility/ship-go/mdns"
spinemodel "github.com/enbility/spine-go/model"
Expand All @@ -26,53 +27,78 @@ func (s *ConfigurationSuite) Test_Configuration() {
brand := "brand"
model := "model"
serial := "serial"
categories := []shipapi.DeviceCategoryType{shipapi.DeviceCategoryTypeEnergyManagementSystem}
port := 4567
heartbeatTimeout := time.Second * 4
entityTypes := []spinemodel.EntityTypeType{spinemodel.EntityTypeTypeCEM}

config, err := NewConfiguration("", brand, model, serial, spinemodel.DeviceTypeTypeEnergyManagementSystem,
config, err := NewConfiguration("", brand, model, serial,
categories,
spinemodel.DeviceTypeTypeEnergyManagementSystem,
entityTypes, 0, certificate, heartbeatTimeout)

assert.Nil(s.T(), config)
assert.NotNil(s.T(), err)

config, err = NewConfiguration("", brand, model, serial, spinemodel.DeviceTypeTypeEnergyManagementSystem,
config, err = NewConfiguration("", brand, model, serial,
categories,
spinemodel.DeviceTypeTypeEnergyManagementSystem,
entityTypes, port, certificate, heartbeatTimeout)

assert.Nil(s.T(), config)
assert.NotNil(s.T(), err)

config, err = NewConfiguration(vendor, "", model, serial, spinemodel.DeviceTypeTypeEnergyManagementSystem,
config, err = NewConfiguration(vendor, "", model, serial,
categories,
spinemodel.DeviceTypeTypeEnergyManagementSystem,
entityTypes, port, certificate, heartbeatTimeout)

assert.Nil(s.T(), config)
assert.NotNil(s.T(), err)

config, err = NewConfiguration(vendor, brand, "", serial, spinemodel.DeviceTypeTypeEnergyManagementSystem,
config, err = NewConfiguration(vendor, brand, "", serial,
categories,
spinemodel.DeviceTypeTypeEnergyManagementSystem,
entityTypes, port, certificate, heartbeatTimeout)

assert.Nil(s.T(), config)
assert.NotNil(s.T(), err)

config, err = NewConfiguration(vendor, brand, model, "", spinemodel.DeviceTypeTypeEnergyManagementSystem,
config, err = NewConfiguration(vendor, brand, model, "",
categories,
spinemodel.DeviceTypeTypeEnergyManagementSystem,
entityTypes, port, certificate, heartbeatTimeout)

assert.Nil(s.T(), config)
assert.NotNil(s.T(), err)

config, err = NewConfiguration(vendor, brand, model, serial, "",
config, err = NewConfiguration(vendor, brand, model, serial,
nil,
spinemodel.DeviceTypeTypeEnergyManagementSystem,
entityTypes, port, certificate, heartbeatTimeout)

assert.Nil(s.T(), config)
assert.NotNil(s.T(), err)

config, err = NewConfiguration(vendor, brand, model, serial, spinemodel.DeviceTypeTypeEnergyManagementSystem,
config, err = NewConfiguration(vendor, brand, model, serial,
categories,
"",
entityTypes, port, certificate, heartbeatTimeout)

assert.Nil(s.T(), config)
assert.NotNil(s.T(), err)

config, err = NewConfiguration(vendor, brand, model, serial,
categories,
spinemodel.DeviceTypeTypeEnergyManagementSystem,
[]spinemodel.EntityTypeType{}, port, certificate, heartbeatTimeout)

assert.Nil(s.T(), config)
assert.NotNil(s.T(), err)

config, err = NewConfiguration(vendor, brand, model, serial, spinemodel.DeviceTypeTypeEnergyManagementSystem,
config, err = NewConfiguration(vendor, brand, model, serial,
categories,
spinemodel.DeviceTypeTypeEnergyManagementSystem,
entityTypes, port, certificate, heartbeatTimeout)

assert.NotNil(s.T(), config)
Expand Down Expand Up @@ -127,6 +153,9 @@ func (s *ConfigurationSuite) Test_Configuration() {
serialValue := config.DeviceSerialNumber()
assert.Equal(s.T(), serial, serialValue)

categoryValue := config.DeviceCategories()
assert.Equal(s.T(), categories, categoryValue)

deviceTypeValue := config.DeviceType()
assert.Equal(s.T(), spinemodel.DeviceTypeTypeEnergyManagementSystem, deviceTypeValue)

Expand Down
7 changes: 5 additions & 2 deletions api/featuresserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,11 @@ type DeviceConfigurationServerInterface interface {
}

type DeviceDiagnosisServerInterface interface {
// set the local diagnosis state of the device
SetLocalState(operatingState *model.DeviceDiagnosisStateDataType)
// set the local device diagnosis state of the device
SetLocalState(statetate *model.DeviceDiagnosisStateDataType)

// set the local device diagnosis operating state
SetLocalOperatingState(operatingState model.DeviceDiagnosisOperatingStateType)
}

type ElectricalConnectionPermittedValueSetForID struct {
Expand Down
7 changes: 4 additions & 3 deletions cmd/controlbox/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ func (h *controlbox) run() {

configuration, err := api.NewConfiguration(
"Demo", "Demo", "ControlBox", "123456789",
[]shipapi.DeviceCategoryType{shipapi.DeviceCategoryTypeGridConnectionHub},
model.DeviceTypeTypeElectricitySupplySystem,
[]model.EntityTypeType{model.EntityTypeTypeGridGuard},
port, certificate, time.Second*60)
Expand Down Expand Up @@ -150,9 +151,9 @@ func (h *controlbox) sendLimit(entity spineapi.EntityRemoteInterface) {
fmt.Println("Sending a limit in 5s...")
time.AfterFunc(time.Second*5, func() {
limit := ucapi.LoadLimit{
Duration: time.Minute * 2,
Duration: time.Hour*1 + time.Minute*2 + time.Second*3,
IsActive: true,
Value: 7000,
Value: 100,
}

resultCB := func(msg model.ResultDataType) {
Expand Down Expand Up @@ -210,7 +211,7 @@ func usage() {
fmt.Println(" go run /cmd/controlbox/main.go <serverport>")
fmt.Println()
fmt.Println("General Usage:")
fmt.Println(" go run /cmd/controlbox/main.go <serverport> <evse-ski> <crtfile> <keyfile>")
fmt.Println(" go run /cmd/controlbox/main.go <serverport> <remoteski> <crtfile> <keyfile>")
}

func main() {
Expand Down
Loading

0 comments on commit 14255b5

Please sign in to comment.