Example #1
0
def visualize(self, start_time=None, end_time=None):
    """
    Visualizes the fleet for the given time frame.

    Args:
        start_time (datetime.datetime or str): The start time, either as a datetime.datetime object or an ISO string. Set to the python fleet creation time if not set. Defaults to None.
        end_time (datetime.datetime or str): The end time, either as a datetime.datetime object or an ISO string. Set to the latest API call time if not set. Defaults to None.

    Returns:
        IFrame: A graphic view of the fleet through time.
    """
    if start_time is None:
        start_time = self.start_time

    if end_time is None:
        end_time = self.end_time

    if isinstance(start_time, str):
        start_time = isoparse(start_time)

    if isinstance(end_time, str):
        end_time = isoparse(end_time)

    url = self.vis_url.format(start=to_rfc3339(start_time),
                              end=to_rfc3339(end_time),
                              api_key=self.api_key,
                              fleet_key=self.fleet_key)

    print(url)

    return IPython.display.IFrame(url, 800, 800)
def cancel_request(self, rid, event_time=None):
    """
    Attempts to cancel a request.

    Args:
        rid (int): The unique request ID
        event_time (datetime.datetime, optional): Time of the cancellation. Set to datetime.datetime.now() if not provided. Defaults to None.

    Raises:
        StatusError: If unsuccessful.

    Returns:
        Status Response: If the request is sucessfully cancelled.
    """
    if event_time is None:
        event_time = datetime.datetime.now()

    if event_time > self.end_time:
        self.end_time = event_time

    url = self.build_url(Endpoints.CANCEL_REQUEST)
    payload = {
        'id': rid,
        'event_time': to_rfc3339(event_time),
        'user_key': self.user_key.todict()
    }

    r = requests.post(url, data = json.dumps(payload))
    resp = r.json()
    
    if r.status_code == 200:
        return StatusResponse(resp=resp)
    else:
        raise StatusError(resp=resp)
Example #3
0
def update_vehicle(self,
                   vid,
                   location,
                   event,
                   direction=Defaults.DEFAULT_DIRECTION,
                   event_time=None,
                   req_id=None):
    """
    Attempts to update a vehicle.

    Args:
        vid (int): The unique vehicle ID
        location (Location): The vehicle location.
        direction (float): Angle in radians clockwise away from true north
        event (VehicleEvent): Describes the current event for the vehicle. 
            pickup occurs when the vehicle has picked up a request. 
            dropoff occurs when the vehicle has dropped of a request. 
            progress should be set when the vehicle is moving to service a request, 
            either picking up or dropping off. The vehicle should be marked as 
            unassigned when it is is not assigned to any requests.
        event_time (datetime.datetime, optional): Time at which the vehicle update has occurred. 
            Set to datetime.datetime.now() if not provided. Defaults to None.
        req_id (int, optional): The unique ID of request the vehicle is servicing. 
            If the vehicle is unassigned, this may be omitted. Defaults to None.

    Returns:
        Vehicle: If successful.

    Raises:
        StatusError: If unsucessful.
    """
    if event_time is None:
        event_time = datetime.datetime.now()

    if event_time > self.end_time:
        self.end_time = event_time

    url = self.build_url(Endpoints.UPDATE_VEHICLE)
    payload = {
        'id': vid,
        'location': location.todict(),
        'direction': direction,
        'event_time': to_rfc3339(event_time),
        'event': event,
        'user_key': self.user_key.todict()
    }

    if req_id is not None:
        payload['req_id'] = req_id

    r = requests.post(url, data=json.dumps(payload))
    resp = r.json()

    if r.status_code == 200:
        return Vehicle.fromdict(self, resp)
    else:
        raise StatusError(resp=resp)
Example #4
0
def plot_metrics(self, metrics, start_time=None, end_time=None):
    """
    Plots time series metrics.

    Args:
        metrics (list[Metrics]): A list of metrics to plot.
        start_time (datetime.datetime or str): The start time, either as a datetime.datetime object or an ISO string. Set to the fleet creation time if not set. Defaults to None.
        end_time (datetime.datetime or str): The end time, either as a datetime.datetime object or an ISO string. Set to the latest API call time if not set. Defaults to None.

    Returns:
        Plotly.Figure: A figure that graphs the metrics
            over the time interval.
    """
    if start_time is None:
        start_time = self.start_time

    if end_time is None:
        end_time = self.end_time

    if isinstance(start_time, str):
        start_time = isoparse(start_time)

    if isinstance(end_time, str):
        end_time = isoparse(end_time)

    url = self.build_url(Endpoints.GRAPHQL)
    query = Metrics.QUERY.format(api_key=self.api_key,
                                 fleet_key=self.fleet_key,
                                 start_time=to_rfc3339(start_time),
                                 end_time=to_rfc3339(end_time))
    r = requests.post(url, json={"query": query})
    resp = r.json()
    data = resp['data']['live_fleets'][0]['metrics']
    x = [met[Metrics.TIME] for met in data]
    figure = go.Figure()
    for metric in metrics:
        figure.add_trace(
            go.Scatter(x=x,
                       y=[met[metric] for met in data],
                       mode='lines+markers',
                       name=metric))
    return figure
