copie d'une base de données vierge et conforme si elle n'existe pas

This commit is contained in:
Vincent BENOIT
2022-11-15 11:06:04 +01:00
parent 5de4445de7
commit 5ea494e645

View File

@@ -3,7 +3,7 @@
# @author: benoit.vince84@free.fr
# @date: Septembre 2022
# @brief: Programme Intercom à partir du module GSM du GNSS_HAT
# @brief: Programme Intercom à partir du module GSM
###################################################################
# Importation de modules externes #
@@ -16,8 +16,9 @@ import RPi.GPIO as GPIO
from datetime import datetime, date
import calendar
import json
from jsonschema import validate
import jsonschema
import socket
import shutil
from signal import signal, SIGINT
from threading import Thread
from apscheduler.schedulers.background import BackgroundScheduler
@@ -26,54 +27,65 @@ from apscheduler.schedulers.background import BackgroundScheduler
# Class et Methods #
def validate_json(json_data={}, logger=None):
''' Validate json by schema
''' Validate json database by schema
:param json_data:
json data loaded
:param logger:
werkzeug context
logger object
:return int:
0 => If validates with 2.0
1 => otherwise
:return bool:
True if OK, otherwise False
'''
if not isinstance(logger, log.Logger):
return False
if not isinstance(json_data, dict):
logger.error("error parameter, expecting dict, get {}".format(type(json_data)))
return False
if not isinstance(logger, log.Logger):
logger.error("error parameter, expecting logging.Logger, get {}".format(type(logger)))
return False
ret = True
try:
with open(os.path.join('/home/pi', 'db.json.schema'), 'r') as f:
schema=json.load(f)
try:
validate(instance=json_data, schema=schema)
except jsonschema.exceptions.ValidationError as e:
logger.error("Validator error")
ret = False
except jsonschema.exceptions.SchemaError as e:
logger.error("Schema error")
ret = False
except FileNotFoundError as e:
logger.error("Impossible d'ouvrir le fichier de validation ({})".format(e))
ret = False
try:
jsonschema.validate(instance=json_data, schema=schema)
except jsonschema.exceptions.ValidationError as e:
logger.error("Erreur de validation de la base de données : {}".format(e))
ret = False
except jsonschema.exceptions.SchemaError as e:
logger.error("Erreur de schéma : {}".format(e))
ret = False
return ret
def get_conf(logger=None):
''' Get configuration
:param logger:
logger object
:return dict:
Configuration dictionnary
'''
if not isinstance(logger, log.Logger):
logger.error("error parameter, expecting logging.Logger, get {}".format(type(logger)))
return None
config = None
# copy database if not exists
if not os.path.exists(os.path.join("/etc/kineintercom", "db.json")):
logger.warning("Le fichier de la base de données n'existe pas ...")
try:
shutil.copyfile(os.path.join("/usr/share/kineintercom", "database_origin.json"),
os.path.join("/etc/kineintercom", "db.json"))
except PermissionError as e:
logger.error("Erreur de permission: {}".format(e))
return None
try:
with open(os.path.join("/etc/kineintercom", "db.json"), 'r') as f:
try:
@@ -100,7 +112,7 @@ def send_at_cmd(cmd='', timeout=0.0, serObj=None, logger=None):
:param serObj:
serial object
:param log:
:param logger:
logger object
:return int:
@@ -121,7 +133,7 @@ def send_at_cmd(cmd='', timeout=0.0, serObj=None, logger=None):
try:
if timeout > 0.0:
serObj.timeout = timeout
serObj.timeout = timeout + 0.1
else:
serObj.timeout = None
serObj.write(bytes(cmd+'\r', 'utf-8'))
@@ -129,19 +141,12 @@ def send_at_cmd(cmd='', timeout=0.0, serObj=None, logger=None):
out = ''
outlst = []
while serObj.in_waiting > 0:
#c = serObj.read(1).decode('utf-8', 'replace')
#if c == '\r' or c == '\n':
# if out != '':
# outlst.append(out)
# out = ''
#else:
# out += c
# remove \r and \n chars from out string
out += serObj.read_until().decode('utf-8', 'replace').replace('\r','').replace('\n','')
if out != '':
outlst.append(out)
out = ''
time.sleep(timeout)
logger.debug("Reponse: {}".format(outlst))
if 'OK' in outlst:
return 0, outlst
@@ -162,16 +167,23 @@ def send_at_cmd(cmd='', timeout=0.0, serObj=None, logger=None):
def set_sim_pin(serObj=None, pin_actif=False, code_pin="", logger=None):
''' Set SIM PIN if necessary
AT+CPIN=<CODE PIN> : Enter PIN (response READY: MT is not pending for any password)
:param serObj:
serial object
:param config:
dictionary config object from JSON database
:param pin_actif:
attribute from dictionary config object
:param code_pin:
attribute from dictionary config object
:param log:
logger object
:return bool:
True if OK, otherwise False
'''
if not isinstance(logger, log.Logger):
return False
@@ -196,28 +208,30 @@ def set_sim_pin(serObj=None, pin_actif=False, code_pin="", logger=None):
elif ret == 1:
logger.warning("Timeout avec la commande AT: {}".format('AT+CPIN?'))
else:
if rsp[1].split('+CPIN: ')[1] == 'SIM PIN':
logger.info('SIM verrouillée ...')
# Must enter SIM PIN
if not pin_actif:
logger.error("Configuration en conflit avec la réponse du module GSM")
return False
else:
# Enter the SIM PIN configured in database
ret, rsp = send_at_cmd(cmd='AT+CPIN='+code_pin,
timeout=0.0,
serObj=serObj,
logger=logger)
if ret == 2:
logger.error("Erreur avec la commande AT: {}".format('AT+CPIN=<CODE_PIN>'))
return False
elif ret == 1:
logger.warning("Timeout avec la commande AT: {}".format('AT+CPIN=<CODE_PIN>'))
else:
logger.info("code PIN saisi ...")
elif rsp[1].split('+CPIN: ')[1] == 'READY':
# SIM PIN already notified
logger.info('SIM déverrouillée ...')
for item in rsp:
if item.startswith('+CPIN:'):
if item.split('+CPIN: ')[1] == 'SIM PIN':
logger.info('SIM verrouillée ...')
# Must enter SIM PIN
if not pin_actif:
logger.error("Configuration en conflit avec la réponse du module GSM")
return False
else:
# Enter the SIM PIN configured in database
ret, _ = send_at_cmd(cmd='AT+CPIN='+code_pin,
timeout=2.0,
serObj=serObj,
logger=logger)
if ret == 2:
logger.error("Erreur avec la commande AT: {}".format('AT+CPIN=<CODE_PIN>'))
return False
elif ret == 1:
logger.warning("Timeout avec la commande AT: {}".format('AT+CPIN=<CODE_PIN>'))
else:
logger.info("code PIN validé ...")
elif item.split('+CPIN: ')[1] == 'READY':
# SIM PIN already notified
logger.info('SIM déverrouillée ...')
return True
@@ -227,15 +241,11 @@ def init_gsm_com(serObj=None, config={}, logger=None):
AT : test command
ATE1 :
AT+CMEE=2 :
AT+CPIN? : Enter PIN (response READY: MT is not pending for any password
AT+CREG? : Network registration - return the status of result code
AT+CSQ :
AT+CLTS=1 :
AT+CMGF=1 : Set the format of messages to Text mode
AT+CLIP=1 : The calling line identifty (CLI) of calling party when
receiving a mobile terminated call
AT+VTD=1 : Tone Duration (in 1/10 seconds)
ATS0=2 : Set Number of Ring before Automatically Answering the call
:param serObj:
serial object
@@ -247,6 +257,7 @@ def init_gsm_com(serObj=None, config={}, logger=None):
logger object
:return bool:
True if OK, otherwise False
'''
if not isinstance(logger, log.Logger):
return False
@@ -288,11 +299,11 @@ def update_gsm_com(serObj=None, config={}, logger=None):
:param config:
dictionary config object from JSON database
:param log:
:param logger:
logger object
:return bool:
True if ok, otherwise False
True if OK, otherwise False
'''
if not isinstance(logger, log.Logger):
return False
@@ -322,7 +333,7 @@ def info_gsm_com(serObj=None, config={}, logger=None):
:param config:
dictionary config object from JSON database
:param log:
:param logger:
logger object
:return bool:
@@ -442,22 +453,21 @@ def verify_caller(buf="", num="", logger=None):
:param num:
Caller phone number
:param log:
:param logger:
logger object
:return bool:
True if authorized, False otherwise
'''
if not isinstance(logger, log.Logger):
return False, ""
if not isinstance(buf, str):
logger.error("error parameter, expecting str, get {}".format(type(buf)))
return False, ""
if not isinstance(num, str):
logger.error("error parameter, expecting str, get {}".format(type(num)))
return False, ""
if not isinstance(logger, log.Logger):
logger.error("error parameter, expecting logging.Logger, get {}".format(type(logger)))
return False, ""
outlst = buf[7:].split(',')
logger.debug("=> {}".format(outlst))
@@ -469,6 +479,12 @@ def verify_caller(buf="", num="", logger=None):
def listener(sock, logger):
''' Thread socket listener
:param sock:
socket object
:param logger:
logger object
'''
global FLAG_CONF_UPDATE
@@ -509,13 +525,13 @@ def listener(sock, logger):
logger.debug("Fin du serveur de communication")
return
def verify_open_hours(conf=None, logger=None):
def verify_open_hours(conf={}, logger=None):
''' Verify if GSM HAT must be opened with conf hours
:param conf:
configuration object
:param log:
:param logger:
logger object
:return bool:
@@ -523,6 +539,9 @@ def verify_open_hours(conf=None, logger=None):
'''
if not isinstance(logger, log.Logger):
return False
if not isinstance(conf, dict):
logger.error("error parameter, expecting dict, get {}".format(type(conf)))
return False
flag = False
my_date = date.today()
@@ -542,6 +561,9 @@ def verify_open_hours(conf=None, logger=None):
def init_module():
''' initialisation of GNSS/GPS/GSM HAT Module
:return bool:
True if OK, otherwise False
'''
try:
GPIO.setmode(GPIO.BOARD)
@@ -553,6 +575,9 @@ def init_module():
def setup_module():
''' Setup module (Set/Reset)
:return bool:
True if OK, otherwise False
'''
while True:
try:
@@ -565,9 +590,18 @@ def setup_module():
#GPIO.cleanup()
return True
def cron_verify_hours(op=None, config=None, logger=None):
def cron_verify_hours(op='', config=None, logger=None):
''' cron job to check opened or closed hours
'''
if not isinstance(logger, log.Logger):
return
if not isinstance(config, dict):
logger.error("error parameter, expecting dict, get {}".format(type(config)))
return
if not isinstance(op, str):
logger.error("error parameter, expecting str, get {}".format(type(op)))
return
global GSM_MODULE_STATE
global GSM_MODULE_INIT_STATE
if op == 'Horaires':
@@ -678,7 +712,7 @@ def main():
hl = log.FileHandler(os.path.join('/var/log/KineIntercom','Intercom.log'))
fl.setLevel(log.DEBUG)
hl.setLevel(log.INFO)
formatter = log.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
formatter = log.Formatter('%(asctime)s - %(funcName)s - %(levelname)s - %(message)s')
fl.setFormatter(formatter)
hl.setFormatter(formatter)
logger.addHandler(fl)
@@ -773,9 +807,6 @@ def main():
else:
GSM_MODULE_INIT_STATE = True
sys.exit(0)
# Retreive GSM infos
logger.info('Récupération des infos du module ...')
ret = info_gsm_com(serObj=ser, config=config, logger=logger)