package service import ( "basic.com/pubsub/protomsg.git" "basic.com/valib/bhomedbapi.git" "basic.com/valib/logger.git" "errors" "github.com/satori/go.uuid" "strconv" "vamicro/sync-service/models" "vamicro/sync-service/vo" "vamicro/config" ) type CameraService struct { } func (sv CameraService) CameraAdd(camVo vo.CameraEditVo) (bool,models.Camera){ var sysApi bhomedbapi.SysSetApi flag, sysconf := sysApi.GetServerInfo() var realMax = 16 if flag && sysconf.RealMax > 0 { realMax = int(sysconf.RealMax) } var err error tx := models.GetDB().Begin() defer func() { if err !=nil && tx !=nil { tx.Rollback() } }() cam := camVo.Copy2Camera() cam.Type = models.TYPE_LOCAL_CAMERA // 本地摄像机 var areaE models.Area if camVo.AreaId !="0" { if _, err = areaE.SelectbyId(camVo.AreaId); err != nil { return false,cam } } cam.Id = uuid.NewV4().String() cam.RunServerId = config.Server.AnalyServerId if camVo.RunType != models.TYPE_RUNTYPE_VIDEO && camVo.RunType != models.TYPE_RUNTYPE_POLL && camVo.RunType != models.TYPE_RUNTYPE_REALTIME { cam.RunType = models.TYPE_RUNTYPE_VIDEO } else { cam.RunType = camVo.RunType } if cam.RunType == models.TYPE_RUNTYPE_REALTIME {//实时需要判断实时数量 realList, e := cam.GetCamerasByRunType(models.TYPE_RUNTYPE_REALTIME, "") if e !=nil || len(realList) >= realMax { return false,cam } } cam.RunEnable = true cam.Floor = models.Default_Layer //添加摄像机的时候不应该指定RunServerId,在哪台服务器上配了任务,RunServerId就是对应的那台服务器 if err = tx.Table("cameras").Create(&cam).Error;err !=nil { return false,cam } if err = tx.Table("camera_area").Create(&models.CameraArea{Cameraid:cam.Id,Areaid:camVo.AreaId}).Error;err !=nil{ return false,cam } //处理传感器 if len(camVo.Sensors) > 0 { for _,sor := range camVo.Sensors { var sorE models.Sensor exist := sorE.Exist(sor.Ip, sor.Port) sorId := "" if exist { sorId = sorE.Id } else { sor.Id = uuid.NewV4().String() if err = tx.Table(sor.TableName()).Create(&sor).Error; err != nil { return false, cam } sorId = sor.Id } if err =tx.Exec("insert into camera_sensor(camera_id, sensor_id) select '"+cam.Id+"','"+sorId+"' where not exists (select 1 from camera_sensor where camera_id='"+cam.Id+"' and sensor_id='"+sorId+"')").Error;err !=nil { return false, cam } } } tx.Commit() return true,cam } func (sv CameraService) CameraUpdate(camVo vo.CameraEditVo) bool{ cam := camVo.Copy2Camera() var sysApi bhomedbapi.SysSetApi flag, sysconf := sysApi.GetServerInfo() var realMax = 16 if flag && sysconf.RealMax > 0 { realMax = int(sysconf.RealMax) } var camTmp models.Camera rows, err := camTmp.SelectById(cam.Id) if err != nil || rows ==0 { return false } cam.Floor = camTmp.Floor if camTmp.RunServerId == "" {//未设置过run_server_id,此种情况是国标摄像机第一次保存,会选择目标服务器的id cam.RunServerId = config.Server.AnalyServerId //此摄像机归属到本台分析服务器 //if cam.RunServerId == "" { // return false //} } else { cam.RunServerId = camTmp.RunServerId //虽然国标摄像机集群内共享,但是更新时不会修改归属 } //过滤非法数据 if cam.RunType != models.TYPE_RUNTYPE_VIDEO && cam.RunType != models.TYPE_RUNTYPE_POLL && cam.RunType != models.TYPE_RUNTYPE_REALTIME { cam.RunType = models.TYPE_RUNTYPE_VIDEO } if cam.RunType == models.TYPE_RUNTYPE_REALTIME { if camTmp.RunType != models.TYPE_RUNTYPE_REALTIME { //由非实时到实时的切换时,需要判断当前的实时数量 realList, e := cam.GetCamerasByRunType(models.TYPE_RUNTYPE_REALTIME, "") if e !=nil || len(realList) >= realMax { return false } } } //处理传感器 var camSensor models.CameraSensor if !camSensor.DeleteByCamId(camVo.Id) { logger.Debug("cameraSensor deleteByCameraId fail") return false } if camVo.Sensors != nil && len(camVo.Sensors) > 0 { for _,sor :=range camVo.Sensors { var sorE models.Sensor exist := sorE.Exist(sor.Ip, sor.Port) sorId := "" if exist { sorId = sorE.Id if err = models.GetDB().Table(sor.TableName()).Where("id=?", sorId).Update(&sor).Error;err !=nil { return false } } else { sor.Id = uuid.NewV4().String() if err = models.GetDB().Table(sor.TableName()).Create(&sor).Error; err != nil { return false } sorId = sor.Id } if err = models.GetDB().Exec("insert into camera_sensor(camera_id, sensor_id) select '"+cam.Id+"','"+sorId+"' where not exists (select 1 from camera_sensor where camera_id='"+camVo.Id+"' and sensor_id='"+sorId+"')").Error;err !=nil { return false } } } cam.IsRunning = camTmp.IsRunning err = cam.Update() if err != nil { return false } return true } func (sv CameraService) GetCamerasByRunType(runType int,cameraName string) (cams []vo.CamSensorVo,err error){ //指定当前机器为过滤条件 var cameraE models.Camera list, err := cameraE.GetCamerasByRunType(runType, cameraName) if err !=nil { return nil,err } var crApi bhomedbapi.CameraRuleApi var sensorE models.Sensor for _,cam :=range list {//判断每一个摄像机是否有可运行的任务和规则 if crApi.ExistRunningTask(cam.Id) { sensors, _ := sensorE.FindByCameraId(cam.Id) var camSor vo.CamSensorVo camSor.Camera = cam if sensors != nil { camSor.Sensors = sensors } else { camSor.Sensors = []models.Sensor{} } cams = append(cams, camSor) } } return cams,nil } func (sv CameraService) UpdateIsRunningState(id string,isRunning bool) bool{ var cameraE models.Camera return cameraE.UpdateIsRunningState(id,isRunning) } func (sv CameraService) UpdateIsRunningAll(camIds []string) bool { var cameraE models.Camera return cameraE.UpdateIsRunningAll(camIds) } func (sv CameraService) UpdateRunEnable(cameraId string,runEnable bool) bool{ var cameraE models.Camera return cameraE.UpdateRunEnable(cameraId, runEnable) } //1.判断本地摄像机的实时数量 //2.判断是否安装有国标,以及国标实时摄像机的数量 func (sv CameraService) ChangeRunType(ccrVo vo.CameraChangeRunVo) bool { var sysApi bhomedbapi.SysSetApi flag, sysconf := sysApi.GetServerInfo() var realMax = 16 if flag && sysconf.RealMax > 0 { realMax = int(sysconf.RealMax) } var err error tx := models.GetDB().Begin() defer func() { if err !=nil && tx !=nil{ tx.Rollback() } }() for _,cameraId :=range ccrVo.CameraIds{ var camE models.Camera rows, e := camE.SelectById(cameraId) if e == nil && rows>0 { if ccrVo.RunType == models.TYPE_RUNTYPE_REALTIME { //非实时向实时切换 if camE.RunType != models.TYPE_RUNTYPE_REALTIME { realList, e := camE.GetCamerasByRunType(models.TYPE_RUNTYPE_REALTIME, "") if e !=nil || len(realList) >= realMax { err = errors.New("realTime cameras limit "+strconv.Itoa(realMax)) return false } } else { continue } } if camE.RunServerId == "" { if err = tx.Exec("update cameras set run_type=?,run_server_id=?,is_running=0 where id=?", ccrVo.RunType,config.Server.AnalyServerId, cameraId).Error;err !=nil{ return false } } else { if err = tx.Exec("update cameras set run_type=?,is_running=0 where id=?", ccrVo.RunType, cameraId).Error;err !=nil{ return false } } } } tx.Commit() return true } func (sv CameraService) UpdateSnapshot(cameraId string, snapshot string) bool { var cameraE models.Camera return cameraE.UpdateSnapshot(cameraId, snapshot) } func (sv CameraService) GetAllCamerasByServer(serverId string, cameraName string) (criList []vo.CameraRunInfo,err error) { var cameraE models.Camera list, err := cameraE.FindAllByServer(serverId, cameraName) if err !=nil { return nil,err } serverName := "" var syssetApi bhomedbapi.SysSetApi fb,localConf := syssetApi.GetServerInfo() if fb { serverName = localConf.ServerName } nodesMap := make(map[string]protomsg.Node) var clusterApi bhomedbapi.ClusterApi flag, cInfo := clusterApi.FindCluster() if flag && cInfo.Nodes != nil{ for _,node :=range cInfo.Nodes { nodesMap[node.Id] = *node } } var crApi bhomedbapi.CameraRuleApi if list !=nil && len(list) >0 { for _,cE :=range list { var cri vo.CameraRunInfo cri.CopyFromCamera(cE) if cri.RunServerId != "" { if cri.RunServerId == config.Server.AnalyServerId { cri.RunServerName = serverName } else { if ne,ok :=nodesMap[cri.RunServerId];ok { cri.RunServerName = ne.NodeName } } } fb, cgs := crApi.FindAllTaskById(cE.Id) if fb && cgs.Rules != nil { for _, g :=range cgs.Rules { var crTask vo.CameraRunTask crTask.HasRule = g.Enable crTask.TaskName = g.SceneName cri.Tasks = append(cri.Tasks, crTask) } } else { cri.Tasks = []vo.CameraRunTask{} } //处理摄像机的状态 if cE.RunType == models.TYPE_RUNTYPE_POLL || cE.RunType == models.TYPE_RUNTYPE_REALTIME { if crApi.ExistRunningTask(cE.Id) { if cE.IsRunning { cri.Status = models.Camera_Status_Doing } else { cri.Status = models.Camera_Status_Wait } } else { cri.Status = models.Camera_Status_NoRule } } else { cri.Status = models.Camera_Status_Other } criList = append(criList, cri) } } return criList,nil } //通过摄像机id获取在哪台服务器上运行 func GetRunServerName(cameraId string) string { var runServerName = "" var camTmp models.Camera rows, _ := camTmp.SelectById(cameraId) if rows >0 { var syssetApi bhomedbapi.SysSetApi fb,localConf := syssetApi.GetServerInfo() if fb { if camTmp.RunServerId == localConf.ServerId {//归属本台服务器 runServerName = localConf.ServerName } else {//属于其他服务器 var clusterApi bhomedbapi.ClusterApi flag, cInfo := clusterApi.FindCluster() if flag { if cInfo.Nodes != nil { for _,n := range cInfo.Nodes { if n.Id == camTmp.RunServerId { runServerName = n.NodeName break } } } } } } } return runServerName }