示例#1
0
    def run(self):
        httpd = http.server.HTTPServer(self.addr, self.handler, False)

        # Prevent the HTTP server from re-binding every handler.
        # https://stackoverflow.com/questions/46210672/
        httpd.socket = self.sock
        httpd.threadid = self.threadid
        httpd.timeout = 2  #- socket timeout
        httpd.server_bind = self.server_close = lambda self: None

        if 'startup' in devices.Dev[self.dev]:
            devices.Dev[self.dev]['startup'](self.setStatus, self.getStatus,
                                             self.sendCommand)

        while not InterruptRequested.is_set():
            #            print ("Start thread %s" % self.threadid)
            while macros.eventList.nextEvent() < 1:
                event = macros.eventList.pop()
                devices.logfile(
                    "  = EVENT (%s) %s/%s" %
                    (datetime.datetime.now().strftime("%I:%M:%S"),
                     event.params['device'], event.name), "EVENT")
                if event.name.startswith("POLL_"):
                    (POLL, devicename, argname) = event.name.split('_', 2)
                    value = devices.Dev[devicename]["pollCallback"](
                        devicename, argname, event.command, event.params)
                    if value is not False:
                        if value is not None and value != '':
                            self.setStatus(argname, str(value), event.params)
                        self.sendCommand(event.command, event.params)
                else:
                    self.sendCommand(event.command, event.params)
            httpd.handle_request()
示例#2
0
def discover(settingsFile, timeout, listen, broadcast):
    if 'requests' not in devices.Modlist:
        logfile(
            "URL/Webhook device support requires 'requests' python module.",
            "WARN")
        return False

    default = "IFTTT"
    if settingsFile.has_section(default):
        return
    print("\tConfiguring default URL device, IFTTT ...")

    settings.backupSettings()
    try:
        ControlIniFile = open(
            path.join(settings.applicationDir, 'settings.ini'), 'w')
        settingsFile.add_section(default)
        settingsFile.add_section(default + ' Status')
        URL = '''https://maker.ifttt.com/trigger/$command/with/key/$status(API_KEY)'''
        API_KEY = '''Click 'Documentation' from https://ifttt.com/maker_webhooks to get API Key'''
        settingsFile.set(default, 'URL', URL)
        settingsFile.set(default + ' Status', 'API_KEY', API_KEY)
        settingsFile.set(default, 'Type', 'URL')
        settingsFile.set(default, 'skipRepeats', 'False')
        settingsFile.write(ControlIniFile)
        ControlIniFile.close()
    except Exception as e:
        logfile("Error writing settings file: %s" % e, "ERROR")
        settings.restoreSettings()
示例#3
0
def discover(settingsFile, timeout, listen, broadcast):
    if 'gpio' not in devices.Modlist:
        logfile(
            "GPIO device support requires Adafruit python module.\npip3 install Adafruit_BBIO",
            "WARN")
        return False
    print("\tDetecting GPIO devices is currently unsupported...")
示例#4
0
def SigInt(signum, frame):
    if threadpool.InterruptRequested.is_set():
        print("\n\nAborting!\n")
        exit()
    logfile("\nShuting down server ...", "SPECIAL")
    threadpool.ShutdownRequested.set()
    threadpool.InterruptRequested.set()
示例#5
0
def readSettings(settingsFile, devname):
    Dev = devices.Dev[devname]
    if Dev['Type'] == 'URL':
        Dev['BaseType'] = "url"
        if 'requests' not in devices.Modlist:
            logfile(
                "URL/Webhook device support requires 'requests' python module.",
                "WARN")
            return False
        device = type('', (), {})()
        device.url = Dev['URL']
        if settingsFile.has_option(devname, "Method"):
            device.method = settingsFile.get(devname, "Method")
        else:
            device.method = "POST"
        if settingsFile.has_option(devname, "Find"):
            device.find = settingsFile.get(devname, "Find")
        if settingsFile.has_option(devname, "Set"):
            device.setvars = settingsFile.get(devname, "Set")
    else:
        return False
    if 'Delay' in Dev:
        device.delay = Dev['Delay']
    else:
        device.delay = 0.25  #- Otherwise you get a Bad Gateway error from IFTTT

    Dev['learnCommand'] = None
    Dev['sendCommand'] = sendCommand
    Dev['getStatus'] = None
    Dev['setStatus'] = None
    Dev['getSensor'] = None
    Dev['virtualize'] = virtualize
    Dev['startup'] = startup
    return device
