def disable_rule(cls, uuids) -> int: try: if not uuids: msg = MyLog.color_red("uuids is empty") MyLog.logger.error(msg) return g_retValue.qjBoxOpcodeInputParamErr.value for uuid in uuids: if not SqliteInterface.rule_exist(uuid): msg = MyLog.color_red("rule(%s) has not exist" % (uuid)) MyLog.logger.error(msg) return g_retValue.qjBoxOpcodeInputParamErr.value # 数据库删除规则 SqliteInterface.set_rule_disable(uuids) # 从正在运行的队列中删除 remove_running_rule_endtime(uuids) DevCommandQueueMng.clear_command_by_rule_uuid(uuids) DevCommandQueueMng.all_dev_exe() # 规则决策 RuleMng.start_new_rule_decision_timer(0) return g_retValue.qjBoxOpcodeSucess.value except Exception as e: msg = MyLog.color_red('disable_rule has except: ' + str(e)) MyLog.logger.error(msg) return g_retValue.qjBoxOpcodeExcept.value
def delete_rule_by_uuid(cls, uuids) -> int: try: # 数据库删除规则 SqliteInterface.delete_rule(uuids) # 删除规则脚本 for uuid in uuids: js_path = RULE_JS_SCRIPT_FOLDER + "/" + uuid + '.js' py_path = RULE_PY_SCRIPT_FOLDER + "/" + uuid + '.py' pyc_path = RULE_PY_SCRIPT_FOLDER + "/" + uuid + '.pyc' if os.path.exists(js_path): os.remove(js_path) if os.path.exists(py_path): os.remove(py_path) if os.path.exists(pyc_path): os.remove(pyc_path) # 从正在运行的队列中删除 remove_running_rule_endtime(uuids) DevCommandQueueMng.clear_command_by_rule_uuid(uuids) DevCommandQueueMng.all_dev_exe() # 规则决策 return g_retValue.qjBoxOpcodeSucess.value except Exception as e: msg = MyLog.color_red('delete_rule_by_uuid has except: ' + str(e)) MyLog.logger.error(msg) return g_retValue.qjBoxOpcodeExcept.value
def manual_control(cls, services) -> int: try: keys = {'priority', 'script'} for service_dict in services: if not cls.__check_keys_exists(service_dict, keys): # 返回参数错误 msg = MyLog.color_red('必要参数不存在') MyLog.logger.error(msg) return g_retValue.qjBoxOpcodeInputParamErr.value if type(service_dict['script'] ) != str or service_dict['script'] == '': msg = MyLog.color_red('script param is invalid') MyLog.logger.error(msg) return g_retValue.qjBoxOpcodeInputParamErr.value if type(service_dict['priority']) != int or service_dict[ 'priority'] < 1 or service_dict['priority'] > 99: msg = MyLog.color_red('priority param is invalid') MyLog.logger.error(msg) return g_retValue.qjBoxOpcodeInputParamErr.value for service_dict in services: current_ts = time.time() py_file_name = '%d' % (current_ts * 1000000) py_path = "/tmp/" + py_file_name + '.py' pyc_path = "/tmp/" + py_file_name + '.pyc' conver_to_py(service_dict['script'], py_path) # 执行脚本 file = importlib.import_module(py_file_name) importlib.reload(file) # dev_command_list = [{'product_id': '', 'dev_id': "", "command_list":[{'service':'', 'param':'', "time":10}]}] dev_command_list, event_list, attr_list = file.script_fun() if dev_command_list: current_ts = time.time() for dev_command in dev_command_list: command_info_list = [] for command in dev_command['command_list']: command_info = CommandInfo( 'manual', command['service'], command['param'], current_ts, current_ts + command['time'], service_dict['priority'], 'manual') command_info_list.append(command_info) if command_info_list: DevCommandQueueMng.add_manual_command( dev_command['product_id'], dev_command['dev_id'], command_info_list) if os.path.exists(py_path): os.remove(py_path) if os.path.exists(pyc_path): os.remove(pyc_path) return g_retValue.qjBoxOpcodeSucess.value except Exception as e: msg = MyLog.color_red('manual_control in rule_mng has except: ' + str(e)) MyLog.logger.error(msg) return g_retValue.qjBoxOpcodeExcept.value
def clear_all_rule(cls) -> int: try: # 数据库清空规则 SqliteInterface.clear_all_rule() # 清空规则脚本 js_path = RULE_JS_SCRIPT_FOLDER py_path = RULE_PY_SCRIPT_FOLDER if os.path.isdir(js_path): shutil.rmtree(js_path) if os.path.isdir(py_path): shutil.rmtree(py_path) DevCommandQueueMng.clear_all_command() return g_retValue.qjBoxOpcodeSucess.value except Exception as e: msg = MyLog.color_red('clear_all_rule has except: ' + str(e)) MyLog.logger.error(msg) return g_retValue.qjBoxOpcodeExcept.value
def running_rule_endtime_handle(): MyLog.logger.info("运行中的规则结束处理") current_ts = time.time() smallest_ts = 0 uuid_list = [] to_del_rule = [] g_lk.acquire() for rule in g_running_rule_endtime_list: MyLog.logger.info(f'rule:{rule}') if rule['end_ts'] < current_ts: MyLog.logger.info("规则(%s)结束" % (rule['uuid'])) # g_running_rule_endtime_list.remove(rule) # 遍历列表过程中改变列表size!!! to_del_rule.append(rule) uuid_list.append(rule['uuid']) # 上报规则结束事件 EventReport.report_rule_end_event(rule['uuid']) else: if smallest_ts == 0: smallest_ts = rule['end_ts'] elif rule['end_ts'] < smallest_ts: smallest_ts = rule['end_ts'] # to fix the bug referred above for del_rule in to_del_rule: g_running_rule_endtime_list.remove(del_rule) g_lk.release() if uuid_list: # 删除结束规则的指令 DevCommandQueueMng.clear_command_by_rule_uuid(uuid_list) # 所有设备队列重新执行指令决策 DevCommandQueueMng.all_dev_exe() global g_running_rule_endtime_handle_timer if g_running_rule_endtime_handle_timer: g_running_rule_endtime_handle_timer.cancel() ts = smallest_ts - current_ts if ts > 0: g_running_rule_endtime_handle_timer = Timer( ts, running_rule_endtime_handle) g_running_rule_endtime_handle_timer.start()
def stop_linkage_rule_running(cls, uuids) -> int: try: for uuid in uuids: rule_type = SqliteInterface.get_type_by_uuid(uuid) if not rule_type or rule_type != 'linkage': msg = MyLog.color_red( "stop_linkage_rule_running the type of input uuid is invalid" ) MyLog.logger.error(msg) return g_retValue.qjBoxOpcodeInputParamErr.value DevCommandQueueMng.clear_command_by_rule_uuid(uuids) remove_running_rule_endtime(uuids) DevCommandQueueMng.all_dev_exe() return g_retValue.qjBoxOpcodeSucess.value except Exception as e: msg = MyLog.color_red('stop_linkage_rule_running has except: ' + str(e)) MyLog.logger.error(msg) return g_retValue.qjBoxOpcodeExcept.value
def stop_manual_control(cls, services) -> int: try: keys = {'productId', 'devId', 'service'} for service_dict in services: if not cls.__check_keys_exists(service_dict, keys): # 字段不存在 msg = MyLog.color_red('必要参数不存在') MyLog.logger.error(msg) return g_retValue.qjBoxOpcodeInputParamErr.value pid = service_dict['productId'] did = service_dict['devId'] srv = service_dict['service'] if type(pid) != str or type(did) != str or type(srv) != str: # 数据类型错误 msg = MyLog.color_red('参数数据类型错误') MyLog.logger.error(msg) return g_retValue.qjBoxOpcodeInputParamErr.value if pid == "" or did == "" or srv == "": # 数据值为空 msg = MyLog.color_red('参数字符串数据为空字符串') MyLog.logger.error(msg) return g_retValue.qjBoxOpcodeInputParamErr.value dev_id_list = [] for service_dict in services: DevCommandQueueMng.clear_manual_command( service_dict['productId'], service_dict['devId'], service_dict['service']) dev_id_list.append(service_dict['devId']) DevCommandQueueMng.dev_list_exe(dev_id_list) return g_retValue.qjBoxOpcodeSucess.value except Exception as e: msg = MyLog.color_red( 'stop_manual_control in rule_mng has except: ' + str(e)) MyLog.logger.error(msg) return g_retValue.qjBoxOpcodeExcept.value
def update_rule(cls, rules) -> int: try: uuid_list = [] for rule_dict in rules: ret = cls.__check_rule_param(rule_dict) if ret != g_retValue.qjBoxOpcodeSucess.value: msg = MyLog.color_red('check_rule_param failed') MyLog.logger.error(msg) return ret uuid_list.append(rule_dict['uuid']) # 数据库删除规则 SqliteInterface.delete_rule(uuid_list) # 删除规则脚本 for uuid in uuid_list: js_path = RULE_JS_SCRIPT_FOLDER + "/" + uuid + '.js' py_path = RULE_PY_SCRIPT_FOLDER + "/" + uuid + '.py' pyc_path = RULE_PY_SCRIPT_FOLDER + "/" + uuid + '.pyc' if os.path.exists(js_path): os.remove(js_path) if os.path.exists(py_path): os.remove(py_path) if os.path.exists(pyc_path): os.remove(pyc_path) # 从正在运行的队列中删除 remove_running_rule_endtime(uuid_list) # 删除指令队列中的相关指令 DevCommandQueueMng.clear_command_by_rule_uuid(uuid_list) DevCommandQueueMng.all_dev_exe() # 重新添加规则 ret = RuleMng.add_rule(rules) return ret except Exception as e: msg = MyLog.color_red('update_rule has except: ' + str(e)) MyLog.logger.error(msg) return g_retValue.qjBoxOpcodeExcept.value
def outside_linkage(cls, services) -> int: try: keys = {'uuid', 'priority', 'script'} for service_dict in services: if not cls.__check_keys_exists(service_dict, keys): # 返回参数错误 msg = MyLog.color_red('必要参数不存在') MyLog.logger.error(msg) return g_retValue.qjBoxOpcodeInputParamErr.value if type(service_dict['uuid'] ) != str or service_dict['uuid'] == '': msg = MyLog.color_red('uuid param is invalid') MyLog.logger.error(msg) return g_retValue.qjBoxOpcodeInputParamErr.value if type(service_dict['script'] ) != str or service_dict['script'] == '': msg = MyLog.color_red('script param is invalid') MyLog.logger.error(msg) return g_retValue.qjBoxOpcodeInputParamErr.value if type(service_dict['priority']) != int or service_dict[ 'priority'] < 1 or service_dict['priority'] > 99: msg = MyLog.color_red('priority param is invalid') MyLog.logger.error(msg) return g_retValue.qjBoxOpcodeInputParamErr.value for service_dict in services: uuid = service_dict['uuid'] py_path = "/tmp/" + uuid + '.py' pyc_path = "/tmp/" + uuid + '.pyc' conver_to_py(service_dict['script'], py_path) if not os.path.exists(py_path): msg = MyLog.color_red( "outside_linkage: py(%s) is not exist" % (py_path)) MyLog.logger.error(msg) continue # 执行脚本 file = importlib.import_module(uuid) importlib.reload(file) # dev_command_list = [{'product_id': '', 'dev_id': "", "command_list":[{'service':'', 'param':'', 'time':10 }]}] dev_command_list, event_list, attr_list = file.script_fun() MyLog.logger.debug('dev_command_list size: %d' % (len(dev_command_list))) if dev_command_list or event_list: current_ts = time.time() # 上报规则开始执行 EventReport.report_rule_start_event(uuid) continue_time = 1 for dev_command in dev_command_list: command_info_list = [] for command in dev_command['command_list']: if continue_time < command['time']: continue_time = command['time'] command_info = CommandInfo( uuid, command['service'], command['param'], current_ts, current_ts + command['time'], service_dict['priority'], 'linkage') MyLog.logger.debug("append command priority = %d" % (service_dict['priority'])) command_info_list.append(command_info) if command_info_list: MyLog.logger.debug('#add_linkage_command') DevCommandQueueMng.add_linkage_command( dev_command['product_id'], dev_command['dev_id'], command_info_list) end_ts = current_ts + continue_time uuid_endtime_list = [{'uuid': uuid, 'end_ts': end_ts}] add_running_rule_endtime(uuid_endtime_list) for custom_event in event_list: EventReport.report_linkage_custom_event( custom_event['event_id'], custom_event['src_dev_list']) if os.path.exists(py_path): os.remove(py_path) if os.path.exists(pyc_path): os.remove(pyc_path) return g_retValue.qjBoxOpcodeSucess.value except Exception as e: msg = MyLog.color_red('outside_linkage in rule_mng has except: ' + str(e)) MyLog.logger.error(msg) return g_retValue.qjBoxOpcodeExcept.value
def run_linkage_rule_by_devid(cls, dev_id, attrs) -> None: try: MyLog.logger.info( f'##########run_linkage_rule_by_devid({dev_id} attrs: {attrs})############' ) uuid_list = SqliteInterface.get_current_linkage_rule_by_src_devid( dev_id) msg = f"get_current_linkage_rule_by_src_devid({dev_id}, sizeof uuid_list = {len(uuid_list)})" MyLog.logger.debug(msg) for uuid in uuid_list: py_path = RULE_PY_SCRIPT_FOLDER + "/" + uuid + '.py' if not os.path.exists(py_path): msg = MyLog.color_red( "run_linkage_rule_by_devid: py(%s) is not exist" % (py_path)) MyLog.logger.error(msg) continue # 执行脚本 py_import_path = RULE_PY_MODEL_PATH + uuid MyLog.logger.debug('py_import_path: ' + py_import_path) file = importlib.import_module(py_import_path) importlib.reload(file) MyLog.logger.debug('run script fun') # dev_command_list = [{'product_id': '', 'dev_id': "", "command_list":[{'service':'', 'param':'', 'time':10 }]}] dev_command_list, event_list, attr_list = file.script_fun() msg = f'dev_command_list size: {len(dev_command_list)}, event_list size: {len(event_list)}' MyLog.logger.debug(msg) # 如果相同的联动策略已经在运行中了,那么这个策略的所有服务都被忽略 if find_running_rule_by_uuid(uuid): for dev_commands_dict in dev_command_list: __, dev_id, service_list = dev_commands_dict.values() for command_dict in service_list: MyLog.logger.debug( f'dev_id:{dev_id},cmd:{command_dict["service"]},uuid:{uuid}' ) EventReport.report_rule_command_ignore_event( dev_id, command_dict['service'], uuid, uuid) continue if attrs: allow_exe = RuleMng.attrs_has_one_in_changed( dev_id, attr_list, attrs) else: allow_exe = True MyLog.logger.debug(f'allow exe: {allow_exe}') if allow_exe and (dev_command_list or event_list): priority = SqliteInterface.get_priority_by_uuid(uuid) if priority < 0: continue current_ts = time.time() # 上报规则开始执行 EventReport.report_rule_start_event(uuid) continue_time = 1 for dev_command in dev_command_list: command_info_list = [] for command in dev_command['command_list']: if continue_time < command['time']: continue_time = command['time'] command_info = CommandInfo( uuid, command['service'], command['param'], current_ts, current_ts + command['time'], priority, 'linkage') command_info_list.append(command_info) if command_info_list: DevCommandQueueMng.add_linkage_command( dev_command['product_id'], dev_command['dev_id'], command_info_list) end_ts = current_ts + continue_time uuid_endtime_list = [{'uuid': uuid, 'end_ts': end_ts}] add_running_rule_endtime(uuid_endtime_list) for custom_event in event_list: EventReport.report_linkage_custom_event( custom_event['event_id'], custom_event['src_dev_list']) MyLog.logger.info( f'##########run_linkage_rule_by_devid finished({dev_id} attrs: {attrs})############' ) except Exception as e: msg = MyLog.color_red('run_linkage_rule_by_devid has except: ' + str(e)) MyLog.logger.error(msg)
def timer_rule_decision(cls) -> None: try: MyLog.logger.info('进行定时规则决策') # 计算出下一次最近的执行时间戳,启动定时器 next_decision_time = cls.get_closest_timestamp() if next_decision_time > 0.0: RuleMng.start_new_rule_decision_timer(next_decision_time) # 获取符合要求的uuid列表 uuid_list = SqliteInterface.get_current_timer_rule() # 执行规则,将规则指令下发给指令管理器 MyLog.logger.info('uuid_list size: ' + str(len(uuid_list))) dev_id_list = [] rule_endtime_list = [] for uuid in uuid_list: MyLog.logger.info('===开始执行规则(%s)===' % (uuid)) priority = SqliteInterface.get_priority_by_uuid(uuid) if priority < 0: continue py_model = RULE_PY_MODEL_PATH + uuid # 如果已经添加到了g_running_rule_endtime_list里,说明这个定时策略早就开始执行了 if not find_running_rule_by_uuid(uuid): EventReport.report_rule_start_event(uuid) # 记录规则结束时间戳到全局变量g_running_rule,等待结束上报结束事件 start_ts, end_ts = cls.get_rule_timestamp(uuid) MyLog.logger.info('规则(%s)结束时间戳:%d' % (uuid, end_ts)) if end_ts > 0: rule_endtime_list.append({ 'uuid': uuid, "end_ts": end_ts }) # 执行脚本 file = importlib.import_module(py_model) importlib.reload(file) # dev_command_list = [{'product_id': '', 'dev_id': "", "command_list":[{'service':'', 'param': , 'time': 10}]}] # event_list = event_list = [{"event_id":"", "src_dev_list":[{"productId":"p_id", "deviceId":"d_id"}]}] dev_command_list, event_list, attr_list = file.script_fun() ts = time.time() for dev_command in dev_command_list: command_info_list = [] for command in dev_command['command_list']: command_info = CommandInfo(uuid, command['service'], command['param'], ts, ts + command['time'], priority, 'timer') command_info_list.append(command_info) if command_info_list: # 如果已经添加到了g_running_rule_endtime_list里,说明联动事件已经添加到命令队列里了 if not find_running_rule_by_uuid(uuid): DevCommandQueueMng.add_timer_command( dev_command['product_id'], dev_command['dev_id'], command_info_list) # dev_id_list.append(dev_command['dev_id']) DevCommandQueueMng.dev_exe_by_command_list( dev_command['dev_id'], command_info_list) # 如果已经添加到了g_running_rule_endtime_list里,说明联动事件已经上报过了 if not find_running_rule_by_uuid(uuid): for custom_event in event_list: EventReport.report_linkage_custom_event( custom_event['event_id'], custom_event['src_dev_list']) MyLog.logger.info('===结束执行规则(%s)===' % (uuid)) add_running_rule_endtime(rule_endtime_list) except Exception as e: msg = MyLog.color_red("timer_rule_decision has except: " + str(e)) MyLog.logger.error(msg)