def main():
    """Command-line interface."""
    import argparse
    parser = argparse.ArgumentParser()
    bosdyn.client.util.add_common_arguments(parser)
    options = parser.parse_args()

    # Create robot object with an image client.
    sdk = bosdyn.client.create_standard_sdk('TimeSyncClient')
    sdk.load_app_token(options.app_token)
    robot = sdk.create_robot(options.hostname)
    robot.authenticate(options.username, options.password)
    time_sync_client = robot.ensure_client(TimeSyncClient.default_service_name)

    # The TimeSyncEndpoint wraps the TimeSyncClient
    time_sync_endpoint = TimeSyncEndpoint(time_sync_client)

    # The easiest way to establish time sync is to use this function, which makes several RPC calls
    # to TimeSyncUpdate, continually updating the clock skew estimate.
    did_establish = time_sync_endpoint.establish_timesync(
        max_samples=10, break_on_success=False)

    print("Did establish timesync: {}".format(did_establish))
    print("Client ID: {}".format(time_sync_endpoint.clock_identifier))
    print("Clock skew seconds: {} nanos: {}".format(
        time_sync_endpoint.clock_skew.seconds,
        time_sync_endpoint.clock_skew.nanos))
    print("Round trip time: {}".format(time_sync_endpoint.round_trip_time))
    return did_establish
Beispiel #2
0
def run_query(options, query):
    """Get data index from robot"""

    bosdyn.client.util.setup_logging(options.verbose)
    sdk = bosdyn.client.create_standard_sdk('GetIndexClient')
    robot = sdk.create_robot(options.hostname)
    robot.authenticate(options.username, options.password)
    service_client = robot.ensure_client(
        DataServiceClient.default_service_name)

    time_sync_endpoint = None
    if not options.robot_time:
        # Establish time sync with robot to obtain skew.
        time_sync_client = robot.ensure_client(
            TimeSyncClient.default_service_name)
        time_sync_endpoint = TimeSyncEndpoint(time_sync_client)
        if not time_sync_endpoint.establish_timesync():
            raise NotEstablishedError("time sync not established")

    # Now assemble the query to obtain a bddf file.

    # Get the parameters for limiting the timespan of the response.
    # pylint: disable=no-member
    query.time_range.CopyFrom(
        timespec_to_robot_timespan(options.timespan, time_sync_endpoint))
    return service_client.get_data_index(query)
Beispiel #3
0
def delete_pages(config):
    """Delete data pages from robot"""

    bosdyn.client.util.setup_logging(config.verbose)
    sdk = bosdyn.client.create_standard_sdk('DeletePagesClient')
    robot = sdk.create_robot(config.hostname)
    robot.authenticate(config.username, config.password)
    service_client = robot.ensure_client(
        DataServiceClient.default_service_name)

    start_timestamp = None
    end_timestamp = None
    time_range = None

    time_sync_endpoint = None
    if not config.robot_time:
        # Establish time sync with robot to obtain skew.
        time_sync_client = robot.ensure_client(
            TimeSyncClient.default_service_name)
        time_sync_endpoint = TimeSyncEndpoint(time_sync_client)
        if not time_sync_endpoint.establish_timesync():
            raise NotEstablishedError("time sync not established")

    if config.timespan:
        time_range = timespec_to_robot_timespan(config.timespan,
                                                time_sync_endpoint)

    print(service_client.delete_data_pages(time_range, config.id))
 def get_clock_skew(self):
     """Returns the client to robot clock_skew."""
     robot = self.get_authenticated_robot_client()
     if robot is not False:
         endpoint = TimeSyncEndpoint(
             robot.ensure_client(TimeSyncClient.default_service_name))
         if not endpoint.establish_timesync(break_on_success=False):
             logging.debug("Failed to achieve time sync.")
             return False
         return endpoint.clock_skew
Beispiel #5
0
def prepare_download(hostname, username, password, timespan, channel,
                     message_type, service):
    """Prepares all arguments for http get request."""

    # Create a robot object.
    sdk = create_standard_sdk('bddf')
    robot = sdk.create_robot(hostname)

    # Use the robot object to authenticate to the robot.
    # A JWT Token is required to download log data.
    try:
        robot.authenticate(username, password)
    except RpcError as err:
        LOGGER.error("Cannot authenticate to robot to obtain token: %s", err)
        return 1

    # Establish time sync with robot to obtain skew.
    time_sync_client = robot.ensure_client(TimeSyncClient.default_service_name)
    time_sync_endpoint = TimeSyncEndpoint(time_sync_client)
    did_establish = time_sync_endpoint.establish_timesync()
    if did_establish:
        LOGGER.debug("Established timesync, skew of sec:%d nanosec:%d",
                     time_sync_endpoint.clock_skew.seconds,
                     time_sync_endpoint.clock_skew.nanos)

    # Now assemble the query to obtain a bddf file.
    url = 'https://{}/v1/data-buffer/bddf/'.format(hostname)
    headers = {"Authorization": "Bearer {}".format(robot.user_token)}

    # Get the parameters for limiting the timespan of the response.
    get_params = request_timespan(timespan, time_sync_endpoint)

    # Optional parameters for limiting the messages
    if channel:
        get_params['channel'] = channel
    if message_type:
        get_params['type'] = message_type
    if service:
        get_params['grpc_service'] = service

    return url, headers, get_params
