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

109 lines
2.1 KiB
Go

package manager
import (
"encoding/json"
"fmt"
"log"
)
type SyncHandler struct {
devices map[string]*_device
chanForSync map[string]chan map[string]interface{}
}
func compareMap(src map[string]interface{}, dst map[string]interface{}, props []string) bool {
for _, prop := range props {
srcV, ok := src[prop].(int)
if !ok {
srcV = int(src[prop].(float64))
}
dstV, ok := dst[prop].(int)
if !ok {
dstV = int(dst[prop].(float64))
}
if srcV != dstV {
fmt.Println("diff ", prop, "] ", 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
props := device.propsToSync
// props := []string{"fan", "light", "servo"}
for _, pname := range props {
prop, ok := params[pname]
if !ok {
origin[pname] = device.states[pname]
} else {
origin[pname] = prop
}
}
err := encoder.Encode(origin)
if err != nil {
return
}
sh.chanForSync[device.IfaceName] = make(chan map[string]interface{})
for state := range sh.chanForSync[device.IfaceName] {
if compareMap(origin, state, props) {
log.Println("Same!!")
close(sh.chanForSync[device.IfaceName])
delete(sh.chanForSync, device.IfaceName)
return
}
log.Println("wrong: ", state)
log.Println("resend: ", origin)
err := encoder.Encode(origin)
if err != nil {
return
}
}
}()
}
type RecvHandler struct {
devices map[interface{}]*_device
chanForSync map[string]chan map[string]interface{}
}
func (rh *RecvHandler) Handle(e Event) {
device, ok := rh.devices[e.Key()]
if !ok {
return
}
param := e.Params()
code, _ := param["code"].(float64)
if int(code) != 100 {
device.states = param
}
channel, ok := rh.chanForSync[device.IfaceName]
if ok {
channel <- device.states
}
// fmt.Println("recv] ", device.states)
}