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:
parent
ca4d8ce583
commit
addb700d23
31
api/api.go
31
api/api.go
@ -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())
|
||||
body["robot"] = robot
|
||||
f := d.Commands()[command]
|
||||
|
||||
if f != nil {
|
||||
data, _ = json.Marshal(f(body))
|
||||
} 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.Write(data)
|
||||
}
|
||||
|
@ -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"))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
19
device.go
19
device.go
@ -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
|
||||
}
|
||||
|
11
driver.go
11
driver.go
@ -6,7 +6,7 @@ type Driver struct {
|
||||
Interval time.Duration `json:"interval"`
|
||||
Pin string `json:"pin"`
|
||||
Name string `json:"name"`
|
||||
Commands []string `json:"commands"`
|
||||
Commands map[string]func(map[string]interface{}) interface{} `json:"commands"`
|
||||
Events map[string]*Event `json:"-"`
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
@ -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",
|
||||
},
|
||||
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 }
|
||||
|
@ -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()
|
||||
}
|
@ -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",
|
||||
},
|
||||
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 }
|
||||
|
@ -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",
|
||||
},
|
||||
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 }
|
||||
|
@ -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,
|
||||
|
@ -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",
|
||||
},
|
||||
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 }
|
||||
|
@ -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",
|
||||
},
|
||||
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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user