Beispiel #6
0
def get_pages(options):
    """Get data pages from robot"""

    bosdyn.client.util.setup_logging(options.verbose)
    sdk = bosdyn.client.create_standard_sdk('GetPagesClient')
    robot = sdk.create_robot(options.hostname)
    robot.authenticate(options.username, options.password)
    service_client = robot.ensure_client(
        DataServiceClient.default_service_name)

    time_sync_endpoint = None
    if not options.robot_time:
        # Establish time sync with robot to obtain skew.
        time_sync_client = robot.ensure_client(
            TimeSyncClient.default_service_name)
        time_sync_endpoint = TimeSyncEndpoint(time_sync_client)
        if not time_sync_endpoint.establish_timesync():
            raise NotEstablishedError("time sync not established")

    resp = service_client.get_data_pages(
        timespec_to_robot_timespan(options.timespan, time_sync_endpoint))
    print("-------- {} pages --------\n".format(len(resp.pages)))
    for page in resp.pages:
        _show_page(page)
Beispiel #7
0
def download_data(  # pylint: disable=too-many-arguments,too-many-locals
        robot,
        hostname,
        start_nsec=None,
        end_nsec=None,
        timespan_spec=None,
        output_filename=None,
        robot_time=False,
        channel=None,
        message_type=None,
        grpc_service=None,
        show_progress=False):
    """
    Download data from robot in bddf format

    Args:
      robot           API robot object
      hostname        hostname/ip-address of robot
      start_nsec      start time of log
      end_nsec        end time of log
      timespan_spec   if start_time, end_time are None, string representing the timespan to download
      robot_time      if True, timespan is in robot_clock, if False, in host clock
      channel         if set, limit data to download to a specific channel
      message_type    if set, limit data by specified message-type
      grpc_service    if set, limit GPRC log data by name of service

    Returns:
      output filename, or None on error
    """
    # pylint: disable=no-member
    # Suppress only the single warning from urllib3 needed.
    requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
    # pylint: enable=no-member

    time_sync_endpoint = None
    if not robot_time:
        # Establish time sync with robot to obtain skew.
        time_sync_client = robot.ensure_client(
            TimeSyncClient.default_service_name)
        time_sync_endpoint = TimeSyncEndpoint(time_sync_client)
        if not time_sync_endpoint.establish_timesync():
            raise NotEstablishedError("time sync not established")

    # Now assemble the query to obtain a bddf file.

    # Get the parameters for limiting the timespan of the response.
    if start_nsec or end_nsec:
        get_params = _request_timespan_from_nanoseconds(
            start_nsec, end_nsec, time_sync_endpoint)
    else:
        get_params = _request_timespan_from_spec(timespan_spec,
                                                 time_sync_endpoint)

    # Optional parameters for limiting the messages
    if channel:
        get_params['channel'] = channel
    if message_type:
        get_params['type'] = message_type
    if grpc_service:
        get_params['grpc_service'] = grpc_service

    # Request the data.
    url = _bddf_url(hostname)
    with requests.get(url,
                      headers=_http_headers(robot),
                      verify=False,
                      stream=True,
                      params=get_params) as resp:
        if resp.status_code != 200:
            LOGGER.error("%s %s response: %d", url, get_params,
                         resp.status_code)
            return None

        outfile = output_filename if output_filename else _output_filename(
            resp)
        with open(outfile, 'wb') as fid:
            for chunk in resp.iter_content(chunk_size=REQUEST_CHUNK_SIZE):
                if show_progress:
                    print('.', end='', flush=True)
                fid.write(chunk)
        if show_progress:
            print()

    return outfile
def time_sync():
    ts = TimeSyncEndpoint(None)
    ts._locked_previous_response = time_sync_pb2.TimeSyncUpdateResponse()
    ts.response.state.status = time_sync_pb2.TimeSyncState.STATUS_OK
    return ts
