def registerEvents(self): if not self._printerListener: self._printerListener = PrinterListener(self) printerManager().registerCallback(self._printerListener)
class AstroprintBoxRouterClient(WebSocketClient): def __init__(self, hostname, router): self._router = router self._printerListener = None self._lastReceived = 0 self._subscribers = 0 self._silentReconnect = False self._cameraManager = cameraManager() self._profileManager = printerProfileManager() self._logger = logging.getLogger(__name__) self._lineCheck = None self._error = False self._condition = threading.Condition() super(AstroprintBoxRouterClient, self).__init__(hostname) def send(self, data): with self._condition: if not self.terminated: try: super(AstroprintBoxRouterClient, self).send(data) except socket.error as e: self._logger.error('Error raised during send: %s' % e) self._error = True #Something happened to the link. Let's try to reset it self.close() def ponged(self, pong): if str(pong) == LINE_CHECK_STRING: self.outstandingPings -= 1 def lineCheck(self, timeout=30): while not self.terminated: sleep(timeout) if self.terminated: break if self.outstandingPings > 0: self._logger.error('The line seems to be down') self._router.close() self._router._doRetry() break if time() - self._lastReceived > timeout: try: self.send(PingControlMessage(data=LINE_CHECK_STRING)) self.outstandingPings += 1 except socket.error: self._logger.error("Line Check failed to send") #retry connection self._router.close() self._router._doRetry() self._lineCheckThread = None def terminate(self): #This is code to fix an apparent error in ws4py try: super(AstroprintBoxRouterClient, self).terminate() except AttributeError as e: if self.stream is None: self.environ = None else: raise e def opened(self): self.outstandingPings = 0 self._lineCheckThread = threading.Thread(target=self.lineCheck) self._lineCheckThread.daemon = True self._error = False self._lineCheckThread.start() def closed(self, code, reason=None): #only retry if the connection was terminated by the remote or a link check failure (silentReconnect) if self._error or (self.server_terminated and self._router.connected): self._router.close() self._router._doRetry() def received_message(self, m): self._lastReceived = time() msg = json.loads(str(m)) printer = printerManager() if msg['type'] == 'auth': self._router.processAuthenticate(msg['data'] if 'data' in msg else None) elif msg['type'] == 'set_temp': if printer.isOperational(): payload = msg['payload'] printer.setTemperature(payload['target'] or 0.0, payload['value'] or 0.0) elif msg['type'] == 'update_subscribers': self._subscribers += int(msg['data']) if not self._printerListener and self._subscribers > 0: self.registerEvents() elif self._printerListener and self._subscribers <= 0: self._subscribers = 0 self.unregisterEvents() elif msg['type'] == 'request': try: reqId = msg['reqId'] request = msg['data']['type'] data = msg['data']['payload'] if request == 'initial_state': response = { 'printing': printer.isPrinting(), 'operational': printer.isOperational(), 'paused': printer.isPaused(), 'camera': printer.isCameraConnected(), 'printCapture': self._cameraManager.timelapseInfo, 'profile': self._profileManager.data } elif request == 'job_info': response = printer._stateMonitor._jobData elif request == 'printerCommand': command = data['command'] options = data['options'] response = {'success': True} if command == 'pause' or command == 'resume': printer.togglePausePrint(); elif command == 'cancel': printer.cancelPrint(); elif command == 'photo': response['image_data'] = base64.b64encode(self._cameraManager.get_pic()) else: response = { 'error': True, 'message': 'Printer command [%s] is not supported' % command } elif request == 'printCapture': freq = data['freq'] if freq: if self._cameraManager.timelapseInfo: if self._cameraManager.update_timelapse(freq): response = {'success': True} else: response = { 'error': True, 'message': 'Error updating the print capture' } else: if self._cameraManager.start_timelapse(freq): response = {'success': True} else: response = { 'error': True, 'message': 'Error creating the print capture' } else: response = { 'error': True, 'message': 'Frequency required' } elif request == 'signoff': from astroprint.cloud import astroprintCloud self._logger.info('Remote signoff requested.') threading.Timer(1, astroprintCloud().remove_logged_user).start() response = {'success': True} else: response = { 'error': True, 'message': 'This Box does not recognize the request type [%s]' % request } self.send(json.dumps({ 'type': 'req_response', 'reqId': reqId, 'data': response })) except Exception as e: message = 'Error sending [%s] response: %s' % (request, e) self._logger.error( message ) self.send(json.dumps({ 'type': 'req_response', 'reqId': reqId, 'data': {'error': True, 'message':message } })) def registerEvents(self): if not self._printerListener: self._printerListener = PrinterListener(self) printerManager().registerCallback(self._printerListener) def unregisterEvents(self): if self._printerListener: printerManager().unregisterCallback(self._printerListener) self._printerListener.cleanup() self._printerListener = None
class AstroprintBoxRouterClient(WebSocketClient): def __init__(self, hostname, router): self._printerListener = None self._lastReceived = 0 self._lineCheck = None self._error = False self._weakRefRouter = weakref.ref(router) self._logger = logging.getLogger(__name__) self._condition = threading.Condition() self._messageHandler = BoxRouterMessageHandler(self._weakRefRouter, self) super(AstroprintBoxRouterClient, self).__init__(hostname) def __del__(self): self.unregisterEvents() def send(self, data): with self._condition: if not self.terminated: try: super(AstroprintBoxRouterClient, self).send(data) except socket.error as e: self._logger.error('Error raised during send: %s' % e) self._error = True #Something happened to the link. Let's try to reset it self.close() def ponged(self, pong): if str(pong) == LINE_CHECK_STRING: self.outstandingPings -= 1 def lineCheck(self, timeout=30): while not self.terminated: sleep(timeout) if self.terminated: break if self.outstandingPings > 0: self._logger.error('The line seems to be down') router = self._weakRefRouter() router.close() router._doRetry() break if time() - self._lastReceived > timeout: try: self.send(PingControlMessage(data=LINE_CHECK_STRING)) self.outstandingPings += 1 except socket.error: self._logger.error("Line Check failed to send") #retry connection router = self._weakRefRouter() router.close() router._doRetry() self._lineCheckThread = None def terminate(self): #This is code to fix an apparent error in ws4py try: self._th = None #If this is not freed, the socket can't be freed because of circular references super(AstroprintBoxRouterClient, self).terminate() except AttributeError as e: if self.stream is None: self.environ = None else: raise e def opened(self): self.outstandingPings = 0 self._lineCheckThread = threading.Thread(target=self.lineCheck) self._lineCheckThread.daemon = True self._error = False self._lineCheckThread.start() def closed(self, code, reason=None): #only retry if the connection was terminated by the remote or a link check failure (silentReconnect) router = self._weakRefRouter() if self._error or (self.server_terminated and router and router.connected): router.close() router._doRetry() def received_message(self, m): self._lastReceived = time() msg = json.loads(str(m)) method = getattr(self._messageHandler, msg['type'], None) if method: response = method(msg) if response is not None: self.send(json.dumps(response)) else: self._logger.warn('Unknown message type [%s] received' % msg['type']) def registerEvents(self): if not self._printerListener: self._printerListener = PrinterListener(self) printerManager().registerCallback(self._printerListener) def unregisterEvents(self): if self._printerListener: printerManager().unregisterCallback(self._printerListener) self._printerListener.cleanup() self._printerListener = None
class AstroprintBoxRouterClient(WebSocketClient): def __init__(self, hostname, router): self._weakRefRouter = weakref.ref(router) self._printerListener = None self._lastReceived = 0 self._subscribers = 0 self._silentReconnect = False self._profileManager = printerProfileManager() self._logger = logging.getLogger(__name__) self._lineCheck = None self._error = False self._condition = threading.Condition() super(AstroprintBoxRouterClient, self).__init__(hostname) def __del__(self): self.unregisterEvents() def send(self, data): with self._condition: if not self.terminated: try: super(AstroprintBoxRouterClient, self).send(data) except socket.error as e: self._logger.error('Error raised during send: %s' % e) self._error = True #Something happened to the link. Let's try to reset it self.close() def ponged(self, pong): if str(pong) == LINE_CHECK_STRING: self.outstandingPings -= 1 def lineCheck(self, timeout=30): while not self.terminated: sleep(timeout) if self.terminated: break if self.outstandingPings > 0: self._logger.error('The line seems to be down') router = self._weakRefRouter() router.close() router._doRetry() break if time() - self._lastReceived > timeout: try: self.send(PingControlMessage(data=LINE_CHECK_STRING)) self.outstandingPings += 1 except socket.error: self._logger.error("Line Check failed to send") #retry connection router = self._weakRefRouter() router.close() router._doRetry() self._lineCheckThread = None def terminate(self): #This is code to fix an apparent error in ws4py try: self._th = None #If this is not freed, the socket can't be freed because of circular references super(AstroprintBoxRouterClient, self).terminate() except AttributeError as e: if self.stream is None: self.environ = None else: raise e def opened(self): self.outstandingPings = 0 self._lineCheckThread = threading.Thread(target=self.lineCheck) self._lineCheckThread.daemon = True self._error = False self._lineCheckThread.start() def closed(self, code, reason=None): #only retry if the connection was terminated by the remote or a link check failure (silentReconnect) router = self._weakRefRouter() if self._error or (self.server_terminated and router and router.connected): router.close() router._doRetry() def received_message(self, m): self._lastReceived = time() msg = json.loads(str(m)) printer = printerManager() if msg['type'] == 'auth': router = self._weakRefRouter() router and router.processAuthenticate(msg['data'] if 'data' in msg else None) elif msg['type'] == 'set_temp': if printer.isOperational(): payload = msg['payload'] printer.setTemperature(payload['target'] or 0.0, payload['value'] or 0.0) elif msg['type'] == 'update_subscribers': self._subscribers += int(msg['data']) if not self._printerListener and self._subscribers > 0: self.registerEvents() elif self._printerListener and self._subscribers <= 0: self._subscribers = 0 self.unregisterEvents() elif msg['type'] == 'request': try: reqId = msg['reqId'] request = msg['data']['type'] data = msg['data']['payload'] if request == 'initial_state': response = { 'printing': printer.isPrinting(), 'operational': printer.isOperational(), 'paused': printer.isPaused(), 'camera': printer.isCameraConnected(), 'printCapture': cameraManager().timelapseInfo, 'profile': self._profileManager.data, 'remotePrint': True } elif request == 'job_info': response = printer._stateMonitor._jobData elif request == 'printerCommand': command = data['command'] options = data['options'] response = {'success': True} if command == 'pause' or command == 'resume': printer.togglePausePrint() elif command == 'cancel': printer.cancelPrint() elif command == 'photo': response['image_data'] = base64.b64encode( cameraManager().get_pic()) else: response = { 'error': True, 'message': 'Printer command [%s] is not supported' % command } elif request == 'printCapture': freq = data['freq'] if freq: cm = cameraManager() if cm.timelapseInfo: if cm.update_timelapse(freq): response = {'success': True} else: response = { 'error': True, 'message': 'Error updating the print capture' } else: if cm.start_timelapse(freq): response = {'success': True} else: response = { 'error': True, 'message': 'Error creating the print capture' } else: response = { 'error': True, 'message': 'Frequency required' } elif request == 'signoff': from astroprint.cloud import astroprintCloud self._logger.info('Remote signoff requested.') threading.Timer( 1, astroprintCloud().remove_logged_user).start() response = {'success': True} elif request == 'print_file': from astroprint.cloud import astroprintCloud from astroprint.printfiles import FileDestinations print_file_id = data['printFileId'] em = eventManager() def progressCb(progress): em.fire( Events.CLOUD_DOWNLOAD, { "type": "progress", "id": print_file_id, "progress": progress }) def successCb(destFile, fileInfo): if fileInfo is not True: if printer.fileManager.saveCloudPrintFile( destFile, fileInfo, FileDestinations.LOCAL): em.fire( Events.CLOUD_DOWNLOAD, { "type": "success", "id": print_file_id, "filename": printer.fileManager._getBasicFilename( destFile), "info": fileInfo["info"] }) else: errorCb(destFile, "Couldn't save the file") return abosluteFilename = printer.fileManager.getAbsolutePath( destFile) if printer.selectFile(abosluteFilename, False, True): self._printerListener._sendUpdate( 'print_file_download', { 'id': print_file_id, 'progress': 100, 'selected': True }) else: self._printerListener._sendUpdate( 'print_file_download', { 'id': print_file_id, 'progress': 100, 'error': True, 'message': 'Unable to start printing', 'selected': False }) def errorCb(destFile, error): if error == 'cancelled': em.fire(Events.CLOUD_DOWNLOAD, { "type": "cancelled", "id": print_file_id }) else: em.fire( Events.CLOUD_DOWNLOAD, { "type": "error", "id": print_file_id, "reason": error }) if destFile and os.path.exists(destFile): os.remove(destFile) if astroprintCloud().download_print_file( print_file_id, progressCb, successCb, errorCb): response = {'success': True} else: response = { 'error': True, 'message': 'Unable to start download process' } elif request == 'cancel_download': from astroprint.printfiles.downloadmanager import downloadManager print_file_id = data['printFileId'] if downloadManager().cancelDownload(print_file_id): response = {'success': True} else: response = { 'error': True, 'message': 'Unable to cancel download' } else: response = { 'error': True, 'message': 'This Box does not recognize the request type [%s]' % request } self.send( json.dumps({ 'type': 'req_response', 'reqId': reqId, 'data': response })) except Exception as e: message = 'Error sending [%s] response: %s' % (request, e) self._logger.error(message) self.send( json.dumps({ 'type': 'req_response', 'reqId': reqId, 'data': { 'error': True, 'message': message } })) def registerEvents(self): if not self._printerListener: self._printerListener = PrinterListener(self) printerManager().registerCallback(self._printerListener) def unregisterEvents(self): if self._printerListener: printerManager().unregisterCallback(self._printerListener) self._printerListener.cleanup() self._printerListener = None
class AstroprintBoxRouterClient(WebSocketClient): def __init__(self, hostname, router): #it needs to be imported here because on the main body 'printer' is None from octoprint.server import printer self._router = router self._printer = printer self._printerListener = None self._lastReceived = 0 self._subscribers = 0 self._silentReconnect = False self._cameraManager = cameraManager() self._profileManager = printerProfileManager() self._logger = logging.getLogger(__name__) self._lineCheck = None super(AstroprintBoxRouterClient, self).__init__(hostname) def send(self, data): try: WebSocketClient.send(self, data) except socket.error as e: self._logger.error('Error raised during send: %s' % e) #Something happened to the link. Let's try to reset it self.close() def ponged(self, pong): if str(pong) == LINE_CHECK_STRING: self.outstandingPings -= 1 def lineCheck(self, timeout=30): while not self.terminated: sleep(timeout) if self.terminated: break if self.outstandingPings > 0: self._logger.error('The line seems to be down') self._router.close() self._router._doRetry() break if time() - self._lastReceived > timeout: try: self.send(PingControlMessage(data=LINE_CHECK_STRING)) self.outstandingPings += 1 except socket.error: self._logger.error("Line Check failed to send") #retry connection self._router.close() self._router._doRetry() self._lineCheckThread = None def terminate(self): #This is code to fix an apparent error in ws4py try: super(AstroprintBoxRouterClient, self).terminate() except AttributeError as e: if self.stream is None: self.environ = None else: raise e def opened(self): self.outstandingPings = 0 self._lineCheckThread = threading.Thread(target=self.lineCheck) self._lineCheckThread.daemon = True self._lineCheckThread.start() def closed(self, code, reason=None): #only retry if the connection was terminated by the remote or a link check failure (silentReconnect) if self.server_terminated and self._router.connected: self._router.close() self._router._doRetry() def received_message(self, m): self._lastReceived = time() msg = json.loads(str(m)) if msg['type'] == 'auth': self._router.processAuthenticate(msg['data'] if 'data' in msg else None) elif msg['type'] == 'set_temp': if self._printer.isOperational(): payload = msg['payload'] self._printer.setTemperature(payload['target'] or 0.0, payload['value'] or 0.0) elif msg['type'] == 'update_subscribers': self._subscribers += int(msg['data']) if not self._printerListener and self._subscribers > 0: self.registerEvents() elif self._printerListener and self._subscribers <= 0: self._subscribers = 0 self.unregisterEvents() elif msg['type'] == 'request': try: reqId = msg['reqId'] request = msg['data']['type'] data = msg['data']['payload'] if request == 'initial_state': response = { 'printing': self._printer.isPrinting(), 'operational': self._printer.isOperational(), 'paused': self._printer.isPaused(), 'camera': self._printer.isCameraConnected(), 'printCapture': self._cameraManager.timelapseInfo, 'profile': self._profileManager.data } elif request == 'job_info': response = self._printer._stateMonitor._jobData elif request == 'printerCommand': command = data['command'] options = data['options'] response = {'success': True} if command == 'pause' or command == 'resume': self._printer.togglePausePrint() elif command == 'cancel': self._printer.cancelPrint() elif command == 'photo': response['image_data'] = base64.b64encode( self._cameraManager.get_pic()) else: response = { 'error': True, 'message': 'Printer command [%s] is not supported' % command } elif request == 'printCapture': freq = data['freq'] if freq: if self._cameraManager.timelapseInfo: if self._cameraManager.update_timelapse(freq): response = {'success': True} else: response = { 'error': True, 'message': 'Error updating the print capture' } else: if self._cameraManager.start_timelapse(freq): response = {'success': True} else: response = { 'error': True, 'message': 'Error creating the print capture' } else: response = { 'error': True, 'message': 'Frequency required' } else: response = { 'error': True, 'message': 'This Box does not recognize the request type [%s]' % request } self.send( json.dumps({ 'type': 'req_response', 'reqId': reqId, 'data': response })) except Exception as e: message = 'Error sending [%s] response: %s' % (request, e) self._logger.error(message) self.send( json.dumps({ 'type': 'req_response', 'reqId': reqId, 'data': { 'error': True, 'message': message } })) def registerEvents(self): if not self._printerListener: self._printerListener = PrinterListener(self) self._printer.registerCallback(self._printerListener) def unregisterEvents(self): if self._printerListener: self._printer.unregisterCallback(self._printerListener) self._printerListener.cleanup() self._printerListener = None
class AstroprintBoxRouterClient(WebSocketClient): def __init__(self, hostname, router): self._weakRefRouter = weakref.ref(router) self._printerListener = None self._lastReceived = 0 self._subscribers = 0 self._silentReconnect = False self._profileManager = printerProfileManager() self._logger = logging.getLogger(__name__) self._lineCheck = None self._error = False self._condition = threading.Condition() super(AstroprintBoxRouterClient, self).__init__(hostname) def __del__(self): self.unregisterEvents() def send(self, data): with self._condition: if not self.terminated: try: super(AstroprintBoxRouterClient, self).send(data) except socket.error as e: self._logger.error('Error raised during send: %s' % e) self._error = True #Something happened to the link. Let's try to reset it self.close() def ponged(self, pong): if str(pong) == LINE_CHECK_STRING: self.outstandingPings -= 1 def lineCheck(self, timeout=30): while not self.terminated: sleep(timeout) if self.terminated: break if self.outstandingPings > 0: self._logger.error('The line seems to be down') router = self._weakRefRouter() router.close() router._doRetry() break if time() - self._lastReceived > timeout: try: self.send(PingControlMessage(data=LINE_CHECK_STRING)) self.outstandingPings += 1 except socket.error: self._logger.error("Line Check failed to send") #retry connection router = self._weakRefRouter() router.close() router._doRetry() self._lineCheckThread = None def terminate(self): #This is code to fix an apparent error in ws4py try: self._th = None #If this is not freed, the socket can't be freed because of circular references super(AstroprintBoxRouterClient, self).terminate() except AttributeError as e: if self.stream is None: self.environ = None else: raise e def opened(self): self.outstandingPings = 0 self._lineCheckThread = threading.Thread(target=self.lineCheck) self._lineCheckThread.daemon = True self._error = False self._lineCheckThread.start() def closed(self, code, reason=None): #only retry if the connection was terminated by the remote or a link check failure (silentReconnect) router = self._weakRefRouter() if self._error or (self.server_terminated and router and router.connected): router.close() router._doRetry() def received_message(self, m): self._lastReceived = time() msg = json.loads(str(m)) printer = printerManager() if msg['type'] == 'auth': router = self._weakRefRouter() router and router.processAuthenticate(msg['data'] if 'data' in msg else None) elif msg['type'] == 'set_temp': if printer.isOperational(): payload = msg['payload'] printer.setTemperature(payload['target'] or 0.0, payload['value'] or 0.0) elif msg['type'] == 'update_subscribers': self._subscribers += int(msg['data']) if not self._printerListener and self._subscribers > 0: self.registerEvents() elif self._printerListener and self._subscribers <= 0: self._subscribers = 0 self.unregisterEvents() elif msg['type'] == 'request': try: reqId = msg['reqId'] request = msg['data']['type'] data = msg['data']['payload'] if request == 'initial_state': response = { 'printing': printer.isPrinting(), 'operational': printer.isOperational(), 'paused': printer.isPaused(), 'camera': printer.isCameraConnected(), 'printCapture': cameraManager().timelapseInfo, 'profile': self._profileManager.data, 'remotePrint': True } elif request == 'job_info': response = printer._stateMonitor._jobData elif request == 'printerCommand': command = data['command'] options = data['options'] response = {'success': True} if command == 'pause' or command == 'resume': printer.togglePausePrint(); elif command == 'cancel': printer.cancelPrint(); elif command == 'photo': response['image_data'] = base64.b64encode(cameraManager().get_pic()) else: response = { 'error': True, 'message': 'Printer command [%s] is not supported' % command } elif request == 'printCapture': freq = data['freq'] if freq: cm = cameraManager() if cm.timelapseInfo: if cm.update_timelapse(freq): response = {'success': True} else: response = { 'error': True, 'message': 'Error updating the print capture' } else: if cm.start_timelapse(freq): response = {'success': True} else: response = { 'error': True, 'message': 'Error creating the print capture' } else: response = { 'error': True, 'message': 'Frequency required' } elif request == 'signoff': from astroprint.cloud import astroprintCloud self._logger.info('Remote signoff requested.') threading.Timer(1, astroprintCloud().remove_logged_user).start() response = {'success': True} elif request == 'print_file': from astroprint.cloud import astroprintCloud from astroprint.printfiles import FileDestinations print_file_id = data['printFileId'] em = eventManager() def progressCb(progress): em.fire( Events.CLOUD_DOWNLOAD, { "type": "progress", "id": print_file_id, "progress": progress } ) def successCb(destFile, fileInfo): if fileInfo is not True: if printer.fileManager.saveCloudPrintFile(destFile, fileInfo, FileDestinations.LOCAL): em.fire( Events.CLOUD_DOWNLOAD, { "type": "success", "id": print_file_id, "filename": printer.fileManager._getBasicFilename(destFile), "info": fileInfo["info"] } ) else: errorCb(destFile, "Couldn't save the file") return abosluteFilename = printer.fileManager.getAbsolutePath(destFile) if printer.selectFile(abosluteFilename, False, True): self._printerListener._sendUpdate('print_file_download', { 'id': print_file_id, 'progress': 100, 'selected': True }) else: self._printerListener._sendUpdate('print_file_download', { 'id': print_file_id, 'progress': 100, 'error': True, 'message': 'Unable to start printing', 'selected': False }) def errorCb(destFile, error): if error == 'cancelled': em.fire( Events.CLOUD_DOWNLOAD, { "type": "cancelled", "id": print_file_id } ) else: em.fire( Events.CLOUD_DOWNLOAD, { "type": "error", "id": print_file_id, "reason": error } ) if destFile and os.path.exists(destFile): os.remove(destFile) if astroprintCloud().download_print_file(print_file_id, progressCb, successCb, errorCb): response = {'success': True} else: response = { 'error': True, 'message': 'Unable to start download process' } elif request == 'cancel_download': from astroprint.printfiles.downloadmanager import downloadManager print_file_id = data['printFileId'] if downloadManager().cancelDownload(print_file_id): response = {'success': True} else: response = { 'error': True, 'message': 'Unable to cancel download' } else: response = { 'error': True, 'message': 'This Box does not recognize the request type [%s]' % request } self.send(json.dumps({ 'type': 'req_response', 'reqId': reqId, 'data': response })) except Exception as e: message = 'Error sending [%s] response: %s' % (request, e) self._logger.error( message ) self.send(json.dumps({ 'type': 'req_response', 'reqId': reqId, 'data': {'error': True, 'message':message } })) def registerEvents(self): if not self._printerListener: self._printerListener = PrinterListener(self) printerManager().registerCallback(self._printerListener) def unregisterEvents(self): if self._printerListener: printerManager().unregisterCallback(self._printerListener) self._printerListener.cleanup() self._printerListener = None
class AstroprintBoxRouterClient(WebSocketClient): def __init__(self, hostname, router): #it needs to be imported here because on the main body 'printer' is None from octoprint.server import printer self._router = router self._printer = printer self._printerListener = None self._subscribers = 0 self._cameraManager = cameraManager() self._logger = logging.getLogger(__name__) WebSocketClient.__init__(self, hostname) def closed(self, code, reason=None): #only retry if the connection was terminated by the remote retry = self._router.connected self._router.close() if retry: self._router._doRetry() def received_message(self, m): msg = json.loads(str(m)) if msg['type'] == 'auth': self._router.processAuthenticate(msg['data'] if 'data' in msg else None) elif msg['type'] == 'set_temp': if self._printer.isOperational(): payload = msg['payload'] self._printer.setTemperature(payload['target'] or 0.0, payload['value'] or 0.0) elif msg['type'] == 'update_subscribers': self._subscribers += int(msg['data']) if not self._printerListener and self._subscribers > 0: self.registerEvents() elif self._printerListener and self._subscribers <= 0: self._subscribers = 0 self.unregisterEvents() elif msg['type'] == 'request': try: reqId = msg['reqId'] request = msg['data']['type'] data = msg['data']['payload'] if request == 'initial_state': response = { 'printing': self._printer.isPrinting(), 'operational': self._printer.isOperational(), 'paused': self._printer.isPaused(), 'camera': self._printer.isCameraConnected(), 'printCapture': self._cameraManager.timelapseInfo } elif request == 'job_info': response = self._printer._stateMonitor._jobData elif request == 'printerCommand': command = data['command'] options = data['options'] response = {'success': True} if command == 'pause' or command == 'resume': self._printer.togglePausePrint(); elif command == 'cancel': self._printer.cancelPrint(); elif command == 'photo': response['image_data'] = base64.b64encode(self._cameraManager.get_pic()) else: response = { 'error': True, 'message': 'Printer command [%s] is not supported' % command } elif request == 'printCapture': freq = data['freq'] if freq: if self._cameraManager.timelapseInfo: if self._cameraManager.update_timelapse(freq): response = {'success': True} else: response = { 'error': True, 'message': 'Error updating the print capture' } else: if self._cameraManager.start_timelapse(freq): response = {'success': True} else: response = { 'error': True, 'message': 'Error creating the print capture' } else: response = { 'error': True, 'message': 'Frequency required' } else: response = { 'error': True, 'message': 'This Box does not recognize the request type [%s]' % request } self.send(json.dumps({ 'type': 'req_response', 'reqId': reqId, 'data': response })) except Exception as e: message = 'Error sending [%s] response: %s' % (request, e) self._logger.error( message ) self.send(json.dumps({ 'type': 'req_response', 'reqId': reqId, 'data': {'error': True, 'message':message } })) def registerEvents(self): if not self._printerListener: self._printerListener = PrinterListener(self) self._printer.registerCallback(self._printerListener) def unregisterEvents(self): if self._printerListener: self._printer.unregisterCallback(self._printerListener) self._printerListener.cleanup() self._printerListener = None