mirror of
https://github.com/hybridgroup/gobot.git
synced 2025-04-24 13:48:49 +08:00
ble: add support for functional options, add tests (#1059)
This commit is contained in:
parent
3ac63bfd27
commit
d96aa52fb9
@ -174,8 +174,7 @@ import (
|
||||
|
||||
func NewSwarmBot(port string) *gobot.Robot {
|
||||
spheroAdaptor := serialport.NewAdaptor(port)
|
||||
spheroDriver := serial.NewSpheroDriver(spheroAdaptor)
|
||||
spheroDriver.SetName("Sphero" + port)
|
||||
spheroDriver := serial.NewSpheroDriver(spheroAdaptor, serial.WithName("Sphero" + port))
|
||||
|
||||
work := func() {
|
||||
spheroDriver.Stop()
|
||||
|
@ -235,7 +235,7 @@ type BLEConnector interface {
|
||||
|
||||
ReadCharacteristic(cUUID string) ([]byte, error)
|
||||
WriteCharacteristic(cUUID string, data []byte) error
|
||||
Subscribe(cUUID string, f func([]byte, error)) error
|
||||
Subscribe(cUUID string, f func(data []byte)) error
|
||||
WithoutResponses(use bool)
|
||||
}
|
||||
|
||||
|
3
doc.go
3
doc.go
@ -85,8 +85,7 @@ Finally, you can use Master Gobot to add the complete Gobot API or control swarm
|
||||
|
||||
func NewSwarmBot(port string) *gobot.Robot {
|
||||
spheroAdaptor := serialport.NewAdaptor(port)
|
||||
spheroDriver := serial.NewSpheroDriver(spheroAdaptor)
|
||||
spheroDriver.SetName("Sphero" + port)
|
||||
spheroDriver := serial.NewSpheroDriver(spheroAdaptor, serial.WithName("Sphero" + port))
|
||||
|
||||
work := func() {
|
||||
spheroDriver.Stop()
|
||||
|
@ -5,7 +5,7 @@ type Driver interface {
|
||||
// Name returns the label for the Driver
|
||||
Name() string
|
||||
// SetName sets the label for the Driver.
|
||||
// Please prefer to use options [gpio.WithName or aio.WithName] instead, if possible.
|
||||
// Please use options [aio.WithName, ble.WithName, gpio.WithName or serial.WithName] instead.
|
||||
SetName(s string)
|
||||
// Start initiates the Driver
|
||||
Start() error
|
||||
|
@ -39,6 +39,44 @@ import(
|
||||
...
|
||||
```
|
||||
|
||||
### BLE client adaptor changed signature for Subscribe()
|
||||
|
||||
Since introducing the usage of "github.com/muka/go-bluetooth" in 2020, the callback do not support the given error
|
||||
parameter anymore. The switch to usage of "tinygo.org/x/bluetooth" has not changed this. Therefore it is removed now
|
||||
from the function.
|
||||
|
||||
### BLE generic drivers changed signature for Get*() functions
|
||||
|
||||
All those functions log an error only or panic, so the caller gets no nice programmatic feedback. The error is now
|
||||
returned instead and the log output needs to be done at caller side.
|
||||
|
||||
```go
|
||||
// old
|
||||
...
|
||||
devName := access.GetDeviceName()
|
||||
appearance := access.GetAppearance()
|
||||
modelNo := info.GetModelNumber()
|
||||
fwRev := info.GetFirmwareRevision()
|
||||
hwRev := info.GetHardwareRevision()
|
||||
manuName := info.GetManufacturerName()
|
||||
pid := info.GetPnPId()
|
||||
level := battery.GetBatteryLevel()
|
||||
...
|
||||
|
||||
// new
|
||||
...
|
||||
devName, err := access.GetDeviceName()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
appearance, err := access.GetAppearance()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
...
|
||||
...
|
||||
```
|
||||
|
||||
### Sphero adaptor split off
|
||||
|
||||
The Serial Based Sphero adaptor was split off into a generic serial adaptor and the driver part. With this, the imports
|
||||
|
@ -2,7 +2,6 @@ package ble
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"log"
|
||||
|
||||
"gobot.io/x/gobot/v2"
|
||||
)
|
||||
@ -16,9 +15,9 @@ type BatteryDriver struct {
|
||||
}
|
||||
|
||||
// NewBatteryDriver creates a new driver
|
||||
func NewBatteryDriver(a gobot.BLEConnector) *BatteryDriver {
|
||||
func NewBatteryDriver(a gobot.BLEConnector, opts ...OptionApplier) *BatteryDriver {
|
||||
d := &BatteryDriver{
|
||||
Driver: NewDriver(a, "Battery", nil, nil),
|
||||
Driver: NewDriver(a, "Battery", nil, nil, opts...),
|
||||
Eventer: gobot.NewEventer(),
|
||||
}
|
||||
|
||||
@ -26,14 +25,13 @@ func NewBatteryDriver(a gobot.BLEConnector) *BatteryDriver {
|
||||
}
|
||||
|
||||
// GetBatteryLevel reads and returns the current battery level
|
||||
func (d *BatteryDriver) GetBatteryLevel() uint8 {
|
||||
func (d *BatteryDriver) GetBatteryLevel() (uint8, error) {
|
||||
c, err := d.Adaptor().ReadCharacteristic(batteryCharaShort)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return 0
|
||||
return 0, err
|
||||
}
|
||||
buf := bytes.NewBuffer(c)
|
||||
val, _ := buf.ReadByte()
|
||||
level := val
|
||||
return level
|
||||
return level, nil
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"gobot.io/x/gobot/v2"
|
||||
"gobot.io/x/gobot/v2/drivers/ble/testutil"
|
||||
@ -13,12 +14,27 @@ import (
|
||||
var _ gobot.Driver = (*BatteryDriver)(nil)
|
||||
|
||||
func TestNewBatteryDriver(t *testing.T) {
|
||||
// arrange
|
||||
d := NewBatteryDriver(testutil.NewBleTestAdaptor())
|
||||
// act & assert
|
||||
assert.True(t, strings.HasPrefix(d.Name(), "Battery"))
|
||||
assert.NotNil(t, d.Eventer)
|
||||
}
|
||||
|
||||
func TestNewBatteryDriverWithName(t *testing.T) {
|
||||
// This is a general test, that options are applied in constructor by using the common WithName() option. Further
|
||||
// tests for options can also be done by call of "WithOption(val).apply(cfg)".
|
||||
// arrange
|
||||
const newName = "new name"
|
||||
a := testutil.NewBleTestAdaptor()
|
||||
// act
|
||||
d := NewBatteryDriver(a, WithName(newName))
|
||||
// assert
|
||||
assert.Equal(t, newName, d.Name())
|
||||
}
|
||||
|
||||
func TestBatteryDriverRead(t *testing.T) {
|
||||
// arrange
|
||||
a := testutil.NewBleTestAdaptor()
|
||||
d := NewBatteryDriver(a)
|
||||
a.SetReadCharacteristicTestFunc(func(cUUID string) ([]byte, error) {
|
||||
@ -28,6 +44,9 @@ func TestBatteryDriverRead(t *testing.T) {
|
||||
|
||||
return nil, nil
|
||||
})
|
||||
|
||||
assert.Equal(t, uint8(20), d.GetBatteryLevel())
|
||||
// act
|
||||
level, err := d.GetBatteryLevel()
|
||||
// assert
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, uint8(20), level)
|
||||
}
|
||||
|
@ -7,8 +7,8 @@ import (
|
||||
"gobot.io/x/gobot/v2"
|
||||
)
|
||||
|
||||
// optionApplier needs to be implemented by each configurable option type
|
||||
type optionApplier interface {
|
||||
// OptionApplier needs to be implemented by each configurable option type
|
||||
type OptionApplier interface {
|
||||
apply(cfg *configuration)
|
||||
}
|
||||
|
||||
@ -31,7 +31,11 @@ type Driver struct {
|
||||
}
|
||||
|
||||
// NewDriver creates a new basic BLE gobot driver.
|
||||
func NewDriver(a interface{}, name string, afterStart func() error, beforeHalt func() error) *Driver {
|
||||
func NewDriver(
|
||||
a interface{}, name string,
|
||||
afterStart func() error, beforeHalt func() error,
|
||||
opts ...OptionApplier,
|
||||
) *Driver {
|
||||
if afterStart == nil {
|
||||
afterStart = func() error { return nil }
|
||||
}
|
||||
@ -49,11 +53,15 @@ func NewDriver(a interface{}, name string, afterStart func() error, beforeHalt f
|
||||
mutex: &sync.Mutex{},
|
||||
}
|
||||
|
||||
for _, o := range opts {
|
||||
o.apply(d.driverCfg)
|
||||
}
|
||||
|
||||
return &d
|
||||
}
|
||||
|
||||
// WithName is used to replace the default name of the driver.
|
||||
func WithName(name string) optionApplier {
|
||||
func WithName(name string) OptionApplier {
|
||||
return nameOption(name)
|
||||
}
|
||||
|
||||
@ -63,7 +71,7 @@ func (d *Driver) Name() string {
|
||||
}
|
||||
|
||||
// SetName sets the name of the driver.
|
||||
// Deprecated: Please use option [aio.WithName] instead.
|
||||
// Deprecated: Please use option [ble.WithName] instead.
|
||||
func (d *Driver) SetName(name string) {
|
||||
WithName(name).apply(d.driverCfg)
|
||||
}
|
||||
|
@ -37,6 +37,21 @@ func TestNewDriver(t *testing.T) {
|
||||
assert.NotNil(t, d.mutex)
|
||||
}
|
||||
|
||||
func TestNewDriverWithName(t *testing.T) {
|
||||
// This is a general test, that options are applied in constructor by using the common WithName() option. Further
|
||||
// tests for options can also be done by call of "WithOption(val).apply(cfg)".
|
||||
// arrange
|
||||
const (
|
||||
name = "mybot"
|
||||
newName = "overwrite mybot"
|
||||
)
|
||||
a := testutil.NewBleTestAdaptor()
|
||||
// act
|
||||
d := NewDriver(a, name, nil, nil, WithName(newName))
|
||||
// assert
|
||||
assert.Equal(t, newName, d.Name())
|
||||
}
|
||||
|
||||
func Test_applyWithName(t *testing.T) {
|
||||
// arrange
|
||||
const name = "mybot"
|
||||
@ -68,3 +83,18 @@ func TestHalt(t *testing.T) {
|
||||
// act, assert
|
||||
require.EqualError(t, d.Halt(), "before halt error")
|
||||
}
|
||||
|
||||
func TestAdaptor(t *testing.T) {
|
||||
wrongConnectorType := struct {
|
||||
a uint32
|
||||
}{}
|
||||
// arrange
|
||||
a := testutil.NewBleTestAdaptor()
|
||||
d := NewDriver(a, "BLE_BASIC", nil, nil)
|
||||
// act, assert
|
||||
assert.Equal(t, a, d.Adaptor())
|
||||
// arrange wrong connector type
|
||||
d.connection = wrongConnectorType
|
||||
// act, assert
|
||||
assert.Nil(t, d.Adaptor())
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package ble
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"log"
|
||||
|
||||
"gobot.io/x/gobot/v2"
|
||||
)
|
||||
@ -22,9 +21,9 @@ type DeviceInformationDriver struct {
|
||||
}
|
||||
|
||||
// NewDeviceInformationDriver creates a new driver
|
||||
func NewDeviceInformationDriver(a gobot.BLEConnector) *DeviceInformationDriver {
|
||||
func NewDeviceInformationDriver(a gobot.BLEConnector, opts ...OptionApplier) *DeviceInformationDriver {
|
||||
n := &DeviceInformationDriver{
|
||||
Driver: NewDriver(a, "DeviceInformation", nil, nil),
|
||||
Driver: NewDriver(a, "DeviceInformation", nil, nil, opts...),
|
||||
Eventer: gobot.NewEventer(),
|
||||
}
|
||||
|
||||
@ -32,61 +31,56 @@ func NewDeviceInformationDriver(a gobot.BLEConnector) *DeviceInformationDriver {
|
||||
}
|
||||
|
||||
// GetModelNumber returns the model number for the BLE Peripheral
|
||||
func (d *DeviceInformationDriver) GetModelNumber() string {
|
||||
func (d *DeviceInformationDriver) GetModelNumber() (string, error) {
|
||||
c, err := d.Adaptor().ReadCharacteristic(deviceInformationModelNumberCharaShort)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return ""
|
||||
return "", err
|
||||
}
|
||||
buf := bytes.NewBuffer(c)
|
||||
model := buf.String()
|
||||
return model
|
||||
return model, nil
|
||||
}
|
||||
|
||||
// GetFirmwareRevision returns the firmware revision for the BLE Peripheral
|
||||
func (d *DeviceInformationDriver) GetFirmwareRevision() string {
|
||||
func (d *DeviceInformationDriver) GetFirmwareRevision() (string, error) {
|
||||
c, err := d.Adaptor().ReadCharacteristic(deviceInformationFirmwareRevisionCharaShort)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return ""
|
||||
return "", err
|
||||
}
|
||||
buf := bytes.NewBuffer(c)
|
||||
val := buf.String()
|
||||
return val
|
||||
return val, nil
|
||||
}
|
||||
|
||||
// GetHardwareRevision returns the hardware revision for the BLE Peripheral
|
||||
func (d *DeviceInformationDriver) GetHardwareRevision() string {
|
||||
func (d *DeviceInformationDriver) GetHardwareRevision() (string, error) {
|
||||
c, err := d.Adaptor().ReadCharacteristic(deviceInformationHardwareRevisionCharaShort)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return ""
|
||||
return "", err
|
||||
}
|
||||
buf := bytes.NewBuffer(c)
|
||||
val := buf.String()
|
||||
return val
|
||||
return val, nil
|
||||
}
|
||||
|
||||
// GetManufacturerName returns the manufacturer name for the BLE Peripheral
|
||||
func (d *DeviceInformationDriver) GetManufacturerName() string {
|
||||
func (d *DeviceInformationDriver) GetManufacturerName() (string, error) {
|
||||
c, err := d.Adaptor().ReadCharacteristic(deviceInformationManufacturerNameCharaShort)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return ""
|
||||
return "", err
|
||||
}
|
||||
buf := bytes.NewBuffer(c)
|
||||
val := buf.String()
|
||||
return val
|
||||
return val, nil
|
||||
}
|
||||
|
||||
// GetPnPId returns the PnP ID for the BLE Peripheral
|
||||
func (d *DeviceInformationDriver) GetPnPId() string {
|
||||
func (d *DeviceInformationDriver) GetPnPId() (string, error) {
|
||||
c, err := d.Adaptor().ReadCharacteristic(deviceInformationPnPIdCharaShort)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return ""
|
||||
return "", err
|
||||
}
|
||||
buf := bytes.NewBuffer(c)
|
||||
val := buf.String()
|
||||
return val
|
||||
return val, nil
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"gobot.io/x/gobot/v2"
|
||||
"gobot.io/x/gobot/v2/drivers/ble/testutil"
|
||||
@ -13,32 +14,71 @@ import (
|
||||
var _ gobot.Driver = (*DeviceInformationDriver)(nil)
|
||||
|
||||
func TestNewDeviceInformationDriver(t *testing.T) {
|
||||
// arrange
|
||||
d := NewDeviceInformationDriver(testutil.NewBleTestAdaptor())
|
||||
// act & assert
|
||||
assert.True(t, strings.HasPrefix(d.Name(), "DeviceInformation"))
|
||||
assert.NotNil(t, d.Eventer)
|
||||
}
|
||||
|
||||
func TestNewDeviceInformationDriverWithName(t *testing.T) {
|
||||
// This is a general test, that options are applied in constructor by using the common WithName() option. Further
|
||||
// tests for options can also be done by call of "WithOption(val).apply(cfg)".
|
||||
// arrange
|
||||
const newName = "new name"
|
||||
a := testutil.NewBleTestAdaptor()
|
||||
// act
|
||||
d := NewDeviceInformationDriver(a, WithName(newName))
|
||||
// assert
|
||||
assert.Equal(t, newName, d.Name())
|
||||
}
|
||||
|
||||
func TestDeviceInformationGetModelNumber(t *testing.T) {
|
||||
// arrange
|
||||
d := NewDeviceInformationDriver(testutil.NewBleTestAdaptor())
|
||||
assert.Equal(t, "2a24", d.GetModelNumber())
|
||||
// act
|
||||
modelNo, err := d.GetModelNumber()
|
||||
// assert
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "2a24", modelNo)
|
||||
}
|
||||
|
||||
func TestDeviceInformationGetFirmwareRevision(t *testing.T) {
|
||||
// arrange
|
||||
d := NewDeviceInformationDriver(testutil.NewBleTestAdaptor())
|
||||
assert.Equal(t, "2a26", d.GetFirmwareRevision())
|
||||
// act
|
||||
fwRev, err := d.GetFirmwareRevision()
|
||||
// assert
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "2a26", fwRev)
|
||||
}
|
||||
|
||||
func TestDeviceInformationGetHardwareRevision(t *testing.T) {
|
||||
// arrange
|
||||
d := NewDeviceInformationDriver(testutil.NewBleTestAdaptor())
|
||||
assert.Equal(t, "2a27", d.GetHardwareRevision())
|
||||
// act
|
||||
hwRev, err := d.GetHardwareRevision()
|
||||
// assert
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "2a27", hwRev)
|
||||
}
|
||||
|
||||
func TestDeviceInformationGetManufacturerName(t *testing.T) {
|
||||
// arrange
|
||||
d := NewDeviceInformationDriver(testutil.NewBleTestAdaptor())
|
||||
assert.Equal(t, "2a29", d.GetManufacturerName())
|
||||
// act
|
||||
manuName, err := d.GetManufacturerName()
|
||||
// assert
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "2a29", manuName)
|
||||
}
|
||||
|
||||
func TestDeviceInformationGetPnPId(t *testing.T) {
|
||||
// arrange
|
||||
d := NewDeviceInformationDriver(testutil.NewBleTestAdaptor())
|
||||
assert.Equal(t, "2a50", d.GetPnPId())
|
||||
// act
|
||||
pid, err := d.GetPnPId()
|
||||
// assert
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "2a50", pid)
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package ble
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"log"
|
||||
|
||||
"gobot.io/x/gobot/v2"
|
||||
)
|
||||
@ -20,9 +19,9 @@ type GenericAccessDriver struct {
|
||||
}
|
||||
|
||||
// NewGenericAccessDriver creates a GenericAccessDriver
|
||||
func NewGenericAccessDriver(a gobot.BLEConnector) *GenericAccessDriver {
|
||||
func NewGenericAccessDriver(a gobot.BLEConnector, opts ...OptionApplier) *GenericAccessDriver {
|
||||
d := &GenericAccessDriver{
|
||||
Driver: NewDriver(a, "GenericAccess", nil, nil),
|
||||
Driver: NewDriver(a, "GenericAccess", nil, nil, opts...),
|
||||
Eventer: gobot.NewEventer(),
|
||||
}
|
||||
|
||||
@ -30,33 +29,31 @@ func NewGenericAccessDriver(a gobot.BLEConnector) *GenericAccessDriver {
|
||||
}
|
||||
|
||||
// GetDeviceName returns the device name for the BLE Peripheral
|
||||
func (d *GenericAccessDriver) GetDeviceName() string {
|
||||
func (d *GenericAccessDriver) GetDeviceName() (string, error) {
|
||||
c, err := d.Adaptor().ReadCharacteristic(genericAccessDeviceNameCharaShort)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return ""
|
||||
return "", err
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(c)
|
||||
val := buf.String()
|
||||
return val
|
||||
return val, nil
|
||||
}
|
||||
|
||||
// GetAppearance returns the appearance string for the BLE Peripheral
|
||||
func (d *GenericAccessDriver) GetAppearance() string {
|
||||
func (d *GenericAccessDriver) GetAppearance() (string, error) {
|
||||
c, err := d.Adaptor().ReadCharacteristic(genericAccessAppearanceCharaShort)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return ""
|
||||
return "", err
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(c)
|
||||
|
||||
var val uint16
|
||||
if err := binary.Read(buf, binary.LittleEndian, &val); err != nil {
|
||||
panic(err)
|
||||
return "", err
|
||||
}
|
||||
return appearances[val]
|
||||
return appearances[val], nil
|
||||
}
|
||||
|
||||
var appearances = map[uint16]string{
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"gobot.io/x/gobot/v2"
|
||||
"gobot.io/x/gobot/v2/drivers/ble/testutil"
|
||||
@ -13,17 +14,37 @@ import (
|
||||
var _ gobot.Driver = (*GenericAccessDriver)(nil)
|
||||
|
||||
func TestNewGenericAccessDriver(t *testing.T) {
|
||||
// arrange
|
||||
d := NewGenericAccessDriver(testutil.NewBleTestAdaptor())
|
||||
// act
|
||||
assert.True(t, strings.HasPrefix(d.Name(), "GenericAccess"))
|
||||
assert.NotNil(t, d.Eventer)
|
||||
}
|
||||
|
||||
func TestNewGenericAccessDriverWithName(t *testing.T) {
|
||||
// This is a general test, that options are applied in constructor by using the common WithName() option. Further
|
||||
// tests for options can also be done by call of "WithOption(val).apply(cfg)".
|
||||
// arrange
|
||||
const newName = "new name"
|
||||
a := testutil.NewBleTestAdaptor()
|
||||
// act
|
||||
d := NewGenericAccessDriver(a, WithName(newName))
|
||||
// assert
|
||||
assert.Equal(t, newName, d.Name())
|
||||
}
|
||||
|
||||
func TestGenericAccessDriverGetDeviceName(t *testing.T) {
|
||||
// arrange
|
||||
d := NewGenericAccessDriver(testutil.NewBleTestAdaptor())
|
||||
assert.Equal(t, "2a00", d.GetDeviceName())
|
||||
// act
|
||||
devName, err := d.GetDeviceName()
|
||||
// assert
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "2a00", devName)
|
||||
}
|
||||
|
||||
func TestGenericAccessDriverGetAppearance(t *testing.T) {
|
||||
// arrange
|
||||
a := testutil.NewBleTestAdaptor()
|
||||
d := NewGenericAccessDriver(a)
|
||||
a.SetReadCharacteristicTestFunc(func(cUUID string) ([]byte, error) {
|
||||
@ -32,6 +53,9 @@ func TestGenericAccessDriverGetAppearance(t *testing.T) {
|
||||
}
|
||||
return nil, nil
|
||||
})
|
||||
|
||||
assert.Equal(t, "Generic Computer", d.GetAppearance())
|
||||
// act
|
||||
app, err := d.GetAppearance()
|
||||
// assert
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "Generic Computer", app)
|
||||
}
|
||||
|
@ -28,11 +28,11 @@ type AccelerometerData struct {
|
||||
}
|
||||
|
||||
// NewAccelerometerDriver creates a AccelerometerDriver
|
||||
func NewAccelerometerDriver(a gobot.BLEConnector) *AccelerometerDriver {
|
||||
func NewAccelerometerDriver(a gobot.BLEConnector, opts ...ble.OptionApplier) *AccelerometerDriver {
|
||||
d := &AccelerometerDriver{
|
||||
Eventer: gobot.NewEventer(),
|
||||
}
|
||||
d.Driver = ble.NewDriver(a, "Microbit Accelerometer", d.initialize, nil)
|
||||
d.Driver = ble.NewDriver(a, "Microbit Accelerometer", d.initialize, nil, opts...)
|
||||
|
||||
d.AddEvent(AccelerometerEvent)
|
||||
|
||||
@ -42,7 +42,7 @@ func NewAccelerometerDriver(a gobot.BLEConnector) *AccelerometerDriver {
|
||||
// initialize tells driver to get ready to do work
|
||||
func (d *AccelerometerDriver) initialize() error {
|
||||
// subscribe to accelerometer notifications
|
||||
return d.Adaptor().Subscribe(accelerometerChara, func(data []byte, e error) {
|
||||
return d.Adaptor().Subscribe(accelerometerChara, func(data []byte) {
|
||||
a := struct{ x, y, z int16 }{x: 0, y: 0, z: 0}
|
||||
|
||||
buf := bytes.NewBuffer(data)
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"gobot.io/x/gobot/v2"
|
||||
"gobot.io/x/gobot/v2/drivers/ble"
|
||||
"gobot.io/x/gobot/v2/drivers/ble/testutil"
|
||||
)
|
||||
|
||||
@ -22,6 +23,18 @@ func TestNewAccelerometerDriver(t *testing.T) {
|
||||
assert.NotNil(t, d.Eventer)
|
||||
}
|
||||
|
||||
func TestNewAccelerometerDriverWithName(t *testing.T) {
|
||||
// This is a general test, that options are applied in constructor by using the common WithName() option. Further
|
||||
// tests for options can also be done by call of "WithOption(val).apply(cfg)".
|
||||
// arrange
|
||||
const newName = "new name"
|
||||
a := testutil.NewBleTestAdaptor()
|
||||
// act
|
||||
d := NewAccelerometerDriver(a, ble.WithName(newName))
|
||||
// assert
|
||||
assert.Equal(t, newName, d.Name())
|
||||
}
|
||||
|
||||
func TestAccelerometerStartAndHalt(t *testing.T) {
|
||||
d := NewAccelerometerDriver(testutil.NewBleTestAdaptor())
|
||||
require.NoError(t, d.Start())
|
||||
@ -43,7 +56,7 @@ func TestAccelerometerReadData(t *testing.T) {
|
||||
|
||||
require.NoError(t, err)
|
||||
|
||||
a.SendTestDataToSubscriber([]byte{0x22, 0x22, 0x23, 0x23, 0x24, 0x24}, nil)
|
||||
a.SendTestDataToSubscriber([]byte{0x22, 0x22, 0x23, 0x23, 0x24, 0x24})
|
||||
|
||||
select {
|
||||
case <-sem:
|
||||
|
@ -21,12 +21,12 @@ type ButtonDriver struct {
|
||||
}
|
||||
|
||||
// NewButtonDriver creates a new driver
|
||||
func NewButtonDriver(a gobot.BLEConnector) *ButtonDriver {
|
||||
func NewButtonDriver(a gobot.BLEConnector, opts ...ble.OptionApplier) *ButtonDriver {
|
||||
d := &ButtonDriver{
|
||||
Eventer: gobot.NewEventer(),
|
||||
}
|
||||
|
||||
d.Driver = ble.NewDriver(a, "Microbit Button", d.initialize, nil)
|
||||
d.Driver = ble.NewDriver(a, "Microbit Button", d.initialize, nil, opts...)
|
||||
|
||||
d.AddEvent(ButtonAEvent)
|
||||
d.AddEvent(ButtonBEvent)
|
||||
@ -37,14 +37,14 @@ func NewButtonDriver(a gobot.BLEConnector) *ButtonDriver {
|
||||
// initialize tells driver to get ready to do work
|
||||
func (d *ButtonDriver) initialize() error {
|
||||
// subscribe to button A notifications
|
||||
if err := d.Adaptor().Subscribe(buttonAChara, func(data []byte, e error) {
|
||||
if err := d.Adaptor().Subscribe(buttonAChara, func(data []byte) {
|
||||
d.Publish(d.Event(ButtonAEvent), data)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// subscribe to button B notifications
|
||||
return d.Adaptor().Subscribe(buttonBChara, func(data []byte, e error) {
|
||||
return d.Adaptor().Subscribe(buttonBChara, func(data []byte) {
|
||||
d.Publish(d.Event(ButtonBEvent), data)
|
||||
})
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"gobot.io/x/gobot/v2"
|
||||
"gobot.io/x/gobot/v2/drivers/ble"
|
||||
"gobot.io/x/gobot/v2/drivers/ble/testutil"
|
||||
)
|
||||
|
||||
@ -21,6 +22,18 @@ func TestNewButtonDriver(t *testing.T) {
|
||||
assert.NotNil(t, d.Eventer)
|
||||
}
|
||||
|
||||
func TestNewButtonDriverWithName(t *testing.T) {
|
||||
// This is a general test, that options are applied in constructor by using the common WithName() option. Further
|
||||
// tests for options can also be done by call of "WithOption(val).apply(cfg)".
|
||||
// arrange
|
||||
const newName = "new name"
|
||||
a := testutil.NewBleTestAdaptor()
|
||||
// act
|
||||
d := NewButtonDriver(a, ble.WithName(newName))
|
||||
// assert
|
||||
assert.Equal(t, newName, d.Name())
|
||||
}
|
||||
|
||||
func TestButtonStartAndHalt(t *testing.T) {
|
||||
d := NewButtonDriver(testutil.NewBleTestAdaptor())
|
||||
require.NoError(t, d.Start())
|
||||
@ -38,7 +51,7 @@ func TestButtonReadData(t *testing.T) {
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
a.SendTestDataToSubscriber([]byte{1}, nil)
|
||||
a.SendTestDataToSubscriber([]byte{1})
|
||||
|
||||
select {
|
||||
case <-sem:
|
||||
|
@ -33,12 +33,12 @@ type pinData struct {
|
||||
}
|
||||
|
||||
// NewIOPinDriver creates a new driver
|
||||
func NewIOPinDriver(a gobot.BLEConnector) *IOPinDriver {
|
||||
func NewIOPinDriver(a gobot.BLEConnector, opts ...ble.OptionApplier) *IOPinDriver {
|
||||
d := &IOPinDriver{
|
||||
Eventer: gobot.NewEventer(),
|
||||
}
|
||||
|
||||
d.Driver = ble.NewDriver(a, "Microbit IO Pins", d.initialize, nil)
|
||||
d.Driver = ble.NewDriver(a, "Microbit IO Pins", d.initialize, nil, opts...)
|
||||
|
||||
return d
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
|
||||
"gobot.io/x/gobot/v2"
|
||||
"gobot.io/x/gobot/v2/drivers/aio"
|
||||
"gobot.io/x/gobot/v2/drivers/ble"
|
||||
"gobot.io/x/gobot/v2/drivers/ble/testutil"
|
||||
"gobot.io/x/gobot/v2/drivers/gpio"
|
||||
)
|
||||
@ -31,6 +32,18 @@ func TestNewIOPinDriver(t *testing.T) {
|
||||
assert.NotNil(t, d.Eventer)
|
||||
}
|
||||
|
||||
func TestNewIOPinDriverWithName(t *testing.T) {
|
||||
// This is a general test, that options are applied in constructor by using the common WithName() option. Further
|
||||
// tests for options can also be done by call of "WithOption(val).apply(cfg)".
|
||||
// arrange
|
||||
const newName = "new name"
|
||||
a := testutil.NewBleTestAdaptor()
|
||||
// act
|
||||
d := NewIOPinDriver(a, ble.WithName(newName))
|
||||
// assert
|
||||
assert.Equal(t, newName, d.Name())
|
||||
}
|
||||
|
||||
func TestIOPinStartAndHalt(t *testing.T) {
|
||||
a := testutil.NewBleTestAdaptor()
|
||||
d := NewIOPinDriver(a)
|
||||
|
@ -19,12 +19,12 @@ type LEDDriver struct {
|
||||
}
|
||||
|
||||
// NewLEDDriver creates a Microbit LEDDriver
|
||||
func NewLEDDriver(a gobot.BLEConnector) *LEDDriver {
|
||||
func NewLEDDriver(a gobot.BLEConnector, opts ...ble.OptionApplier) *LEDDriver {
|
||||
d := &LEDDriver{
|
||||
Eventer: gobot.NewEventer(),
|
||||
}
|
||||
|
||||
d.Driver = ble.NewDriver(a, "Microbit LED", nil, nil)
|
||||
d.Driver = ble.NewDriver(a, "Microbit LED", nil, nil, opts...)
|
||||
|
||||
return d
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"gobot.io/x/gobot/v2"
|
||||
"gobot.io/x/gobot/v2/drivers/ble"
|
||||
"gobot.io/x/gobot/v2/drivers/ble/testutil"
|
||||
)
|
||||
|
||||
@ -25,6 +26,18 @@ func TestNewLEDDriver(t *testing.T) {
|
||||
assert.NotNil(t, d.Eventer)
|
||||
}
|
||||
|
||||
func TestNewLEDDriverWithName(t *testing.T) {
|
||||
// This is a general test, that options are applied in constructor by using the common WithName() option. Further
|
||||
// tests for options can also be done by call of "WithOption(val).apply(cfg)".
|
||||
// arrange
|
||||
const newName = "new name"
|
||||
a := testutil.NewBleTestAdaptor()
|
||||
// act
|
||||
d := NewLEDDriver(a, ble.WithName(newName))
|
||||
// assert
|
||||
assert.Equal(t, newName, d.Name())
|
||||
}
|
||||
|
||||
func TestLEDWriteMatrix(t *testing.T) {
|
||||
d := initTestLEDDriver()
|
||||
require.NoError(t, d.WriteMatrix([]byte{0x01, 0x02}))
|
||||
|
@ -28,11 +28,11 @@ type MagnetometerData struct {
|
||||
}
|
||||
|
||||
// NewMagnetometerDriver creates a Microbit MagnetometerDriver
|
||||
func NewMagnetometerDriver(a gobot.BLEConnector) *MagnetometerDriver {
|
||||
func NewMagnetometerDriver(a gobot.BLEConnector, opts ...ble.OptionApplier) *MagnetometerDriver {
|
||||
d := &MagnetometerDriver{
|
||||
Eventer: gobot.NewEventer(),
|
||||
}
|
||||
d.Driver = ble.NewDriver(a, "Microbit Magnetometer", d.initialize, nil)
|
||||
d.Driver = ble.NewDriver(a, "Microbit Magnetometer", d.initialize, nil, opts...)
|
||||
|
||||
d.AddEvent(MagnetometerEvent)
|
||||
|
||||
@ -42,7 +42,7 @@ func NewMagnetometerDriver(a gobot.BLEConnector) *MagnetometerDriver {
|
||||
// initialize tells driver to get ready to do work
|
||||
func (d *MagnetometerDriver) initialize() error {
|
||||
// subscribe to magnetometer notifications
|
||||
return d.Adaptor().Subscribe(magnetometerChara, func(data []byte, e error) {
|
||||
return d.Adaptor().Subscribe(magnetometerChara, func(data []byte) {
|
||||
a := struct{ x, y, z int16 }{x: 0, y: 0, z: 0}
|
||||
|
||||
buf := bytes.NewBuffer(data)
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"gobot.io/x/gobot/v2"
|
||||
"gobot.io/x/gobot/v2/drivers/ble"
|
||||
"gobot.io/x/gobot/v2/drivers/ble/testutil"
|
||||
)
|
||||
|
||||
@ -27,6 +28,18 @@ func TestMagnetometerDriver(t *testing.T) {
|
||||
assert.NotNil(t, d.Eventer)
|
||||
}
|
||||
|
||||
func TestNewMagnetometerDriverWithName(t *testing.T) {
|
||||
// This is a general test, that options are applied in constructor by using the common WithName() option. Further
|
||||
// tests for options can also be done by call of "WithOption(val).apply(cfg)".
|
||||
// arrange
|
||||
const newName = "new name"
|
||||
a := testutil.NewBleTestAdaptor()
|
||||
// act
|
||||
d := NewMagnetometerDriver(a, ble.WithName(newName))
|
||||
// assert
|
||||
assert.Equal(t, newName, d.Name())
|
||||
}
|
||||
|
||||
func TestMagnetometerStartAndHalt(t *testing.T) {
|
||||
d := initTestMagnetometerDriver()
|
||||
require.NoError(t, d.Start())
|
||||
@ -46,7 +59,7 @@ func TestMagnetometerReadData(t *testing.T) {
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
a.SendTestDataToSubscriber([]byte{0x22, 0x22, 0x23, 0x23, 0x24, 0x24}, nil)
|
||||
a.SendTestDataToSubscriber([]byte{0x22, 0x22, 0x23, 0x23, 0x24, 0x24})
|
||||
|
||||
select {
|
||||
case <-sem:
|
||||
|
@ -21,11 +21,11 @@ type TemperatureDriver struct {
|
||||
}
|
||||
|
||||
// NewTemperatureDriver creates a Microbit TemperatureDriver
|
||||
func NewTemperatureDriver(a gobot.BLEConnector) *TemperatureDriver {
|
||||
func NewTemperatureDriver(a gobot.BLEConnector, opts ...ble.OptionApplier) *TemperatureDriver {
|
||||
d := &TemperatureDriver{
|
||||
Eventer: gobot.NewEventer(),
|
||||
}
|
||||
d.Driver = ble.NewDriver(a, "Microbit Temperature", d.initialize, nil)
|
||||
d.Driver = ble.NewDriver(a, "Microbit Temperature", d.initialize, nil, opts...)
|
||||
|
||||
d.AddEvent(TemperatureEvent)
|
||||
|
||||
@ -35,7 +35,7 @@ func NewTemperatureDriver(a gobot.BLEConnector) *TemperatureDriver {
|
||||
// initialize tells driver to get ready to do work
|
||||
func (d *TemperatureDriver) initialize() error {
|
||||
// subscribe to temperature notifications
|
||||
return d.Adaptor().Subscribe(temperatureChara, func(data []byte, e error) {
|
||||
return d.Adaptor().Subscribe(temperatureChara, func(data []byte) {
|
||||
var l int8
|
||||
buf := bytes.NewBuffer(data)
|
||||
val, _ := buf.ReadByte()
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"gobot.io/x/gobot/v2"
|
||||
"gobot.io/x/gobot/v2/drivers/ble"
|
||||
"gobot.io/x/gobot/v2/drivers/ble/testutil"
|
||||
)
|
||||
|
||||
@ -19,13 +20,25 @@ func initTestTemperatureDriver() *TemperatureDriver {
|
||||
return d
|
||||
}
|
||||
|
||||
func TestTemperatureDriver(t *testing.T) {
|
||||
d := initTestTemperatureDriver()
|
||||
func TestNewTemperatureDriver(t *testing.T) {
|
||||
d := NewTemperatureDriver(testutil.NewBleTestAdaptor())
|
||||
assert.IsType(t, &TemperatureDriver{}, d)
|
||||
assert.True(t, strings.HasPrefix(d.Name(), "Microbit Temperature"))
|
||||
assert.NotNil(t, d.Eventer)
|
||||
}
|
||||
|
||||
func TestNewTemperatureDriverWithName(t *testing.T) {
|
||||
// This is a general test, that options are applied in constructor by using the common WithName() option. Further
|
||||
// tests for options can also be done by call of "WithOption(val).apply(cfg)".
|
||||
// arrange
|
||||
const newName = "new name"
|
||||
a := testutil.NewBleTestAdaptor()
|
||||
// act
|
||||
d := NewTemperatureDriver(a, ble.WithName(newName))
|
||||
// assert
|
||||
assert.Equal(t, newName, d.Name())
|
||||
}
|
||||
|
||||
func TestTemperatureStartAndHalt(t *testing.T) {
|
||||
d := initTestTemperatureDriver()
|
||||
require.NoError(t, d.Start())
|
||||
@ -43,7 +56,7 @@ func TestTemperatureReadData(t *testing.T) {
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
a.SendTestDataToSubscriber([]byte{0x22}, nil)
|
||||
a.SendTestDataToSubscriber([]byte{0x22})
|
||||
|
||||
select {
|
||||
case <-sem:
|
||||
|
@ -81,7 +81,7 @@ type Pcmd struct {
|
||||
}
|
||||
|
||||
// NewDriver creates a Parrot Minidrone Driver
|
||||
func NewMinidroneDriver(a gobot.BLEConnector) *MinidroneDriver {
|
||||
func NewMinidroneDriver(a gobot.BLEConnector, opts ...ble.OptionApplier) *MinidroneDriver {
|
||||
d := &MinidroneDriver{
|
||||
Pcmd: Pcmd{
|
||||
Flag: 0,
|
||||
@ -93,7 +93,7 @@ func NewMinidroneDriver(a gobot.BLEConnector) *MinidroneDriver {
|
||||
},
|
||||
Eventer: gobot.NewEventer(),
|
||||
}
|
||||
d.Driver = ble.NewDriver(a, "Minidrone", d.initialize, d.shutdown)
|
||||
d.Driver = ble.NewDriver(a, "Minidrone", d.initialize, d.shutdown, opts...)
|
||||
|
||||
d.AddEvent(BatteryEvent)
|
||||
d.AddEvent(FlightStatusEvent)
|
||||
@ -349,14 +349,14 @@ func (d *MinidroneDriver) initialize() error {
|
||||
}
|
||||
|
||||
// subscribe to battery notifications
|
||||
if err := d.Adaptor().Subscribe(batteryChara, func(data []byte, e error) {
|
||||
if err := d.Adaptor().Subscribe(batteryChara, func(data []byte) {
|
||||
d.Publish(d.Event(BatteryEvent), data[len(data)-1])
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// subscribe to flying status notifications
|
||||
if err := d.Adaptor().Subscribe(flightStatusChara, func(data []byte, e error) {
|
||||
if err := d.Adaptor().Subscribe(flightStatusChara, func(data []byte) {
|
||||
d.processFlightStatus(data)
|
||||
}); err != nil {
|
||||
return err
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"gobot.io/x/gobot/v2"
|
||||
"gobot.io/x/gobot/v2/drivers/ble"
|
||||
"gobot.io/x/gobot/v2/drivers/ble/testutil"
|
||||
)
|
||||
|
||||
@ -27,6 +28,18 @@ func TestNewMinidroneDriver(t *testing.T) {
|
||||
assert.NotNil(t, d.Eventer)
|
||||
}
|
||||
|
||||
func TestNewMinidroneDriverWithName(t *testing.T) {
|
||||
// This is a general test, that options are applied in constructor by using the common WithName() option. Further
|
||||
// tests for options can also be done by call of "WithOption(val).apply(cfg)".
|
||||
// arrange
|
||||
const newName = "new name"
|
||||
a := testutil.NewBleTestAdaptor()
|
||||
// act
|
||||
d := NewMinidroneDriver(a, ble.WithName(newName))
|
||||
// assert
|
||||
assert.Equal(t, newName, d.Name())
|
||||
}
|
||||
|
||||
func TestMinidroneHalt(t *testing.T) {
|
||||
d := initTestMinidroneDriver()
|
||||
require.NoError(t, d.Halt())
|
||||
|
@ -18,9 +18,9 @@ type SerialPortDriver struct {
|
||||
}
|
||||
|
||||
// NewSerialPortDriver returns a new serial over Bluetooth LE connection
|
||||
func NewSerialPortDriver(a gobot.BLEConnector, rid string, tid string) *SerialPortDriver {
|
||||
func NewSerialPortDriver(a gobot.BLEConnector, rid string, tid string, opts ...OptionApplier) *SerialPortDriver {
|
||||
d := &SerialPortDriver{
|
||||
Driver: NewDriver(a, "BleSerial", nil, nil),
|
||||
Driver: NewDriver(a, "BleSerial", nil, nil, opts...),
|
||||
rid: rid,
|
||||
tid: tid,
|
||||
}
|
||||
@ -35,7 +35,7 @@ func (p *SerialPortDriver) Open() error {
|
||||
}
|
||||
|
||||
// subscribe to response notifications
|
||||
return p.Adaptor().Subscribe(p.rid, func(data []byte, e error) {
|
||||
return p.Adaptor().Subscribe(p.rid, func(data []byte) {
|
||||
p.responseMutex.Lock()
|
||||
defer p.responseMutex.Unlock()
|
||||
p.responseData = append(p.responseData, data...)
|
||||
|
@ -1,10 +1,12 @@
|
||||
package ble
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"gobot.io/x/gobot/v2"
|
||||
"gobot.io/x/gobot/v2/drivers/ble/testutil"
|
||||
@ -14,7 +16,193 @@ var _ gobot.Driver = (*SerialPortDriver)(nil)
|
||||
|
||||
var _ io.ReadWriteCloser = (*SerialPortDriver)(nil)
|
||||
|
||||
func TestBLESerialPort(t *testing.T) {
|
||||
func TestNewSerialPortDriver(t *testing.T) {
|
||||
d := NewSerialPortDriver(testutil.NewBleTestAdaptor(), "123", "456")
|
||||
assert.Equal(t, "01:02:03:0A:0B:0C", d.Address())
|
||||
}
|
||||
|
||||
func TestNewSerialPortDriverWithName(t *testing.T) {
|
||||
// This is a general test, that options are applied in constructor by using the common WithName() option. Further
|
||||
// tests for options can also be done by call of "WithOption(val).apply(cfg)".
|
||||
// arrange
|
||||
const newName = "new name"
|
||||
a := testutil.NewBleTestAdaptor()
|
||||
// act
|
||||
d := NewSerialPortDriver(a, "123", "456", WithName(newName))
|
||||
// assert
|
||||
assert.Equal(t, newName, d.Name())
|
||||
}
|
||||
|
||||
func TestSerialPortOpen(t *testing.T) {
|
||||
const receiveCharacteristicUUID = "123"
|
||||
tests := map[string]struct {
|
||||
simConnectErr bool
|
||||
simSubscribeErr bool
|
||||
wantErr string
|
||||
}{
|
||||
"open_ok": {},
|
||||
"error_connect": {
|
||||
simConnectErr: true,
|
||||
wantErr: "connect error",
|
||||
},
|
||||
"error_subscribe": {
|
||||
simSubscribeErr: true,
|
||||
wantErr: "subscribe error",
|
||||
},
|
||||
}
|
||||
for name, tc := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
// arrange
|
||||
a := testutil.NewBleTestAdaptor()
|
||||
a.SetSimulateConnectError(tc.simConnectErr)
|
||||
a.SetSimulateSubscribeError(tc.simSubscribeErr)
|
||||
d := NewSerialPortDriver(a, receiveCharacteristicUUID, "456")
|
||||
// act
|
||||
err := d.Open()
|
||||
// assert
|
||||
if tc.wantErr == "" {
|
||||
require.NoError(t, err)
|
||||
a.SendTestDataToSubscriber([]byte{3, 5, 7})
|
||||
assert.Equal(t, []byte{3, 5, 7}, d.responseData)
|
||||
assert.Equal(t, receiveCharacteristicUUID, a.SubscribeCharaUUID())
|
||||
} else {
|
||||
require.EqualError(t, err, tc.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSerialPortRead(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
availableData []byte
|
||||
readDataBuffer []byte
|
||||
wantCount int
|
||||
wantData []byte
|
||||
wantRemaining []byte
|
||||
}{
|
||||
"no_data": {
|
||||
availableData: []byte{},
|
||||
readDataBuffer: []byte{0, 0, 0},
|
||||
wantCount: 0,
|
||||
wantData: []byte{0, 0, 0},
|
||||
wantRemaining: nil,
|
||||
},
|
||||
"read_all": {
|
||||
availableData: []byte{1, 2, 3},
|
||||
readDataBuffer: []byte{0, 0, 0},
|
||||
wantCount: 3,
|
||||
wantData: []byte{1, 2, 3},
|
||||
wantRemaining: nil,
|
||||
},
|
||||
"read_smaller": {
|
||||
availableData: []byte{4, 6, 7},
|
||||
readDataBuffer: []byte{0, 0},
|
||||
wantCount: 2,
|
||||
wantData: []byte{4, 6},
|
||||
wantRemaining: []byte{7},
|
||||
},
|
||||
"read_bigger": {
|
||||
availableData: []byte{7, 8},
|
||||
readDataBuffer: []byte{0, 0, 0},
|
||||
wantCount: 2,
|
||||
wantData: []byte{7, 8, 0},
|
||||
wantRemaining: nil,
|
||||
},
|
||||
}
|
||||
for name, tc := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
// arrange
|
||||
d := NewSerialPortDriver(testutil.NewBleTestAdaptor(), "123", "456")
|
||||
d.responseData = append(d.responseData, tc.availableData...)
|
||||
// act
|
||||
gotCount, err := d.Read(tc.readDataBuffer)
|
||||
// assert
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, tc.wantCount, gotCount)
|
||||
assert.Equal(t, tc.wantData, tc.readDataBuffer)
|
||||
assert.Equal(t, tc.wantRemaining, d.responseData)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSerialPortWrite(t *testing.T) {
|
||||
const transmitCharacteristicUUID = "456"
|
||||
tests := map[string]struct {
|
||||
writeData []byte
|
||||
simError bool
|
||||
wantCount int
|
||||
wantData []byte
|
||||
wantErr string
|
||||
}{
|
||||
"write_ok": {
|
||||
writeData: []byte{1, 2, 3},
|
||||
wantCount: 3,
|
||||
wantData: []byte{1, 2, 3},
|
||||
},
|
||||
"error_write": {
|
||||
writeData: []byte{1, 2, 3},
|
||||
simError: true,
|
||||
wantCount: 3,
|
||||
wantData: []byte{1, 2, 3},
|
||||
wantErr: "write error",
|
||||
},
|
||||
}
|
||||
for name, tc := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
// arrange
|
||||
a := testutil.NewBleTestAdaptor()
|
||||
var gotUUID string
|
||||
var gotData []byte
|
||||
a.SetWriteCharacteristicTestFunc(func(cUUID string, data []byte) error {
|
||||
gotUUID = cUUID
|
||||
gotData = append(gotData, data...)
|
||||
if tc.simError {
|
||||
return fmt.Errorf("write error")
|
||||
}
|
||||
return nil
|
||||
})
|
||||
d := NewSerialPortDriver(a, "123", transmitCharacteristicUUID)
|
||||
|
||||
// act
|
||||
gotCount, err := d.Write(tc.writeData)
|
||||
// assert
|
||||
if tc.wantErr == "" {
|
||||
require.NoError(t, err)
|
||||
} else {
|
||||
require.EqualError(t, err, tc.wantErr)
|
||||
}
|
||||
assert.Equal(t, tc.wantCount, gotCount)
|
||||
assert.Equal(t, transmitCharacteristicUUID, gotUUID)
|
||||
assert.Equal(t, tc.wantData, gotData)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSerialPortClose(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
simDisconnectErr bool
|
||||
wantErr string
|
||||
}{
|
||||
"close_ok": {},
|
||||
"error_close": {
|
||||
simDisconnectErr: true,
|
||||
wantErr: "disconnect error",
|
||||
},
|
||||
}
|
||||
for name, tc := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
// arrange
|
||||
a := testutil.NewBleTestAdaptor()
|
||||
a.SetSimulateDisconnectError(tc.simDisconnectErr)
|
||||
d := NewSerialPortDriver(a, "123", "456")
|
||||
// act
|
||||
err := d.Close()
|
||||
// assert
|
||||
if tc.wantErr == "" {
|
||||
require.NoError(t, err)
|
||||
} else {
|
||||
require.EqualError(t, err, tc.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package sphero
|
||||
|
||||
import (
|
||||
"gobot.io/x/gobot/v2"
|
||||
"gobot.io/x/gobot/v2/drivers/ble"
|
||||
"gobot.io/x/gobot/v2/drivers/common/sphero"
|
||||
)
|
||||
|
||||
@ -11,8 +12,8 @@ type BB8Driver struct {
|
||||
}
|
||||
|
||||
// NewBB8Driver creates a driver for a Sphero BB-8
|
||||
func NewBB8Driver(a gobot.BLEConnector) *BB8Driver {
|
||||
return &BB8Driver{OllieDriver: newOllieBaseDriver(a, "BB8", bb8DefaultCollisionConfig())}
|
||||
func NewBB8Driver(a gobot.BLEConnector, opts ...ble.OptionApplier) *BB8Driver {
|
||||
return &BB8Driver{OllieDriver: newOllieBaseDriver(a, "BB8", bb8DefaultCollisionConfig(), opts...)}
|
||||
}
|
||||
|
||||
// bb8DefaultCollisionConfig returns a CollisionConfig with sensible collision defaults
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"gobot.io/x/gobot/v2"
|
||||
"gobot.io/x/gobot/v2/drivers/ble"
|
||||
"gobot.io/x/gobot/v2/drivers/ble/testutil"
|
||||
)
|
||||
|
||||
@ -19,3 +20,15 @@ func TestNewBB8Driver(t *testing.T) {
|
||||
assert.NotNil(t, d.OllieDriver)
|
||||
assert.Equal(t, d.defaultCollisionConfig, bb8DefaultCollisionConfig())
|
||||
}
|
||||
|
||||
func TestNewBB8DriverWithName(t *testing.T) {
|
||||
// This is a general test, that options are applied in constructor by using the common WithName() option. Further
|
||||
// tests for options can also be done by call of "WithOption(val).apply(cfg)".
|
||||
// arrange
|
||||
const newName = "new name"
|
||||
a := testutil.NewBleTestAdaptor()
|
||||
// act
|
||||
d := NewBB8Driver(a, ble.WithName(newName))
|
||||
// assert
|
||||
assert.Equal(t, newName, d.Name())
|
||||
}
|
||||
|
@ -74,17 +74,20 @@ type OllieDriver struct {
|
||||
}
|
||||
|
||||
// NewOllieDriver creates a driver for a Sphero Ollie
|
||||
func NewOllieDriver(a gobot.BLEConnector) *OllieDriver {
|
||||
return newOllieBaseDriver(a, "Ollie", ollieDefaultCollisionConfig())
|
||||
func NewOllieDriver(a gobot.BLEConnector, opts ...ble.OptionApplier) *OllieDriver {
|
||||
return newOllieBaseDriver(a, "Ollie", ollieDefaultCollisionConfig(), opts...)
|
||||
}
|
||||
|
||||
func newOllieBaseDriver(a gobot.BLEConnector, name string, dcc sphero.CollisionConfig) *OllieDriver {
|
||||
func newOllieBaseDriver(
|
||||
a gobot.BLEConnector, name string,
|
||||
dcc sphero.CollisionConfig, opts ...ble.OptionApplier,
|
||||
) *OllieDriver {
|
||||
d := &OllieDriver{
|
||||
defaultCollisionConfig: dcc,
|
||||
Eventer: gobot.NewEventer(),
|
||||
packetChannel: make(chan *packet, 1024),
|
||||
}
|
||||
d.Driver = ble.NewDriver(a, name, d.initialize, d.shutdown)
|
||||
d.Driver = ble.NewDriver(a, name, d.initialize, d.shutdown, opts...)
|
||||
|
||||
d.AddEvent(sphero.ErrorEvent)
|
||||
d.AddEvent(sphero.CollisionEvent)
|
||||
@ -283,7 +286,7 @@ func (d *OllieDriver) shutdown() error {
|
||||
}
|
||||
|
||||
// handleResponses handles responses returned from Ollie
|
||||
func (d *OllieDriver) handleResponses(data []byte, e error) {
|
||||
func (d *OllieDriver) handleResponses(data []byte) {
|
||||
// since packets can only be 20 bytes long, we have to puzzle them together
|
||||
newMessage := false
|
||||
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"gobot.io/x/gobot/v2"
|
||||
"gobot.io/x/gobot/v2/drivers/ble"
|
||||
"gobot.io/x/gobot/v2/drivers/ble/testutil"
|
||||
"gobot.io/x/gobot/v2/drivers/common/sphero"
|
||||
)
|
||||
@ -29,6 +30,18 @@ func TestNewOllieDriver(t *testing.T) {
|
||||
assert.NotNil(t, d.packetChannel)
|
||||
}
|
||||
|
||||
func TestNewOllieDriverWithName(t *testing.T) {
|
||||
// This is a general test, that options are applied in constructor by using the common WithName() option. Further
|
||||
// tests for options can also be done by call of "WithOption(val).apply(cfg)".
|
||||
// arrange
|
||||
const newName = "new name"
|
||||
a := testutil.NewBleTestAdaptor()
|
||||
// act
|
||||
d := NewOllieDriver(a, ble.WithName(newName))
|
||||
// assert
|
||||
assert.Equal(t, newName, d.Name())
|
||||
}
|
||||
|
||||
func TestOllieStartAndHalt(t *testing.T) {
|
||||
d := initTestOllieDriver()
|
||||
require.NoError(t, d.Start())
|
||||
@ -62,7 +75,7 @@ func TestLocatorData(t *testing.T) {
|
||||
d.GetLocatorData(func(p Point2D) {
|
||||
assert.Equal(t, point.y, p.Y)
|
||||
})
|
||||
d.handleResponses(packet, nil)
|
||||
d.handleResponses(packet)
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,11 +113,11 @@ func TestDataStreaming(t *testing.T) {
|
||||
c := uint16(b)
|
||||
bytes = append(bytes, byte(c))
|
||||
}
|
||||
d.handleResponses(bytes, nil)
|
||||
d.handleResponses(bytes)
|
||||
}
|
||||
|
||||
// send empty packet to indicate start of next message
|
||||
d.handleResponses([]byte{0xFF}, nil)
|
||||
d.handleResponses([]byte{0xFF})
|
||||
select {
|
||||
case <-responseChan:
|
||||
case <-time.After(10 * time.Millisecond):
|
||||
|
@ -2,6 +2,7 @@ package sphero
|
||||
|
||||
import (
|
||||
"gobot.io/x/gobot/v2"
|
||||
"gobot.io/x/gobot/v2/drivers/ble"
|
||||
"gobot.io/x/gobot/v2/drivers/common/sphero"
|
||||
)
|
||||
|
||||
@ -11,8 +12,8 @@ type SPRKPlusDriver struct {
|
||||
}
|
||||
|
||||
// NewSPRKPlusDriver creates a driver for a Sphero SPRK+
|
||||
func NewSPRKPlusDriver(a gobot.BLEConnector) *SPRKPlusDriver {
|
||||
return &SPRKPlusDriver{OllieDriver: newOllieBaseDriver(a, "SPRKPlus", sprkplusDefaultCollisionConfig())}
|
||||
func NewSPRKPlusDriver(a gobot.BLEConnector, opts ...ble.OptionApplier) *SPRKPlusDriver {
|
||||
return &SPRKPlusDriver{OllieDriver: newOllieBaseDriver(a, "SPRKPlus", sprkplusDefaultCollisionConfig(), opts...)}
|
||||
}
|
||||
|
||||
// sprkplusDefaultCollisionConfig returns a CollisionConfig with sensible collision defaults
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"gobot.io/x/gobot/v2"
|
||||
"gobot.io/x/gobot/v2/drivers/ble"
|
||||
"gobot.io/x/gobot/v2/drivers/ble/testutil"
|
||||
)
|
||||
|
||||
@ -19,3 +20,15 @@ func TestNewSPRKPlusDriver(t *testing.T) {
|
||||
assert.NotNil(t, d.OllieDriver)
|
||||
assert.Equal(t, d.defaultCollisionConfig, sprkplusDefaultCollisionConfig())
|
||||
}
|
||||
|
||||
func TestNewSPRKPlusDriverWithName(t *testing.T) {
|
||||
// This is a general test, that options are applied in constructor by using the common WithName() option. Further
|
||||
// tests for options can also be done by call of "WithOption(val).apply(cfg)".
|
||||
// arrange
|
||||
const newName = "new name"
|
||||
a := testutil.NewBleTestAdaptor()
|
||||
// act
|
||||
d := NewSPRKPlusDriver(a, ble.WithName(newName))
|
||||
// assert
|
||||
assert.Equal(t, newName, d.Name())
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"gobot.io/x/gobot/v2"
|
||||
@ -14,9 +15,13 @@ type bleTestClientAdaptor struct {
|
||||
mtx sync.Mutex
|
||||
withoutResponses bool
|
||||
|
||||
simulateConnectErr bool
|
||||
simulateSubscribeErr bool
|
||||
simulateDisconnectErr bool
|
||||
readCharacteristicFunc func(string) ([]byte, error)
|
||||
writeCharacteristicFunc func(string, []byte) error
|
||||
subscribeFunc func([]byte, error)
|
||||
subscribeFunc func([]byte)
|
||||
subscribeCharaUUID string
|
||||
}
|
||||
|
||||
func NewBleTestAdaptor() *bleTestClientAdaptor {
|
||||
@ -31,6 +36,10 @@ func NewBleTestAdaptor() *bleTestClientAdaptor {
|
||||
}
|
||||
}
|
||||
|
||||
func (t *bleTestClientAdaptor) SubscribeCharaUUID() string {
|
||||
return t.subscribeCharaUUID
|
||||
}
|
||||
|
||||
func (t *bleTestClientAdaptor) SetReadCharacteristicTestFunc(f func(cUUID string) (data []byte, err error)) {
|
||||
t.mtx.Lock()
|
||||
defer t.mtx.Unlock()
|
||||
@ -43,15 +52,40 @@ func (t *bleTestClientAdaptor) SetWriteCharacteristicTestFunc(f func(cUUID strin
|
||||
t.writeCharacteristicFunc = f
|
||||
}
|
||||
|
||||
func (t *bleTestClientAdaptor) SendTestDataToSubscriber(data []byte, err error) {
|
||||
t.mtx.Lock()
|
||||
defer t.mtx.Unlock()
|
||||
t.subscribeFunc(data, err)
|
||||
func (t *bleTestClientAdaptor) SetSimulateConnectError(val bool) {
|
||||
t.simulateConnectErr = val
|
||||
}
|
||||
|
||||
func (t *bleTestClientAdaptor) SetSimulateSubscribeError(val bool) {
|
||||
t.simulateSubscribeErr = val
|
||||
}
|
||||
|
||||
func (t *bleTestClientAdaptor) SetSimulateDisconnectError(val bool) {
|
||||
t.simulateDisconnectErr = val
|
||||
}
|
||||
|
||||
func (t *bleTestClientAdaptor) SendTestDataToSubscriber(data []byte) {
|
||||
t.mtx.Lock()
|
||||
defer t.mtx.Unlock()
|
||||
t.subscribeFunc(data)
|
||||
}
|
||||
|
||||
func (t *bleTestClientAdaptor) Connect() error {
|
||||
if t.simulateConnectErr {
|
||||
return fmt.Errorf("connect error")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *bleTestClientAdaptor) Reconnect() error { return nil }
|
||||
|
||||
func (t *bleTestClientAdaptor) Disconnect() error {
|
||||
if t.simulateDisconnectErr {
|
||||
return fmt.Errorf("disconnect error")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *bleTestClientAdaptor) Connect() error { return nil }
|
||||
func (t *bleTestClientAdaptor) Reconnect() error { return nil }
|
||||
func (t *bleTestClientAdaptor) Disconnect() error { return nil }
|
||||
func (t *bleTestClientAdaptor) Finalize() error { return nil }
|
||||
func (t *bleTestClientAdaptor) Name() string { return t.name }
|
||||
func (t *bleTestClientAdaptor) SetName(n string) { t.name = n }
|
||||
@ -70,7 +104,11 @@ func (t *bleTestClientAdaptor) WriteCharacteristic(cUUID string, data []byte) er
|
||||
return t.writeCharacteristicFunc(cUUID, data)
|
||||
}
|
||||
|
||||
func (t *bleTestClientAdaptor) Subscribe(cUUID string, f func([]byte, error)) error {
|
||||
func (t *bleTestClientAdaptor) Subscribe(cUUID string, f func(data []byte)) error {
|
||||
if t.simulateSubscribeErr {
|
||||
return fmt.Errorf("subscribe error")
|
||||
}
|
||||
t.subscribeCharaUUID = cUUID
|
||||
t.subscribeFunc = f
|
||||
return nil
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ type driver struct {
|
||||
}
|
||||
|
||||
// newDriver creates a new basic serial gobot driver.
|
||||
func newDriver(a interface{}, name string) *driver {
|
||||
func newDriver(a interface{}, name string, opts ...optionApplier) *driver {
|
||||
d := driver{
|
||||
Commander: gobot.NewCommander(),
|
||||
connection: a,
|
||||
@ -49,6 +49,10 @@ func newDriver(a interface{}, name string) *driver {
|
||||
mutex: &sync.Mutex{},
|
||||
}
|
||||
|
||||
for _, o := range opts {
|
||||
o.apply(d.driverCfg)
|
||||
}
|
||||
|
||||
return &d
|
||||
}
|
||||
|
||||
@ -63,7 +67,7 @@ func (d *driver) Name() string {
|
||||
}
|
||||
|
||||
// SetName sets the name of the driver.
|
||||
// Deprecated: Please use option [aio.WithName] instead.
|
||||
// Deprecated: Please use option [serial.WithName] instead.
|
||||
func (d *driver) SetName(name string) {
|
||||
WithName(name).apply(d.driverCfg)
|
||||
}
|
||||
|
@ -36,6 +36,21 @@ func Test_newDriver(t *testing.T) {
|
||||
assert.NotNil(t, d.mutex)
|
||||
}
|
||||
|
||||
func Test_newDriverWithName(t *testing.T) {
|
||||
// This is a general test, that options are applied in constructor by using the common WithName() option. Further
|
||||
// tests for options can also be done by call of "WithOption(val).apply(cfg)".
|
||||
// arrange
|
||||
const (
|
||||
name = "mybot"
|
||||
newName = "overwrite mybot"
|
||||
)
|
||||
a := newSerialTestAdaptor()
|
||||
// act
|
||||
d := newDriver(a, name, WithName(newName))
|
||||
// assert
|
||||
assert.Equal(t, newName, d.Name())
|
||||
}
|
||||
|
||||
func Test_applyWithName(t *testing.T) {
|
||||
// arrange
|
||||
const name = "mybot"
|
||||
|
@ -51,9 +51,9 @@ type SpheroDriver struct {
|
||||
// "SetStabilization" - See SpheroDriver.SetStabilization
|
||||
// "SetDataStreaming" - See SpheroDriver.SetDataStreaming
|
||||
// "SetRotationRate" - See SpheroDriver.SetRotationRate
|
||||
func NewSpheroDriver(a spheroSerialAdaptor) *SpheroDriver {
|
||||
func NewSpheroDriver(a spheroSerialAdaptor, opts ...optionApplier) *SpheroDriver {
|
||||
d := &SpheroDriver{
|
||||
driver: newDriver(a, "Sphero"),
|
||||
driver: newDriver(a, "Sphero", opts...),
|
||||
Eventer: gobot.NewEventer(),
|
||||
packetChannel: make(chan *packet, 1024),
|
||||
responseChannel: make(chan []uint8, 1024),
|
||||
|
@ -27,6 +27,18 @@ func TestNewSpheroDriver(t *testing.T) {
|
||||
assert.NotNil(t, d.Eventer)
|
||||
}
|
||||
|
||||
func TestNewSpheroDriverWithName(t *testing.T) {
|
||||
// This is a general test, that options are applied in constructor by using the common WithName() option. Further
|
||||
// tests for options can also be done by call of "WithOption(val).apply(cfg)".
|
||||
// arrange
|
||||
const newName = "new name"
|
||||
a := newSerialTestAdaptor()
|
||||
// act
|
||||
d := NewSpheroDriver(a, WithName(newName))
|
||||
// assert
|
||||
assert.Equal(t, newName, d.Name())
|
||||
}
|
||||
|
||||
func TestSpheroCommands(t *testing.T) {
|
||||
d := initTestSpheroDriver()
|
||||
var ret interface{}
|
||||
|
@ -31,7 +31,11 @@ func main() {
|
||||
|
||||
work := func() {
|
||||
gobot.Every(5*time.Second, func() {
|
||||
fmt.Println("Battery level:", battery.GetBatteryLevel())
|
||||
level, err := battery.GetBatteryLevel()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println("Battery level:", level)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -29,11 +29,35 @@ func main() {
|
||||
info := ble.NewDeviceInformationDriver(bleAdaptor)
|
||||
|
||||
work := func() {
|
||||
fmt.Println("Model number:", info.GetModelNumber())
|
||||
fmt.Println("Firmware rev:", info.GetFirmwareRevision())
|
||||
fmt.Println("Hardware rev:", info.GetHardwareRevision())
|
||||
fmt.Println("Manufacturer name:", info.GetManufacturerName())
|
||||
fmt.Println("PnPId:", info.GetPnPId())
|
||||
modelNo, err := info.GetModelNumber()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println("Model number:", modelNo)
|
||||
|
||||
fwRev, err := info.GetFirmwareRevision()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println("Firmware rev:", fwRev)
|
||||
|
||||
hwRev, err := info.GetHardwareRevision()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println("Hardware rev:", hwRev)
|
||||
|
||||
manuName, err := info.GetManufacturerName()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println("Manufacturer name:", manuName)
|
||||
|
||||
pid, err := info.GetPnPId()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println("PnPId:", pid)
|
||||
}
|
||||
|
||||
robot := gobot.NewRobot("bleBot",
|
||||
|
@ -29,8 +29,17 @@ func main() {
|
||||
access := ble.NewGenericAccessDriver(bleAdaptor)
|
||||
|
||||
work := func() {
|
||||
fmt.Println("Device name:", access.GetDeviceName())
|
||||
fmt.Println("Appearance:", access.GetAppearance())
|
||||
devName, err := access.GetDeviceName()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println("Device name:", devName)
|
||||
|
||||
appearance, err := access.GetAppearance()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println("Appearance:", appearance)
|
||||
}
|
||||
|
||||
robot := gobot.NewRobot("bleBot",
|
||||
|
@ -30,8 +30,17 @@ func NewSwarmBot(port string) *gobot.Robot {
|
||||
access := ble.NewGenericAccessDriver(bleAdaptor)
|
||||
|
||||
work := func() {
|
||||
fmt.Println("Device name:", access.GetDeviceName())
|
||||
fmt.Println("Appearance:", access.GetAppearance())
|
||||
devName, err := access.GetDeviceName()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println("Device name:", devName)
|
||||
|
||||
appearance, err := access.GetAppearance()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println("Appearance:", appearance)
|
||||
}
|
||||
|
||||
robot := gobot.NewRobot("bot "+port,
|
||||
|
@ -30,11 +30,35 @@ func NewSwarmBot(port string) *gobot.Robot {
|
||||
info := ble.NewDeviceInformationDriver(bleAdaptor)
|
||||
|
||||
work := func() {
|
||||
fmt.Println("Model number:", info.GetModelNumber())
|
||||
fmt.Println("Firmware rev:", info.GetFirmwareRevision())
|
||||
fmt.Println("Hardware rev:", info.GetHardwareRevision())
|
||||
fmt.Println("Manufacturer name:", info.GetManufacturerName())
|
||||
fmt.Println("PnPId:", info.GetPnPId())
|
||||
modelNo, err := info.GetModelNumber()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println("Model number:", modelNo)
|
||||
|
||||
fwRev, err := info.GetFirmwareRevision()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println("Firmware rev:", fwRev)
|
||||
|
||||
hwRev, err := info.GetHardwareRevision()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println("Hardware rev:", hwRev)
|
||||
|
||||
manuName, err := info.GetManufacturerName()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println("Manufacturer name:", manuName)
|
||||
|
||||
pid, err := info.GetPnPId()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println("PnPId:", pid)
|
||||
}
|
||||
|
||||
robot := gobot.NewRobot("bot "+port,
|
||||
|
@ -35,8 +35,7 @@ func main() {
|
||||
for _, port := range spheros {
|
||||
spheroAdaptor := serialport.NewAdaptor(port)
|
||||
|
||||
cell := serial.NewSpheroDriver(spheroAdaptor)
|
||||
cell.SetName("Sphero" + port)
|
||||
cell := serial.NewSpheroDriver(spheroAdaptor, serial.WithName("Sphero"+port))
|
||||
|
||||
work := func() {
|
||||
conway := new(conway)
|
||||
|
@ -19,8 +19,7 @@ import (
|
||||
|
||||
func NewSwarmBot(port string) *gobot.Robot {
|
||||
spheroAdaptor := serialport.NewAdaptor(port)
|
||||
spheroDriver := serial.NewSpheroDriver(spheroAdaptor)
|
||||
spheroDriver.SetName("Sphero" + port)
|
||||
spheroDriver := serial.NewSpheroDriver(spheroAdaptor, serial.WithName("Sphero"+port))
|
||||
|
||||
work := func() {
|
||||
spheroDriver.Stop()
|
||||
|
@ -71,7 +71,11 @@ func main() {
|
||||
|
||||
work := func() {
|
||||
gobot.Every(5*time.Second, func() {
|
||||
fmt.Println("Battery level:", battery.GetBatteryLevel())
|
||||
level, err := battery.GetBatteryLevel()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println("Battery level:", level)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -181,7 +181,7 @@ func (a *Adaptor) WriteCharacteristic(cUUID string, data []byte) error {
|
||||
|
||||
// Subscribe subscribes to notifications from the BLE device for the
|
||||
// requested service and characteristic
|
||||
func (a *Adaptor) Subscribe(cUUID string, f func([]byte, error)) error {
|
||||
func (a *Adaptor) Subscribe(cUUID string, f func([]byte)) error {
|
||||
if !a.connected {
|
||||
return fmt.Errorf("Cannot subscribe to BLE device until connected")
|
||||
}
|
||||
@ -189,10 +189,7 @@ func (a *Adaptor) Subscribe(cUUID string, f func([]byte, error)) error {
|
||||
cUUID = convertUUID(cUUID)
|
||||
|
||||
if char, ok := a.characteristics[cUUID]; ok {
|
||||
fn := func(d []byte) {
|
||||
f(d, nil)
|
||||
}
|
||||
return char.EnableNotifications(fn)
|
||||
return char.EnableNotifications(f)
|
||||
}
|
||||
|
||||
return fmt.Errorf("Unknown characteristic: %s", cUUID)
|
||||
|
@ -46,7 +46,7 @@ func NewNullReadWriteCloser() *nullReadWriteCloser {
|
||||
}
|
||||
}
|
||||
|
||||
func initTestSpheroAdaptor() (*Adaptor, *nullReadWriteCloser) {
|
||||
func initTestAdaptor() (*Adaptor, *nullReadWriteCloser) {
|
||||
a := NewAdaptor("/dev/null")
|
||||
rwc := NewNullReadWriteCloser()
|
||||
|
||||
@ -56,34 +56,34 @@ func initTestSpheroAdaptor() (*Adaptor, *nullReadWriteCloser) {
|
||||
return a, rwc
|
||||
}
|
||||
|
||||
func TestSpheroAdaptorName(t *testing.T) {
|
||||
a, _ := initTestSpheroAdaptor()
|
||||
func TestNewAdaptor(t *testing.T) {
|
||||
a := NewAdaptor("/dev/null")
|
||||
assert.True(t, strings.HasPrefix(a.Name(), "Serial"))
|
||||
assert.Equal(t, "/dev/null", a.Port())
|
||||
}
|
||||
|
||||
func TestName(t *testing.T) {
|
||||
a, _ := initTestAdaptor()
|
||||
assert.True(t, strings.HasPrefix(a.Name(), "Serial"))
|
||||
a.SetName("NewName")
|
||||
assert.Equal(t, "NewName", a.Name())
|
||||
}
|
||||
|
||||
func TestSpheroAdaptor(t *testing.T) {
|
||||
a, _ := initTestSpheroAdaptor()
|
||||
assert.True(t, strings.HasPrefix(a.Name(), "Serial"))
|
||||
assert.Equal(t, "/dev/null", a.Port())
|
||||
}
|
||||
|
||||
func TestSpheroAdaptorReconnect(t *testing.T) {
|
||||
a, _ := initTestSpheroAdaptor()
|
||||
_ = a.Connect()
|
||||
func TestReconnect(t *testing.T) {
|
||||
a, _ := initTestAdaptor()
|
||||
require.NoError(t, a.Connect())
|
||||
assert.True(t, a.connected)
|
||||
_ = a.Reconnect()
|
||||
require.NoError(t, a.Reconnect())
|
||||
assert.True(t, a.connected)
|
||||
_ = a.Disconnect()
|
||||
require.NoError(t, a.Disconnect())
|
||||
assert.False(t, a.connected)
|
||||
_ = a.Reconnect()
|
||||
require.NoError(t, a.Reconnect())
|
||||
assert.True(t, a.connected)
|
||||
}
|
||||
|
||||
func TestSpheroAdaptorFinalize(t *testing.T) {
|
||||
a, rwc := initTestSpheroAdaptor()
|
||||
_ = a.Connect()
|
||||
func TestFinalize(t *testing.T) {
|
||||
a, rwc := initTestAdaptor()
|
||||
require.NoError(t, a.Connect())
|
||||
require.NoError(t, a.Finalize())
|
||||
|
||||
rwc.testAdaptorClose = func() error {
|
||||
@ -94,8 +94,8 @@ func TestSpheroAdaptorFinalize(t *testing.T) {
|
||||
require.ErrorContains(t, a.Finalize(), "close error")
|
||||
}
|
||||
|
||||
func TestSpheroAdaptorConnect(t *testing.T) {
|
||||
a, _ := initTestSpheroAdaptor()
|
||||
func TestConnect(t *testing.T) {
|
||||
a, _ := initTestAdaptor()
|
||||
require.NoError(t, a.Connect())
|
||||
|
||||
a.connect = func(string) (io.ReadWriteCloser, error) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user