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{} next EventHandler } 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 { 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) }