def allowed_alert_type(): status = functl.get("") allowed_alert = [] allowed_title = [] for k, v in status.items(): if v.get("enable", False): allowed_alert.append(k) allowed_title.append(v.get("title", "")) return allowed_alert, allowed_title
def init_func(device_id): if device_id: init_func_list = {} for f, v in functl.get("").items(): init_func_list[f] = { "enable": True, "zones": [], "reverse": False, "detection_cycle": v["detection_cycle"], "alert_level": v["alert_level"], "threshold": v["init_threshold"], "aggreagate": v["aggreagate"], "aggreagate_times": v["aggreagate_times"], } update(device_id, {"function": init_func_list})
def summary_category(query): """ 查询各种类型报警数量 """ results = mongodb.alerts.find(query) alert_sum_dict = {} all_functions = functl.get("") # all_alert_type = SYS_CONF.get("all_alerts", []) for func_name in all_functions: alert_sum_dict[func_name] = 0 for result in results: title = result.get("func_name") if title in alert_sum_dict: alert_sum_dict[title] += 1 return alert_sum_dict
def on_function_batch(self, data): """ 批量更新边侧摄像头某种类型的告警设置 """ logging.info("function batch setting: {}".format(data)) msg_id = data["msg_id"] func_name = data["func_name"] enable = data["enable"] aggreagate = data["aggreagate"] device_ids = data["device_ids"] update_server = data["update_server"] desc = "success" if update_server: # 修改function表的设置 function = functl.get(func_name) if function: function["enable"] = enable function["aggreagate"] = aggreagate functl.update_all({func_name: function}) else: desc = "func_name {} not support".format(func_name) # 依次处理每个设备 for device_id in device_ids: cam_info = camctl.get_one(device_id) function = cam_info.function one_function = function.get(func_name) if one_function: one_function["enable"] = enable one_function["aggreagate"] = aggreagate function[func_name] = one_function camctl.update(device_id, {"function": function}) else: if desc == "success": desc = "" desc += "device {} not support func_name {}".format( device_id, func_name) resp_data = { "msg_id": msg_id, # 带着上面的msgId "desc": desc # success表示成功,失败传原因 } self.publish(Cloud.topic_pub_function_batch, resp_data)
def report_function(self, msg_id=None, device_id=None): """ 更新边侧设备告警设置 需要边侧启动并连接成功后向云侧主动报告一次 """ data = {} if msg_id: data["msg_id"] = msg_id if device_id: data["function"] = camctl.get_one(device_id).function elif device.is_edge_proxy(): data["function"] = functl.get("") else: cam = device.get_edge_ipc_cam() data["function"] = cam.function logging.info("report function: {}".format(data)) self.publish(Cloud.topic_pub_function, data)
def do_post(self, data): """ modify part of function settings of a specific camera """ device_id = data.get("device_id") func_name = data.get("func_name") enable = data.get("enable", False) zones = data.get("zones", [[]]) reverse = data.get("reverse", False) threshold = data.get("threshold", 0.2) detection_cycle = data.get( "detection_cycle", { "detection_starttime": 0, "detection_endtime": 64800, "detection_period": [0, 1, 2, 3, 4, 5, 6], }) _, _, ts = clock.now() detected_time = [ts] * len(zones) try: cam = camctl.get_one(device_id) if func_name not in functl.get(""): raise RuntimeError("invalid function id") if not isinstance(zones, list): raise RuntimeError("invalid parameters") all_function = cam.function function_spec = all_function.get(func_name, {}) function_spec["enable"] = enable function_spec["zone"] = zones function_spec["reverse"] = reverse function_spec["threshold"] = threshold function_spec["detection_cycle"] = detection_cycle function_spec["detected_time"] = detected_time all_function[func_name] = function_spec camctl.update(device_id, {"function": all_function}) cam = camctl.get_one(device_id) except Exception as err: logging.exception(err) return self.failed(500, "{}".format(err)) return self.success(cam.function)
def add(cam_type, address, username, password, cam_uuid=None, cam_port=554, cam_channel=1): for c in get_all( {})[0]: # take this structure to handle more complicated scenario if c.cam_address == address and c.cam_channel == cam_channel: return c.uuid _, _, ts = clock.now() init_func_list = {} for f, v in functl.get("").items(): init_func_list[f] = { "enable": True, "zones": [], "reverse": False, "detection_cycle": v["detection_cycle"], "alert_level": v["alert_level"], "threshold": v["init_threshold"], "aggreagate": v["aggreagate"], "aggreagate_times": v["aggreagate_times"], } if not cam_uuid: cam_uuid = _gen_id(address) camera_data = { "uuid": cam_uuid, "name": address, "edgex_name": "", "type": "camera", "cam_type": cam_type, "cam_address": address, "cam_port": cam_port, "cam_username": username, "cam_passwd": password, "cam_channel": cam_channel, "host_id": SYS_CONF['host_id'], "host_ip": SYS_CONF['host_ip'], "location": '未指定', "wakeup_time": ts, "status": "normal", "interval": SYS_CONF['default_capture_interval'], "function": init_func_list, "flavour": False, "history": SYS_CONF['history'], "alert": SYS_CONF["alert"], "upload": SYS_CONF["upload"], "detected_times": [ts], } mongodb.device.insert_one(camera_data) get_all({}) warning_count = { camera_data["uuid"]: {func: [] for func in functl.get("").keys()} } memory.WARNING_COUNT.update(warning_count) # RT.insert_subtask(camera_data['uuid']) Middle.RT.insert_subtask(camera_data['uuid']) if device.is_edge_proxy(): Middle.CldT.report_cam_setting(cam_uuid) Middle.CldT.report_function_cam(cam_uuid)
def do_get(self, data): return self.success(functl.get(""))
def __call__(self, raw_results, cam): # leave filter cam_function = cam.function cam_info = cam_function.get(self.func_name, {}) cam_reverse = cam_info.get("reverse", False) aggreagate_time = functl.get(self.func_name).get("aggreagate", 300) filter_results = [] if cam_info.get("enable", False): logging.info("_apply_{}_filter:: filtering...".format( self.func_name)) cam_zones = cam_info.get("zones", []) cam_detected_times = cam.detected_times _, _, ts = clock.now() if cam_zones == []: logging.info("apply_{}_filter:: zones: whole img".format( self.func_name)) logging.info( "last detected time is:: {}, current time is:: {}".format( clock._get_csttz_dt(cam_detected_times[0]), clock._get_csttz_dt(ts))) detected_flag = False for result in raw_results: if result[0] == 'person_body': detected_flag = True if detected_flag: cam_detected_times = [ts] camctl.update(cam.uuid, {"detected_times": cam_detected_times}) else: if (ts - cam_detected_times[0]) > aggreagate_time: return_result = ["leave", 0.666, "0", "0", "1", "1"] filter_results.append(return_result) else: logging.info("_apply_{}_filter:: zones: {}".format( self.func_name, cam_zones)) if len(cam_detected_times) != len(cam_zones): cam_detected_times = [ts] * len(cam_zones) for result in raw_results: in_flag = False in_index = -1 if result[0] == "person_body": left_leg_x = int(result[2]) right_leg_x = int(result[4]) leg_y = int(result[5]) check_point = { "x": int((left_leg_x + right_leg_x) / 2), "y": leg_y } for i, zone in enumerate(cam_zones): check_point_inside = _isInsidePolygon( check_point, zone) if check_point_inside: in_flag = True in_index = i if in_flag: cam_detected_times[in_index] = ts camctl.update(cam.uuid, {"detected_times": cam_detected_times}) for i, zone in enumerate(cam_zones): detected_time = cam_detected_times[i] logging.info( "zone {} @ last detected time is:: {}, current time is:: {}" .format(i, clock._get_csttz_dt(detected_time), clock._get_csttz_dt(ts))) if (ts - detected_time) > aggreagate_time: xmin = str(zone[0]["x"]) ymin = str(zone[0]["y"]) xmax = str(zone[2]["x"]) ymax = str(zone[2]["y"]) return_result = [ "leave", 0.666, xmin, ymin, xmax, ymax ] filter_results.append(return_result) """ if cam_reverse: if not in_flag: filter_results.append(result) else: if in_flag: filter_results.append(result) """ logging.info("_apply_{}_filter:: results: {}".format( self.func_name, filter_results)) parse_results = reslove_result(filter_results, self.func_name) return parse_results
def export(parse_results, pic_path, cam): export_url = SYS_CONF["exporter"].get("url") if export_url is None: raise RuntimeError("export url is None!") alert_allowed, _ = alctl.allowed_alert_type() img = cv2.imread(pic_path) cst_dt, utc_dt, ts = clock.now() cor = [20, 20] for func_name in alert_allowed: color = FUNC_BBOX_COLOR[func_name] cv2.putText(img, func_name, tuple(cor), cv2.FONT_HERSHEY_COMPLEX, 0.5, color, 1) cor[1] = cor[1] + 15 export_data = { "device_id": cam.uuid, "device_name": cam.name, "host_id": SYS_CONF.get("host_id"), "host_ip": SYS_CONF.get("host_ip"), "timestamp": clock.format_dt_standard(utc_dt), "location": cam.location, "alert": [], "image": '', } for func_name, alert_info in parse_results.items(): if func_name not in alert_allowed: logging.info("alert(%s) raise, but will not export", func_name) continue aggregation_time = functl.get(func_name).get("aggreagate", 600) result = mongodb.alerts.find_one({ "create_time": { '$gte': (ts - aggregation_time) }, "device_id": cam.uuid, "func_name": func_name }) if not result: for position in alert_info: probability = str(position["probability"]) xmin = int(position["xmin"]) ymin = int(position["ymin"]) xmax = int(position["xmax"]) ymax = int(position["ymax"]) export_data["alert"].append([ func_name, probability, str(xmin), str(ymin), str(xmax), str(ymax) ]) img = cv2.rectangle(img, (xmin, ymin), (xmax, ymax), FUNC_BBOX_COLOR[func_name], 4) b64_str = cv2.imencode('.jpg', img)[1].tostring() b64_img = base64.b64encode(b64_str) export_data["image"] = str(b64_img, encoding='utf-8') requests_data = json.dumps(export_data) try: if export_data["alert"] != []: response = requests.post(export_url, data=requests_data) logging.info(response) except Exception as err: logging.error("export data failed!")
def on_snap(self, data): """ 手动拍照 """ msg_id = data["msg_id"] device_id = data["device_id"] cam = camctl.get_one(device_id) # snap image will delete by routine, add suffix to avoid saved_path, if_sto_db = bktctl.save(cam.frame(), device_id, True, False, "snap") resp_data = { "msg_id": msg_id, # 请求中的msg_id "name": "", # 图片名称 "device_id": device_id, # 设备ID "create_time": clkctl._unix13ts(), # 1 3位时间戳 "alert": [], # ai识别产生的告警列表 } if if_sto_db and cam.history and cam.history.get("upload", "") == "local": resp_data["path"] = saved_path.split("w2s/")[1] else: with open(saved_path, "rb") as f: resp_data["img_str"] = str(base64.b64encode(f.read()), encoding='utf-8') function_list = rcgctl.period_function_filter(cam, mode="manual") model_list = rcgctl.ai_pointer_filter(function_list) try: logging.info( "%s manual photo: start ai recognize, function is : %s, model is : %s", device_id, str(function_list), str(model_list)) parse_results = rcgctl.recognize(saved_path, device_id, function_list, model_list) if parse_results: for k, v in parse_results.items(): res = { "func_name": k, # AI类型 "title": functl.get(k).get("title", ""), # 告警名称 "alert_position": v, # 告警框列表,每个框是一个矩形 "create_time": clkctl._unix13ts(), # 13位时间戳 "level": cam.function.get(k, {}).get( "alert_level", functl.get(k).get("alert_level", "")) # general/urgent } resp_data["alert"].append(res) self.publish(Cloud.topic_pub_snap, resp_data) else: self.publish(Cloud.topic_pub_snap, resp_data) logging.info("%s manual photo success: %s", device_id, resp_data) except Exception as err: logging.error("%s manual photo ai failed: %s", device_id, err) self.publish(Cloud.topic_pub_snap, resp_data) finally: if not if_sto_db: bktctl.delete(saved_path)
def create(cam, func_name, result_info, image_path): alert_allowed, _ = allowed_alert_type() if func_name not in alert_allowed: logging.info("alert(%s) raise, but will not prompt", func_name) return False _, _, ts = clock.now() alert = { "sub_type": "camera", "device_id": cam.uuid, "device_name": cam.name, "host_id": SYS_CONF.get("host_id"), "host_ip": SYS_CONF.get("host_ip"), "func_name": func_name, "title": functl.get(func_name).get("title", ""), # TODO: alert_position should be renamed "alert_position": result_info, "create_time": ts, "location": cam.location, "status": "opening", "affirmed": False, "level": cam.function.get(func_name, {}).get("alert_level", functl.get(func_name).get("alert_level", "")), } aggreagate = cam.function[func_name].get("aggreagate", 60) warning_count = memory.WARNING_COUNT[cam.uuid].get(func_name, []) logging.info("driver.alert:: warning_count of func@{} is {}".format(func_name, warning_count)) aggreagate_times = cam.function[func_name].get("aggreagate_times", 1) # aggreagate_times=1, 超过告警间隔才发送告警 if aggreagate_times == 1: result = mongodb.alerts.find_one( {"create_time": {'$gte': (ts - aggreagate)}, "device_id": cam.uuid, "func_name": func_name}) if result: return False _save_alert_in_db(alert, image_path, cam) alert_data = copy.deepcopy(alert) alert_data.pop("_id", None) alert_data["create_time"] = ts * 1000 Middle.CldT.report_alert(alert_data, cam, os.path.join(IMG_BASE_PATH, image_path)) return True # aggreagate_times>1,aggreagate内连续告警超过aggreagate_tims才告警 if len(warning_count) < aggreagate_times: memory.WARNING_COUNT[cam.uuid][func_name].append(ts) if len(memory.WARNING_COUNT[cam.uuid][func_name]) == aggreagate_times: if (ts - warning_count[0]) <= aggreagate: memory.WARNING_COUNT[cam.uuid][func_name].pop(0) result = mongodb.alerts.find_one( {"create_time": {'$gte': (ts - aggreagate + 1)}, "device_id": cam.uuid, "func_name": func_name}) if result: return False _save_alert_in_db(alert, image_path, cam) alert_data = copy.deepcopy(alert) alert_data.pop("_id", None) alert_data["create_time"] = ts * 1000 Middle.CldT.report_alert(alert_data, cam, os.path.join(IMG_BASE_PATH, image_path)) return True return False # 当aggreagate_times改小时,只截取一部分ts if len(warning_count) >= aggreagate_times: memory.WARNING_COUNT[cam.uuid][func_name].append(ts) memory.WARNING_COUNT[cam.uuid][func_name] = memory.WARNING_COUNT[cam.uuid][func_name][-aggreagate_times:] if (ts - memory.WARNING_COUNT[cam.uuid][func_name][0]) <= aggreagate: memory.WARNING_COUNT[cam.uuid][func_name].pop(0) result = mongodb.alerts.find_one( {"create_time": {'$gte': (ts - aggreagate + 1)}, "device_id": cam.uuid, "func_name": func_name}) if result: return False _save_alert_in_db(alert, image_path, cam) alert_data = copy.deepcopy(alert) alert_data.pop("_id", None) alert_data["create_time"] = ts * 1000 Middle.CldT.report_alert(alert_data, cam, os.path.join(IMG_BASE_PATH, image_path)) return True return False """ aggregation_time = cam.function.get(func_name, {}).get("aggreagate", functl.get(func_name).get("aggreagate", 600)) result = mongodb.alerts.find_one( {"create_time": {'$gte': (ts - aggregation_time)}, "device_id": cam.uuid, "func_name": func_name}) if result: return False mongodb.alerts.insert_one(alert) return True """ """