etri-smartfarm-poc-controll.../listener.go

148 lines
2.7 KiB
Go
Raw Permalink Normal View History

2021-12-10 01:14:34 +00:00
package manager
2021-12-10 06:45:28 +00:00
import (
"encoding/json"
"fmt"
"log"
2021-12-16 06:57:48 +00:00
"reflect"
2021-12-12 04:48:55 +00:00
"sync"
2021-12-10 06:45:28 +00:00
)
2021-12-10 01:14:34 +00:00
2021-12-10 06:45:28 +00:00
type SyncHandler struct {
devices map[string]*_device
2021-12-12 04:48:55 +00:00
mutex *sync.Mutex
2021-12-10 06:45:28 +00:00
chanForSync map[string]chan map[string]interface{}
2021-12-16 08:42:57 +00:00
states map[string]map[string]interface{}
2021-12-10 06:45:28 +00:00
}
2021-12-12 01:08:11 +00:00
func compareMap(src map[string]interface{}, dst map[string]interface{}) bool {
for key, value := range src {
if key == "code" {
continue
}
2021-12-16 06:57:48 +00:00
if reflect.TypeOf(value).String() == "string" {
dstV, ok := dst[key].(string)
if !ok || value != dstV {
return false
}
continue
}
2021-12-16 08:34:08 +00:00
srcV, ok := value.(float64)
2021-12-10 06:45:28 +00:00
if !ok {
2021-12-16 08:34:08 +00:00
srcV = float64(value.(int))
2021-12-10 06:45:28 +00:00
}
2021-12-16 08:34:08 +00:00
dstV, ok := dst[key].(float64)
2021-12-10 06:45:28 +00:00
if !ok {
2021-12-16 08:34:08 +00:00
dstV = float64(dst[key].(int))
2021-12-10 06:45:28 +00:00
}
2021-12-12 01:08:11 +00:00
2021-12-10 06:45:28 +00:00
if srcV != dstV {
2021-12-12 01:08:11 +00:00
fmt.Println("diff ", key, "] ", srcV, " vs ", dstV)
2021-12-10 06:45:28 +00:00
return false
}
}
2021-12-12 01:08:11 +00:00
2021-12-10 06:45:28 +00:00
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
}
2021-12-10 01:14:34 +00:00
2021-12-10 06:45:28 +00:00
params := e.Params()
if params == nil {
return
}
go func() {
encoder := json.NewEncoder(device.Iface)
origin := map[string]interface{}{}
origin["code"] = 200
2021-12-12 01:08:11 +00:00
for key, value := range params {
origin[key] = value
2021-12-10 06:45:28 +00:00
}
2021-12-16 08:42:57 +00:00
sh.states[device.UUID] = origin
2021-12-12 01:08:11 +00:00
// props := []string{"fan", "light", "servo"}
2021-12-10 06:45:28 +00:00
err := encoder.Encode(origin)
if err != nil {
return
}
2021-12-12 04:11:56 +00:00
_, ok := sh.chanForSync[device.IfaceName]
if ok {
2021-12-12 04:48:55 +00:00
sh.mutex.Lock()
2021-12-12 04:11:56 +00:00
close(sh.chanForSync[device.IfaceName])
2021-12-12 04:22:53 +00:00
delete(sh.chanForSync, device.IfaceName)
2021-12-12 06:18:56 +00:00
sh.mutex.Unlock()
2021-12-12 04:11:56 +00:00
}
2021-12-12 06:18:56 +00:00
2021-12-12 04:11:56 +00:00
chanForSync := make(chan map[string]interface{})
2021-12-12 06:18:56 +00:00
sh.mutex.Lock()
sh.chanForSync[device.IfaceName] = chanForSync
sh.mutex.Unlock()
2021-12-12 04:22:53 +00:00
2021-12-12 04:11:56 +00:00
for state := range chanForSync {
2021-12-16 08:42:57 +00:00
if compareMap(sh.states[device.UUID], state) {
2021-12-12 04:48:55 +00:00
sh.mutex.Lock()
2021-12-10 06:45:28 +00:00
close(sh.chanForSync[device.IfaceName])
delete(sh.chanForSync, device.IfaceName)
2021-12-12 06:18:56 +00:00
sh.mutex.Unlock()
2021-12-10 06:45:28 +00:00
return
}
log.Println("wrong: ", state)
2021-12-16 08:42:57 +00:00
log.Println("resend: ", sh.states[device.UUID])
err := encoder.Encode(sh.states[device.UUID])
2021-12-10 06:45:28 +00:00
if err != nil {
return
}
}
2021-12-12 06:18:56 +00:00
2021-12-10 06:45:28 +00:00
}()
2021-12-10 01:14:34 +00:00
}
2021-12-10 06:45:28 +00:00
type RecvHandler struct {
devices map[interface{}]*_device
chanForSync map[string]chan map[string]interface{}
2021-12-10 08:07:20 +00:00
next EventHandler
2021-12-10 06:45:28 +00:00
}
func (rh *RecvHandler) Handle(e Event) {
2021-12-12 06:18:56 +00:00
defer func() {
if r := recover(); r != nil {
fmt.Println("panic recover - ", r)
}
}()
2021-12-10 06:45:28 +00:00
device, ok := rh.devices[e.Key()]
if !ok {
return
}
param := e.Params()
code, _ := param["code"].(float64)
2021-12-10 08:07:20 +00:00
if int(code) == 100 {
return
2021-12-10 06:45:28 +00:00
}
2021-12-10 01:14:34 +00:00
2021-12-10 08:07:20 +00:00
device.states = param
2021-12-10 06:45:28 +00:00
channel, ok := rh.chanForSync[device.IfaceName]
if ok {
channel <- device.states
}
2021-12-10 01:14:34 +00:00
2021-12-10 08:07:20 +00:00
if rh.next != nil {
rh.next.Handle(e)
}
2021-12-10 06:45:28 +00:00
// fmt.Println("recv] ", device.states)
2021-12-10 01:14:34 +00:00
}