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 __init__(self, dev_eui, app_eui=None, que_limit=1): """ :param app_eui: bytes :param device: Device :return: """ # app_eui = hexlify(app_eui).decode() # if not db0.sismember(ConstDB.app_devs+app_eui, dev_eui): # raise KeyError("Data enqueue failed. Device %s not registered in this app %s" % (hexlify(dev_eui).decode(), app_eui)) # if isinstance(device, bytes): # device = Device.query.get(device) # if app_eui is not None: hex_dev_eui = hexlify(dev_eui).decode() device_app_eui = db0.hget(ConstDB.dev + hex_dev_eui, FieldDevice.app_eui) if device_app_eui is None: raise KeyError("Data enqueue failed. Device %s is not active yet" % hex_dev_eui) if app_eui is not None: if device_app_eui != app_eui: raise KeyError( "Data enqueue failed. Device %s not registered in this app %s" % (hex_dev_eui, hexlify(app_eui).decode())) self.dev_eui = dev_eui self.key = ConstDB.dev + hex_dev_eui self.que_limit = que_limit
def add_device(self, dev_eui): """ :param dev_eui: bytes :return: """ dev_eui = hexlify(dev_eui).decode() dev_app_eui = db0.hget(ConstDB.dev + dev_eui, FieldDevice.app_eui) if self.app_eui == dev_app_eui: """ db0.set(ConstDB.group_dev + hexlify(self.id).decode() + ':' + dev_eui, 1) """ dbsession = DBSession() group_id = hexlify(self.id).decode() query = dbsession.query(GroupMysql).filter( GroupMysql.id == group_id) if query.count() == 0: group_init = GroupMysql(id=group_id) dbsession.add(group_init) else: group_init = query.first() query = dbsession.query(DevMysql).filter(DevMysql.id == dev_eui) if query.count() == 0: dev_init = DevMysql(id=dev_eui) dbsession.add(dev_init) else: dev_init = query.first() query = dbsession.query(GroupDevice).filter( and_(GroupDevice.group_id == group_id, GroupDevice.dev_id == dev_eui)).count() if query == 0: group_init.devs.append(dev_init) dbsession.commit() dbsession.close() else: raise KeyError('No such Device in this Application')
def init_on_load(self): if self.__token is not None: self.token_cipher = cipher_token(self.app_eui[0:8], self.__token) freq_plan = db0.hget(ConstDB.app + hexlify(self.app_eui).decode(), Field.freq_plan) if freq_plan is not None: self.freq_plan = FrequencyPlan(freq_plan.decode()) else: self.freq_plan = FrequencyPlan.EU863_870
def count_in_hour(key): res = [] cur_time = datetime.now() cur_hour = cur_time.hour today_key = key + cur_time.strftime('%Y-%m-%d') yesterday_key = key + (cur_time - timedelta(days=1)).strftime('%Y-%m-%d') for x in range(0, 24): hour = cur_hour - 23 + x if hour < 0: data = db0.hget(yesterday_key, hour + 24) else: data = db0.hget(today_key, hour) if not data: data = 0 else: data = int(data) res.append(data) return res
def update(self): pipe = db0.pipeline() group_key = ConstDB.group + hexlify(self.id).decode() orignal_addr = db0.hget(group_key, FieldGroup.addr) if self.addr != orignal_addr: AddrManger.addr_available(self.addr) pipe.rename(ConstDB.addr + hexlify(orignal_addr).decode(), ConstDB.addr + hexlify(self.addr).decode()) pipe.hmset(group_key, self.__zip_vars_can_write()) pipe.execute()
def delete(self): db_sql.session.delete(self) db_sql.session.flush() if self.active_at is not None: app_eui = hexlify(self.app_eui).decode() dev_eui = hexlify(self.dev_eui).decode() addr = hexlify(db0.hget(ConstDB.dev + dev_eui, FieldDevice.addr)).decode() msgs_up = db0.keys(ConstDB.msg_up + app_eui + ':' + dev_eui + ':*') msgs_down = db0.keys(ConstDB.msg_down + ConstDB.dev + dev_eui + ':*') mac_cmds = db0.keys(ConstDB.mac_cmd + dev_eui + ':*') trans_params = db0.keys(ConstDB.trans_params + dev_eui + ':*') # groups = db0.keys(ConstDB.group_dev + '*:' + dev_eui) dbsession = DBSession() query = dbsession.query(GroupDevice.group_id).filter( GroupDevice.dev_id == dev_eui).all() dbsession.close() group_devs_list = [i_query[0] for i_query in query] groups = [ (ConstDB.group_dev + i_group_list + ':' + dev_eui).encode() for i_group_list in group_devs_list ] statistics_up = db0.keys(ConstDB.statistics_up + dev_eui + ':*') statistics_down = db0.keys(ConstDB.statistics_down + ConstDB.dev + dev_eui + ':*') pipe = db0.pipeline() pipe.delete(ConstDB.dev_ack + dev_eui) pipe.delete(ConstDB.dev + dev_eui) pipe.srem(ConstDB.app_devs + app_eui, self.dev_eui) for key in groups: pipe.delete(key) pipe.delete(ConstDB.addr + addr) pipe.delete(ConstDB.dev_gateways + dev_eui) for key in mac_cmds: pipe.delete(key) for key in msgs_up: pipe.delete(key) for key in msgs_down: pipe.delete(key) pipe.delete(ConstDB.que_down + ConstDB.dev + dev_eui) pipe.delete(ConstDB.mac_cmd_que + dev_eui) for key in trans_params: pipe.delete(key) for key in statistics_down: pipe.delete(key) for key in statistics_up: pipe.delete(key) pipe.execute() AddrManger.recycle_addr(unhexlify(addr)) db_sql.session.commit()
def __get_more_info(self): FREQ_PLAN = frequency_plan[self.app.freq_plan] info = db0.hget(ConstDB.dev_info + hexlify(self.dev_eui).decode(), self._info_field) self.MaxDutyCycle = int(info[0]) if info and info[0] else 0 self.RX1DRoffset = int( info[1]) if info and info[1] else FREQ_PLAN.RX1DRoffset self.RX2DataRate = int( info[2]) if info and info[2] else FREQ_PLAN.RX2DataRate self.RX2Frequency = float( info[3]) if info and info[3] else FREQ_PLAN.RX2Frequency self.RxDelay = int( info[4]) if info and info[4] else FREQ_PLAN.RECEIVE_DELAY1 self.battery = int(info[5]) if info and info[5] else None self.snr = int(info[6]) if info and info[6] else None
def push(self, fport, payload, cipher=False, seqno=None): """ :param fport: int from 0 to 255 :param payload: bytes :param cipher: True or False :param seqno: if cipher is True, seqno mush present and must math fcnt else will raise SeqNoError :return: """ assert isinstance( payload, bytes) and len(payload) < MAX_FRMPAYLOAD_LENGTH, 'Payload Error' assert isinstance(fport, int) and 0 < fport < 255, 'FPort Error' assert isinstance(cipher, bool), 'Cipher Type Error' if self.que_limit <= self.len(): raise QueOccupied('The queue of this Group:%s is occupied' % hexlify(self.id).decode()) fport = pack('B', fport) if cipher is False: appskey = db0.hget(self.key, FieldGroup.appskey) if len(appskey) != 16: raise AppSKeyAbsence(self.key) cipher = b'\x00' else: fcnt = int(db0.hget(self.key, FieldGroup.fcnt)) que_len = self.len() seqno_expect = fcnt + que_len + 1 if seqno != seqno_expect: raise SeqNoError(seqno, seqno_expect) cipher = b'\x01' db0.rpush(ConstDB.que_down + self.key, cipher + fport + payload) db0.publish(Channel.que_down_alarm_multi, self.key) Logger.info(action=Action.publish, resource=Resource.group, id=self.id, msg='Publish ' + Channel.que_down_alarm_multi + ' ' + self.key)
def delete(self): db_sql.session.delete(self) db_sql.session.flush() if self.active_at is not None: app_eui = hexlify(self.app_eui).decode() dev_eui = hexlify(self.dev_eui).decode() addr = hexlify(db0.hget(ConstDB.dev + dev_eui, FieldDevice.addr)).decode() msgs_up = db0.keys(ConstDB.msg_up + app_eui + ':' + dev_eui + ':*') msgs_down = db0.keys(ConstDB.msg_down + ConstDB.dev + dev_eui + ':*') mac_cmds = db0.keys(ConstDB.mac_cmd + dev_eui + ':*') trans_params = db0.keys(ConstDB.trans_params + dev_eui + ':*') groups = db0.keys(ConstDB.group_dev + '*:' + dev_eui) statistics_up = db0.keys(ConstDB.statistics_up + dev_eui + ':*') statistics_down = db0.keys(ConstDB.statistics_down + ConstDB.dev + dev_eui + ':*') pipe = db0.pipeline() pipe.delete(ConstDB.dev_ack + dev_eui) pipe.delete(ConstDB.dev + dev_eui) pipe.srem(ConstDB.app_devs + app_eui, self.dev_eui) for key in groups: pipe.delete(key) pipe.delete(ConstDB.addr + addr) pipe.delete(ConstDB.dev_gateways + dev_eui) for key in mac_cmds: pipe.delete(key) for key in msgs_up: pipe.delete(key) for key in msgs_down: pipe.delete(key) pipe.delete(ConstDB.que_down + ConstDB.dev + dev_eui) pipe.delete(ConstDB.mac_cmd_que + dev_eui) for key in trans_params: pipe.delete(key) for key in statistics_down: pipe.delete(key) for key in statistics_up: pipe.delete(key) pipe.execute() AddrManger.recycle_addr(unhexlify(addr)) db_sql.session.commit()
def update(self, fields): dd = {} pipe = db0.pipeline() dev_key = ConstDB.dev + hexlify(self.dev_eui).decode() for field in fields: if field.name in self.__redis_fields: if not self.active_at: raise Exception('Device is not active yet') value = getattr(self, field.name) if field.name == FieldDevice.addr: orignal_addr = db0.hget(dev_key, FieldDevice.addr) if value != orignal_addr: AddrManger.addr_available(self.addr) pipe.rename( ConstDB.addr + hexlify(orignal_addr).decode(), ConstDB.addr + hexlify(self.addr).decode()) if isinstance(value, enum.Enum): value = value.value elif isinstance(value, bool): value = value.real dd[field.name] = value if len(dd) > 0: pipe.hmset(dev_key, dd) pipe.execute()
dbsession = DBSession() gateway_init = GatewayLocation(gateway_id=gateway_id, latitude=latitude, longitude=longitude, altitude=altitude, code_province=code_province, code_city=code_city, code_area=code_area) dbsession.add(gateway_init) dbsession.commit() dbsession.close() def create_db(): Base.metadata.create_all(bind=engine) def drop_db(): Base.metadata.drop_all(bind=engine) if __name__ == '__main__': # create_db() from database.db0 import db0, ConstDB key_list = db0.keys(pattern=ConstDB.gateway + '*') for i_key in key_list: gateway_id = i_key.decode().split(':')[1] location = db0.hget(i_key, 'location') data = location.decode().split(',') lng = float(data[0]) lat = float(data[1]) alt = int(data[2]) # print('id=%s lat=%s lng=%s' % (gateway_id, str(lat), str(lng))) GatewayLocation.insert(gateway_id=gateway_id, latitude=lat, longitude=lng, altitude=alt)
def __get_freq_plan(self): freq_plan = db0.hget(ConstDB.app + hexlify(self.app_eui).decode(), 'freq_plan') if freq_plan is not None: return FrequencyPlan(freq_plan.decode())