Skip to content

Commit

Permalink
Merge branch 'dev' of https://github.com/hybridgroup/gobot into pebbl…
Browse files Browse the repository at this point in the history
…e-support

* 'dev' of https://github.com/hybridgroup/gobot: (44 commits)
  Fix errors in examples
  Update i2c package
  Update gpio package
  Update sphero package and examples
  Update spark package and examples
  Update opencv package and examples
  Update neurosky package and examples
  Update leap package and examples
  Update joystick package and examples
  Update hello examples
  Update digispark package and examples
  Update beaglebone package and examples
  Update firmata examples
  Update ardrone adaptor, driver and examples
  Mark failing tests as pending
  WIP api refactor
  Fix platform tests
  Interval is now a time.Duration
  Gobot tests are green again
  After and Every now require a time.Duration instead of a string
  ...
  • Loading branch information
Javier Cervantes committed May 23, 2014
2 parents 37241b7 + 30b92ac commit 3de9d86
Show file tree
Hide file tree
Showing 105 changed files with 715 additions and 959 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,14 @@ We're busy adding documentation to our web site at http://gobot.io/ please check
Thank you!

## Contributing

* All active development is in the `dev` branch. New or updated features must be added to the `dev` branch. Hotfixes will be considered on the `master` branch in situations where it does not alter behaviour or features, only fixes a bug.
* All patches must be provided under the Apache 2.0 License
* Please use the -s option in git to "sign off" that the commit is your work and you are providing it under the Apache 2.0 License
* Submit a Github Pull Request to the appropriate branch and ideally discuss the changes with us in IRC.
* We will look at the patch, test it out, and give you feedback.
* Avoid doing minor whitespace changes, renamings, etc. along with merged content. These will be done by the maintainers from time to time but they can complicate merges and should be done seperately.
* Take care to maintain the existing coding style.
* `go fmt` your code.
* Add unit tests for any new or changed functionality.
* All pull requests should be "fast forward"
* If there are commits after yours use “git rebase -i <new_head_branch>”
Expand Down
118 changes: 42 additions & 76 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ type api struct {
start func(*api)
}