示例#6
0
def execute_shell(command,query):
    section = "SHELL " + command
    #devices.logfile (section,"DEBUG")
    parameters = None
    if settingsFile.has_option(section,"parameters"):
        parameters = expandVariables(settingsFile.get(section,"parameters"),query)
    if settingsFile.has_option(section,"command"):
        command = expandVariables(settingsFile.get(section,"command"),query)
    else:
        devices.logfile ("You must specify at least a \"command\" for any SHELL command","ERROR")
    execCommand = command
    if parameters != None:
        execCommand = [command,parameters]
    shell = False
    try:
        if settingsFile.has_option(section,"shell") and settingsFile.get(section,"shell")!="False":
            retval = subprocess.check_output(execCommand)
        else:
            retval = subprocess.check_output(execCommand,shell=shell)
        if settingsFile.has_option(section,"store"):
            setStatus(expandVariables(settingsFile.get(section,"store"),query),str(retval,'utf8').strip(),query)
    except subprocess.CalledProcessError as e:
        retval = "Fail: %d; %s" % (e.returncode,e.output)
    if len(retval) < 1:
        retval = command
    return retval
示例#7
0
def getSensor(sensorName, params):
    devicename = params['device']
    device = devices.DeviceByName[devicename]
    Dev = devices.Dev[devicename]
    try:
        sensor = device.sensor[sensorName]
        if sensor.sensorType.startswith("temp"):
            reading1 = ADC.read(sensor.gpio)
            time.sleep(0.5)
            reading2 = ADC.read(sensor.gpio)
            reading = (reading1 + reading2) / 2
            millivolts = reading * 1800  # 1.8V reference = 1800 mV
            tempC = (millivolts - 500) / 10
            if sensor.sensorType == "tempC":
                sensor.lastread = tempC
            elif sensor.sensorType == "tempF":
                tempF = (tempC * 9 / 5) + 32
                sensor.lastread = tempF
        value = round(sensor.lastread)
        params['value'] = value
        return value
    except Exception as e:
        logfile(
            "Error finding sensor %s in %s: %s" % (sensorName, devicename, e),
            "ERROR")
        traceback.print_exc()
    return False
示例#8
0
def getStatus(commandName, params):
    if '/' in commandName:
        (deviceName, commandName) = commandName.split('/')
        params = params.copy()
        params['device'] = deviceName
    else:
        deviceName = params["device"]
    sectionName = deviceName + " Status"

    device = devices.DeviceByName[deviceName]
    func = devices.Dev[deviceName]["getStatus"]
    if func is not None:
        #print ("getStatus func(%s) is %s" % (type(func),func))
        retval = func(device, deviceName, commandName, params)
        if retval is not False:
            if 'REDIRECT' in retval:
                (command, deviceName) = retval.split(' ', 2)
                sectionName = deviceName + " Status"
            else:
                return retval
    if settingsFile.has_option(sectionName, commandName):
        status = settingsFile.get(sectionName, commandName)
        return status
    if settingsFile.has_option('Status', commandName):
        status = settingsFile.get('Status', commandName)
        params["globalVariable"] = commandName
        if status:
            return status
    logfile("Can't find %s %s" % (sectionName, commandName), "WARN")
    return "0"
示例#9
0
def getType(statusName, params):
    deviceName = params["device"]
    if deviceName in devices.DeviceByName:
        device = devices.DeviceByName[deviceName]
    else:
        logfile("Failed: No such device, %s" % deviceName, "ERROR")
        return False

    sectionName = "RADIO " + statusName
    if settingsFile.has_section(sectionName):
        if settingsFile.has_option(sectionName, "commands"):
            varlist = settingsFile.get(sectionName, "commands")
            pattern = re.compile("\s*(commands|device|deviceDelay)\s*")
            varlist = pattern.sub('', varlist)
            return ("list", varlist)
        else:
            varlist = settingsFile.options(sectionName)
            if "device" in varlist:
                varlist.remove("device")
            if "deviceDelay" in varlist:
                varlist.remove("deviceDelay")
            if "sequence" in varlist:
                varlist.remove("sequence")
            varlist = ' '.join(varlist)
            return ("list", varlist)
    return ("string", None)
