From 7020f44ad57ac8b3942bc64553f51284297a96ad Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Sat, 23 Nov 2013 09:12:57 -0800 Subject: [PATCH 01/11] Add robot master --- gobot.go | 91 ++++++++++++++++++++++++++------------------------------ robot.go | 9 ++++++ utils.go | 63 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 114 insertions(+), 49 deletions(-) create mode 100644 utils.go diff --git a/gobot.go b/gobot.go index 5573e8be..caed767a 100644 --- a/gobot.go +++ b/gobot.go @@ -1,65 +1,58 @@ package gobot -import ( - "math/rand" - "net" - "time" -) +import "time" -func Every(t string, f func()) { - dur := parseDuration(t) - go func() { - for { - time.Sleep(dur) - go f() - } - }() +type Gobot struct { + // Master *Master + Robots []Robot } -func After(t string, f func()) { - dur := parseDuration(t) - go func() { - time.Sleep(dur) - f() - }() +func NewGobot() *Gobot { + g := new(Gobot) + // g.Master = new(Master) + return g } -func parseDuration(t string) time.Duration { - return ParseDuration(t) -} -func ParseDuration(t string) time.Duration { - dur, err := time.ParseDuration(t) - if err != nil { - panic(err) +func (g *Gobot) Start() { + // g.Master.robots = g.Robots + for s := range g.Robots { + go g.Robots[s].Start() } - return dur -} -func Random(min int, max int) int { - rand.Seed(time.Now().UTC().UnixNano()) - return rand.Intn(max-min) + min -} - -func On(cs chan interface{}) interface{} { - for s := range cs { - return s - } - return nil -} - -func Work(robots []Robot) { - for s := range robots { - go robots[s].Start() - } for { time.Sleep(10 * time.Millisecond) } } -func ConnectTo(port string) net.Conn { - tcpPort, err := net.Dial("tcp", port) - if err != nil { - panic(err) +func (m *Gobot) FindRobot(name string) *Robot { + for s := range m.Robots { + if m.Robots[s].Name == name { + return &m.Robots[s] + } } - return tcpPort + return nil +} +func (m *Gobot) FindRobotDevice(name string, device string) *Device { + for r := range m.Robots { + if m.Robots[r].Name == name { + for d := range m.Robots[r].devices { + if m.Robots[r].devices[d].Name == device { + return m.Robots[r].devices[d] + } + } + } + } + return nil +} +func (m *Gobot) FindRobotConnection(name string, connection string) *Connection { + for r := range m.Robots { + if m.Robots[r].Name == name { + for c := range m.Robots[r].connections { + if m.Robots[r].connections[c].Name == connection { + return m.Robots[r].connections[c] + } + } + } + } + return nil } diff --git a/robot.go b/robot.go index 54f3a44f..1650f62c 100644 --- a/robot.go +++ b/robot.go @@ -65,3 +65,12 @@ func (r *Robot) startDevices() { r.devices[i].Start() } } + +func (r *Robot) Device(name string) *Device { + for i := range r.devices { + if r.devices[i].Name == name { + return r.devices[i] + } + } + return nil +} diff --git a/utils.go b/utils.go new file mode 100644 index 00000000..6953e4d9 --- /dev/null +++ b/utils.go @@ -0,0 +1,63 @@ +package gobot + +import ( + "math/rand" + "net" + "reflect" + "time" +) + +func Every(t string, f func()) { + dur := parseDuration(t) + go func() { + for { + time.Sleep(dur) + go f() + } + }() +} + +func After(t string, f func()) { + dur := parseDuration(t) + go func() { + time.Sleep(dur) + f() + }() +} + +func parseDuration(t string) time.Duration { + dur, err := time.ParseDuration(t) + if err != nil { + panic(err) + } + return dur +} + +func Rand(max int) int { + rand.Seed(time.Now().UTC().UnixNano()) + return rand.Intn(max) +} + +func On(cs chan interface{}) interface{} { + for s := range cs { + return s + } + return nil +} + +func ConnectTo(port string) net.Conn { + tcpPort, err := net.Dial("tcp", port) + if err != nil { + panic(err) + } + return tcpPort +} + +func Call(thing interface{}, method string, params ...interface{}) (result []reflect.Value, err error) { + in := make([]reflect.Value, len(params)) + for k, param := range params { + in[k] = reflect.ValueOf(param) + } + result = reflect.ValueOf(thing).MethodByName(method).Call(in) + return +} From a0ac5f1f9f3b7ca7aa4a316f25693c57d0612551 Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Sat, 23 Nov 2013 09:15:44 -0800 Subject: [PATCH 02/11] Add master example --- examples/sphero_master.go | 46 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 examples/sphero_master.go diff --git a/examples/sphero_master.go b/examples/sphero_master.go new file mode 100644 index 00000000..160d6c95 --- /dev/null +++ b/examples/sphero_master.go @@ -0,0 +1,46 @@ +package main + +import ( + "github.com/hybridgroup/gobot" + "github.com/hybridgroup/gobot-sphero" +) + +func main() { + bot := gobot.NewGobot() + + spheros := map[string]string{ + "Sphero-BPO": "127.0.0.1:4560", + } + + for name, port := range spheros { + spheroAdaptor := new(gobotSphero.SpheroAdaptor) + spheroAdaptor.Name = "sphero" + spheroAdaptor.Port = port + + sphero := gobotSphero.NewSphero(spheroAdaptor) + sphero.Name = "sphero" + sphero.Interval = "0.5s" + + work := func(){ + sphero.SetRGB(uint8(255), uint8(0), uint8(0)) + } + + bot.Robots = append(bot.Robots, gobot.Robot { + Name: name, + Connections: []interface{} { spheroAdaptor }, + Devices: []interface{} { sphero }, + Work: work, + }) + } + + bot.Robots = append(bot.Robots, gobot.Robot { + Work: func(){ + sphero := bot.FindRobot("Sphero-BPO") + gobot.Every("1s", func () { + gobot.Call(sphero.Device("sphero").Driver, "SetRGB", uint8(gobot.Rand(255)), uint8(gobot.Rand(255)), uint8(gobot.Rand(255))) + }) + }, + }) + + bot.Start() +} From e6ef542a98cc37fede07fdd18bbaf574d6bbbe23 Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Sat, 23 Nov 2013 09:26:54 -0800 Subject: [PATCH 03/11] Clean up variables --- gobot.go | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/gobot.go b/gobot.go index caed767a..e915e321 100644 --- a/gobot.go +++ b/gobot.go @@ -3,18 +3,15 @@ package gobot import "time" type Gobot struct { - // Master *Master Robots []Robot } func NewGobot() *Gobot { g := new(Gobot) - // g.Master = new(Master) return g } func (g *Gobot) Start() { - // g.Master.robots = g.Robots for s := range g.Robots { go g.Robots[s].Start() } @@ -24,32 +21,32 @@ func (g *Gobot) Start() { } } -func (m *Gobot) FindRobot(name string) *Robot { - for s := range m.Robots { - if m.Robots[s].Name == name { - return &m.Robots[s] +func (g *Gobot) FindRobot(name string) *Robot { + for s := range g.Robots { + if g.Robots[s].Name == name { + return &g.Robots[s] } } return nil } -func (m *Gobot) FindRobotDevice(name string, device string) *Device { - for r := range m.Robots { - if m.Robots[r].Name == name { - for d := range m.Robots[r].devices { - if m.Robots[r].devices[d].Name == device { - return m.Robots[r].devices[d] +func (g *Gobot) FindRobotDevice(name string, device string) *Device { + for r := range g.Robots { + if g.Robots[r].Name == name { + for d := range g.Robots[r].devices { + if g.Robots[r].devices[d].Name == device { + return g.Robots[r].devices[d] } } } } return nil } -func (m *Gobot) FindRobotConnection(name string, connection string) *Connection { - for r := range m.Robots { - if m.Robots[r].Name == name { - for c := range m.Robots[r].connections { - if m.Robots[r].connections[c].Name == connection { - return m.Robots[r].connections[c] +func (g *Gobot) FindRobotConnection(name string, connection string) *Connection { + for r := range g.Robots { + if g.Robots[r].Name == name { + for c := range g.Robots[r].connections { + if g.Robots[r].connections[c].Name == connection { + return g.Robots[r].connections[c] } } } From e8ee0c9d57247f03eae76e79bfa34e586ca5072f Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Sat, 23 Nov 2013 10:36:08 -0800 Subject: [PATCH 04/11] Initial GETs for api --- api.go | 25 +++++++++++++++++++++++++ connection.go | 2 +- device.go | 2 +- driver.go | 2 +- examples/sphero_api.go | 38 ++++++++++++++++++++++++++++++++++++++ examples/sphero_master.go | 2 +- robot.go | 12 ++++++++---- utils.go | 6 ++++++ 8 files changed, 81 insertions(+), 8 deletions(-) create mode 100644 api.go create mode 100644 examples/sphero_api.go diff --git a/api.go b/api.go new file mode 100644 index 00000000..b4a37421 --- /dev/null +++ b/api.go @@ -0,0 +1,25 @@ +package gobot + +import "github.com/codegangsta/martini" + +func Api(bot *Gobot) { + m := martini.Classic() + + m.Get("/robots", func() string { + return toJson(bot.Robots) + }) + + m.Get("/robots/:robotname", func(params martini.Params) string { + return toJson(bot.FindRobot(params["robotname"])) + }) + + m.Get("/robots/:robotname/devices", func(params martini.Params) string { + return toJson(bot.FindRobot(params["robotname"]).GetDevices()) + }) + + m.Get("/robots/:robotname/devices/:devicename", func(params martini.Params) string { + return toJson(bot.FindRobotDevice(params["robotname"], params["devicename"])) + }) + + go m.Run() +} diff --git a/connection.go b/connection.go index eaaad42b..8f9b3380 100644 --- a/connection.go +++ b/connection.go @@ -9,7 +9,7 @@ type Connection struct { Name string Adaptor interface{} Port string - Robot *Robot + Robot *Robot `json:"-"` Params map[string]string } diff --git a/device.go b/device.go index 6c0babbe..6b268ac5 100644 --- a/device.go +++ b/device.go @@ -8,7 +8,7 @@ import ( type Device struct { Name string Interval string - Robot *Robot + Robot *Robot `json:"-"` Driver interface{} Params map[string]string } diff --git a/driver.go b/driver.go index 4ab5039a..aca82e67 100644 --- a/driver.go +++ b/driver.go @@ -7,7 +7,7 @@ type Driver struct { Pin string Name string Params map[string]string - Events map[string]chan interface{} + Events map[string]chan interface{} `json:"-"` } func NewDriver(d Driver) Driver { diff --git a/examples/sphero_api.go b/examples/sphero_api.go new file mode 100644 index 00000000..7faaf3fd --- /dev/null +++ b/examples/sphero_api.go @@ -0,0 +1,38 @@ +package main + +import ( + "github.com/hybridgroup/gobot" + "github.com/hybridgroup/gobot-sphero" +) + +func main() { + bot := gobot.NewGobot() + gobot.Api(bot) + + spheros := map[string]string{ + "Sphero-BPO": "127.0.0.1:4560", + } + + for name, port := range spheros { + spheroAdaptor := new(gobotSphero.SpheroAdaptor) + spheroAdaptor.Name = "sphero" + spheroAdaptor.Port = port + + sphero := gobotSphero.NewSphero(spheroAdaptor) + sphero.Name = "sphero" + sphero.Interval = "0.5s" + + work := func(){ + sphero.SetRGB(uint8(255), uint8(0), uint8(0)) + } + + bot.Robots = append(bot.Robots, gobot.Robot { + Name: name, + Connections: []interface{} { spheroAdaptor }, + Devices: []interface{} { sphero }, + Work: work, + }) + } + + bot.Start() +} diff --git a/examples/sphero_master.go b/examples/sphero_master.go index 160d6c95..df8882d3 100644 --- a/examples/sphero_master.go +++ b/examples/sphero_master.go @@ -37,7 +37,7 @@ func main() { Work: func(){ sphero := bot.FindRobot("Sphero-BPO") gobot.Every("1s", func () { - gobot.Call(sphero.Device("sphero").Driver, "SetRGB", uint8(gobot.Rand(255)), uint8(gobot.Rand(255)), uint8(gobot.Rand(255))) + gobot.Call(sphero.GetDevice("sphero").Driver, "SetRGB", uint8(gobot.Rand(255)), uint8(gobot.Rand(255)), uint8(gobot.Rand(255))) }) }, }) diff --git a/robot.go b/robot.go index 1650f62c..97e16674 100644 --- a/robot.go +++ b/robot.go @@ -11,9 +11,9 @@ type Robot struct { Connections []interface{} Devices []interface{} Name string - Work func() - connections []*Connection - devices []*Device + Work func() `json:"-"` + connections []*Connection `json:"-"` + devices []*Device `json:"-"` } func (r *Robot) Start() { @@ -66,7 +66,11 @@ func (r *Robot) startDevices() { } } -func (r *Robot) Device(name string) *Device { +func (r *Robot) GetDevices() []*Device { + return r.devices +} + +func (r *Robot) GetDevice(name string) *Device { for i := range r.devices { if r.devices[i].Name == name { return r.devices[i] diff --git a/utils.go b/utils.go index 6953e4d9..f251d418 100644 --- a/utils.go +++ b/utils.go @@ -1,6 +1,7 @@ package gobot import ( + "encoding/json" "math/rand" "net" "reflect" @@ -61,3 +62,8 @@ func Call(thing interface{}, method string, params ...interface{}) (result []ref result = reflect.ValueOf(thing).MethodByName(method).Call(in) return } + +func toJson(obj interface{}) string { + b, _ := json.Marshal(obj) + return string(b) +} From 58df3a8e21854232bfc4b141653b1a6448d88454 Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Sat, 23 Nov 2013 16:19:11 -0800 Subject: [PATCH 05/11] Add POST command --- api.go | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/api.go b/api.go index b4a37421..477685f2 100644 --- a/api.go +++ b/api.go @@ -1,6 +1,10 @@ package gobot -import "github.com/codegangsta/martini" +import ( + "encoding/json" + "github.com/codegangsta/martini" + "net/http" +) func Api(bot *Gobot) { m := martini.Classic() @@ -21,5 +25,20 @@ func Api(bot *Gobot) { return toJson(bot.FindRobotDevice(params["robotname"], params["devicename"])) }) + m.Post("/robots/:robotname/devices/:devicename/commands/:command", func(params martini.Params, res http.ResponseWriter, req *http.Request) string { + decoder := json.NewDecoder(req.Body) + var response_hash map[string]interface{} + decoder.Decode(&response_hash) + robot := bot.FindRobotDevice(params["robotname"], params["devicename"]) + p := make([]interface{}, len(response_hash)) + i := 0 + for _, v := range response_hash { + p[i] = v + i++ + } + Call(robot.Driver, params["command"], p...) + return "" + }) + go m.Run() } From cfe0d71f41228eed24dac7035d0d2e6ee483a4e7 Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Sun, 24 Nov 2013 14:41:36 -0800 Subject: [PATCH 06/11] Add api commands --- api.go | 18 +++++++++++------- device.go | 4 ++-- driver.go | 1 + utils.go | 5 ++--- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/api.go b/api.go index 477685f2..7c08d2d7 100644 --- a/api.go +++ b/api.go @@ -25,19 +25,23 @@ func Api(bot *Gobot) { return toJson(bot.FindRobotDevice(params["robotname"], params["devicename"])) }) + m.Get("/robots/:robotname/devices/:devicename/commands", func(params martini.Params) string { + return toJson(bot.FindRobotDevice(params["robotname"], params["devicename"]).Commands()) + }) + m.Post("/robots/:robotname/devices/:devicename/commands/:command", func(params martini.Params, res http.ResponseWriter, req *http.Request) string { decoder := json.NewDecoder(req.Body) var response_hash map[string]interface{} decoder.Decode(&response_hash) robot := bot.FindRobotDevice(params["robotname"], params["devicename"]) - p := make([]interface{}, len(response_hash)) - i := 0 - for _, v := range response_hash { - p[i] = v - i++ + commands := robot.Commands().([]string) + for command := range commands { + if commands[command] == params["command"] { + ret := Call(robot.Driver, params["command"], response_hash) + return toJson(map[string]interface{}{"results": ret}) + } } - Call(robot.Driver, params["command"], p...) - return "" + return toJson(map[string]interface{}{"results": "Unknown Command"}) }) go m.Run() diff --git a/device.go b/device.go index 6b268ac5..c5f57061 100644 --- a/device.go +++ b/device.go @@ -29,6 +29,6 @@ func (d *Device) Start() { } } -func (d *Device) Command(method_name string, arguments []string) { - //dt.Driver.Command(method_name, arguments) +func (d *Device) Commands() interface{} { + return reflect.ValueOf(d.Driver).Elem().FieldByName("Commands").Interface() } diff --git a/driver.go b/driver.go index aca82e67..978c6895 100644 --- a/driver.go +++ b/driver.go @@ -7,6 +7,7 @@ type Driver struct { Pin string Name string Params map[string]string + Commands []string Events map[string]chan interface{} `json:"-"` } diff --git a/utils.go b/utils.go index f251d418..8dfaa3c9 100644 --- a/utils.go +++ b/utils.go @@ -54,13 +54,12 @@ func ConnectTo(port string) net.Conn { return tcpPort } -func Call(thing interface{}, method string, params ...interface{}) (result []reflect.Value, err error) { +func Call(thing interface{}, method string, params ...interface{}) []reflect.Value { in := make([]reflect.Value, len(params)) for k, param := range params { in[k] = reflect.ValueOf(param) } - result = reflect.ValueOf(thing).MethodByName(method).Call(in) - return + return reflect.ValueOf(thing).MethodByName(method).Call(in) } func toJson(obj interface{}) string { From f1ac7a90737b79cd7b0521c374f86629aacc85ef Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Sun, 24 Nov 2013 14:56:13 -0800 Subject: [PATCH 07/11] go fmt examples --- api.go | 6 ++-- examples/sphero_api.go | 50 +++++++++++++++--------------- examples/sphero_master.go | 64 +++++++++++++++++++-------------------- 3 files changed, 60 insertions(+), 60 deletions(-) diff --git a/api.go b/api.go index 7c08d2d7..7cb4ca4a 100644 --- a/api.go +++ b/api.go @@ -31,13 +31,13 @@ func Api(bot *Gobot) { m.Post("/robots/:robotname/devices/:devicename/commands/:command", func(params martini.Params, res http.ResponseWriter, req *http.Request) string { decoder := json.NewDecoder(req.Body) - var response_hash map[string]interface{} - decoder.Decode(&response_hash) + var body map[string]interface{} + decoder.Decode(&body) robot := bot.FindRobotDevice(params["robotname"], params["devicename"]) commands := robot.Commands().([]string) for command := range commands { if commands[command] == params["command"] { - ret := Call(robot.Driver, params["command"], response_hash) + ret := Call(robot.Driver, params["command"], body) return toJson(map[string]interface{}{"results": ret}) } } diff --git a/examples/sphero_api.go b/examples/sphero_api.go index 7faaf3fd..e9d5cbfc 100644 --- a/examples/sphero_api.go +++ b/examples/sphero_api.go @@ -1,38 +1,38 @@ package main import ( - "github.com/hybridgroup/gobot" - "github.com/hybridgroup/gobot-sphero" + "github.com/hybridgroup/gobot" + "github.com/hybridgroup/gobot-sphero" ) func main() { - bot := gobot.NewGobot() - gobot.Api(bot) + bot := gobot.NewGobot() + gobot.Api(bot) - spheros := map[string]string{ - "Sphero-BPO": "127.0.0.1:4560", - } + spheros := map[string]string{ + "Sphero-BPO": "127.0.0.1:4560", + } - for name, port := range spheros { - spheroAdaptor := new(gobotSphero.SpheroAdaptor) - spheroAdaptor.Name = "sphero" - spheroAdaptor.Port = port + for name, port := range spheros { + spheroAdaptor := new(gobotSphero.SpheroAdaptor) + spheroAdaptor.Name = "sphero" + spheroAdaptor.Port = port - sphero := gobotSphero.NewSphero(spheroAdaptor) - sphero.Name = "sphero" - sphero.Interval = "0.5s" + sphero := gobotSphero.NewSphero(spheroAdaptor) + sphero.Name = "sphero" + sphero.Interval = "0.5s" - work := func(){ - sphero.SetRGB(uint8(255), uint8(0), uint8(0)) - } + work := func() { + sphero.SetRGB(uint8(255), uint8(0), uint8(0)) + } - bot.Robots = append(bot.Robots, gobot.Robot { - Name: name, - Connections: []interface{} { spheroAdaptor }, - Devices: []interface{} { sphero }, - Work: work, - }) - } + bot.Robots = append(bot.Robots, gobot.Robot{ + Name: name, + Connections: []interface{}{spheroAdaptor}, + Devices: []interface{}{sphero}, + Work: work, + }) + } - bot.Start() + bot.Start() } diff --git a/examples/sphero_master.go b/examples/sphero_master.go index df8882d3..a76a5052 100644 --- a/examples/sphero_master.go +++ b/examples/sphero_master.go @@ -1,46 +1,46 @@ package main import ( - "github.com/hybridgroup/gobot" - "github.com/hybridgroup/gobot-sphero" + "github.com/hybridgroup/gobot" + "github.com/hybridgroup/gobot-sphero" ) func main() { - bot := gobot.NewGobot() + bot := gobot.NewGobot() - spheros := map[string]string{ - "Sphero-BPO": "127.0.0.1:4560", - } + spheros := map[string]string{ + "Sphero-BPO": "127.0.0.1:4560", + } - for name, port := range spheros { - spheroAdaptor := new(gobotSphero.SpheroAdaptor) - spheroAdaptor.Name = "sphero" - spheroAdaptor.Port = port + for name, port := range spheros { + spheroAdaptor := new(gobotSphero.SpheroAdaptor) + spheroAdaptor.Name = "sphero" + spheroAdaptor.Port = port - sphero := gobotSphero.NewSphero(spheroAdaptor) - sphero.Name = "sphero" - sphero.Interval = "0.5s" + sphero := gobotSphero.NewSphero(spheroAdaptor) + sphero.Name = "sphero" + sphero.Interval = "0.5s" - work := func(){ - sphero.SetRGB(uint8(255), uint8(0), uint8(0)) - } + work := func() { + sphero.SetRGB(uint8(255), uint8(0), uint8(0)) + } - bot.Robots = append(bot.Robots, gobot.Robot { - Name: name, - Connections: []interface{} { spheroAdaptor }, - Devices: []interface{} { sphero }, - Work: work, - }) - } + bot.Robots = append(bot.Robots, gobot.Robot{ + Name: name, + Connections: []interface{}{spheroAdaptor}, + Devices: []interface{}{sphero}, + Work: work, + }) + } - bot.Robots = append(bot.Robots, gobot.Robot { - Work: func(){ - sphero := bot.FindRobot("Sphero-BPO") - gobot.Every("1s", func () { - gobot.Call(sphero.GetDevice("sphero").Driver, "SetRGB", uint8(gobot.Rand(255)), uint8(gobot.Rand(255)), uint8(gobot.Rand(255))) - }) - }, - }) + bot.Robots = append(bot.Robots, gobot.Robot{ + Work: func() { + sphero := bot.FindRobot("Sphero-BPO") + gobot.Every("1s", func() { + gobot.Call(sphero.GetDevice("sphero").Driver, "SetRGB", uint8(gobot.Rand(255)), uint8(gobot.Rand(255)), uint8(gobot.Rand(255))) + }) + }, + }) - bot.Start() + bot.Start() } From 7baa0b6b1f718f3a23747d0f49730651bbc3c1fd Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Sun, 24 Nov 2013 15:47:48 -0800 Subject: [PATCH 08/11] Accept POST and GET for commands --- api.go | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/api.go b/api.go index 7cb4ca4a..5fadd455 100644 --- a/api.go +++ b/api.go @@ -6,7 +6,10 @@ import ( "net/http" ) +type api struct{} + func Api(bot *Gobot) { + a := new(api) m := martini.Classic() m.Get("/robots", func() string { @@ -29,20 +32,29 @@ func Api(bot *Gobot) { return toJson(bot.FindRobotDevice(params["robotname"], params["devicename"]).Commands()) }) - m.Post("/robots/:robotname/devices/:devicename/commands/:command", func(params martini.Params, res http.ResponseWriter, req *http.Request) string { - decoder := json.NewDecoder(req.Body) - var body map[string]interface{} - decoder.Decode(&body) - robot := bot.FindRobotDevice(params["robotname"], params["devicename"]) - commands := robot.Commands().([]string) - for command := range commands { - if commands[command] == params["command"] { - ret := Call(robot.Driver, params["command"], body) - return toJson(map[string]interface{}{"results": ret}) - } - } - return toJson(map[string]interface{}{"results": "Unknown Command"}) + command_route := "/robots/:robotname/devices/:devicename/commands/:command" + + m.Get(command_route, func(params martini.Params, res http.ResponseWriter, req *http.Request) string { + return a.executeCommand(bot, params, res, req) + }) + m.Post(command_route, func(params martini.Params, res http.ResponseWriter, req *http.Request) string { + return a.executeCommand(bot, params, res, req) }) go m.Run() } + +func (a *api) executeCommand(bot *Gobot, params martini.Params, res http.ResponseWriter, req *http.Request) string { + decoder := json.NewDecoder(req.Body) + var body map[string]interface{} + decoder.Decode(&body) + robot := bot.FindRobotDevice(params["robotname"], params["devicename"]) + commands := robot.Commands().([]string) + for command := range commands { + if commands[command] == params["command"] { + ret := Call(robot.Driver, params["command"], body) + return toJson(map[string]interface{}{"results": ret}) + } + } + return toJson(map[string]interface{}{"results": "Unknown Command"}) +} From 17e0d39e5cbaad0ca62328ed335ce8d44a55a8dc Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Sun, 24 Nov 2013 15:59:36 -0800 Subject: [PATCH 09/11] Update README.md --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index e8731413..2910a0e8 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,20 @@ func main() { robot.Start() } ``` +## API: + +Gobot includes a RESTful API to query the status of any robot running within a group, including the connection and device status, and execute device commands. + +To activate the API, use the `Api` command like this: + +```go + master := gobot.NewGobot() + gobot.Api(master) +``` +To specify the api port run your Gobot program with the `PORT` environment variable +``` + $ PORT=8080 go run gobotProgram.go +``` ## Hardware Support Gobot has a extensible system for connecting to hardware devices. The following robotics and physical computing platforms are currently supported: From 787269cb01ad263dc0811f39448ddbb3f69f0203 Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Sun, 24 Nov 2013 16:17:47 -0800 Subject: [PATCH 10/11] Rename Gobot struct to Master --- api.go | 4 +-- examples/sphero_api.go | 2 +- examples/sphero_master.go | 2 +- gobot.go | 55 --------------------------------------- master.go | 55 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 59 insertions(+), 59 deletions(-) delete mode 100644 gobot.go create mode 100644 master.go diff --git a/api.go b/api.go index 5fadd455..73cfe3fd 100644 --- a/api.go +++ b/api.go @@ -8,7 +8,7 @@ import ( type api struct{} -func Api(bot *Gobot) { +func Api(bot *Master) { a := new(api) m := martini.Classic() @@ -44,7 +44,7 @@ func Api(bot *Gobot) { go m.Run() } -func (a *api) executeCommand(bot *Gobot, params martini.Params, res http.ResponseWriter, req *http.Request) string { +func (a *api) executeCommand(bot *Master, params martini.Params, res http.ResponseWriter, req *http.Request) string { decoder := json.NewDecoder(req.Body) var body map[string]interface{} decoder.Decode(&body) diff --git a/examples/sphero_api.go b/examples/sphero_api.go index e9d5cbfc..0b9562e1 100644 --- a/examples/sphero_api.go +++ b/examples/sphero_api.go @@ -6,7 +6,7 @@ import ( ) func main() { - bot := gobot.NewGobot() + bot := gobot.GobotMaster() gobot.Api(bot) spheros := map[string]string{ diff --git a/examples/sphero_master.go b/examples/sphero_master.go index a76a5052..476ebaae 100644 --- a/examples/sphero_master.go +++ b/examples/sphero_master.go @@ -6,7 +6,7 @@ import ( ) func main() { - bot := gobot.NewGobot() + bot := gobot.GobotMaster() spheros := map[string]string{ "Sphero-BPO": "127.0.0.1:4560", diff --git a/gobot.go b/gobot.go deleted file mode 100644 index e915e321..00000000 --- a/gobot.go +++ /dev/null @@ -1,55 +0,0 @@ -package gobot - -import "time" - -type Gobot struct { - Robots []Robot -} - -func NewGobot() *Gobot { - g := new(Gobot) - return g -} - -func (g *Gobot) Start() { - for s := range g.Robots { - go g.Robots[s].Start() - } - - for { - time.Sleep(10 * time.Millisecond) - } -} - -func (g *Gobot) FindRobot(name string) *Robot { - for s := range g.Robots { - if g.Robots[s].Name == name { - return &g.Robots[s] - } - } - return nil -} -func (g *Gobot) FindRobotDevice(name string, device string) *Device { - for r := range g.Robots { - if g.Robots[r].Name == name { - for d := range g.Robots[r].devices { - if g.Robots[r].devices[d].Name == device { - return g.Robots[r].devices[d] - } - } - } - } - return nil -} -func (g *Gobot) FindRobotConnection(name string, connection string) *Connection { - for r := range g.Robots { - if g.Robots[r].Name == name { - for c := range g.Robots[r].connections { - if g.Robots[r].connections[c].Name == connection { - return g.Robots[r].connections[c] - } - } - } - } - return nil -} diff --git a/master.go b/master.go new file mode 100644 index 00000000..c87fa52a --- /dev/null +++ b/master.go @@ -0,0 +1,55 @@ +package gobot + +import "time" + +type Master struct { + Robots []Robot +} + +func GobotMaster() *Master { + m := new(Master) + return m +} + +func (m *Master) Start() { + for s := range m.Robots { + go m.Robots[s].Start() + } + + for { + time.Sleep(10 * time.Millisecond) + } +} + +func (m *Master) FindRobot(name string) *Robot { + for s := range m.Robots { + if m.Robots[s].Name == name { + return &m.Robots[s] + } + } + return nil +} +func (m *Master) FindRobotDevice(name string, device string) *Device { + for r := range m.Robots { + if m.Robots[r].Name == name { + for d := range m.Robots[r].devices { + if m.Robots[r].devices[d].Name == device { + return m.Robots[r].devices[d] + } + } + } + } + return nil +} +func (m *Master) FindRobotConnection(name string, connection string) *Connection { + for r := range m.Robots { + if m.Robots[r].Name == name { + for c := range m.Robots[r].connections { + if m.Robots[r].connections[c].Name == connection { + return m.Robots[r].connections[c] + } + } + } + } + return nil +} From 2fced445c9e4275bb7b4e98c98f40561575579e6 Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Sun, 24 Nov 2013 16:24:32 -0800 Subject: [PATCH 11/11] Update examples --- README.md | 2 +- examples/sphero_api.go | 8 ++++---- examples/sphero_master.go | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 2910a0e8..51eec88e 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ Gobot includes a RESTful API to query the status of any robot running within a g To activate the API, use the `Api` command like this: ```go - master := gobot.NewGobot() + master := gobot.GobotMaster() gobot.Api(master) ``` To specify the api port run your Gobot program with the `PORT` environment variable diff --git a/examples/sphero_api.go b/examples/sphero_api.go index 0b9562e1..e06c66f8 100644 --- a/examples/sphero_api.go +++ b/examples/sphero_api.go @@ -6,8 +6,8 @@ import ( ) func main() { - bot := gobot.GobotMaster() - gobot.Api(bot) + master := gobot.GobotMaster() + gobot.Api(master) spheros := map[string]string{ "Sphero-BPO": "127.0.0.1:4560", @@ -26,7 +26,7 @@ func main() { sphero.SetRGB(uint8(255), uint8(0), uint8(0)) } - bot.Robots = append(bot.Robots, gobot.Robot{ + master.Robots = append(master.Robots, gobot.Robot{ Name: name, Connections: []interface{}{spheroAdaptor}, Devices: []interface{}{sphero}, @@ -34,5 +34,5 @@ func main() { }) } - bot.Start() + master.Start() } diff --git a/examples/sphero_master.go b/examples/sphero_master.go index 476ebaae..1c3af0e0 100644 --- a/examples/sphero_master.go +++ b/examples/sphero_master.go @@ -6,7 +6,7 @@ import ( ) func main() { - bot := gobot.GobotMaster() + master := gobot.GobotMaster() spheros := map[string]string{ "Sphero-BPO": "127.0.0.1:4560", @@ -25,7 +25,7 @@ func main() { sphero.SetRGB(uint8(255), uint8(0), uint8(0)) } - bot.Robots = append(bot.Robots, gobot.Robot{ + master.Robots = append(master.Robots, gobot.Robot{ Name: name, Connections: []interface{}{spheroAdaptor}, Devices: []interface{}{sphero}, @@ -33,14 +33,14 @@ func main() { }) } - bot.Robots = append(bot.Robots, gobot.Robot{ + master.Robots = append(master.Robots, gobot.Robot{ Work: func() { - sphero := bot.FindRobot("Sphero-BPO") + sphero := master.FindRobot("Sphero-BPO") gobot.Every("1s", func() { gobot.Call(sphero.GetDevice("sphero").Driver, "SetRGB", uint8(gobot.Rand(255)), uint8(gobot.Rand(255)), uint8(gobot.Rand(255))) }) }, }) - bot.Start() + master.Start() }