mise a jour des sources et ajout du serveur socket AF_UNIX

This commit is contained in:
Vincent BENOIT
2022-11-08 08:46:33 +01:00
parent 2895819b1e
commit 31ac0da5b1
+218 -154
View File
@@ -36,7 +36,7 @@ def get_conf(logger=None):
config = None config = None
try: try:
with open(os.path.join("/home/pi/KineIntercom/src", "KineIntercom.json"), 'r') as f: with open(os.path.join("/etc/kineintercom", "db.json"), 'r') as f:
try: try:
config = json.load(f) config = json.load(f)
except json.decoder.JSONDecodeError as e: except json.decoder.JSONDecodeError as e:
@@ -96,12 +96,12 @@ def send_at_cmd(cmd='', timeout=0.0, serObj=None, logger=None):
out += c out += c
logger.debug("Reponse: {}".format(outlst)) logger.debug("Reponse: {}".format(outlst))
if 'OK' in outlst: if 'OK' in outlst:
return 0 return 0, outlst
elif 'ERROR' in outlst: elif 'ERROR' in outlst:
logger.error("Error with cmd : {}".format(cmd)) logger.error("Error with cmd : {}".format(cmd))
return 2 return 2, None
else: else:
return 1 return 1, None
except Exception as e: except Exception as e:
logger.error("Error: {}".format(e)) logger.error("Error: {}".format(e))
return 2 return 2
@@ -150,7 +150,34 @@ def init_gsm_com(serObj=None, config=None, logger=None):
'AT+CLIP=1', 'AT+CLIP=1',
'AT+VTD='+str(config['DTMF_DURATION'])] 'AT+VTD='+str(config['DTMF_DURATION'])]
for cmd in cmd_lst: for cmd in cmd_lst:
ret = send_at_cmd(cmd=cmd, timeout=0.0, serObj=serObj, logger=logger) ret, _ = send_at_cmd(cmd=cmd, timeout=0.0, serObj=serObj, logger=logger)
if ret == 2:
logger.error("Erreur avec la commande AT: {}".format(cmd))
return False
elif ret == 1:
lgger.warning("Timeout avec la commande AT: {}".format(cmd))
return True
def info_gsm_com(serObj=None, config=None, logger=None):
''' Retreive GSM Module info
'''
if not isinstance(serObj, serial.serialposix.Serial):
logger.error("error parameter, expecting serial.serialposix.Serial, get {}".format(type(serObj)))
return False
if not isinstance(logger, log.Logger):
logger.error("error parameter, expecting logging.Logger, get {}".format(type(logger)))
return False
cmd_lst = ['AT+CGMI',
'AT+CGMM',
'AT+CGMR',
'AT+COPS?',
'AT+CSMINS?',
'AT+CSPN?',
'AT+CGSN',
'AT+CCALR?']
for cmd in cmd_lst:
ret, rsp = send_at_cmd(cmd=cmd, timeout=0.0, serObj=serObj, logger=logger)
if ret == 2: if ret == 2:
logger.error("Erreur avec la commande AT: {}".format(cmd)) logger.error("Erreur avec la commande AT: {}".format(cmd))
return False return False
@@ -188,7 +215,7 @@ def verify_caller(buf="", num="", logger=None):
outlst = buf[7:].split(',') outlst = buf[7:].split(',')
logger.debug("=> {}".format(outlst)) logger.debug("=> {}".format(outlst))
phone_number = outlst[0].replace("\"","") phone_number = outlst[0].replace("\"","")
if phone_number != num: if not phone_number.endswith(num):
logger.warning("phone number not match ! {}/{}".format(phone_number, num)) logger.warning("phone number not match ! {}/{}".format(phone_number, num))
return False, phone_number return False, phone_number
return True, phone_number return True, phone_number
@@ -196,21 +223,37 @@ def verify_caller(buf="", num="", logger=None):
def listener(sock, logger): def listener(sock, logger):
''' Thread socket listener ''' Thread socket listener
''' '''
logger.debug("Démarrage du serveur de communication avec le service horaire")
global FLAG_CONF_UPDATE
global FLAG_HORAIRE_UPDATE
flag = True
logger.debug("Démarrage du serveur de communication avec le backend du configurateur")
while True: while True:
# Wait for a connection # Wait for a connection
try: try:
clientsocket, address = sock.accept() clientsocket, address = sock.accept()
flag = True
logger.debug("Client connecté {}".format(clientsocket))
except socket.timeout: except socket.timeout:
continue continue
# socket recv() will block for a maximum of 1 sec. # socket recv() will block for a maximum of 1 sec.
#clientsocket.settimeout(1) #clientsocket.settimeout(1)
data = b''
while clientsocket: while clientsocket:
while True: while flag:
try: try:
data = clientsocket.recv(1) data += clientsocket.recv(1)
except Error as e: if data.decode('utf-8').endswith('\n'):
if data.decode('utf-8').startswith('RELOAD_DB'):
logger.debug("==> RELOAD DB")
FLAG_CONF_UPDATE = True
elif data.decode('utf-8').startswith('RELOAD_HOURS'):
FLAG_CONF_UPDATE = True
FLAG_HORAIRE_UPDATE = True
clientsocket = None
flag = False
except:
continue continue
if not data: if not data:
break break
@@ -234,66 +277,79 @@ def verify_open_hours(conf=None, logger=None):
my_date = date.today() my_date = date.today()
day = calendar.day_name[my_date.weekday()] day = calendar.day_name[my_date.weekday()]
now = datetime.now() now = datetime.now()
for k,v in conf[day].items(): for item in conf[day]:
time_conf = int(k.split('h')[0])*60 + int(k.split('h')[1]) time_conf = int(item['name'].split('h')[0])*60 + int(item['name'].split('h')[1])
current_time = now.hour*60 + now.minute current_time = now.hour*60 + now.minute
if current_time >= time_conf: if current_time >= time_conf:
if v == 1: if item['state'] == 1:
flag = True flag = True
elif v == 0: elif item['state'] == 0:
flag = False flag = False
logger.debug('Jour: {} - Temps courant: {} - Ouverture: {}'.format(day, now.strftime('%Hh%M'), flag)) logger.debug('Jour: {} - Temps courant: {} - Ouverture: {}'.format(day, now.strftime('%Hh%M'), flag))
return flag return flag
def init_module(): def init_module():
''' initialisation of GNSS/GPS/GSM HAT Module ''' initialisation of GNSS/GPS/GSM HAT Module
''' '''
GPIO.setwarnings(False) try:
GPIO.setmode(GPIO.BOARD) GPIO.setmode(GPIO.BOARD)
GPIO.setup(7, GPIO.OUT) GPIO.setwarnings(False)
return GPIO.setup(7, GPIO.OUT)
except ValueError as e:
return False
return True
def setup_module(): def setup_module():
''' Setup module (Set/Reset) ''' Setup module (Set/Reset)
''' '''
while True: while True:
GPIO.output(7, GPIO.LOW) try:
time.sleep(2) GPIO.output(7, GPIO.LOW)
GPIO.output(7, GPIO.HIGH) time.sleep(2)
GPIO.output(7, GPIO.HIGH)
except ValueError as e:
return False
break break
GPIO.cleanup() #GPIO.cleanup()
return True
def cron_verify_hours(config=None, logger=None): def cron_verify_hours(op=None, config=None, logger=None):
''' cron task ''' cron job to check opened or closed hours
''' '''
global GSM_MODULE_STATE global GSM_MODULE_STATE
global GSM_MODULE_INIT_STATE global GSM_MODULE_INIT_STATE
# Verify hours with conf file if op == 'Horaires':
opened = verify_open_hours(conf=config, logger=logger) # Verify hours with conf file
opened = verify_open_hours(conf=config, logger=logger)
elif op == 'Manuel ON':
opened = True
elif op == 'Manuel OFF':
opened = False
else:
logger.error("Wrong 'OPERATION' parameter in database")
if opened: if opened:
# Si le module GSM doit être allumé et qu'il est éteint, on l'allume # Si le module GSM doit être allumé et qu'il est éteint, on l'allume
if not GSM_MODULE_STATE: if not GSM_MODULE_STATE:
logger.info("Allumage du module GSM HAT ...") logger.info("Allumage du module GSM HAT ...")
init_module() if not setup_module():
setup_module() logger.error('Erreur d\'allumage du module GSM')
GSM_MODULE_STATE = True else:
GSM_MODULE_INIT_STATE = False GSM_MODULE_STATE = True
GSM_MODULE_INIT_STATE = False
else: else:
# Si le module GSM doit être éteint et qu'il est allumé, on l'eteint # Si le module GSM doit être éteint et qu'il est allumé, on l'eteint
if GSM_MODULE_STATE: if GSM_MODULE_STATE:
logger.debug("Fermeture du module GSM HAT ...") logger.debug("Fermeture du module GSM HAT ...")
init_module() if not setup_module():
setup_module() logger.error('Erreur de fermeture du module GSM')
GSM_MODULE_STATE = False else:
GSM_MODULE_INIT_STATE = False GSM_MODULE_STATE = False
GSM_MODULE_INIT_STATE = False
def sigint_handler(signal, frame):
''' SIGINT handler function
'''
sys.exit(0)
def process(buf="", config=None, ser=None, logger=None): def process(buf="", config=None, ser=None, logger=None):
''' ''' run process
''' '''
if not isinstance(logger, log.Logger): if not isinstance(logger, log.Logger):
return False return False
@@ -312,20 +368,20 @@ def process(buf="", config=None, ser=None, logger=None):
ret, phone_number = verify_caller(buf=buf, num=config['NUM_AUTORISE'], logger=logger) ret, phone_number = verify_caller(buf=buf, num=config['NUM_AUTORISE'], logger=logger)
if not ret: if not ret:
# Disconnect connexion # Disconnect connexion
ret = send_at_cmd(cmd="ATH", timeout=0.0, serObj=ser, logger=logger) ret, _ = send_at_cmd(cmd="ATH", timeout=0.0, serObj=ser, logger=logger)
logger.warning("Phone number not authorized : {}".format(phone_number)) logger.warning("Phone number not authorized : {}".format(phone_number))
else: else:
logger.debug("Phone number authorized ...") logger.debug("Phone number authorized ...")
time.sleep(0.3) time.sleep(0.3)
# connect # connect
ret = send_at_cmd(cmd='ATA', timeout=0.0, serObj=ser, logger=logger) ret, _ = send_at_cmd(cmd='ATA', timeout=0.0, serObj=ser, logger=logger)
if ret == 0: if ret == 0:
time.sleep(0.2) time.sleep(0.2)
# send DMTF tone # send DMTF tone
send_at_cmd(cmd='AT+VTS='+config['DTMF_CODE'], timeout=0.0, serObj=ser, logger=logger) send_at_cmd(cmd='AT+VTS='+config['DTMF_CODE'], timeout=0.0, serObj=ser, logger=logger)
time.sleep(0.5) time.sleep(config['TONE_DURATION'])
# Disconnect # Disconnect
ret = send_at_cmd(cmd='ATH', timeout=0.0, serObj=ser, logger=logger) ret, _ = send_at_cmd(cmd='ATH', timeout=0.0, serObj=ser, logger=logger)
if ret > 0: if ret > 0:
logger.error('Cannot disconnect ...') logger.error('Cannot disconnect ...')
else: else:
@@ -337,6 +393,8 @@ def process(buf="", config=None, ser=None, logger=None):
GSM_MODULE_STATE = False GSM_MODULE_STATE = False
GSM_MODULE_INIT_STATE = False GSM_MODULE_INIT_STATE = False
FLAG_CONF_UPDATE = False
FLAG_HORAIRE_UPDATE = False
def main(): def main():
''' main function ''' main function
@@ -352,19 +410,20 @@ def main():
global GSM_MODULE_STATE global GSM_MODULE_STATE
global GSM_MODULE_INIT_STATE global GSM_MODULE_INIT_STATE
global FLAG_CONF_UPDATE
# Caught Keyboard interrupt global FLAG_HORAIRE_UPDATE
signal(SIGINT, sigint_handler)
# Configuration loader # Configuration loader
config = get_conf(logger) config = get_conf(logger)
if not config: if not config:
logger.error("Impossible de charger la configuration") logger.error("Impossible de charger la configuration")
exit(1) sys.exit(1)
# init GSM HAT module # init GSM HAT module
logger.info("Initialisation du module GSM HAT ...") logger.info("Initialisation du module GSM HAT ...")
init_module() if not init_module():
logger.error("Impossible d'initialiser les GPIO de la board")
sys.exit(1)
# Serial configuration # Serial configuration
ser = serial.Serial('/dev/ttyAMA0', ser = serial.Serial('/dev/ttyAMA0',
@@ -383,7 +442,8 @@ def main():
try: try:
ser.flushInput() #flush input buffer, discarding all its contents ser.flushInput() #flush input buffer, discarding all its contents
ser.flushOutput() #flush output buffer, aborting current output ser.flushOutput() #flush output buffer, aborting current output
ret = send_at_cmd(cmd='AT', timeout=0.5, serObj=ser, logger=logger) # send AT command to test the connection
ret, _ = send_at_cmd(cmd='AT', timeout=0.5, serObj=ser, logger=logger)
if ret == 2: if ret == 2:
logger.error("Erreur d'envoie de la commande AT") logger.error("Erreur d'envoie de la commande AT")
elif ret == 1: elif ret == 1:
@@ -398,136 +458,140 @@ def main():
logger.error("Impossible d'ouvrir le port série") logger.error("Impossible d'ouvrir le port série")
sys.exit(1) sys.exit(1)
# Verify if open or not # Verify if the GSM module must be opened or not
opened = verify_open_hours(conf=config['HORAIRES'], logger=logger) if config['OPERATION'] == 'Horaires':
opened = verify_open_hours(conf=config['HORAIRES'], logger=logger)
elif config['OPERATION'] == 'Manuel ON':
opened = True
elif config['OPERATION'] == 'Manuel OFF':
opened = False
else:
logger.error("Wrong 'OPERATION' parameter in database")
ser.close()
sys.exit(1)
if opened: if opened:
# Si le module GSM doit être allumé et qu'il est éteint, on l'allume # Si le module GSM doit être allumé et qu'il est éteint, on l'allume
if not GSM_MODULE_STATE: if not GSM_MODULE_STATE:
logger.info("Allumage du module GSM HAT ...") logger.info("Allumage du module GSM HAT ...")
setup_module() if not setup_module():
GSM_MODULE_STATE = True logger.error("Erreur de configuration des GPIOs de la board")
# Attente de 10 secondes avant d'initier l'init GSM
time.sleep(10)
# Initialize GSM communication
ret = init_gsm_com(serObj=ser, config=config, logger=logger)
if not ret:
logger.error("Erreur d'initialisation de la com GSM avec le module")
ser.close() ser.close()
sys.exit(1) sys.exit(1)
else: else:
GSM_MODULE_INIT_STATE = True GSM_MODULE_STATE = True
# Attente de 10 secondes avant d'initier l'init GSM
time.sleep(10)
# Initialize GSM communication
logger.info("Initialisation des commandes AT nécessaires ...")
ret = init_gsm_com(serObj=ser, config=config, logger=logger)
if not ret:
logger.error("Erreur d'initialisation de la com GSM avec le module")
ser.close()
sys.exit(1)
else:
GSM_MODULE_INIT_STATE = True
# Retreive GSM infos
logger.info('Récupération des infos du module ...')
ret = info_gsm_com(serObj=ser, config=config, logger=logger)
if not ret:
logger.error("Erreur d'initialisation de la com GSM avec le module")
ser.close()
sys.exit(1)
else: else:
# Si le module GSM doit être éteint et qu'il est allumé, on l'eteint # Si le module GSM doit être éteint et qu'il est allumé, on l'eteint
if GSM_MODULE_STATE: if GSM_MODULE_STATE:
logger.debug("Fermeture du module GSM HAT ...") logger.debug("Fermeture du module GSM HAT ...")
setup_module() if not setup_module():
GSM_MODULE_STATE = False logger.error("Erreur de configuration des GPIOs de la board")
GSM_MODULE_INIT_STATE = False ser.close()
sys.exit(1)
else:
GSM_MODULE_STATE = False
GSM_MODULE_INIT_STATE = False
# server_addr = "/tmp/uds_socket" server_addr = "/tmp/uds_socket"
# # Make sure the socket does not already exist # Make sure the socket does not already exist
# try: try:
# os.unlink(server_addr) os.unlink(server_addr)
# except OSError: except OSError:
# if os.path.exists(server_addr): if os.path.exists(server_addr):
# raise raise
#
# # Create UDS socket # Create UDS socket
# sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
# # Bind the socket to the port # Bind the socket to the port
# sock.bind(server_addr) sock.bind(server_addr)
# # Listen for incoming connections # Listen for incoming connections
# sock.listen(1) sock.listen(1)
# thread = Thread(target=listener, args=(sock, logger,)) thread = Thread(target=listener, args=(sock, logger,))
# thread.start() thread.start()
# time.sleep(1) time.sleep(1)
# Scheduler opened hours # Scheduler opened hours
sched = BackgroundScheduler(daemon=True) sched = BackgroundScheduler(daemon=True)
sched.add_job(func=cron_verify_hours, sched.add_job(func=cron_verify_hours,
args=(config['HORAIRES'], logger), args=(config['OPERATION'], config['HORAIRES'], logger),
trigger='cron', trigger='cron',
minute='*', minute='*',
id="task_verify_hours") id="job_id")
sched.start() sched.start()
out = '' out = ''
while True: try:
# Si le module GSM est ouvert while True:
if GSM_MODULE_STATE: if FLAG_CONF_UPDATE:
if not GSM_MODULE_INIT_STATE: logger.info("Configuration must be reloaded ...")
time.sleep(5) # reload conf in memory
# Initialize GSM serial communication config = get_conf(logger)
ret = init_gsm_com(serObj=ser, config=config, logger=logger) if FLAG_HORAIRE_UPDATE:
if not ret: logger.info("Restart scheduler ...")
logger.error("Erreur d'initialisation de la com GSM avec le module") # Stop job scheduler to restart it
sched.remove_job('job_id')
sched.add_job(func=cron_verify_hours,
args=(config['OPERATION'], config['HORAIRES'], logger),
trigger='cron',
minute='*',
id="job_id")
FLAG_HORAIRE_UPDATE = False
FLAG_CONF_UPDATE = False
# Si le module GSM est ouvert
if GSM_MODULE_STATE:
# Si le module GSM n'a pas été initialisé
if not GSM_MODULE_INIT_STATE:
# Attente de 10sec pour que le module accroche le signal après allumage
time.sleep(10)
# Initialize GSM serial communication
ret = init_gsm_com(serObj=ser, config=config, logger=logger)
if not ret:
logger.error("Erreur d'initialisation de la com GSM avec le module")
break
else:
GSM_MODULE_INIT_STATE = True
# While the number of bytes in the input buffer > 0
if ser.in_waiting > 0:
# remove \r and \n chars from out string
out += ser.read_until().decode('utf-8').replace('\r','').replace('\n','')
if len(out) > 0 :
logger.debug("out: {}".format(out))
time.sleep(.1)
ret = process(buf=out, config=config, ser=ser, logger=logger)
if not ret:
break
out = ''
else: else:
GSM_MODULE_INIT_STATE = True time.sleep(1)
else:
# While the number of bytes in the input buffer > 0 time.sleep(1)
while ser.in_waiting > 0: except KeyboardInterrupt:
# remove \r and \n chars from out string logger.error("Keyboard Interrupt !!")
out += ser.read_until().decode('utf-8').replace('\r','').replace('\n','')
if len(out) > 0 :
logger.debug("out: {}".format(out))
time.sleep(.1)
ret = process(buf=out, config=config, ser=ser, logger=logger)
out = ''
else:
time.sleep(10)
# if ser.isOpen():
# logger.info("Le port de communication avec le module GSM est ouvert")
# try:
# ser.flushInput() #flush input buffer, discarding all its contents
# ser.flushOutput() #flush output buffer, aborting current output
# if GSM_MODULE_STATE:
# # Initialize GSM communication
# ret = init_gsm_com(serObj=ser, config=config, logger=logger)
# if not ret:
# logger.error("Erreur d'initialisation de la communication avec le module GSM")
# return
# out = ''
# while True:
# # While the number of bytes in the input buffer > 0
# while ser.in_waiting > 0:
# # remove \r and \n chars from out string
# out += ser.read_until().decode('utf-8').replace('\r','').replace('\n','')
# if len(out) > 0 :
# logger.debug("out: {}".format(out))
# time.sleep(.1)
# if out.startswith('+CLIP: '):
# # Verify date and time
# ret = verify_open_hours(conf=config['HORAIRES'], log=logger)
# # Verify caller phone number
# ret, phone_number = verify_caller(buf=out, num=config['NUM_AUTORISE'], log=logger)
# if not ret:
# # Disconnect connexion
# send_at_cmd(cmd="ATH", serObj=ser, logger=logger)
# logger.warning("Phone number not authorized : {}".format(phone_number))
# else:
# logger.debug("Phone number authorized ...")
# time.sleep(0.3)
# # connect
# ret = send_at_cmd(cmd='ATA', serObj=ser, logger=logger)
# if ret:
# time.sleep(0.2)
# # send DMTF tone
# send_at_cmd(cmd='AT+VTS='+config['DTMF_CODE'], serObj=ser, logger=logger)
# time.sleep(0.5)
# # Disconnect
# ret = send_at_cmd(cmd='ATH', serObj=ser, logger=logger)
# if not ret:
# logger.error('Cannot disconnect ...')
# out = ''
# except Exception as e:
# logger.error("error communicating: {}".format(e))
# else:
# logger.error("cannot open serial port")
logger.info("fermeture du port de communication avec le GNSS_HAT") logger.info("fermeture du port de communication avec le GNSS_HAT")
ser.close() ser.close()
sched.shutdown(wait=False) sched.shutdown(wait=False)
thread.join()
if __name__ == '__main__': if __name__ == '__main__':
main() main()