示例#10
0
def getSensor(sensorName, params):
    deviceName = params['device']
    device = devices.DeviceByName[deviceName]
    Dev = devices.Dev[deviceName]
    try:
        # print ("Checking sensors %s %s" % (sensorName,deviceName))
        if "RM" in Dev['Type'].upper() and "temp" in sensorName:
            temperature = device.check_temperature()
            if temperature:
                if 'deviceDelay' not in params:
                    time.sleep(device.delay)
                else:
                    time.sleep(float(params['deviceDelay']))
                return temperature
        elif "A1" in Dev['Type'].upper():
            result = device.check_sensors()
            if result:
                if 'deviceDelay' not in params:
                    time.sleep(device.delay)
                else:
                    time.sleep(float(params['deviceDelay']))
                return result[sensorName]
        else:
            #logfile ("I don't know how to find %s for a %s" % (sensorName,Dev['Type']), "ERROR")
            return False
    except Exception as e:
        logfile(
            "Error finding sensor %s in %s: %s" % (sensorName, deviceName, e),
            "ERROR")
        traceback.print_exc()
    return False
示例#11
0
 def access_denied(self):
     response = "Client %s is not allowed to use GET!" % self.client_ip()
     self._set_headers(self.path)
     self.wfile.write(bytes('''{ "error": "%s" }''' % response, 'utf-8'))
     logfile(response, "WARN")
     #self.close_connection = True
     return False
示例#12
0
 def password_required(self):
     response = "POST Password required from %s" % self.client_ip()
     self._set_headers(self.path)
     self.wfile.write(bytes('''{ "error": "%s" }''' % response, 'utf-8'))
     logfile(response, "WARN")
     #self.close_connection = True
     return False
示例#13
0
def restoreSettings():
    if path.isfile(settingsINI + ".bak"):
        shutil.copy2(settingsINI + ".bak", settingsINI)
    else:
        devices.logfile(
            "Can't find backup to restore!  Refusing to make this worse!",
            "WARN")
        sys.exit()
示例#14
0
def relayTo(device,query):
    if device == query['device']:
        devices.logfile ("RELAY %s attempted to relay to itself" % query['command'],"ERROR")
        return True
    newquery = query.copy()
    newquery['device'] = device
    #print ("Relaying %s to %s" % (query['command'],device))
    sendCommand(query['command'],newquery)
    return
示例#15
0
def backupSettings():
    try:
        shutil.copy2(settingsINI, settingsINI + ".bak")
    except FileNotFoundError:
        devices.logfile(
            "\tNo settings.ini to backup.  Hope we're creating one!", "ERROR")
    except:
        devices.logfile("Error in backup operation!  Refusing to continue!",
                        "WARN")
        sys.exit()
示例#16
0
def sendCommand(command, device, deviceName, params):
    try:
        device.fileh.write(macros.expandVariables(command, params))
        device.fileh.write("\n")
        device.fileh.flush()
        os.fsync(device.fileh)
    except Exception as e:
        traceback.print_exc()
        logfile("Error Writing to %s: %s" % (device.filename, e), "ERROR")
        return False
    return True
示例#17
0
def execute_event(command,query):
    section = "EVENT "+command
    try:
        newquery = query.copy()
        newquery['command'] = settingsFile.get(section,"command")
        for option in settingsFile.options(section):
            newquery[option] = settingsFile.get(section,option)
        execute_event_raw(command,newquery)
        return "command"
    except Exception as e:
        devices.logfile ("EVENT Failed: %s" % e,"ERROR")
    return False
示例#18
0
def execute_wol(command,query):
    section = "WOL "+command
    #devices.logfile (section,"DEBUG")
    try:
        port = None
        mac = expandVariables(settingsFile.get(section,"mac"),query)
        ip = expandVariables(settingsFile.get(section,"ip"),query)
        if settingsFile.has_option(section,"port"):
            port = expandVariables(settingsFile.get(section,"port"),query)
        return wol.wake(mac,ip,port)
    except Exception as e:
        devices.logfile ("WOL Failed: %s" % e,"ERROR")
    return False
