def analyze_DutyCycleAns(device, cmd_payload): assert len(cmd_payload) == 0, 'WRONG MAC CMD PAYLOAD OF DutyCycleAns' DevInfo(device.dev_eui).p_to_c('MaxDutyCycle') Logger.info(action=Action.mac_cmd_get, type=IDType.device, id=hexlify(device.dev_eui).decode(), msg='DutyCycleAns Success: %s' % cmd_payload)
def __show_msg(self, title, desc): Logger.info('待办事项【%s】提醒' % title, module='__show_msg') msg = tk.Tk() msg.title(title) msg.resizable(False, False) msg.iconbitmap(Constants.ICO_PATH) position_x = (self.SCREEN_WIDTH - Constants.MSG_BOX_WIDTH) / 2 position_y = (self.SCREEN_HEIGHT - Constants.MSG_BOX_HEIGHT) / 2 msg.geometry('%dx%d+%d+%d' % (Constants.MSG_BOX_WIDTH, Constants.MSG_BOX_HEIGHT, position_x, position_y)) msg.attributes('-topmost', 2) tk.Label(msg, text='您有如下待办事项需处理:', font=(Constants.FONT, Constants.FONT_SIZE_14, Constants.FONT_WEIGHT)).grid(row=0, column=0) tk.Label(msg, text=desc, fg=Constants.WHITE_COLOR, bg=Constants.SCHEDULER_COLOR, font=(Constants.FONT, Constants.FONT_SIZE_10)).grid(row=1, column=0, sticky=tk.NW, padx=30) msg.mainloop()
def __add_schedule(self): key = self.sch_date.strftime('%Y-%m-%d') s_title = self.s_title.get() s_desc = self.s_desc.get() hour = int(self.hour.get()) minute = int(self.minute.get()) if not all([s_title, s_desc]): messagebox.showerror('提示', '标题和描述不能为空!') return values = { 'title': s_title, 'describ': s_desc, 'hour': hour, 'minute': minute } self.sl.add_scheduler(key, values) self.__render_one_day_info(self.row, self.sch_date) # 如果添加的是今日的日程安排,并且提醒时间大于当前时间,则需将该日程添加到日程提醒中 if self.sch_date == self.today: tell_time = dt(self.today.year, self.today.month, self.today.day, hour, minute, 0) # 如果提醒时间在当前时间之后则添加到提醒任务中 if tell_time > dt.now(): self.bs.add_job(self.__show_msg, trigger=DateTrigger(run_date=tell_time), args=[s_title, s_desc]) # 关闭添加日程窗口 self.__close_add_schedule_window() Logger.info(self.bs.get_jobs(), module='__add_schedule')
def analyze_mac_cmd_ans(device, mac_cmd): """ :param mac_fhdr_fopts: bytes :return:dict """ while len(mac_cmd) != 0: cid = mac_cmd[0] try: if 128 <= cid <= 255: Logger.info(action=Action.mac_cmd_get, type=IDType.device, id=hexlify(device.dev_eui).decode(), msg='Proprietary MAC CMD:% cid' % cid) return cmd_payload_len = MACConst.mac_cmd_up_len[cid] cmd_payload = mac_cmd[1:cmd_payload_len + 1] mac_cmd = mac_cmd[cmd_payload_len + 1:] cid_switch(device, cid, cmd_payload) except KeyError as error: Logger.error(action=Action.mac_cmd_get, type=IDType.device, id=hexlify(device.dev_eui).decode(), msg='ERROR: %s' % error) return except AssertionError as error: Logger.error(action=Action.mac_cmd_get, type=IDType.device, id=hexlify(device.dev_eui).decode(), msg='ERROR: %s' % error) return
def __show_day_info_msg(self): try: Logger.info('每天上午10点定时提醒', module='__show_day_info_msg') msg = tk.Tk() msg.title(Constants.TITLE) msg.resizable(False, False) msg.iconbitmap(Constants.ICO_PATH) position_x = (self.SCREEN_WIDTH - Constants.DAY_INFO_MSG_WIDTH) / 2 position_y = (self.SCREEN_HEIGHT - Constants.DAY_INFO_MSG_HEIGHT) / 2 msg.geometry( '%dx%d%+d+%d' % (Constants.DAY_INFO_MSG_WIDTH, Constants.DAY_INFO_MSG_HEIGHT, position_x, position_y)) msg.attributes('-topmost', 2) info_frame = tk.Frame(msg) info_frame.grid(row=0, column=0, columnspan=7) self.__render_one_day_info(row=0, date=self.today, info_frame=info_frame) msg.mainloop() except Exception as e: Logger.info(e, module='__add_schedule')
def analyze_RXTimingSetupAns(device, cmd_payload): assert len(cmd_payload) == 0, 'WRONG MAC CMD PAYLOAD OF RXTimingSetupAns' Logger.info(action=Action.mac_cmd_get, type=IDType.device, id=hexlify(device.dev_eui).decode(), msg='RXTimingSetupAns Success: %s' % cmd_payload) DevInfo(device.dev_eui).p_to_c('RxDelay')
def get(dev_eui): """ :param dev_eui: bytes :return: """ Assertions.a_eui(dev_eui) info = db0.hgetall(ConstDB0.dev + hexlify(dev_eui).decode()) Logger.info(info) try: addr = info[b'addr'] app_eui = info[b'app_eui'] nwkskey = info[b'nwkskey'] appskey = info.get(b'appskey', b'') fcnt_up = int(info[b'fcnt_up']) fcnt_down = int(info[b'fcnt_down']) dev_class = ClassType(info[b'dev_class'].decode()) adr = bool(int(info[b'adr'])) check_fcnt = bool(int(info[b'check_fcnt'])) return Device(dev_eui=dev_eui, addr=addr, app_eui=app_eui, nwkskey=nwkskey, appskey=appskey, fcnt_up=fcnt_up, fcnt_down=fcnt_down, dev_class=dev_class, adr=adr, check_fcnt=check_fcnt) except Exception as error: Logger.error(action=Action.object, type=IDType.device, id=hexlify(dev_eui).decode(), msg='Get Device ERROR: %s' % error)
def publish(self): data = json.dumps(self.__obj_to_dict()) # db1.publish(Channel1.join_req_alarm, data) db0.publish(Channel1.join_accept_alarm + hexlify(self.app_eui).decode(), data) Logger.info(action=Action.otaa, msg='Publish Join Accept alram %s, %s' % ( Channel1.join_req_alarm, data))
def push_into_que(self): dev_eui = hexlify(self.device.dev_eui).decode() db0.set(ConstDB.mac_cmd + dev_eui + ':' + hexlify(self.cid).decode(), self.cid + self.generate_payload()) que_key = ConstDB.mac_cmd_que + dev_eui db0.lrem(que_key, count=0, value=self.cid) db0.rpush(que_key, self.cid) if self.device.dev_class == ClassType.c: db0.publish(Channel.que_down_alarm_c, self.device.dev_eui) Logger.info(action=Action.publish, resource=Resource.device, id=dev_eui, msg='add_mac_cmd que_down_alarm_c:' + self.device.dev_eui)
def analyze_DlChannelAns(device, cmd_payload): freq_ok = cmd_payload & 0b1 up_freq_exist = cmd_payload >> 1 if freq_ok and up_freq_exist: Logger.info(action=Action.mac_cmd_get, type=IDType.device, id=hexlify(device.dev_eui).decode(), msg='DlChannelAns: %s, freq_ok: %s, up_freq_exist: %s' % (cmd_payload, freq_ok, up_freq_exist))
def otaa(server): ps = db1.pubsub() ps.psubscribe(Channel1.join_accept_alarm + '*') while True: for item in ps.listen(): Logger.info(msg='PS Listen %s' % item, type=IDType.sub, action=Action.otaa) if item['type'] == 'pmessage': sender = OTAASender(item, server=server) sender.start()
def rx_1(server): ps = db0.pubsub() ps.subscribe(Channel0.rx1_alarm) while True: for item in ps.listen(): Logger.info(msg='PS Listen %s' % item, type=IDType.sub, action=Action.rx1) if item['type'] == 'message': t0 = time.time() sender = Sender(item['data'], server, 1, t0) sender.start()
def shift_to(dev_eui, datr, FREQ_PLAN): payload = LinkADRReqPayload( data_rate=datr, tx_power=FREQ_PLAN.TXPower.default.value, ch_mask=FREQ_PLAN.Channel.CH_MASK, ch_mask_cntl=FREQ_PLAN.Channel.CH_MASK_CNTL, nb_trans=FREQ_PLAN.Channel.NB_TRANS).return_data() mac_cmd_down = MACCmd(dev_eui) mac_cmd_down.push_into_que(CID.LinkADRReq, payload=payload) Logger.info(action=Action.adr, type=IDType.device, id=hexlify(dev_eui).decode(), msg="shift to %s" % datr)
def pop_restart(self): restart = db0.hget(ConstDB0.gateway + hexlify(self.mac_addr).decode(), 'restart') if restart == b'1': db0.hdel(ConstDB0.gateway + hexlify(self.mac_addr).decode(), 'restart') Logger.info(action=Action.object, type=IDType.gateway, id=hexlify(self.mac_addr).decode(), msg='Restart') return True else: return False
def class_c(server): ps = db0.pubsub() ps.subscribe(Channel0.que_down_alarm_c) while True: for item in ps.listen(): Logger.info(msg='PS Listen %s' % item, type=IDType.sub, action=Action.class_c) if item['type'] == 'message': dev_eui = unhexlify(item['data'].decode().split(':')[1]) # sender = ClassCSender(item['data'], server) sender = Sender(dev_eui, server, rx_window=2) sender.start()
def push(self, fport, payload, cipher=True, seqno=None, confirmed=False, rx_window=0): assert isinstance(payload, bytes) and len( payload) < MAX_FRMPAYLOAD_LENGTH, 'Payload over Max Length' assert isinstance(fport, int) and 0 < fport < 255, 'FPort Error' assert isinstance(cipher, bool), 'Cipher Type Error' assert rx_window == 0 or rx_window == 1 or rx_window == 2, 'RX WINDOW ERROR' if self.que_limit <= self.len(): raise QueOccupied('The queue of this Dev:%s is occupied' % hexlify(self.dev_eui).decode()) fport = pack('B', fport) if cipher is False: appskey = db0.hget(self.key, FieldDevice.appskey) if len(appskey) != 16: raise AppSKeyAbsence(self.key) cipher = 0 else: fcnt_down = int(db0.hget(self.key, FieldDevice.fcnt_down)) que_len = self.len() seqno_expect = fcnt_down + que_len + 1 if seqno != seqno_expect: raise SeqNoError(seqno, seqno_expect) cipher = 1 settings = (cipher << 7) + (rx_window << 5) + (confirmed.real << 4) settings = bytes([settings]) dev_class = ClassType( db0.hget(self.key, FieldDevice.dev_class).decode()) if dev_class == ClassType.c and rx_window == 1: db0.rpush(ConstDB.que_down + self.key + ':1', settings + fport + payload) else: db0.rpush(ConstDB.que_down + self.key, settings + fport + payload) if dev_class == ClassType.c and (rx_window == 2 or rx_window == 0): db0.publish(Channel.que_down_alarm_c, self.key) Logger.info(action=Action.publish, resource=Resource.device, id=self.dev_eui, msg='Publish ' + Channel.que_down_alarm_c + ' ' + self.key) elif dev_class == ClassType.b: db0.publish(Channel.que_down_alarm_b, self.key) Logger.info(action=Action.publish, resource=Resource.device, id=self.dev_eui, msg='Publish ' + Channel.que_down_alarm_b + ' ' + self.key)
def analyze_LinkCheckReq(device, cmd_payload): assert len(cmd_payload) == 0, 'WRONG MAC CMD PAYLOAD OF LinkCheckReq' Logger.info(action=Action.mac_cmd_get, type=IDType.device, id=hexlify(device.dev_eui).decode(), msg='LinkCheckReq: %s' % cmd_payload) cnt = db0.zcard(ConstDB0.dev_gateways + hexlify(device.dev_eui).decode()) #gen a ans down margin = b'\x00' GwCnt = bytes([cnt]) payload = LinkCheckAnsPayload(margin, GwCnt).return_data() mac_cmd = MACCmd(device.dev_eui) #push into que mac_cmd.push_into_que(CID.LinkCheckAns, payload)
def analyze_PingSlotInfoReq(device, cmd_payload): assert len(cmd_payload) == 1, "WRONG MAC CMD PAYLOAD OF PingSlotInfoReq" datr = cmd_payload[0] & 0b1111 periodicity = cmd_payload[0] >> 4 & 0b111 rfu = cmd_payload[0] >> 7 Logger.info(action=Action.mac_cmd_get, type=IDType.device, id=hexlify(device.dev_eui).decode(), msg='PingSlotInfoReq: %s, datr: %s, periodicity: %s' % (cmd_payload, datr, periodicity)) ClassBInfo(ConstDB0.dev + hexlify(device.dev_eui).decode(), datr, periodicity).set() #sent ans back ping_slot_info_ans = MACCmd(device.dev_eui) ping_slot_info_ans.push_into_que(cid=CID.PingSlotInfoAns)
def _run(self): result = write_join_accept_data(self.dev_eui, self.data) if not result: Logger.error(action=Action.otaa, msg='No packet, pull_info return!!!') return packet = result[0] pull_info = result[1] if pull_info.prot_ver == 2: resend = ReSender(pull_info, packet, self.server) resend.start() self.server.sendto(packet, pull_info.ip_addr) Logger.info(action=Action.otaa, type=IDType.ip_addr, id='%s:%d' % pull_info.ip_addr, msg='SENT JOIN ACCEPT %s' % packet)
def analyze_BeaconTimingReq(device, cmd_payload): assert len(cmd_payload) == 0, "WRONG MAC CMD PAYLOAD OF BeaconTimingReq" Logger.info(action=Action.mac_cmd_get, type=IDType.device, id=hexlify(device.dev_eui).decode(), msg='BeaconTimingReq: %s' % cmd_payload) ##action ---- get the next beacon timing and channel delay = BeaconTiming.cal_beacon_time_delay(device) channel = 0 ##gen payload mac_cmd_payload = BeaconTimingAns(delay, channel).return_data() beacon_timing_ans = MACCmd(device.dev_eui) beacon_timing_ans.push_into_que(CID.BeaconTimingAns, payload=mac_cmd_payload)
def __init__(self, request_msg, trans_params, gateway): """ :param request_msg:str :param trans_params:dict :param gateway_mac_addr: :return: """ Greenlet.__init__(self) app_eui = int.to_bytes(int.from_bytes(request_msg[1:9], byteorder='little'), byteorder='big', length=8) dev_eui = int.to_bytes(int.from_bytes(request_msg[9:17], byteorder='little'), byteorder='big', length=8) dev_nonce = int.to_bytes(int.from_bytes(request_msg[17:19], byteorder='little'), byteorder='big', length=2) mic = request_msg[19:23] hex_dev_eui = hexlify(dev_eui).decode() hex_app_eui = hexlify(app_eui).decode() Logger.info(action=Action.otaa, type=IDType.device, id=dev_eui, msg="JOIN REQ: APP:%s, dev_nonce:%s" % (hex_app_eui, dev_nonce)) real_app_eui = db0.hget(ConstDB0.dev + hex_dev_eui, 'app_eui') if real_app_eui is not None and real_app_eui != app_eui: raise Exception('Device %s belong to other app %s, not app %s' % (dev_eui, real_app_eui, app_eui)) else: app = Application.objects.get(app_eui) if app is None: raise KeyError('APP:%s does not exist' % hex_app_eui) elif gateway.public is not True and app.user_id != gateway.user_id: raise AccessDeny( hexlify(gateway.mac_addr).decode(), ConstDB0.app + hex_app_eui) self.app = app self.dev_eui = dev_eui self.request_msg = request_msg self.trans_params = trans_params self.gateway = gateway self.dev_nonce = dev_nonce self.mic = mic
def analyze_BeaconFreqAns(device, cmd_payload): assert len(cmd_payload) == 1, "WRONG MAC CMD PAYLOAD OF BeaconFreqAns" status = cmd_payload[0] freq_ack = status & 0b1 rfu = status >> 1 if freq_ack == 1: Logger.info(action=Action.mac_cmd_get, type=IDType.device, id=hexlify(device.dev_eui).decode(), msg='BeaconFreqAns: %s, freq_ack: %s' % (cmd_payload, freq_ack)) else: Logger.info(action=Action.mac_cmd_get, type=IDType.device, id=hexlify(device.dev_eui).decode(), msg='BeaconFreqAns: %s, freq_ack: %s' % (cmd_payload, freq_ack))
def analyze_PingSlotFreqAns(device, cmd_payload): assert len(cmd_payload) == 1, "WRONG MAC CMD PAYLOAD OF PingSlotFreqAns" status = cmd_payload[0] ch_ack = status & 0b1 dr_ack = status >> 1 & 0b1 rfu = status >> 2 if ch_ack & dr_ack == 1: Logger.info(action=Action.mac_cmd_get, type=IDType.device, id=hexlify(device.dev_eui).decode(), msg='PingSlotFreqAns Success: %s, ch_ack: %s, dr_ack: %s' % (cmd_payload, ch_ack, dr_ack)) else: Logger.error(action=Action.mac_cmd_get, type=IDType.device, id=hexlify(device.dev_eui).decode(), msg='PingSlotFreqAns Fqil: %s, ch_ack: %s, dr_ack: %s' % (cmd_payload, ch_ack, dr_ack))
def analyze_NewChannelAns(device, cmd_payload): assert len(cmd_payload) == 1, 'WRONG MAC CMD PAYLOAD OF NewChannelAns' # logger.info(ConstLog.mac_cmd+'analyze_NewChannelAns') status = cmd_payload[0] ch_ack = status & 0b1 dr_ack = status >> 1 & 0b1 rfu = status >> 2 if ch_ack & dr_ack == 1: Logger.info(action=Action.mac_cmd_get, type=IDType.device, id=hexlify(device.dev_eui).decode(), msg='DevStatusAns Success: %s, ch_ack: %d, dr_ack: %d' % (cmd_payload, ch_ack, dr_ack)) else: Logger.error(action=Action.mac_cmd_get, type=IDType.device, id=hexlify(device.dev_eui).decode(), msg='DevStatusAns Fail: %s, ch_ack: %d, dr_ack: %d' % (cmd_payload, ch_ack, dr_ack))
class AssertSetIF(object): def __init__(self, project): self.project = project self.failList = [] self.logger = Logger(self.project).get_logger() def assertIn(self, member, container, msg=''): try: if member in container: self.logger.info('测试通过: %s' % msg) else: raise AssertionError except Exception: expectedMsg = '预期结果: %s' % (member) failMsg = ('测试未通过: %s, %s' % (msg, expectedMsg)) self.logger.error(failMsg) self.failList.append(failMsg) def assertEqual(self, par1, par2, msg=''): try: if par1 == par2: self.logger.info('测试通过: %s' % msg) else: raise AssertionError except Exception: expectedMsg = '预期结果: %s' % (par1) failMsg = ('测试未通过: %s, %s' % (msg, expectedMsg)) self.logger.error(failMsg) self.failList.append(failMsg) def assertNotIn(self, member, container, msg=''): try: if member not in container: self.logger.info('测试通过: %s' % msg) else: raise AssertionError except Exception: expectedMsg = '预期结果: %s' % (member) failMsg = ('测试未通过: %s, %s' % (msg, expectedMsg)) self.logger.error(failMsg) self.failList.append(failMsg) def assertNotEqual(self, par1, par2, msg=''): try: if par1 != par2: self.logger.info('测试通过: %s' % msg) else: raise AssertionError except Exception: expectedMsg = '预期结果: %s' % (par1) failMsg = ('测试未通过: %s, %s' % (msg, expectedMsg)) self.logger.error(failMsg) self.failList.append(failMsg)
def __add_schedule_background_tasks(self): sch_date = self.today t_schedules = self.sl.get_today_schedulers( sch_date.strftime('%Y-%m-%d')) if t_schedules and len(t_schedules) > 0: for sch in t_schedules: tell_time = dt(self.today.year, self.today.month, self.today.day, int(sch.get('hour')), int(sch.get('minute')), 0) # 过期的就不再添加到提醒任务中了 if tell_time > dt.now(): self.bs.add_job( self.__show_msg, trigger=DateTrigger(run_date=tell_time), args=[sch.get('title'), sch.get('describ')]) Logger.info(self.bs.get_jobs(), module='__add_schedule_background_tasks')
def group(server): ps = db0.pubsub() ps.subscribe(Channel0.que_down_alarm_multi) Logger.info(msg='Listen IN GROUP', type=IDType.sub, action=Action.multi) while True: for item in ps.listen(): Logger.info(msg='PS Listen %s' % item, type=IDType.sub, action=Action.multi) if item['type'] == 'message': key_split = item['data'].decode().split(':') group = Group.objects.get(unhexlify(key_split[1])) send_packet_info = write_pull_resp_multi(group) if send_packet_info is not None: send_packets = send_packet_info['packet'] pull_info_set = send_packet_info['pull_info_set'] fcnt = send_packet_info['fcnt'] for pull_info in pull_info_set: for send_packet in send_packets: send_packet = bytes( [pull_info.prot_ver]) + get_random_token( ) + Const.PULL_RESP_IDENTIFIER + json.dumps({ 'txpk': send_packet }).encode() server.socket.sendto(send_packet, pull_info.ip_addr) Logger.info(msg='%s' % send_packet, action=Action.pull_resp, type=IDType.ip_addr, id='%s:%d' % pull_info.ip_addr)
def run(self): device = Device.objects.get(self.dev_eui) if device.dev_class == ClassType.a or (device.dev_class == ClassType.c and self.rx_window == 1): send_info = write_pull_resp(device, rx_window=self.rx_window) if send_info is not None: send_data = send_info[0] fcnt = send_info[1] pull_info = send_info[2] self.server.socket.sendto(send_data, pull_info.ip_addr) t1 = time.time() self.args.append(t1) self.args.reverse() timing.info(msg='PULL_RESP: DEV:%s, TIME:%s' % (hexlify(device.dev_eui).decode(), self.args)) Logger.info(msg='RX1Sender %s' % send_data, action=Action.pull_resp, type=IDType.ip_addr, id='%s:%d' % pull_info.ip_addr) if pull_info.prot_ver == 2: resend = ReSender(pull_info, send_data, self.server) resend.start() # msg = MsgDn(category=ConstDB0.dev, eui=hexlify(device.dev_eui).decode(), ts=int(time.time()), fcnt=fcnt) # msg.save() else: while device.que_down.len() != 0 or Resend( device.dev_eui).check_exist(): send_data, fcnt, pull_info = write_pull_resp( device, rx_window=self.rx_window) if send_data is not None: self.server.socket.sendto(send_data, pull_info.ip_addr) Logger.info(msg='CLASS_B or class_c rx2 Sender %s' % send_data, action=Action.pull_resp, type=IDType.ip_addr, id='%s:%d' % pull_info.ip_addr) if pull_info.prot_ver == 2: resend = ReSender(pull_info, send_data, self.server) resend.start() gevent.sleep(3)
class RequestHandler(object): def __init__(self): self.logger = Logger().get_logger() def get(self, url, **kwargs): try: params = kwargs.get('params') headers = kwargs.get('headers') rsp = requests.get(url, params=params, headers=headers) time_consuming = rsp.elapsed.microseconds / 1000 self.logger.info('请求耗时: %s ms' % (time_consuming)) return rsp except Exception as e: self.logger.error('Get 请求 %s 错误: %s' % (url, e)) def post(self, url, **kwargs): try: params = kwargs.get('params') data = kwargs.get('data') r_json = kwargs.get('json') headers = kwargs.get('headers') self.logger.info(f"请求地址: {url}") rsp = requests.post(url, params=params, data=data, json=r_json, headers=headers) time_consuming = rsp.elapsed.microseconds / 1000 self.logger.info('请求耗时: %s ms' % (time_consuming)) return rsp except Exception as e: self.logger.error('Post 请求 %s 错误: %s' % (url, e))
def all(cls, group_id=None): """ :param app_eui: bytes :return: """ devices = [] keys = [] if group_id is not None: # keys = db0.keys(ConstDB.group_dev + hexlify(group_id).decode() + ':*') # keys = [unhexlify(key.decode().split(':')[2]) for key in keys] dbsession = DBSession() Logger.info('chenxing', 'group_id', group_id) group_id = hexlify(group_id).decode() query = dbsession.query(GroupDevice.dev_id).filter( GroupDevice.group_id == group_id).all() dbsession.close() Logger.info('chenxing', 'query', query) keys = [i_query[0] for i_query in query] keys = [unhexlify(key) for key in keys] Logger.info('chenxing', 'keys', str(keys)) for key in keys: device = Device.query.get(key) devices.append(device) return devices