def _convert_message( self, clresp: commlink.CLResponse) -> typing.Optional[CommonMSG]: """Convert an RFID response into a common message. Return None if this message should not be passed on. """ # assume that we are going to return this message... ret_code: commlink.TLSRetCode = clresp.return_code() if ret_code == commlink.BaseCommLink.RC_TIMEOUT: return CommonMSG(CommonMSG.MSG_SV_RFID_STATREP, CommonMSG.RFID_TIMEOUT) ret_is_ok = (ret_code == commlink.BaseCommLink.RC_OK) # A: determine the kind of message to return based on the comment_dict # or the current mode # Our decision is stored into msg_type msg_type = None ret_data: typing.Optional[typing.List[typing.Any]] = None comm_dct = clresp.get_comment_dct() if comm_dct is None: comment_str = None else: comment_str = comm_dct.get(commlink.BaseCommLink.COMMENT_ID, None) self._log_debug("clresp comment {}, Comment: {}".format( clresp, comment_str)) if comment_str is None: # we have a message because the user pressed the trigger -- # try to determine what kind of message to send back # based on our current mode if self.mode == TlsMode.radar: msg_type = CommonMSG.MSG_RF_RADAR_DATA elif self.mode == TlsMode.stock: msg_type = CommonMSG.MSG_RF_CMD_RESP else: self._log_debug('no comment_str and no mode: returning None') msg_type = None elif comment_str == 'radarsetup': # the server has previously sent a command to the RFID reader to go into # radar mode. We generate a message only if this failed. if not ret_is_ok: msg_type = CommonMSG.MSG_RF_CMD_RESP elif comment_str == 'RAD': msg_type = CommonMSG.MSG_RF_RADAR_DATA elif comment_str == 'IVreset': if not ret_is_ok: msg_type = CommonMSG.MSG_RF_CMD_RESP else: self._log_error('unhandled comment string {}'.format(comment_str)) # B: now try to determine ret_data. if msg_type is None: return None if msg_type == CommonMSG.MSG_RF_RADAR_DATA: self.runningave.add_clresp(clresp) ret_data = self.runningave.get_runningave() self._log_debug("Returning radar data {}".format(ret_data)) elif msg_type == CommonMSG.MSG_RF_CMD_RESP: ret_data = clresp.rl # do something with ret_data here and return a CommonMSG or None if ret_data is None: return None assert msg_type is not None and ret_data is not None, "convert_message error 99" return CommonMSG(msg_type, ret_data)
def test_commonmsg01(self): """Check illegal msgtypes are caught.""" mydat = 100.0 # wrong type or value should raise an appropriate assertion for msg, exc in [([1, 2], TypeError), ("blastr", ValueError)]: with pytest.raises(exc): CommonMSG(msg, mydat)
def generate_msg(self) -> typing.Optional[CommonMSG]: """Read a message from the RFID reader device if one is present. Convert this message into a CommonMsg instance or None and return it. The returned message will be put on the TaskMeister's queue. Typically, when the user presses the trigger of the RFID reader, we will send a message with the scanned data back. Note: This method overrules the method defined in BaseTaskMeister. """ self._log_debug("TLS GM enter") # check for a change of the state of the commlink first. # if the state has changed, report this. new_state = self._cl.get_rfid_state() if new_state != self.cur_state: self.cur_state = new_state self._log_debug( "TLS: state change reported. new state: {}".format(new_state)) return CommonMSG(CommonMSG.MSG_SV_RFID_STATREP, new_state) # no state change. if its up: # read something (blocking) and return that (could be None) # else: # return None the taskmeister will ignore it. if self.cur_state == CommonMSG.RFID_ON: self._log_debug("TLS before read... ") clresp: commlink.CLResponse = self._cl.raw_read_response() self._log_debug("TLS got {}".format(clresp)) return self._convert_message(clresp) self._log_debug("TLS state is: {}, returning None".format( self.cur_state)) return None
def refresh_locmut_dct(self) -> None: """Request a new locmutation list from the stocky server if we need an update. This is done by sending a hash of the current data. The server will send an update if our data is out of date. """ self.send_WS_msg( CommonMSG(CommonMSG.MSG_WC_LOCMUT_REQ, self.locmut_hash))
def send_ws_msg(self, msg: CommonMSG) -> None: """Send a command to the web client over websocket in a standard JSON format. Args: msg: the message to send. """ if self.ws is not None: self.ws.sendMSG(msg.as_dict())
def generate_msg(self) -> typing.Optional[CommonMSG]: """ Generate a message if the monitored file has appeared or disappeared since the last call. """ newstate = self.file_exists() if self._curstate != newstate: self._curstate = newstate return CommonMSG(CommonMSG.MSG_SV_FILE_STATE_CHANGE, newstate) return None
def test_delay01(self) -> None: """Perform test of a DelayTaskMeister""" tn = self.msgq.num_messages() if tn != 0: raise RuntimeError("unexpected tn = {}".format(tn)) msg = CommonMSG(CommonMSG.MSG_SV_RAND_NUM, 'delaytest') d = Taskmeister.DelayTaskMeister(self.msgq, self.logger, self.sec_interval, msg) d.trigger() gevent.sleep(self.test_sleep_time) tn = self.msgq.num_messages() if tn != 1: raise RuntimeError("unexpected tn = {}".format(tn))
def _init_rfid_server(self, CommLinkClass) -> None: """Perform initialisation activities for the RFID server. This server only talks to the RFID reader via rfcomm and serves the results via websockets. """ # start the rfcomm daemon... # the command to run is something along the lines of: # "/usr/bin/rfcomm connect /dev/rfcomm0 88:6B:0F:86:4D:F9" rfcomm_cmd = "{} connect {} {} ".format( self.cfg_dct['RFCOMM_PROGRAM'], self.cfg_dct['RFID_READER_DEVNAME'], self.cfg_dct['RFID_READER_BT_ADDRESS']) self.logger.debug("rfcomm command : '{}'".format(rfcomm_cmd)) self.rfcommtask = Taskmeister.DaemonTaskMeister( self.logger, rfcomm_cmd, 1) rfstat = self.rfcommtask.get_status() if rfstat != Taskmeister.DaemonTaskMeister.STATUS_RUNNING: self.logger.error( "rfcomm daemon is not running: status = {}".format(rfstat)) raise RuntimeError("rfcomm program has not started") self.logger.debug("rfcomm comand is running.") self.logger.debug("serverclass: instantiating CommLinkClass...") self.filewatcher = Taskmeister.FileChecker( self.msgQ, self.logger, 5, True, self.cfg_dct['RFID_READER_DEVNAME']) self.comm_link = CommLinkClass(self.cfg_dct) if self.comm_link is None: self.logger.error("serverclass: comm_link is None!...") return self.logger.debug("serverclass: instantiating TLSAscii...") self.tls = TLSAscii.TLSReader(self.msgQ, self.logger, self.comm_link, AVENUM) # create messages and a delayTM for the RFID activity spinner self._rfid_act_on = CommonMSG(CommonMSG.MSG_SV_RFID_ACTIVITY, True) rfid_act_off = CommonMSG(CommonMSG.MSG_SV_RFID_ACTIVITY, False) # set up the RFID activity delay timer self.rfid_delay_task = Taskmeister.DelayTaskMeister( self.msgQ, self.logger, 1.5, rfid_act_off)
def send_server_config(self) -> None: """Collect information about the server configuration and send this to the webclient. """ # NOTE: the cfg_dct has keys we do not want to send to the webclient. dd = self.cfg_dct cfg_dct = {k: dd[k] for k in serverconfig.known_set} # extract information about the RFID reader if its online. rfid_info_dct = self.comm_link.get_info_dct( ) if self.comm_link is not None else None if rfid_info_dct is not None: for k, val in rfid_info_dct.items(): cfg_dct[k] = val self.send_ws_msg(CommonMSG(CommonMSG.MSG_SV_SRV_CONFIG_DATA, cfg_dct))
def test_commonmsg01(self) -> None: c = CommonMSG(CommonMSG.MSG_SV_RAND_NUM, 10) assert c.msg == CommonMSG.MSG_SV_RAND_NUM, "wrong msg" assert c.data == 10, "wrong data" ll = CommonMSG.valid_msg_lst assert ll, "msg_lst expected" print("lst is {}".format(ll)) # # ll = CommonMSG.bla # print("lst is {}".format(ll)) # assert ll, "ll is empty" dd = CommonMSG.valid_msg_dct assert dd, "msg_dct expected" print("dct is {}".format(dd))
def test_send_rfid_msg(self): """Test behaviour of send_rfid_msg() with a number of valid/ invalid arguments. E.g. sending an instance other than a CommonMSG should raise an exception. """ with pytest.raises(TypeError): self.tls.send_rfid_msg('bla') cm = CommonMSG(CommonMSG.MSG_WC_RADAR_MODE, False) self.tls.send_rfid_msg(cm) assert self.tls.mode == TLSAscii.TlsMode.stock cm = CommonMSG(CommonMSG.MSG_WC_RADAR_MODE, True) self.tls.send_rfid_msg(cm) assert self.tls.mode == TLSAscii.TlsMode.radar cm = CommonMSG(CommonMSG.MSG_SV_GENERIC_COMMAND, '.iv') self.tls.send_rfid_msg(cm) assert self.tls.mode == TLSAscii.TlsMode.stock cm = CommonMSG(CommonMSG.MSG_SV_RAND_NUM, 'bla') with pytest.raises(RuntimeError): self.tls.send_rfid_msg(cm)
def generate_msg(self) -> typing.Optional[CommonMSG]: # generate either a barcode or RFID scan ? do_barcode = random.random() < 0.5 if do_barcode: nselect = 1 prelim = ['CS', '.bc,'] else: # RFID scan nselect = random.randrange(len(self.taglst)) prelim = ['CS', '.iv,'] sel_tags = random.choices(self.taglst, k=nselect) scan_data = [prelim] + [['EP', tag] for tag in sel_tags] + [['OK', '']] print("returning: '{}'".format(scan_data)) return CommonMSG(CommonMSG.MSG_RF_CMD_RESP, scan_data)
def test_commonmsg00(self): """Sanity check the MSG names... and check we can instantiate all message types.""" msglst = CommonMSG.valid_msg_lst msgdct = CommonMSG.valid_msg_dct # names must be unique assert len(msglst) == len(msgdct), "unexpected dct length" assert len(msglst) == CommonMSG.NUM_MSG, "inconsistent lst length" # names must allow assignment to exactly one source. mydat = 100.0 for msgtype in msglst: c = CommonMSG(msgtype, mydat) assert isinstance(c, CommonMSG), "expected a CommonMSG" assert c.msg == msgtype, "wrong type" assert c.data == mydat, "wrong data" nn = sum([ c.is_from_server(), c.is_from_webclient(), c.is_from_rfid_reader() ]) assert nn == 1, "illegal name {}".format(msgtype)
def generate_msg(self) -> typing.Optional[CommonMSG]: """Block until a data message is received from the webclient over websocket in JSON format. The resulting python data structure is analysed. If it is a valid message as defined in :mod:`webclient.commonmsg` , it is put on the queue as a CommonMSG instance. """ lverb = True if lverb: print("WSGM: before rec msg") dct = self.ws.receiveMSG() if lverb: print("WSGM: received msg") # the return value is either None or a dict. if dct is None: self._log_error("received None over ws, returning None") retmsg = None elif isinstance(dct, dict): need_keys = frozenset(['msg', 'data']) got_keys = set(dct.keys()) if need_keys <= got_keys: # now make sure we have a legal msg field try: retmsg = CommonMSG(dct['msg'], dct['data']) except (ValueError, TypeError): self._log_error("illegal msgtype= '{}'".format(dct['msg'])) retmsg = None xtra_keys = got_keys - need_keys if xtra_keys: self._log_warning( "unexpected extra dict keys, got '{}'".format( got_keys)) else: self._log_error("unknown keys in {}".format(got_keys)) retmsg = None # if retmsg is not None and retmsg.msg == CommonMSG.MSG_WC_EOF: self._set_task_finished() mmm = "WebSocketReader.generate_msg returning commonmsg..." self._log_debug(mmm) print(mmm) return retmsg
def rcvMsg(self, whofrom: base.base_obj, msgdesc: base.MSGdesc_Type, msgdat: typing.Optional[base.MSGdata_Type]) -> None: lverb = True if lverb: # print("{}.rcvMsg: {}: {} from {}".format(self._idstr, msgdesc, msgdat, whofrom._idstr)) print("{}.rcvMsg: {} from {}".format(self._idstr, msgdesc, whofrom._idstr)) if msgdesc == base.MSGD_BUTTON_CLICK: print("wcstatus GOT BUTTON CLICK msgdat={}".format(msgdat)) if msgdat is None: print("msgdat is None") return cmd = msgdat.get("cmd", None) print("wcstatus GOT BUTTON CLICK CMD {}".format(cmd)) if cmd == CMD_LOGOUT: # the logout button was pressed self.send_WS_msg(CommonMSG(CommonMSG.MSG_WC_LOGOUT_TRY, 1)) elif cmd == CMD_TRY_RFID_SERVER: self._check_for_RFID_server() else: print('wcstatus: unrecognised cmd {}'.format(cmd)) return elif msgdesc == base.MSGD_COMMS_ARE_UP: # this happens when the stocky server or RFID server websocket first comes online. # Use it for setting status and some initial data caching. print("COMMS ARE UP: {}".format(whofrom)) if whofrom == self._server_ws: self.set_WS_state(True) self.refresh_locmut_dct() elif whofrom == self._rfid_ws: print("MSG FROM RFID server!!") elif msgdesc == base.MSGD_COMMS_ARE_DOWN: # this happens when the stocky server crashes, taking # the websocket connection with it print("COMMS ARE DOWN: {}".format(whofrom)) if whofrom == self._server_ws: self.set_WS_state(False) elif whofrom == self._rfid_ws: self._rfid_ws = None self.set_RFID_state(RFID_OFF)
def test_wsreader01(self): """The WebSocketReader must behave sensibly when it reads junk from the websocket, and also produce a message on good data. """ rawws = DummyWebsocket(self.sec_interval, None) ws = ServerWebSocket.JSONWebSocket(rawws, self.logger) wsr = Taskmeister.WebSocketReader(self.msgq, self.logger, ws, sec_interval=1.0, do_activate=False) assert wsr is not None, "wsr is None!" ok_dct = {'msg': CommonMSG.MSG_SV_RAND_NUM, 'data': 'dolly'} extra_dct = { 'msg': CommonMSG.MSG_SV_RAND_NUM, 'data': 'dolly', 'extra': 'message' } ok_msg = CommonMSG(ok_dct['msg'], ok_dct['data']) for faulty_data, doraw, exp_val in [({ 'bla': 'blu' }, True, None), ({ 'msg': 'hello' }, True, None), ([1, 2, 3], True, None), (b'[1, 2}', False, None), ({ 'msg': 'hello', 'data': 'dolly' }, True, None), ([1, 2, 3], True, None), (extra_dct, True, ok_msg), (ok_dct, True, ok_msg)]: if doraw: rawws = DummyWebsocket(self.sec_interval, faulty_data) else: rawws = DummyWebsocket(self.sec_interval, None) rawws._set_json_val(faulty_data) ws = ServerWebSocket.JSONWebSocket(rawws, self.logger) wsr.ws = ws retmsg = wsr.generate_msg() print("after sleep exp: {}, got {}".format(exp_val, retmsg))
def send_qai_status(self, upd_dct: typing.Optional[dict]): """Send status information about the server's connection status to the webclient. """ if upd_dct is not None: did_dbreq = True dbreq_ok = upd_dct.get("ok", False) dbreq_msg = upd_dct.get("msg", "no message") else: did_dbreq = False dbreq_ok = True dbreq_msg = "NOTE: No update from QAI database performed." wc_stock_dct = self.stockdb.generate_webclient_stocklist() self.send_ws_msg( CommonMSG( CommonMSG.MSG_SV_STOCK_INFO_RESP, dict(db_stats=self.stockdb.get_db_stats(), upd_time=self.stockdb.get_update_time(), stock_dct=wc_stock_dct, did_dbreq=did_dbreq, dbreq_ok=dbreq_ok, dbreq_msg=dbreq_msg)))
def send_WS_msg(self, msg: CommonMSG) -> None: """Send a message to the server via websocket.""" if self.is_WS_up(): self._server_ws.send(msg.as_dict()) else: print("SEND IS NOOOT HAPPENING")
def generate_msg(self) -> typing.Optional[CommonMSG]: cmdstr = self.cmdlst[self.nmsg] self.nmsg = (self.nmsg + 1) % len(self.cmdlst) return CommonMSG(CommonMSG.MSG_SV_GENERIC_COMMAND, cmdstr) if cmdstr else None
def generate_msg(self) -> typing.Optional[CommonMSG]: return CommonMSG(CommonMSG.MSG_SV_TIMER_TICK, self.msgid)
def generate_msg(self) -> typing.Optional[CommonMSG]: number = round(random.random() * 10, 3) self._log_debug("random: {}".format(number)) return CommonMSG(CommonMSG.MSG_SV_RAND_NUM, number)
def server_handle_msg(self, msg: CommonMSG) -> None: """Handle this message to me, the stocky server Args: msg: the message to handle. """ # self.logger.debug("server handling msg...") print("server handling msg...{}".format(msg)) print("server handling msg...") if msg.msg == CommonMSG.MSG_WC_RADAR_MODE: radar_on = msg.data self.logger.debug("RADAR mode...{}".format(radar_on)) self.timer_tm.set_active(radar_on) elif msg.msg == CommonMSG.MSG_SV_TIMER_TICK: self.logger.debug("server received tick...") # print("MY logger is called '{}'".format(get_logger_name(self.logger))) if self.tls is not None and self.tls.is_in_radarmode(): self.tls.radar_get() elif msg.msg == CommonMSG.MSG_WC_LOGIN_TRY: self.logger.debug("server received LOGIN request...") print("server received LOGIN request...") # try to log in and send back the response u_name = msg.data.get('username', None) p_word = msg.data.get('password', None) if u_name is None or p_word is None: self.logger.debug( "server received a None with LOGIN request...") else: self.logger.debug("LOGIN request data OK...") print("trying login") login_resp = self.qaisession.login_try(u_name, p_word) print("got login resp") # self.sleep(3) if not isinstance(login_resp, dict): raise RuntimeError("fatal login try error") self.send_ws_msg(CommonMSG(CommonMSG.MSG_SV_LOGIN_RES, login_resp)) # dict(ok=False, msg="User unknown", data=msg.data))) elif msg.msg == CommonMSG.MSG_WC_LOGOUT_TRY: # log out and send back response. self.qaisession.logout() log_state = self.qaisession.is_logged_in() self.send_ws_msg( CommonMSG(CommonMSG.MSG_SV_LOGOUT_RES, dict(logstate=log_state))) elif msg.msg == CommonMSG.MSG_WC_STOCK_INFO_REQ: # request about chemstock information do_update = msg.data.get('do_update', False) print("chemstock 1 do_update={}".format(do_update)) upd_dct: typing.Optional[dict] = None if do_update: upd_dct = self.stockdb.update_from_qai() print("update dct {}".format(upd_dct)) print("chemstock 2..") self.send_qai_status(upd_dct) print("chemstock 3") elif msg.msg == CommonMSG.MSG_WC_ADD_STOCK_REQ: # get a string for adding RFID labels to QAI. dct = msg.data rfidstrlst = dct.get('rfids', None) locid = dct.get('location', None) new_stock = dct.get('newstock', False) qai_str = self.qaisession.generate_receive_url( locid, rfidstrlst, new_stock) self.send_ws_msg( CommonMSG(CommonMSG.MSG_SV_ADD_STOCK_RESP, qai_str)) elif msg.msg == CommonMSG.MSG_SV_RFID_STATREP: # print("state change enter") self.handle_rfid_clstatechange(msg.data) # print("state change exit") elif msg.msg == CommonMSG.MSG_SV_FILE_STATE_CHANGE: # print("state change enter") self.handle_rfid_filestatechange(msg.data) # print("state change exit") elif msg.msg == CommonMSG.MSG_WC_LOCATION_INFO: # location change information: save to DB self.stockdb.add_loc_changes(msg.data['locid'], msg.data['locdat']) elif msg.msg == CommonMSG.MSG_WC_LOCMUT_REQ: client_hash = msg.data newhash, rdct = self.stockdb.get_loc_changes(client_hash) self.send_ws_msg( CommonMSG(CommonMSG.MSG_SV_LOCMUT_RESP, dict(data=rdct, hash=newhash))) elif msg.msg == CommonMSG.MSG_WC_DO_LOCMUT_REQ: move_dct = msg.data['locmove'] res = self.stockdb.perform_loc_changes(move_dct) self.send_ws_msg( CommonMSG(CommonMSG.MSG_SV_DO_LOCMUT_RESP, dict(data=res))) self.en_queue( CommonMSG(CommonMSG.MSG_WC_STOCK_INFO_REQ, dict(do_update=True))) self.en_queue( CommonMSG(CommonMSG.MSG_WC_LOCMUT_REQ, dict(data=None))) else: self.logger.error("server not handling message {}".format(msg)) raise RuntimeError("unhandled message {}".format(msg)) # print("--END of server handling msg...{}".format(msg)) print("--END of server handling msg...")
def start_QAI_download(self): """Tell server to start download of QAI data...""" self.send_WS_msg( CommonMSG(CommonMSG.MSG_WC_STOCK_INFO_REQ, dict(do_update=True)))
def rcvMsg(self, whofrom: base.base_obj, msgdesc: base.MSGdesc_Type, msgdat: typing.Optional[base.MSGdata_Type]) -> None: lverb = True if lverb: # print("{}.rcvMsg: {}: {} from {}".format(self._idstr, msgdesc, msgdat, whofrom._idstr)) print("{}.rcvMsg: {} from {}".format(self._idstr, msgdesc, whofrom._idstr)) if msgdesc == base.MSGD_SERVER_MSG: # message from the server. if msgdat is None: print("msgdat is None") return cmd = msgdat.get("msg", None) val = msgdat.get("data", None) if cmd == CommonMSG.MSG_SV_RFID_STATREP and self.wcstatus is not None: print("GOT RFID state {}".format(val)) self.wcstatus.set_RFID_state(val) print("state set OK") elif cmd == CommonMSG.MSG_SV_RFID_ACTIVITY and self.wcstatus is not None: self.wcstatus.set_RFID_state(CommonMSG.RFID_ON) self.wcstatus.set_rfid_activity(val) elif cmd == CommonMSG.MSG_SV_RAND_NUM: # print("GOT number {}".format(val)) newnum = val numlst = self.numlst while len(numlst) >= LST_NUM: numlst.pop(0) numlst.append(newnum) # print("LEN {}".format(len(self.numlst))) # self.showlist() elif cmd == CommonMSG.MSG_RF_RADAR_DATA: self.setradardata(val) elif cmd == CommonMSG.MSG_RF_CMD_RESP: self.sndMsg(base.MSGD_RFID_CLICK, val) elif cmd == CommonMSG.MSG_SV_LOGIN_RES: self.set_login_status(val) elif cmd == CommonMSG.MSG_SV_LOGOUT_RES and self.wcstatus is not None: self.wcstatus.set_logout_status() elif cmd == CommonMSG.MSG_SV_STOCK_INFO_RESP: self.set_qai_update(val) elif cmd == CommonMSG.MSG_SV_ADD_STOCK_RESP: self.addnewstock(val) elif cmd == CommonMSG.MSG_SV_LOCMUT_RESP: rdct, newhash = val['data'], val['hash'] self.set_locmut_update(rdct, newhash) elif cmd == CommonMSG.MSG_SV_SRV_CONFIG_DATA and self.wcstatus is not None: self.wcstatus.set_server_cfg_data(val) else: print("unrecognised server command {}".format(msgdat)) elif msgdesc == base.MSGD_BUTTON_CLICK: print("webclient GOT BUTTON CLICK msgdat={}".format(msgdat)) if msgdat is None: print("msgdat is None") return cmd = msgdat.get("cmd", None) print("webclient GOT BUTTON CLICK CMD {}".format(cmd)) if cmd == "viewswitch": # the switch view does the actual switching on the web client, # but we have to tell the server what 'mode' we are in so that # it can control the RFID reader appropriately. target_view = msgdat.get('target', None) radar_on = target_view == RADAR_VIEW_NAME self.send_WS_msg( CommonMSG(CommonMSG.MSG_WC_RADAR_MODE, radar_on)) if target_view is None: print("target_view is None") return if target_view == CHECK_STOCK_VIEW_NAME: self.send_WS_msg( CommonMSG(CommonMSG.MSG_WC_RADAR_MODE, False)) else: print('unknown view target {}'.format(target_view)) elif cmd == 'roomswitch': print("roomswitch not being handled") # there is no self.lb... # se_ndx, se_val = self.lb.get_selected() # print("showchecklist: got LOCKY VBAL '{}' '{}'".format(se_ndx, se_val)) # self.showchecklist(se_ndx) elif cmd == wcviews.AddNewStockView.GO_ADD_NEW_STOCK or\ cmd == wcviews.AddNewStockView.GO_ADD_NEW_RFIDTAG: # the GO button of add new stock was pressed: # get the selected RFID tags and request an add URL from the server. print("GOT addnewstock GO button!") vv = self.switch.getView(ADDSTOCK_VIEW_NAME) add_info_dct = vv.get_selection_dct() add_info_dct[ 'newstock'] = cmd == wcviews.AddNewStockView.GO_ADD_NEW_STOCK if add_info_dct is not None: self.send_WS_msg( CommonMSG(CommonMSG.MSG_WC_ADD_STOCK_REQ, add_info_dct)) else: print('webclient: unrecognised cmd {}'.format(cmd)) return elif msgdesc == base.MSGD_FORM_SUBMIT: # the login form has sent us a login request. pass this to the server # for verification print("webclient GOT FORM SUBMIT".format(msgdat)) un = msgdat.get('username', None) if msgdat is not None else None pw = msgdat.get('password', None) if msgdat is not None else None dd = {'username': un, 'password': pw} self.send_WS_msg(CommonMSG(CommonMSG.MSG_WC_LOGIN_TRY, dd)) print("OK: sent message") else: print("unhandled message {}".format(msgdesc))
def mainloop(self): """This routine is entered into when the webclient has established a websocket connection to the server. Flask will call this routine with a newly established web socket when the webclient makes a connection via the websocket protocol. .. note:: mainloop is reentrant: we enter here with a new websocket every time the webclient is started or restarted... The general strategy of the mainloop is to initialise all parties concerned, then enter an infinite loop in which messages are taken from the message queue. Some messages are either simply passed on to interested parties, while others are handled as requests by the server itself in :meth:`server_handle_msg` . """ lverb = True is_rfid_scanner = (self.comm_link is not None) print("mainloop begin: is_rfid_server: {}".format(is_rfid_scanner)) self.logger.info("mainloop begin") # start a random generator thread for testing.... # self.randTM = Taskmeister.RandomGenerator(self.msgQ, self.logger) # self.randTM.set_active(True) if is_rfid_scanner: # send the RFID status to the webclient rfid_stat = self.comm_link.get_rfid_state() self.send_ws_msg( CommonMSG(CommonMSG.MSG_SV_RFID_STATREP, rfid_stat)) else: # send the stocky server config data self.send_server_config() # send the QAI update status to the webclient self.send_qai_status(None) do_loop = True while do_loop: if lverb: print("YO: before get") msg: CommonMSG = self.msgQ.get() self.logger.debug("handling msgtype '{}'".format(msg.msg)) if lverb: print("YO: handling msgtype '{}'".format(msg.msg)) # handle a EOF separately if msg.msg == CommonMSG.MSG_WC_EOF: if lverb: print("mainloop detected WS_EOF... quitting") self.ws = None do_loop = False print("step 2") if msg.is_from_rfid_reader(): self.logger.debug("GOT RFID {}".format(msg.as_dict())) self.activate_rfid_spinner() is_handled = False if self.ws is not None and msg.msg in CommonStockyServer.MSG_FOR_WC_SET: is_handled = True # print("sending to WS...") self.send_ws_msg(msg) # print("...OK send") if self.tls is not None and msg.msg in CommonStockyServer.MSG_FOR_RFID_SET: is_handled = True self.tls.send_rfid_msg(msg) if msg.msg in CommonStockyServer.MSG_FOR_ME_SET: print("msg for me: {}".format(msg.msg)) is_handled = True self.server_handle_msg(msg) print("done handling") if not is_handled: mmm = "mainloop DID NOT handle msgtype '{}'".format(msg.msg) self.logger.error(mmm) print(mmm) print("end of ML.while") print("OUT OF LOOP")