def _set_current_user(self, entrance_id, entrance_addr): """ 设置当前库房登录者并发送至web 不存在就创建并保存到DB :return: """ user = User.by_code(code=self.user_code) if user is not None: self.user_id = user.uuid data = {'user_id': self.user_id} pkg_to_web = TransferPackage(code=USER_ENTRANCE_SUCCESS, eq_type=3, msg_type=2, storeroom_id=self.storeroom_id, data=data, eq_id=entrance_id) self.q_send.put(pkg_to_web) print('put to q_send for sending to web--', pkg_to_web) print('size of q_send', self.q_send.qsize()) roles = user.roles if roles: self.user_role = roles[0].level else: self.user_role = 3 else: mylogger.warning('get no user by code %s' % self.user_code) user = User(login_name=self.user_code, code=self.user_code, card_id=self.card_id, register_time=datetime.datetime.now()) rsl = user.save() if not rsl: mylogger.warning('Fail to save user by code %s from entrance %s' % (self.user_code, str(entrance_addr)))
def puttask(self, json_data): """ 1、发送gataway_server和设备相关的pkg到gataway_server; :param data: :return: """ try: all_type = {1: 'entrance_zk', 2: 'entrance_hk', 3: 'code_scan', 4: 'gravity', 5: 'rfid2000', 6: 'rfid2000fh', 7: 'channel_machine', 8: 'led'} # pkg = eval(str(data, encoding='utf-8')) pkg = TransferPackage() pkg.uuid = json_data['uuid'] if 'uuid' in json_data.keys() else None pkg.target = json_data['target'] if 'target' in json_data.keys() else None pkg.source = json_data['source'] if 'source' in json_data.keys() else None pkg.code = json_data['code'] if 'code' in json_data.keys() else None pkg.msg_type = json_data['msg_type'] if 'msg_type' in json_data.keys() else None pkg.storeroom_id = json_data['storeroom_id'] if 'storeroom_id' in json_data.keys() else None if pkg.code == ENTRANCE_ADD_USER: eq_id = json_data['equipment_id'] if 'equipment_id' in json_data.keys() else None user_id = json_data['data']['user_id'] user = User.by_uuid(user_id) entrance = Entrance.by_id(eq_id) func = 'add_new_user' args = (user.code, user.fingerprint, user.login_name, user.card_id) if entrance.type == 2: # 1-ZK; 2-HK; func = 'build_new_user_to_terminal' args = (user_id, ) pkg.data = {'func': func, 'args': args} elif pkg.code == ENTRANCE_REDUCE_USER: eq_id = json_data['equipment_id'] if 'equipment_id' in json_data.keys() else None user_id = json_data['data']['user_id'] user = User.by_uuid(user_id) entrance = Entrance.by_id(eq_id) func = 'delete_user' args = (user.card_id, ) if entrance.type == 2: # 1-ZK; 2-HK; func = 'del_user_from_web' args = (user.card_id,) pkg.data = {'func': func, 'args': args} elif pkg.code == GATEWAY_ADD_NEW_EQUIPMENT: raw_data = json_data['data'] func = 'add_new_equipment' eq_type_value = int(raw_data['type']) args = (raw_data['ip'], raw_data['port'], all_type[eq_type_value], raw_data['is_server'], pkg.storeroom_id, pkg.uuid) pkg.data = {'func': func, 'args': args} elif pkg.code == GATEWAY_REDUCE_EQUIPMENT: raw_data = json_data['data'] func = 'delete_equipment' args = (raw_data['ip'], raw_data['port'], raw_data['is_server']) pkg.data = {'func': func, 'args': args} else: pkg.data = json_data['data'] if 'data' in json_data.keys() else None self.q_task.put(pkg) except Exception as e: print(e) mylogger.warning(e)
def _stop_channel_machine(self): if len(self.channel_machines) > 0: for k, v in self.channel_machines.items(): pkg = TransferPackage() pkg.target = v pkg.msg_type = 0 pkg.storeroom_id = self.storeroom_id data = {'func': 'stop_running', 'args': ()} pkg.data = data self.q_task.put(pkg) else: mylogger.warning('storeroom--(%s, %d) has no channel machine to stop')
def get_all_channel_machine(storeroom, clients_servers): channels = storeroom.channel_machines if channels is not None: for channel in channels: if check_ip(channel.ip): if channel.is_server is True: clients_servers['servers'][(channel.ip, channel.port)] = ( 'channel_machine', channel.id) else: clients_servers['clients'][(channel.ip, channel.port)] = ( 'channel_machine', channel.id) else: mylogger.warning('wrong IP of channel_machine ip--%s' % channel.ip)
def _modify_db_eq_status(self, eq_type: str, addr: tuple, is_online: bool): """ 设备的类型包括:['entrance_zk', 'code_scane', 'channel_machine', 'led', 'gravity', 'rfid2000', 'rfid2000fh'] :param eq_type: :return: """ try: if eq_type == 'entrance_zk' or eq_type == 'entrance_hk': entrance = Entrance.by_addr(ip=addr[0], port=addr[1]) if entrance is not None: entrance.update('status', int(is_online)) if not is_online: cur_dt = str(datetime.datetime.now()) entrance.update('last_offline_time', cur_dt) else: mylogger.warning( 'Not found object(%s,%d) from DB-entrance while updating' % addr) elif eq_type in ['gravity', 'rfid2000', 'rfid2000fh']: collector = Collector.by_addr(ip=addr[0], port=addr[1]) if collector is not None: collector.update('status', int(is_online)) # shelf = collector.shelf # map(lambda grid: grid.update('status', int(is_online)), shelf.grids) if not is_online: cur_dt = str(datetime.datetime.now()) collector.update('last_offline_time', cur_dt) else: mylogger.warning( 'Not found object(%s,%d) from DB-collector while updating' % addr) elif eq_type == 'led': indicator = Indicator.by_addr(ip=addr[0], port=addr[1]) if indicator is not None: indicator.update('status', int(is_online)) if not is_online: cur_dt = str(datetime.datetime.now()) indicator.update('last_offline_time', cur_dt) else: mylogger.warning( 'Not found object(%s,%d) from DB-indicator while updating' % addr) elif eq_type == 'channel_machine': cm = ChannelMachine.by_addr(ip=addr[0], port=addr[1]) if cm is not None: cm.update('status', int(is_online)) if not is_online: cur_dt = str(datetime.datetime.now()) cm.update('last_offline_time', cur_dt) else: mylogger.warning( 'Not found object(%s,%d) from DB-indicator while updating' % addr) else: pass print('\033[1;33m', str(addr), 'is online' if is_online else 'is offline', '\033[0m') except Exception as e: print('_modify_db_eq_status', e)
def get_all_code_scanners(storeroom, clients_servers): scanners = storeroom.code_scanners if scanners is not None: for scanner in scanners: if check_ip(scanner.ip): if scanner.is_server is True: clients_servers['servers'][(scanner.ip, scanner.port)] = ('code_scan', scanner.id) else: clients_servers['clients'][(scanner.ip, scanner.port)] = ('code_scan', scanner.id) else: mylogger.warning('wrong IP of code_scanner ip--%s' % scanner.ip)
def get_all_entrances(storeroom, clients_servers): type_name = {1: 'entrance_zk', 2: 'entrance_hk'} entrances = storeroom.entrance if entrances is not None: for entrance in entrances: if check_ip(entrance.ip): if entrance.is_server is True: clients_servers['servers'][(entrance.ip, entrance.port)] = ( type_name[entrance.type], entrance.id) else: clients_servers['clients'][(entrance.ip, entrance.port)] = ( type_name[entrance.type], entrance.id) else: mylogger.warning('wrong IP of entrance ip--%s' % entrance.ip)
def get_all_led(storeroom, clients_servers): shelfs = storeroom.shelfs if shelfs is not None: for shelf in shelfs: indicators = shelf.indicators if indicators is not None: for indicator in indicators: if check_ip(indicator.ip): if indicator.is_server is True: clients_servers['servers'][( indicator.ip, indicator.port)] = ('led', indicator.id) else: clients_servers['clients'][( indicator.ip, indicator.port)] = ('led', indicator.id) else: mylogger.warning('wrong IP of led ip--%s' % indicator.ip)
def check_equipments_status(self): """ 如果线程为None,表示连接已断开, 则删除相应激活字典中键值对。 :return: """ with self.lock: for k, v in self.terminal_active.copy().items(): if not v['thread'].isAlive(): pkg = TransferPackage(source=k, msg_type=2, code=EQUIPMENT_OFFLINE) self.queue_rsl.put(pkg) if v['is_server']: del self.server_active[k] else: del self.client_active[k] del self.terminal_active[k] mylogger.warning('equipment (%s, %d) is offline' % k) self._modify_db_eq_status(eq_type=v['type'], addr=k, is_online=False)
def get_all_collectors(storeroom, clients_servers): type_name = {1: 'gravity', 2: 'rfid2000', 3: 'rfid2000fh'} shelfs = storeroom.shelfs if shelfs is not None: for shelf in shelfs: collectors = shelf.collectors if collectors is not None: for collector in collectors: if check_ip(collector.ip): if collector.is_server is True: clients_servers['servers'][( collector.ip, collector.port)] = (type_name[collector.type], collector.id) else: clients_servers['clients'][( collector.ip, collector.port)] = (type_name[collector.type], collector.id) else: mylogger.warning('wrong IP of collector ip--%s' % collector.ip)
def _save_rfid_data(self, rfid_history: list): """ 1、逐个判断借出或者归还; 2、借出:若耗材则直接保存已还,否则直接保存未还并设置goods出库; 3、归还:是否在未还列表,是则修改已还并设置goods入库,否则新增记录设置错误用户已还并设置goods入库; :param history: :return: """ try: # print('rfid history--', history) current_dt = datetime.datetime.now() # 先把self.rfid_goods中的key从bytes转为str; rfid_current = {k.hex(): v for k, v in self.rfid_goods.items()} goods_registered = Goods.by_epc_list(epcs=list(rfid_current.keys())) goods_epc_db = {g.epc: g for g in goods_registered} epc_grid_history = {h.epc: h for h in rfid_history} if rfid_history is not None else {} for epc, v in rfid_current.items(): grid_current = Grid.by_eqid_antenna(eq_id=v[0], antenna_num=v[1].hex(), addr_num=v[3].hex()) grid_id_current = grid_current.id if grid_current is not None else None if epc in goods_epc_db.keys(): # 存在于DB的EPC if v[2] is True: # 为归还 if epc in epc_grid_history.keys(): # 该EPC在未还列表 goods_grid_id = goods_epc_db[epc].grid_id wrong_place_gid = grid_id_current if grid_id_current != goods_grid_id else None status = 3 if wrong_place_gid else 0 record = epc_grid_history[epc] if record: record.update('status', status) record.update('inbound_datetime', current_dt) record.update('wrong_place_gid', wrong_place_gid) else: if self.user_role == 1 or self.user_role == 2: # 管理员新增物资 record = History_inbound_outbound(user_id=self.user_id, grid_id=grid_id_current, epc=epc, count=1, inbound_datetime=current_dt, status=5) record.save() mylogger.info('EPC(%s) was increased by administrator--%s' % (epc, self.user_code)) else: # 普通用户代还 record = History_inbound_outbound(user_id=self.user_id, grid_id=grid_id_current, epc=epc, count=1, inbound_datetime=current_dt, status=4) record.save() mylogger.info('EPC(%s) was returned by wrong user--%s' % (epc, self.user_code)) else: # 为借出 goods = goods_epc_db[epc] status = 0 if goods.type == 2 else 1 record = History_inbound_outbound(user_id=self.user_id, grid_id=grid_id_current, epc=epc, count=1, outbound_datetime=current_dt, status=status) record.save() goods.update('is_in_store', 0) else: # 不存在于DB的EPC record = History_inbound_outbound(user_id=self.user_id, grid_id=grid_id_current, epc=epc, count=1, inbound_datetime=current_dt, status=6, wrong_place_gid=grid_id_current) record.save() mylogger.warning('EPC(%s) was not registered but token in by user--%s' % (epc, self.user_code)) except Exception as e: mylogger.warning(e)
def _save_gravity_data(self, history: list): """ 1、借出 1.1 有错放记录的格子 1.2 正常的格子 2、归还 2.1 已借未还的格子 2.2 无借却还的格子 :param history: :return: """ try: current_dt = datetime.datetime.now() # grids_history = [h.grid_id for h in history] for k, v in self.gravity_goods.items(): if v[1] < 0: # 为借出 print('\033[1;33m', 'take out weight %d' % v[1], '\033[0m') records_this_grid = [record for record in history if record.grid_id == k] is_wrong_place = False for record in records_this_grid: if record.status == 3: is_wrong_place = True if is_wrong_place: # 有错放记录的格子 if self.user_role == 1 or self.user_role == 2: msg = 'the wrong placed grid-%s was take out-%dg by administrator-%s' % (k, v[1], self.user_code) mylogger.info(msg=msg) else: # 普通用户借出 is_returned = False for g in self.gravity_goods.values(): if g[1] > 0 and abs(g[1] + v[1]) < self.gravity_precision: # 归还清单有对应的重量 is_returned = True rsl = History_inbound_outbound.by_user_grid_status3(user_id=self.user_id, grid_id=k) if rsl: for record in rsl: if abs(record.count + v[1]) < self.gravity_precision: # 清除该错放记录 record.update('status', 0) record.update('outbound_datetime', current_dt) if not is_returned: status = 0 if v[0] == 2 else 1 record = History_inbound_outbound(user_id=self.user_id, grid_id=k, count=abs(v[1]), outbound_datetime=current_dt, status=status, monitor_way=1) record.save() print('create a new record') else: # 没有错放记录的格子 status = 0 if v[0] == 2 else 1 record = History_inbound_outbound(user_id=self.user_id, grid_id=k, count=abs(v[1]), outbound_datetime=current_dt, status=status, monitor_way=1) record.save() else: # 为归还 print('\033[1;33m', 'put in weight %d' % v[1], '\033[0m') grid_id_need_return = [h.grid_id for h in history if (h.status == 1 or h.status == 2)] if k in grid_id_need_return: # 已借未还 records_this_grid = [record for record in history if record.grid_id == k and (record.status == 1 or record.status == 2)] remain = v[1] for record in records_this_grid: if record.return_mark is not None: # 尚未还清的记录 return_mark_dict = eval(record.return_mark) returned_count = sum(return_mark_dict.values()) need_return = record.count - returned_count diff = remain - need_return record.update('inbound_datetime', current_dt) return_mark_dict[current_dt.strftime("%Y-%m-%d-%H-%M-%S")] = need_return record.update('return_mark', str(return_mark_dict)) if diff >= -self.gravity_precision: # 该条记录全还清 record.update('status', 0) remain -= need_return else: # 该条记录只还部分,并结束该格子的归还 break else: # 未还过的记录 diff = remain - record.count record.update('inbound_datetime', current_dt) return_mark_dict = {current_dt.strftime("%Y-%m-%d-%H-%M-%S"): record.count} record.update('return_mark', str(return_mark_dict)) if diff >= -self.gravity_precision: # 该条记录全还清 record.update('status', 0) remain -= record.count else: # 该条记录只还部分,并结束该格子的归还 break print('remain--', remain) if remain > self.gravity_precision: # 归还后有超出重量的其他东西,记录为错放格子 record = History_inbound_outbound(user_id=self.user_id, grid_id=k, count=remain, monitor_way=1, inbound_datetime=current_dt, status=3, wrong_place_gid=k) record.save() msg = 'the grid-%s was returned by overweight-%dg by user-%s' % (k, v[1], self.user_code) mylogger.warning(msg=msg) else: # 无借却还 if self.user_role == 1 or self.user_role == 2: msg = 'the grid-%s was put in-%dg by administrator-%s' % (k, v[1], self.user_code) mylogger.info(msg=msg) record = History_inbound_outbound(user_id=self.user_id, grid_id=k, count=abs(v[1]), monitor_way=1, inbound_datetime=current_dt, status=5) record.save() # 修改该格子物资的新增字段 else: if grid_id_need_return: # 只要仍然有未还的记录,放错格子 record = History_inbound_outbound(user_id=self.user_id, grid_id=k, count=abs(v[1]), monitor_way=1, inbound_datetime=current_dt, status=3, wrong_place_gid=k) record.save() msg = 'the grid-%s was wrong placed weight-%dg by user-%s' % (k, v[1], self.user_code) mylogger.info(msg=msg) except Exception as e: mylogger.warning(e)
def _save_rfid_data(self, history: list): """ 1、逐个判断借出或者归还; 2、借出:若耗材则直接保存已还,否则直接保存未还并设置goods出库; 3、归还:是否在未还列表,是则修改已还并设置goods入库,否则新增记录设置错误用户已还并设置goods入库; :param history: :return: """ try: # print('rfid history--', history) current_dt = datetime.datetime.now() # 先把self.rfid_goods中的key从bytes转为str; rfid_current = {k.hex(): v for k, v in self.rfid_goods.items()} goods_db = Goods.by_epc_list(epcs=rfid_current.keys()) goods_epc_db = [g.epc for g in goods_db] epc_grid_id = {h.epc: h.grid_id for h in history} if history is not None else {} for epc, v in rfid_current.items(): print('epc--', epc) print('goods_epc_db--', goods_epc_db) grid_current = Grid.by_eqid_antenna(eq_id=v[0], antenna_num=v[1].hex(), addr_num=v[3].hex()) grid_id_current = grid_current.id if grid_current is not None else None if epc in goods_epc_db: # 存在于DB的EPC if v[2] is True: # 为归还 wrong_place_gid = grid_current if grid_id_current != epc_grid_id[ epc] else None record = History_inbound_outbound.by_epc_need_return( epc=epc) if record: wrong_return_user = self.user_id if self.user_id != record.user_id else None record.update('status', 0) record.update('inbound_datetime', current_dt) record.update('wrong_place_gid', wrong_place_gid) record.update('wrong_return_user', wrong_return_user) goods = [g for g in goods_db if g.epc == epc] if goods: goods[0].update('is_in_store', 1) else: record = History_inbound_outbound( user_id=self.user_id, grid_id=grid_id_current, epc=epc, count=1, inbound_datetime=current_dt, status=0, wrong_place_gid=grid_id_current, wrong_return_uid=self.user_id) record.save() mylogger.warning( 'get no history by_epc_need_return() EPC(%s) but still was returned' % epc) else: # 为借出 record = History_inbound_outbound( user_id=self.user_id, grid_id=grid_id_current, epc=epc, count=1, outbound_datetime=current_dt, status=1) record.save() goods = [g for g in goods_db if g.epc == epc] if goods: goods[0].update('is_in_store', 0) else: # 不存在于DB的EPC record = History_inbound_outbound( user_id=self.user_id, grid_id=grid_id_current, epc=epc, count=1, inbound_datetime=current_dt, status=0, wrong_place_gid=grid_id_current) record.save() mylogger.warning( 'get no goods in database by EPC(%s) but still was returned' % epc) except Exception as e: mylogger.warning(e)
def _save_gravity_data(self, history: list): """ 1、若为耗材,则直接保存并设为已还; 2、若为借出,先判断是否位置错误,符合条件则设置为已还,否则新增借出并设置未还; 3、若为归还,则查询是否有未还,有再判断是否全部归还或者放置错误;没有则判断为放置错误; :param history: :return: """ try: current_dt = datetime.datetime.now() grids_history = [h.grid_id for h in history] for k, v in self.gravity_goods.items(): if v[0] == 2: # 为耗材 record = History_inbound_outbound( user_id=self.user_id, grid_id=k, count=abs(v[1]), outbound_datetime=current_dt, status=0, monitor_way=1) record.save() else: # 工具或仪器 if v[1] < 0: # 为借出 if k in grids_history: # 存在位置错误的 record = history[grids_history.index(k)] diff = record.count - abs(v[1]) if record.wrong_place_gid and abs( diff) < self.gravity_precision: record.update('wrong_place_gid', None) else: record = History_inbound_outbound( user_id=self.user_id, grid_id=k, count=abs(v[1]), monitor_way=1, outbound_datetime=current_dt, status=1) record.save() else: # 为归还 if k in grids_history: # 有未还 record = history[grids_history.index(k)] diff = record.count - v[1] if abs(diff) < self.gravity_precision: # 全部归还 record.update('status', 0) record.update('inbound_datetime', current_dt) if self.user_id != record.user_id: record.update('wrong_return_user', self.user_id) elif diff > 5: # 部分归还 record.update('count', diff) record.update('inbound_datetime', current_dt) if self.user_id != record.user_id: record.update('wrong_return_user', self.user_id) else: # 放置错误 record.update('wrong_place_gid', k) record.update('inbound_datetime', current_dt) else: # 放置错误 record = History_inbound_outbound( user_id=self.user_id, grid_id=k, count=abs(v[1]), monitor_way=1, inbound_datetime=current_dt, status=0, wrong_place_gid=k) record.save() except Exception as e: mylogger.warning(e)
def _connect_server(self, addr: tuple, ttype: str, storeroom_id: str, uuid: str): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(0.1) failed_count = 0 terminal_type = ttype queue_task = Queue(50) queue_rsl = Queue(50) subevent = threading.Event() thread = None while self.isrunning: try: if terminal_type == 'entrance_zk': thread = EntranceZK(addr, queue_task, queue_rsl, subevent, self.queue_equipment_push, storeroom_id, uuid) elif terminal_type == 'entrance_hk': thread = HKVision(addr, queue_task, queue_rsl, subevent, self.queue_equipment_push, storeroom_id, uuid) else: s.connect(addr) if terminal_type == 'gravity': gravity = Collector.by_addr(addr[0], addr[1]) if gravity: addr_nums = gravity.node_addrs.replace( ' ', '').split(',') thread = GravityShelf(addr, s, queue_task, queue_rsl, subevent, self.queue_equipment_push, storeroom_id, uuid, addr_nums) elif terminal_type == 'led': thread = IndicatorLCD(addr, s, queue_task, queue_rsl, subevent, storeroom_id, uuid) elif terminal_type == 'rfid2000': thread = RfidR2000(addr, s, queue_task, queue_rsl, subevent, self.queue_equipment_push, storeroom_id, uuid) elif terminal_type == 'rfid2000fh': r2000fh = Collector.by_addr(addr[0], addr[1]) addr_nums = ['01'] if r2000fh: addr_nums = r2000fh.node_addrs.replace( ' ', '').split(',') thread = RfidR2000FH(addr, s, queue_task, queue_rsl, subevent, self.queue_equipment_push, storeroom_id, uuid, addr_nums) elif terminal_type == 'channel_machine': r2000fh = Collector.by_addr(addr[0], addr[1]) addr_nums = ['01'] if r2000fh: addr_nums = r2000fh.node_addrs.replace( ' ', '').split(',') thread = ChannelMachineR2000FH( addr, s, queue_task, queue_rsl, subevent, self.queue_equipment_push, storeroom_id, uuid, addr_nums) else: pass if thread: thread.setDaemon(True) thread.start() self.lock.acquire() self.terminal_active[addr] = { 'thread': thread, 'type': terminal_type, 'queuetask': queue_task, 'queuersl': queue_rsl, 'status': False, 'subevent': subevent, 'data': {}, 'is_server': True } self.server_active[addr] = (terminal_type, storeroom_id, uuid) self.lock.release() print('服务端(%s)已成功连接。。' % str(addr)) mylogger.info('服务端(%s)已成功连接。。online' % str(addr)) self._modify_db_eq_status(eq_type=terminal_type, addr=addr, is_online=True) break except socket.error: failed_count += 1 # print("fail to connect to server %d times" % failed_count) if failed_count == 10: print('fail to connect to server %s' % str(addr)) mylogger.warning('fail to connect to server %s' % str(addr)) break