def getAllApplications(maxAttempt=Globals.MAX_RETRY): """ Make a API call to get all Applications belonging to the Enterprise """ try: api_instance = esperclient.ApplicationApi( esperclient.ApiClient(Globals.configuration)) api_response = None for attempt in range(maxAttempt): try: api_response = api_instance.get_all_applications( Globals.enterprise_id, limit=Globals.limit, offset=Globals.offset, is_hidden=False, ) break except Exception as e: if attempt == maxAttempt - 1: ApiToolLog().LogError(e) raise e time.sleep(Globals.RETRY_SLEEP) postEventToFrame(wxThread.myEVT_LOG, "---> App API Request Finished") return api_response except ApiException as e: raise Exception( "Exception when calling ApplicationApi->get_all_applications: %s\n" % e)
def processDeviceGroup(self, templateFound): toDeviceGroups = getDeviceGroupsForHost( self.getEsperConfig(self.toApi, self.toKey), self.toEntId) allDeviceGroupId = None found, templateFound, allDeviceGroupId = self.checkDeviceGroup( templateFound, toDeviceGroups, allDeviceGroupId) if not found: postEventToFrame(wxThread.myEVT_LOG, "Creating new device group...") res = createDeviceGroupForHost( self.getEsperConfig(self.toApi, self.toKey), self.toEntId, templateFound["template"]["device_group"]["name"], ) if res: toDeviceGroups = getDeviceGroupsForHost( self.getEsperConfig(self.toApi, self.toKey), self.toEntId) _, templateFound, _ = self.checkDeviceGroup( templateFound, toDeviceGroups, allDeviceGroupId) else: templateFound["template"]["device_group"] = allDeviceGroupId postEventToFrame( wxThread.myEVT_LOG, "Failed to recreate Device Group, using All Device group!", ) wx.MessageBox( "Failed to recreate Device Group, using All Device group!", style=wx.OK | wx.ICON_ERROR, ) return templateFound
def uploadMissingApk(self, app, template, newTemplate, config, entId): try: postEventToFrame( wxThread.myEVT_LOG, "Attempting to download %s to upload to endpoint" % app["packageName"], ) file = "%s.apk" % app["applicationName"] deleteFile(file) download(app["downloadUrl"], file) res = uploadApplicationForHost(config, entId, file) if type(res) != InlineResponse201: deleteFile(file) raise Exception("Upload failed!") deleteFile(file) if template["template"]["application"]["startOnBoot"] == app[ "packageName"]: newTemplate["application"]["appMode"] = template["template"][ "application"]["appMode"] newTemplate["application"]["startOnBoot"] = template[ "template"]["application"]["startOnBoot"] except Exception as e: print(e) ApiToolLog().LogError(e) postEventToFrame( wxThread.myEVT_LOG, "To Enterprise is missing app, %s, not adding to template" % app["applicationName"], ) self.missingApps += str(app["applicationName"]) + ", "
def setAppStateForAllAppsListed(state, maxAttempt=Globals.MAX_RETRY): api_instance = esperclient.DeviceApi( esperclient.ApiClient(Globals.configuration)) api_response = None for attempt in range(maxAttempt): try: api_response = api_instance.get_all_devices( Globals.enterprise_id, limit=Globals.limit, offset=Globals.offset, ) break except Exception as e: if attempt == maxAttempt - 1: postEventToFrame( wxThread.myEVT_LOG, "---> ERROR: Failed to get devices ids to modify tags and aliases", ) print(e) ApiToolLog().LogError(e) return time.sleep(Globals.RETRY_SLEEP) deviceIdentifers = Globals.frame.gridPanel.getDeviceIdentifersFromGrid() if api_response: tempRes = [] for device in api_response.results: for deviceIds in deviceIdentifers: if (device.device_name in deviceIds or device.hardware_info["serialNumber"] in deviceIds): tempRes.append(device) if tempRes: api_response.results = tempRes threads = [] for device in api_response.results: if (device.device_name in deviceIdentifers or device.hardware_info["serialNumber"] in deviceIdentifers): t = wxThread.GUIThread( Globals.frame, setAllAppsState, args=(Globals.frame, device, state), name="setAllAppsState", ) threads.append(t) t.start() limitActiveThreads(threads) t = wxThread.GUIThread( Globals.frame, waitTillThreadsFinish, args=(tuple(threads), state, -1, 4), name="waitTillThreadsFinish%s" % state, ) t.start()
def getAllDevices(groupToUse, maxAttempt=Globals.MAX_RETRY): """ Make a API call to get all Devices belonging to the Enterprise """ if not groupToUse: return None try: api_instance = esperclient.DeviceApi( esperclient.ApiClient(Globals.configuration)) api_response = None if type(groupToUse) == list: for group in groupToUse: for attempt in range(maxAttempt): try: response = api_instance.get_all_devices( Globals.enterprise_id, group=group, limit=Globals.limit, offset=Globals.offset, ) break except Exception as e: if attempt == maxAttempt - 1: ApiToolLog().LogError(e) raise e time.sleep(Globals.RETRY_SLEEP) if not api_response: api_response = response else: api_response.results = api_response.results + response.results else: for attempt in range(maxAttempt): try: api_response = api_instance.get_all_devices( Globals.enterprise_id, group=groupToUse, limit=Globals.limit, offset=Globals.offset, ) break except Exception as e: if attempt == maxAttempt - 1: ApiToolLog().LogError(e) raise e time.sleep(Globals.RETRY_SLEEP) postEventToFrame(wxThread.myEVT_LOG, "---> Device API Request Finished") return api_response except ApiException as e: raise Exception( "Exception when calling DeviceApi->get_all_devices: %s\n" % e)
def clearAppData(frame, device): json_resp = None try: appToUse = frame.sidePanel.appChoice.GetClientData( frame.sidePanel.appChoice.GetSelection()) _, apps = getdeviceapps(device.id, createAppList=False, useEnterprise=Globals.USE_ENTERPRISE_APP) cmdArgs = {} for app in apps["results"]: if app["package_name"] == appToUse: cmdArgs["package_name"] = app["package_name"] cmdArgs["application_name"] = app["app_name"] cmdArgs["version_code"] = app["version_code"] cmdArgs["version_name"] = app["version_name"] if app["app_type"] == "GOOGLE": cmdArgs["is_g_play"] = True else: cmdArgs["is_g_play"] = False break if cmdArgs: reqData = { "command_type": "DEVICE", "command_args": cmdArgs, "devices": [device.id], "groups": [], "device_type": Globals.CMD_DEVICE_TYPE, "command": "CLEAR_APP_DATA", } resp, json_resp = postEsperCommand(reqData) logBadResponse(resp.request.url, resp, json_resp) if resp.status_code > 300: postEventToFrame(wxThread.myEVT_ON_FAILED, device) if resp.status_code < 300: frame.Logging( "---> Clear %s App Data Command has been sent to %s" % (cmdArgs["application_name"], device.device_name)) else: frame.Logging( "ERROR: Failed to send Clear %s App Data Command to %s" % (frame.sidePanel.appChoice.GetValue(), device.device_name)) except Exception as e: ApiToolLog().LogError(e) frame.Logging("ERROR: Failed to send Clear App Data Command to %s" % (device.device_name)) postEventToFrame(wxThread.myEVT_ON_FAILED, device) return json_resp
def processWallpapers(self, templateFound): if self.toApi and self.toKey and self.toEntId: postEventToFrame(wxThread.myEVT_LOG, "Processing wallpapers in template...") if templateFound["template"]["brand"]: bgList = [] for bg in templateFound["template"]["brand"]["wallpapers"]: newBg = self.uploadWallpaper(self.toApi, self.toKey, self.toEntId, bg) if newBg: newBg["enterprise"] = self.toEntId newBg["wallpaper"] = newBg["id"] newBg["orientations"] = bg["orientations"] newBg["screen_types"] = bg["screen_types"] bgList.append(newBg) templateFound["template"]["brand"]["wallpapers"] = bgList return templateFound
def changeAliasForDevice(device, aliasDic, frame, maxGaugeAction): numNewName = 0 succeeded = 0 logString = "" # Alias modification if (device.device_name in aliasDic.keys() or device.hardware_info["serialNumber"] in aliasDic.keys()): newName = None if device.device_name in aliasDic: newName = aliasDic[device.device_name] else: newName = aliasDic[device.hardware_info["serialNumber"]] logString = str("--->" + str(device.device_name) + " : " + str(newName) + "--->") if not newName and not device.alias_name: return if newName != str(device.alias_name): numNewName += 1 status = "" try: ignoreQueued = False if Globals.REACH_QUEUED_ONLY else True status = apiCalls.setdevicename(frame, device.id, newName, ignoreQueued) except Exception as e: ApiToolLog().LogError(e) if "Success" in str(status): logString = logString + " <success>" succeeded += 1 elif "Queued" in str(status): logString = logString + " <Queued> Make sure device is online." postEventToFrame(wxThread.myEVT_ON_FAILED, (device, "Queued")) else: logString = logString + " <failed>" postEventToFrame(wxThread.myEVT_ON_FAILED, device) else: logString = logString + " (Alias Name already set)" if "Success" in logString or "Queued" in logString: postEventToFrame(wxThread.myEVT_UPDATE_GRID_CONTENT, (device, "alias")) postEventToFrame( wxThread.myEVT_UPDATE_GAUGE, int(frame.gauge.GetValue() + 1 / maxGaugeAction * 100), ) postEventToFrame(wxThread.myEVT_LOG, logString) return (numNewName, succeeded)
def getDeviceById(deviceToUse, maxAttempt=Globals.MAX_RETRY): """ Make a API call to get a Device belonging to the Enterprise by its Id """ try: api_instance = esperclient.DeviceApi( esperclient.ApiClient(Globals.configuration)) api_response_list = [] api_response = None if type(deviceToUse) == list: for device in deviceToUse: for attempt in range(maxAttempt): try: api_response = api_instance.get_device_by_id( Globals.enterprise_id, device_id=device) break except Exception as e: if attempt == maxAttempt - 1: ApiToolLog().LogError(e) raise e time.sleep(Globals.RETRY_SLEEP) if api_response: api_response_list.append(api_response) else: for attempt in range(maxAttempt): try: api_response = api_instance.get_device_by_id( Globals.enterprise_id, device_id=deviceToUse) break except Exception as e: if attempt == maxAttempt - 1: ApiToolLog().LogError(e) raise e time.sleep(Globals.RETRY_SLEEP) if api_response and api_response_list: api_response.results = api_response_list elif api_response: api_response.results = [api_response] postEventToFrame(wxThread.myEVT_LOG, "---> Device API Request Finished") return api_response except ApiException as e: print("Exception when calling DeviceApi->get_device_by_id: %s\n" % e) ApiToolLog().LogError(e)
def processCollectionDevices(collectionList): if collectionList["results"]: splitResults = splitListIntoChunks(collectionList["results"]) if splitResults: threads = [] number_of_devices = 0 for chunk in splitResults: t = wxThread.GUIThread( Globals.frame, fillInDeviceInfoDict, args=(chunk, number_of_devices, len(collectionList["results"] * 2)), name="fillInDeviceInfoDict", ) threads.append(t) t.start() number_of_devices += len(chunk) t = wxThread.GUIThread( Globals.frame, waitTillThreadsFinish, args=( tuple(threads), GeneralActions.SHOW_ALL_AND_GENERATE_REPORT.value, Globals.enterprise_id, 3, ), eventType=wxThread.myEVT_FETCH, name="waitTillThreadsFinish3", ) t.start() else: if Globals.frame: Globals.frame.Logging("---> No devices found for EQL query") postEventToFrame( wxThread.myEVT_MESSAGE_BOX, ("No devices found for EQL query.", wx.ICON_INFORMATION), ) postEventToFrame(wxThread.myEVT_COMPLETE, (True))
def processApplications(self, template, newTemplate, apps): for app in template["template"]["application"]["apps"]: if ("isGPlay" in app and app["isGPlay"]) or ("is_g_play" in app and app["is_g_play"]): newTemplate["application"]["apps"].append(app) else: for toApp in apps: if (toApp.application_name == app["applicationName"] or toApp.package_name == app["packageName"]): versionId = list( filter( lambda x: x.version_code == app["versionName"], toApp.versions, )) if not versionId: versionId = toApp.versions[0].id else: versionId = versionId[0].id newTemplate["application"]["apps"].append({ "is_g_play": False, "id": toApp.id, "app_version": versionId, "appVersionId": versionId, "installationRule": app["installationRule"], }) postEventToFrame( wxThread.myEVT_LOG, "Added the '%s' app to the template" % app["applicationName"], ) break
def prepareTemplate(self, dest=None, chosenTemplate=None): if self.parent and self.parent.gauge: self.parent.gauge.Pulse() self.toApi = self.apiLink.format(tenant=self.toTenant) toTemplates = (dest if dest else self.getTemplates( self.toApi, self.toKey, self.toEntId)) toApps = getAllApplicationsForHost( self.getEsperConfig(self.toApi, self.toKey), self.toEntId) templateFound = None maxId = len(toTemplates) + 1 templateExist = list( filter(lambda x: x["name"] == self.templateName, toTemplates)) templateFound = chosenTemplate if templateFound: templateFound["enterprise"] = self.toEntId templateFound = self.checkTemplate( templateFound, toApps.results, self.getEsperConfig(self.toApi, self.toKey), self.toEntId, ) if templateExist: templateFound["id"] = templateExist[0]["id"] postEventToFrame( wxThread.myEVT_CONFIRM_CLONE_UPDATE, ( self, self.toApi, self.toKey, self.toEntId, templateFound, self.missingApps, ), ) else: templateFound["id"] = maxId + 1 postEventToFrame( wxThread.myEVT_CONFIRM_CLONE, ( self, self.toApi, self.toKey, self.toEntId, templateFound, self.missingApps, ), ) else: postEventToFrame(wxThread.myEVT_LOG, "Template was not found. Check arguements.")
def setKiosk(frame, device, deviceInfo): """Toggles Kiosk Mode With Specified App""" logString = "" failed = False warning = False appSelection = frame.sidePanel.appChoice.GetSelection() if appSelection < 0: return {} appToUse = frame.sidePanel.appChoice.GetClientData(appSelection) logString = ( str("--->" + str(device.device_name) + " " + str(device.alias_name)) + " -> Kiosk ->" + str(appToUse)) timeout = Globals.COMMAND_TIMEOUT if Globals.SET_APP_STATE_AS_SHOW: stateStatus = setAppState(device.id, appToUse, state="SHOW") timeout = (Globals.COMMAND_TIMEOUT if "Command Success" in str(stateStatus) else 0) status = toggleKioskMode(frame, device.id, appToUse, True, timeout) if status: if "Success" in str(status): logString = logString + " <success>" elif "Queued" in str(status): logString = (logString + " <warning, check back on the device (%s)>" % device.device_name) warning = True else: logString = logString + " <failed>" failed = True if deviceInfo["Status"] != "Online": logString = logString + " (Device offline)" postEventToFrame(wxThread.myEVT_LOG, logString) if failed: postEventToFrame(wxThread.myEVT_ON_FAILED, deviceInfo) if warning: postEventToFrame(wxThread.myEVT_ON_FAILED, (device, "Queued")) if hasattr(status, "state"): entry = { "Esper Name": device.device_name, "Device Id": device.id, "Status": status.state, } if hasattr(status, "reason"): entry["Reason"] = status.reason return entry else: return { "Esper Name": device.device_name, "Device Id": device.id, "Status": status, }
def uploadWallpaper(self, link, key, enterprise_id, bg): json_resp = None files = None try: headers = { "Authorization": f"Bearer {key}", } download(bg["url"], "wallpaper.jpeg") if os.path.exists("wallpaper.jpeg"): payload = { "orientation": bg["orientation"], "enterprise": enterprise_id, } url = (link + enterprise_id + self.wallpaper_extension + self.limit_extension.format(num=Globals.limit)) files = {"image_file": open("wallpaper.jpeg", "rb")} postEventToFrame(wxThread.myEVT_LOG, "Attempting to upload wallpaper...") resp = performPostRequestWithRetry(url, headers=headers, data=payload, files=files) if resp.ok: postEventToFrame(wxThread.myEVT_LOG, "Wallpaper upload Succeeded!") json_resp = resp.json() else: postEventToFrame(wxThread.myEVT_LOG, "Wallpaper upload Failed!") wx.MessageBox( "Wallpaper upload Failed! Source: %s" % bg["url"], style=wx.OK | wx.ICON_ERROR, ) resp.raise_for_status() else: wx.MessageBox( "Failed to download wallpaper for uploading", style=wx.OK | wx.ICON_ERROR, ) except Exception as e: raise e finally: if files: files["image_file"].close() deleteFile("wallpaper.jpeg") if json_resp: return json_resp
def setMulti(frame, device, deviceInfo): """Toggles Multi App Mode""" logString = ( str("--->" + str(device.device_name) + " " + str(device.alias_name)) + " -> Multi ->") failed = False warning = False status = None if deviceInfo["Mode"] == "Kiosk": status = toggleKioskMode(frame, device.id, {}, False) if status: if "Success" in str(status): logString = logString + " <success>" elif "Queued" in str(status): logString = (logString + " <warning, check back on the device (%s)>" % device.device_name) warning = True else: logString = logString + " <failed>" failed = True else: logString = logString + " (Already Multi mode, skipping)" if deviceInfo["Status"] != "Online": logString = logString + " (Device offline)" postEventToFrame(wxThread.myEVT_LOG, logString) if failed: postEventToFrame(wxThread.myEVT_ON_FAILED, deviceInfo) if warning: postEventToFrame(wxThread.myEVT_ON_FAILED, (device, "Queued")) if status and hasattr(status, "state"): entry = { "Esper Name": device.device_name, "Device Id": device.id, "Status": status.state, } if hasattr(status, "reason"): entry["Reason"] = status.reason return entry else: return { "Esper Name": device.device_name, "Device Id": device.id, "Status": status, }
def changeTagsForDevice(device, tagsFromGrid, frame, maxGaugeAction): # Tag modification changeSucceeded = 0 if (device.device_name in tagsFromGrid.keys() or device.hardware_info["serialNumber"] in tagsFromGrid.keys()): tagsFromCell = None key = None if device.device_name in tagsFromGrid: key = device.device_name tagsFromCell = tagsFromGrid[key] else: key = device.hardware_info["serialNumber"] tagsFromCell = tagsFromGrid[key] tags = apiCalls.setdevicetags(device.id, tagsFromCell) if tags == tagsFromGrid[key]: changeSucceeded += 1 postEventToFrame(wxThread.myEVT_UPDATE_GRID_CONTENT, (device, "tags")) postEventToFrame(wxThread.myEVT_UPDATE_TAG_CELL, (device.device_name, tags)) postEventToFrame( wxThread.myEVT_UPDATE_GAUGE, int(frame.gauge.GetValue() + 1 / maxGaugeAction * 100), ) return changeSucceeded
def executeDeviceModification(frame, maxAttempt=Globals.MAX_RETRY): """ Attempt to modify device data according to what has been changed in the Grid """ api_instance = esperclient.DeviceApi( esperclient.ApiClient(Globals.configuration)) api_response = None for attempt in range(maxAttempt): try: api_response = api_instance.get_all_devices( Globals.enterprise_id, limit=Globals.limit, offset=Globals.offset, ) break except Exception as e: if attempt == maxAttempt - 1: postEventToFrame( wxThread.myEVT_LOG, "---> ERROR: Failed to get devices ids to modify tags and aliases", ) print(e) ApiToolLog().LogError(e) return time.sleep(Globals.RETRY_SLEEP) tagsFromGrid = frame.gridPanel.getDeviceTagsFromGrid() aliasDic = frame.gridPanel.getDeviceAliasFromList() frame.gauge.SetValue(1) maxGaugeAction = len(tagsFromGrid.keys()) + len(aliasDic.keys()) if api_response: tempRes = list( filter(lambda x: x.device_name in tagsFromGrid.keys(), api_response.results)) if not tempRes: if "serialNumber" in api_response.results[0].hardware_info: tempRes = list( filter( lambda x: x.hardware_info["serialNumber"] in tagsFromGrid.keys(), api_response.results, )) if tempRes: api_response.results = tempRes splitResults = splitListIntoChunks(api_response.results) threads = [] for chunk in splitResults: t = wxThread.GUIThread( frame, processDeviceModificationForList, args=(frame, chunk, tagsFromGrid, aliasDic, maxGaugeAction), name="processDeviceModificationForList", ) threads.append(t) t.start() t = wxThread.GUIThread( frame, waitTillThreadsFinish, args=(tuple(threads), -1, -1, 2), name="waitTillThreadsFinish", ) t.start()
def TakeAction(frame, group, action, label, isDevice=False, isUpdate=False): """Calls API To Perform Action And Logs Result To UI""" if not Globals.enterprise_id: frame.loadConfigPrompt() if frame: frame.menubar.disableConfigMenu() logActionExecution(frame, action, group) if (action == GeneralActions.SHOW_ALL_AND_GENERATE_REPORT.value ) and not isUpdate: frame.gridPanel.emptyDeviceGrid() frame.gridPanel.emptyNetworkGrid() frame.gridPanel.disableGridProperties() if platform.system() == "Windows": frame.gridPanel.grid_1.Freeze() frame.gridPanel.grid_2.Freeze() frame.CSVUploaded = False deviceList = None if isDevice: deviceToUse = group frame.Logging("---> Making API Request") wxThread.doAPICallInThread( frame, apiCalls.getDeviceById, args=(deviceToUse), eventType=wxThread.myEVT_RESPONSE, callback=iterateThroughDeviceList, callbackArgs=(frame, action), optCallbackArgs=(Globals.enterprise_id, False, isUpdate), waitForJoin=False, name="iterateThroughDeviceListForDevice", ) elif action in Globals.GRID_ACTIONS: iterateThroughGridRows(frame, action) else: # Iterate Through Each Device in Group VIA Api Request try: groupToUse = group frame.Logging("---> Making API Request") if isUpdate: api_response = apiCalls.getAllDevices(groupToUse) deviceList = iterateThroughDeviceList(frame, action, api_response, Globals.enterprise_id, isUpdate=True) else: wxThread.doAPICallInThread( frame, apiCalls.getAllDevices, args=(groupToUse), eventType=wxThread.myEVT_RESPONSE, callback=iterateThroughDeviceList, callbackArgs=(frame, action), optCallbackArgs=(Globals.enterprise_id), waitForJoin=False, name="iterateThroughDeviceListForGroup", ) except ApiException as e: print("Exception when calling DeviceApi->get_all_devices: %s\n" % e) ApiToolLog().LogError(e) if deviceList: if isUpdate: postEventToFrame(wxThread.myEVT_UPDATE, deviceList) else: postEventToFrame(wxThread.myEVT_FETCH, (action, Globals.enterprise_id, deviceList))
def waitTillThreadsFinish(threads, action, entId, source, event=None, maxGauge=None): """ Wait till all threads have finished then send a signal back to the Main thread """ joinThreadList(threads) if source == 1: deviceList = {} for thread in threads: if type(thread.result) == tuple: deviceList = {**deviceList, **thread.result[1]} if maxGauge: postEventToFrame( wxThread.myEVT_UPDATE_GAUGE, int(len(deviceList) / maxGauge * 100), ) postEventToFrame(event, action) return (action, entId, deviceList, True, len(deviceList) * 2) if source == 2: postEventToFrame(wxThread.myEVT_COMPLETE, None) changeSucceeded = succeeded = numNewName = 0 tagsFromGrid = None for thread in threads: if type(thread.result) == tuple: changeSucceeded += thread.result[0] succeeded += thread.result[1] numNewName += thread.result[2] tagsFromGrid = thread.result[3] msg = ( "Successfully changed tags for %s of %s devices and aliases for %s of %s devices." % (changeSucceeded, len(tagsFromGrid.keys()), succeeded, numNewName)) postEventToFrame(wxThread.myEVT_LOG, msg) postEventToFrame( wxThread.myEVT_MESSAGE_BOX, (msg, wx.ICON_INFORMATION), ) if source == 3: deviceList = {} for thread in threads: if type(thread.result) == dict: deviceList = {**deviceList, **thread.result} return ( GeneralActions.SHOW_ALL_AND_GENERATE_REPORT.value, Globals.enterprise_id, deviceList, True, len(deviceList) * 2, ) if source == 4: postEventToFrame(wxThread.myEVT_THREAD_WAIT, (threads, 3, action))
def waitForCommandToFinish( frame, request_id, ignoreQueue=False, timeout=Globals.COMMAND_TIMEOUT, maxAttempt=Globals.MAX_RETRY, ): """ Wait until a Command is done or it times out """ api_instance = getCommandsApiInstance() response = None for attempt in range(maxAttempt): try: response = api_instance.get_command_request_status( Globals.enterprise_id, request_id) break except Exception as e: if attempt == maxAttempt - 1: ApiToolLog().LogError(e) raise e time.sleep(Globals.RETRY_SLEEP) if response and response.results: status = response.results[0] postEventToFrame(wxThread.myEVT_LOG, "---> Command state: %s" % str(status.state)) stateList = [ "Command Success", "Command Failure", "Command TimeOut", "Command Cancelled", "Command Queued", "Command Scheduled", ] if ignoreQueue: stateList.remove("Command Queued") start = time.perf_counter() while status.state not in stateList: end = time.perf_counter() duration = end - start if duration >= timeout: postEventToFrame( wxThread.myEVT_LOG, "---> Skipping wait for Command, last logged Command state: %s (Device may be offline)" % str(status.state), ) break for attempt in range(maxAttempt): try: response = api_instance.get_command_request_status( Globals.enterprise_id, request_id) break except Exception as e: if attempt == maxAttempt - 1: ApiToolLog().LogError(e) raise e time.sleep(Globals.RETRY_SLEEP) if response and response.results: status = response.results[0] postEventToFrame(wxThread.myEVT_LOG, "---> Command state: %s" % str(status.state)) time.sleep(3) return status else: return response.results