Beispiel #9
0
def main():  # pylint: disable=too-many-locals
    """Command-line interface"""
    import argparse  # pylint: disable=import-outside-toplevel
    parser = argparse.ArgumentParser()
    parser.add_argument('-T',
                        '--timespan',
                        help='Time span (default last 5 minutes)')
    parser.add_argument('--help-timespan',
                        action='store_true',
                        help='Print time span formatting options')
    parser.add_argument('-c',
                        '--channel',
                        help='Specify channel for data (default=all)')
    parser.add_argument('-t',
                        '--type',
                        help='Specify message type (default=all)')
    parser.add_argument('-s',
                        '--service',
                        help='Specify service name (default=all)')
    parser.add_argument('-o',
                        '--output',
                        help='Output file name (default is "download.bddf"')

    bosdyn.client.util.add_common_arguments(parser)
    options = parser.parse_args()

    if options.verbose:
        LOGGER.setLevel(logging.DEBUG)

    if options.help_timespan:
        _print_help_timespan()
        return 0

    # Create a robot object.
    sdk = create_standard_sdk('bddf')
    robot = sdk.create_robot(options.hostname)

    # Use the robot object to authenticate to the robot.
    # A JWT Token is required to download log data.
    try:
        robot.authenticate(options.username, options.password)
    except RpcError as err:
        LOGGER.error("Cannot authenticate to robot to obtain token: %s", err)
        return 1

    # Establish time sync with robot to obtain skew.
    time_sync_client = robot.ensure_client(TimeSyncClient.default_service_name)
    time_sync_endpoint = TimeSyncEndpoint(time_sync_client)
    did_establish = time_sync_endpoint.establish_timesync()
    if did_establish:
        LOGGER.debug("Established timesync, skew of sec:%d nanosec:%d",
                     time_sync_endpoint.clock_skew.seconds,
                     time_sync_endpoint.clock_skew.nanos)

    # Now assemble the query to obtain a bddf file.
    url = 'https://{}/v1/data-buffer/bddf/'.format(options.hostname)
    headers = {"Authorization": "Bearer {}".format(robot.user_token)}

    # Get the parameters for limiting the timespan of the response.
    get_params = request_timespan(options.timespan, time_sync_endpoint)

    # Optional parameters for limiting the messages
    if options.channel:
        get_params['channel'] = options.channel
    if options.type:
        get_params['type'] = options.type
    if options.service:
        get_params['grpc_service'] = options.service

    # Request the data.
    with requests.get(url,
                      headers=headers,
                      verify=False,
                      stream=True,
                      params=get_params) as resp:
        if resp.status_code != 200:
            LOGGER.error("https response: %d", resp.status_code)
            sys.exit(1)
        outfile = output_filename(options, resp)
        with open(outfile, 'wb') as fid:
            for chunk in resp.iter_content(chunk_size=REQUEST_CHUNK_SIZE):
                print('.', end='', flush=True)
                fid.write(chunk)
        print()

    LOGGER.info("Wrote '%s'.", outfile)
    return 0
Beispiel #10
0
def download_data(  # pylint: disable=too-many-arguments,too-many-locals
        robot,
        hostname,
        start_nsec=None,
        end_nsec=None,
        timespan_spec=None,
        output_filename=None,
        robot_time=False,
        channel=None,
        message_type=None,
        grpc_service=None,
        show_progress=False):
    """
    Download data from robot in bddf format

    Args:
      robot           API robot object
      hostname        hostname/ip-address of robot
      start_nsec      start time of log
      end_nsec        end time of log
      timespan_spec   if start_time, end_time are None, string representing the timespan to download
      robot_time      if True, timespan is in robot_clock, if False, in host clock
      channel         if set, limit data to download to a specific channel
      message_type    if set, limit data by specified message-type
      grpc_service    if set, limit GRPC log data by name of service

    Returns:
      output filename, or None on error
    """
    time_sync_endpoint = None
    if not robot_time:
        # Establish time sync with robot to obtain skew.
        time_sync_client = robot.ensure_client(
            TimeSyncClient.default_service_name)
        time_sync_endpoint = TimeSyncEndpoint(time_sync_client)
        if not time_sync_endpoint.establish_timesync():
            raise NotEstablishedError("time sync not established")

    # Now assemble the query to obtain a bddf file.

    # Get the parameters for limiting the timespan of the response.
    if start_nsec or end_nsec:
        get_params = _request_timespan_from_nanoseconds(
            start_nsec, end_nsec, time_sync_endpoint)
    else:
        get_params = _request_timespan_from_spec(timespan_spec,
                                                 time_sync_endpoint)

    # Optional parameters for limiting the messages
    if channel:
        get_params['channel'] = channel
    if message_type:
        get_params['type'] = message_type
    if grpc_service:
        get_params['grpc_service'] = grpc_service

    # Request the data.
    url = _bddf_url(hostname) + '?{}'.format(urlencode(get_params))
    request = Request(url, headers=_http_headers(robot))
    context = ssl._create_unverified_context()  # pylint: disable=protected-access
    with urlopen(request, context=context, timeout=REQUEST_TIMEOUT) as resp:
        if resp.status != 200:
            LOGGER.error("%s %s response: %d", url, get_params, resp.status)
            return None

        outfile = output_filename if output_filename else _output_filename(
            resp)
        with open(outfile, 'wb') as fid:
            while True:
                chunk = resp.read(REQUEST_CHUNK_SIZE)
                if len(chunk) == 0:
                    break
                if show_progress:
                    print('.', end='', flush=True)
                fid.write(chunk)
        if show_progress:
            print()

    return outfile