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-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-12 01:08:11 +00:00
|
|
|
srcV, ok := value.(int)
|
2021-12-10 06:45:28 +00:00
|
|
|
if !ok {
|
2021-12-12 01:08:11 +00:00
|
|
|
srcV = int(value.(float64))
|
2021-12-10 06:45:28 +00:00
|
|
|
}
|
|
|
|
|
2021-12-12 01:08:11 +00:00
|
|
|
dstV, ok := dst[key].(int)
|
2021-12-10 06:45:28 +00:00
|
|
|
if !ok {
|
2021-12-12 01:08:11 +00:00
|
|
|
dstV = int(dst[key].(float64))
|
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-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-12 01:08:11 +00:00
|
|
|
if compareMap(origin, 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)
|
|
|
|
log.Println("resend: ", origin)
|
|
|
|
err := encoder.Encode(origin)
|
|
|
|
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
|
|
|
}
|