// Copyright 2019 github.com. All rights reserved. // Use of this source code is governed by github.com. package timetask import ( "access-control-monitor/consts" "access-control-monitor/pb" "access-control-monitor/pb/v1" "access-control-monitor/utils" "context" "encoding/json" "fmt" "sync" "time" "github.com/jaryhe/gopkgs/logger" "go.uber.org/zap" ) var status map[string]int64 var mutex sync.Mutex func handleOfflineAlarm(sn string) error { deviceInfo, err := utils.GetDeviceInfo(sn) if err != nil { return err } alram := &v1.AlarmAddRequest{ Date: time.Now().Format(consts.TimeSecondLayOut), ProjectId: deviceInfo.ProjectId, Sn: sn, DeviceName: deviceInfo.Name, DeviceType: consts.AccessControlDeviceName, DeviceCode:int32(consts.AccessControlDeviceCode), } alram.AlarmReason = "离线" alram.AlarmCode = consts.DeviceOfflineCode // 添加告警 _, err = pb.Alarm.AlarmAdd(context.Background(), alram) if err != nil { reqByte, _ := json.Marshal(*alram) logger.Error("rpc", zap.String("call", "pb.SmartAlarm.AlarmAdd"), zap.String("args", string(reqByte)), zap.String("error", err.Error())) return err } return nil } func setAccessControlStatus(sn string, status int32) error { if status == consts.DeviceOffline { handleOfflineAlarm(sn) } rpcReq := &v1.DeviceStatusUpdateRequest{Sn: sn, Status: status, DeviceCode: consts.AccessControlDeviceCode} _, err := pb.Auth.DeviceStatusUpdate(context.Background(), rpcReq) if err != nil { reqByte, _ := json.Marshal(*rpcReq) logger.Error("rpc", zap.String("call", "pb.SmartAuth.DeviceStatusUpdate"), zap.String("args", string(reqByte)), zap.String("error", err.Error())) } return err } func accessControlStatusTaskImpl() { defer func() { if r := recover(); r != nil { err := fmt.Errorf("%+v", r) logger.Error("err", zap.String("system_err", err.Error()), zap.Stack("stacktrace")) } }() timeNow := time.Now().Unix() for k, v := range status { // 超过3分钟没有连接认为超时 if (timeNow - v) > consts.HalfMinSecond*3 { mutex.Lock() // 设置状态成功后清除缓存 err := setAccessControlStatus(k, consts.DeviceOffline) if err == nil { delete(status, k) } mutex.Unlock() } } } func accessControlStatusTask() { status = make(map[string]int64) for { // 任务实现 accessControlStatusTaskImpl() // 休眠60s time.Sleep(consts.HalfMinSecond * time.Second) } } func UpdateDustTime(sn string) { timeNow := time.Now().Unix() mutex.Lock() defer mutex.Unlock() // 重新启动或设备上线 if _, ok := status[sn]; !ok { // 设置为在线 err := setAccessControlStatus(sn, consts.DeviceOnline) if err != nil { // 设置失败不更新本地缓存 return } } // 更新时间为当前时间搓 status[sn] = timeNow }