Files
appointment_tool/main.py
T
2022-03-14 23:07:46 +01:00

223 lines
6.9 KiB
Python

import datetime
import logging
import re
import sys
import time
from typing import Union
from gsmmodem import GsmModem
import params
from ModemPool import ModemPool
from card_pool import CardPool
from commandor import Commandor
from logs.LogSender import LOG_APPOINTMENT_TIMEOUT, LOG_SUBJECT_EVENT, TYPE_EVENT_RESET_ALL_SIM_CARDS
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 = 60
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 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 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)
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]
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):
logger.info(" [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 read_all_the_phone_number():
params.oracle_log_sender.send_log(msg="SIM卡自检开始", subject=LOG_SUBJECT_EVENT, type=TYPE_EVENT_RESET_ALL_SIM_CARDS)
slot_number = 1
global current_card_pool_slot
slot_sum = 30
# card_pool.switch_to_slot(29)
firebase_store_manager.clear_all_sim_info()
for i in range(slot_number, slot_sum + 1):
card_pool.reset()
logger.info("will switch to " + str(i))
current_card_pool_slot = 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 = 30
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]
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))
start_listen()
start_book()