package service import ( "errors" "strconv" "vamicro/config" "vamicro/sync-service/models" "vamicro/sync-service/vo" "basic.com/pubsub/protomsg.git" "basic.com/valib/bhomedbapi.git" "basic.com/valib/logger.git" uuid "github.com/satori/go.uuid" ) 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 }