Compare commits
18 Commits
Author | SHA1 | Date | |
---|---|---|---|
5fa75efee5 | |||
652d936d83 | |||
0f1e5e610e | |||
2a77d039a0 | |||
ce91a11c5a | |||
37705d6fe5 | |||
ab08e7ab15 | |||
a0ff2d6f52 | |||
31b00fb912 | |||
0788b44783 | |||
29a7d73791 | |||
e0c59f23cc | |||
2763715d2c | |||
8934cbfa4c | |||
fac5330b9c | |||
322b7b195f | |||
2d66bc9e49 | |||
8b8d37d0a1 |
20
change_permission.go
Normal file
20
change_permission.go
Normal file
@ -0,0 +1,20 @@
|
||||
package manager
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
func ChangePermission(iface string) error {
|
||||
log.Println("changing the mod of file")
|
||||
|
||||
cmd := exec.Command("chmod", "a+rw", iface)
|
||||
b, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(string(b))
|
||||
return nil
|
||||
}
|
94
cli.go
Normal file
94
cli.go
Normal file
@ -0,0 +1,94 @@
|
||||
package manager
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"sync"
|
||||
|
||||
"git.godopu.net/lab/etri-smartfarm-poc-controller-serial/puserial"
|
||||
"github.com/rjeczalik/notify"
|
||||
)
|
||||
|
||||
var ctx context.Context
|
||||
var cancel context.CancelFunc
|
||||
var ch_discover chan notify.EventInfo
|
||||
var _managerObj *_manager
|
||||
var registerHandleFunc func(e Event)
|
||||
var removeHandleFunc func(e Event)
|
||||
|
||||
func init() {
|
||||
ctx, cancel = context.WithCancel(context.Background())
|
||||
ch_discover = make(chan notify.EventInfo)
|
||||
devWithUUID := map[string]*_device{}
|
||||
devWithIface := map[interface{}]*_device{}
|
||||
chanForSync := map[string]chan map[string]interface{}{}
|
||||
|
||||
_managerObj = &_manager{
|
||||
devicesWithUUID: devWithUUID,
|
||||
devicesWithIface: devWithIface,
|
||||
chanForSync: chanForSync,
|
||||
SyncListener: &SyncHandler{devices: devWithUUID, chanForSync: chanForSync, mutex: &sync.Mutex{}, states: map[string]map[string]interface{}{}},
|
||||
RecvListener: &RecvHandler{devices: devWithIface, chanForSync: chanForSync},
|
||||
}
|
||||
|
||||
registerHandleFunc = nil
|
||||
removeHandleFunc = nil
|
||||
}
|
||||
|
||||
func AddRegisterHandleFunc(h func(e Event)) {
|
||||
registerHandleFunc = h
|
||||
}
|
||||
|
||||
func AddRemoveHandleFunc(h func(e Event)) {
|
||||
removeHandleFunc = h
|
||||
}
|
||||
|
||||
func Close() {
|
||||
cancel()
|
||||
}
|
||||
|
||||
func Sync(key string, param map[string]interface{}) {
|
||||
_managerObj.onSync(key, param)
|
||||
}
|
||||
|
||||
func AddRecvListener(h EventHandler) {
|
||||
_managerObj.addRecvListener(h)
|
||||
}
|
||||
|
||||
// func SetDevicePropsToSync(uuid string, propsToSync []string) error {
|
||||
// device, ok := _managerObj.devicesWithUUID[uuid]
|
||||
// if !ok {
|
||||
// return errors.New("device not found")
|
||||
// }
|
||||
// device.propsToSync = propsToSync
|
||||
// return nil
|
||||
// }
|
||||
|
||||
func Run() error {
|
||||
ifaces, err := puserial.InitDevice()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, e := range ifaces {
|
||||
go _managerObj.onAdded(e)
|
||||
}
|
||||
|
||||
go puserial.WatchNewDevice(ctx, ch_discover)
|
||||
|
||||
for {
|
||||
e, ok := <-ch_discover
|
||||
if !ok {
|
||||
log.Println("manager exit")
|
||||
return nil
|
||||
}
|
||||
switch e.Event() {
|
||||
case notify.Create:
|
||||
go _managerObj.onAdded(e.Path())
|
||||
// case notify.Remove:
|
||||
// log.Println("USB Disconnected!!")
|
||||
// _managerObj.onAdded(e.Path())
|
||||
}
|
||||
|
||||
}
|
||||
}
|
65
communication.go
Normal file
65
communication.go
Normal file
@ -0,0 +1,65 @@
|
||||
package manager
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"log"
|
||||
)
|
||||
|
||||
func recv(port io.Reader, r Receiver) {
|
||||
reader := bufio.NewReader(port)
|
||||
|
||||
for {
|
||||
b, _, err := reader.ReadLine()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
log.Println("USB is disconnected")
|
||||
_managerObj.onRemoved(port)
|
||||
return
|
||||
}
|
||||
}
|
||||
recvObj := map[string]interface{}{}
|
||||
err = json.Unmarshal(b, &recvObj)
|
||||
|
||||
if err == nil {
|
||||
r.onRecv(port, recvObj)
|
||||
}
|
||||
// data = string(b)
|
||||
}
|
||||
}
|
||||
|
||||
// for {
|
||||
// fmt.Print("> ")
|
||||
// cmd, _, _ := cmdReader.ReadLine()
|
||||
// cmdTkns := strings.Split(string(cmd), " ")
|
||||
|
||||
// if cmdTkns[0] == "light" {
|
||||
// command["code"] = 1
|
||||
// if cmdTkns[1] == "on" {
|
||||
// command["light"] = 100
|
||||
// } else {
|
||||
// command["light"] = 0
|
||||
// }
|
||||
// } else if cmdTkns[0] == "fan" {
|
||||
// command["code"] = 2
|
||||
// if cmdTkns[1] == "on" {
|
||||
// command["status"] = 1
|
||||
// } else {
|
||||
// command["status"] = 0
|
||||
// }
|
||||
// } else if cmdTkns[0] == "servo" {
|
||||
// command["code"] = 3
|
||||
// angle, err := strconv.Atoi(cmdTkns[1])
|
||||
// if err != nil {
|
||||
// continue
|
||||
// }
|
||||
// command["angle"] = angle
|
||||
// } else if cmdTkns[0] == "print" {
|
||||
// fmt.Println(data)
|
||||
// }
|
||||
// err := encoder.Encode(command)
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
// }
|
51
examples/main.go
Normal file
51
examples/main.go
Normal file
@ -0,0 +1,51 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
manager "git.godopu.net/lab/etri-smartfarm-poc-controller-serial"
|
||||
)
|
||||
|
||||
func main() {
|
||||
manager.AddRecvListener(manager.NewEventHandler(func(e manager.Event) {
|
||||
fmt.Println("RECV: ", e.Params())
|
||||
}))
|
||||
|
||||
manager.AddRegisterHandleFunc(func(e manager.Event) {
|
||||
param := e.Params()
|
||||
fmt.Println(param["uuid"].(string), " is registered!! ] ", param["sname"])
|
||||
})
|
||||
|
||||
manager.AddRemoveHandleFunc(func(e manager.Event) {
|
||||
param := e.Params()
|
||||
fmt.Println(param["uuid"].(string), " is removed!!")
|
||||
})
|
||||
|
||||
go manager.Run()
|
||||
defer manager.Close()
|
||||
|
||||
param := map[string]interface{}{}
|
||||
for {
|
||||
fmt.Print("> ")
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
b, _, _ := reader.ReadLine()
|
||||
cmd := string(b)
|
||||
fmt.Println("cmd: ", cmd)
|
||||
if cmd == "exit" {
|
||||
return
|
||||
}
|
||||
|
||||
tkns := strings.Split(cmd, " ")
|
||||
key := tkns[0]
|
||||
value, err := strconv.Atoi(tkns[2])
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
param[tkns[1]] = value
|
||||
manager.Sync(key, param)
|
||||
}
|
||||
}
|
21
interface.go
Normal file
21
interface.go
Normal file
@ -0,0 +1,21 @@
|
||||
package manager
|
||||
|
||||
type Event interface {
|
||||
Params() map[string]interface{}
|
||||
Key() interface{}
|
||||
}
|
||||
type EventHandler interface {
|
||||
Handle(e Event)
|
||||
}
|
||||
|
||||
type Receiver interface {
|
||||
onRecv(key interface{}, params map[string]interface{})
|
||||
}
|
||||
|
||||
type Syncronizer interface {
|
||||
onSync(key interface{}, params map[string]interface{})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
147
listener.go
Normal file
147
listener.go
Normal file
@ -0,0 +1,147 @@
|
||||
package manager
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"reflect"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type SyncHandler struct {
|
||||
devices map[string]*_device
|
||||
mutex *sync.Mutex
|
||||
chanForSync map[string]chan map[string]interface{}
|
||||
states map[string]map[string]interface{}
|
||||
}
|
||||
|
||||
func compareMap(src map[string]interface{}, dst map[string]interface{}) bool {
|
||||
|
||||
for key, value := range src {
|
||||
if key == "code" {
|
||||
continue
|
||||
}
|
||||
|
||||
if reflect.TypeOf(value).String() == "string" {
|
||||
dstV, ok := dst[key].(string)
|
||||
if !ok || value != dstV {
|
||||
return false
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
srcV, ok := value.(float64)
|
||||
if !ok {
|
||||
srcV = float64(value.(int))
|
||||
}
|
||||
|
||||
dstV, ok := dst[key].(float64)
|
||||
if !ok {
|
||||
dstV = float64(dst[key].(int))
|
||||
}
|
||||
|
||||
if srcV != dstV {
|
||||
fmt.Println("diff ", key, "] ", srcV, " vs ", dstV)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (sh *SyncHandler) Handle(e Event) {
|
||||
device, ok := sh.devices[e.Key().(string)]
|
||||
// fmt.Println("sync] ", device.IfaceName)
|
||||
// fmt.Println(sh.devices)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
params := e.Params()
|
||||
if params == nil {
|
||||
return
|
||||
}
|
||||
|
||||
go func() {
|
||||
encoder := json.NewEncoder(device.Iface)
|
||||
origin := map[string]interface{}{}
|
||||
origin["code"] = 200
|
||||
for key, value := range params {
|
||||
origin[key] = value
|
||||
}
|
||||
|
||||
sh.states[device.UUID] = origin
|
||||
// props := []string{"fan", "light", "servo"}
|
||||
|
||||
err := encoder.Encode(origin)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
_, ok := sh.chanForSync[device.IfaceName]
|
||||
if ok {
|
||||
sh.mutex.Lock()
|
||||
close(sh.chanForSync[device.IfaceName])
|
||||
delete(sh.chanForSync, device.IfaceName)
|
||||
sh.mutex.Unlock()
|
||||
}
|
||||
|
||||
chanForSync := make(chan map[string]interface{})
|
||||
sh.mutex.Lock()
|
||||
sh.chanForSync[device.IfaceName] = chanForSync
|
||||
sh.mutex.Unlock()
|
||||
|
||||
for state := range chanForSync {
|
||||
if compareMap(sh.states[device.UUID], state) {
|
||||
sh.mutex.Lock()
|
||||
close(sh.chanForSync[device.IfaceName])
|
||||
delete(sh.chanForSync, device.IfaceName)
|
||||
sh.mutex.Unlock()
|
||||
return
|
||||
}
|
||||
log.Println("wrong: ", state)
|
||||
log.Println("resend: ", sh.states[device.UUID])
|
||||
err := encoder.Encode(sh.states[device.UUID])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
}()
|
||||
}
|
||||
|
||||
type RecvHandler struct {
|
||||
devices map[interface{}]*_device
|
||||
chanForSync map[string]chan map[string]interface{}
|
||||
next EventHandler
|
||||
}
|
||||
|
||||
func (rh *RecvHandler) Handle(e Event) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
fmt.Println("panic recover - ", r)
|
||||
}
|
||||
}()
|
||||
device, ok := rh.devices[e.Key()]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
param := e.Params()
|
||||
code, _ := param["code"].(float64)
|
||||
if int(code) == 100 {
|
||||
return
|
||||
}
|
||||
|
||||
device.states = param
|
||||
channel, ok := rh.chanForSync[device.IfaceName]
|
||||
if ok {
|
||||
channel <- device.states
|
||||
}
|
||||
|
||||
if rh.next != nil {
|
||||
rh.next.Handle(e)
|
||||
}
|
||||
|
||||
// fmt.Println("recv] ", device.states)
|
||||
}
|
177
main.go
177
main.go
@ -1,177 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/jacobsa/go-serial/serial"
|
||||
"github.com/rjeczalik/notify"
|
||||
)
|
||||
|
||||
func readJsonFromSerial(obj map[string]interface{}, decoder *json.Decoder) error {
|
||||
err := decoder.Decode(&obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func msgSender(did string) {
|
||||
|
||||
}
|
||||
|
||||
func initUSB() (string, error) {
|
||||
fs, err := ioutil.ReadDir("/dev")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for _, f := range fs {
|
||||
if strings.Contains(f.Name(), "ttyACM") {
|
||||
return filepath.Join("/dev", f.Name()), nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", errors.New("USB Not found")
|
||||
}
|
||||
|
||||
func discoverUSB() string {
|
||||
fmt.Println("Waiting USB")
|
||||
ch := make(chan notify.EventInfo, 1)
|
||||
if err := notify.Watch("/dev", ch, notify.Create, notify.Remove); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer notify.Stop(ch)
|
||||
|
||||
for e := range ch {
|
||||
if strings.Contains(e.Path(), "/dev/ttyACM") {
|
||||
if e.Event() == notify.Create {
|
||||
log.Println("Got event:", e.Path())
|
||||
return e.Path()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func main() {
|
||||
dev, err := initUSB()
|
||||
if err != nil {
|
||||
if err.Error() == "USB Not found" {
|
||||
dev = discoverUSB()
|
||||
} else {
|
||||
log.Fatalln(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("discover: ", dev)
|
||||
time.Sleep(time.Second)
|
||||
|
||||
log.Println("changing the mod of file")
|
||||
cmd := exec.Command("chmod", "a+rw", dev)
|
||||
b, _ := cmd.CombinedOutput()
|
||||
fmt.Println(string(b))
|
||||
|
||||
// Set up options.
|
||||
options := serial.OpenOptions{
|
||||
PortName: dev,
|
||||
BaudRate: 9600,
|
||||
DataBits: 8,
|
||||
StopBits: 1,
|
||||
MinimumReadSize: 16,
|
||||
}
|
||||
|
||||
// Open the port.
|
||||
port, err := serial.Open(options)
|
||||
if err != nil {
|
||||
log.Fatalf("serial.Open: %v", err)
|
||||
}
|
||||
|
||||
// Make sure to close it later.
|
||||
defer port.Close()
|
||||
|
||||
// Write 4 bytes to the port.
|
||||
// b := []byte{0x00, 0x01, 0x02, 0x03}
|
||||
// n, err := port.Write(b)
|
||||
// if err != nil {
|
||||
// log.Fatalf("port.Write: %v", err)
|
||||
// }
|
||||
|
||||
// fmt.Println("Wrote", n, "bytes.")
|
||||
// var tokenByte string
|
||||
|
||||
reader := bufio.NewReader(port)
|
||||
// decoder := json.NewDecoder(port)
|
||||
encoder := json.NewEncoder(port)
|
||||
command := map[string]interface{}{}
|
||||
command["code"] = 1
|
||||
command["light"] = 0
|
||||
|
||||
var data string
|
||||
go func() {
|
||||
for {
|
||||
b, _, _ := reader.ReadLine()
|
||||
recvObj := map[string]interface{}{}
|
||||
err := json.Unmarshal(b, &recvObj)
|
||||
// err = readJsonFromSerial(recvObj, decoder)
|
||||
if err != nil {
|
||||
if err.Error() == "EOF" {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("error: ", string(b))
|
||||
}
|
||||
|
||||
data = string(b)
|
||||
// fmt.Println("line : ", recvObj)
|
||||
}
|
||||
}()
|
||||
|
||||
cmdReader := bufio.NewReader(os.Stdin)
|
||||
for {
|
||||
fmt.Print("> ")
|
||||
cmd, _, _ := cmdReader.ReadLine()
|
||||
cmdTkns := strings.Split(string(cmd), " ")
|
||||
|
||||
if cmdTkns[0] == "light" {
|
||||
command["code"] = 1
|
||||
if cmdTkns[1] == "on" {
|
||||
command["light"] = 100
|
||||
} else {
|
||||
command["light"] = 0
|
||||
}
|
||||
} else if cmdTkns[0] == "fan" {
|
||||
command["code"] = 2
|
||||
if cmdTkns[1] == "on" {
|
||||
command["status"] = 1
|
||||
} else {
|
||||
command["status"] = 0
|
||||
}
|
||||
} else if cmdTkns[0] == "servo" {
|
||||
command["code"] = 3
|
||||
angle, err := strconv.Atoi(cmdTkns[1])
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
command["angle"] = angle
|
||||
} else if cmdTkns[0] == "print" {
|
||||
fmt.Println(data)
|
||||
}
|
||||
err := encoder.Encode(command)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
131
manager.go
Normal file
131
manager.go
Normal file
@ -0,0 +1,131 @@
|
||||
package manager
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
|
||||
"github.com/jacobsa/go-serial/serial"
|
||||
)
|
||||
|
||||
type _manager struct {
|
||||
devicesWithUUID map[string]*_device
|
||||
devicesWithIface map[interface{}]*_device
|
||||
chanForSync map[string]chan map[string]interface{}
|
||||
RegisterListener EventHandler
|
||||
SyncListener EventHandler
|
||||
RecvListener EventHandler
|
||||
}
|
||||
|
||||
func (m *_manager) onRegistered(dev *_device) {
|
||||
// if m.RegisterListener != nil {
|
||||
// m.RegisterListener.Handle(&EventStruct{key: })
|
||||
// }
|
||||
if registerHandleFunc != nil {
|
||||
param := map[string]interface{}{}
|
||||
param["uuid"] = dev.UUID
|
||||
param["sname"] = dev.Sname
|
||||
|
||||
registerHandleFunc(&EventStruct{key: dev.UUID, params: param})
|
||||
}
|
||||
go recv(dev.Iface, m)
|
||||
}
|
||||
|
||||
func (m *_manager) onRemoved(port io.Reader) {
|
||||
dev := _managerObj.devicesWithIface[port]
|
||||
delete(m.devicesWithUUID, dev.UUID)
|
||||
delete(m.devicesWithIface, port)
|
||||
ch, ok := m.chanForSync[dev.UUID]
|
||||
if ok {
|
||||
close(ch)
|
||||
delete(m.chanForSync, dev.UUID)
|
||||
}
|
||||
|
||||
if removeHandleFunc != nil {
|
||||
param := map[string]interface{}{}
|
||||
param["uuid"] = dev.UUID
|
||||
|
||||
removeHandleFunc(&EventStruct{key: dev.UUID, params: param})
|
||||
}
|
||||
// log.Println(m.devicesWithUUID)
|
||||
// log.Println(m.devicesWithIface)
|
||||
}
|
||||
|
||||
func (m *_manager) onAdded(iface string) {
|
||||
err := ChangePermission(iface)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Set up options.
|
||||
options := serial.OpenOptions{
|
||||
PortName: iface,
|
||||
BaudRate: 9600,
|
||||
DataBits: 8,
|
||||
StopBits: 1,
|
||||
MinimumReadSize: 16,
|
||||
}
|
||||
|
||||
// Open the port.
|
||||
go func() {
|
||||
port, err := serial.Open(options)
|
||||
if err != nil {
|
||||
log.Printf("serial.Open: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
reader := bufio.NewReader(port)
|
||||
encoder := json.NewEncoder(port)
|
||||
|
||||
sndMsg := map[string]interface{}{}
|
||||
sndMsg["code"] = 100
|
||||
|
||||
for {
|
||||
b, _, _ := reader.ReadLine()
|
||||
rcvMsg := map[string]interface{}{}
|
||||
err := json.Unmarshal(b, &rcvMsg)
|
||||
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
code, ok := rcvMsg["code"].(float64)
|
||||
if ok && code == 100 {
|
||||
newDevice := &_device{
|
||||
UUID: rcvMsg["uuid"].(string),
|
||||
IfaceName: iface,
|
||||
Iface: port,
|
||||
Sname: rcvMsg["sname"].(string),
|
||||
states: map[string]interface{}{},
|
||||
}
|
||||
m.devicesWithUUID[rcvMsg["uuid"].(string)] = newDevice
|
||||
m.devicesWithIface[port] = newDevice
|
||||
|
||||
m.onRegistered(newDevice)
|
||||
fmt.Println("onAdded sub-routine is died")
|
||||
return
|
||||
}
|
||||
encoder.Encode(sndMsg)
|
||||
}
|
||||
}()
|
||||
|
||||
fmt.Println("onAdded main-routine is died")
|
||||
}
|
||||
|
||||
func (m *_manager) onSync(key interface{}, params map[string]interface{}) {
|
||||
if m.SyncListener != nil {
|
||||
m.SyncListener.Handle(&EventStruct{key: key, params: params})
|
||||
}
|
||||
}
|
||||
|
||||
func (m *_manager) onRecv(key interface{}, params map[string]interface{}) {
|
||||
if m.RecvListener != nil {
|
||||
m.RecvListener.Handle(&EventStruct{key: key, params: params})
|
||||
}
|
||||
}
|
||||
|
||||
func (m *_manager) addRecvListener(h EventHandler) {
|
||||
m.RecvListener = &RecvHandler{next: h, devices: m.devicesWithIface, chanForSync: m.chanForSync}
|
||||
}
|
15
model.go
Normal file
15
model.go
Normal file
@ -0,0 +1,15 @@
|
||||
package manager
|
||||
|
||||
import "io"
|
||||
|
||||
type _device struct {
|
||||
UUID string
|
||||
IfaceName string
|
||||
Sname string
|
||||
Iface io.ReadWriter
|
||||
states map[string]interface{}
|
||||
}
|
||||
|
||||
type RecvEvent struct {
|
||||
Params map[string]interface{}
|
||||
}
|
@ -1,164 +1,174 @@
|
||||
package serial
|
||||
package puserial
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/jacobsa/go-serial/serial"
|
||||
"github.com/rjeczalik/notify"
|
||||
)
|
||||
|
||||
func DiscoverUSB() string {
|
||||
fmt.Println("Waiting USB")
|
||||
ch := make(chan notify.EventInfo, 1)
|
||||
if err := notify.Watch("/dev", ch, notify.Create, notify.Remove); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer notify.Stop(ch)
|
||||
|
||||
for e := range ch {
|
||||
if strings.Contains(e.Path(), "/dev/ttyACM") {
|
||||
if e.Event() == notify.Create {
|
||||
log.Println("Got event:", e.Path())
|
||||
return e.Path()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func InitUSB() (string, error) {
|
||||
func InitDevice() ([]string, error) {
|
||||
fs, err := ioutil.ReadDir("/dev")
|
||||
if err != nil {
|
||||
return "", err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []string = nil
|
||||
for _, f := range fs {
|
||||
if strings.Contains(f.Name(), "ttyACM") {
|
||||
return filepath.Join("/dev", f.Name()), nil
|
||||
result = append(result, filepath.Join("/dev", f.Name()))
|
||||
}
|
||||
}
|
||||
|
||||
return "", errors.New("USB Not found")
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func Run() {
|
||||
dev, err := InitUSB()
|
||||
if err != nil {
|
||||
if err.Error() == "USB Not found" {
|
||||
dev = DiscoverUSB()
|
||||
} else {
|
||||
log.Fatalln(err.Error())
|
||||
}
|
||||
func WatchNewDevice(ctx context.Context, ch_discover chan<- notify.EventInfo) error {
|
||||
defer close(ch_discover)
|
||||
|
||||
filter := make(chan notify.EventInfo, 1)
|
||||
if err := notify.Watch("/dev", filter, notify.Create); err != nil {
|
||||
return err
|
||||
}
|
||||
defer notify.Stop(filter)
|
||||
|
||||
fmt.Println("discover: ", dev)
|
||||
time.Sleep(time.Second)
|
||||
|
||||
log.Println("changing the mod of file")
|
||||
cmd := exec.Command("chmod", "a+rw", dev)
|
||||
b, _ := cmd.CombinedOutput()
|
||||
fmt.Println(string(b))
|
||||
|
||||
// Set up options.
|
||||
options := serial.OpenOptions{
|
||||
PortName: dev,
|
||||
BaudRate: 9600,
|
||||
DataBits: 8,
|
||||
StopBits: 1,
|
||||
MinimumReadSize: 16,
|
||||
}
|
||||
|
||||
// Open the port.
|
||||
port, err := serial.Open(options)
|
||||
if err != nil {
|
||||
log.Fatalf("serial.Open: %v", err)
|
||||
}
|
||||
|
||||
// Make sure to close it later.
|
||||
defer port.Close()
|
||||
|
||||
// Write 4 bytes to the port.
|
||||
// b := []byte{0x00, 0x01, 0x02, 0x03}
|
||||
// n, err := port.Write(b)
|
||||
// if err != nil {
|
||||
// log.Fatalf("port.Write: %v", err)
|
||||
// }
|
||||
|
||||
// fmt.Println("Wrote", n, "bytes.")
|
||||
// var tokenByte string
|
||||
|
||||
reader := bufio.NewReader(port)
|
||||
// decoder := json.NewDecoder(port)
|
||||
encoder := json.NewEncoder(port)
|
||||
command := map[string]interface{}{}
|
||||
command["code"] = 1
|
||||
command["light"] = 0
|
||||
|
||||
var data string
|
||||
go func() {
|
||||
for {
|
||||
b, _, _ := reader.ReadLine()
|
||||
recvObj := map[string]interface{}{}
|
||||
err := json.Unmarshal(b, &recvObj)
|
||||
// err = readJsonFromSerial(recvObj, decoder)
|
||||
if err != nil {
|
||||
if err.Error() == "EOF" {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("error: ", string(b))
|
||||
}
|
||||
|
||||
data = string(b)
|
||||
// fmt.Println("line : ", recvObj)
|
||||
}
|
||||
}()
|
||||
|
||||
cmdReader := bufio.NewReader(os.Stdin)
|
||||
for {
|
||||
fmt.Print("> ")
|
||||
cmd, _, _ := cmdReader.ReadLine()
|
||||
cmdTkns := strings.Split(string(cmd), " ")
|
||||
|
||||
if cmdTkns[0] == "light" {
|
||||
command["code"] = 1
|
||||
if cmdTkns[1] == "on" {
|
||||
command["light"] = 100
|
||||
} else {
|
||||
command["light"] = 0
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
case e := <-filter:
|
||||
if strings.Contains(e.Path(), "/dev/ttyACM") {
|
||||
fmt.Println(e.Path())
|
||||
ch_discover <- e
|
||||
}
|
||||
} else if cmdTkns[0] == "fan" {
|
||||
command["code"] = 2
|
||||
if cmdTkns[1] == "on" {
|
||||
command["status"] = 1
|
||||
} else {
|
||||
command["status"] = 0
|
||||
}
|
||||
} else if cmdTkns[0] == "servo" {
|
||||
command["code"] = 3
|
||||
angle, err := strconv.Atoi(cmdTkns[1])
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
command["angle"] = angle
|
||||
} else if cmdTkns[0] == "print" {
|
||||
fmt.Println(data)
|
||||
}
|
||||
err := encoder.Encode(command)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// func InitUSB() (string, error) {
|
||||
// fs, err := ioutil.ReadDir("/dev")
|
||||
// if err != nil {
|
||||
// return "", err
|
||||
// }
|
||||
|
||||
// for _, f := range fs {
|
||||
// if strings.Contains(f.Name(), "ttyACM") {
|
||||
// return filepath.Join("/dev", f.Name()), nil
|
||||
// }
|
||||
// }
|
||||
|
||||
// return "", errors.New("USB Not found")
|
||||
// }
|
||||
|
||||
// func Run() {
|
||||
// dev, err := InitUSB()
|
||||
// if err != nil {
|
||||
// if err.Error() == "USB Not found" {
|
||||
// dev = DiscoverUSB()
|
||||
// } else {
|
||||
// log.Fatalln(err.Error())
|
||||
// }
|
||||
// }
|
||||
|
||||
// fmt.Println("discover: ", dev)
|
||||
// time.Sleep(time.Second)
|
||||
|
||||
// log.Println("changing the mod of file")
|
||||
// cmd := exec.Command("chmod", "a+rw", dev)
|
||||
// b, _ := cmd.CombinedOutput()
|
||||
// fmt.Println(string(b))
|
||||
|
||||
// // Set up options.
|
||||
// options := serial.OpenOptions{
|
||||
// PortName: dev,
|
||||
// BaudRate: 9600,
|
||||
// DataBits: 8,
|
||||
// StopBits: 1,
|
||||
// MinimumReadSize: 16,
|
||||
// }
|
||||
|
||||
// // Open the port.
|
||||
// port, err := serial.Open(options)
|
||||
// if err != nil {
|
||||
// log.Fatalf("serial.Open: %v", err)
|
||||
// }
|
||||
|
||||
// // Make sure to close it later.
|
||||
// defer port.Close()
|
||||
|
||||
// // Write 4 bytes to the port.
|
||||
// // b := []byte{0x00, 0x01, 0x02, 0x03}
|
||||
// // n, err := port.Write(b)
|
||||
// // if err != nil {
|
||||
// // log.Fatalf("port.Write: %v", err)
|
||||
// // }
|
||||
|
||||
// // fmt.Println("Wrote", n, "bytes.")
|
||||
// // var tokenByte string
|
||||
|
||||
// reader := bufio.NewReader(port)
|
||||
// // decoder := json.NewDecoder(port)
|
||||
// encoder := json.NewEncoder(port)
|
||||
// command := map[string]interface{}{}
|
||||
// command["code"] = 1
|
||||
// command["light"] = 0
|
||||
|
||||
// var data string
|
||||
// go func() {
|
||||
// for {
|
||||
// b, _, _ := reader.ReadLine()
|
||||
// recvObj := map[string]interface{}{}
|
||||
// err := json.Unmarshal(b, &recvObj)
|
||||
// // err = readJsonFromSerial(recvObj, decoder)
|
||||
// if err != nil {
|
||||
// if err.Error() == "EOF" {
|
||||
// return
|
||||
// }
|
||||
|
||||
// fmt.Println("error: ", string(b))
|
||||
// }
|
||||
|
||||
// data = string(b)
|
||||
// // fmt.Println("line : ", recvObj)
|
||||
// }
|
||||
// }()
|
||||
|
||||
// cmdReader := bufio.NewReader(os.Stdin)
|
||||
// for {
|
||||
// fmt.Print("> ")
|
||||
// cmd, _, _ := cmdReader.ReadLine()
|
||||
// cmdTkns := strings.Split(string(cmd), " ")
|
||||
|
||||
// if cmdTkns[0] == "light" {
|
||||
// command["code"] = 1
|
||||
// if cmdTkns[1] == "on" {
|
||||
// command["light"] = 100
|
||||
// } else {
|
||||
// command["light"] = 0
|
||||
// }
|
||||
// } else if cmdTkns[0] == "fan" {
|
||||
// command["code"] = 2
|
||||
// if cmdTkns[1] == "on" {
|
||||
// command["status"] = 1
|
||||
// } else {
|
||||
// command["status"] = 0
|
||||
// }
|
||||
// } else if cmdTkns[0] == "servo" {
|
||||
// command["code"] = 3
|
||||
// angle, err := strconv.Atoi(cmdTkns[1])
|
||||
// if err != nil {
|
||||
// continue
|
||||
// }
|
||||
// command["angle"] = angle
|
||||
// } else if cmdTkns[0] == "print" {
|
||||
// fmt.Println(data)
|
||||
// }
|
||||
// err := encoder.Encode(command)
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
164
serial/serial.go
164
serial/serial.go
@ -1,164 +0,0 @@
|
||||
package puserial
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/jacobsa/go-serial/serial"
|
||||
"github.com/rjeczalik/notify"
|
||||
)
|
||||
|
||||
func DiscoverUSB() string {
|
||||
fmt.Println("Waiting USB")
|
||||
ch := make(chan notify.EventInfo, 1)
|
||||
if err := notify.Watch("/dev", ch, notify.Create, notify.Remove); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer notify.Stop(ch)
|
||||
|
||||
for e := range ch {
|
||||
if strings.Contains(e.Path(), "/dev/ttyACM") {
|
||||
if e.Event() == notify.Create {
|
||||
log.Println("Got event:", e.Path())
|
||||
return e.Path()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func InitUSB() (string, error) {
|
||||
fs, err := ioutil.ReadDir("/dev")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for _, f := range fs {
|
||||
if strings.Contains(f.Name(), "ttyACM") {
|
||||
return filepath.Join("/dev", f.Name()), nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", errors.New("USB Not found")
|
||||
}
|
||||
|
||||
func Run() {
|
||||
dev, err := InitUSB()
|
||||
if err != nil {
|
||||
if err.Error() == "USB Not found" {
|
||||
dev = DiscoverUSB()
|
||||
} else {
|
||||
log.Fatalln(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("discover: ", dev)
|
||||
time.Sleep(time.Second)
|
||||
|
||||
log.Println("changing the mod of file")
|
||||
cmd := exec.Command("chmod", "a+rw", dev)
|
||||
b, _ := cmd.CombinedOutput()
|
||||
fmt.Println(string(b))
|
||||
|
||||
// Set up options.
|
||||
options := serial.OpenOptions{
|
||||
PortName: dev,
|
||||
BaudRate: 9600,
|
||||
DataBits: 8,
|
||||
StopBits: 1,
|
||||
MinimumReadSize: 16,
|
||||
}
|
||||
|
||||
// Open the port.
|
||||
port, err := serial.Open(options)
|
||||
if err != nil {
|
||||
log.Fatalf("serial.Open: %v", err)
|
||||
}
|
||||
|
||||
// Make sure to close it later.
|
||||
defer port.Close()
|
||||
|
||||
// Write 4 bytes to the port.
|
||||
// b := []byte{0x00, 0x01, 0x02, 0x03}
|
||||
// n, err := port.Write(b)
|
||||
// if err != nil {
|
||||
// log.Fatalf("port.Write: %v", err)
|
||||
// }
|
||||
|
||||
// fmt.Println("Wrote", n, "bytes.")
|
||||
// var tokenByte string
|
||||
|
||||
reader := bufio.NewReader(port)
|
||||
// decoder := json.NewDecoder(port)
|
||||
encoder := json.NewEncoder(port)
|
||||
command := map[string]interface{}{}
|
||||
command["code"] = 1
|
||||
command["light"] = 0
|
||||
|
||||
var data string
|
||||
go func() {
|
||||
for {
|
||||
b, _, _ := reader.ReadLine()
|
||||
recvObj := map[string]interface{}{}
|
||||
err := json.Unmarshal(b, &recvObj)
|
||||
// err = readJsonFromSerial(recvObj, decoder)
|
||||
if err != nil {
|
||||
if err.Error() == "EOF" {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("error: ", string(b))
|
||||
}
|
||||
|
||||
data = string(b)
|
||||
// fmt.Println("line : ", recvObj)
|
||||
}
|
||||
}()
|
||||
|
||||
cmdReader := bufio.NewReader(os.Stdin)
|
||||
for {
|
||||
fmt.Print("> ")
|
||||
cmd, _, _ := cmdReader.ReadLine()
|
||||
cmdTkns := strings.Split(string(cmd), " ")
|
||||
|
||||
if cmdTkns[0] == "light" {
|
||||
command["code"] = 1
|
||||
if cmdTkns[1] == "on" {
|
||||
command["light"] = 100
|
||||
} else {
|
||||
command["light"] = 0
|
||||
}
|
||||
} else if cmdTkns[0] == "fan" {
|
||||
command["code"] = 2
|
||||
if cmdTkns[1] == "on" {
|
||||
command["status"] = 1
|
||||
} else {
|
||||
command["status"] = 0
|
||||
}
|
||||
} else if cmdTkns[0] == "servo" {
|
||||
command["code"] = 3
|
||||
angle, err := strconv.Atoi(cmdTkns[1])
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
command["angle"] = angle
|
||||
} else if cmdTkns[0] == "print" {
|
||||
fmt.Println(data)
|
||||
}
|
||||
err := encoder.Encode(command)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
28
structure.go
Normal file
28
structure.go
Normal file
@ -0,0 +1,28 @@
|
||||
package manager
|
||||
|
||||
type EventStruct struct {
|
||||
Event
|
||||
params map[string]interface{}
|
||||
key interface{}
|
||||
}
|
||||
|
||||
func (es *EventStruct) Params() map[string]interface{} {
|
||||
return es.params
|
||||
}
|
||||
|
||||
func (es *EventStruct) Key() interface{} {
|
||||
return es.key
|
||||
}
|
||||
|
||||
type EventHandlerStruct struct {
|
||||
EventHandler
|
||||
HandleFunc func(e Event)
|
||||
}
|
||||
|
||||
func (ehs *EventHandlerStruct) Handle(e Event) {
|
||||
ehs.HandleFunc(e)
|
||||
}
|
||||
|
||||
func NewEventHandler(h func(e Event)) *EventHandlerStruct {
|
||||
return &EventHandlerStruct{HandleFunc: h}
|
||||
}
|
Loading…
Reference in New Issue
Block a user