from common.models import * import socket import configparser import sys import json from pydoc import locate CONFIG_FILE = "../simulators/config/socket_config.ini" GRAMMAR_FILE = "../simulators/config/grammar.json" class DeviceController(): ''' Generic object for the communication with all the devices (need inheritance) ''' def __init__(self, device_name): ''' The messages and their parameters will be defined in the objects that inherits from this class ''' config = configparser.ConfigParser() config.read(CONFIG_FILE) self.ip = config.get(device_name, "ip") self.port = int(config.get(device_name, "port")) self.set_msgs = [] self.get_msgs = [] self.do_msgs = [] self.enums = {} with open(GRAMMAR_FILE) as grammar_file: grammar = json.load(grammar_file) enums = grammar["Enums"] for enum in enums: self.enums[enum] = enums[enum] if device_name[:6] == "Camera": device = grammar["Camera"] for item in device["set"]: param_type = item["param_type"] if len(param_type) < 4 or param_type[:4] != "Enum": ''' This transforms 'int' string to type ''' param_type = locate(param_type) self.set_msgs.append((item["name"], item["nb_param"], param_type)) for item in device["get"]: self.get_msgs.append(item) for item in device["do"]: param_type = item["param_type"] if len(param_type) < 4 or param_type[:4] != "Enum": param_type = locate(param_type) self.do_msgs.append((item["name"], item["nb_param"], param_type)) device = grammar[device_name] for item in device["set"]: param_type = item["param_type"] if len(param_type) < 4 or param_type[:4] != "Enum": param_type = locate(param_type) self.set_msgs.append((item["name"], item["nb_param"], param_type)) for item in device["get"]: self.get_msgs.append(item) for item in device["do"]: param_type = item["param_type"] if len(param_type) < 4 or param_type[:4] != "Enum": param_type = locate(param_type) self.do_msgs.append((item["name"], item["nb_param"], param_type)) def init_socket(self): if self.ip is None or self.port is None: raise ValueError("IP and/or PORT not initialized") # TODO: gérer un fail de connexion self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: self.sock.connect((self.ip, self.port)) except ConnectionError: print("Connection failed to ip : " + str(self.ip) + " Port : " + str(self.port), file=sys.stderr) return (1) return (0) def set(self, cmd, *args): ''' Send a SET message to the device ''' msg = [msg for msg in self.set_msgs if msg[0] == cmd] if len(msg) == 0: raise ValueError("Invalid message argument %s" % (cmd,)) msg = msg[0] if len(args) not in msg[1]: raise ValueError("Bad number of arguments") if type(msg[2]) is str: if msg[2] not in self.enums.keys(): raise TypeError("Enum %s doesn't exist. Please check the grammar.json file." % (msg[2],)) enum = self.enums[msg[2]] for arg in args: if arg not in enum: raise TypeError("Bad value '%s' for enum '%s'" % (arg, msg[2])) else: for arg in args: if type(arg) != msg[2]: raise TypeError("Bad type of argument: expected %s" % (msg[2],)) # if self.init_socket() == 1: # self._message_queue message = "SET " + cmd + " " + " ".join([str(arg) for arg in args]) self.sock.send(bytes(message, "UTF-8")) # print("set ", cmd) def get(self, cmd): ''' Send a GET message to the device ''' if cmd not in self.get_msgs: raise ValueError("Invalid message argument %s" % (cmd,)) self.init_socket() message = "GET " + cmd self.sock.send(bytes(message, "UTF-8")) # print("get ", cmd) # TODO: gérer le timeout ret = self.sock.recv(1024).decode() # print("return : ", ret) return ret def do(self, cmd, *args): ''' Send a DO message to the device ''' msg = [msg for msg in self.do_msgs if msg[0] == cmd] if len(msg) == 0: raise ValueError("Invalid message argument %s" % (cmd,)) msg = msg[0] if len(args) not in msg[1]: raise ValueError("Bad number of arguments") if type(msg[2]) is str: if msg[2] not in self.enums.keys(): raise TypeError("Enum %s doesn't exist. Please check the grammar.json file." % (msg[2],)) enum = self.enums[msg[2]] for arg in args: if arg not in enum: raise TypeError("Bad value '%s' for enum '%s'" % (arg, msg[2])) else: for arg in args: if type(arg) != msg[2]: raise TypeError("Bad type of argument: expected %s" % (msg[2],)) self.init_socket() message = "DO " + cmd + " " + " ".join([str(arg) for arg in args]) self.sock.send(bytes(message, "UTF-8")) # print("do ", cmd)