def forward_simulate(self, duration, current_time=None):
    """
    Forward simulates the fleet for a given duration.

    Args:
        duration (string): A duration to forward simulate for, e.g. "5m."
        current_time (datetime.datetime or str, optional): The current time, from when the simulation will begin. Can be provided as a datetime.datetime object or ISO string. Set to datetime.datetime.now() if not provided. Defaults to None.

    Returns:
        VehicleAssignments: The final state of all vehicles and requests, after the simulation.

    Raises:
        StatusError: If unsuccessful.
    """
    if current_time is None:
        current_time = datetime.datetime.now()

    if isinstance(current_time, str):
        current_time = isoparse(current_time)

    duration_td = datetime.timedelta(seconds=timeparse(duration))

    if current_time + duration_td > self.end_time:
        self.end_time = current_time + duration_td

    url = self.build_url(Endpoints.FORWARD_SIMULATE)
    payload = {
        'user_key': self.user_key.todict(),
        'sim_duration': duration,
        'current_time': to_rfc3339(current_time)
    }

    r = requests.post(url, data=json.dumps(payload))
    resp = r.json()

    if r.status_code == 200:
        return VehicleAssignments(
            vehs=[Vehicle.fromdict(self, veh) for veh in resp.get('vehs')],
            requests=[Request.fromdict(self, req) for req in resp.get('reqs')],
            notifications=[
                Notification.fromdict(notif)
                for notif in resp.get('notifications')
            ],
        )
    else:
        raise StatusError(resp=resp)
Example #6
0
    def todict(self):
        """
        Converts a Request to a python dict.

        Returns:
            dict: A dictionary representation of self.
        """
        return {
            'fleet': self.fleet.todict(),
            'pickup': self.pickup.todict(),
            'dropoff': self.dropoff.todict(),
            'request_time': to_rfc3339(self.request_time),
            'req_id': self.req_id,
            'veh_id': self.veh_id,
            'load': self.load,
            'assigned': self.assigned
        }
Example #7
0
def add_request(self, rid, pickup, dropoff, load, request_time=None):
    """
    Attempts to add a request.

    Args:
        rid (int): The unique request ID.
        pickup (Location): The pickup location.
        dropoff (Location): The dropoff location.
        load (int): The load (number of passengers).
        request_time (datetime.datetime, optional): Time of the request. This may be in the future for scheduled pickups. Set to datetime.datetime.now() if not provided. Defaults to None.

    Returns:
        StatusResponse: If successful.

    Raises:
        StatusError: If unsuccessful.
    """

    if request_time is None:
        request_time = datetime.datetime.now()

    if request_time > self.end_time:
        self.end_time = request_time

    url = self.build_url(Endpoints.ADD_REQUEST)
    payload = {
        'id': rid,
        'pickup': pickup.todict(),
        'dropoff': dropoff.todict(),
        'load': load,
        'request_time': to_rfc3339(request_time),
        'user_key': self.user_key.todict()
    }

    r = requests.post(url, data=json.dumps(payload))
    resp = r.json()

    if r.status_code == 200:
        return StatusResponse(resp=resp)
    else:
        raise StatusError(resp=resp)
def get_assignments(self, current_time=None):
    """
    Computes vehicle assignments for the fleet in the current state.

    Args:
        current_time (datetime.datetime, optional): Current time. Set to datetime.datetime.now() if not provided. Defaults to None.

    Raises:
        StatusError: If unsuccessful.

    Returns:
        VehicleAssignments: If assignments are successfully computed.
    """
    if current_time is None:
        current_time = datetime.datetime.now()

    if current_time > self.end_time:
        self.end_time = current_time

    url = self.build_url(Endpoints.COMPUTE_ASSIGNMENTS)
    payload = {
        'api_key': self.api_key,
        'fleet_key': self.fleet_key,
        'current_time': to_rfc3339(current_time)
    }

    r = requests.get(url, params=payload)
    resp = r.json()

    if r.status_code == 200:
        return VehicleAssignments(
            vehs=[Vehicle.fromdict(self, veh) for veh in resp.get('vehs')],
            requests=[Request.fromdict(self, req) for req in resp.get('reqs')],
            notifications=[
                Notification.fromdict(notif)
                for notif in resp.get('notifications')
            ],
        )
    else:
        raise StatusError(resp=resp)