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

View File

@ -61,7 +61,7 @@ var _ = Describe("API", func() {
json.Unmarshal(body, &i) json.Unmarshal(body, &i)
Expect(len(i)).To(Equal(3)) 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) request, _ := http.NewRequest("GET", "/robots/Robot%201/commands", nil)
response := httptest.NewRecorder() response := httptest.NewRecorder()
a.server.ServeHTTP(response, request) a.server.ServeHTTP(response, request)
@ -71,16 +71,16 @@ var _ = Describe("API", func() {
json.Unmarshal(body, &i) json.Unmarshal(body, &i)
Expect(i).To(Equal([]string{"robotTestFunction"})) Expect(i).To(Equal([]string{"robotTestFunction"}))
}) })
PIt("should execute robot command", func() { It("should execute robot command", func() {
request, _ := http.NewRequest("GET", "/robots/Robot%201/commands/robotTestFuntion", bytes.NewBufferString(`{"message":"Beep Boop"}`)) request, _ := http.NewRequest("GET", "/robots/Robot%201/commands/robotTestFunction", bytes.NewBufferString(`{"message":"Beep Boop"}`))
request.Header.Add("Content-Type", "application/json") request.Header.Add("Content-Type", "application/json")
response := httptest.NewRecorder() response := httptest.NewRecorder()
a.server.ServeHTTP(response, request) a.server.ServeHTTP(response, request)
body, _ := ioutil.ReadAll(response.Body) body, _ := ioutil.ReadAll(response.Body)
var i []interface{} var i interface{}
json.Unmarshal(body, &i) 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() { It("should not execute unknown robot command", func() {
request, _ := http.NewRequest("GET", "/robots/Robot%201/commands/robotTestFuntion1", bytes.NewBufferString(`{"message":"Beep Boop"}`)) 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) a.server.ServeHTTP(response, request)
body, _ := ioutil.ReadAll(response.Body) body, _ := ioutil.ReadAll(response.Body)
var i []interface{} var i interface{}
json.Unmarshal(body, &i) 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() { It("should not execute unknown device command", func() {
request, _ := http.NewRequest("GET", "/robots/Robot%201/devices/Device%201/commands/DriverCommand1", bytes.NewBufferString(`{"name":"human"}`)) 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) a.server.ServeHTTP(response, request)
body, _ := ioutil.ReadAll(response.Body) body, _ := ioutil.ReadAll(response.Body)
var i []interface{} var i interface{}
json.Unmarshal(body, &i) 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 getInterval() time.Duration
setName(string) setName(string)
getName() string getName() string
getCommands() map[string]func(map[string]interface{}) interface{}
} }
type JSONDevice struct { type JSONDevice struct {
@ -93,17 +94,27 @@ func (d *device) Halt() bool {
return d.Driver.Halt() return d.Driver.Halt()
} }
func (d *device) Commands() interface{} { func (d *device) getCommands() map[string]func(map[string]interface{}) interface{} {
return FieldByNamePtr(d.Driver, "Commands").Interface() return d.Driver.getCommands()
}
func (d *device) Commands() map[string]func(map[string]interface{}) interface{} {
return d.getCommands()
} }
func (d *device) ToJSON() *JSONDevice { func (d *device) ToJSON() *JSONDevice {
return &JSONDevice{ jsonDevice := &JSONDevice{
Name: d.Name, Name: d.Name,
Driver: d.Type, Driver: d.Type,
Connection: d.Robot.Connection(FieldByNamePtr(FieldByNamePtr(d.Driver, "Adaptor"). Connection: d.Robot.Connection(FieldByNamePtr(FieldByNamePtr(d.Driver, "Adaptor").
Interface().(AdaptorInterface), "Name"). Interface().(AdaptorInterface), "Name").
Interface().(string)).ToJSON(), 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

@ -6,7 +6,7 @@ type Driver struct {
Interval time.Duration `json:"interval"` Interval time.Duration `json:"interval"`
Pin string `json:"pin"` Pin string `json:"pin"`
Name string `json:"name"` Name string `json:"name"`
Commands []string `json:"commands"` Commands map[string]func(map[string]interface{}) interface{} `json:"commands"`
Events map[string]*Event `json:"-"` Events map[string]*Event `json:"-"`
} }
@ -17,6 +17,7 @@ type DriverInterface interface {
getInterval() time.Duration getInterval() time.Duration
setName(string) setName(string)
getName() string getName() string
getCommands() map[string]func(map[string]interface{}) interface{}
} }
func (d *Driver) setInterval(t time.Duration) { func (d *Driver) setInterval(t time.Duration) {
@ -34,3 +35,11 @@ func (d *Driver) setName(s string) {
func (d *Driver) getName() string { func (d *Driver) getName() string {
return d.Name 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 { func NewAnalogSensorDriver(a AnalogReader, name string, pin string) *AnalogSensorDriver {
return &AnalogSensorDriver{ d := &AnalogSensorDriver{
Driver: gobot.Driver{ Driver: gobot.Driver{
Name: name, Name: name,
Pin: pin, Pin: pin,
Commands: []string{ Commands: make(map[string]func(map[string]interface{}) interface{}),
"ReadC",
},
}, },
Adaptor: a, Adaptor: a,
} }
d.Driver.AddCommand("Read", func(params map[string]interface{}) interface{} {
return d.Read()
})
return d
} }
func (a *AnalogSensorDriver) Start() bool { return true } 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 ( import (
"github.com/hybridgroup/gobot" "github.com/hybridgroup/gobot"
"strconv"
) )
type DirectPinDriver struct { type DirectPinDriver struct {
@ -10,21 +11,43 @@ type DirectPinDriver struct {
} }
func NewDirectPinDriver(a DirectPin, name string, pin string) *DirectPinDriver { func NewDirectPinDriver(a DirectPin, name string, pin string) *DirectPinDriver {
return &DirectPinDriver{ d := &DirectPinDriver{
Driver: gobot.Driver{ Driver: gobot.Driver{
Name: name, Name: name,
Pin: pin, Pin: pin,
Commands: []string{ Commands: make(map[string]func(map[string]interface{}) interface{}),
"DigitalReadC",
"DigitalWriteC",
"AnalogReadC",
"AnalogWriteC",
"PwmWriteC",
"ServoWriteC",
},
}, },
Adaptor: a, 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 } 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 { func NewLedDriver(a PwmDigitalWriter, name string, pin string) *LedDriver {
return &LedDriver{ l := &LedDriver{
Driver: gobot.Driver{ Driver: gobot.Driver{
Name: name, Name: name,
Pin: pin, Pin: pin,
Commands: []string{ Commands: make(map[string]func(map[string]interface{}) interface{}),
"ToggleC",
"OnC",
"OffC",
"BrightnessC",
},
}, },
High: false, High: false,
Adaptor: a, 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 } 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{ Driver: gobot.Driver{
Name: name, Name: name,
Pin: pin, Pin: pin,
Commands: []string{
"OffC",
"OnC",
"IsOnC",
"IsOffC",
"ToggleC",
"SpeedC",
"MinC",
"MaxC",
"ForwardC",
"BackwardC",
"CurrentSpeedC",
},
}, },
CurrentState: 0, CurrentState: 0,
CurrentSpeed: 0, CurrentSpeed: 0,

View File

@ -11,20 +11,36 @@ type ServoDriver struct {
} }
func NewServoDriver(a Servo, name string, pin string) *ServoDriver { func NewServoDriver(a Servo, name string, pin string) *ServoDriver {
return &ServoDriver{ s := &ServoDriver{
Driver: gobot.Driver{ Driver: gobot.Driver{
Name: name, Name: name,
Pin: pin, Pin: pin,
Commands: []string{ Commands: make(map[string]func(map[string]interface{}) interface{}),
"MoveC",
"MinC",
"CenterC",
"MaxC",
},
}, },
CurrentAngle: 0, CurrentAngle: 0,
Adaptor: a, 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 } 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) Init() bool { return true }
func (t *testDriver) Start() bool { return true } func (t *testDriver) Start() bool { return true }
func (t *testDriver) Halt() 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 { type testAdaptor struct {
Adaptor Adaptor
@ -40,16 +36,25 @@ func (t *testAdaptor) Finalize() bool { return true }
func (t *testAdaptor) Connect() bool { return true } func (t *testAdaptor) Connect() bool { return true }
func newTestDriver(name string, adaptor *testAdaptor) *testDriver { func newTestDriver(name string, adaptor *testAdaptor) *testDriver {
return &testDriver{ t := &testDriver{
Driver: Driver{ Driver: Driver{
Commands: []string{ Commands: make(map[string]func(map[string]interface{}) interface{}),
"TestDriverCommand",
"DriverCommand",
},
Name: name, Name: name,
}, },
Adaptor: adaptor, 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 { 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 { func NewTestRobot(name string) *Robot {
return newTestRobot(name) return newTestRobot(name)
} }
@ -81,10 +80,14 @@ func newTestRobot(name string) *Robot {
driver2 := newTestDriver("Device 2", adaptor2) driver2 := newTestDriver("Device 2", adaptor2)
driver3 := newTestDriver("Device 3", adaptor3) driver3 := newTestDriver("Device 3", adaptor3)
work := func() {} work := func() {}
//Commands := map[string]interface{}{ r := NewRobot(name, []Connection{adaptor1, adaptor2, adaptor3}, []Device{driver1, driver2, driver3}, work)
// "robotTestFunction": robotTestFunction, r.AddCommand("robotTestFunction", func(params map[string]interface{}) interface{} {
//} message := params["message"].(string)
return NewRobot(name, []Connection{adaptor1, adaptor2, adaptor3}, []Device{driver1, driver2, driver3}, work) robot := params["robot"].(string)
fmt.Println(params)
return fmt.Sprintf("hey %v, %v", robot, message)
})
return r
} }
func newTestStruct() *testStruct { func newTestStruct() *testStruct {