package service import ( "encoding/json" "errors" "time" "vamicro/camera-common/vo" "vamicro/chanmanage-service/cache" "vamicro/chanmanage-service/models" "basic.com/pubsub/protomsg.git" "basic.com/valib/bhomeclient.git" "basic.com/valib/bhomedbapi.git" "basic.com/valib/logger.git" ) const ( ProcName = "chanmanage-service" ) type PollSetService struct { Bk bhomeclient.Broker } func NewPollSetService(broker bhomeclient.Broker) *PollSetService { ps := &PollSetService{ Bk: broker, } return ps } func (sv *PollSetService) GetPollConfig() (models.PollConfig, error) { var pcE models.PollConfig return pcE.GetOne() } func (sv *PollSetService) SavePollConfig(pc models.PollConfig) bool { if pc.Save() { dbMsg := protomsg.DbChangeMessage{ Table: protomsg.TableChanged_T_PollConfig, Action: protomsg.DbAction_Insert, } pb, _ := json.Marshal(dbMsg) sv.Bk.Publish(ProcName, pb) return true } return false } func (sv *PollSetService) UpdatePollConfig(pc models.PollConfig) bool { if pc.Update() { dbMsg := protomsg.DbChangeMessage{ Table: protomsg.TableChanged_T_PollConfig, Action: protomsg.DbAction_Update, } pb, _ := json.Marshal(dbMsg) sv.Bk.Publish(ProcName, pb) return true } return false } func (sv *PollSetService) UpdateEnable(enable bool) bool { var pc models.PollConfig if pc.UpdateEnable(enable) { dbMsg := protomsg.DbChangeMessage{ Table: protomsg.TableChanged_T_PollConfig, Action: protomsg.DbAction_Update, } pb, _ := json.Marshal(dbMsg) sv.Bk.Publish(ProcName, pb) return true } return false } // 触发条件 // 1.实时摄像机切换为轮询或者监控,或者实时由监控切换为实时 // 2.实时摄像机规则Enable状态改变 func (sv *PollSetService) ResetChannelCount() { //1.计算做实时任务的路数 //2.本地文件占的路数 //3.总路数减去实时占的路数以及本地文件占的路数,即为轮询占的路数 runInfo := sv.StatisticRunInfo() realCount := runInfo.RealValidCount videoCount := 0 pollCount := 0 if realCount < runInfo.ChannelTotal { allocI := runInfo.ChannelTotal - realCount //实时剩余算力 logger.Debug("allocI:", allocI) videoCount = runInfo.StackChannelCount if videoCount > allocI { videoCount = allocI pollCount = 0 } else { pollCount = runInfo.ChannelTotal - realCount - videoCount if pollCount < 0 { pollCount = 0 } } } sv.UpdateChannelCount(pollCount, videoCount) } // 拖动改变轮询和数据栈的数量 func (sv *PollSetService) UpdateChannelCount(pollChannelCount int, videoChannelCount int) bool { var fasApi bhomedbapi.FileStackApi var err error tx := models.GetDB().Begin() defer func() { if err != nil && tx != nil { tx.Rollback() } }() err = tx.Exec("update poll_config set pollChannelCount=?", pollChannelCount).Error if err != nil { return false } //改变数据栈的算力 if !fasApi.UpdateChannelCount(videoChannelCount) { err = errors.New("fileSetting UpdateChannelCount ret false") return false } tx.Commit() dbMsg := protomsg.DbChangeMessage{ Table: protomsg.TableChanged_T_PollConfig, Action: protomsg.DbAction_Update, } pb, _ := json.Marshal(dbMsg) sv.Bk.Publish(ProcName, pb) return true } func (sv *PollSetService) StatisticRunInfo() vo.CameraRunStatistic { var v vo.CameraRunStatistic var camApi bhomedbapi.CameraApi var gbApi bhomedbapi.Gb28181Api timeStart := time.Now() sysconf, err1 := cache.GetServerInfo() if err1 == nil { v.ChannelTotal = int(sysconf.RealMax) } logger.Debug("statisticRunInfo 取完ServerInfo耗时:", time.Since(timeStart)) timeStart = time.Now() camMap := make(map[string]protomsg.Camera) if cams := camApi.FindAll("", "", "", ""); cams != nil { for _, c := range cams { camMap[c.Id] = c } } logger.Debug("statisticRunInfo 取完本地摄像机耗时:", time.Since(timeStart)) timeStart = time.Now() if cams := gbApi.FindAll("", "", "", ""); cams != nil { for _, c := range cams { camMap[c.Id] = c } } logger.Debug("statisticRunInfo 取完国标摄像机耗时:", time.Since(timeStart)) timeStart = time.Now() allRules, e := cache.GetCameraRules() ruleM := make(map[string]protomsg.CameraAndRules) if e == nil && allRules != nil { for _, ar := range allRules { if ar.CameraInfo != nil { ruleM[ar.CameraInfo.Id] = ar } } } //获取督查任务 tasks := models.GetTasks() rTotal := 0 pTotal := 0 for _, c := range camMap { if c.RunType == bhomeclient.TYPE_RUNTYPE_REALTIME { rTotal++ if taskInfo, ok := tasks[c.Id]; ok && taskInfo != nil && len(taskInfo) > 0 { v.RealValidCount++ } else { v.RealInvalidCount++ } if c.IsRunning { v.RealRunningCount++ } } else if c.RunType == bhomeclient.TYPE_RUNTYPE_POLL { // pTotal++ // if crInfo, ok := ruleM[c.Id]; ok && crInfo.Rules != nil && len(crInfo.Rules) > 0 { // v.PollValidCount++ // } else { // v.PollInvalidCount++ // } // if c.IsRunning { // v.PollRunningCount++ // } } } //总算里暂时只统计实时算力 v.ChannelTotal = rTotal v.RealTotal = rTotal v.PollTotal = pTotal logger.Debug("statisticRunInfo 获取完ExistRunningTask耗时:", time.Since(timeStart)) timeStart = time.Now() //轮询通道数量从轮询配置中获取20250724移除 // var pollConf models.PollConfig // pcE, err2 := pollConf.GetOne() // if err2 == nil { // v.PollChannelCount = pcE.PollChannelCount // } //tmpPC := v.RealTotal - v.StackTotal //if tmpPC < 0 { // v.PollChannelCount = 0 //} else { // v.PollChannelCount = tmpPC //} var fasApi bhomedbapi.FileAnalysisApi if set, err := fasApi.GetFileAnalysisSet(); err == nil { v.StackChannelCount = int(set.VideoChannelCount) } logger.Debug("statisticRunInfo 取完FileAnalysisSet耗时:", time.Since(timeStart)) timeStart = time.Now() var sckApi bhomedbapi.FileStackApi sb, scks := sckApi.FindAllDoingStacks() if sb && scks != nil { for _, sck := range scks { if sck.Enable { //打开分析开关,纳入统计 v.StackTotal++ if crInfo, ok := ruleM[sck.Id]; ok && crInfo.Rules != nil && len(crInfo.Rules) > 0 { v.StackValidCount++ } else { v.StackInvalidCount++ } if sck.Status == bhomeclient.Stack_Status_Doing { v.StackRunningCount++ } } } } logger.Debug("statisticRunInfo 取完数据栈状态耗时:", time.Since(timeStart)) // 山东断流监控测试 //for i := 1; i < 10; i++ { // v.DuanliuID = append(v.DuanliuID, strconv.Itoa(i)+"->"+strconv.Itoa(i)+"->"+"test-duanliu-"+strconv.Itoa(i)) //} // 山东断流监控 for _, k := range GetDuanliuIds() { // 解析摄像机信息 var cameraInfo string if c, ok := camMap[k]; ok { cameraInfo = c.Id + "->" + c.Name + "->" + c.Rtsp } else { continue } v.DuanliuID = append(v.DuanliuID, cameraInfo) } logger.Debug("statisticRunInfo 断流数据:", v.DuanliuID) return v }