import datetime import logging import re import sys import time from typing import Union from gsmmodem import GsmModem import params from modems.ModemPool import ModemPool from modems.card_pool import CardPool from commandor import Commandor from logs.LogSender import LOG_APPOINTMENT_TIMEOUT, LOG_SUBJECT_EVENT, TYPE_EVENT_RESET_ALL_SIM_CARDS, LOG_SUBJECT_SMS, \ TYPE_SMS_RECEIVED from params import MODEM_POOL_PORTS, CARD_POOL_PORT, firebase_store_manager, oracle_log_sender from pojo.ReserveResultPojo import ReserveResultPojo from utils.excel_reader import ExcelHelper from pojo.serial_modem import SerialModem from logs.AppLogging import init_logger from utils.message_receiver import MessageReceiver OTP_TIMEOUT = 600 is_finished = False commandor = Commandor() contacts = [] current_gsm_modem = None card_pool = CardPool(CARD_POOL_PORT) # used to save the current slot position current_card_pool_slot = 1 current_sim_position = 1 def get_devices_ports() -> list: return MODEM_POOL_PORTS def send_command(cmd: str, ser, wait_time_in_s: int = 0) -> bytes: ser.write(cmd.encode()) msg = ser.read(100) count = 0 while 'OK' not in str(msg) and count < wait_time_in_s: time.sleep(1) count = count + 1 msg = ser.read(100) print(msg) return msg def create_modem_for_port(port: str) -> Union[SerialModem, None]: logger.info('Initializing modem... for ' + port) serial_modem = None try: modem = GsmModem(port) return SerialModem(modem=modem) except Exception as ext: logger.error(ext) return serial_modem def timeout_occurred(serial_modem: SerialModem): firebase_store_manager.save_timeout_contact(serial_modem.contact) oracle_log_sender.send_log(str(serial_modem.phone_number), type=LOG_APPOINTMENT_TIMEOUT) logger.info("will close timeout modem") serial_modem.modem.close() commandor.reset_air_plan_mode() def start_to_handle_sms(serial_modem: SerialModem): global current_gsm_modem current_gsm_modem = serial_modem.modem serial_modem.modem.smsReceivedCallback = handle_sms global is_finished is_finished = False serial_modem.modem.smsTextMode = False logger.info('Waiting for SMS message, for phone number ' + str(serial_modem.phone_number)) listen_at = time.time() while not is_finished: time.sleep(2) # check whether timeout now = time.time() if (listen_at + OTP_TIMEOUT) < now: logger.info("time out for {}, switch to next contact".format(serial_modem.phone_number)) # save the contact in timeout timeout_occurred(serial_modem) current_gsm_modem.close() return return def handle_sms(sms): logger.info( u'== SMS message received ==\nFrom: {0}\nTime: {1}\nMessage:\n{2}\n'.format(sms.number, sms.time, sms.text)) # extract the otp number date = str(sms.time)[0:10] msg = "phone:{}, sms:{}".format(sms.number, sms.text) params.oracle_log_sender.send_log(msg=msg, subject=LOG_SUBJECT_SMS, type=TYPE_SMS_RECEIVED) if date == str(datetime.date.today()): logger.info("this sms is for today") if "rendez-vous" in sms.text: logger.info("try to extract the otp") pattern = r'\d{6,8}' # if re.match(pattern, sms.text): match = re.search(pattern, sms.text) otp = match.group(0) logger.info("otp is " + otp) commandor.send_otp(otp) # wait for the sms for 20 seconds global is_finished while not is_finished: time.sleep(2) is_finished = True global current_gsm_modem if current_gsm_modem: logger.info("will close used modem") current_gsm_modem.close() else: logger.info("The sms is not for RDV") else: logger.info("The sms is not for today") def init_modems() -> list: modems = [] for port in get_devices_ports(): serial_modem = create_modem_for_port(port) if serial_modem: modems.append(serial_modem) return modems def on_message_received(ch, method, properties, body): print(str(body)) print(" [x] Received {} {}".format(body, datetime.datetime.now())) # parse the received message result = ReserveResultPojo.from_json(body) result.sim_position = current_sim_position result.slot_position = current_card_pool_slot logger.info(result) firebase_store_manager.save(result) oracle_log_sender.send_appoint_result(result) # set the flag to True global is_finished is_finished = True def start_listen(): logger.info("start to listen to message queue") receiver = MessageReceiver() receiver.start_listener(on_message_received) def start_book(): slot_number = 1 slot_sum = 22 for i in range(slot_number, slot_sum + 1): card_pool.reset() logger.info("will switch to " + str(i)) card_pool.switch_to_slot(i) modem_pool = ModemPool(get_devices_ports()) modem_pool.reset_all_modems() modem_list = init_modems() # create listeners for chaque modem # read the contact, and contact the 2 objects together excel_reader = ExcelHelper() global contacts contacts = excel_reader.read_contacts() global current_sim_position current_sim_position = 1 for modem in modem_list: current_sim_position = current_sim_position + 1 try: # get contact for current modem modem.get_ccid() # find the contact with ccid contact = [contact for contact in contacts if contact.ccid == modem.ccid] if len(contact) > 0: modem.phone_number = contact[0].phone modem.contact = contact[0] else: logger.info("contact not found for this ccid") modem.modem.close() continue if modem.contact: logger.info("contact found for this ccid") signal = modem.modem.signalStrength logger.info("信号强度: " + str(signal)) commandor.start_page(modem.contact) start_to_handle_sms(modem) except Exception as error: print(error) continue if __name__ == '__main__': init_logger() logger = logging.getLogger() logger.addHandler(logging.StreamHandler(stream=sys.stdout)) start_listen() start_book() # card_pool.switch_to_slot(12)