示例#19
0
def execute_logicnode_raw(query):
    try:
        value = expandVariables(query['test'],query)
        newcommand = None
        if str(value) in query:
            newcommand = expandVariables(query[str(value)],query)
        elif value.isnumeric():
            if value == "1" and "on" in query:
                newcommand  = expandVariables(query["on"],query)
                return sendCommand("." + newcommand,query)
            elif value == "0" and "off" in query:
                newcommand = expandVariables(query["off"],query)
                return sendCommand("." + newcommand,query)
            value = float(value)
            if "compare" in query:
                compareVar = expandVariables(query["compare"],query)
                try:
                    compare = float(compareVar)
                except:
                    compare = float(getStatus(compareVar,query))
            else:
                compare = 0
            newvalue = value - compare
            if newvalue < 0:
                if "less" in query:
                    newcommand = expandVariables(query["less"],query)
                elif "neg" in query:
                    newcommand = expandVariables(query["neg"],query)
            elif newvalue > 0:
                if "more" in query:
                    newcommand = expandVariables(query["more"],query)
                elif "pos" in query:
                    newcommand = expandVariables(query["pos"],query)
            else:
                if "equal" in query:
                    newcommand = expandVariables(query["equal"],query)
                elif "zero" in query:
                    newcommand = expandVariables(query["zero"],query)
        if newcommand is None:
            if "else" in query:
                newcommand = expandVariables(query["else"],query)
        if newcommand is not None:
            return sendCommand("." + newcommand,query)
        return False
    except Exception as e:
        if "error" in query:
            newcommand = expandVariables(query['error'],query)
            return sendCommand("." + newcommand,query)
        devices.logfile ("LOGIC Failed: %s" % e, "ERROR")
        traceback.print_exc()
        return False
示例#20
0
def readSettings(settingsFile, devname):
    try:
        Dev = devices.Dev[devname]
        if Dev['Type'] == 'GPIO':
            Dev['BaseType'] = "gpio"
            device = type('', (), {})()
            device.sensor = {}
            ADC.setup()
            for section in settingsFile.sections():
                if section.startswith("GPIO "):
                    sensorname = section[5:]
                    sensor = device.sensor[sensorname] = type('', (), {})()
                    sensor.sensorType = settingsFile.get(section, "type")
                    sensor.gpio = settingsFile.get(section, "gpio")
                    sensor.lastread = False
                    if settingsFile.has_option(section, "poll"):
                        sensor.poll = float(settingsFile.get(section,
                                                             "poll")) * 60
                    else:
                        sensor.poll = 300.0  #- 5 minutes
                    if settingsFile.has_option(section, "trigger"):
                        sensor.trigger = trigger = settingsFile.get(
                            section, "trigger")
                        initialparams = {}
                        initialparams['device'] = devname
                        macros.eventList.add(
                            "POLL_" + devname + "_" + sensorname, 4.0,
                            sensor.trigger, initialparams)
                    sensor.lastread = None  #- Change this to read the status variable
        else:
            return False
        if 'Delay' in Dev:
            device.delay = Dev['Delay']
        else:
            device.delay = 0.0

        #- set the callbacks
        Dev['learnCommand'] = None
        Dev['sendCommand'] = None
        Dev['getStatus'] = None
        Dev['setStatus'] = None
        Dev['getSensor'] = getSensor
        Dev['pollCallback'] = pollCallback

        return device
    except Exception as e:
        logfile(
            "GPIO device support requires Adafruit python module.\npip3 install Adafruit_BBIO",
            "WARN")
        return None
示例#21
0
def execute_ping(command,query):
    section = "PING "+command
    #devices.logfile (section,"DEBUG")
    try:
        host = expandVariables(settingsFile.get(section,"host"),query)
        if ping(host):
            rawcommand = settingsFile.get(section,"on")
        else:
            rawcommand = settingsFile.get(section,"off")
        # print ("Command will be %s" % rawcommand)
        result = sendCommand(rawcommand,query)
        return command
    except Exception as e:
        devices.logfile ("PING Failed: %s" % e,"ERROR")
    return False
示例#22
0
def execute_logicnode(command,query):
    section = "LOGIC "+command
    #devices.logfile (section,"DEBUG")
    newcommand = None
    newquery = query.copy()
    newquery['command'] = command
    if settingsFile.has_option(section,"test"):
        newquery["test"] = expandVariables(settingsFile.get(section,"test"),query)
    else:
        devices.logfile ("LOGIC Failed: A test value is requiWARN","ERROR")
        return
    for var in settingsFile.options(section):
        newquery[var] = settingsFile.get(section,var)
    execute_logicnode_raw(newquery)
    return command
