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 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 = 90 is_finished = False commandor = Commandor() contacts = [] current_gsm_modem = None 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) 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): 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] if date == str(datetime.date.today()): logger.info("this sms is for today") 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 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): 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) firebase_store_manager.clear_all_sim_info() 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 = 1 slot_sum = 29 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 modem in modem_list: 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] if modem.contact: 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)) # read_all_the_phone_number() start_listen() start_book()