From 7c63f215934a2a49458b8896033fb89aedfd81df Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Thu, 20 Nov 2014 18:00:32 -0800 Subject: [PATCH 01/24] Completely overhaul driver and adaptor interfaces --- adaptor.go | 85 +------------------------- adaptor_test.go | 18 ------ commander.go | 39 ++++++++++++ connection.go | 2 +- device.go | 2 +- driver.go | 158 +----------------------------------------------- driver_test.go | 57 ----------------- eventer.go | 33 ++++++++++ gobot.go | 37 +++--------- loopback.go | 20 ++++++ pinger.go | 40 ++++++++++++ robot.go | 21 ++----- test_helper.go | 113 ++++++++-------------------------- utils.go | 56 +++++++++++++++-- 14 files changed, 225 insertions(+), 456 deletions(-) delete mode 100644 adaptor_test.go create mode 100644 commander.go delete mode 100644 driver_test.go create mode 100644 eventer.go create mode 100644 loopback.go create mode 100644 pinger.go diff --git a/adaptor.go b/adaptor.go index 60c14e47f..d944265ad 100644 --- a/adaptor.go +++ b/adaptor.go @@ -1,89 +1,10 @@ package gobot -import "fmt" - -type Adaptor struct { - name string - port string - connected bool - adaptorType string -} - -// AdaptorInterface defines behaviour expected for a Gobot Adaptor -type AdaptorInterface interface { +type Adaptor interface { Finalize() []error Connect() []error - Port() string Name() string - Type() string - Connected() bool - SetConnected(bool) - SetName(string) - SetPort(string) + Port() string + String() string ToJSON() *JSONConnection } - -// NewAdaptor returns a new Gobot Adaptor -func NewAdaptor(name string, adaptorType string, v ...interface{}) *Adaptor { - if name == "" { - name = fmt.Sprintf("%X", Rand(int(^uint(0)>>1))) - } - - a := &Adaptor{ - adaptorType: adaptorType, - name: name, - port: "", - } - - for i := range v { - switch v[i].(type) { - case string: - a.port = v[i].(string) - } - } - - return a -} - -// Port returns adaptor port -func (a *Adaptor) Port() string { - return a.port -} - -// SetPort sets adaptor port -func (a *Adaptor) SetPort(s string) { - a.port = s -} - -// Name returns adaptor name -func (a *Adaptor) Name() string { - return a.name -} - -// SetName sets adaptor name -func (a *Adaptor) SetName(s string) { - a.name = s -} - -// Type returns adaptor type -func (a *Adaptor) Type() string { - return a.adaptorType -} - -// Connected returns true if adaptor is connected -func (a *Adaptor) Connected() bool { - return a.connected -} - -// SetConnected sets adaptor as connected/disconnected -func (a *Adaptor) SetConnected(b bool) { - a.connected = b -} - -// ToJSON returns a json representation of adaptor -func (a *Adaptor) ToJSON() *JSONConnection { - return &JSONConnection{ - Name: a.Name(), - Adaptor: a.Type(), - } -} diff --git a/adaptor_test.go b/adaptor_test.go deleted file mode 100644 index 22ca59ea6..000000000 --- a/adaptor_test.go +++ /dev/null @@ -1,18 +0,0 @@ -package gobot - -import "testing" - -func TestAdaptor(t *testing.T) { - a := NewAdaptor("", "testBot", "/dev/null") - Refute(t, a.Name(), "") - a.SetPort("/dev/null1") - Assert(t, a.Port(), "/dev/null1") - a.SetName("myAdaptor") - Assert(t, a.Name(), "myAdaptor") - - a.SetConnected(true) - Assert(t, a.Connected(), true) - - a.SetConnected(false) - Assert(t, a.Connected(), false) -} diff --git a/commander.go b/commander.go new file mode 100644 index 000000000..28487fb0f --- /dev/null +++ b/commander.go @@ -0,0 +1,39 @@ +package gobot + +import "errors" + +type commander struct { + commands map[string]func(map[string]interface{}) interface{} +} + +type Commander interface { + Command(string) (command func(map[string]interface{}) interface{}, err error) + Commands() (commands map[string]func(map[string]interface{}) interface{}) + AddCommand(name string, command func(map[string]interface{}) interface{}) +} + +func NewCommander() Commander { + return &commander{ + commands: make(map[string]func(map[string]interface{}) interface{}), + } +} + +// Command retrieves a command by name +func (c *commander) Command(name string) (command func(map[string]interface{}) interface{}, err error) { + command, ok := c.commands[name] + if ok { + return + } + err = errors.New("Unknown Command") + return +} + +// Commands returns a map of driver commands +func (c *commander) Commands() map[string]func(map[string]interface{}) interface{} { + return c.commands +} + +// AddCommand links specified command name to `f` +func (c *commander) AddCommand(name string, command func(map[string]interface{}) interface{}) { + c.commands[name] = command +} diff --git a/connection.go b/connection.go index 59183e0bf..b5620af80 100644 --- a/connection.go +++ b/connection.go @@ -12,7 +12,7 @@ type JSONConnection struct { Adaptor string `json:"adaptor"` } -type Connection AdaptorInterface +type Connection Adaptor type connections []Connection diff --git a/device.go b/device.go index ef738b6e2..bf5986cf8 100644 --- a/device.go +++ b/device.go @@ -14,7 +14,7 @@ type JSONDevice struct { Commands []string `json:"commands"` } -type Device DriverInterface +type Device Driver type devices []Device diff --git a/driver.go b/driver.go index 1b355ea7a..bb655f221 100644 --- a/driver.go +++ b/driver.go @@ -1,163 +1,11 @@ package gobot -import ( - "fmt" - "time" -) - -// DriverInterface defines Driver expected behaviour -type DriverInterface interface { +type Driver interface { Start() []error Halt() []error - Adaptor() AdaptorInterface - SetInterval(time.Duration) - Interval() time.Duration - SetName(string) Name() string Pin() string - SetPin(string) - Command(string) func(map[string]interface{}) interface{} - Commands() map[string]func(map[string]interface{}) interface{} - AddCommand(string, func(map[string]interface{}) interface{}) - Events() map[string]*Event - Event(string) *Event - AddEvent(string) - Type() string + String() string + Connection() Connection ToJSON() *JSONDevice } - -type Driver struct { - adaptor AdaptorInterface - interval time.Duration - pin string - name string - commands map[string]func(map[string]interface{}) interface{} - events map[string]*Event - driverType string -} - -// NewDriver returns a Driver with specified parameters -// and sets driver pin, adaptor and interval -func NewDriver(name string, driverType string, v ...interface{}) *Driver { - if name == "" { - name = fmt.Sprintf("%X", Rand(int(^uint(0)>>1))) - } - - d := &Driver{ - driverType: driverType, - name: name, - interval: 10 * time.Millisecond, - commands: make(map[string]func(map[string]interface{}) interface{}), - events: make(map[string]*Event), - adaptor: nil, - pin: "", - } - - for i := range v { - switch v[i].(type) { - case string: - d.pin = v[i].(string) - case AdaptorInterface: - d.adaptor = v[i].(AdaptorInterface) - case time.Duration: - d.interval = v[i].(time.Duration) - } - } - - return d -} - -// Adaptor returns driver adaptor -func (d *Driver) Adaptor() AdaptorInterface { - return d.adaptor -} - -// SetInterval defines driver interval duration. -func (d *Driver) SetInterval(t time.Duration) { - d.interval = t -} - -// Interval current driver interval duration -func (d *Driver) Interval() time.Duration { - return d.interval -} - -// SetName sets driver name. -func (d *Driver) SetName(s string) { - d.name = s -} - -// Name returns driver name. -func (d *Driver) Name() string { - return d.name -} - -// Pin returns driver pin -func (d *Driver) Pin() string { - return d.pin -} - -// SetPin defines driver pin -func (d *Driver) SetPin(pin string) { - d.pin = pin -} - -// Type returns driver type -func (d *Driver) Type() string { - return d.driverType -} - -// Events returns driver events map -func (d *Driver) Events() map[string]*Event { - return d.events -} - -// Event returns an event by name if exists -func (d *Driver) Event(name string) *Event { - e, ok := d.events[name] - if ok { - return e - } else { - panic(fmt.Sprintf("Unknown Driver Event: %v", name)) - } -} - -// AddEvents adds a new event by name -func (d *Driver) AddEvent(name string) { - d.events[name] = NewEvent() -} - -// Command retrieves a command by name -func (d *Driver) Command(name string) func(map[string]interface{}) interface{} { - return d.commands[name] -} - -// Commands returns a map of driver commands -func (d *Driver) Commands() map[string]func(map[string]interface{}) interface{} { - return d.commands -} - -// AddCommand links specified command name to `f` -func (d *Driver) AddCommand(name string, f func(map[string]interface{}) interface{}) { - d.commands[name] = f -} - -// ToJSON returns JSON Driver represnentation including adaptor and commands -func (d *Driver) ToJSON() *JSONDevice { - jsonDevice := &JSONDevice{ - Name: d.Name(), - Driver: d.Type(), - Commands: []string{}, - Connection: "", - } - - if d.Adaptor() != nil { - jsonDevice.Connection = d.Adaptor().ToJSON().Name - } - - for command := range d.Commands() { - jsonDevice.Commands = append(jsonDevice.Commands, command) - } - - return jsonDevice -} diff --git a/driver_test.go b/driver_test.go deleted file mode 100644 index bc0c72844..000000000 --- a/driver_test.go +++ /dev/null @@ -1,57 +0,0 @@ -package gobot - -import ( - "fmt" - "testing" - "time" -) - -func TestDriver(t *testing.T) { - a := NewTestAdaptor("testAdaptor") - d := NewDriver("", - "testDriver", - a, - "1", - 5*time.Second, - ) - - Refute(t, d.Name(), "") - Assert(t, d.Type(), "testDriver") - Assert(t, d.Interval(), 5*time.Second) - Assert(t, d.Pin(), "1") - Assert(t, d.Adaptor(), a) - - d.SetPin("10") - Assert(t, d.Pin(), "10") - - d.SetName("myDriver") - Assert(t, d.Name(), "myDriver") - - d.SetInterval(100 * time.Second) - Assert(t, d.Interval(), 100*time.Second) - - Assert(t, len(d.Commands()), 0) - d.AddCommand("cmd1", func(params map[string]interface{}) interface{} { - return fmt.Sprintf("hello from %v", params["name"]) - }) - Assert(t, len(d.Commands()), 1) - Assert(t, - d.Command("cmd1")(map[string]interface{}{"name": d.Name()}).(string), - "hello from "+d.Name(), - ) - - Assert(t, len(d.Events()), 0) - d.AddEvent("event1") - Assert(t, len(d.Events()), 1) - Refute(t, d.Event("event1"), nil) - - defer func() { - r := recover() - if r != nil { - Assert(t, "Unknown Driver Event: event2", r) - } else { - t.Errorf("Did not return Unknown Event error") - } - }() - d.Event("event2") -} diff --git a/eventer.go b/eventer.go new file mode 100644 index 000000000..e15485c9a --- /dev/null +++ b/eventer.go @@ -0,0 +1,33 @@ +package gobot + +type eventer struct { + events map[string]*Event +} + +type Eventer interface { + Events() (events map[string]*Event) + Event(name string) (event *Event) + AddEvent(name string) +} + +func NewEventer() Eventer { + return &eventer{ + events: make(map[string]*Event), + } +} + +// Events returns driver events map +func (e *eventer) Events() map[string]*Event { + return e.events +} + +// Event returns an event by name if exists +func (e *eventer) Event(name string) (event *Event) { + event, _ = e.events[name] + return +} + +// AddEvents adds a new event by name +func (e *eventer) AddEvent(name string) { + e.events[name] = NewEvent() +} diff --git a/gobot.go b/gobot.go index db0af5608..0a039addc 100644 --- a/gobot.go +++ b/gobot.go @@ -14,47 +14,24 @@ type JSONGobot struct { // Gobot is a container composed of one or more robots type Gobot struct { - robots *robots - commands map[string]func(map[string]interface{}) interface{} - trap func(chan os.Signal) + robots *robots + trap func(chan os.Signal) + Commander + Eventer } // NewGobot instantiates a new Gobot func NewGobot() *Gobot { return &Gobot{ - robots: &robots{}, - commands: make(map[string]func(map[string]interface{}) interface{}), + robots: &robots{}, trap: func(c chan os.Signal) { signal.Notify(c, os.Interrupt) }, + Commander: NewCommander(), + Eventer: NewEventer(), } } -/* -AddCommand creates a new command and adds it to the Gobot. This command -will be available via HTTP using '/commands/name' - -Example: - gbot.AddCommand( 'rollover', func( params map[string]interface{}) interface{} { - fmt.Println( "Rolling over - Stand by...") - }) - - With the api package setup, you can now get your Gobot to rollover using: http://localhost:3000/commands/rollover -*/ -func (g *Gobot) AddCommand(name string, f func(map[string]interface{}) interface{}) { - g.commands[name] = f -} - -// Commands lists all available commands on this Gobot instance. -func (g *Gobot) Commands() map[string]func(map[string]interface{}) interface{} { - return g.commands -} - -// Command fetch the associated command using the given command name -func (g *Gobot) Command(name string) func(map[string]interface{}) interface{} { - return g.commands[name] -} - // Start runs the main Gobot event loop func (g *Gobot) Start() (errs []error) { if rerrs := g.robots.Start(); len(rerrs) > 0 { diff --git a/loopback.go b/loopback.go new file mode 100644 index 000000000..e44a2fce0 --- /dev/null +++ b/loopback.go @@ -0,0 +1,20 @@ +package gobot + +type loopbackAdaptor struct { + name string + port string +} + +func (t *loopbackAdaptor) Finalize() (errs []error) { return } +func (t *loopbackAdaptor) Connect() (errs []error) { return } +func (t *loopbackAdaptor) Name() string { return t.name } +func (t *loopbackAdaptor) Port() string { return t.port } +func (t *loopbackAdaptor) String() string { return "loopbackAdaptor" } +func (t *loopbackAdaptor) ToJSON() *JSONConnection { return &JSONConnection{} } + +func NewLoopbackAdaptor(name string) *loopbackAdaptor { + return &loopbackAdaptor{ + name: name, + port: "", + } +} diff --git a/pinger.go b/pinger.go new file mode 100644 index 000000000..f5e3d9e09 --- /dev/null +++ b/pinger.go @@ -0,0 +1,40 @@ +package gobot + +type pingDriver struct { + name string + pin string + connection Connection + Eventer + Commander +} + +func (t *pingDriver) Start() (errs []error) { return } +func (t *pingDriver) Halt() (errs []error) { return } +func (t *pingDriver) Name() string { return t.name } +func (t *pingDriver) Pin() string { return t.pin } +func (t *pingDriver) String() string { return "pingDriver" } +func (t *pingDriver) Connection() Connection { return t.connection } +func (t *pingDriver) ToJSON() *JSONDevice { return &JSONDevice{} } + +func NewPingDriver(adaptor *loopbackAdaptor, name string) *pingDriver { + t := &pingDriver{ + name: name, + connection: adaptor, + pin: "", + Eventer: NewEventer(), + Commander: NewCommander(), + } + + t.AddEvent("ping") + + t.AddCommand("ping", func(params map[string]interface{}) interface{} { + return t.Ping() + }) + + return t +} + +func (t *pingDriver) Ping() string { + Publish(t.Event("ping"), "ping") + return "pong" +} diff --git a/robot.go b/robot.go index 143bb3c28..11517003c 100644 --- a/robot.go +++ b/robot.go @@ -19,10 +19,11 @@ type JSONRobot struct { // a user can specificy custom commands to control a robot remotely. type Robot struct { Name string - commands map[string]func(map[string]interface{}) interface{} Work func() connections *connections devices *devices + Commander + Eventer } type robots []*Robot @@ -62,10 +63,11 @@ func NewRobot(name string, v ...interface{}) *Robot { r := &Robot{ Name: name, - commands: make(map[string]func(map[string]interface{}) interface{}), connections: &connections{}, devices: &devices{}, Work: nil, + Eventer: NewEventer(), + Commander: NewCommander(), } log.Println("Initializing Robot", r.Name, "...") @@ -94,21 +96,6 @@ func NewRobot(name string, v ...interface{}) *Robot { return r } -// AddCommand setup a new command that we be made available via the REST api. -func (r *Robot) AddCommand(name string, f func(map[string]interface{}) interface{}) { - r.commands[name] = f -} - -// Commands lists out all available commands on this robot. -func (r *Robot) Commands() map[string]func(map[string]interface{}) interface{} { - return r.commands -} - -// Command fetch a named command on this robot. -func (r *Robot) Command(name string) func(map[string]interface{}) interface{} { - return r.commands[name] -} - // Start a robot instance and runs it's work function if any. You should not // need to manually start a robot if already part of a Gobot application as the // robot will be automatically started for you. diff --git a/test_helper.go b/test_helper.go index 67935c3a9..fc7608258 100644 --- a/test_helper.go +++ b/test_helper.go @@ -1,32 +1,6 @@ package gobot -import ( - "fmt" - "reflect" - "runtime" - "strings" - "testing" - "time" -) - -func logFailure(t *testing.T, message string) { - _, file, line, _ := runtime.Caller(2) - s := strings.Split(file, "/") - t.Errorf("%v:%v: %v", s[len(s)-1], line, message) -} -func Assert(t *testing.T, a interface{}, b interface{}) { - if !reflect.DeepEqual(a, b) { - logFailure(t, fmt.Sprintf("%v - \"%v\", should equal, %v - \"%v\"", - a, reflect.TypeOf(a), b, reflect.TypeOf(b))) - } -} - -func Refute(t *testing.T, a interface{}, b interface{}) { - if reflect.DeepEqual(a, b) { - logFailure(t, fmt.Sprintf("%v - \"%v\", should not equal, %v - \"%v\"", - a, reflect.TypeOf(a), b, reflect.TypeOf(b))) - } -} +import "fmt" type testStruct struct { i int @@ -59,21 +33,26 @@ func (NullReadWriteCloser) Close() error { } type testDriver struct { - Driver + name string + pin string + connection Connection + Commander } -func (t *testDriver) Start() (errs []error) { return } -func (t *testDriver) Halt() (errs []error) { return } +func (t *testDriver) Start() (errs []error) { return } +func (t *testDriver) Halt() (errs []error) { return } +func (t *testDriver) Name() string { return t.name } +func (t *testDriver) Pin() string { return t.pin } +func (t *testDriver) String() string { return "testDriver" } +func (t *testDriver) Connection() Connection { return t.connection } +func (t *testDriver) ToJSON() *JSONDevice { return &JSONDevice{} } func NewTestDriver(name string, adaptor *testAdaptor) *testDriver { t := &testDriver{ - Driver: *NewDriver( - name, - "TestDriver", - adaptor, - "1", - 100*time.Millisecond, - ), + name: name, + connection: adaptor, + pin: "1", + Commander: NewCommander(), } t.AddCommand("TestDriverCommand", func(params map[string]interface{}) interface{} { @@ -90,19 +69,21 @@ func NewTestDriver(name string, adaptor *testAdaptor) *testDriver { } type testAdaptor struct { - Adaptor + name string + port string } func (t *testAdaptor) Finalize() (errs []error) { return } func (t *testAdaptor) Connect() (errs []error) { return } +func (t *testAdaptor) Name() string { return t.name } +func (t *testAdaptor) Port() string { return t.port } +func (t *testAdaptor) String() string { return "testAdaptor" } +func (t *testAdaptor) ToJSON() *JSONConnection { return &JSONConnection{} } func NewTestAdaptor(name string) *testAdaptor { return &testAdaptor{ - Adaptor: *NewAdaptor( - name, - "TestAdaptor", - "/dev/null", - ), + name: name, + port: "/dev/null", } } @@ -126,49 +107,3 @@ func NewTestRobot(name string) *Robot { }) return r } - -type loopbackAdaptor struct { - Adaptor -} - -func (t *loopbackAdaptor) Finalize() (errs []error) { return } -func (t *loopbackAdaptor) Connect() (errs []error) { return } - -func NewLoopbackAdaptor(name string) *loopbackAdaptor { - return &loopbackAdaptor{ - Adaptor: *NewAdaptor( - name, - "Loopback", - ), - } -} - -type pingDriver struct { - Driver -} - -func (t *pingDriver) Start() (errs []error) { return } -func (t *pingDriver) Halt() (errs []error) { return } - -func NewPingDriver(adaptor *loopbackAdaptor, name string) *pingDriver { - t := &pingDriver{ - Driver: *NewDriver( - name, - "Ping", - adaptor, - ), - } - - t.AddEvent("ping") - - t.AddCommand("ping", func(params map[string]interface{}) interface{} { - return t.Ping() - }) - - return t -} - -func (t *pingDriver) Ping() string { - Publish(t.Event("ping"), "ping") - return "pong" -} diff --git a/utils.go b/utils.go index 631c605d2..a5249d245 100644 --- a/utils.go +++ b/utils.go @@ -2,11 +2,46 @@ package gobot import ( "crypto/rand" + "errors" + "fmt" + "log" "math" "math/big" + "reflect" + "runtime" + "strings" + "testing" "time" ) +var eventError = func(e *Event) (err error) { + if e == nil { + err = errors.New("Event does not exist") + log.Println(err.Error()) + return + } + return +} + +func logFailure(t *testing.T, message string) { + _, file, line, _ := runtime.Caller(2) + s := strings.Split(file, "/") + t.Errorf("%v:%v: %v", s[len(s)-1], line, message) +} +func Assert(t *testing.T, a interface{}, b interface{}) { + if !reflect.DeepEqual(a, b) { + logFailure(t, fmt.Sprintf("%v - \"%v\", should equal, %v - \"%v\"", + a, reflect.TypeOf(a), b, reflect.TypeOf(b))) + } +} + +func Refute(t *testing.T, a interface{}, b interface{}) { + if reflect.DeepEqual(a, b) { + logFailure(t, fmt.Sprintf("%v - \"%v\", should not equal, %v - \"%v\"", + a, reflect.TypeOf(a), b, reflect.TypeOf(b))) + } +} + // Every triggers f every `t` time until the end of days. func Every(t time.Duration, f func()) { c := time.Tick(t) @@ -25,19 +60,28 @@ func After(t time.Duration, f func()) { } // Publish emits an event by writting value -func Publish(e *Event, val interface{}) { - e.Write(val) +func Publish(e *Event, val interface{}) (err error) { + if err = eventError(e); err == nil { + e.Write(val) + } + return } // On adds `f` to callbacks that are executed on specified event -func On(e *Event, f func(s interface{})) { - e.Callbacks = append(e.Callbacks, callback{f, false}) +func On(e *Event, f func(s interface{})) (err error) { + if err = eventError(e); err == nil { + e.Callbacks = append(e.Callbacks, callback{f, false}) + } + return } // Once adds `f` to callbacks that are executed on specified event // and sets flag to be called only once -func Once(e *Event, f func(s interface{})) { - e.Callbacks = append(e.Callbacks, callback{f, true}) +func Once(e *Event, f func(s interface{})) (err error) { + if err = eventError(e); err == nil { + e.Callbacks = append(e.Callbacks, callback{f, true}) + } + return } // Rand generates random int lower than max From 59aee80c91a2c9f89045687a0d4487215640c576 Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Fri, 21 Nov 2014 11:57:26 -0800 Subject: [PATCH 02/24] Remove ToJSON methods and create JSON constructors --- adaptor.go | 1 - api/api.go | 30 +++++++++++++++--------------- commander.go | 12 +++--------- connection.go | 9 +++++++++ device.go | 17 +++++++++++++++++ driver.go | 1 - gobot.go | 34 +++++++++++++++++----------------- gobot_test.go | 2 +- robot.go | 42 +++++++++++++++++++++--------------------- 9 files changed, 83 insertions(+), 65 deletions(-) diff --git a/adaptor.go b/adaptor.go index d944265ad..7e55d75bf 100644 --- a/adaptor.go +++ b/adaptor.go @@ -6,5 +6,4 @@ type Adaptor interface { Name() string Port() string String() string - ToJSON() *JSONConnection } diff --git a/api/api.go b/api/api.go index 95a28bea1..94b8854bb 100644 --- a/api/api.go +++ b/api/api.go @@ -160,13 +160,13 @@ func (a *api) robeaux(res http.ResponseWriter, req *http.Request) { // mcp returns MCP route handler. // Writes JSON with gobot representation func (a *api) mcp(res http.ResponseWriter, req *http.Request) { - a.writeJSON(map[string]interface{}{"MCP": a.gobot.ToJSON()}, res) + a.writeJSON(map[string]interface{}{"MCP": gobot.NewJSONGobot(a.gobot)}, res) } // mcpCommands returns commands route handler. // Writes JSON with global commands representation func (a *api) mcpCommands(res http.ResponseWriter, req *http.Request) { - a.writeJSON(map[string]interface{}{"commands": a.gobot.ToJSON().Commands}, res) + a.writeJSON(map[string]interface{}{"commands": gobot.NewJSONGobot(a.gobot).Commands}, res) } // robots returns route handler. @@ -174,7 +174,7 @@ func (a *api) mcpCommands(res http.ResponseWriter, req *http.Request) { func (a *api) robots(res http.ResponseWriter, req *http.Request) { jsonRobots := []*gobot.JSONRobot{} a.gobot.Robots().Each(func(r *gobot.Robot) { - jsonRobots = append(jsonRobots, r.ToJSON()) + jsonRobots = append(jsonRobots, gobot.NewJSONRobot(r)) }) a.writeJSON(map[string]interface{}{"robots": jsonRobots}, res) } @@ -182,13 +182,13 @@ func (a *api) robots(res http.ResponseWriter, req *http.Request) { // robot returns route handler. // Writes JSON with robot representation func (a *api) robot(res http.ResponseWriter, req *http.Request) { - a.writeJSON(map[string]interface{}{"robot": a.gobot.Robot(req.URL.Query().Get(":robot")).ToJSON()}, res) + a.writeJSON(map[string]interface{}{"robot": gobot.NewJSONRobot(a.gobot.Robot(req.URL.Query().Get(":robot")))}, res) } // robotCommands returns commands route handler // Writes JSON with robot commands representation func (a *api) robotCommands(res http.ResponseWriter, req *http.Request) { - a.writeJSON(map[string]interface{}{"commands": a.gobot.Robot(req.URL.Query().Get(":robot")).ToJSON().Commands}, res) + a.writeJSON(map[string]interface{}{"commands": gobot.NewJSONRobot(a.gobot.Robot(req.URL.Query().Get(":robot"))).Commands}, res) } // robotDevices returns devices route handler. @@ -196,7 +196,7 @@ func (a *api) robotCommands(res http.ResponseWriter, req *http.Request) { func (a *api) robotDevices(res http.ResponseWriter, req *http.Request) { jsonDevices := []*gobot.JSONDevice{} a.gobot.Robot(req.URL.Query().Get(":robot")).Devices().Each(func(d gobot.Device) { - jsonDevices = append(jsonDevices, d.ToJSON()) + jsonDevices = append(jsonDevices, gobot.NewJSONDevice(d)) }) a.writeJSON(map[string]interface{}{"devices": jsonDevices}, res) } @@ -205,8 +205,8 @@ func (a *api) robotDevices(res http.ResponseWriter, req *http.Request) { // Writes JSON with robot device representation func (a *api) robotDevice(res http.ResponseWriter, req *http.Request) { a.writeJSON( - map[string]interface{}{"device": a.gobot.Robot(req.URL.Query().Get(":robot")). - Device(req.URL.Query().Get(":device")).ToJSON()}, res, + map[string]interface{}{"device": gobot.NewJSONDevice(a.gobot.Robot(req.URL.Query().Get(":robot")). + Device(req.URL.Query().Get(":device")))}, res, ) } @@ -225,7 +225,7 @@ func (a *api) robotDeviceEvent(res http.ResponseWriter, req *http.Request) { res.Header().Set("Connection", "keep-alive") gobot.On(a.gobot.Robot(req.URL.Query().Get(":robot")). - Device(req.URL.Query().Get(":device")).Event(req.URL.Query().Get(":event")), + Device(req.URL.Query().Get(":device")).(gobot.Eventer).Event(req.URL.Query().Get(":event")), func(data interface{}) { d, _ := json.Marshal(data) msg <- string(d) @@ -247,8 +247,8 @@ func (a *api) robotDeviceEvent(res http.ResponseWriter, req *http.Request) { // writes JSON with robot device commands representation func (a *api) robotDeviceCommands(res http.ResponseWriter, req *http.Request) { a.writeJSON( - map[string]interface{}{"commands": a.gobot.Robot(req.URL.Query().Get(":robot")). - Device(req.URL.Query().Get(":device")).ToJSON().Commands}, res, + map[string]interface{}{"commands": gobot.NewJSONDevice(a.gobot.Robot(req.URL.Query().Get(":robot")). + Device(req.URL.Query().Get(":device"))).Commands}, res, ) } @@ -257,7 +257,7 @@ func (a *api) robotDeviceCommands(res http.ResponseWriter, req *http.Request) { func (a *api) robotConnections(res http.ResponseWriter, req *http.Request) { jsonConnections := []*gobot.JSONConnection{} a.gobot.Robot(req.URL.Query().Get(":robot")).Connections().Each(func(c gobot.Connection) { - jsonConnections = append(jsonConnections, c.ToJSON()) + jsonConnections = append(jsonConnections, gobot.NewJSONConnection(c)) }) a.writeJSON(map[string]interface{}{"connections": jsonConnections}, res) } @@ -266,8 +266,8 @@ func (a *api) robotConnections(res http.ResponseWriter, req *http.Request) { // writes JSON with robot connection representation func (a *api) robotConnection(res http.ResponseWriter, req *http.Request) { a.writeJSON( - map[string]interface{}{"connection": a.gobot.Robot(req.URL.Query().Get(":robot")). - Connection(req.URL.Query().Get(":connection")).ToJSON()}, + map[string]interface{}{"connection": gobot.NewJSONConnection(a.gobot.Robot(req.URL.Query().Get(":robot")). + Connection(req.URL.Query().Get(":connection")))}, res, ) } @@ -284,7 +284,7 @@ func (a *api) executeMcpCommand(res http.ResponseWriter, req *http.Request) { func (a *api) executeDeviceCommand(res http.ResponseWriter, req *http.Request) { a.executeCommand( a.gobot.Robot(req.URL.Query().Get(":robot")). - Device(req.URL.Query().Get(":device")). + Device(req.URL.Query().Get(":device")).(gobot.Commander). Command(req.URL.Query().Get(":command")), res, req, diff --git a/commander.go b/commander.go index 28487fb0f..91ba77e9f 100644 --- a/commander.go +++ b/commander.go @@ -1,13 +1,11 @@ package gobot -import "errors" - type commander struct { commands map[string]func(map[string]interface{}) interface{} } type Commander interface { - Command(string) (command func(map[string]interface{}) interface{}, err error) + Command(string) (command func(map[string]interface{}) interface{}) Commands() (commands map[string]func(map[string]interface{}) interface{}) AddCommand(name string, command func(map[string]interface{}) interface{}) } @@ -19,12 +17,8 @@ func NewCommander() Commander { } // Command retrieves a command by name -func (c *commander) Command(name string) (command func(map[string]interface{}) interface{}, err error) { - command, ok := c.commands[name] - if ok { - return - } - err = errors.New("Unknown Command") +func (c *commander) Command(name string) (command func(map[string]interface{}) interface{}) { + command, _ = c.commands[name] return } diff --git a/connection.go b/connection.go index b5620af80..16a5e745f 100644 --- a/connection.go +++ b/connection.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "log" + "reflect" ) // JSONConnection holds a JSON representation of a connection. @@ -12,6 +13,14 @@ type JSONConnection struct { Adaptor string `json:"adaptor"` } +// ToJSON returns a json representation of an adaptor +func NewJSONConnection(connection Connection) *JSONConnection { + return &JSONConnection{ + Name: connection.Name(), + Adaptor: reflect.TypeOf(connection).String(), + } +} + type Connection Adaptor type connections []Connection diff --git a/device.go b/device.go index bf5986cf8..7fec1da2e 100644 --- a/device.go +++ b/device.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "log" + "reflect" ) // JSONDevice is a JSON representation of a Gobot Device. @@ -14,6 +15,22 @@ type JSONDevice struct { Commands []string `json:"commands"` } +func NewJSONDevice(device Device) *JSONDevice { + jsonDevice := &JSONDevice{ + Name: device.Name(), + Driver: reflect.TypeOf(device).String(), + Commands: []string{}, + Connection: "", + } + if device.Connection() != nil { + jsonDevice.Connection = device.Connection().Name() + } + for command := range device.(Commander).Commands() { + jsonDevice.Commands = append(jsonDevice.Commands, command) + } + return jsonDevice +} + type Device Driver type devices []Device diff --git a/driver.go b/driver.go index bb655f221..909af0306 100644 --- a/driver.go +++ b/driver.go @@ -7,5 +7,4 @@ type Driver interface { Pin() string String() string Connection() Connection - ToJSON() *JSONDevice } diff --git a/gobot.go b/gobot.go index 411be8f2e..dded0828a 100644 --- a/gobot.go +++ b/gobot.go @@ -12,6 +12,23 @@ type JSONGobot struct { Commands []string `json:"commands"` } +// ToJSON returns a JSON representation of this Gobot. +func NewJSONGobot(gobot *Gobot) *JSONGobot { + jsonGobot := &JSONGobot{ + Robots: []*JSONRobot{}, + Commands: []string{}, + } + + for command := range gobot.Commands() { + jsonGobot.Commands = append(jsonGobot.Commands, command) + } + + gobot.robots.Each(func(r *Robot) { + jsonGobot.Robots = append(jsonGobot.Robots, NewJSONRobot(r)) + }) + return jsonGobot +} + // Gobot is a container composed of one or more robots type Gobot struct { robots *robots @@ -92,20 +109,3 @@ func (g *Gobot) Robot(name string) *Robot { } return nil } - -// ToJSON returns a JSON representation of this Gobot. -func (g *Gobot) ToJSON() *JSONGobot { - jsonGobot := &JSONGobot{ - Robots: []*JSONRobot{}, - Commands: []string{}, - } - - for command := range g.Commands() { - jsonGobot.Commands = append(jsonGobot.Commands, command) - } - - g.robots.Each(func(r *Robot) { - jsonGobot.Robots = append(jsonGobot.Robots, r.ToJSON()) - }) - return jsonGobot -} diff --git a/gobot_test.go b/gobot_test.go index 0ed066fd1..43e47d20f 100644 --- a/gobot_test.go +++ b/gobot_test.go @@ -39,7 +39,7 @@ func TestGobotToJSON(t *testing.T) { g.AddCommand("test_function", func(params map[string]interface{}) interface{} { return nil }) - json := g.ToJSON() + json := NewJSONGobot(g) Assert(t, len(json.Robots), g.Robots().Len()) Assert(t, len(json.Commands), len(g.Commands())) } diff --git a/robot.go b/robot.go index 2f8e2573c..062b512d9 100644 --- a/robot.go +++ b/robot.go @@ -14,6 +14,27 @@ type JSONRobot struct { Devices []*JSONDevice `json:"devices"` } +// NewJSONRobot returns a JSON representation of the robot. +func NewJSONRobot(robot *Robot) *JSONRobot { + jsonRobot := &JSONRobot{ + Name: robot.Name, + Commands: []string{}, + Connections: []*JSONConnection{}, + Devices: []*JSONDevice{}, + } + + for command := range robot.Commands() { + jsonRobot.Commands = append(jsonRobot.Commands, command) + } + + robot.Devices().Each(func(device Device) { + jsonDevice := NewJSONDevice(device) + jsonRobot.Connections = append(jsonRobot.Connections, NewJSONConnection(robot.Connection(jsonDevice.Connection))) + jsonRobot.Devices = append(jsonRobot.Devices, jsonDevice) + }) + return jsonRobot +} + // Robot is a named entitity that manages a collection of connections and devices. // It containes it's own work routine and a collection of // custom commands to control a robot remotely via the Gobot api. @@ -168,24 +189,3 @@ func (r *Robot) Connection(name string) Connection { } return nil } - -// ToJSON returns a JSON representation of the robot. -func (r *Robot) ToJSON() *JSONRobot { - jsonRobot := &JSONRobot{ - Name: r.Name, - Commands: []string{}, - Connections: []*JSONConnection{}, - Devices: []*JSONDevice{}, - } - - for command := range r.Commands() { - jsonRobot.Commands = append(jsonRobot.Commands, command) - } - - r.Devices().Each(func(device Device) { - jsonDevice := device.ToJSON() - jsonRobot.Connections = append(jsonRobot.Connections, r.Connection(jsonDevice.Connection).ToJSON()) - jsonRobot.Devices = append(jsonRobot.Devices, jsonDevice) - }) - return jsonRobot -} From 4cb20e10881562892fb5012f3a13dc4ef3a5d67e Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Fri, 21 Nov 2014 19:35:01 -0800 Subject: [PATCH 03/24] Add Piner and Porter --- adaptor.go | 4 +++- connection.go | 7 +++++-- device.go | 6 ++++-- driver.go | 6 ++++-- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/adaptor.go b/adaptor.go index 7e55d75bf..893fc8533 100644 --- a/adaptor.go +++ b/adaptor.go @@ -4,6 +4,8 @@ type Adaptor interface { Finalize() []error Connect() []error Name() string +} + +type Porter interface { Port() string - String() string } diff --git a/connection.go b/connection.go index 16a5e745f..1c96dd52d 100644 --- a/connection.go +++ b/connection.go @@ -42,10 +42,13 @@ func (c *connections) Start() (errs []error) { log.Println("Starting connections...") for _, connection := range *c { info := "Starting connection " + connection.Name() - if connection.Port() != "" { - info = info + " on port " + connection.Port() + + if porter, ok := connection.(Porter); ok { + info = info + " on port " + porter.Port() } + log.Println(info + "...") + if errs = connection.Connect(); len(errs) > 0 { for i, err := range errs { errs[i] = errors.New(fmt.Sprintf("Connection %q: %v", connection.Name(), err)) diff --git a/device.go b/device.go index 7fec1da2e..adba5064d 100644 --- a/device.go +++ b/device.go @@ -52,9 +52,11 @@ func (d *devices) Start() (errs []error) { log.Println("Starting devices...") for _, device := range *d { info := "Starting device " + device.Name() - if device.Pin() != "" { - info = info + " on pin " + device.Pin() + + if piner, ok := device.(Piner); ok { + info = info + " on pin " + piner.Pin() } + log.Println(info + "...") if errs = device.Start(); len(errs) > 0 { for i, err := range errs { diff --git a/driver.go b/driver.go index 909af0306..2a206688e 100644 --- a/driver.go +++ b/driver.go @@ -4,7 +4,9 @@ type Driver interface { Start() []error Halt() []error Name() string - Pin() string - String() string Connection() Connection } + +type Piner interface { + Pin() string +} From d38b95f41ff5e2352771978f2d61f482e4299bc3 Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Fri, 21 Nov 2014 19:36:41 -0800 Subject: [PATCH 04/24] Refactor firmata to use new adaptor interface --- platforms/firmata/firmata_adaptor.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/platforms/firmata/firmata_adaptor.go b/platforms/firmata/firmata_adaptor.go index db14e3d0c..8ba707141 100644 --- a/platforms/firmata/firmata_adaptor.go +++ b/platforms/firmata/firmata_adaptor.go @@ -11,10 +11,11 @@ import ( "github.com/tarm/goserial" ) -var _ gobot.AdaptorInterface = (*FirmataAdaptor)(nil) +var _ gobot.Adaptor = (*FirmataAdaptor)(nil) type FirmataAdaptor struct { - gobot.Adaptor + name string + port string board *board i2cAddress byte connect func(*FirmataAdaptor) (err error) @@ -43,11 +44,8 @@ func NewFirmataAdaptor(name string, args ...interface{}) *FirmataAdaptor { } return &FirmataAdaptor{ - Adaptor: *gobot.NewAdaptor( - name, - "FirmataAdaptor", - port, - ), + name: name, + port: port, connect: func(f *FirmataAdaptor) (err error) { if conn == nil { conn, err = serial.OpenPort(&serial.Config{Name: f.Port(), Baud: 57600}) @@ -67,7 +65,6 @@ func (f *FirmataAdaptor) Connect() (errs []error) { return []error{err} } f.board.connect() - f.SetConnected(true) return } @@ -88,6 +85,9 @@ func (f *FirmataAdaptor) Finalize() (errs []error) { return } +func (f *FirmataAdaptor) Port() string { return f.port } +func (f *FirmataAdaptor) Name() string { return f.name } + // InitServo (not yet implemented) func (f *FirmataAdaptor) InitServo() (err error) { return errors.New("InitServo is not yet implemented") From 88db6be3acd76315362cc004702c51c79a8deadd Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Sat, 22 Nov 2014 12:21:28 -0800 Subject: [PATCH 05/24] Refactor gpio to use new driver interface --- platforms/gpio/analog_sensor_driver.go | 37 ++++++++++++++-------- platforms/gpio/button_driver.go | 44 ++++++++++++++++++-------- platforms/gpio/direct_pin_driver.go | 23 ++++++++------ platforms/gpio/led_driver.go | 27 +++++++++------- platforms/gpio/makey_button_driver.go | 36 +++++++++++++-------- platforms/gpio/motor_driver.go | 19 +++++------ platforms/gpio/motor_driver_test.go | 2 +- platforms/gpio/servo_driver.go | 22 +++++++------ platforms/gpio/test_helper.go | 13 ++++---- 9 files changed, 136 insertions(+), 87 deletions(-) diff --git a/platforms/gpio/analog_sensor_driver.go b/platforms/gpio/analog_sensor_driver.go index 33b2c1f72..d61e7fea7 100644 --- a/platforms/gpio/analog_sensor_driver.go +++ b/platforms/gpio/analog_sensor_driver.go @@ -1,15 +1,21 @@ package gpio import ( - "github.com/hybridgroup/gobot" "time" + + "github.com/hybridgroup/gobot" ) -var _ gobot.DriverInterface = (*AnalogSensorDriver)(nil) +var _ gobot.Driver = (*AnalogSensorDriver)(nil) // Represents an Analog Sensor type AnalogSensorDriver struct { - gobot.Driver + name string + pin string + interval time.Duration + connection gobot.Connection + gobot.Eventer + gobot.Commander } // NewAnalogSensorDriver returns a new AnalogSensorDriver given an AnalogReader, name and pin. @@ -18,12 +24,12 @@ type AnalogSensorDriver struct { // "Read" - See AnalogSensor.Read func NewAnalogSensorDriver(a AnalogReader, name string, pin string) *AnalogSensorDriver { d := &AnalogSensorDriver{ - Driver: *gobot.NewDriver( - name, - "AnalogSensorDriver", - a.(gobot.AdaptorInterface), - pin, - ), + name: name, + connection: a.(gobot.Connection), + pin: pin, + Eventer: gobot.NewEventer(), + Commander: gobot.NewCommander(), + interval: 10 * time.Millisecond, } d.AddEvent("data") @@ -36,8 +42,8 @@ func NewAnalogSensorDriver(a AnalogReader, name string, pin string) *AnalogSenso return d } -func (a *AnalogSensorDriver) adaptor() AnalogReader { - return a.Adaptor().(AnalogReader) +func (a *AnalogSensorDriver) conn() AnalogReader { + return a.Connection().(AnalogReader) } // Starts the AnalogSensorDriver and reads the Analog Sensor at the given Driver.Interval(). @@ -55,16 +61,19 @@ func (a *AnalogSensorDriver) Start() (errs []error) { value = newValue gobot.Publish(a.Event("data"), value) } - <-time.After(a.Interval()) + <-time.After(a.interval) } }() return } // Halt returns true on a successful halt of the driver -func (a *AnalogSensorDriver) Halt() (errs []error) { return } +func (a *AnalogSensorDriver) Halt() (errs []error) { return } +func (a *AnalogSensorDriver) Name() string { return a.name } +func (a *AnalogSensorDriver) Pin() string { return a.pin } +func (a *AnalogSensorDriver) Connection() gobot.Connection { return a.connection } // Read returns the current reading from the Analog Sensor func (a *AnalogSensorDriver) Read() (val int, err error) { - return a.adaptor().AnalogRead(a.Pin()) + return a.conn().AnalogRead(a.Pin()) } diff --git a/platforms/gpio/button_driver.go b/platforms/gpio/button_driver.go index 87341e64a..49411251f 100644 --- a/platforms/gpio/button_driver.go +++ b/platforms/gpio/button_driver.go @@ -1,28 +1,30 @@ package gpio import ( - "github.com/hybridgroup/gobot" "time" + + "github.com/hybridgroup/gobot" ) -var _ gobot.DriverInterface = (*ButtonDriver)(nil) +var _ gobot.Driver = (*ButtonDriver)(nil) // Represents a digital Button type ButtonDriver struct { - gobot.Driver - Active bool + Active bool + pin string + name string + connection gobot.Connection + gobot.Eventer } // NewButtonDriver return a new ButtonDriver given a DigitalReader, name and pin func NewButtonDriver(a DigitalReader, name string, pin string) *ButtonDriver { b := &ButtonDriver{ - Driver: *gobot.NewDriver( - name, - "ButtonDriver", - a.(gobot.AdaptorInterface), - pin, - ), - Active: false, + name: name, + connection: a.(gobot.Adaptor), + pin: pin, + Active: false, + Eventer: gobot.NewEventer(), } b.AddEvent("push") @@ -33,7 +35,7 @@ func NewButtonDriver(a DigitalReader, name string, pin string) *ButtonDriver { } func (b *ButtonDriver) adaptor() DigitalReader { - return b.Adaptor().(DigitalReader) + return b.Connection().(DigitalReader) } // Starts the ButtonDriver and reads the state of the button at the given Driver.Interval(). @@ -54,7 +56,8 @@ func (b *ButtonDriver) Start() (errs []error) { state = newValue b.update(newValue) } - <-time.After(b.Interval()) + //<-time.After(b.Interval()) + <-time.After(100 * time.Millisecond) } }() return @@ -63,6 +66,21 @@ func (b *ButtonDriver) Start() (errs []error) { // Halt returns true on a successful halt of the driver func (b *ButtonDriver) Halt() (errs []error) { return } +func (b *ButtonDriver) Name() string { return b.name } +func (b *ButtonDriver) Pin() string { return b.pin } +func (b *ButtonDriver) Connection() gobot.Connection { return b.connection } +func (b *ButtonDriver) String() string { return "ButtonDriver" } +func (b *ButtonDriver) ToJSON() *gobot.JSONDevice { + return &gobot.JSONDevice{ + Name: b.Name(), + Driver: b.String(), + Connection: b.Connection().Name(), + //Commands: l.Commands(), + //Commands: l.Commands(), + } + +} + func (b *ButtonDriver) readState() (val int, err error) { return b.adaptor().DigitalRead(b.Pin()) } diff --git a/platforms/gpio/direct_pin_driver.go b/platforms/gpio/direct_pin_driver.go index 9b9f2b26a..1a0fa7238 100644 --- a/platforms/gpio/direct_pin_driver.go +++ b/platforms/gpio/direct_pin_driver.go @@ -6,11 +6,14 @@ import ( "github.com/hybridgroup/gobot" ) -var _ gobot.DriverInterface = (*DirectPinDriver)(nil) +var _ gobot.Driver = (*DirectPinDriver)(nil) // Represents a raw GPIO pin type DirectPinDriver struct { - gobot.Driver + name string + pin string + connection gobot.Connection + gobot.Commander } // NewDirectPinDriver return a new DirectPinDriver given a DirectPin, name and pin. @@ -24,12 +27,10 @@ type DirectPinDriver struct { // "ServoWrite" - See DirectPinDriver.ServoWrite func NewDirectPinDriver(a DirectPin, name string, pin string) *DirectPinDriver { d := &DirectPinDriver{ - Driver: *gobot.NewDriver( - name, - "DirectPinDriver", - a.(gobot.AdaptorInterface), - pin, - ), + name: name, + connection: a.(gobot.Connection), + pin: pin, + Commander: gobot.NewCommander(), } d.AddCommand("DigitalRead", func(params map[string]interface{}) interface{} { @@ -61,9 +62,13 @@ func NewDirectPinDriver(a DirectPin, name string, pin string) *DirectPinDriver { } func (d *DirectPinDriver) adaptor() DirectPin { - return d.Adaptor().(DirectPin) + return d.Connection().(DirectPin) } +func (d *DirectPinDriver) Name() string { return d.name } +func (d *DirectPinDriver) Pin() string { return d.pin } +func (d *DirectPinDriver) Connection() gobot.Connection { return d.connection } + // Starts the DirectPinDriver. Returns true on successful start of the driver func (d *DirectPinDriver) Start() (errs []error) { return } diff --git a/platforms/gpio/led_driver.go b/platforms/gpio/led_driver.go index f77095e3c..5d902a67a 100644 --- a/platforms/gpio/led_driver.go +++ b/platforms/gpio/led_driver.go @@ -2,12 +2,15 @@ package gpio import "github.com/hybridgroup/gobot" -var _ gobot.DriverInterface = (*LedDriver)(nil) +var _ gobot.Driver = (*LedDriver)(nil) // Represents a digital Led type LedDriver struct { - gobot.Driver - high bool + pin string + name string + connection gobot.Connection + high bool + gobot.Commander } // NewLedDriver return a new LedDriver given a PwmDigitalWriter, name and pin. @@ -19,13 +22,11 @@ type LedDriver struct { // "Off" - See LedDriver.Off func NewLedDriver(a PwmDigitalWriter, name string, pin string) *LedDriver { l := &LedDriver{ - Driver: *gobot.NewDriver( - name, - "LedDriver", - pin, - a.(gobot.AdaptorInterface), - ), - high: false, + name: name, + pin: pin, + connection: a.(gobot.Connection), + high: false, + Commander: gobot.NewCommander(), } l.AddCommand("Brightness", func(params map[string]interface{}) interface{} { @@ -49,7 +50,7 @@ func NewLedDriver(a PwmDigitalWriter, name string, pin string) *LedDriver { } func (l *LedDriver) adaptor() PwmDigitalWriter { - return l.Adaptor().(PwmDigitalWriter) + return l.Connection().(PwmDigitalWriter) } // Start starts the LedDriver. Returns true on successful start of the driver @@ -58,6 +59,10 @@ func (l *LedDriver) Start() (errs []error) { return } // Halt halts the LedDriver. Returns true on successful halt of the driver func (l *LedDriver) Halt() (errs []error) { return } +func (l *LedDriver) Name() string { return l.name } +func (l *LedDriver) Pin() string { return l.pin } +func (l *LedDriver) Connection() gobot.Connection { return l.connection } + // State return true if the led is On and false if the led is Off func (l *LedDriver) State() bool { return l.high diff --git a/platforms/gpio/makey_button_driver.go b/platforms/gpio/makey_button_driver.go index c61ecad3e..b3fe8c638 100644 --- a/platforms/gpio/makey_button_driver.go +++ b/platforms/gpio/makey_button_driver.go @@ -1,29 +1,33 @@ package gpio import ( - "github.com/hybridgroup/gobot" "time" + + "github.com/hybridgroup/gobot" ) -var _ gobot.DriverInterface = (*MakeyButtonDriver)(nil) +var _ gobot.Driver = (*MakeyButtonDriver)(nil) // Represents a Makey Button type MakeyButtonDriver struct { - gobot.Driver - Active bool - data []int + name string + pin string + connection gobot.Connection + Active bool + data []int + interval time.Duration + gobot.Eventer } // NewMakeyButtonDriver returns a new MakeyButtonDriver given a DigitalRead, name and pin. func NewMakeyButtonDriver(a DigitalReader, name string, pin string) *MakeyButtonDriver { m := &MakeyButtonDriver{ - Driver: *gobot.NewDriver( - name, - "MakeyButtonDriver", - a.(gobot.AdaptorInterface), - pin, - ), - Active: false, + name: name, + connection: a.(gobot.Connection), + pin: pin, + Active: false, + Eventer: gobot.NewEventer(), + interval: 10 * time.Millisecond, } m.AddEvent("error") @@ -33,8 +37,12 @@ func NewMakeyButtonDriver(a DigitalReader, name string, pin string) *MakeyButton return m } +func (b *MakeyButtonDriver) Name() string { return b.name } +func (b *MakeyButtonDriver) Pin() string { return b.pin } +func (b *MakeyButtonDriver) Connection() gobot.Connection { return b.connection } + func (b *MakeyButtonDriver) adaptor() DigitalReader { - return b.Adaptor().(DigitalReader) + return b.Connection().(DigitalReader) } // Starts the MakeyButtonDriver and reads the state of the button at the given Driver.Interval(). @@ -61,7 +69,7 @@ func (m *MakeyButtonDriver) Start() (errs []error) { } } } - <-time.After(m.Interval()) + <-time.After(m.interval) }() return } diff --git a/platforms/gpio/motor_driver.go b/platforms/gpio/motor_driver.go index aabc79f44..3cd11a057 100644 --- a/platforms/gpio/motor_driver.go +++ b/platforms/gpio/motor_driver.go @@ -4,11 +4,12 @@ import ( "github.com/hybridgroup/gobot" ) -var _ gobot.DriverInterface = (*MotorDriver)(nil) +var _ gobot.Driver = (*MotorDriver)(nil) // Represents a Motor type MotorDriver struct { - gobot.Driver + name string + connection gobot.Connection SpeedPin string SwitchPin string DirectionPin string @@ -21,13 +22,10 @@ type MotorDriver struct { } // NewMotorDriver return a new MotorDriver given a PwmDigitalWriter, name and pin -func NewMotorDriver(a PwmDigitalWriter, name string, pin string) *MotorDriver { +func NewMotorDriver(a PwmDigitalWriter, name string) *MotorDriver { return &MotorDriver{ - Driver: *gobot.NewDriver( - name, - "MotorDriver", - a.(gobot.AdaptorInterface), - ), + name: name, + connection: a.(gobot.Adaptor), CurrentState: 0, CurrentSpeed: 0, CurrentMode: "digital", @@ -35,8 +33,11 @@ func NewMotorDriver(a PwmDigitalWriter, name string, pin string) *MotorDriver { } } +func (m *MotorDriver) Name() string { return m.name } +func (m *MotorDriver) Connection() gobot.Connection { return m.connection } + func (m *MotorDriver) adaptor() PwmDigitalWriter { - return m.Adaptor().(PwmDigitalWriter) + return m.Connection().(PwmDigitalWriter) } // Start starts the MotorDriver. Returns true on successful start of the driver diff --git a/platforms/gpio/motor_driver_test.go b/platforms/gpio/motor_driver_test.go index 4da808a76..d8e62b362 100644 --- a/platforms/gpio/motor_driver_test.go +++ b/platforms/gpio/motor_driver_test.go @@ -7,7 +7,7 @@ import ( ) func initTestMotorDriver() *MotorDriver { - return NewMotorDriver(newGpioTestAdaptor("adaptor"), "bot", "1") + return NewMotorDriver(newGpioTestAdaptor("adaptor"), "bot") } func TestMotorDriverStart(t *testing.T) { diff --git a/platforms/gpio/servo_driver.go b/platforms/gpio/servo_driver.go index a62200871..2d0383ad6 100644 --- a/platforms/gpio/servo_driver.go +++ b/platforms/gpio/servo_driver.go @@ -6,11 +6,14 @@ import ( "github.com/hybridgroup/gobot" ) -var _ gobot.DriverInterface = (*ServoDriver)(nil) +var _ gobot.Driver = (*ServoDriver)(nil) // Represents a Servo type ServoDriver struct { - gobot.Driver + name string + pin string + connection gobot.Connection + gobot.Commander CurrentAngle byte } @@ -23,12 +26,10 @@ type ServoDriver struct { // "Max" - See ServoDriver.Max func NewServoDriver(a Servo, name string, pin string) *ServoDriver { s := &ServoDriver{ - Driver: *gobot.NewDriver( - name, - "ServoDriver", - a.(gobot.AdaptorInterface), - pin, - ), + name: name, + connection: a.(gobot.Connection), + pin: pin, + Commander: gobot.NewCommander(), CurrentAngle: 0, } @@ -50,8 +51,11 @@ func NewServoDriver(a Servo, name string, pin string) *ServoDriver { } +func (s *ServoDriver) Name() string { return s.name } +func (s *ServoDriver) Pin() string { return s.pin } +func (s *ServoDriver) Connection() gobot.Connection { return s.connection } func (s *ServoDriver) adaptor() Servo { - return s.Adaptor().(Servo) + return s.Connection().(Servo) } // Start starts the ServoDriver. Returns true on successful start of the driver. diff --git a/platforms/gpio/test_helper.go b/platforms/gpio/test_helper.go index e200020d6..f75587270 100644 --- a/platforms/gpio/test_helper.go +++ b/platforms/gpio/test_helper.go @@ -1,9 +1,8 @@ package gpio -import "github.com/hybridgroup/gobot" - type gpioTestAdaptor struct { - gobot.Adaptor + name string + port string } func (t *gpioTestAdaptor) AnalogWrite(string, byte) (err error) { return nil } @@ -19,12 +18,12 @@ func (t *gpioTestAdaptor) DigitalRead(string) (val int, err error) { } func (t *gpioTestAdaptor) Connect() (errs []error) { return } func (t *gpioTestAdaptor) Finalize() (errs []error) { return } +func (t *gpioTestAdaptor) Name() string { return t.name } +func (t *gpioTestAdaptor) Port() string { return t.port } func newGpioTestAdaptor(name string) *gpioTestAdaptor { return &gpioTestAdaptor{ - Adaptor: *gobot.NewAdaptor( - name, - "/dev/null", - ), + name: name, + port: "/dev/null", } } From 9a0f3b46f7504e6cffb44d80fe14bfbd47f17997 Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Sat, 22 Nov 2014 18:56:23 -0800 Subject: [PATCH 06/24] Refactor ardrone to use new driver and adaptor interfaces --- platforms/ardrone/ardrone_adaptor.go | 15 ++++++--------- platforms/ardrone/ardrone_adaptor_test.go | 3 ++- platforms/ardrone/ardrone_driver.go | 21 ++++++++++++--------- platforms/ardrone/ardrone_driver_test.go | 3 ++- 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/platforms/ardrone/ardrone_adaptor.go b/platforms/ardrone/ardrone_adaptor.go index 23cb09f8a..9c2d905ee 100644 --- a/platforms/ardrone/ardrone_adaptor.go +++ b/platforms/ardrone/ardrone_adaptor.go @@ -5,7 +5,7 @@ import ( "github.com/hybridgroup/gobot" ) -var _ gobot.AdaptorInterface = (*ArdroneAdaptor)(nil) +var _ gobot.Adaptor = (*ArdroneAdaptor)(nil) // drone defines expected drone behaviour type drone interface { @@ -23,7 +23,7 @@ type drone interface { } type ArdroneAdaptor struct { - gobot.Adaptor + name string drone drone connect func(*ArdroneAdaptor) (err error) } @@ -31,10 +31,7 @@ type ArdroneAdaptor struct { // NewArdroneAdaptor creates a new ardrone and connects with default configuration func NewArdroneAdaptor(name string, v ...string) *ArdroneAdaptor { return &ArdroneAdaptor{ - Adaptor: *gobot.NewAdaptor( - name, - "ArdroneAdaptor", - ), + name: name, connect: func(a *ArdroneAdaptor) (err error) { config := client.DefaultConfig() if len(v) > 0 { @@ -50,6 +47,8 @@ func NewArdroneAdaptor(name string, v ...string) *ArdroneAdaptor { } } +func (a *ArdroneAdaptor) Name() string { return a.name } + // Connect returns true when connection to ardrone is established correclty func (a *ArdroneAdaptor) Connect() (errs []error) { if err := a.connect(a); err != nil { @@ -59,6 +58,4 @@ func (a *ArdroneAdaptor) Connect() (errs []error) { } // Finalize returns true when connection is finalized correctly -func (a *ArdroneAdaptor) Finalize() (errs []error) { - return -} +func (a *ArdroneAdaptor) Finalize() (errs []error) { return } diff --git a/platforms/ardrone/ardrone_adaptor_test.go b/platforms/ardrone/ardrone_adaptor_test.go index c3b848700..36a90761a 100644 --- a/platforms/ardrone/ardrone_adaptor_test.go +++ b/platforms/ardrone/ardrone_adaptor_test.go @@ -1,8 +1,9 @@ package ardrone import ( - "github.com/hybridgroup/gobot" "testing" + + "github.com/hybridgroup/gobot" ) func initTestArdroneAdaptor() *ArdroneAdaptor { diff --git a/platforms/ardrone/ardrone_driver.go b/platforms/ardrone/ardrone_driver.go index d56060567..40abbc81e 100644 --- a/platforms/ardrone/ardrone_driver.go +++ b/platforms/ardrone/ardrone_driver.go @@ -4,31 +4,34 @@ import ( "github.com/hybridgroup/gobot" ) -var _ gobot.DriverInterface = (*ArdroneDriver)(nil) +var _ gobot.Driver = (*ArdroneDriver)(nil) type ArdroneDriver struct { - gobot.Driver + name string + connection gobot.Connection + gobot.Eventer } // NewArdroneDriver creates an ArdroneDriver with specified name. // // It add the following events: // 'flying' - Sent when the device has taken off. -func NewArdroneDriver(adaptor *ArdroneAdaptor, name string) *ArdroneDriver { +func NewArdroneDriver(connection *ArdroneAdaptor, name string) *ArdroneDriver { d := &ArdroneDriver{ - Driver: *gobot.NewDriver( - name, - "ArdroneDriver", - adaptor, - ), + name: name, + connection: connection, + Eventer: gobot.NewEventer(), } d.AddEvent("flying") return d } +func (a *ArdroneDriver) Name() string { return a.name } +func (a *ArdroneDriver) Connection() gobot.Connection { return a.connection } + // adaptor returns ardrone adaptor func (a *ArdroneDriver) adaptor() *ArdroneAdaptor { - return a.Adaptor().(*ArdroneAdaptor) + return a.Connection().(*ArdroneAdaptor) } // Start returns true if driver is started succesfully diff --git a/platforms/ardrone/ardrone_driver_test.go b/platforms/ardrone/ardrone_driver_test.go index bf5624e5b..9925441e2 100644 --- a/platforms/ardrone/ardrone_driver_test.go +++ b/platforms/ardrone/ardrone_driver_test.go @@ -1,8 +1,9 @@ package ardrone import ( - "github.com/hybridgroup/gobot" "testing" + + "github.com/hybridgroup/gobot" ) func initTestArdroneDriver() *ArdroneDriver { From 149760e392fa3500309263085802b0cc67befddf Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Sat, 22 Nov 2014 18:59:27 -0800 Subject: [PATCH 07/24] Refactor beaglebone to use new adaptor interface --- platforms/beaglebone/beaglebone_adaptor.go | 11 +++++------ platforms/beaglebone/pwm_pin.go | 3 ++- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/platforms/beaglebone/beaglebone_adaptor.go b/platforms/beaglebone/beaglebone_adaptor.go index b28e2b9bf..41cf96822 100644 --- a/platforms/beaglebone/beaglebone_adaptor.go +++ b/platforms/beaglebone/beaglebone_adaptor.go @@ -14,7 +14,8 @@ import ( "github.com/hybridgroup/gobot/sysfs" ) -var _ gobot.AdaptorInterface = (*BeagleboneAdaptor)(nil) +var _ gobot.Adaptor = (*BeagleboneAdaptor)(nil) + var slots = "/sys/devices/bone_capemgr.*" var ocp = "/sys/devices/ocp.*" var usrLed = "/sys/devices/ocp.3/gpio-leds.8/leds/beaglebone:green:" @@ -114,7 +115,7 @@ var analogPins = map[string]string{ } type BeagleboneAdaptor struct { - gobot.Adaptor + name string digitalPins []sysfs.DigitalPin pwmPins map[string]*pwmPin i2cDevice io.ReadWriteCloser @@ -126,10 +127,7 @@ type BeagleboneAdaptor struct { // NewBeagleboneAdaptor returns a new beaglebone adaptor with specified name func NewBeagleboneAdaptor(name string) *BeagleboneAdaptor { b := &BeagleboneAdaptor{ - Adaptor: *gobot.NewAdaptor( - name, - "BeagleboneAdaptor", - ), + name: name, digitalPins: make([]sysfs.DigitalPin, 120), pwmPins: make(map[string]*pwmPin), } @@ -141,6 +139,7 @@ func NewBeagleboneAdaptor(name string) *BeagleboneAdaptor { return b } +func (b *BeagleboneAdaptor) Name() string { return b.name } // Connect returns true on a succesful connection to beaglebone board. // It initializes digital, pwm and analog pins diff --git a/platforms/beaglebone/pwm_pin.go b/platforms/beaglebone/pwm_pin.go index 4997fa753..cdb99a063 100644 --- a/platforms/beaglebone/pwm_pin.go +++ b/platforms/beaglebone/pwm_pin.go @@ -2,9 +2,10 @@ package beaglebone import ( "fmt" - "github.com/hybridgroup/gobot/sysfs" "os" "strings" + + "github.com/hybridgroup/gobot/sysfs" ) type pwmPin struct { From 802820700a1af7bbb3d0d9b00e10f17a80a3c1ea Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Sat, 22 Nov 2014 19:01:27 -0800 Subject: [PATCH 08/24] Refactor digispark to use new adaptor interface --- platforms/digispark/digispark_adaptor.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/platforms/digispark/digispark_adaptor.go b/platforms/digispark/digispark_adaptor.go index 1f8ae689a..bb75cb1b8 100644 --- a/platforms/digispark/digispark_adaptor.go +++ b/platforms/digispark/digispark_adaptor.go @@ -8,10 +8,10 @@ import ( "github.com/hybridgroup/gobot" ) -var _ gobot.AdaptorInterface = (*DigisparkAdaptor)(nil) +var _ gobot.Adaptor = (*DigisparkAdaptor)(nil) type DigisparkAdaptor struct { - gobot.Adaptor + name string littleWire lw servo bool pwm bool @@ -21,10 +21,7 @@ type DigisparkAdaptor struct { // NewDigisparkAdaptor create a Digispark adaptor with specified name func NewDigisparkAdaptor(name string) *DigisparkAdaptor { return &DigisparkAdaptor{ - Adaptor: *gobot.NewAdaptor( - name, - "DigisparkAdaptor", - ), + name: name, connect: func(d *DigisparkAdaptor) (err error) { d.littleWire = littleWireConnect() if d.littleWire.(*littleWire).lwHandle == nil { @@ -35,6 +32,8 @@ func NewDigisparkAdaptor(name string) *DigisparkAdaptor { } } +func (d *DigisparkAdaptor) Name() string { return d.name } + // Connect starts connection to digispark, returns true if successful func (d *DigisparkAdaptor) Connect() (errs []error) { if err := d.connect(d); err != nil { From 1f2c7fd6c72df7c06a6a42c714c34d837dfb4f66 Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Sat, 22 Nov 2014 19:38:39 -0800 Subject: [PATCH 09/24] Refactor i2c to use new driver interface --- platforms/i2c/blinkm_driver.go | 18 ++++++++++-------- platforms/i2c/blinkm_driver_test.go | 15 ++++++++------- platforms/i2c/hmc6352_driver.go | 17 +++++++++-------- platforms/i2c/hmc6352_driver_test.go | 4 +--- platforms/i2c/mpl115a2_driver.go | 23 ++++++++++++++--------- platforms/i2c/mpl115a2_driver_test.go | 2 +- platforms/i2c/mpu6050_driver.go | 25 ++++++++++++++++--------- platforms/i2c/mpu6050_driver_test.go | 2 +- platforms/i2c/test_helper.go | 12 +++--------- platforms/i2c/wiichuck_driver.go | 23 ++++++++++++++--------- platforms/i2c/wiichuck_driver_test.go | 4 ++-- 11 files changed, 79 insertions(+), 66 deletions(-) diff --git a/platforms/i2c/blinkm_driver.go b/platforms/i2c/blinkm_driver.go index 25e3fdb43..f5e30f026 100644 --- a/platforms/i2c/blinkm_driver.go +++ b/platforms/i2c/blinkm_driver.go @@ -6,10 +6,12 @@ import ( "github.com/hybridgroup/gobot" ) -var _ gobot.DriverInterface = (*BlinkMDriver)(nil) +var _ gobot.Driver = (*BlinkMDriver)(nil) type BlinkMDriver struct { - gobot.Driver + name string + connection gobot.Connection + gobot.Commander } // NewBlinkMDriver creates a new BlinkMDriver with specified name. @@ -21,11 +23,9 @@ type BlinkMDriver struct { // Color - returns the color of the LED. func NewBlinkMDriver(a I2cInterface, name string) *BlinkMDriver { b := &BlinkMDriver{ - Driver: *gobot.NewDriver( - name, - "BlinkMDriver", - a.(gobot.AdaptorInterface), - ), + name: name, + connection: a.(gobot.Connection), + Commander: gobot.NewCommander(), } b.AddCommand("Rgb", func(params map[string]interface{}) interface{} { @@ -51,10 +51,12 @@ func NewBlinkMDriver(a I2cInterface, name string) *BlinkMDriver { return b } +func (b *BlinkMDriver) Name() string { return b.name } +func (b *BlinkMDriver) Connection() gobot.Connection { return b.connection } // adaptor returns I2C adaptor func (b *BlinkMDriver) adaptor() I2cInterface { - return b.Adaptor().(I2cInterface) + return b.Connection().(I2cInterface) } // Start writes start bytes diff --git a/platforms/i2c/blinkm_driver_test.go b/platforms/i2c/blinkm_driver_test.go index 264e4ccff..d586cc843 100644 --- a/platforms/i2c/blinkm_driver_test.go +++ b/platforms/i2c/blinkm_driver_test.go @@ -1,8 +1,9 @@ package i2c import ( - "github.com/hybridgroup/gobot" "testing" + + "github.com/hybridgroup/gobot" ) // --------- HELPERS @@ -20,7 +21,7 @@ func initTestBlinkDriverWithStubbedAdaptor() (*BlinkMDriver, *i2cTestAdaptor) { func TestBlinkMDriver(t *testing.T) { // Does it implement gobot.DriverInterface? - var _ gobot.DriverInterface = (*BlinkMDriver)(nil) + var _ gobot.Driver = (*BlinkMDriver)(nil) // Does its adaptor implements the I2cInterface? driver := initTestBlinkMDriver() @@ -40,14 +41,14 @@ func TestNewBlinkMDriver(t *testing.T) { func TestNewBlinkMDriverCommands_Rgb(t *testing.T) { blinkM := initTestBlinkMDriver() - result := blinkM.Driver.Command("Rgb")(rgb) + result := blinkM.Command("Rgb")(rgb) gobot.Assert(t, result, nil) } func TestNewBlinkMDriverCommands_Fade(t *testing.T) { blinkM := initTestBlinkMDriver() - result := blinkM.Driver.Command("Fade")(rgb) + result := blinkM.Command("Fade")(rgb) gobot.Assert(t, result, nil) } @@ -61,7 +62,7 @@ func TestNewBlinkMDriverCommands_FirmwareVersion(t *testing.T) { return []byte{99, 1} } - result := blinkM.Driver.Command("FirmwareVersion")(param) + result := blinkM.Command("FirmwareVersion")(param) version, _ := blinkM.FirmwareVersion() gobot.Assert(t, result.(map[string]interface{})["version"].(string), version) @@ -70,7 +71,7 @@ func TestNewBlinkMDriverCommands_FirmwareVersion(t *testing.T) { adaptor.i2cReadImpl = func() []byte { return []byte{99} } - result = blinkM.Driver.Command("FirmwareVersion")(param) + result = blinkM.Command("FirmwareVersion")(param) version, _ = blinkM.FirmwareVersion() gobot.Assert(t, result.(map[string]interface{})["version"].(string), version) @@ -81,7 +82,7 @@ func TestNewBlinkMDriverCommands_Color(t *testing.T) { param := make(map[string]interface{}) - result := blinkM.Driver.Command("Color")(param) + result := blinkM.Command("Color")(param) color, _ := blinkM.Color() gobot.Assert(t, result.(map[string]interface{})["color"].([]byte), color) diff --git a/platforms/i2c/hmc6352_driver.go b/platforms/i2c/hmc6352_driver.go index f4fad9528..b4fe8409c 100644 --- a/platforms/i2c/hmc6352_driver.go +++ b/platforms/i2c/hmc6352_driver.go @@ -6,26 +6,27 @@ import ( "github.com/hybridgroup/gobot" ) -var _ gobot.DriverInterface = (*HMC6352Driver)(nil) +var _ gobot.Driver = (*HMC6352Driver)(nil) type HMC6352Driver struct { - gobot.Driver + name string + connection gobot.Connection } // NewHMC6352Driver creates a new driver with specified name and i2c interface func NewHMC6352Driver(a I2cInterface, name string) *HMC6352Driver { return &HMC6352Driver{ - Driver: *gobot.NewDriver( - name, - "HMC6352Driver", - a.(gobot.AdaptorInterface), - ), + name: name, + connection: a.(gobot.Connection), } } +func (h *HMC6352Driver) Name() string { return h.name } +func (h *HMC6352Driver) Connection() gobot.Connection { return h.connection } + // adaptor returns HMC6352 adaptor func (h *HMC6352Driver) adaptor() I2cInterface { - return h.Adaptor().(I2cInterface) + return h.Connection().(I2cInterface) } // Start writes initialization bytes and reads from adaptor diff --git a/platforms/i2c/hmc6352_driver_test.go b/platforms/i2c/hmc6352_driver_test.go index 95a43f396..024e51466 100644 --- a/platforms/i2c/hmc6352_driver_test.go +++ b/platforms/i2c/hmc6352_driver_test.go @@ -22,7 +22,7 @@ func initTestHMC6352DriverWithStubbedAdaptor() (*HMC6352Driver, *i2cTestAdaptor) func TestHMC6352Driver(t *testing.T) { // Does it implement gobot.DriverInterface? - var _ gobot.DriverInterface = (*HMC6352Driver)(nil) + var _ gobot.Driver = (*HMC6352Driver)(nil) // Does its adaptor implements the I2cInterface? driver := initTestHMC6352Driver() @@ -50,7 +50,6 @@ func TestHMC6352DriverStart(t *testing.T) { numberOfCyclesForEvery := 3 - hmc.SetInterval(1 * time.Millisecond) gobot.Assert(t, len(hmc.Start()), 0) go func() { for { @@ -75,7 +74,6 @@ func TestHMC6352DriverStart(t *testing.T) { return []byte{99} } - hmc.SetInterval(1 * time.Millisecond) gobot.Assert(t, len(hmc.Start()), 0) go func() { for { diff --git a/platforms/i2c/mpl115a2_driver.go b/platforms/i2c/mpl115a2_driver.go index d4a95c8e5..994e8b6a9 100644 --- a/platforms/i2c/mpl115a2_driver.go +++ b/platforms/i2c/mpl115a2_driver.go @@ -8,7 +8,7 @@ import ( "time" ) -var _ gobot.DriverInterface = (*MPL115A2Driver)(nil) +var _ gobot.Driver = (*MPL115A2Driver)(nil) const MPL115A2_REGISTER_PRESSURE_MSB = 0x00 const MPL115A2_REGISTER_PRESSURE_LSB = 0x01 @@ -25,7 +25,10 @@ const MPL115A2_REGISTER_C12_COEFF_LSB = 0x0B const MPL115A2_REGISTER_STARTCONVERSION = 0x12 type MPL115A2Driver struct { - gobot.Driver + name string + connection gobot.Connection + interval time.Duration + gobot.Eventer A0 float32 B1 float32 B2 float32 @@ -37,19 +40,21 @@ type MPL115A2Driver struct { // NewMPL115A2Driver creates a new driver with specified name and i2c interface func NewMPL115A2Driver(a I2cInterface, name string) *MPL115A2Driver { m := &MPL115A2Driver{ - Driver: *gobot.NewDriver( - name, - "MPL115A2Driver", - a.(gobot.AdaptorInterface), - ), + name: name, + connection: a.(gobot.Connection), + Eventer: gobot.NewEventer(), + interval: 10 * time.Millisecond, } m.AddEvent("error") return m } +func (h *MPL115A2Driver) Name() string { return h.name } +func (h *MPL115A2Driver) Connection() gobot.Connection { return h.connection } + // adaptor returns MPL115A2 adaptor func (h *MPL115A2Driver) adaptor() I2cInterface { - return h.Adaptor().(I2cInterface) + return h.Connection().(I2cInterface) } // Start writes initialization bytes and reads from adaptor @@ -63,7 +68,7 @@ func (h *MPL115A2Driver) Start() (errs []error) { return } - gobot.Every(h.Interval(), func() { + gobot.Every(h.interval, func() { if err := h.adaptor().I2cWrite([]byte{MPL115A2_REGISTER_STARTCONVERSION, 0}); err != nil { gobot.Publish(h.Event("error"), err) return diff --git a/platforms/i2c/mpl115a2_driver_test.go b/platforms/i2c/mpl115a2_driver_test.go index e5ac01215..dc271c5f3 100644 --- a/platforms/i2c/mpl115a2_driver_test.go +++ b/platforms/i2c/mpl115a2_driver_test.go @@ -21,7 +21,7 @@ func initTestMPL115A2DriverWithStubbedAdaptor() (*MPL115A2Driver, *i2cTestAdapto func TestMPL115A2DriverDriver(t *testing.T) { // Does it implement gobot.DriverInterface? - var _ gobot.DriverInterface = (*MPL115A2Driver)(nil) + var _ gobot.Driver = (*MPL115A2Driver)(nil) // Does its adaptor implements the I2cInterface? driver := initTestMPL115A2Driver() diff --git a/platforms/i2c/mpu6050_driver.go b/platforms/i2c/mpu6050_driver.go index e80bb0c22..66d14e621 100644 --- a/platforms/i2c/mpu6050_driver.go +++ b/platforms/i2c/mpu6050_driver.go @@ -3,10 +3,12 @@ package i2c import ( "bytes" "encoding/binary" + "time" + "github.com/hybridgroup/gobot" ) -var _ gobot.DriverInterface = (*MPU6050Driver)(nil) +var _ gobot.Driver = (*MPU6050Driver)(nil) const MPU6050_RA_ACCEL_XOUT_H = 0x3B const MPU6050_RA_PWR_MGMT_1 = 0x6B @@ -30,7 +32,10 @@ type ThreeDData struct { } type MPU6050Driver struct { - gobot.Driver + name string + connection gobot.Connection + interval time.Duration + gobot.Eventer Accelerometer ThreeDData Gyroscope ThreeDData Temperature int16 @@ -39,19 +44,21 @@ type MPU6050Driver struct { // NewMPU6050Driver creates a new driver with specified name and i2c interface func NewMPU6050Driver(a I2cInterface, name string) *MPU6050Driver { m := &MPU6050Driver{ - Driver: *gobot.NewDriver( - name, - "MPU6050Driver", - a.(gobot.AdaptorInterface), - ), + name: name, + connection: a.(gobot.Connection), + interval: 10 * time.Millisecond, + Eventer: gobot.NewEventer(), } m.AddEvent("error") return m } +func (h *MPU6050Driver) Name() string { return h.name } +func (h *MPU6050Driver) Connection() gobot.Connection { return h.connection } + // adaptor returns MPU6050 adaptor func (h *MPU6050Driver) adaptor() I2cInterface { - return h.Adaptor().(I2cInterface) + return h.Connection().(I2cInterface) } // Start writes initialization bytes and reads from adaptor @@ -61,7 +68,7 @@ func (h *MPU6050Driver) Start() (errs []error) { return []error{err} } - gobot.Every(h.Interval(), func() { + gobot.Every(h.interval, func() { if err := h.adaptor().I2cWrite([]byte{MPU6050_RA_ACCEL_XOUT_H}); err != nil { gobot.Publish(h.Event("error"), err) return diff --git a/platforms/i2c/mpu6050_driver_test.go b/platforms/i2c/mpu6050_driver_test.go index 14ff70637..071ff4ac8 100644 --- a/platforms/i2c/mpu6050_driver_test.go +++ b/platforms/i2c/mpu6050_driver_test.go @@ -21,7 +21,7 @@ func initTestMPU6050DriverWithStubbedAdaptor() (*MPU6050Driver, *i2cTestAdaptor) func TestMPU6050Driver(t *testing.T) { // Does it implement gobot.DriverInterface? - var _ gobot.DriverInterface = (*MPU6050Driver)(nil) + var _ gobot.Driver = (*MPU6050Driver)(nil) // Does its adaptor implements the I2cInterface? driver := initTestMPU6050Driver() diff --git a/platforms/i2c/test_helper.go b/platforms/i2c/test_helper.go index 75a181b76..49b7fd312 100644 --- a/platforms/i2c/test_helper.go +++ b/platforms/i2c/test_helper.go @@ -1,9 +1,5 @@ package i2c -import ( - "github.com/hybridgroup/gobot" -) - var rgb = map[string]interface{}{ "red": 1.0, "green": 1.0, @@ -19,7 +15,7 @@ var green = castColor("green") var blue = castColor("blue") type i2cTestAdaptor struct { - gobot.Adaptor + name string i2cReadImpl func() []byte } @@ -28,15 +24,13 @@ func (t *i2cTestAdaptor) I2cRead(uint) (data []byte, err error) { return t.i2cReadImpl(), nil } func (t *i2cTestAdaptor) I2cWrite([]byte) (err error) { return nil } +func (t *i2cTestAdaptor) Name() string { return t.name } func (t *i2cTestAdaptor) Connect() (errs []error) { return } func (t *i2cTestAdaptor) Finalize() (errs []error) { return } func newI2cTestAdaptor(name string) *i2cTestAdaptor { return &i2cTestAdaptor{ - Adaptor: *gobot.NewAdaptor( - name, - "I2cTestAdaptor", - ), + name: name, i2cReadImpl: func() []byte { return []byte{} }, diff --git a/platforms/i2c/wiichuck_driver.go b/platforms/i2c/wiichuck_driver.go index 829c83ed4..2f854ce8d 100644 --- a/platforms/i2c/wiichuck_driver.go +++ b/platforms/i2c/wiichuck_driver.go @@ -2,14 +2,18 @@ package i2c import ( "errors" + "time" "github.com/hybridgroup/gobot" ) -var _ gobot.DriverInterface = (*WiichuckDriver)(nil) +var _ gobot.Driver = (*WiichuckDriver)(nil) type WiichuckDriver struct { - gobot.Driver + name string + connection gobot.Connection + interval time.Duration + gobot.Eventer joystick map[string]float64 data map[string]float64 } @@ -22,11 +26,10 @@ type WiichuckDriver struct { // "joystick" - Get's triggered every "interval" amount of time if a joystick event occured, you can access values x, y func NewWiichuckDriver(a I2cInterface, name string) *WiichuckDriver { w := &WiichuckDriver{ - Driver: *gobot.NewDriver( - name, - "WiichuckDriver", - a.(gobot.AdaptorInterface), - ), + name: name, + connection: a.(gobot.Connection), + interval: 10 * time.Millisecond, + Eventer: gobot.NewEventer(), joystick: map[string]float64{ "sy_origin": -1, "sx_origin": -1, @@ -44,10 +47,12 @@ func NewWiichuckDriver(a I2cInterface, name string) *WiichuckDriver { w.AddEvent("joystick") return w } +func (w *WiichuckDriver) Name() string { return w.name } +func (w *WiichuckDriver) Connection() gobot.Connection { return w.connection } // adaptor returns i2c interface adaptor func (w *WiichuckDriver) adaptor() I2cInterface { - return w.Adaptor().(I2cInterface) + return w.Connection().(I2cInterface) } // Start initilizes i2c and reads from adaptor @@ -56,7 +61,7 @@ func (w *WiichuckDriver) Start() (errs []error) { if err := w.adaptor().I2cStart(0x52); err != nil { return []error{err} } - gobot.Every(w.Interval(), func() { + gobot.Every(w.interval, func() { if err := w.adaptor().I2cWrite([]byte{0x40, 0x00}); err != nil { gobot.Publish(w.Event("error"), err) return diff --git a/platforms/i2c/wiichuck_driver_test.go b/platforms/i2c/wiichuck_driver_test.go index 113099ed4..f1044e808 100644 --- a/platforms/i2c/wiichuck_driver_test.go +++ b/platforms/i2c/wiichuck_driver_test.go @@ -21,7 +21,7 @@ func initTestWiichuckDriverWithStubbedAdaptor() (*WiichuckDriver, *i2cTestAdapto // --------- TESTS func TestWiichuckDriver(t *testing.T) { // Does it implement gobot.DriverInterface? - var _ gobot.DriverInterface = (*WiichuckDriver)(nil) + var _ gobot.Driver = (*WiichuckDriver)(nil) // Does its adaptor implements the I2cInterface? driver := initTestWiichuckDriver() @@ -47,7 +47,7 @@ func TestWiichuckDriverStart(t *testing.T) { numberOfCyclesForEvery := 3 - wii.SetInterval(1 * time.Millisecond) + wii.interval = 1 * time.Millisecond gobot.Assert(t, len(wii.Start()), 0) go func() { From cca91da5edfacd86cbc1475ae7af550e41d4ac96 Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Sat, 22 Nov 2014 19:43:53 -0800 Subject: [PATCH 10/24] Refactor edison to use new adaptor interface --- platforms/intel-iot/edison/edison_adaptor.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/platforms/intel-iot/edison/edison_adaptor.go b/platforms/intel-iot/edison/edison_adaptor.go index aa6e0d2ae..84fcc69b0 100644 --- a/platforms/intel-iot/edison/edison_adaptor.go +++ b/platforms/intel-iot/edison/edison_adaptor.go @@ -10,7 +10,7 @@ import ( "github.com/hybridgroup/gobot/sysfs" ) -var _ gobot.AdaptorInterface = (*EdisonAdaptor)(nil) +var _ gobot.Adaptor = (*EdisonAdaptor)(nil) func writeFile(path string, data []byte) (i int, err error) { file, err := sysfs.OpenFile(path, os.O_WRONLY, 0644) @@ -51,7 +51,7 @@ type sysfsPin struct { } type EdisonAdaptor struct { - gobot.Adaptor + name string tristate sysfs.DigitalPin digitalPins map[int]sysfs.DigitalPin pwmPins map[int]*pwmPin @@ -184,10 +184,7 @@ func changePinMode(pin, mode string) (err error) { // creates connect function func NewEdisonAdaptor(name string) *EdisonAdaptor { return &EdisonAdaptor{ - Adaptor: *gobot.NewAdaptor( - name, - "EdisonAdaptor", - ), + name: name, connect: func(e *EdisonAdaptor) (err error) { e.tristate = sysfs.NewDigitalPin(214) if err = e.tristate.Export(); err != nil { @@ -251,6 +248,8 @@ func NewEdisonAdaptor(name string) *EdisonAdaptor { } } +func (e *EdisonAdaptor) Name() string { return e.name } + // Connect starts conection with board and creates // digitalPins and pwmPins adaptor maps func (e *EdisonAdaptor) Connect() (errs []error) { From c1ce92f582fe3fe94525aba338ddc7a59eff417a Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Sat, 22 Nov 2014 19:54:32 -0800 Subject: [PATCH 11/24] Refactor joystick to use new driver and adaptor interfaces --- platforms/joystick/joystick_adaptor.go | 12 ++++++------ platforms/joystick/joystick_driver.go | 21 ++++++++++++--------- platforms/joystick/joystick_driver_test.go | 2 +- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/platforms/joystick/joystick_adaptor.go b/platforms/joystick/joystick_adaptor.go index ae0d72c9c..7b469bd1f 100644 --- a/platforms/joystick/joystick_adaptor.go +++ b/platforms/joystick/joystick_adaptor.go @@ -2,11 +2,12 @@ package joystick import ( "errors" + "github.com/hybridgroup/go-sdl2/sdl" "github.com/hybridgroup/gobot" ) -var _ gobot.AdaptorInterface = (*JoystickAdaptor)(nil) +var _ gobot.Adaptor = (*JoystickAdaptor)(nil) type joystick interface { Close() @@ -14,7 +15,7 @@ type joystick interface { } type JoystickAdaptor struct { - gobot.Adaptor + name string joystick joystick connect func(*JoystickAdaptor) (err error) } @@ -24,10 +25,7 @@ type JoystickAdaptor struct { // or panics if no joystick can be found func NewJoystickAdaptor(name string) *JoystickAdaptor { return &JoystickAdaptor{ - Adaptor: *gobot.NewAdaptor( - name, - "JoystickAdaptor", - ), + name: name, connect: func(j *JoystickAdaptor) (err error) { sdl.Init(sdl.INIT_JOYSTICK) if sdl.NumJoysticks() > 0 { @@ -39,6 +37,8 @@ func NewJoystickAdaptor(name string) *JoystickAdaptor { } } +func (j *JoystickAdaptor) Name() string { return j.name } + // Connect returns true if connection to device is succesfull func (j *JoystickAdaptor) Connect() (errs []error) { if err := j.connect(j); err != nil { diff --git a/platforms/joystick/joystick_driver.go b/platforms/joystick/joystick_driver.go index cea8b9d1a..521274432 100644 --- a/platforms/joystick/joystick_driver.go +++ b/platforms/joystick/joystick_driver.go @@ -11,10 +11,13 @@ import ( "github.com/hybridgroup/gobot" ) -var _ gobot.DriverInterface = (*JoystickDriver)(nil) +var _ gobot.Driver = (*JoystickDriver)(nil) type JoystickDriver struct { - gobot.Driver + name string + interval time.Duration + connection gobot.Connection + gobot.Eventer configPath string config joystickConfig poll func() sdl.Event @@ -49,11 +52,9 @@ type joystickConfig struct { // (button)_release - triggered when (button) is released func NewJoystickDriver(a *JoystickAdaptor, name string, config string) *JoystickDriver { d := &JoystickDriver{ - Driver: *gobot.NewDriver( - name, - "JoystickDriver", - a, - ), + name: name, + connection: a, + Eventer: gobot.NewEventer(), configPath: config, poll: func() sdl.Event { return sdl.PollEvent() @@ -63,10 +64,12 @@ func NewJoystickDriver(a *JoystickAdaptor, name string, config string) *Joystick d.AddEvent("error") return d } +func (j *JoystickDriver) Name() string { return j.name } +func (j *JoystickDriver) Connection() gobot.Connection { return j.connection } // adaptor returns joystick adaptor func (j *JoystickDriver) adaptor() *JoystickAdaptor { - return j.Adaptor().(*JoystickAdaptor) + return j.Connection().(*JoystickAdaptor) } // Start initiallizes event polling with defined interval @@ -99,7 +102,7 @@ func (j *JoystickDriver) Start() (errs []error) { gobot.Publish(j.Event("error"), err) } } - <-time.After(j.Interval()) + <-time.After(j.interval) } }() return diff --git a/platforms/joystick/joystick_driver_test.go b/platforms/joystick/joystick_driver_test.go index 05ccb08e7..16ada0a3c 100644 --- a/platforms/joystick/joystick_driver_test.go +++ b/platforms/joystick/joystick_driver_test.go @@ -24,7 +24,7 @@ func initTestJoystickDriver() *JoystickDriver { func TestJoystickDriverStart(t *testing.T) { d := initTestJoystickDriver() - d.SetInterval(1 * time.Millisecond) + d.interval = 1 * time.Millisecond gobot.Assert(t, len(d.Start()), 0) <-time.After(2 * time.Millisecond) } From b57a26c5cb8ce283d73eb989393f829e9430c7ba Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Fri, 28 Nov 2014 17:52:01 -0800 Subject: [PATCH 12/24] Refactor leap to use new driver and adaptor interfaces --- platforms/leap/leap_motion_adaptor.go | 19 ++++++++++--------- platforms/leap/leap_motion_adaptor_test.go | 3 ++- platforms/leap/leap_motion_driver.go | 18 ++++++++++-------- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/platforms/leap/leap_motion_adaptor.go b/platforms/leap/leap_motion_adaptor.go index 1c70fc541..b96fd4230 100644 --- a/platforms/leap/leap_motion_adaptor.go +++ b/platforms/leap/leap_motion_adaptor.go @@ -1,16 +1,18 @@ package leap import ( - "code.google.com/p/go.net/websocket" "fmt" - "github.com/hybridgroup/gobot" "io" + + "code.google.com/p/go.net/websocket" + "github.com/hybridgroup/gobot" ) -var _ gobot.AdaptorInterface = (*LeapMotionAdaptor)(nil) +var _ gobot.Adaptor = (*LeapMotionAdaptor)(nil) type LeapMotionAdaptor struct { - gobot.Adaptor + name string + port string ws io.ReadWriteCloser connect func(*LeapMotionAdaptor) (err error) } @@ -18,11 +20,8 @@ type LeapMotionAdaptor struct { // NewLeapMotionAdaptor creates a new leap motion adaptor using specified name and port func NewLeapMotionAdaptor(name string, port string) *LeapMotionAdaptor { return &LeapMotionAdaptor{ - Adaptor: *gobot.NewAdaptor( - name, - "LeapMotionAdaptor", - port, - ), + name: name, + port: port, connect: func(l *LeapMotionAdaptor) (err error) { ws, err := websocket.Dial( fmt.Sprintf("ws://%v/v3.json", l.Port()), @@ -37,6 +36,8 @@ func NewLeapMotionAdaptor(name string, port string) *LeapMotionAdaptor { }, } } +func (l *LeapMotionAdaptor) Name() string { return l.name } +func (l *LeapMotionAdaptor) Port() string { return l.port } // Connect returns true if connection to leap motion is established succesfully func (l *LeapMotionAdaptor) Connect() (errs []error) { diff --git a/platforms/leap/leap_motion_adaptor_test.go b/platforms/leap/leap_motion_adaptor_test.go index 4c1934b65..8eec30384 100644 --- a/platforms/leap/leap_motion_adaptor_test.go +++ b/platforms/leap/leap_motion_adaptor_test.go @@ -1,8 +1,9 @@ package leap import ( - "github.com/hybridgroup/gobot" "testing" + + "github.com/hybridgroup/gobot" ) func initTestLeapMotionAdaptor() *LeapMotionAdaptor { diff --git a/platforms/leap/leap_motion_driver.go b/platforms/leap/leap_motion_driver.go index 34c995870..28fa5761a 100644 --- a/platforms/leap/leap_motion_driver.go +++ b/platforms/leap/leap_motion_driver.go @@ -8,10 +8,12 @@ import ( "github.com/hybridgroup/gobot" ) -var _ gobot.DriverInterface = (*LeapMotionDriver)(nil) +var _ gobot.Driver = (*LeapMotionDriver)(nil) type LeapMotionDriver struct { - gobot.Driver + name string + connection gobot.Connection + gobot.Eventer } var receive = func(ws io.ReadWriteCloser) []byte { @@ -26,20 +28,20 @@ var receive = func(ws io.ReadWriteCloser) []byte { // "message" - Gets triggered when receiving a message from leap motion func NewLeapMotionDriver(a *LeapMotionAdaptor, name string) *LeapMotionDriver { l := &LeapMotionDriver{ - Driver: *gobot.NewDriver( - name, - "LeapMotionDriver", - a, - ), + name: name, + connection: a, + Eventer: gobot.NewEventer(), } l.AddEvent("message") return l } +func (l *LeapMotionDriver) Name() string { return l.name } +func (l *LeapMotionDriver) Connection() gobot.Connection { return l.connection } // adaptor returns leap motion adaptor func (l *LeapMotionDriver) adaptor() *LeapMotionAdaptor { - return l.Adaptor().(*LeapMotionAdaptor) + return l.Connection().(*LeapMotionAdaptor) } // Start inits leap motion driver by enabling gestures From 677d54eb8655d8964a94e45a5fe5e7710e0ac9f8 Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Fri, 28 Nov 2014 17:56:34 -0800 Subject: [PATCH 13/24] Refactor mavlink to use new driver and adaptor interfaces --- platforms/mavlink/mavlink_adaptor.go | 15 ++++++++------- platforms/mavlink/mavlink_driver.go | 23 ++++++++++++++--------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/platforms/mavlink/mavlink_adaptor.go b/platforms/mavlink/mavlink_adaptor.go index 380523b14..168356334 100644 --- a/platforms/mavlink/mavlink_adaptor.go +++ b/platforms/mavlink/mavlink_adaptor.go @@ -7,10 +7,11 @@ import ( "github.com/tarm/goserial" ) -var _ gobot.AdaptorInterface = (*MavlinkAdaptor)(nil) +var _ gobot.Adaptor = (*MavlinkAdaptor)(nil) type MavlinkAdaptor struct { - gobot.Adaptor + name string + port string sp io.ReadWriteCloser connect func(*MavlinkAdaptor) (err error) } @@ -18,11 +19,8 @@ type MavlinkAdaptor struct { // NewMavLinkAdaptor creates a new mavlink adaptor with specified name and port func NewMavlinkAdaptor(name string, port string) *MavlinkAdaptor { return &MavlinkAdaptor{ - Adaptor: *gobot.NewAdaptor( - name, - "mavlink.MavlinkAdaptor", - port, - ), + name: name, + port: port, connect: func(m *MavlinkAdaptor) (err error) { s, err := serial.OpenPort(&serial.Config{Name: m.Port(), Baud: 57600}) if err != nil { @@ -34,6 +32,9 @@ func NewMavlinkAdaptor(name string, port string) *MavlinkAdaptor { } } +func (m *MavlinkAdaptor) Name() string { return m.name } +func (m *MavlinkAdaptor) Port() string { return m.port } + // Connect returns true if connection to device is successful func (m *MavlinkAdaptor) Connect() (errs []error) { if err := m.connect(m); err != nil { diff --git a/platforms/mavlink/mavlink_driver.go b/platforms/mavlink/mavlink_driver.go index ec4ed8477..2ffd123f9 100644 --- a/platforms/mavlink/mavlink_driver.go +++ b/platforms/mavlink/mavlink_driver.go @@ -7,10 +7,13 @@ import ( common "github.com/hybridgroup/gobot/platforms/mavlink/common" ) -var _ gobot.DriverInterface = (*MavlinkDriver)(nil) +var _ gobot.Driver = (*MavlinkDriver)(nil) type MavlinkDriver struct { - gobot.Driver + name string + connection gobot.Connection + interval time.Duration + gobot.Eventer } type MavlinkInterface interface { @@ -23,11 +26,10 @@ type MavlinkInterface interface { // "message" - triggered when a new valid message is processed func NewMavlinkDriver(a *MavlinkAdaptor, name string) *MavlinkDriver { m := &MavlinkDriver{ - Driver: *gobot.NewDriver( - name, - "mavlink.MavlinkDriver", - a, - ), + name: name, + connection: a, + Eventer: gobot.NewEventer(), + interval: 10 * time.Millisecond, } m.AddEvent("packet") @@ -37,9 +39,12 @@ func NewMavlinkDriver(a *MavlinkAdaptor, name string) *MavlinkDriver { return m } +func (m *MavlinkDriver) Connection() gobot.Connection { return m.connection } +func (m *MavlinkDriver) Name() string { return m.name } + // adaptor returns driver associated adaptor func (m *MavlinkDriver) adaptor() *MavlinkAdaptor { - return m.Driver.Adaptor().(*MavlinkAdaptor) + return m.Connection().(*MavlinkAdaptor) } // Start begins process to read mavlink packets every m.Interval @@ -59,7 +64,7 @@ func (m *MavlinkDriver) Start() (errs []error) { continue } gobot.Publish(m.Event("message"), message) - <-time.After(m.Interval()) + <-time.After(m.interval) } }() return From 58dd2923dff83b65f7d66f9d9a0b5f658012b724 Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Fri, 28 Nov 2014 17:58:16 -0800 Subject: [PATCH 14/24] Refactor mqtt to use new adaptor interface --- platforms/mqtt/mqtt_adaptor.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/platforms/mqtt/mqtt_adaptor.go b/platforms/mqtt/mqtt_adaptor.go index 276d76b3f..b3c101f32 100644 --- a/platforms/mqtt/mqtt_adaptor.go +++ b/platforms/mqtt/mqtt_adaptor.go @@ -5,10 +5,10 @@ import ( "github.com/hybridgroup/gobot" ) -var _ gobot.AdaptorInterface = (*MqttAdaptor)(nil) +var _ gobot.Adaptor = (*MqttAdaptor)(nil) type MqttAdaptor struct { - gobot.Adaptor + name string Host string clientID string client *mqtt.MqttClient @@ -17,14 +17,12 @@ type MqttAdaptor struct { // NewMqttAdaptor creates a new mqtt adaptor with specified name, host and client id func NewMqttAdaptor(name string, host string, clientID string) *MqttAdaptor { return &MqttAdaptor{ - Adaptor: *gobot.NewAdaptor( - name, - "MqttAdaptor", - ), + name: name, Host: host, clientID: clientID, } } +func (a *MqttAdaptor) Name() string { return a.name } // Connect returns true if connection to mqtt is established func (a *MqttAdaptor) Connect() (errs []error) { From 903f7470af494714c2b592a3dc0a80a272de5d20 Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Fri, 28 Nov 2014 18:01:31 -0800 Subject: [PATCH 15/24] Refactor neurosky to use new driver and adaptor interfaces --- platforms/neurosky/neurosky_adaptor.go | 14 +++++++------- platforms/neurosky/neurosky_driver.go | 18 ++++++++++-------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/platforms/neurosky/neurosky_adaptor.go b/platforms/neurosky/neurosky_adaptor.go index f836e13a6..222da413c 100644 --- a/platforms/neurosky/neurosky_adaptor.go +++ b/platforms/neurosky/neurosky_adaptor.go @@ -7,10 +7,11 @@ import ( "github.com/tarm/goserial" ) -var _ gobot.AdaptorInterface = (*NeuroskyAdaptor)(nil) +var _ gobot.Adaptor = (*NeuroskyAdaptor)(nil) type NeuroskyAdaptor struct { - gobot.Adaptor + name string + port string sp io.ReadWriteCloser connect func(*NeuroskyAdaptor) (err error) } @@ -18,11 +19,8 @@ type NeuroskyAdaptor struct { // NewNeuroskyAdaptor creates a neurosky adaptor with specified name func NewNeuroskyAdaptor(name string, port string) *NeuroskyAdaptor { return &NeuroskyAdaptor{ - Adaptor: *gobot.NewAdaptor( - name, - "NeuroskyAdaptor", - port, - ), + name: name, + port: port, connect: func(n *NeuroskyAdaptor) (err error) { sp, err := serial.OpenPort(&serial.Config{Name: n.Port(), Baud: 57600}) if err != nil { @@ -33,6 +31,8 @@ func NewNeuroskyAdaptor(name string, port string) *NeuroskyAdaptor { }, } } +func (n *NeuroskyAdaptor) Name() string { return n.name } +func (n *NeuroskyAdaptor) Port() string { return n.port } // Connect returns true if connection to device is successful func (n *NeuroskyAdaptor) Connect() (errs []error) { diff --git a/platforms/neurosky/neurosky_driver.go b/platforms/neurosky/neurosky_driver.go index 42f7b6415..7e1afedf2 100644 --- a/platforms/neurosky/neurosky_driver.go +++ b/platforms/neurosky/neurosky_driver.go @@ -6,7 +6,7 @@ import ( "github.com/hybridgroup/gobot" ) -var _ gobot.DriverInterface = (*NeuroskyDriver)(nil) +var _ gobot.Driver = (*NeuroskyDriver)(nil) const BTSync byte = 0xAA @@ -32,7 +32,9 @@ const CodeWave byte = 0x80 const CodeAsicEEG byte = 0x83 type NeuroskyDriver struct { - gobot.Driver + name string + connection gobot.Connection + gobot.Eventer } type EEG struct { @@ -58,11 +60,9 @@ type EEG struct { // eeg - showing eeg data func NewNeuroskyDriver(a *NeuroskyAdaptor, name string) *NeuroskyDriver { n := &NeuroskyDriver{ - Driver: *gobot.NewDriver( - name, - "NeuroskyDriver", - a, - ), + name: name, + connection: a, + Eventer: gobot.NewEventer(), } n.AddEvent("extended") @@ -76,10 +76,12 @@ func NewNeuroskyDriver(a *NeuroskyAdaptor, name string) *NeuroskyDriver { return n } +func (n *NeuroskyDriver) Connection() gobot.Connection { return n.connection } +func (n *NeuroskyDriver) Name() string { return n.name } // adaptor returns neurosky adaptor func (n *NeuroskyDriver) adaptor() *NeuroskyAdaptor { - return n.Adaptor().(*NeuroskyAdaptor) + return n.Connection().(*NeuroskyAdaptor) } // Start creates a go routine to listen from serial port From dcfc8e47ccba61b6b2da4229b9b6a8270b62f517 Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Fri, 28 Nov 2014 18:05:19 -0800 Subject: [PATCH 16/24] Refactor opencv to use new driver interfaces --- platforms/opencv/camera_driver.go | 29 +++++++++++++++++------------ platforms/opencv/window_driver.go | 12 ++++++------ 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/platforms/opencv/camera_driver.go b/platforms/opencv/camera_driver.go index 2b8e2f947..7312f0133 100644 --- a/platforms/opencv/camera_driver.go +++ b/platforms/opencv/camera_driver.go @@ -3,29 +3,31 @@ package opencv import ( "errors" + "time" + cv "github.com/hybridgroup/go-opencv/opencv" "github.com/hybridgroup/gobot" - "time" ) -var _ gobot.DriverInterface = (*CameraDriver)(nil) +var _ gobot.Driver = (*CameraDriver)(nil) type CameraDriver struct { - gobot.Driver - camera capture - Source interface{} - start func(*CameraDriver) (err error) + name string + camera capture + interval time.Duration + Source interface{} + start func(*CameraDriver) (err error) + gobot.Eventer } // NewCameraDriver creates a new driver with specified name and source. // It also creates a start function to either set camera as a File or Camera capture. func NewCameraDriver(name string, source interface{}) *CameraDriver { c := &CameraDriver{ - Driver: *gobot.NewDriver( - name, - "CameraDriver", - ), - Source: source, + name: name, + Eventer: gobot.NewEventer(), + Source: source, + interval: 10 * time.Millisecond, start: func(c *CameraDriver) (err error) { switch v := c.Source.(type) { case string: @@ -44,6 +46,9 @@ func NewCameraDriver(name string, source interface{}) *CameraDriver { return c } +func (c *CameraDriver) Name() string { return c.name } +func (c *CameraDriver) Connection() gobot.Connection { return nil } + // Start initializes camera by grabbing a frame // every `interval` and publishing an frame event func (c *CameraDriver) Start() (errs []error) { @@ -58,7 +63,7 @@ func (c *CameraDriver) Start() (errs []error) { gobot.Publish(c.Event("frame"), image) } } - <-time.After(c.Interval()) + <-time.After(c.interval) } }() return diff --git a/platforms/opencv/window_driver.go b/platforms/opencv/window_driver.go index 965d717df..d020a58ad 100644 --- a/platforms/opencv/window_driver.go +++ b/platforms/opencv/window_driver.go @@ -5,10 +5,10 @@ import ( "github.com/hybridgroup/gobot" ) -var _ gobot.DriverInterface = (*WindowDriver)(nil) +var _ gobot.Driver = (*WindowDriver)(nil) type WindowDriver struct { - gobot.Driver + name string window window start func(*WindowDriver) } @@ -17,16 +17,16 @@ type WindowDriver struct { // It adds an start function to initialize window func NewWindowDriver(name string) *WindowDriver { return &WindowDriver{ - Driver: *gobot.NewDriver( - name, - "WindowDriver", - ), + name: name, start: func(w *WindowDriver) { w.window = cv.NewWindow(w.Name(), cv.CV_WINDOW_NORMAL) }, } } +func (w *WindowDriver) Name() string { return w.name } +func (w *WindowDriver) Connection() gobot.Connection { return nil } + // Start starts window thread and driver func (w *WindowDriver) Start() (errs []error) { cv.StartWindowThread() From d03e6490ae6f8fa95b33909faedfe2aef0733545 Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Fri, 28 Nov 2014 18:10:05 -0800 Subject: [PATCH 17/24] Refactor pebble to use new driver and adaptor interfaces --- platforms/pebble/pebble_adaptor.go | 11 +++++------ platforms/pebble/pebble_adaptor_test.go | 3 ++- platforms/pebble/pebble_driver.go | 20 ++++++++++++-------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/platforms/pebble/pebble_adaptor.go b/platforms/pebble/pebble_adaptor.go index 0421ef4f9..f777ffdff 100644 --- a/platforms/pebble/pebble_adaptor.go +++ b/platforms/pebble/pebble_adaptor.go @@ -4,22 +4,21 @@ import ( "github.com/hybridgroup/gobot" ) -var _ gobot.AdaptorInterface = (*PebbleAdaptor)(nil) +var _ gobot.Adaptor = (*PebbleAdaptor)(nil) type PebbleAdaptor struct { - gobot.Adaptor + name string } // NewPebbleAdaptor creates a new pebble adaptor with specified name func NewPebbleAdaptor(name string) *PebbleAdaptor { return &PebbleAdaptor{ - Adaptor: *gobot.NewAdaptor( - name, - "PebbleAdaptor", - ), + name: name, } } +func (a *PebbleAdaptor) Name() string { return a.name } + // Connect returns true if connection to pebble is established succesfully func (a *PebbleAdaptor) Connect() (errs []error) { return diff --git a/platforms/pebble/pebble_adaptor_test.go b/platforms/pebble/pebble_adaptor_test.go index ff29735e1..2192de278 100644 --- a/platforms/pebble/pebble_adaptor_test.go +++ b/platforms/pebble/pebble_adaptor_test.go @@ -1,8 +1,9 @@ package pebble import ( - "github.com/hybridgroup/gobot" "testing" + + "github.com/hybridgroup/gobot" ) func initTestPebbleAdaptor() *PebbleAdaptor { diff --git a/platforms/pebble/pebble_driver.go b/platforms/pebble/pebble_driver.go index 2c358734d..d25b84b99 100644 --- a/platforms/pebble/pebble_driver.go +++ b/platforms/pebble/pebble_driver.go @@ -4,10 +4,13 @@ import ( "github.com/hybridgroup/gobot" ) -var _ gobot.DriverInterface = (*PebbleDriver)(nil) +var _ gobot.Driver = (*PebbleDriver)(nil) type PebbleDriver struct { - gobot.Driver + name string + connection gobot.Connection + gobot.Commander + gobot.Eventer Messages []string } @@ -22,12 +25,11 @@ type PebbleDriver struct { // "pending_message" func NewPebbleDriver(adaptor *PebbleAdaptor, name string) *PebbleDriver { p := &PebbleDriver{ - Driver: *gobot.NewDriver( - name, - "PebbleDriver", - adaptor, - ), - Messages: []string{}, + name: name, + connection: adaptor, + Messages: []string{}, + Eventer: gobot.NewEventer(), + Commander: gobot.NewCommander(), } p.AddEvent("button") @@ -50,6 +52,8 @@ func NewPebbleDriver(adaptor *PebbleAdaptor, name string) *PebbleDriver { return p } +func (d *PebbleDriver) Name() string { return d.name } +func (d *PebbleDriver) Connection() gobot.Connection { return d.connection } // Start returns true if driver is initialized correctly func (d *PebbleDriver) Start() (errs []error) { return } From acd7cc7ea8999540ea77f9c2f79075180a841578 Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Fri, 28 Nov 2014 18:11:35 -0800 Subject: [PATCH 18/24] Refactor raspi to use new adaptor interface --- platforms/raspi/raspi_adaptor.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/platforms/raspi/raspi_adaptor.go b/platforms/raspi/raspi_adaptor.go index 61c723167..a3e923472 100644 --- a/platforms/raspi/raspi_adaptor.go +++ b/platforms/raspi/raspi_adaptor.go @@ -13,7 +13,7 @@ import ( "github.com/hybridgroup/gobot/sysfs" ) -var _ gobot.AdaptorInterface = (*RaspiAdaptor)(nil) +var _ gobot.Adaptor = (*RaspiAdaptor)(nil) var boardRevision = func() (string, string) { cat, _ := exec.Command("cat", "/proc/cpuinfo").Output() @@ -46,7 +46,7 @@ var boardRevision = func() (string, string) { } type RaspiAdaptor struct { - gobot.Adaptor + name string revision string i2cLocation string digitalPins map[int]sysfs.DigitalPin @@ -143,10 +143,7 @@ var pins = map[string]map[string]int{ // NewRaspiAdaptor creates a RaspiAdaptor with specified name and func NewRaspiAdaptor(name string) *RaspiAdaptor { r := &RaspiAdaptor{ - Adaptor: *gobot.NewAdaptor( - name, - "RaspiAdaptor", - ), + name: name, digitalPins: make(map[int]sysfs.DigitalPin), } rev, i2cLoc := boardRevision() @@ -154,6 +151,7 @@ func NewRaspiAdaptor(name string) *RaspiAdaptor { r.i2cLocation = i2cLoc return r } +func (r *RaspiAdaptor) Name() string { return r.name } // Connect starts conection with board and creates // digitalPins and pwmPins adaptor maps From 57978d87e96c633074e771557bfa7e0026abbdab Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Fri, 28 Nov 2014 18:15:11 -0800 Subject: [PATCH 19/24] Refactor spark to use new adaptor interface --- platforms/spark/spark_core_adaptor.go | 12 ++++-------- platforms/spark/spark_core_adaptor_test.go | 16 ++++------------ 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/platforms/spark/spark_core_adaptor.go b/platforms/spark/spark_core_adaptor.go index 396c75bde..95fbeaf44 100644 --- a/platforms/spark/spark_core_adaptor.go +++ b/platforms/spark/spark_core_adaptor.go @@ -11,10 +11,10 @@ import ( "github.com/hybridgroup/gobot" ) -var _ gobot.AdaptorInterface = (*SparkCoreAdaptor)(nil) +var _ gobot.Adaptor = (*SparkCoreAdaptor)(nil) type SparkCoreAdaptor struct { - gobot.Adaptor + name string DeviceID string AccessToken string APIServer string @@ -24,25 +24,21 @@ type SparkCoreAdaptor struct { // using api.spark.io server as default func NewSparkCoreAdaptor(name string, deviceID string, accessToken string) *SparkCoreAdaptor { return &SparkCoreAdaptor{ - Adaptor: *gobot.NewAdaptor( - name, - "SparkCoreAdaptor", - ), + name: name, DeviceID: deviceID, AccessToken: accessToken, APIServer: "https://api.spark.io", } } +func (s *SparkCoreAdaptor) Name() string { return s.name } // Connect returns true if connection to spark core is succesfull func (s *SparkCoreAdaptor) Connect() (errs []error) { - s.SetConnected(true) return } // Finalize returns true if connection to spark core is finalized successfully func (s *SparkCoreAdaptor) Finalize() (errs []error) { - s.SetConnected(false) return } diff --git a/platforms/spark/spark_core_adaptor_test.go b/platforms/spark/spark_core_adaptor_test.go index c8426a4e9..08ca19db6 100644 --- a/platforms/spark/spark_core_adaptor_test.go +++ b/platforms/spark/spark_core_adaptor_test.go @@ -54,14 +54,12 @@ func initTestSparkCoreAdaptor() *SparkCoreAdaptor { // TESTS func TestSparkCoreAdaptor(t *testing.T) { - // does it implements AdaptorInterface? - var _ gobot.AdaptorInterface = (*SparkCoreAdaptor)(nil) + var _ gobot.Adaptor = (*SparkCoreAdaptor)(nil) - //does it embed gobot.Adaptor? - var a interface{} = initTestSparkCoreAdaptor().Adaptor + var a interface{} = initTestSparkCoreAdaptor() _, ok := a.(gobot.Adaptor) if !ok { - t.Errorf("SparkCoreAdaptor{}.Adaptor should be a gobot.Adaptor") + t.Errorf("SparkCoreAdaptor{} should be a gobot.Adaptor") } } @@ -79,11 +77,6 @@ func TestNewSparkCoreAdaptor(t *testing.T) { func TestSparkCoreAdaptorConnect(t *testing.T) { a := initTestSparkCoreAdaptor() gobot.Assert(t, len(a.Connect()), 0) - - a.SetConnected(false) - - gobot.Assert(t, len(a.Connect()), 0) - gobot.Assert(t, a.Connected(), true) } func TestSparkCoreAdaptorFinalize(t *testing.T) { @@ -92,7 +85,6 @@ func TestSparkCoreAdaptorFinalize(t *testing.T) { a.Connect() gobot.Assert(t, len(a.Finalize()), 0) - gobot.Assert(t, a.Connected(), false) } func TestSparkCoreAdaptorAnalogRead(t *testing.T) { @@ -221,7 +213,7 @@ func TestSparkCoreAdaptorDeviceURL(t *testing.T) { gobot.Assert(t, a.deviceURL(), "http://server/v1/devices/devID") //When APIServer is not set - a = &SparkCoreAdaptor{Adaptor: gobot.Adaptor{}, DeviceID: "myDevice", AccessToken: "token"} + a = &SparkCoreAdaptor{name: "sparkie", DeviceID: "myDevice", AccessToken: "token"} gobot.Assert(t, a.deviceURL(), "https://api.spark.io/v1/devices/myDevice") } From 61e70f7571ed4bde14c33de348d12ee039e35f05 Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Fri, 28 Nov 2014 18:21:02 -0800 Subject: [PATCH 20/24] Refactor sphero to use new driver and adaptor interfaces --- platforms/sphero/sphero_adaptor.go | 27 +++++++++++++------------ platforms/sphero/sphero_adaptor_test.go | 3 ++- platforms/sphero/sphero_driver.go | 21 +++++++++++-------- 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/platforms/sphero/sphero_adaptor.go b/platforms/sphero/sphero_adaptor.go index 86163b361..e5c6fc664 100644 --- a/platforms/sphero/sphero_adaptor.go +++ b/platforms/sphero/sphero_adaptor.go @@ -7,41 +7,42 @@ import ( "github.com/tarm/goserial" ) -var _ gobot.AdaptorInterface = (*SpheroAdaptor)(nil) +var _ gobot.Adaptor = (*SpheroAdaptor)(nil) // Represents a Connection to a Sphero type SpheroAdaptor struct { - gobot.Adaptor - sp io.ReadWriteCloser - connect func(*SpheroAdaptor) (err error) + name string + port string + sp io.ReadWriteCloser + connected bool + connect func(*SpheroAdaptor) (err error) } // NewSpheroAdaptor returns a new SpheroAdaptor given a name and port func NewSpheroAdaptor(name string, port string) *SpheroAdaptor { return &SpheroAdaptor{ - Adaptor: *gobot.NewAdaptor( - name, - "SpheroAdaptor", - port, - ), + name: name, + port: port, connect: func(a *SpheroAdaptor) (err error) { c := &serial.Config{Name: a.Port(), Baud: 115200} s, err := serial.OpenPort(c) if err != nil { return err } + a.connected = true a.sp = s return }, } } +func (a *SpheroAdaptor) Name() string { return a.name } +func (a *SpheroAdaptor) Port() string { return a.port } // Connect initiates a connection to the Sphero. Returns true on successful connection. func (a *SpheroAdaptor) Connect() (errs []error) { if err := a.connect(a); err != nil { return []error{err} } - a.SetConnected(true) return } @@ -49,7 +50,7 @@ func (a *SpheroAdaptor) Connect() (errs []error) { // it will first close that connection and then establish a new connection. // Returns true on Successful reconnection func (a *SpheroAdaptor) Reconnect() (errs []error) { - if a.Connected() == true { + if a.connected == true { a.Disconnect() } return a.Connect() @@ -60,11 +61,11 @@ func (a *SpheroAdaptor) Disconnect() (errs []error) { if err := a.sp.Close(); err != nil { return []error{err} } - a.SetConnected(false) + a.connected = false return } // Finalize finalizes the SpheroAdaptor func (a *SpheroAdaptor) Finalize() (errs []error) { - return + return a.Disconnect() } diff --git a/platforms/sphero/sphero_adaptor_test.go b/platforms/sphero/sphero_adaptor_test.go index 1df6e4b4b..05fb3b4b3 100644 --- a/platforms/sphero/sphero_adaptor_test.go +++ b/platforms/sphero/sphero_adaptor_test.go @@ -1,8 +1,9 @@ package sphero import ( - "github.com/hybridgroup/gobot" "testing" + + "github.com/hybridgroup/gobot" ) func initTestSpheroAdaptor() *SpheroAdaptor { diff --git a/platforms/sphero/sphero_driver.go b/platforms/sphero/sphero_driver.go index 1add47d56..b0dd117fe 100644 --- a/platforms/sphero/sphero_driver.go +++ b/platforms/sphero/sphero_driver.go @@ -9,7 +9,7 @@ import ( "github.com/hybridgroup/gobot" ) -var _ gobot.DriverInterface = (*SpheroDriver)(nil) +var _ gobot.Driver = (*SpheroDriver)(nil) type packet struct { header []uint8 @@ -19,12 +19,15 @@ type packet struct { // Represents a Sphero type SpheroDriver struct { - gobot.Driver + name string + connection gobot.Connection seq uint8 asyncResponse [][]uint8 syncResponse [][]uint8 packetChannel chan *packet responseChannel chan []uint8 + gobot.Eventer + gobot.Commander } type Collision struct { @@ -51,11 +54,10 @@ type Collision struct { // "SetStabilization" - See SpheroDriver.SetStabilization func NewSpheroDriver(a *SpheroAdaptor, name string) *SpheroDriver { s := &SpheroDriver{ - Driver: *gobot.NewDriver( - name, - "SpheroDriver", - a, - ), + name: name, + connection: a, + Eventer: gobot.NewEventer(), + Commander: gobot.NewCommander(), packetChannel: make(chan *packet, 1024), responseChannel: make(chan []uint8, 1024), } @@ -106,8 +108,11 @@ func NewSpheroDriver(a *SpheroAdaptor, name string) *SpheroDriver { return s } +func (s *SpheroDriver) Name() string { return s.name } +func (s *SpheroDriver) Connection() gobot.Connection { return s.connection } + func (s *SpheroDriver) adaptor() *SpheroAdaptor { - return s.Adaptor().(*SpheroAdaptor) + return s.Connection().(*SpheroAdaptor) } // Start starts the SpheroDriver and enables Collision Detection. From 705041021711a13c652c38e8639d3698c985c9b4 Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Fri, 28 Nov 2014 18:37:03 -0800 Subject: [PATCH 21/24] Add optional interval parameter for drivers which poll at an interval --- platforms/gpio/analog_sensor_driver.go | 6 +++++- platforms/gpio/makey_button_driver.go | 6 +++++- platforms/i2c/hmc6352_driver.go | 3 +-- platforms/i2c/mpl115a2_driver.go | 6 +++++- platforms/i2c/mpu6050_driver.go | 15 ++++++++++----- platforms/i2c/wiichuck_driver.go | 6 +++++- platforms/joystick/joystick_driver.go | 9 +++++++-- platforms/mavlink/mavlink_driver.go | 6 +++++- platforms/opencv/camera_driver.go | 6 +++++- 9 files changed, 48 insertions(+), 15 deletions(-) diff --git a/platforms/gpio/analog_sensor_driver.go b/platforms/gpio/analog_sensor_driver.go index d61e7fea7..4e39c4edc 100644 --- a/platforms/gpio/analog_sensor_driver.go +++ b/platforms/gpio/analog_sensor_driver.go @@ -22,7 +22,7 @@ type AnalogSensorDriver struct { // // Adds the following API Commands: // "Read" - See AnalogSensor.Read -func NewAnalogSensorDriver(a AnalogReader, name string, pin string) *AnalogSensorDriver { +func NewAnalogSensorDriver(a AnalogReader, name string, pin string, v ...time.Duration) *AnalogSensorDriver { d := &AnalogSensorDriver{ name: name, connection: a.(gobot.Connection), @@ -32,6 +32,10 @@ func NewAnalogSensorDriver(a AnalogReader, name string, pin string) *AnalogSenso interval: 10 * time.Millisecond, } + if len(v) > 0 { + d.interval = v[0] + } + d.AddEvent("data") d.AddEvent("error") d.AddCommand("Read", func(params map[string]interface{}) interface{} { diff --git a/platforms/gpio/makey_button_driver.go b/platforms/gpio/makey_button_driver.go index b3fe8c638..d5caaeb8d 100644 --- a/platforms/gpio/makey_button_driver.go +++ b/platforms/gpio/makey_button_driver.go @@ -20,7 +20,7 @@ type MakeyButtonDriver struct { } // NewMakeyButtonDriver returns a new MakeyButtonDriver given a DigitalRead, name and pin. -func NewMakeyButtonDriver(a DigitalReader, name string, pin string) *MakeyButtonDriver { +func NewMakeyButtonDriver(a DigitalReader, name string, pin string, v ...time.Duration) *MakeyButtonDriver { m := &MakeyButtonDriver{ name: name, connection: a.(gobot.Connection), @@ -30,6 +30,10 @@ func NewMakeyButtonDriver(a DigitalReader, name string, pin string) *MakeyButton interval: 10 * time.Millisecond, } + if len(v) > 0 { + m.interval = v[0] + } + m.AddEvent("error") m.AddEvent("push") m.AddEvent("release") diff --git a/platforms/i2c/hmc6352_driver.go b/platforms/i2c/hmc6352_driver.go index b4fe8409c..feaef44f5 100644 --- a/platforms/i2c/hmc6352_driver.go +++ b/platforms/i2c/hmc6352_driver.go @@ -29,8 +29,7 @@ func (h *HMC6352Driver) adaptor() I2cInterface { return h.Connection().(I2cInterface) } -// Start writes initialization bytes and reads from adaptor -// using specified interval to update Heading +// Start initialized the hmc6352 func (h *HMC6352Driver) Start() (errs []error) { if err := h.adaptor().I2cStart(0x21); err != nil { return []error{err} diff --git a/platforms/i2c/mpl115a2_driver.go b/platforms/i2c/mpl115a2_driver.go index 994e8b6a9..cd9095f05 100644 --- a/platforms/i2c/mpl115a2_driver.go +++ b/platforms/i2c/mpl115a2_driver.go @@ -38,13 +38,17 @@ type MPL115A2Driver struct { } // NewMPL115A2Driver creates a new driver with specified name and i2c interface -func NewMPL115A2Driver(a I2cInterface, name string) *MPL115A2Driver { +func NewMPL115A2Driver(a I2cInterface, name string, v ...time.Duration) *MPL115A2Driver { m := &MPL115A2Driver{ name: name, connection: a.(gobot.Connection), Eventer: gobot.NewEventer(), interval: 10 * time.Millisecond, } + + if len(v) > 0 { + m.interval = v[0] + } m.AddEvent("error") return m } diff --git a/platforms/i2c/mpu6050_driver.go b/platforms/i2c/mpu6050_driver.go index 66d14e621..0e0d89c29 100644 --- a/platforms/i2c/mpu6050_driver.go +++ b/platforms/i2c/mpu6050_driver.go @@ -32,23 +32,28 @@ type ThreeDData struct { } type MPU6050Driver struct { - name string - connection gobot.Connection - interval time.Duration - gobot.Eventer + name string + connection gobot.Connection + interval time.Duration Accelerometer ThreeDData Gyroscope ThreeDData Temperature int16 + gobot.Eventer } // NewMPU6050Driver creates a new driver with specified name and i2c interface -func NewMPU6050Driver(a I2cInterface, name string) *MPU6050Driver { +func NewMPU6050Driver(a I2cInterface, name string, v ...time.Duration) *MPU6050Driver { m := &MPU6050Driver{ name: name, connection: a.(gobot.Connection), interval: 10 * time.Millisecond, Eventer: gobot.NewEventer(), } + + if len(v) > 0 { + m.interval = v[0] + } + m.AddEvent("error") return m } diff --git a/platforms/i2c/wiichuck_driver.go b/platforms/i2c/wiichuck_driver.go index 2f854ce8d..9c92dbf79 100644 --- a/platforms/i2c/wiichuck_driver.go +++ b/platforms/i2c/wiichuck_driver.go @@ -24,7 +24,7 @@ type WiichuckDriver struct { // "z"- Get's triggered every interval amount of time if the z button is pressed // "c" - Get's triggered every interval amount of time if the c button is pressed // "joystick" - Get's triggered every "interval" amount of time if a joystick event occured, you can access values x, y -func NewWiichuckDriver(a I2cInterface, name string) *WiichuckDriver { +func NewWiichuckDriver(a I2cInterface, name string, v ...time.Duration) *WiichuckDriver { w := &WiichuckDriver{ name: name, connection: a.(gobot.Connection), @@ -42,6 +42,10 @@ func NewWiichuckDriver(a I2cInterface, name string) *WiichuckDriver { }, } + if len(v) > 0 { + w.interval = v[0] + } + w.AddEvent("z") w.AddEvent("c") w.AddEvent("joystick") diff --git a/platforms/joystick/joystick_driver.go b/platforms/joystick/joystick_driver.go index 521274432..044c5a374 100644 --- a/platforms/joystick/joystick_driver.go +++ b/platforms/joystick/joystick_driver.go @@ -17,10 +17,10 @@ type JoystickDriver struct { name string interval time.Duration connection gobot.Connection - gobot.Eventer configPath string config joystickConfig poll func() sdl.Event + gobot.Eventer } // pair is a JSON representation of name and id @@ -50,7 +50,7 @@ type joystickConfig struct { // It adds the following events: // (button)_press - triggered when (button) is pressed // (button)_release - triggered when (button) is released -func NewJoystickDriver(a *JoystickAdaptor, name string, config string) *JoystickDriver { +func NewJoystickDriver(a *JoystickAdaptor, name string, config string, v ...time.Duration) *JoystickDriver { d := &JoystickDriver{ name: name, connection: a, @@ -59,6 +59,11 @@ func NewJoystickDriver(a *JoystickAdaptor, name string, config string) *Joystick poll: func() sdl.Event { return sdl.PollEvent() }, + interval: 10 * time.Millisecond, + } + + if len(v) > 0 { + d.interval = v[0] } d.AddEvent("error") diff --git a/platforms/mavlink/mavlink_driver.go b/platforms/mavlink/mavlink_driver.go index 2ffd123f9..8f573fe7a 100644 --- a/platforms/mavlink/mavlink_driver.go +++ b/platforms/mavlink/mavlink_driver.go @@ -24,7 +24,7 @@ type MavlinkInterface interface { // It add the following events: // "packet" - triggered when a new packet is read // "message" - triggered when a new valid message is processed -func NewMavlinkDriver(a *MavlinkAdaptor, name string) *MavlinkDriver { +func NewMavlinkDriver(a *MavlinkAdaptor, name string, v ...time.Duration) *MavlinkDriver { m := &MavlinkDriver{ name: name, connection: a, @@ -32,6 +32,10 @@ func NewMavlinkDriver(a *MavlinkAdaptor, name string) *MavlinkDriver { interval: 10 * time.Millisecond, } + if len(v) > 0 { + m.interval = v[0] + } + m.AddEvent("packet") m.AddEvent("message") m.AddEvent("error") diff --git a/platforms/opencv/camera_driver.go b/platforms/opencv/camera_driver.go index 7312f0133..9b12aae3e 100644 --- a/platforms/opencv/camera_driver.go +++ b/platforms/opencv/camera_driver.go @@ -22,7 +22,7 @@ type CameraDriver struct { // NewCameraDriver creates a new driver with specified name and source. // It also creates a start function to either set camera as a File or Camera capture. -func NewCameraDriver(name string, source interface{}) *CameraDriver { +func NewCameraDriver(name string, source interface{}, v ...time.Duration) *CameraDriver { c := &CameraDriver{ name: name, Eventer: gobot.NewEventer(), @@ -41,6 +41,10 @@ func NewCameraDriver(name string, source interface{}) *CameraDriver { }, } + if len(v) > 0 { + c.interval = v[0] + } + c.AddEvent("frame") return c From cad4c4abb06813dc50e694fa8d6b8dafeea8622e Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Fri, 28 Nov 2014 18:44:52 -0800 Subject: [PATCH 22/24] Clean up button driver --- platforms/gpio/button_driver.go | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/platforms/gpio/button_driver.go b/platforms/gpio/button_driver.go index 49411251f..9c9903f6c 100644 --- a/platforms/gpio/button_driver.go +++ b/platforms/gpio/button_driver.go @@ -13,18 +13,24 @@ type ButtonDriver struct { Active bool pin string name string + interval time.Duration connection gobot.Connection gobot.Eventer } // NewButtonDriver return a new ButtonDriver given a DigitalReader, name and pin -func NewButtonDriver(a DigitalReader, name string, pin string) *ButtonDriver { +func NewButtonDriver(a DigitalReader, name string, pin string, v ...time.Duration) *ButtonDriver { b := &ButtonDriver{ name: name, - connection: a.(gobot.Adaptor), + connection: a, pin: pin, Active: false, Eventer: gobot.NewEventer(), + interval: 10 * time.Millisecond, + } + + if len(v) > 0 { + b.interval = v[0] } b.AddEvent("push") @@ -56,8 +62,7 @@ func (b *ButtonDriver) Start() (errs []error) { state = newValue b.update(newValue) } - //<-time.After(b.Interval()) - <-time.After(100 * time.Millisecond) + <-time.After(b.interval) } }() return @@ -69,17 +74,6 @@ func (b *ButtonDriver) Halt() (errs []error) { return } func (b *ButtonDriver) Name() string { return b.name } func (b *ButtonDriver) Pin() string { return b.pin } func (b *ButtonDriver) Connection() gobot.Connection { return b.connection } -func (b *ButtonDriver) String() string { return "ButtonDriver" } -func (b *ButtonDriver) ToJSON() *gobot.JSONDevice { - return &gobot.JSONDevice{ - Name: b.Name(), - Driver: b.String(), - Connection: b.Connection().Name(), - //Commands: l.Commands(), - //Commands: l.Commands(), - } - -} func (b *ButtonDriver) readState() (val int, err error) { return b.adaptor().DigitalRead(b.Pin()) From 972219c62b1fe53d65408881b7926fd489592ff8 Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Fri, 28 Nov 2014 18:53:09 -0800 Subject: [PATCH 23/24] Fix failing test --- platforms/gpio/button_driver.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platforms/gpio/button_driver.go b/platforms/gpio/button_driver.go index 9c9903f6c..791c9c7fb 100644 --- a/platforms/gpio/button_driver.go +++ b/platforms/gpio/button_driver.go @@ -22,7 +22,7 @@ type ButtonDriver struct { func NewButtonDriver(a DigitalReader, name string, pin string, v ...time.Duration) *ButtonDriver { b := &ButtonDriver{ name: name, - connection: a, + connection: a.(gobot.Connection), pin: pin, Active: false, Eventer: gobot.NewEventer(), From 3047c5c092af9ec1ae59fb1de99bf9947e4b0d55 Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Fri, 28 Nov 2014 19:04:22 -0800 Subject: [PATCH 24/24] Pins are tired of pining --- device.go | 4 ++-- driver.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/device.go b/device.go index adba5064d..b584f8efe 100644 --- a/device.go +++ b/device.go @@ -53,8 +53,8 @@ func (d *devices) Start() (errs []error) { for _, device := range *d { info := "Starting device " + device.Name() - if piner, ok := device.(Piner); ok { - info = info + " on pin " + piner.Pin() + if pinner, ok := device.(Pinner); ok { + info = info + " on pin " + pinner.Pin() } log.Println(info + "...") diff --git a/driver.go b/driver.go index 2a206688e..f3f5ca592 100644 --- a/driver.go +++ b/driver.go @@ -7,6 +7,6 @@ type Driver interface { Connection() Connection } -type Piner interface { +type Pinner interface { Pin() string }