diff --git a/api/api.go b/api/api.go index 3c88ab82..6cf2106c 100644 --- a/api/api.go +++ b/api/api.go @@ -62,12 +62,14 @@ func NewAPI(g *gobot.Gobot) *api { func (a *api) Start() { a.server = pat.New() - commandRoute := "/robots/:robot/devices/:device/commands/:command" + commandRoute := "/commands/:command" + deviceCommandRoute := "/robots/:robot/devices/:device/commands/:command" robotCommandRoute := "/robots/:robot/commands/:command" - a.server.Get("/", http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { - http.Redirect(res, req, "/robots", 301) - })) + a.server.Get("/", a.setHeaders(a.root)) + a.server.Get("/commands", a.setHeaders(a.commands)) + a.server.Get(commandRoute, a.setHeaders(a.executeCommand)) + a.server.Post(commandRoute, a.setHeaders(a.executeCommand)) a.server.Get("/robots", a.setHeaders(a.robots)) a.server.Get("/robots/:robot", a.setHeaders(a.robot)) a.server.Get("/robots/:robot/commands", a.setHeaders(a.robotCommands)) @@ -76,8 +78,8 @@ func (a *api) Start() { a.server.Get("/robots/:robot/devices", a.setHeaders(a.robotDevices)) a.server.Get("/robots/:robot/devices/:device", a.setHeaders(a.robotDevice)) a.server.Get("/robots/:robot/devices/:device/commands", a.setHeaders(a.robotDeviceCommands)) - a.server.Get(commandRoute, a.setHeaders(a.executeDeviceCommand)) - a.server.Post(commandRoute, a.setHeaders(a.executeDeviceCommand)) + a.server.Get(deviceCommandRoute, a.setHeaders(a.executeDeviceCommand)) + a.server.Post(deviceCommandRoute, a.setHeaders(a.executeDeviceCommand)) a.server.Get("/robots/:robot/connections", a.setHeaders(a.robotConnections)) a.server.Get("/robots/:robot/connections/:connection", a.setHeaders(a.robotConnection)) @@ -116,6 +118,18 @@ func (a *api) setHeaders(f func(http.ResponseWriter, *http.Request)) http.Handle } } +func (a *api) root(res http.ResponseWriter, req *http.Request) { + data, _ := json.Marshal(a.gobot.ToJSON()) + res.Header().Set("Content-Type", "application/json; charset=utf-8") + res.Write(data) +} + +func (a *api) commands(res http.ResponseWriter, req *http.Request) { + data, _ := json.Marshal(a.gobot.ToJSON().Commands) + res.Header().Set("Content-Type", "application/json; charset=utf-8") + res.Write(data) +} + func (a *api) robots(res http.ResponseWriter, req *http.Request) { jsonRobots := []*gobot.JSONRobot{} for _, robot := range a.gobot.Robots { @@ -195,6 +209,24 @@ func (a *api) robotConnection(res http.ResponseWriter, req *http.Request) { res.Write(data) } +func (a *api) executeCommand(res http.ResponseWriter, req *http.Request) { + command := req.URL.Query().Get(":command") + + data, _ := ioutil.ReadAll(req.Body) + body := make(map[string]interface{}) + json.Unmarshal(data, &body) + f := a.gobot.Commands[command] + + if f != nil { + data, _ = json.Marshal(f(body)) + } else { + data, _ = json.Marshal("Unknown Command") + } + + res.Header().Set("Content-Type", "application/json; charset=utf-8") + res.Write(data) +} + func (a *api) executeDeviceCommand(res http.ResponseWriter, req *http.Request) { robot := req.URL.Query().Get(":robot") device := req.URL.Query().Get(":device") diff --git a/examples/hello_api.go b/examples/hello_api.go index 9e479c86..4af3feee 100644 --- a/examples/hello_api.go +++ b/examples/hello_api.go @@ -7,17 +7,18 @@ import ( ) func main() { - master := gobot.NewGobot() - a := api.NewAPI(master) - a.Start() + gbot := gobot.NewGobot() + api.NewAPI(gbot).Start() - hello := gobot.NewRobot("hello", nil, nil, nil) - - hello.AddCommand("HiThere", func(params map[string]interface{}) interface{} { - return []string{fmt.Sprintf("Hey"), fmt.Sprintf("dude!")} + gbot.AddCommand("CustomGobotCommand", func(params map[string]interface{}) interface{} { + return "This command is attached to the master!" }) - master.Robots = append(master.Robots, hello) + hello := gobot.NewRobot("hello", nil, nil, nil) + hello.AddCommand("HiThere", func(params map[string]interface{}) interface{} { + return fmt.Sprintf("This command is attached to the robot %v", hello.Name) + }) - master.Start() + gbot.Robots = append(gbot.Robots, hello) + gbot.Start() } diff --git a/gobot.go b/gobot.go index 35675794..ed38cce3 100644 --- a/gobot.go +++ b/gobot.go @@ -6,19 +6,30 @@ import ( "os/signal" ) +type JSONGobot struct { + Robots []*JSONRobot `json:"robots"` + Commands []string `json:"commands"` +} + type Gobot struct { - Robots []*Robot - trap func(chan os.Signal) + Robots []*Robot + Commands map[string]func(map[string]interface{}) interface{} + trap func(chan os.Signal) } func NewGobot() *Gobot { return &Gobot{ + Commands: make(map[string]func(map[string]interface{}) interface{}), trap: func(c chan os.Signal) { signal.Notify(c, os.Interrupt) }, } } +func (g *Gobot) AddCommand(name string, f func(map[string]interface{}) interface{}) { + g.Commands[name] = f +} + func (g *Gobot) Start() { Robots(g.Robots).Start() @@ -42,3 +53,17 @@ func (g *Gobot) Robot(name string) *Robot { } return nil } + +func (g *Gobot) ToJSON() *JSONGobot { + jsonGobot := &JSONGobot{ + Robots: []*JSONRobot{}, + Commands: []string{}, + } + for command := range g.Commands { + jsonGobot.Commands = append(jsonGobot.Commands, command) + } + for _, robot := range g.Robots { + jsonGobot.Robots = append(jsonGobot.Robots, robot.ToJSON()) + } + return jsonGobot +}