import datetime import logging import re import sys import time from typing import Union from gsmmodem import GsmModem from ModemPool import ModemPool from card_pool import CardPool from commandor import Commandor from logs.LogSender import LOG_APPOINTMENT_TIMEOUT, LOG_APPOINTMENT_SUCCESS 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 BAUDRATE = 115200 OTP_TIMEOUT = 70 is_finished = False commandor = Commandor() contacts = [] card_pool = CardPool(CARD_POOL_PORT) def get_devices_ports() -> list: return MODEM_POOL_PORTS def has_sim(ser) -> bool: # check pin cmd_check_pin = "AT+cpin?\r" msg = send_command(cmd_check_pin, ser) if b'OK' in msg: return True else: return False 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) # msg = ser.read(100) print(msg) return msg def get_phone_number(ser): cmd = "AT+CNUM\r" send_command(cmd, ser) def execut_USSD_cmd(cmd, ser): send_command(cmd, ser) def create_modem_for_port(port: str) -> Union[SerialModem, None]: logger.info('Initializing modem... for ' + port) # Uncomment the following line to see what the modem is doing: init_logger() serial_modem = None try: modem = GsmModem(port) # time.sleep(1) # modem.connect() # number = modem.ownNumber # logger.info("The SIM card phone number is:") # logger.info(number) return SerialModem(modem=modem) except Exception as ext: print(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) def start_to_handle_sms(serial_modem: SerialModem): 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) 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 logger.info("try to extract the otp") match = re.search(r'\d{6,8}', 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 def select_sim_storage(ser) -> bool: # use SIM Card storage cmd_sm = "AT+CPBS=\"SM\"\r" result = send_command(cmd_sm, ser) if "ERROR" in str(result): return False else: return True 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): logger.info(" [x] Received {} {}".format(body, datetime.datetime.now())) # parse the received message result = ReserveResultPojo.from_json(body) print(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 read_all_the_phone_number(): slot_number = 1 slot_sum = 31 # card_pool.switch_to_slot(3) for i in range(slot_number, slot_sum + 1): card_pool.reset() print("will switch to " + str(i)) card_pool.switch_to_slot(i) modem_pool = ModemPool(get_devices_ports()) modem_pool.reset_all_modems() modem_pool.get_raw_phone_number(i) def start_book(): slot_number = 12 slot_sum = 31 for i in range(slot_number, slot_sum + 1): card_pool.reset() print("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() for index, modem in modem_list: # get contact for current modem modem.get_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] if modem.contact: commandor.start_page(modem.contact) start_to_handle_sms(modem) if __name__ == '__main__': init_logger() logger = logging.getLogger() logger.addHandler(logging.StreamHandler(stream=sys.stdout)) # read_all_the_phone_number() start_listen() start_book()