示例#23
0
def expandVariables(commandString,query):
    statusVar = commandString.find("$status(")
    newquery = query.copy()
    while statusVar > -1:
        endVar = commandString.find(")",statusVar)
        if endVar < 0:
            devices.logfile ("No END Parenthesis found in $status variable","ERROR")
            statusVar = -1
        varname = commandString[statusVar+8:endVar]
        varvalue = getStatus(varname,newquery)
        commandString = commandString.replace(commandString[statusVar:endVar+1],varvalue)
        statusVar = commandString.find("$status(")
    firstPass = commandString
    secondPass = string.Template(firstPass).substitute(newquery)
    return secondPass
示例#24
0
def readSettings(settingsFile, devname):
    try:
        Dev = devices.Dev[devname]
        if Dev['Type'] == 'RM' or Dev['Type'] == 'RM2':
            device = broadlink.rm((Dev['IPAddress'], 80), Dev['MACAddress'],
                                  Dev['Device'])
        elif Dev['Type'] == 'MP1':
            device = broadlink.mp1((Dev['IPAddress'], 80), Dev['MACAddress'],
                                   Dev['Device'])
        elif Dev['Type'] == 'SP1':
            device = broadlink.sp1((Dev['IPAddress'], 80), Dev['MACAddress'],
                                   Dev['Device'])
        elif Dev['Type'] == 'SP2':
            device = broadlink.sp2((Dev['IPAddress'], 80), Dev['MACAddress'],
                                   Dev['Device'])
        elif Dev['Type'] == 'A1':
            device = broadlink.a1((Dev['IPAddress'], 80), Dev['MACAddress'],
                                  Dev['Device'])
        elif Dev['Type'] == 'HYSEN':
            device = broadlink.hysen((Dev['IPAddress'], 80), Dev['MACAddress'],
                                     Dev['Device'])
        elif Dev['Type'] == 'S1C':
            device = broadlink.S1C((Dev['IPAddress'], 80), Dev['MACAddress'],
                                   Dev['Device'])
        elif Dev['Type'] == 'DOOYA':
            device = broadlink.dooya((Dev['IPAddress'], 80), Dev['MACAddress'],
                                     Dev['Device'])
        else:
            return False
        Dev['BaseType'] = "broadlink"

        if 'Delay' in Dev:
            device.delay = Dev['Delay']
        else:
            device.delay = 0.0

        #- set the callbacks
        Dev['learnCommand'] = learnCommand
        Dev['sendCommand'] = sendCommand
        Dev['getStatus'] = None
        Dev['setStatus'] = None
        Dev['getSensor'] = getSensor
        return device
    except Exception as e:
        logfile(
            "Broadlink device support requires broadlink python module.\npip3 install broadlink",
            "WARN")
        return None
示例#25
0
def execute_event_raw(command,query):
    #print ("RAW: %s" % command)
    try:
        newcommand = expandVariables(query['command'],query)
        delay = 0.0
        if 'seconds' in query:
            delay += float(expandVariables(str(query['seconds']),query))
        if 'minutes' in query:
            delay += float(expandVariables(str(query['minutes']),query)) * 60
        if 'hours' in query:
            delay += float(expandVariables(str(query['hours']),query)) * 3600
        eventList.add(command,delay,newcommand,query)
        return command
    except Exception as e:
        devices.logfile ("EVENT Failed: %s" % e,"ERROR")
        traceback.print_exc()
    return False
示例#26
0
def start(handler_class=Handler, port=8080, listen='0.0.0.0'):
    addr = (listen, port)
    if settings.Hostname == "localhost":
        name = ''
    else:
        name = settings.Hostname + " "
    logfile(
        '\nStarting RestHome server %son %s:%s ...\n' % (name, listen, port),
        "SPECIAL")
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.bind(addr)
    sock.listen(5)
    devices.startUp(sock, addr, setStatus, getStatus, sendCommand,
                    handler_class)
    while not threadpool.InterruptRequested.is_set():
        threadpool.InterruptRequested.wait(2)
    logfile("Closing Server ...", "SPECIAL")
    sock.close()
