def Tick(self, request, context): """Logs text, then provides a valid response.""" response = remote_pb2.TickResponse() # This utility context manager will fill out some fields in the message headers. with ResponseContext(response, request): # Default to saying hello to "world". name = 'World' # See if a different name was provided to us in the request's inputs. # This "user-string" input is provided by the Autowalk missions. # To provide other inputs, see the RemoteGrpc message. for keyvalue in request.inputs: if keyvalue.key == 'user-string': name = util.get_value_from_constant_value_message( keyvalue.value.constant) self.logger.info('Hello %s!', name) response.status = remote_pb2.TickResponse.STATUS_SUCCESS return response
def _tick_implementation(self, request, response): """Make a power off request if none has been made; otherwise check request progress.""" # Verify we know about the session ID. if request.session_id not in self.sessions_by_id: self.logger.error('Do not know about session ID "%s"', request.session_id) response.status = remote_pb2.TickResponse.STATUS_INVALID_SESSION_ID return # Make a sublease of the provided lease, or fill out the response with an error. current_lease = self._sublease_or_none( request.leases, response, remote_pb2.TickResponse.STATUS_MISSING_LEASES) if current_lease is None: return node_name = '<unknown>' # This node_name input is provided by the Autowalk missions. # To provide other inputs, see the RemoteGrpc message. for keyvalue in request.inputs: if keyvalue.key == 'user-string': node_name = util.get_value_from_constant_value_message( keyvalue.value.constant) self.logger.info('Ticked by node "%s"', node_name) cmd_client = self.bosdyn_sdk_robot.ensure_client( RobotCommandClient.default_service_name) # The client to the robot maintains a "wallet" of leases to use for its requests. # Inform it about the lease provided by the client to this service. cmd_client.lease_wallet.add(current_lease) # Because SafePowerOff can take a while, we also need to Retain the lease, to tell the # robot that we're still using it. lease_client = self.bosdyn_sdk_robot.ensure_client( LeaseClient.default_service_name) # We'll "fire and forget" the retain RPC -- if it doesn't succeed, the robot will # go through its comms loss policy. lease_client.retain_lease_async(current_lease) self._perform_and_monitor_power_off(cmd_client, request.session_id, response)
def _tick_implementation(self, request, response): # This callback_text input is provided by the Autowalk missions. callback_text = '<unknown>' for keyvalue in request.inputs: if keyvalue.key == 'user-string': callback_text = util.get_value_from_constant_value_message( keyvalue.value.constant) self.logger.info("The callback text is {}.".format(callback_text)) # Defining helper functions for appropriate Error handling. def populate_error_response(mesg): self.logger.exception(mesg) response.header.error.code = header_pb2.CommonError.CODE_INTERNAL_SERVER_ERROR response.header.error.message = mesg response.status = remote_pb2.TickResponse.STATUS_FAILURE def take_picture_helper(): try: self.camera.takePicture() self.logger.info('theta took a picture') response.status = remote_pb2.TickResponse.STATUS_SUCCESS except RequestException as e: populate_error_response( 'Ricoh take picture command failed. Ensure ricoh theta is connected to spot. ' + str(e)) def download_helper(): try: self.camera.downloadMissionImages(DEFAULT_PATH) self.logger.info('theta downloaded mission images') response.status = remote_pb2.TickResponse.STATUS_SUCCESS except RequestException as e: populate_error_response( 'Download attempt failed. Ensure ricoh theta is connected to spot. ' + str(e)) except Exception as e: populate_error_response( 'Download failed. Please check download/file path. ' + str(e)) def upload_to_cloud_helper(upload_func, bucket_name): """Uploads all images taken during mission to cloud service. Args: upload_func (function): upload_to_aws or upload_to_gcp bucket_name (str): "cloud-bucket-name" """ for dir_path in self.camera.download_paths: for image_file in os.listdir(dir_path): src_filename = os.path.join(dir_path, image_file) try: upload_func(bucket_name, src_filename, image_file) response.status = remote_pb2.TickResponse.STATUS_SUCCESS except Exception as e: populate_error_response( 'Upload to cloud failed. Please check cloud storage parameters/credentials. ' + str(e)) # Check callback_text for applicable commands. if callback_text.startswith("take theta image"): take_picture_helper() elif callback_text.startswith("download theta images"): download_helper() elif callback_text.startswith("upload to gcp"): # download remaining images download_helper() # upload all mission images upload_to_cloud_helper(upload_to_gcp, GCP_BUCKET_NAME) elif callback_text.startswith("upload to aws"): # download remaining images download_helper() # upload all mission images upload_to_cloud_helper(upload_to_aws, AWS_BUCKET_NAME) else: self.logger.info('Callback text \'' + str(callback_text) + '\' is not a valid option.') response.status = remote_pb2.TickResponse.STATUS_FAILURE