def on_function(self, data): # 目前该function仅用于TD201/202 # 阵列和盒子等代理使用function batch和function cam,其中function cam应该废弃变成function logging.info("function setting: {}".format(data)) msg_id = data.pop("msg_id", "") func_name = data.pop("func_name") if device.is_edge_ipc(): cam = device.get_edge_ipc_cam() elif "device_id" in data: cam = camctl.get_one(data["device_id"]) else: logging.info("unexpected function setting got: %s", data) self.report_function(msg_id) return cam_function = cam.function if cam_function and func_name in cam_function: for k, v in data.items(): cam_function[func_name][k] = v logging.info("change cam {} function: {}".format( cam.uuid, cam_function)) camctl.update(cam.uuid, {"function": cam_function}) self.report_function(msg_id, data.pop("device_id", None))
def report_img(self, device_id, save_name, img_path, timestamp, img_size, if_sto_db): """ 历史采集图片上传 TODO: 1.当本地存储关闭后,云端存储打开,因为upload方式,所以并不会传图 2.当sto_img 为false情况, 本地不保存图片, 只能设置为base64 """ cam_info = camctl.get_one(device_id) if not camctl.if_upload_img(cam_info): return data = { "name": save_name, "device_id": device_id, "create_time": timestamp, "size": img_size, # "path": img_path.split("local/")[1], } if cam_info.upload and cam_info.upload.get("img_type", "") == "local": if not if_sto_db: with open(img_path, "rb") as f: data["img_str"] = str(base64.b64encode(f.read()), encoding="utf-8") else: data["path"] = img_path.split("w2s/")[1] else: logging.info("upload type: %s", cam_info.upload.get("img_type", "")) with open(img_path, "rb") as f: data["img_str"] = str(base64.b64encode(f.read()), encoding="utf-8") camctl.update_last_upload(device_id) self.publish(Cloud.topic_pub_img, data)
def recognize(path, device_id, function_list, model_list): cam = camctl.get_one(device_id) if SYS_CONF["device"] == "TD201": raw_results = get_td201_ai() else: try: results = _request_cluster(path, model_list) raw_results = [] for part, result in results.items(): for item in result: raw_results.append(item) except Exception as err: logging.exception(err) raise RuntimeError("invalid AI response: {}".format(err)) parse_list = [] for func in function_list: parse_list.append(FUNC_PARSE_MAP[func]) warning_parser = parctl.Warning_Parser(parse_list) parse_results = warning_parser(raw_results, cam) if parse_results: export_info = SYS_CONF["exporter"] if export_info.get("enable", False): expctl.export(parse_results, path, cam) url = path.split("w2s/")[1] for k, v in parse_results.items(): altctl.create(cam=cam, func_name=k, result_info=v, image_path=url) return parse_results
def __run(self): try: cam = camctl.get_one(self.cam_uuid) if clkctl.check_period_filter(cam.detection_cycle.get('detection_period'), cam.detection_cycle.get('detection_time')): if_sto_img = camctl.if_sto_img(cam) saved_path, if_sto_db = bktctl.save(cam.frame(), self.cam_uuid, if_sto_img) function_list = rcgctl.period_function_filter(cam) model_list = rcgctl.ai_pointer_filter(function_list) logging.info(model_list) if len(model_list): logging.info("task(%s@%s): start ai recognize, function is : %s, model is : %s", self.name, self.cam_uuid, str(function_list), str(model_list)) rcgctl.recognize(saved_path, self.cam_uuid, function_list, model_list) logging.info("task(%s@%s): succ and next in: %s", self.name, self.cam_uuid, cam.interval) else: logging.info("task(%s@%s): not in ai recognize cycle", self.name, self.cam_uuid) if not if_sto_db: bktctl.delete(saved_path) if cam.interval != self.success_interval: self.success_interval = cam.interval self.schedule.clear() self.schedule.every(self.success_interval).seconds.do(self.run_threaded, self.__run) except Exception as err: logging.error("task(%s) failed", self.name) logging.exception(err) logging.info("task(%s@%s): fail and next in: %s", self.name, self.cam_uuid, self.fail_interval) self.success_interval = self.fail_interval self.schedule.clear() self.schedule.every(self.fail_interval).seconds.do(self.run_threaded, self.__run)
def on_stream(self, data): """ 摄像头推流 """ logging.info("open streaming: {}".format(data)) msg_id = data["msg_id"] device_id = data["device_id"] stream = "" desc = "success" try: cam = camctl.get_one(device_id) cam.open_stream() stream = cam.preview_stream() except Exception as err: logging.exception("failed to open streaming on {} {}".format( device_id, err)) desc = str(err) resp_data = { "msg_id": msg_id, "stream": stream, # url "desc": desc, } self.publish(Cloud.topic_pub_stream, resp_data)
def on_cam_back(self, data): """ 摄像头录像回放 """ logging.info("open back streaming: {}".format(data)) msg_id = data["msg_id"] device_id = data["device_id"] start = int(data["start"] / 1000) end = int(data["end"] / 1000) starttime = time.strftime("%Y%m%dt%H%M%Sz", time.localtime(start)) endtime = time.strftime("%Y%m%dt%H%M%Sz", time.localtime(end)) stream = "" desc = "success" try: cam = camctl.get_one(device_id) cam.open_back_stream(starttime, endtime) stream = cam.preview_stream(back=True) except Exception as err: logging.exception("failed to start back on {} {}".format( device_id, err)) desc = str(err) resp_data = { "msg_id": msg_id, "stream": stream, # url "desc": desc, } self.publish(Cloud.topic_pub_cam_back, resp_data)
def remove_subtask(self, uuid): cam = camctl.get_one(uuid) try: if uuid in self.cap_th: self.cap_th[uuid].stop() del self.cap_th[uuid] except Exception as err: logging.exception(err) logging.info("subtask(%s): failed to stop", cam.name)
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 do_put(self, data): """ overwrite all function settings of a specific camera """ device_id = data.get("device_id") new_setting = data.get("function") try: if not isinstance(new_setting, dict): raise RuntimeError("invalid parameters") camctl.update(device_id, {"function": new_setting}) 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 do_post(self, data): """ income alert """ device_id = camctl._gen_id("10.48.48.10") rcg_result = data.get("result") rcg_images = data.get("images") try: cam = camctl.get_one(device_id) saved_path, _ = bktctl.save(rcg_images, cam.uuid) function_list = rcgctl.period_function_filter(cam) model_list = rcgctl.ai_pointer_filter(function_list) # rcgctl.recognize(saved_path, device_id, function_list, model_list, overwrite=rcg_result) except Exception as err: logging.exception(err) return self.failed(500, "{}".format(err)) return self.success(cam.function)
def on_stream_close(self, data): """ 摄像头关闭推流 """ logging.info("close streaming: {}".format(data)) device_id = data.get("device_id") try: cam = camctl.get_one(device_id) cam.close_stream() except Exception as err: logging.exception(err) logging.error("failed to stop streaming on {}".format(device_id)) return logging.info("stop streaming on {} success".format(device_id))
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 report_cam_setting(self, cam_uuid, msg_id=None): """ 普通摄像头设置变更 msg_id:如果收到的变更中包含msgId,传递;边侧自己修改则不需要传递 """ cam_info = camctl.get_one(cam_uuid) data = { "interval": cam_info.interval, # 采集间隔,5秒 "detection_cycle": cam_info.detection_cycle, # 采集时段设置 "history": cam_info.history, # 历史图片存储设置 "alert": cam_info.alert, # 告警图片存储设置 "upload": cam_info.upload, "cam_uuid": cam_uuid, # 摄像头编号,修改该摄像头设置 "time": clkctl._unix13ts(), # 时间戳 } if msg_id: data["msg_id"] = msg_id self.publish(Cloud.topic_pub_cam_setting, data)
def report_function_cam(self, device_ids, msg_id=None): """ 边侧更新某摄像头告警设置 msg_id:如果收到的变更中包含msgId,传递;边侧自己修改则不需要传递 """ if isinstance(device_ids, str): device_ids = [device_ids] data = { "cams": [{ "functions": camctl.get_one(device_id).function, "device_id": device_id } for device_id in device_ids], "time": clkctl._unix13ts() } if msg_id: data["msg_id"] = msg_id self.publish(Cloud.topic_pub_function_cam, data)
def on_function_cam(self, data): """ 全量更新摄像头的告警设置 """ logging.info("function cam setting: {}".format(data)) msg_id = data["msg_id"] function = data["function"] device_ids = data["device_ids"] for device_id in device_ids: cam_function = camctl.get_one(device_id).function for func_name in cam_function: if func_name in function: cam_function[func_name] = function[func_name] logging.info("change cam {} function: {}".format( device_id, cam_function)) camctl.update(device_id, {"function": cam_function}) self.report_function_cam(device_ids, msg_id)
def do_get(self, data): """ list function setting of a specific camera or all cameras """ device_id = data.get("device_id") try: cameras = [] if device_id is None: cameras = camctl.get_all({})[0] else: cameras = [camctl.get_one(device_id)] data = [{ "device_id": c.uuid, "function": c.function, "frame": os.path.join("/media/{}/image".format(c.uuid), bktctl.latest_images(c.uuid, 1)[0]['name']) } for c in cameras] except Exception as err: logging.exception(err) return self.failed(500, "{}".format(err)) return self.success(data)
def __init__(self, uuid): super().__init__("capcam") self.cam_uuid = uuid self.success_interval = camctl.get_one(self.cam_uuid).interval self.schedule = Scheduler()
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)