예제 #1
0
 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)
예제 #2
0
 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
예제 #3
0
 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')
예제 #4
0
 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
예제 #5
0
 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
예제 #6
0
 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()
예제 #7
0
    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()
예제 #8
0
 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
예제 #9
0
 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)
예제 #10
0
 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()
예제 #11
0
 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()
예제 #12
0
        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)

예제 #13
0
 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())