func NewApi(g gobot.Gobot) *api {
func NewApi(g *gobot.Gobot) *api {
return &api{
Gobot: g,
startFunc: func(a *api) {
gobot: g,
start: func(a *api) {
if a == nil {
return
}
Expand Down Expand Up @@ -68,170 +68,136 @@ func NewApi(g gobot.Gobot) *api {
func (a *api) Start() {
a.server = martini.Classic()

m.Use(martini.Static("robeaux"))
m.Use(cors.Allow(&cors.Options{
a.server.Use(martini.Static("robeaux"))
a.server.Use(cors.Allow(&cors.Options{
AllowAllOrigins: true,
}))

m.Get("/robots", func(res http.ResponseWriter, req *http.Request) {
a.server.Get("/robots", func(res http.ResponseWriter, req *http.Request) {
a.robots(res, req)
})

m.Get("/robots/:robotname", func(params martini.Params, res http.ResponseWriter, req *http.Request) {
a.server.Get("/robots/:robotname", func(params martini.Params, res http.ResponseWriter, req *http.Request) {
a.robot(params["robotname"], res, req)
})

m.Get("/robots/:robotname/commands", func(params martini.Params, res http.ResponseWriter, req *http.Request) {
a.server.Get("/robots/:robotname/commands", func(params martini.Params, res http.ResponseWriter, req *http.Request) {
a.robot_commands(params["robotname"], res, req)
})

robot_command_route := "/robots/:robotname/commands/:command"

m.Get(robot_command_route, func(params martini.Params, res http.ResponseWriter, req *http.Request) {
a.server.Get(robot_command_route, func(params martini.Params, res http.ResponseWriter, req *http.Request) {
a.executeRobotCommand(params["robotname"], params["command"], res, req)
})
m.Post(robot_command_route, func(params martini.Params, res http.ResponseWriter, req *http.Request) {
a.server.Post(robot_command_route, func(params martini.Params, res http.ResponseWriter, req *http.Request) {
a.executeRobotCommand(params["robotname"], params["command"], res, req)
})

m.Get("/robots/:robotname/devices", func(params martini.Params, res http.ResponseWriter, req *http.Request) {
a.server.Get("/robots/:robotname/devices", func(params martini.Params, res http.ResponseWriter, req *http.Request) {
a.robot_devices(params["robotname"], res, req)
})

m.Get("/robots/:robotname/devices/:devicename", func(params martini.Params, res http.ResponseWriter, req *http.Request) {
a.server.Get("/robots/:robotname/devices/:devicename", func(params martini.Params, res http.ResponseWriter, req *http.Request) {
a.robot_device(params["robotname"], params["devicename"], res, req)
})

m.Get("/robots/:robotname/devices/:devicename/commands", func(params martini.Params, res http.ResponseWriter, req *http.Request) {
a.server.Get("/robots/:robotname/devices/:devicename/commands", func(params martini.Params, res http.ResponseWriter, req *http.Request) {
a.robot_device_commands(params["robotname"], params["devicename"], res, req)
})

command_route := "/robots/:robotname/devices/:devicename/commands/:command"

m.Get(command_route, func(params martini.Params, res http.ResponseWriter, req *http.Request) {
a.server.Get(command_route, func(params martini.Params, res http.ResponseWriter, req *http.Request) {
a.executeCommand(params["robotname"], params["devicename"], params["command"], res, req)
})
m.Post(command_route, func(params martini.Params, res http.ResponseWriter, req *http.Request) {
a.server.Post(command_route, func(params martini.Params, res http.ResponseWriter, req *http.Request) {
a.executeCommand(params["robotname"], params["devicename"], params["command"], res, req)
})

m.Get("/robots/:robotname/connections", func(params martini.Params, res http.ResponseWriter, req *http.Request) {
a.server.Get("/robots/:robotname/connections", func(params martini.Params, res http.ResponseWriter, req *http.Request) {
a.robot_connections(params["robotname"], res, req)
})

m.Get("/robots/:robotname/connections/:connectionname", func(params martini.Params, res http.ResponseWriter, req *http.Request) {
a.server.Get("/robots/:robotname/connections/:connectionname", func(params martini.Params, res http.ResponseWriter, req *http.Request) {
a.robot_connection(params["robotname"], params["connectionname"], res, req)
})

a.start(a)
}

func (me *api) robots(res http.ResponseWriter, req *http.Request) {
jsonRobots := make([]*jsonRobot, 0)
for _, robot := range me.master.Robots {
jsonRobots = append(jsonRobots, me.formatJsonRobot(robot))
func (a *api) robots(res http.ResponseWriter, req *http.Request) {
jsonRobots := make([]*gobot.JsonRobot, 0)
for _, robot := range a.gobot.Robots {
jsonRobots = append(jsonRobots, robot.ToJson())
}
data, _ := json.Marshal(jsonRobots)
res.Header().Set("Content-Type", "application/json; charset=utf-8")
res.Write(data)
}

func (me *api) robot(name string, res http.ResponseWriter, req *http.Request) {
data, _ := json.Marshal(me.formatJsonRobot(me.master.FindRobot(name)))
func (a *api) robot(name string, res http.ResponseWriter, req *http.Request) {
data, _ := json.Marshal(a.gobot.Robot(name).ToJson())
res.Header().Set("Content-Type", "application/json; charset=utf-8")
res.Write(data)
}

func (me *api) robot_commands(name string, res http.ResponseWriter, req *http.Request) {
data, _ := json.Marshal(me.master.FindRobot(name).RobotCommands)
func (a *api) robot_commands(name string, res http.ResponseWriter, req *http.Request) {
data, _ := json.Marshal(a.gobot.Robot(name).RobotCommands)
res.Header().Set("Content-Type", "application/json; charset=utf-8")
res.Write(data)
}

func (me *api) robot_devices(name string, res http.ResponseWriter, req *http.Request) {
devices := me.master.FindRobot(name).GetDevices()
jsonDevices := make([]*jsonDevice, 0)
func (a *api) robot_devices(name string, res http.ResponseWriter, req *http.Request) {
devices := a.gobot.Robot(name).Devices()
jsonDevices := make([]*gobot.JsonDevice, 0)
for _, device := range devices {
jsonDevices = append(jsonDevices, me.formatJsonDevice(device))
jsonDevices = append(jsonDevices, device.ToJson())
}
data, _ := json.Marshal(jsonDevices)
res.Header().Set("Content-Type", "application/json; charset=utf-8")
res.Write(data)
}

func (me *api) robot_device(robot string, device string, res http.ResponseWriter, req *http.Request) {
data, _ := json.Marshal(me.formatJsonDevice(me.master.FindRobot(robot).GetDevice(device)))
func (a *api) robot_device(robot string, device string, res http.ResponseWriter, req *http.Request) {
data, _ := json.Marshal(a.gobot.Robot(robot).Device(device).ToJson())
res.Header().Set("Content-Type", "application/json; charset=utf-8")
res.Write(data)
}

func (me *api) robot_device_commands(robot string, device string, res http.ResponseWriter, req *http.Request) {
data, _ := json.Marshal(me.master.FindRobot(robot).GetDevice(device).Commands())
func (a *api) robot_device_commands(robot string, device string, res http.ResponseWriter, req *http.Request) {
data, _ := json.Marshal(a.gobot.Robot(robot).Device(device).Commands())
res.Header().Set("Content-Type", "application/json; charset=utf-8")
res.Write(data)
}

func (me *api) robot_connections(name string, res http.ResponseWriter, req *http.Request) {
connections := me.master.FindRobot(name).GetConnections()
jsonConnections := make([]*jsonConnection, 0)
func (a *api) robot_connections(name string, res http.ResponseWriter, req *http.Request) {
connections := a.gobot.Robot(name).Connections()
jsonConnections := make([]*gobot.JsonConnection, 0)
for _, connection := range connections {
jsonConnections = append(jsonConnections, me.formatJsonConnection(connection))
jsonConnections = append(jsonConnections, connection.ToJson())
}
data, _ := json.Marshal(jsonConnections)
res.Header().Set("Content-Type", "application/json; charset=utf-8")
res.Write(data)
}

func (me *api) robot_connection(robot string, connection string, res http.ResponseWriter, req *http.Request) {
data, _ := json.Marshal(me.formatJsonConnection(me.master.FindRobot(robot).GetConnection(connection)))
func (a *api) robot_connection(robot string, connection string, res http.ResponseWriter, req *http.Request) {
data, _ := json.Marshal(a.gobot.Robot(robot).Connection(connection).ToJson())
res.Header().Set("Content-Type", "application/json; charset=utf-8")
res.Write(data)
}

func (a *api) formatJsonRobot(robot *Robot) *jsonRobot {
jsonRobot := new(jsonRobot)
jsonRobot.Name = robot.Name
jsonRobot.Commands = robot.RobotCommands
jsonRobot.Connections = make([]*jsonConnection, 0)
for _, device := range robot.devices {
jsonDevice := a.formatJsonDevice(device)
jsonRobot.Connections = append(jsonRobot.Connections, jsonDevice.Connection)
jsonRobot.Devices = append(jsonRobot.Devices, jsonDevice)
}
return jsonRobot
}

func (a *api) formatJsonConnection(connection *connection) *jsonConnection {
jsonConnection := new(jsonConnection)
jsonConnection.Name = connection.Name
jsonConnection.Port = connection.Port
jsonConnection.Adaptor = connection.Type
return jsonConnection
}

func (a *api) formatJsonDevice(device *device) *jsonDevice {
jsonDevice := new(jsonDevice)
jsonDevice.Name = device.Name
jsonDevice.Driver = device.Type
jsonDevice.Connection = a.formatJsonConnection(
a.master.FindRobot(device.Robot.Name).
GetConnection(FieldByNamePtr(FieldByNamePtr(device.Driver, "Adaptor").
Interface().(AdaptorInterface), "Name").
Interface().(string)))
jsonDevice.Commands = FieldByNamePtr(device.Driver, "Commands").Interface().([]string)
return jsonDevice
}

func (a *api) executeCommand(robotname string, devicename string, commandname string, res http.ResponseWriter, req *http.Request) {
data, _ := ioutil.ReadAll(req.Body)
var body map[string]interface{}
json.Unmarshal(data, &body)
robot := a.master.FindRobot(robotname).GetDevice(devicename)
robot := a.gobot.Robot(robotname).Device(devicename)
commands := robot.Commands().([]string)
for command := range commands {
if commands[command] == commandname {
ret := make([]interface{}, 0)
for _, v := range Call(robot.Driver, commandname, body) {
for _, v := range gobot.Call(robot.Driver, commandname, body) {
ret = append(ret, v.Interface())
}
data, _ = json.Marshal(ret)
Expand All @@ -249,7 +215,7 @@ func (a *api) executeRobotCommand(robotname string, commandname string, res http
data, _ := ioutil.ReadAll(req.Body)
body := make(map[string]interface{})
json.Unmarshal(data, &body)
robot := a.master.FindRobot(robotname)
robot := a.gobot.Robot(robotname)
in := make([]reflect.Value, 1)
body["robotname"] = robotname
in[0] = reflect.ValueOf(body)
Expand Down
21 changes: 0 additions & 21 deletions api/api_convention.go

This file was deleted.

20 changes: 20 additions & 0 deletions api/api_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package api

import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"log"
"testing"
)

type null struct{}

func (null) Write(p []byte) (int, error) {
return len(p), nil
}

func TestApi(t *testing.T) {
log.SetOutput(new(null))
RegisterFailHandler(Fail)
RunSpecs(t, "Api Suite")
}
28 changes: 12 additions & 16 deletions api/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,30 @@ package api
import (
"bytes"
"encoding/json"
"github.com/hybridgroup/gobot"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"io/ioutil"
"net/http"
"net/http/httptest"
"os"
)

var _ = Describe("Master", func() {
var _ = Describe("API", func() {
var (
m *Master
m *gobot.Gobot
a *api
)

BeforeEach(func() {
m = NewMaster()
a = Api(m)
a.startFunc = func(m *api) {}
m = gobot.NewGobot()
a = NewApi(m)
a.start = func(m *api) {}

m.Robots = []*Robot{
newTestRobot("Robot 1"),
newTestRobot("Robot 2"),
newTestRobot("Robot 3"),
m.Robots = []*gobot.Robot{
gobot.NewTestRobot("Robot 1"),
gobot.NewTestRobot("Robot 2"),
gobot.NewTestRobot("Robot 3"),
}
m.trap = func(c chan os.Signal) {
c <- os.Interrupt
}
m.Start()
})

Context("when valid", func() {
Expand Down Expand Up @@ -61,7 +57,7 @@ var _ = Describe("Master", func() {
json.Unmarshal(body, &i)
Expect(len(i)).To(Equal(3))
})
It("should return robot commands", func() {
PIt("should return robot commands", func() {
request, _ := http.NewRequest("GET", "/robots/Robot%201/commands", nil)
response := httptest.NewRecorder()
a.robot_commands("Robot 1", response, request)
Expand All @@ -70,7 +66,7 @@ var _ = Describe("Master", func() {
json.Unmarshal(body, &i)
Expect(i).To(Equal([]string{"robotTestFunction"}))
})
It("should execute robot command", func() {
PIt("should execute robot command", func() {
request, _ := http.NewRequest("GET", "/robots/Robot%201/commands/robotTestFuntion", bytes.NewBufferString(`{"message":"Beep Boop"}`))
request.Header.Add("Content-Type", "application/json")
response := httptest.NewRecorder()
Expand Down
18 changes: 16 additions & 2 deletions connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,15 @@ type Connection interface {
Finalize() bool
}

type JsonConnection struct {
Name string `json:"name"`
Port string `json:"port"`
Adaptor string `json:"adaptor"`
}

type connection struct {
Name string `json:"name"`
Type string `json:"adaptor"`
Name string `json:"-"`
Type string `json:"-"`
Adaptor AdaptorInterface `json:"-"`
Port string `json:"-"`
Robot *Robot `json:"-"`
Expand Down Expand Up @@ -68,3 +74,11 @@ func (c *connection) Finalize() bool {
log.Println("Finalizing " + c.Name + "...")
return c.Adaptor.Finalize()
}

func (c *connection) ToJson() *JsonConnection {
jsonConnection := new(JsonConnection)
jsonConnection.Name = c.Name
jsonConnection.Port = c.Port
jsonConnection.Adaptor = c.Type
return jsonConnection
}
Loading

0 comments on commit 3de9d86

Please sign in to comment.