1
0
mirror of https://github.com/hybridgroup/gobot.git synced 2025-04-24 13:48:49 +08:00

Refactor driver commands

This commit is contained in:
Adrian Zankich 2014-06-11 17:41:04 -07:00
parent ca4d8ce583
commit addb700d23
11 changed files with 168 additions and 166 deletions

View File

@ -76,8 +76,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.executeCommand))
a.server.Post(commandRoute, a.setHeaders(a.executeCommand))
a.server.Get(commandRoute, a.setHeaders(a.executeDeviceCommand))
a.server.Post(commandRoute, 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))
@ -168,7 +168,7 @@ func (a *api) robotDeviceCommands(res http.ResponseWriter, req *http.Request) {
robot := req.URL.Query().Get(":robot")
device := req.URL.Query().Get(":device")
data, _ := json.Marshal(a.gobot.Robot(robot).Device(device).Commands())
data, _ := json.Marshal(a.gobot.Robot(robot).Device(device).ToJSON().Commands)
res.Header().Set("Content-Type", "application/json; charset=utf-8")
res.Write(data)
}
@ -195,29 +195,24 @@ func (a *api) robotConnection(res http.ResponseWriter, req *http.Request) {
res.Write(data)
}
func (a *api) executeCommand(res http.ResponseWriter, req *http.Request) {
func (a *api) executeDeviceCommand(res http.ResponseWriter, req *http.Request) {
robot := req.URL.Query().Get(":robot")
device := req.URL.Query().Get(":device")
command := req.URL.Query().Get(":command")
data, _ := ioutil.ReadAll(req.Body)
var body map[string]interface{}
body := make(map[string]interface{})
json.Unmarshal(data, &body)
d := a.gobot.Robot(robot).Device(device)
commands := d.Commands().([]string)
for c := range commands {
if commands[c] == command {
ret := []interface{}{}
for _, v := range gobot.Call(d.Driver, command, body) {
ret = append(ret, v.Interface())
}
data, _ = json.Marshal(ret)
res.Header().Set("Content-Type", "application/json; charset=utf-8")
res.Write(data)
return
}
body["robot"] = robot
f := d.Commands()[command]
if f != nil {
data, _ = json.Marshal(f(body))
} else {
data, _ = json.Marshal("Unknown Command")
}
data, _ = json.Marshal([]interface{}{"Unknown Command"})
res.Header().Set("Content-Type", "application/json; charset=utf-8")
res.Write(data)
}

View File

@ -61,7 +61,7 @@ var _ = Describe("API", func() {
json.Unmarshal(body, &i)
Expect(len(i)).To(Equal(3))
})
PIt("should return robot commands", func() {
It("should return robot commands", func() {
request, _ := http.NewRequest("GET", "/robots/Robot%201/commands", nil)
response := httptest.NewRecorder()
a.server.ServeHTTP(response, request)
@ -71,16 +71,16 @@ var _ = Describe("API", func() {
json.Unmarshal(body, &i)
Expect(i).To(Equal([]string{"robotTestFunction"}))
})
PIt("should execute robot command", func() {
request, _ := http.NewRequest("GET", "/robots/Robot%201/commands/robotTestFuntion", bytes.NewBufferString(`{"message":"Beep Boop"}`))
It("should execute robot command", func() {
request, _ := http.NewRequest("GET", "/robots/Robot%201/commands/robotTestFunction", bytes.NewBufferString(`{"message":"Beep Boop"}`))
request.Header.Add("Content-Type", "application/json")
response := httptest.NewRecorder()
a.server.ServeHTTP(response, request)
body, _ := ioutil.ReadAll(response.Body)
var i []interface{}
var i interface{}
json.Unmarshal(body, &i)
Expect(i[0]).To(Equal("hey Robot 1, Beep Boop"))
Expect(i).To(Equal("hey Robot 1, Beep Boop"))
})
It("should not execute unknown robot command", func() {
request, _ := http.NewRequest("GET", "/robots/Robot%201/commands/robotTestFuntion1", bytes.NewBufferString(`{"message":"Beep Boop"}`))
@ -120,9 +120,9 @@ var _ = Describe("API", func() {
a.server.ServeHTTP(response, request)
body, _ := ioutil.ReadAll(response.Body)
var i []interface{}
var i interface{}
json.Unmarshal(body, &i)
Expect(i[0]).To(Equal("hello human"))
Expect(i).To(Equal("hello human"))
})
It("should not execute unknown device command", func() {
request, _ := http.NewRequest("GET", "/robots/Robot%201/devices/Device%201/commands/DriverCommand1", bytes.NewBufferString(`{"name":"human"}`))
@ -131,9 +131,9 @@ var _ = Describe("API", func() {
a.server.ServeHTTP(response, request)
body, _ := ioutil.ReadAll(response.Body)
var i []interface{}
var i interface{}
json.Unmarshal(body, &i)
Expect(i[0]).To(Equal("Unknown Command"))
Expect(i).To(Equal("Unknown Command"))
})
})
})

View File

@ -14,6 +14,7 @@ type Device interface {
getInterval() time.Duration
setName(string)
getName() string
getCommands() map[string]func(map[string]interface{}) interface{}
}
type JSONDevice struct {
@ -93,17 +94,27 @@ func (d *device) Halt() bool {
return d.Driver.Halt()
}
func (d *device) Commands() interface{} {
return FieldByNamePtr(d.Driver, "Commands").Interface()
func (d *device) getCommands() map[string]func(map[string]interface{}) interface{} {
return d.Driver.getCommands()
}
func (d *device) Commands() map[string]func(map[string]interface{}) interface{} {
return d.getCommands()
}
func (d *device) ToJSON() *JSONDevice {
return &JSONDevice{
jsonDevice := &JSONDevice{
Name: d.Name,
Driver: d.Type,
Connection: d.Robot.Connection(FieldByNamePtr(FieldByNamePtr(d.Driver, "Adaptor").
Interface().(AdaptorInterface), "Name").
Interface().(string)).ToJSON(),
Commands: FieldByNamePtr(d.Driver, "Commands").Interface().([]string),
Commands: []string{},
}
commands := d.getCommands()
for command := range commands {
jsonDevice.Commands = append(jsonDevice.Commands, command)
}
return jsonDevice
}

View File

@ -3,11 +3,11 @@ package gobot
import "time"
type Driver struct {
Interval time.Duration `json:"interval"`
Pin string `json:"pin"`
Name string `json:"name"`
Commands []string `json:"commands"`
Events map[string]*Event `json:"-"`
Interval time.Duration `json:"interval"`
Pin string `json:"pin"`
Name string `json:"name"`
Commands map[string]func(map[string]interface{}) interface{} `json:"commands"`
Events map[string]*Event `json:"-"`
}
type DriverInterface interface {
@ -17,6 +17,7 @@ type DriverInterface interface {
getInterval() time.Duration
setName(string)
getName() string
getCommands() map[string]func(map[string]interface{}) interface{}
}
func (d *Driver) setInterval(t time.Duration) {
@ -34,3 +35,11 @@ func (d *Driver) setName(s string) {
func (d *Driver) getName() string {
return d.Name
}
func (d *Driver) AddCommand(name string, f func(map[string]interface{}) interface{}) {
d.Commands[name] = f
}
func (d *Driver) getCommands() map[string]func(map[string]interface{}) interface{} {
return d.Commands
}

View File

@ -10,16 +10,18 @@ type AnalogSensorDriver struct {
}
func NewAnalogSensorDriver(a AnalogReader, name string, pin string) *AnalogSensorDriver {
return &AnalogSensorDriver{
d := &AnalogSensorDriver{
Driver: gobot.Driver{
Name: name,
Pin: pin,
Commands: []string{
"ReadC",
},
Name: name,
Pin: pin,
Commands: make(map[string]func(map[string]interface{}) interface{}),
},
Adaptor: a,
}
d.Driver.AddCommand("Read", func(params map[string]interface{}) interface{} {
return d.Read()
})
return d
}
func (a *AnalogSensorDriver) Start() bool { return true }

View File

@ -1,62 +0,0 @@
package gpio
import "strconv"
// Led
func (l *LedDriver) ToggleC(params map[string]interface{}) {
l.Toggle()
}
func (l *LedDriver) OnC(params map[string]interface{}) {
l.On()
}
func (l *LedDriver) OffC(params map[string]interface{}) {
l.Off()
}
func (l *LedDriver) BrightnessC(params map[string]interface{}) {
level := byte(params["level"].(float64))
l.Brightness(level)
}
// Servo
func (l *ServoDriver) MoveC(params map[string]interface{}) {
angle := byte(params["angle"].(float64))
l.Move(angle)
}
func (l *ServoDriver) MinC(params map[string]interface{}) {
l.Min()
}
func (l *ServoDriver) CenterC(params map[string]interface{}) {
l.Center()
}
func (l *ServoDriver) MaxC(params map[string]interface{}) {
l.Max()
}
// Direct Pin
func (d *DirectPinDriver) DigitalReadC(params map[string]interface{}) int {
return d.DigitalRead()
}
func (d *DirectPinDriver) DigitalWriteC(params map[string]interface{}) {
level, _ := strconv.Atoi(params["level"].(string))
d.DigitalWrite(byte(level))
}
func (d *DirectPinDriver) AnalogReadC(params map[string]interface{}) int {
return d.AnalogRead()
}
func (d *DirectPinDriver) AnalogWriteC(params map[string]interface{}) {
level, _ := strconv.Atoi(params["level"].(string))
d.AnalogWrite(byte(level))
}
func (d *DirectPinDriver) PwmWriteC(params map[string]interface{}) {
level, _ := strconv.Atoi(params["level"].(string))
d.PwmWrite(byte(level))
}
func (d *DirectPinDriver) ServoWriteC(params map[string]interface{}) {
level, _ := strconv.Atoi(params["level"].(string))
d.ServoWrite(byte(level))
}
// Analog Sensor
func (d *AnalogSensorDriver) ReadC(params map[string]interface{}) int {
return d.Read()
}

View File

@ -2,6 +2,7 @@ package gpio
import (
"github.com/hybridgroup/gobot"
"strconv"
)
type DirectPinDriver struct {
@ -10,21 +11,43 @@ type DirectPinDriver struct {
}
func NewDirectPinDriver(a DirectPin, name string, pin string) *DirectPinDriver {
return &DirectPinDriver{
d := &DirectPinDriver{
Driver: gobot.Driver{
Name: name,
Pin: pin,
Commands: []string{
"DigitalReadC",
"DigitalWriteC",
"AnalogReadC",
"AnalogWriteC",
"PwmWriteC",
"ServoWriteC",
},
Name: name,
Pin: pin,
Commands: make(map[string]func(map[string]interface{}) interface{}),
},
Adaptor: a,
}
d.Driver.AddCommand("DigitalRead", func(params map[string]interface{}) interface{} {
return d.DigitalRead()
})
d.Driver.AddCommand("DigitalWrite", func(params map[string]interface{}) interface{} {
level, _ := strconv.Atoi(params["level"].(string))
d.DigitalWrite(byte(level))
return nil
})
d.Driver.AddCommand("AnalogRead", func(params map[string]interface{}) interface{} {
return d.AnalogRead()
})
d.Driver.AddCommand("AnalogWrite", func(params map[string]interface{}) interface{} {
level, _ := strconv.Atoi(params["level"].(string))
d.AnalogWrite(byte(level))
return nil
})
d.Driver.AddCommand("PwmWrite", func(params map[string]interface{}) interface{} {
level, _ := strconv.Atoi(params["level"].(string))
d.PwmWrite(byte(level))
return nil
})
d.Driver.AddCommand("ServoWrite", func(params map[string]interface{}) interface{} {
level, _ := strconv.Atoi(params["level"].(string))
d.ServoWrite(byte(level))
return nil
})
return d
}
func (d *DirectPinDriver) Start() bool { return true }

View File

@ -11,20 +11,38 @@ type LedDriver struct {
}
func NewLedDriver(a PwmDigitalWriter, name string, pin string) *LedDriver {
return &LedDriver{
l := &LedDriver{
Driver: gobot.Driver{
Name: name,
Pin: pin,
Commands: []string{
"ToggleC",
"OnC",
"OffC",
"BrightnessC",
},
Name: name,
Pin: pin,
Commands: make(map[string]func(map[string]interface{}) interface{}),
},
High: false,
Adaptor: a,
}
l.Driver.AddCommand("Brightness", func(params map[string]interface{}) interface{} {
level := byte(params["level"].(float64))
l.Brightness(level)
return nil
})
l.Driver.AddCommand("Toggle", func(params map[string]interface{}) interface{} {
l.Toggle()
return nil
})
l.Driver.AddCommand("On", func(params map[string]interface{}) interface{} {
l.On()
return nil
})
l.Driver.AddCommand("Off", func(params map[string]interface{}) interface{} {
l.Off()
return nil
})
return l
}
func (l *LedDriver) Start() bool { return true }

View File

@ -23,19 +23,6 @@ func NewMotorDriver(a PwmDigitalWriter, name string, pin string) *MotorDriver {
Driver: gobot.Driver{
Name: name,
Pin: pin,
Commands: []string{
"OffC",
"OnC",
"IsOnC",
"IsOffC",
"ToggleC",
"SpeedC",
"MinC",
"MaxC",
"ForwardC",
"BackwardC",
"CurrentSpeedC",
},
},
CurrentState: 0,
CurrentSpeed: 0,

View File

@ -11,20 +11,36 @@ type ServoDriver struct {
}
func NewServoDriver(a Servo, name string, pin string) *ServoDriver {
return &ServoDriver{
s := &ServoDriver{
Driver: gobot.Driver{
Name: name,
Pin: pin,
Commands: []string{
"MoveC",
"MinC",
"CenterC",
"MaxC",
},
Name: name,
Pin: pin,
Commands: make(map[string]func(map[string]interface{}) interface{}),
},
CurrentAngle: 0,
Adaptor: a,
}
s.Driver.AddCommand("Move", func(params map[string]interface{}) interface{} {
angle := byte(params["angle"].(float64))
s.Move(angle)
return nil
})
s.Driver.AddCommand("Min", func(params map[string]interface{}) interface{} {
s.Min()
return nil
})
s.Driver.AddCommand("Center", func(params map[string]interface{}) interface{} {
s.Center()
return nil
})
s.Driver.AddCommand("Max", func(params map[string]interface{}) interface{} {
s.Max()
return nil
})
return s
}
func (s *ServoDriver) Start() bool { return true }

View File

@ -27,10 +27,6 @@ type testDriver struct {
func (t *testDriver) Init() bool { return true }
func (t *testDriver) Start() bool { return true }
func (t *testDriver) Halt() bool { return true }
func (t *testDriver) TestDriverCommand(params map[string]interface{}) string {
name := params["name"].(string)
return fmt.Sprintf("hello %v", name)
}
type testAdaptor struct {
Adaptor
@ -40,16 +36,25 @@ func (t *testAdaptor) Finalize() bool { return true }
func (t *testAdaptor) Connect() bool { return true }
func newTestDriver(name string, adaptor *testAdaptor) *testDriver {
return &testDriver{
t := &testDriver{
Driver: Driver{
Commands: []string{
"TestDriverCommand",
"DriverCommand",
},
Name: name,
Commands: make(map[string]func(map[string]interface{}) interface{}),
Name: name,
},
Adaptor: adaptor,
}
t.Driver.AddCommand("TestDriverCommand", func(params map[string]interface{}) interface{} {
name := params["name"].(string)
return fmt.Sprintf("hello %v", name)
})
t.Driver.AddCommand("DriverCommand", func(params map[string]interface{}) interface{} {
name := params["name"].(string)
return fmt.Sprintf("hello %v", name)
})
return t
}
func newTestAdaptor(name string) *testAdaptor {
@ -64,12 +69,6 @@ func newTestAdaptor(name string) *testAdaptor {
}
}
func robotTestFunction(params map[string]interface{}) string {
message := params["message"].(string)
robotname := params["robotname"].(string)
return fmt.Sprintf("hey %v, %v", robotname, message)
}
func NewTestRobot(name string) *Robot {
return newTestRobot(name)
}
@ -81,10 +80,14 @@ func newTestRobot(name string) *Robot {
driver2 := newTestDriver("Device 2", adaptor2)
driver3 := newTestDriver("Device 3", adaptor3)
work := func() {}
//Commands := map[string]interface{}{
// "robotTestFunction": robotTestFunction,
//}
return NewRobot(name, []Connection{adaptor1, adaptor2, adaptor3}, []Device{driver1, driver2, driver3}, work)
r := NewRobot(name, []Connection{adaptor1, adaptor2, adaptor3}, []Device{driver1, driver2, driver3}, work)
r.AddCommand("robotTestFunction", func(params map[string]interface{}) interface{} {
message := params["message"].(string)
robot := params["robot"].(string)
fmt.Println(params)
return fmt.Sprintf("hey %v, %v", robot, message)
})
return r
}
func newTestStruct() *testStruct {