Skip to content

Commit

Permalink
Merge pull request hybridgroup#157 from hybridgroup/refactor_interfaces
Browse files Browse the repository at this point in the history
Refactor Adaptor and Driver interfaces
  • Loading branch information
deadprogram committed Nov 29, 2014
2 parents 67e8da6 + 3047c5c commit 91a0123
Show file tree
Hide file tree
Showing 67 changed files with 779 additions and 890 deletions.
88 changes: 3 additions & 85 deletions adaptor.go
Original file line number Diff line number Diff line change
@@ -1,93 +1,11 @@
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)
ToJSON() *JSONConnection
}

// NewAdaptor returns a new Adaptor given a name, adaptorType and optionally accepts:
//
// string: Port the adaptor connects to
//
// adaptorType is a label used for identification in the api
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 the 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 an adaptor
func (a *Adaptor) ToJSON() *JSONConnection {
return &JSONConnection{
Name: a.Name(),
Adaptor: a.Type(),
}
type Porter interface {
Port() string
}
18 changes: 0 additions & 18 deletions adaptor_test.go

This file was deleted.

30 changes: 15 additions & 15 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,43 +160,43 @@ 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.
// Writes JSON with robots representation
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)
}

// 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.
// Writes JSON with robot devices representation
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)
}
Expand All @@ -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,
)
}

Expand All @@ -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)
Expand All @@ -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,
)
}

Expand All @@ -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)
}
Expand All @@ -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,
)
}
Expand All @@ -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,
Expand Down
33 changes: 33 additions & 0 deletions commander.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package gobot

type commander struct {
commands map[string]func(map[string]interface{}) interface{}
}

type Commander interface {
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{})
}

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{}) {
command, _ = c.commands[name]
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
}
18 changes: 15 additions & 3 deletions connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"log"
"reflect"
)

// JSONConnection holds a JSON representation of a connection.
Expand All @@ -12,7 +13,15 @@ type JSONConnection struct {
Adaptor string `json:"adaptor"`
}

type Connection AdaptorInterface
// 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

Expand All @@ -33,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))
Expand Down
25 changes: 22 additions & 3 deletions device.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"log"
"reflect"
)

// JSONDevice is a JSON representation of a Gobot Device.
Expand All @@ -14,7 +15,23 @@ type JSONDevice struct {
Commands []string `json:"commands"`
}

type Device DriverInterface
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

Expand All @@ -35,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 pinner, ok := device.(Pinner); ok {
info = info + " on pin " + pinner.Pin()
}

log.Println(info + "...")
if errs = device.Start(); len(errs) > 0 {
for i, err := range errs {
Expand Down
Loading

0 comments on commit 91a0123

Please sign in to comment.