diff --git a/spine/device.go b/spine/device.go index 860f84c..9726813 100644 --- a/spine/device.go +++ b/spine/device.go @@ -1,6 +1,10 @@ package spine -import "github.com/enbility/spine-go/model" +import ( + "encoding/json" + + "github.com/enbility/spine-go/model" +) type Device struct { address *model.AddressDeviceType @@ -33,6 +37,26 @@ func (r *Device) Address() *model.AddressDeviceType { return r.address } +// Add support for JSON Marshalling +// +// Instances of EntityInterface are used as arguments and return values in various API calls, +// therefor it is helpfull to be able to marshal them to JSON and thus make the API calls +// usable with various communication interfaces +func (r *Device) MarshalJSON() ([]byte, error) { + var tempAddress string + + if r.address != nil { + tempAddress = string(*r.address) + } + + bytes, err := json.Marshal(tempAddress) + if err != nil { + return nil, err + } + + return bytes, nil +} + func (r *Device) DeviceType() *model.DeviceTypeType { return r.dType } diff --git a/spine/device_test.go b/spine/device_test.go new file mode 100644 index 0000000..ab4db50 --- /dev/null +++ b/spine/device_test.go @@ -0,0 +1,35 @@ +package spine + +import ( + "encoding/json" + "testing" + + "github.com/enbility/spine-go/model" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" +) + +func TestDeviceSuite(t *testing.T) { + suite.Run(t, new(DeviceTestSuite)) +} + +type DeviceTestSuite struct { + suite.Suite +} + +func (s *DeviceTestSuite) Test_Device() { + deviceAddress := model.AddressDeviceType("test") + device := NewDevice(&deviceAddress, nil, nil) + + value, err := json.Marshal(device) + assert.Nil(s.T(), err) + assert.NotNil(s.T(), value) + assert.Equal(s.T(), `"test"`, string(value)) + + device = NewDevice(nil, nil, nil) + + value, err = json.Marshal(device) + assert.Nil(s.T(), err) + assert.NotNil(s.T(), value) + assert.Equal(s.T(), `""`, string(value)) +} diff --git a/spine/entity.go b/spine/entity.go index e4b41f1..2b480b8 100644 --- a/spine/entity.go +++ b/spine/entity.go @@ -1,6 +1,7 @@ package spine import ( + "encoding/json" "sync" "github.com/ahmetb/go-linq/v3" @@ -32,7 +33,7 @@ func NewEntity(eType model.EntityTypeType, deviceAddress *model.AddressDeviceTyp Entity: entityAddress, }, } - if entityAddress[0] == 0 { + if entityAddress != nil && entityAddress[0] == 0 { // Entity 0 Feature addresses start with 0 entity.fIdGenerator = newFeatureIdGenerator(0) } else { @@ -47,6 +48,33 @@ func (r *Entity) Address() *model.EntityAddressType { return r.address } +// Add support for JSON Marshalling +// +// Instances of EntityInterface are used as arguments and return values in various API calls, +// therefor it is helpfull to be able to marshal them to JSON and thus make the API calls +// usable with various communication interfaces +func (r *Entity) MarshalJSON() ([]byte, error) { + // we do not want to omit address fields, if they are nil + // and field names should not be lowercased + type tempAddressType struct { + Device model.AddressDeviceType + Entity []model.AddressEntityType + } + var tempAddress tempAddressType + + if r.address.Device != nil { + tempAddress.Device = *r.address.Device + } + tempAddress.Entity = r.address.Entity + + bytes, err := json.Marshal(tempAddress) + if err != nil { + return nil, err + } + + return bytes, nil +} + func (r *Entity) EntityType() model.EntityTypeType { return r.eType } diff --git a/spine/entity_test.go b/spine/entity_test.go new file mode 100644 index 0000000..e7bc407 --- /dev/null +++ b/spine/entity_test.go @@ -0,0 +1,42 @@ +package spine + +import ( + "encoding/json" + "testing" + + "github.com/enbility/spine-go/model" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" +) + +func TestEntitySuite(t *testing.T) { + suite.Run(t, new(EntityTestSuite)) +} + +type EntityTestSuite struct { + suite.Suite +} + +func (s *EntityTestSuite) Test_Entity() { + deviceAddress := model.AddressDeviceType("test") + entity := NewEntity(model.EntityTypeTypeCEM, &deviceAddress, NewAddressEntityType([]uint{1, 1})) + + value, err := json.Marshal(entity) + assert.Nil(s.T(), err) + assert.NotNil(s.T(), value) + assert.Equal(s.T(), `{"Device":"test","Entity":[1,1]}`, string(value)) + + entity = NewEntity(model.EntityTypeTypeCEM, &deviceAddress, nil) + + value, err = json.Marshal(entity) + assert.Nil(s.T(), err) + assert.NotNil(s.T(), value) + assert.Equal(s.T(), `{"Device":"test","Entity":null}`, string(value)) + + entity = NewEntity(model.EntityTypeTypeCEM, nil, nil) + + value, err = json.Marshal(entity) + assert.Nil(s.T(), err) + assert.NotNil(s.T(), value) + assert.Equal(s.T(), `{"Device":"","Entity":null}`, string(value)) +}