async def generate_call_all_data(self): try: if not self.term_item_list: logger.info('device[%s] prepare term_item_list..', self.device_id) cursor = None all_keys = set() while cursor != 0: res = self.redis.scan(cursor or b'0', match='HS:MAPPING:IEC104:{}:*'.format(self.device_id)) cursor, keys = res all_keys.update(keys) self.term_item_list = [self.redis.hgetall(key) for key in all_keys] logger.info('device[%s] len(term_item_list) = %s', self.device_id, len(self.term_item_list)) for term_item_dict in self.term_item_list: typ = int(term_item_dict['code_type']) if typ > TYP.M_EP_TD_1.value: typ = TYP.M_ME_TC_1.value address = int(term_item_dict['protocol_code']) up_limit = term_item_dict.get('up_limit') down_limit = term_item_dict.get('down_limit') value = None if up_limit: value = random.randint(str_to_number(down_limit), str_to_number(up_limit)) frame = iec_104.init_frame(self.ssn, self.rsn, TYP(typ), Cause.introgen) frame.ASDU.StartAddress = address frame.ASDU.data[0].address = address frame.ASDU.data[0].value = value or random.randint(100, 200) if hasattr(frame.ASDU.data[0], 'cp56time2a'): frame.ASDU.data[0].cp56time2a = datetime.datetime.now() if hasattr(frame.ASDU.data[0], 'cp24time2a'): frame.ASDU.data[0].cp24time2a = datetime.datetime.now() await self.send_frame(frame) except Exception as e: logger.error("device[%s] generate_call_all_data failed: %s", self.device_id, repr(e), exc_info=True)
async def generate_call_all_data(self): try: if not self.term_item_list: logger.info("device[%s] prepare term_item_list..", self.device_id) cursor = None all_keys = set() while cursor != 0: res = self.redis.scan(cursor or b"0", match="HS:MAPPING:IEC104:{}:*".format(self.device_id)) cursor, keys = res all_keys.update(keys) self.term_item_list = [self.redis.hgetall(key) for key in all_keys] logger.info("device[%s] len(term_item_list) = %s", self.device_id, len(self.term_item_list)) for term_item_dict in self.term_item_list: typ = int(term_item_dict["code_type"]) if typ > TYP.M_EP_TD_1.value: typ = TYP.M_ME_TC_1.value address = int(term_item_dict["protocol_code"]) up_limit = term_item_dict.get("up_limit") down_limit = term_item_dict.get("down_limit") value = None if up_limit: value = random.randint(str_to_number(down_limit), str_to_number(up_limit)) frame = iec_104.init_frame(self.ssn, self.rsn, TYP(typ), Cause.introgen) frame.ASDU.StartAddress = address frame.ASDU.data[0].address = address frame.ASDU.data[0].value = value or random.randint(100, 200) if hasattr(frame.ASDU.data[0], "cp56time2a"): frame.ASDU.data[0].cp56time2a = datetime.datetime.now() if hasattr(frame.ASDU.data[0], "cp24time2a"): frame.ASDU.data[0].cp24time2a = datetime.datetime.now() await self.send_frame(frame) except Exception as e: logger.error("device[%s] generate_call_all_data failed: %s", self.device_id, repr(e), exc_info=True)
async def handle_i(self, frame): try: self.start_timer(IECParam.T2) logger.debug("device[%s] got I_Frame-->TYP,Cause=%s,sq_count=%s", self.device_id, (frame.ASDU.TYP.name, frame.ASDU.Cause.name), frame.ASDU.sq_count) # 控制方向的过程信息 if TYP.C_SC_NA_1 <= frame.ASDU.TYP <= TYP.C_SE_TC_1 or TYP.C_CS_NA_1 == frame.ASDU.TYP: send_data = frame send_data.ASDU.Cause = Cause.actcon await self.send_frame(send_data) # 总召唤命令 elif frame.ASDU.TYP == TYP.C_IC_NA_1: send_data = frame send_data.ASDU.Cause = Cause.actcon await self.send_frame(send_data) logger.debug('device[%s] send task data begin, ssn=%s', self.device_id, self.ssn) await self.generate_call_all_data() send_data.ASDU.Cause = Cause.actterm await self.send_frame(send_data) # 电能脉冲召唤命令 elif frame.ASDU.TYP == TYP.C_CI_NA_1: send_data = frame send_data.ASDU.Cause = Cause.actcon await self.send_frame(send_data) self.generate_call_power_data() send_data.ASDU.Cause = Cause.actterm await self.send_frame(send_data) logger.debug('device[%s] send task data end, ssn=%s', self.device_id, self.ssn) # 读命令 elif frame.ASDU.TYP == TYP.C_RD_NA_1: if frame.ASDU.Cause == Cause.req: term_item_dict = self.redis.hgetall('HS:MAPPING:IEC104:{}:{}'.format( self.device_id, frame.ASDU.data[0].address)) value = None last_time = self.redis.lindex('LST:DATA_TIME:{}:{}:{}'.format( self.device_id, term_item_dict['term_id'], term_item_dict['item_id']), -1) if last_time: value = self.redis.hget('HS:DATA:{}:{}:{}'.format( self.device_id, term_item_dict['term_id'], term_item_dict['item_id']), last_time) logger.debug('term_item_dict=%s', term_item_dict) typ = TYP(int(term_item_dict['code_type'])) address = int(term_item_dict['protocol_code']) send_frame = iec_104.init_frame(self.ssn, self.rsn, typ, Cause.req) send_frame.ASDU.data[0].value = str_to_number(value) or random.uniform(100, 200) send_frame.ASDU.data[0].address = address logger.debug('C_RD_NA_1, send_frame=%s', send_frame) await self.send_frame(send_frame) # 完成尚未实现的I帧 else: logger.error("device[%s] unknown I_frame: %s", self.device_id, frame) if self.w == IECParam.W: logger.debug("self.w,Param_S=%s, send S_frame", (self.w, IECParam.W.value)) await self.send_frame(iec_104.init_frame("S", self.rsn)) except Exception as e: logger.error("device[%s] handle_i failed: %s", self.device_id, repr(e), exc_info=True)
def test_str_to_number(self): self.assertEqual(str(1.1), str(str_to_number('1.1'))) self.assertEqual(str(1), str(str_to_number('1'))) self.assertEqual(str(1), str(str_to_number(1)))
async def handle_i(self, frame): try: self.start_timer(IECParam.T2) logger.debug( "device[%s] got I_Frame-->TYP,Cause=%s,sq_count=%s", self.device_id, (frame.ASDU.TYP.name, frame.ASDU.Cause.name), frame.ASDU.sq_count, ) # 控制方向的过程信息 if TYP.C_SC_NA_1 <= frame.ASDU.TYP <= TYP.C_SE_TC_1 or TYP.C_CS_NA_1 == frame.ASDU.TYP: send_data = frame send_data.ASDU.Cause = Cause.actcon await self.send_frame(send_data) # 总召唤命令 elif frame.ASDU.TYP == TYP.C_IC_NA_1: send_data = frame send_data.ASDU.Cause = Cause.actcon await self.send_frame(send_data) logger.debug("device[%s] send task data begin, ssn=%s", self.device_id, self.ssn) await self.generate_call_all_data() send_data.ASDU.Cause = Cause.actterm await self.send_frame(send_data) # 电能脉冲召唤命令 elif frame.ASDU.TYP == TYP.C_CI_NA_1: send_data = frame send_data.ASDU.Cause = Cause.actcon await self.send_frame(send_data) self.generate_call_power_data() send_data.ASDU.Cause = Cause.actterm await self.send_frame(send_data) logger.debug("device[%s] send task data end, ssn=%s", self.device_id, self.ssn) # 读命令 elif frame.ASDU.TYP == TYP.C_RD_NA_1: if frame.ASDU.Cause == Cause.act: term_item_dict = self.redis.hgetall( "HS:MAPPING:IEC104:{}:{}".format(self.device_id, frame.ASDU.data[0].address) ) value = None last_time = self.redis.lindex( "LST:DATA_TIME:{}:{}:{}".format( self.device_id, term_item_dict["term_id"], term_item_dict["item_id"] ), -1, ) if last_time: value = self.redis.hget( "HS:DATA:{}:{}:{}".format( self.device_id, term_item_dict["term_id"], term_item_dict["item_id"] ), last_time, ) logger.debug("term_item_dict=%s", term_item_dict) typ = TYP(int(term_item_dict["code_type"])) address = int(term_item_dict["protocol_code"]) send_frame = iec_104.init_frame(self.ssn, self.rsn, typ, Cause.req) send_frame.ASDU.data[0].value = str_to_number(value) or random.uniform(100, 200) send_frame.ASDU.data[0].address = address logger.debug("C_RD_NA_1, send_frame=%s", send_frame) await self.send_frame(send_frame) # 完成尚未实现的I帧 else: logger.error("device[%s] unknown I_frame: %s", self.device_id, frame) if self.w == IECParam.W: logger.debug("self.w,Param_S=%s, send S_frame", (self.w, IECParam.W.value)) await self.send_frame(iec_104.init_frame("S", self.rsn)) except Exception as e: logger.error("device[%s] handle_i failed: %s", self.device_id, repr(e), exc_info=True)