diff --git a/change_permission.go b/change_permission.go new file mode 100644 index 0000000..e222a18 --- /dev/null +++ b/change_permission.go @@ -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 +} diff --git a/cli.go b/cli.go new file mode 100644 index 0000000..9945418 --- /dev/null +++ b/cli.go @@ -0,0 +1,103 @@ +package manager + +import ( + "bufio" + "context" + "encoding/json" + "fmt" + "log" + "time" + + "git.godopu.net/lab/etri-smartfarm-poc-controller-serial/puserial" + "github.com/jacobsa/go-serial/serial" + "github.com/rjeczalik/notify" +) + +var ctx context.Context +var cancel context.CancelFunc +var ch_discover chan notify.EventInfo +var _managerObj *_manager + +func init() { + ctx, cancel = context.WithCancel(context.Background()) + ch_discover = make(chan notify.EventInfo) + _managerObj = &_manager{ + devices: map[string]*_device{}, + SyncListener: nil, + RecvListener: nil, + } +} + +func Close() { + cancel() +} + +func register(iface string) { + fmt.Println("Handle] ", iface) + + // change permission + 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. + port, err := serial.Open(options) + if err != nil { + log.Fatalf("serial.Open: %v", err) + } + + // Make sure to close it later. + defer port.Close() + reader := bufio.NewReader(port) + dev := &_device{} + + for { + b, _, _ := reader.ReadLine() + + err := json.Unmarshal(b, &dev) + + if err != nil { + continue + } + + fmt.Println(dev) + port.Write([]byte{200}) + time.Sleep(time.Second) + break + } + + // var data string +} + +func Run() error { + iface, err := puserial.InitDevice() + if err != nil { + if err.Error() != "USB Not found" { + return err + } + } else { + // _managerObj.onAdd(iface) + register(iface) + } + + go puserial.WatchNewDevice(ctx, ch_discover) + + for { + e, ok := <-ch_discover + if !ok { + log.Println("manager exit") + return nil + } + register(e.Path()) + } +} diff --git a/communication.go b/communication.go new file mode 100644 index 0000000..35183a0 --- /dev/null +++ b/communication.go @@ -0,0 +1,69 @@ +package manager + +import ( + "bufio" + "encoding/json" + "fmt" + "io" + "log" +) + +func recv(reader bufio.Reader, input chan<- Event) { + for { + b, _, err := reader.ReadLine() + if err != nil { + if err == io.EOF { + log.Println("USB is disconnected") + return + } + } + recvObj := map[string]interface{}{} + err = json.Unmarshal(b, &recvObj) + // err = readJsonFromSerial(recvObj, decoder) + + if err == nil { + fmt.Println("line : ", string(b)) + + } + // data = string(b) + } +} + +func send(sender io.Writer, output <-chan Event) { + +} + +// 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) +// } +// } diff --git a/examples/main.go b/examples/main.go new file mode 100644 index 0000000..2545b60 --- /dev/null +++ b/examples/main.go @@ -0,0 +1,22 @@ +package main + +import ( + "fmt" + "time" + + manager "git.godopu.net/lab/etri-smartfarm-poc-controller-serial" +) + +func main() { + go manager.Run() + + fmt.Print("> ") + var cmd string + fmt.Scanln(&cmd) + + if cmd == "exit" { + manager.Close() + } + + time.Sleep(time.Second) +} diff --git a/go.mod b/go.mod index 23b99e3..5acbfe7 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,9 @@ module git.godopu.net/lab/etri-smartfarm-poc-controller-serial go 1.17 -require github.com/rjeczalik/notify v0.9.2 +require ( + github.com/jacobsa/go-serial v0.0.0-20180131005756-15cf729a72d4 + github.com/rjeczalik/notify v0.9.2 +) require golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7 // indirect diff --git a/go.sum b/go.sum index aedd95f..b252394 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/jacobsa/go-serial v0.0.0-20180131005756-15cf729a72d4 h1:G2ztCwXov8mRvP0ZfjE6nAlaCX2XbykaeHdbT6KwDz0= +github.com/jacobsa/go-serial v0.0.0-20180131005756-15cf729a72d4/go.mod h1:2RvX5ZjVtsznNZPEt4xwJXNJrM3VTZoQf7V6gk0ysvs= github.com/rjeczalik/notify v0.9.2 h1:MiTWrPj55mNDHEiIX5YUSKefw/+lCQVoAFmD6oQm5w8= github.com/rjeczalik/notify v0.9.2/go.mod h1:aErll2f0sUX9PXZnVNyeiObbmTlk5jnMoCa4QEjJeqM= golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7 h1:bit1t3mgdR35yN0cX0G8orgLtOuyL9Wqxa1mccLB0ig= diff --git a/interface.go b/interface.go new file mode 100644 index 0000000..3cdfbfb --- /dev/null +++ b/interface.go @@ -0,0 +1,8 @@ +package manager + +type Event interface { + ToJson() +} +type EventHandler interface { + Handle(e Event) +} diff --git a/listener.go b/listener.go new file mode 100644 index 0000000..636e432 --- /dev/null +++ b/listener.go @@ -0,0 +1,13 @@ +package manager + +type SyncHandler struct{} + +func (_ *SyncHandler) Handle() { + +} + +type RecvHandler struct{} + +func (_ *RecvHandler) Handle() { + +} diff --git a/manager.go b/manager.go index 6bf4fa5..14293b2 100644 --- a/manager.go +++ b/manager.go @@ -1,27 +1,75 @@ package manager import ( - "context" - "fmt" - "time" + "bufio" + "encoding/json" + "log" - "git.godopu.net/lab/etri-smartfarm-poc-controller-serial/puserial" - "github.com/rjeczalik/notify" + "github.com/jacobsa/go-serial/serial" ) -func Run() { - fmt.Println("Hello world") - - ctx, _ := context.WithTimeout(context.Background(), time.Second*10) - ch_discover := make(chan notify.EventInfo) - go puserial.WatchNewDevice(ctx, ch_discover) - - for { - e, ok := <-ch_discover - if !ok { - fmt.Println("byebye~!") - return - } - fmt.Println(e) - } +type _manager struct { + devices map[string]*_device + SyncListener EventHandler + RecvListener EventHandler +} + +func (m *_manager) onAdd(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.Fatalf("serial.Open: %v", err) + } + + reader := bufio.NewReader(port) + + for { + port.Write([]byte("Introduce\n")) + + b, _, err := reader.ReadLine() + if err != nil { + return + } + + var obj map[string]interface{} + err = json.Unmarshal(b, &obj) + if err != nil { + continue + } + + uuid, ok := obj["uuid"] + if ok { + m.devices[iface] = &_device{ + UUID: uuid.(string), + IfaceName: iface, + Iface: port, + } + break + } + } + }() + +} + +func (m *_manager) onSync(e Event) { + +} + +func (m *_manager) onRecv(e Event) { + } diff --git a/model.go b/model.go new file mode 100644 index 0000000..2f016cf --- /dev/null +++ b/model.go @@ -0,0 +1,14 @@ +package manager + +import "io" + +type _device struct { + UUID string + IfaceName string + Iface io.ReadWriter + states []map[string]interface{} +} + +type RecvEvent struct { + Params map[string]interface{} +} diff --git a/puserial/serial.go b/puserial/serial.go index 30abaf5..155aed4 100644 --- a/puserial/serial.go +++ b/puserial/serial.go @@ -2,12 +2,29 @@ package puserial import ( "context" + "errors" "fmt" + "io/ioutil" + "path/filepath" "strings" "github.com/rjeczalik/notify" ) +func InitDevice() (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 WatchNewDevice(ctx context.Context, ch_discover chan<- notify.EventInfo) error { defer close(ch_discover) @@ -20,7 +37,6 @@ func WatchNewDevice(ctx context.Context, ch_discover chan<- notify.EventInfo) er for { select { case <-ctx.Done(): - fmt.Println("routine bye") return nil case e := <-filter: if strings.Contains(e.Path(), "/dev/ttyACM") {