示例#27
0
 def do_GET(self):
     self.Parameters = collections.defaultdict(lambda: ' ')
     try:
         if GlobalPassword and ('/ui/' not in self.path
                                and 'getIcon' not in self.path
                                and self.path != '/favicon.ico'):
             try:
                 if RestrictAccess and self.client_ip(
                 ) not in RestrictAccess:
                     return self.access_denied()
                 return self.messageHandler()
             except NameError as e:
                 logfile("Error: %s" % e, "ERROR")
                 traceback.print_exc()
                 self.password_required()
         else:
             return self.messageHandler()
     except NameError:  #- No security specified
         self.messageHandler()
示例#28
0
def discover(settingsFile, timeout, listen, broadcast):
    if 'broadlink' not in devices.Modlist:
        logfile(
            "Broadlink device support requires broadlink python module.\npip3 install broadlink",
            "WARN")
        return False
    print("\tDetecting Broadlink devices ...")
    try:
        broadlinkDevices = broadlink.discover(timeout, listen, broadcast)
    except:
        broadlinkDevices = broadlink.discover(timeout, listen)

    settings.backupSettings()
    try:
        ControlIniFile = open(
            path.join(settings.applicationDir, 'settings.ini'), 'w')
        for device in broadlinkDevices:
            try:
                device.hostname = socket.gethostbyaddr(device.host[0])[0]
                if "." in device.hostname:
                    device.hostname = device.hostname.split('.')[0]
            except:
                device.hostname = "Broadlink" + device.type.upper()
            if device.hostname in devices.DeviceByName:
                device.hostname = "%s-%s" % (device.hostname, str(
                    device.host).split('.')[3])
            if not settingsFile.has_section(device.hostname):
                settingsFile.add_section(device.hostname)
            settingsFile.set(device.hostname, 'IPAddress', str(device.host[0]))
            hexmac = ':'.join(["%02x" % (x) for x in reversed(device.mac)])
            settingsFile.set(device.hostname, 'MACAddress', hexmac)
            settingsFile.set(device.hostname, 'Device', hex(device.devtype))
            settingsFile.set(device.hostname, 'Timeout', str(device.timeout))
            settingsFile.set(device.hostname, 'Type', device.type.upper())
            print("\t\t%s: Found %s on %s (%s) type: %s" %
                  (device.hostname, device.type, device.host, hexmac,
                   hex(device.devtype)))
        settingsFile.write(ControlIniFile)
        ControlIniFile.close()
    except Exception as e:
        logfile("Error writing settings file: %s" % e, "ERROR")
        settings.restoreSettings()
示例#29
0
 def do_POST(self):
     self.Parameters = collections.defaultdict(lambda: ' ')
     password = ''
     try:
         content_len = int(self.headers.get('content-length', 0))
         JSONbody = self.rfile.read(content_len).decode("utf-8")
         #print ("POST body: %s" % JSONbody)
         self.Parameters.update(json.loads(JSONbody))
         password = self.Parameters['password']
     except:
         traceback.print_exc()
         pass
     try:
         if not GlobalPassword:
             return self.messageHandler()
         if GlobalPassword and GlobalPassword == password:
             return self.messageHandler()
         else:
             logfile('''POST Password Wrong: "%s"''' % password, "WARN")
     except NameError:
         return self.password_required()
     self.password_required()
示例#30
0
def learnCommand(devname, device, params):
    try:
        device.enter_learning()
        start = time.time()
        #- We want the real device delay here, not the modified one
        #- min of 0.5 second.  Result is almost always 1 second
        sleeptime = max(devices.Dev[devname]["Delay"], 0.5)
        LearnedCommand = None
        while LearnedCommand is None and time.time(
        ) - start < settings.GlobalTimeout:
            time.sleep(sleeptime)
            LearnedCommand = device.check_data()

        if LearnedCommand is None:
            logfile('Command not received', "ERROR")
            return False

        AdditionalData = bytearray([0x00, 0x00, 0x00, 0x00])
        finalCommand = AdditionalData + LearnedCommand

        AESEncryption = AES.new(device.key, AES.MODE_CBC, bytes(device.iv))
        return binascii.hexlify(AESEncryption.decrypt(bytes(finalCommand)))
    except:
        traceback.print_exc()