Add here_travel_time (#24603)

* Add here_travel_time

* Bump herepy version to 0.6.2

* Update requirements_all.txt

* Disable pylint and catch errors

* Add herepy to requirements_test_all

* Correctly place test req for herepy

* use homeassistant.const.LENGTH_METERS

* Implemented Requested Changes

* Better error message for cryptic error code

* add requested changes

* add_entities instead of async

* Add route attr and distance in km instead of m

* fix linting errors

* attribute duration in minutes instead of seconds

* Correct pattern for longitude

* dont split attribute but rather local var

* move strings to const and use travelTime

* Add tests

* Add route for pedestrian and public

* fix public transport route generation

* remove print statement

* Standalone pytest

* Use hass fixture and increase test cov
_resolve_zone is redundant

* Clean up redundant code

* Add type annotations

* Readd _resolve_zone and add a test for it

* Full test cov

* use caplog

* Add origin/destination attributes
According to https://github.com/home-assistant/home-assistant/pull/24956

* Add mode: bicycle

* black

* Add mode: publicTransportTimeTable

* Fix error for publicTransportTimeTable
Switch route_mode and travel_mode in api request.

* split up config options

* More type hints

* implement *_entity_id

* align attributes with google_travel_time

* route in lib
apply requested changes

* Update requirements_all.txt

* remove DATA_KEY

* Use ATTR_MODE

* add attribution

* Only add attribution if not none

* Add debug log for raw response

* Add _build_hass_attribution

* clearer var names in credentials check

* async _are_valid_client_credentials
pull/26847/head
Kevin Eifinger 2019-09-23 11:50:18 +02:00 committed by Martin Hjelmare
parent 5c7f869f9b
commit 5c0fa35d4a
20 changed files with 3911 additions and 0 deletions

View File

@ -115,6 +115,7 @@ homeassistant/components/gtfs/* @robbiet480
homeassistant/components/harmony/* @ehendrix23
homeassistant/components/hassio/* @home-assistant/hass-io
homeassistant/components/heos/* @andrewsayre
homeassistant/components/here_travel_time/* @eifinger
homeassistant/components/hikvision/* @mezz64
homeassistant/components/hikvisioncam/* @fbradyirl
homeassistant/components/history/* @home-assistant/core

View File

@ -0,0 +1 @@
"""The here_travel_time component."""

View File

@ -0,0 +1,12 @@
{
"domain": "here_travel_time",
"name": "HERE travel time",
"documentation": "https://www.home-assistant.io/components/here_travel_time",
"requirements": [
"herepy==0.6.3.1"
],
"dependencies": [],
"codeowners": [
"@eifinger"
]
}

View File

@ -0,0 +1,431 @@
"""Support for HERE travel time sensors."""
from datetime import timedelta
import logging
from typing import Callable, Dict, Optional, Union
import herepy
import voluptuous as vol
from homeassistant.components.sensor import PLATFORM_SCHEMA
from homeassistant.const import (
ATTR_ATTRIBUTION,
ATTR_LATITUDE,
ATTR_LONGITUDE,
CONF_MODE,
CONF_NAME,
CONF_UNIT_SYSTEM,
CONF_UNIT_SYSTEM_IMPERIAL,
CONF_UNIT_SYSTEM_METRIC,
)
from homeassistant.core import HomeAssistant, State
from homeassistant.helpers import location
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import Entity
_LOGGER = logging.getLogger(__name__)
CONF_DESTINATION_LATITUDE = "destination_latitude"
CONF_DESTINATION_LONGITUDE = "destination_longitude"
CONF_DESTINATION_ENTITY_ID = "destination_entity_id"
CONF_ORIGIN_LATITUDE = "origin_latitude"
CONF_ORIGIN_LONGITUDE = "origin_longitude"
CONF_ORIGIN_ENTITY_ID = "origin_entity_id"
CONF_APP_ID = "app_id"
CONF_APP_CODE = "app_code"
CONF_TRAFFIC_MODE = "traffic_mode"
CONF_ROUTE_MODE = "route_mode"
DEFAULT_NAME = "HERE Travel Time"
TRAVEL_MODE_BICYCLE = "bicycle"
TRAVEL_MODE_CAR = "car"
TRAVEL_MODE_PEDESTRIAN = "pedestrian"
TRAVEL_MODE_PUBLIC = "publicTransport"
TRAVEL_MODE_PUBLIC_TIME_TABLE = "publicTransportTimeTable"
TRAVEL_MODE_TRUCK = "truck"
TRAVEL_MODE = [
TRAVEL_MODE_BICYCLE,
TRAVEL_MODE_CAR,
TRAVEL_MODE_PEDESTRIAN,
TRAVEL_MODE_PUBLIC,
TRAVEL_MODE_PUBLIC_TIME_TABLE,
TRAVEL_MODE_TRUCK,
]
TRAVEL_MODES_PUBLIC = [TRAVEL_MODE_PUBLIC, TRAVEL_MODE_PUBLIC_TIME_TABLE]
TRAVEL_MODES_VEHICLE = [TRAVEL_MODE_CAR, TRAVEL_MODE_TRUCK]
TRAVEL_MODES_NON_VEHICLE = [TRAVEL_MODE_BICYCLE, TRAVEL_MODE_PEDESTRIAN]
TRAFFIC_MODE_ENABLED = "traffic_enabled"
TRAFFIC_MODE_DISABLED = "traffic_disabled"
ROUTE_MODE_FASTEST = "fastest"
ROUTE_MODE_SHORTEST = "shortest"
ROUTE_MODE = [ROUTE_MODE_FASTEST, ROUTE_MODE_SHORTEST]
ICON_BICYCLE = "mdi:bike"
ICON_CAR = "mdi:car"
ICON_PEDESTRIAN = "mdi:walk"
ICON_PUBLIC = "mdi:bus"
ICON_TRUCK = "mdi:truck"
UNITS = [CONF_UNIT_SYSTEM_METRIC, CONF_UNIT_SYSTEM_IMPERIAL]
ATTR_DURATION = "duration"
ATTR_DISTANCE = "distance"
ATTR_ROUTE = "route"
ATTR_ORIGIN = "origin"
ATTR_DESTINATION = "destination"
ATTR_MODE = "mode"
ATTR_UNIT_SYSTEM = CONF_UNIT_SYSTEM
ATTR_TRAFFIC_MODE = CONF_TRAFFIC_MODE
ATTR_DURATION_IN_TRAFFIC = "duration_in_traffic"
ATTR_ORIGIN_NAME = "origin_name"
ATTR_DESTINATION_NAME = "destination_name"
UNIT_OF_MEASUREMENT = "min"
SCAN_INTERVAL = timedelta(minutes=5)
TRACKABLE_DOMAINS = ["device_tracker", "sensor", "zone", "person"]
NO_ROUTE_ERROR_MESSAGE = "HERE could not find a route based on the input"
COORDINATE_SCHEMA = vol.Schema(
{
vol.Inclusive(CONF_DESTINATION_LATITUDE, "coordinates"): cv.latitude,
vol.Inclusive(CONF_DESTINATION_LONGITUDE, "coordinates"): cv.longitude,
}
)
PLATFORM_SCHEMA = vol.All(
cv.has_at_least_one_key(CONF_DESTINATION_LATITUDE, CONF_DESTINATION_ENTITY_ID),
cv.has_at_least_one_key(CONF_ORIGIN_LATITUDE, CONF_ORIGIN_ENTITY_ID),
PLATFORM_SCHEMA.extend(
{
vol.Required(CONF_APP_ID): cv.string,
vol.Required(CONF_APP_CODE): cv.string,
vol.Inclusive(
CONF_DESTINATION_LATITUDE, "destination_coordinates"
): cv.latitude,
vol.Inclusive(
CONF_DESTINATION_LONGITUDE, "destination_coordinates"
): cv.longitude,
vol.Exclusive(CONF_DESTINATION_LATITUDE, "destination"): cv.latitude,
vol.Exclusive(CONF_DESTINATION_ENTITY_ID, "destination"): cv.entity_id,
vol.Inclusive(CONF_ORIGIN_LATITUDE, "origin_coordinates"): cv.latitude,
vol.Inclusive(CONF_ORIGIN_LONGITUDE, "origin_coordinates"): cv.longitude,
vol.Exclusive(CONF_ORIGIN_LATITUDE, "origin"): cv.latitude,
vol.Exclusive(CONF_ORIGIN_ENTITY_ID, "origin"): cv.entity_id,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_MODE, default=TRAVEL_MODE_CAR): vol.In(TRAVEL_MODE),
vol.Optional(CONF_ROUTE_MODE, default=ROUTE_MODE_FASTEST): vol.In(
ROUTE_MODE
),
vol.Optional(CONF_TRAFFIC_MODE, default=False): cv.boolean,
vol.Optional(CONF_UNIT_SYSTEM): vol.In(UNITS),
}
),
)
async def async_setup_platform(
hass: HomeAssistant,
config: Dict[str, Union[str, bool]],
async_add_entities: Callable,
discovery_info: None = None,
) -> None:
"""Set up the HERE travel time platform."""
app_id = config[CONF_APP_ID]
app_code = config[CONF_APP_CODE]
here_client = herepy.RoutingApi(app_id, app_code)
if not await hass.async_add_executor_job(
_are_valid_client_credentials, here_client
):
_LOGGER.error(
"Invalid credentials. This error is returned if the specified token was invalid or no contract could be found for this token."
)
return
if config.get(CONF_ORIGIN_LATITUDE) is not None:
origin = f"{config[CONF_ORIGIN_LATITUDE]},{config[CONF_ORIGIN_LONGITUDE]}"
else:
origin = config[CONF_ORIGIN_ENTITY_ID]
if config.get(CONF_DESTINATION_LATITUDE) is not None:
destination = (
f"{config[CONF_DESTINATION_LATITUDE]},{config[CONF_DESTINATION_LONGITUDE]}"
)
else:
destination = config[CONF_DESTINATION_ENTITY_ID]
travel_mode = config[CONF_MODE]
traffic_mode = config[CONF_TRAFFIC_MODE]
route_mode = config[CONF_ROUTE_MODE]
name = config[CONF_NAME]
units = config.get(CONF_UNIT_SYSTEM, hass.config.units.name)
here_data = HERETravelTimeData(
here_client, travel_mode, traffic_mode, route_mode, units
)
sensor = HERETravelTimeSensor(name, origin, destination, here_data)
async_add_entities([sensor], True)
def _are_valid_client_credentials(here_client: herepy.RoutingApi) -> bool:
"""Check if the provided credentials are correct using defaults."""
known_working_origin = [38.9, -77.04833]
known_working_destination = [39.0, -77.1]
try:
here_client.car_route(
known_working_origin,
known_working_destination,
[
herepy.RouteMode[ROUTE_MODE_FASTEST],
herepy.RouteMode[TRAVEL_MODE_CAR],
herepy.RouteMode[TRAFFIC_MODE_DISABLED],
],
)
except herepy.InvalidCredentialsError:
return False
return True
class HERETravelTimeSensor(Entity):
"""Representation of a HERE travel time sensor."""
def __init__(
self, name: str, origin: str, destination: str, here_data: "HERETravelTimeData"
) -> None:
"""Initialize the sensor."""
self._name = name
self._here_data = here_data
self._unit_of_measurement = UNIT_OF_MEASUREMENT
self._origin_entity_id = None
self._destination_entity_id = None
self._attrs = {
ATTR_UNIT_SYSTEM: self._here_data.units,
ATTR_MODE: self._here_data.travel_mode,
ATTR_TRAFFIC_MODE: self._here_data.traffic_mode,
}
# Check if location is a trackable entity
if origin.split(".", 1)[0] in TRACKABLE_DOMAINS:
self._origin_entity_id = origin
else:
self._here_data.origin = origin
if destination.split(".", 1)[0] in TRACKABLE_DOMAINS:
self._destination_entity_id = destination
else:
self._here_data.destination = destination
@property
def state(self) -> Optional[str]:
"""Return the state of the sensor."""
if self._here_data.traffic_mode:
if self._here_data.traffic_time is not None:
return str(round(self._here_data.traffic_time / 60))
if self._here_data.base_time is not None:
return str(round(self._here_data.base_time / 60))
return None
@property
def name(self) -> str:
"""Get the name of the sensor."""
return self._name
@property
def device_state_attributes(
self
) -> Optional[Dict[str, Union[None, float, str, bool]]]:
"""Return the state attributes."""
if self._here_data.base_time is None:
return None
res = self._attrs
if self._here_data.attribution is not None:
res[ATTR_ATTRIBUTION] = self._here_data.attribution
res[ATTR_DURATION] = self._here_data.base_time / 60
res[ATTR_DISTANCE] = self._here_data.distance
res[ATTR_ROUTE] = self._here_data.route
res[ATTR_DURATION_IN_TRAFFIC] = self._here_data.traffic_time / 60
res[ATTR_ORIGIN] = self._here_data.origin
res[ATTR_DESTINATION] = self._here_data.destination
res[ATTR_ORIGIN_NAME] = self._here_data.origin_name
res[ATTR_DESTINATION_NAME] = self._here_data.destination_name
return res
@property
def unit_of_measurement(self) -> str:
"""Return the unit this state is expressed in."""
return self._unit_of_measurement
@property
def icon(self) -> str:
"""Icon to use in the frontend depending on travel_mode."""
if self._here_data.travel_mode == TRAVEL_MODE_BICYCLE:
return ICON_BICYCLE
if self._here_data.travel_mode == TRAVEL_MODE_PEDESTRIAN:
return ICON_PEDESTRIAN
if self._here_data.travel_mode in TRAVEL_MODES_PUBLIC:
return ICON_PUBLIC
if self._here_data.travel_mode == TRAVEL_MODE_TRUCK:
return ICON_TRUCK
return ICON_CAR
async def async_update(self) -> None:
"""Update Sensor Information."""
# Convert device_trackers to HERE friendly location
if self._origin_entity_id is not None:
self._here_data.origin = await self._get_location_from_entity(
self._origin_entity_id
)
if self._destination_entity_id is not None:
self._here_data.destination = await self._get_location_from_entity(
self._destination_entity_id
)
await self.hass.async_add_executor_job(self._here_data.update)
async def _get_location_from_entity(self, entity_id: str) -> Optional[str]:
"""Get the location from the entity state or attributes."""
entity = self.hass.states.get(entity_id)
if entity is None:
_LOGGER.error("Unable to find entity %s", entity_id)
return None
# Check if the entity has location attributes
if location.has_location(entity):
return self._get_location_from_attributes(entity)
# Check if device is in a zone
zone_entity = self.hass.states.get("zone.{}".format(entity.state))
if location.has_location(zone_entity):
_LOGGER.debug(
"%s is in %s, getting zone location", entity_id, zone_entity.entity_id
)
return self._get_location_from_attributes(zone_entity)
# If zone was not found in state then use the state as the location
if entity_id.startswith("sensor."):
return entity.state
@staticmethod
def _get_location_from_attributes(entity: State) -> str:
"""Get the lat/long string from an entities attributes."""
attr = entity.attributes
return "{},{}".format(attr.get(ATTR_LATITUDE), attr.get(ATTR_LONGITUDE))
class HERETravelTimeData:
"""HERETravelTime data object."""
def __init__(
self,
here_client: herepy.RoutingApi,
travel_mode: str,
traffic_mode: bool,
route_mode: str,
units: str,
) -> None:
"""Initialize herepy."""
self.origin = None
self.destination = None
self.travel_mode = travel_mode
self.traffic_mode = traffic_mode
self.route_mode = route_mode
self.attribution = None
self.traffic_time = None
self.distance = None
self.route = None
self.base_time = None
self.origin_name = None
self.destination_name = None
self.units = units
self._client = here_client
def update(self) -> None:
"""Get the latest data from HERE."""
if self.traffic_mode:
traffic_mode = TRAFFIC_MODE_ENABLED
else:
traffic_mode = TRAFFIC_MODE_DISABLED
if self.destination is not None and self.origin is not None:
# Convert location to HERE friendly location
destination = self.destination.split(",")
origin = self.origin.split(",")
_LOGGER.debug(
"Requesting route for origin: %s, destination: %s, route_mode: %s, mode: %s, traffic_mode: %s",
origin,
destination,
herepy.RouteMode[self.route_mode],
herepy.RouteMode[self.travel_mode],
herepy.RouteMode[traffic_mode],
)
try:
response = self._client.car_route(
origin,
destination,
[
herepy.RouteMode[self.route_mode],
herepy.RouteMode[self.travel_mode],
herepy.RouteMode[traffic_mode],
],
)
except herepy.NoRouteFoundError:
# Better error message for cryptic no route error codes
_LOGGER.error(NO_ROUTE_ERROR_MESSAGE)
return
_LOGGER.debug("Raw response is: %s", response.response)
# pylint: disable=no-member
source_attribution = response.response.get("sourceAttribution")
if source_attribution is not None:
self.attribution = self._build_hass_attribution(source_attribution)
# pylint: disable=no-member
route = response.response["route"]
summary = route[0]["summary"]
waypoint = route[0]["waypoint"]
self.base_time = summary["baseTime"]
if self.travel_mode in TRAVEL_MODES_VEHICLE:
self.traffic_time = summary["trafficTime"]
else:
self.traffic_time = self.base_time
distance = summary["distance"]
if self.units == CONF_UNIT_SYSTEM_IMPERIAL:
# Convert to miles.
self.distance = distance / 1609.344
else:
# Convert to kilometers
self.distance = distance / 1000
# pylint: disable=no-member
self.route = response.route_short
self.origin_name = waypoint[0]["mappedRoadName"]
self.destination_name = waypoint[1]["mappedRoadName"]
@staticmethod
def _build_hass_attribution(source_attribution: Dict) -> Optional[str]:
"""Build a hass frontend ready string out of the sourceAttribution."""
suppliers = source_attribution.get("supplier")
if suppliers is not None:
supplier_titles = []
for supplier in suppliers:
title = supplier.get("title")
if title is not None:
supplier_titles.append(title)
joined_supplier_titles = ",".join(supplier_titles)
attribution = f"With the support of {joined_supplier_titles}. All information is provided without warranty of any kind."
return attribution

View File

@ -619,6 +619,9 @@ hdate==0.9.0
# homeassistant.components.heatmiser
heatmiserV3==0.9.1
# homeassistant.components.here_travel_time
herepy==0.6.3.1
# homeassistant.components.hikvisioncam
hikvision==0.4

View File

@ -171,6 +171,9 @@ hbmqtt==0.9.5
# homeassistant.components.jewish_calendar
hdate==0.9.0
# homeassistant.components.here_travel_time
herepy==0.6.3.1
# homeassistant.components.pi_hole
hole==0.5.0

View File

@ -87,6 +87,7 @@ TEST_REQUIREMENTS = (
"haversine",
"hbmqtt",
"hdate",
"herepy",
"hole",
"holidays",
"home-assistant-frontend",

View File

@ -0,0 +1 @@
"""Tests for here_travel_time component."""

View File

@ -0,0 +1,947 @@
"""The test for the here_travel_time sensor platform."""
import logging
from unittest.mock import patch
import urllib
import herepy
import pytest
from homeassistant.components.here_travel_time.sensor import (
ATTR_ATTRIBUTION,
ATTR_DESTINATION,
ATTR_DESTINATION_NAME,
ATTR_DISTANCE,
ATTR_DURATION,
ATTR_DURATION_IN_TRAFFIC,
ATTR_ORIGIN,
ATTR_ORIGIN_NAME,
ATTR_ROUTE,
CONF_MODE,
CONF_TRAFFIC_MODE,
CONF_UNIT_SYSTEM,
ICON_BICYCLE,
ICON_CAR,
ICON_PEDESTRIAN,
ICON_PUBLIC,
ICON_TRUCK,
NO_ROUTE_ERROR_MESSAGE,
ROUTE_MODE_FASTEST,
ROUTE_MODE_SHORTEST,
SCAN_INTERVAL,
TRAFFIC_MODE_DISABLED,
TRAFFIC_MODE_ENABLED,
TRAVEL_MODE_BICYCLE,
TRAVEL_MODE_CAR,
TRAVEL_MODE_PEDESTRIAN,
TRAVEL_MODE_PUBLIC,
TRAVEL_MODE_PUBLIC_TIME_TABLE,
TRAVEL_MODE_TRUCK,
UNIT_OF_MEASUREMENT,
)
from homeassistant.const import ATTR_ICON
from homeassistant.setup import async_setup_component
import homeassistant.util.dt as dt_util
from tests.common import async_fire_time_changed, load_fixture
DOMAIN = "sensor"
PLATFORM = "here_travel_time"
APP_ID = "test"
APP_CODE = "test"
TRUCK_ORIGIN_LATITUDE = "41.9798"
TRUCK_ORIGIN_LONGITUDE = "-87.8801"
TRUCK_DESTINATION_LATITUDE = "41.9043"
TRUCK_DESTINATION_LONGITUDE = "-87.9216"
BIKE_ORIGIN_LATITUDE = "41.9798"
BIKE_ORIGIN_LONGITUDE = "-87.8801"
BIKE_DESTINATION_LATITUDE = "41.9043"
BIKE_DESTINATION_LONGITUDE = "-87.9216"
CAR_ORIGIN_LATITUDE = "38.9"
CAR_ORIGIN_LONGITUDE = "-77.04833"
CAR_DESTINATION_LATITUDE = "39.0"
CAR_DESTINATION_LONGITUDE = "-77.1"
def _build_mock_url(origin, destination, modes, app_id, app_code, departure):
"""Construct a url for HERE."""
base_url = "https://route.cit.api.here.com/routing/7.2/calculateroute.json?"
parameters = {
"waypoint0": origin,
"waypoint1": destination,
"mode": ";".join(str(herepy.RouteMode[mode]) for mode in modes),
"app_id": app_id,
"app_code": app_code,
"departure": departure,
}
url = base_url + urllib.parse.urlencode(parameters)
return url
def _assert_truck_sensor(sensor):
"""Assert that states and attributes are correct for truck_response."""
assert sensor.state == "14"
assert sensor.attributes.get("unit_of_measurement") == UNIT_OF_MEASUREMENT
assert sensor.attributes.get(ATTR_ATTRIBUTION) is None
assert sensor.attributes.get(ATTR_DURATION) == 13.533333333333333
assert sensor.attributes.get(ATTR_DISTANCE) == 13.049
assert sensor.attributes.get(ATTR_ROUTE) == (
"I-190; I-294 S - Tri-State Tollway; I-290 W - Eisenhower Expy W; "
"IL-64 W - E North Ave; I-290 E - Eisenhower Expy E; I-290"
)
assert sensor.attributes.get(CONF_UNIT_SYSTEM) == "metric"
assert sensor.attributes.get(ATTR_DURATION_IN_TRAFFIC) == 13.533333333333333
assert sensor.attributes.get(ATTR_ORIGIN) == ",".join(
[TRUCK_ORIGIN_LATITUDE, TRUCK_ORIGIN_LONGITUDE]
)
assert sensor.attributes.get(ATTR_DESTINATION) == ",".join(
[TRUCK_DESTINATION_LATITUDE, TRUCK_DESTINATION_LONGITUDE]
)
assert sensor.attributes.get(ATTR_ORIGIN_NAME) == ""
assert sensor.attributes.get(ATTR_DESTINATION_NAME) == "Eisenhower Expy E"
assert sensor.attributes.get(CONF_MODE) == TRAVEL_MODE_TRUCK
assert sensor.attributes.get(CONF_TRAFFIC_MODE) is False
assert sensor.attributes.get(ATTR_ICON) == ICON_TRUCK
@pytest.fixture
def requests_mock_credentials_check(requests_mock):
"""Add the url used in the api validation to all requests mock."""
modes = [ROUTE_MODE_FASTEST, TRAVEL_MODE_CAR, TRAFFIC_MODE_DISABLED]
response_url = _build_mock_url(
",".join([CAR_ORIGIN_LATITUDE, CAR_ORIGIN_LONGITUDE]),
",".join([CAR_DESTINATION_LATITUDE, CAR_DESTINATION_LONGITUDE]),
modes,
APP_ID,
APP_CODE,
"now",
)
requests_mock.get(
response_url, text=load_fixture("here_travel_time/car_response.json")
)
return requests_mock
@pytest.fixture
def requests_mock_truck_response(requests_mock_credentials_check):
"""Return a requests_mock for truck respones."""
modes = [ROUTE_MODE_FASTEST, TRAVEL_MODE_TRUCK, TRAFFIC_MODE_DISABLED]
response_url = _build_mock_url(
",".join([TRUCK_ORIGIN_LATITUDE, TRUCK_ORIGIN_LONGITUDE]),
",".join([TRUCK_DESTINATION_LATITUDE, TRUCK_DESTINATION_LONGITUDE]),
modes,
APP_ID,
APP_CODE,
"now",
)
requests_mock_credentials_check.get(
response_url, text=load_fixture("here_travel_time/truck_response.json")
)
@pytest.fixture
def requests_mock_car_disabled_response(requests_mock_credentials_check):
"""Return a requests_mock for truck respones."""
modes = [ROUTE_MODE_FASTEST, TRAVEL_MODE_CAR, TRAFFIC_MODE_DISABLED]
response_url = _build_mock_url(
",".join([CAR_ORIGIN_LATITUDE, CAR_ORIGIN_LONGITUDE]),
",".join([CAR_DESTINATION_LATITUDE, CAR_DESTINATION_LONGITUDE]),
modes,
APP_ID,
APP_CODE,
"now",
)
requests_mock_credentials_check.get(
response_url, text=load_fixture("here_travel_time/car_response.json")
)
async def test_car(hass, requests_mock_car_disabled_response):
"""Test that car works."""
config = {
DOMAIN: {
"platform": PLATFORM,
"name": "test",
"origin_latitude": CAR_ORIGIN_LATITUDE,
"origin_longitude": CAR_ORIGIN_LONGITUDE,
"destination_latitude": CAR_DESTINATION_LATITUDE,
"destination_longitude": CAR_DESTINATION_LONGITUDE,
"app_id": APP_ID,
"app_code": APP_CODE,
}
}
assert await async_setup_component(hass, DOMAIN, config)
sensor = hass.states.get("sensor.test")
assert sensor.state == "30"
assert sensor.attributes.get("unit_of_measurement") == UNIT_OF_MEASUREMENT
assert sensor.attributes.get(ATTR_ATTRIBUTION) is None
assert sensor.attributes.get(ATTR_DURATION) == 30.05
assert sensor.attributes.get(ATTR_DISTANCE) == 23.903
assert sensor.attributes.get(ATTR_ROUTE) == (
"US-29 - K St NW; US-29 - Whitehurst Fwy; "
"I-495 N - Capital Beltway; MD-187 S - Old Georgetown Rd"
)
assert sensor.attributes.get(CONF_UNIT_SYSTEM) == "metric"
assert sensor.attributes.get(ATTR_DURATION_IN_TRAFFIC) == 31.016666666666666
assert sensor.attributes.get(ATTR_ORIGIN) == ",".join(
[CAR_ORIGIN_LATITUDE, CAR_ORIGIN_LONGITUDE]
)
assert sensor.attributes.get(ATTR_DESTINATION) == ",".join(
[CAR_DESTINATION_LATITUDE, CAR_DESTINATION_LONGITUDE]
)
assert sensor.attributes.get(ATTR_ORIGIN_NAME) == "22nd St NW"
assert sensor.attributes.get(ATTR_DESTINATION_NAME) == "Service Rd S"
assert sensor.attributes.get(CONF_MODE) == TRAVEL_MODE_CAR
assert sensor.attributes.get(CONF_TRAFFIC_MODE) is False
assert sensor.attributes.get(ATTR_ICON) == ICON_CAR
# Test traffic mode disabled
assert sensor.attributes.get(ATTR_DURATION) != sensor.attributes.get(
ATTR_DURATION_IN_TRAFFIC
)
async def test_traffic_mode_enabled(hass, requests_mock_credentials_check):
"""Test that traffic mode enabled works."""
modes = [ROUTE_MODE_FASTEST, TRAVEL_MODE_CAR, TRAFFIC_MODE_ENABLED]
response_url = _build_mock_url(
",".join([CAR_ORIGIN_LATITUDE, CAR_ORIGIN_LONGITUDE]),
",".join([CAR_DESTINATION_LATITUDE, CAR_DESTINATION_LONGITUDE]),
modes,
APP_ID,
APP_CODE,
"now",
)
requests_mock_credentials_check.get(
response_url, text=load_fixture("here_travel_time/car_enabled_response.json")
)
config = {
DOMAIN: {
"platform": PLATFORM,
"name": "test",
"origin_latitude": CAR_ORIGIN_LATITUDE,
"origin_longitude": CAR_ORIGIN_LONGITUDE,
"destination_latitude": CAR_DESTINATION_LATITUDE,
"destination_longitude": CAR_DESTINATION_LONGITUDE,
"app_id": APP_ID,
"app_code": APP_CODE,
"traffic_mode": True,
}
}
assert await async_setup_component(hass, DOMAIN, config)
sensor = hass.states.get("sensor.test")
# Test traffic mode enabled
assert sensor.attributes.get(ATTR_DURATION) != sensor.attributes.get(
ATTR_DURATION_IN_TRAFFIC
)
async def test_imperial(hass, requests_mock_car_disabled_response):
"""Test that imperial units work."""
config = {
DOMAIN: {
"platform": PLATFORM,
"name": "test",
"origin_latitude": CAR_ORIGIN_LATITUDE,
"origin_longitude": CAR_ORIGIN_LONGITUDE,
"destination_latitude": CAR_DESTINATION_LATITUDE,
"destination_longitude": CAR_DESTINATION_LONGITUDE,
"app_id": APP_ID,
"app_code": APP_CODE,
"unit_system": "imperial",
}
}
assert await async_setup_component(hass, DOMAIN, config)
sensor = hass.states.get("sensor.test")
assert sensor.attributes.get(ATTR_DISTANCE) == 14.852635608048994
async def test_route_mode_shortest(hass, requests_mock_credentials_check):
"""Test that route mode shortest works."""
origin = "38.902981,-77.048338"
destination = "39.042158,-77.119116"
modes = [ROUTE_MODE_SHORTEST, TRAVEL_MODE_CAR, TRAFFIC_MODE_DISABLED]
response_url = _build_mock_url(origin, destination, modes, APP_ID, APP_CODE, "now")
requests_mock_credentials_check.get(
response_url, text=load_fixture("here_travel_time/car_shortest_response.json")
)
config = {
DOMAIN: {
"platform": PLATFORM,
"name": "test",
"origin_latitude": origin.split(",")[0],
"origin_longitude": origin.split(",")[1],
"destination_latitude": destination.split(",")[0],
"destination_longitude": destination.split(",")[1],
"app_id": APP_ID,
"app_code": APP_CODE,
"route_mode": ROUTE_MODE_SHORTEST,
}
}
assert await async_setup_component(hass, DOMAIN, config)
sensor = hass.states.get("sensor.test")
assert sensor.attributes.get(ATTR_DISTANCE) == 18.388
async def test_route_mode_fastest(hass, requests_mock_credentials_check):
"""Test that route mode fastest works."""
origin = "38.902981,-77.048338"
destination = "39.042158,-77.119116"
modes = [ROUTE_MODE_FASTEST, TRAVEL_MODE_CAR, TRAFFIC_MODE_ENABLED]
response_url = _build_mock_url(origin, destination, modes, APP_ID, APP_CODE, "now")
requests_mock_credentials_check.get(
response_url, text=load_fixture("here_travel_time/car_enabled_response.json")
)
config = {
DOMAIN: {
"platform": PLATFORM,
"name": "test",
"origin_latitude": origin.split(",")[0],
"origin_longitude": origin.split(",")[1],
"destination_latitude": destination.split(",")[0],
"destination_longitude": destination.split(",")[1],
"app_id": APP_ID,
"app_code": APP_CODE,
"traffic_mode": True,
}
}
assert await async_setup_component(hass, DOMAIN, config)
sensor = hass.states.get("sensor.test")
assert sensor.attributes.get(ATTR_DISTANCE) == 23.381
async def test_truck(hass, requests_mock_truck_response):
"""Test that truck works."""
config = {
DOMAIN: {
"platform": PLATFORM,
"name": "test",
"origin_latitude": TRUCK_ORIGIN_LATITUDE,
"origin_longitude": TRUCK_ORIGIN_LONGITUDE,
"destination_latitude": TRUCK_DESTINATION_LATITUDE,
"destination_longitude": TRUCK_DESTINATION_LONGITUDE,
"app_id": APP_ID,
"app_code": APP_CODE,
"mode": TRAVEL_MODE_TRUCK,
}
}
assert await async_setup_component(hass, DOMAIN, config)
sensor = hass.states.get("sensor.test")
_assert_truck_sensor(sensor)
async def test_public_transport(hass, requests_mock_credentials_check):
"""Test that publicTransport works."""
origin = "41.9798,-87.8801"
destination = "41.9043,-87.9216"
modes = [ROUTE_MODE_FASTEST, TRAVEL_MODE_PUBLIC, TRAFFIC_MODE_DISABLED]
response_url = _build_mock_url(origin, destination, modes, APP_ID, APP_CODE, "now")
requests_mock_credentials_check.get(
response_url, text=load_fixture("here_travel_time/public_response.json")
)
config = {
DOMAIN: {
"platform": PLATFORM,
"name": "test",
"origin_latitude": origin.split(",")[0],
"origin_longitude": origin.split(",")[1],
"destination_latitude": destination.split(",")[0],
"destination_longitude": destination.split(",")[1],
"app_id": APP_ID,
"app_code": APP_CODE,
"mode": TRAVEL_MODE_PUBLIC,
}
}
assert await async_setup_component(hass, DOMAIN, config)
sensor = hass.states.get("sensor.test")
assert sensor.state == "89"
assert sensor.attributes.get("unit_of_measurement") == UNIT_OF_MEASUREMENT
assert sensor.attributes.get(ATTR_ATTRIBUTION) is None
assert sensor.attributes.get(ATTR_DURATION) == 89.16666666666667
assert sensor.attributes.get(ATTR_DISTANCE) == 22.325
assert sensor.attributes.get(ATTR_ROUTE) == (
"332 - Palmer/Schiller; 332 - Cargo Rd./Delta Cargo; " "332 - Palmer/Schiller"
)
assert sensor.attributes.get(CONF_UNIT_SYSTEM) == "metric"
assert sensor.attributes.get(ATTR_DURATION_IN_TRAFFIC) == 89.16666666666667
assert sensor.attributes.get(ATTR_ORIGIN) == origin
assert sensor.attributes.get(ATTR_DESTINATION) == destination
assert sensor.attributes.get(ATTR_ORIGIN_NAME) == "Mannheim Rd"
assert sensor.attributes.get(ATTR_DESTINATION_NAME) == ""
assert sensor.attributes.get(CONF_MODE) == TRAVEL_MODE_PUBLIC
assert sensor.attributes.get(CONF_TRAFFIC_MODE) is False
assert sensor.attributes.get(ATTR_ICON) == ICON_PUBLIC
async def test_public_transport_time_table(hass, requests_mock_credentials_check):
"""Test that publicTransportTimeTable works."""
origin = "41.9798,-87.8801"
destination = "41.9043,-87.9216"
modes = [ROUTE_MODE_FASTEST, TRAVEL_MODE_PUBLIC_TIME_TABLE, TRAFFIC_MODE_DISABLED]
response_url = _build_mock_url(origin, destination, modes, APP_ID, APP_CODE, "now")
requests_mock_credentials_check.get(
response_url,
text=load_fixture("here_travel_time/public_time_table_response.json"),
)
config = {
DOMAIN: {
"platform": PLATFORM,
"name": "test",
"origin_latitude": origin.split(",")[0],
"origin_longitude": origin.split(",")[1],
"destination_latitude": destination.split(",")[0],
"destination_longitude": destination.split(",")[1],
"app_id": APP_ID,
"app_code": APP_CODE,
"mode": TRAVEL_MODE_PUBLIC_TIME_TABLE,
}
}
assert await async_setup_component(hass, DOMAIN, config)
sensor = hass.states.get("sensor.test")
assert sensor.state == "80"
assert sensor.attributes.get("unit_of_measurement") == UNIT_OF_MEASUREMENT
assert sensor.attributes.get(ATTR_ATTRIBUTION) is None
assert sensor.attributes.get(ATTR_DURATION) == 79.73333333333333
assert sensor.attributes.get(ATTR_DISTANCE) == 14.775
assert sensor.attributes.get(ATTR_ROUTE) == (
"330 - Archer/Harlem (Terminal); 309 - Elmhurst Metra Station"
)
assert sensor.attributes.get(CONF_UNIT_SYSTEM) == "metric"
assert sensor.attributes.get(ATTR_DURATION_IN_TRAFFIC) == 79.73333333333333
assert sensor.attributes.get(ATTR_ORIGIN) == origin
assert sensor.attributes.get(ATTR_DESTINATION) == destination
assert sensor.attributes.get(ATTR_ORIGIN_NAME) == "Mannheim Rd"
assert sensor.attributes.get(ATTR_DESTINATION_NAME) == ""
assert sensor.attributes.get(CONF_MODE) == TRAVEL_MODE_PUBLIC_TIME_TABLE
assert sensor.attributes.get(CONF_TRAFFIC_MODE) is False
assert sensor.attributes.get(ATTR_ICON) == ICON_PUBLIC
async def test_pedestrian(hass, requests_mock_credentials_check):
"""Test that pedestrian works."""
origin = "41.9798,-87.8801"
destination = "41.9043,-87.9216"
modes = [ROUTE_MODE_FASTEST, TRAVEL_MODE_PEDESTRIAN, TRAFFIC_MODE_DISABLED]
response_url = _build_mock_url(origin, destination, modes, APP_ID, APP_CODE, "now")
requests_mock_credentials_check.get(
response_url, text=load_fixture("here_travel_time/pedestrian_response.json")
)
config = {
DOMAIN: {
"platform": PLATFORM,
"name": "test",
"origin_latitude": origin.split(",")[0],
"origin_longitude": origin.split(",")[1],
"destination_latitude": destination.split(",")[0],
"destination_longitude": destination.split(",")[1],
"app_id": APP_ID,
"app_code": APP_CODE,
"mode": TRAVEL_MODE_PEDESTRIAN,
}
}
assert await async_setup_component(hass, DOMAIN, config)
sensor = hass.states.get("sensor.test")
assert sensor.state == "211"
assert sensor.attributes.get("unit_of_measurement") == UNIT_OF_MEASUREMENT
assert sensor.attributes.get(ATTR_ATTRIBUTION) is None
assert sensor.attributes.get(ATTR_DURATION) == 210.51666666666668
assert sensor.attributes.get(ATTR_DISTANCE) == 12.533
assert sensor.attributes.get(ATTR_ROUTE) == (
"Mannheim Rd; W Belmont Ave; Cullerton St; E Fullerton Ave; "
"La Porte Ave; E Palmer Ave; N Railroad Ave; W North Ave; "
"E North Ave; E Third St"
)
assert sensor.attributes.get(CONF_UNIT_SYSTEM) == "metric"
assert sensor.attributes.get(ATTR_DURATION_IN_TRAFFIC) == 210.51666666666668
assert sensor.attributes.get(ATTR_ORIGIN) == origin
assert sensor.attributes.get(ATTR_DESTINATION) == destination
assert sensor.attributes.get(ATTR_ORIGIN_NAME) == "Mannheim Rd"
assert sensor.attributes.get(ATTR_DESTINATION_NAME) == ""
assert sensor.attributes.get(CONF_MODE) == TRAVEL_MODE_PEDESTRIAN
assert sensor.attributes.get(CONF_TRAFFIC_MODE) is False
assert sensor.attributes.get(ATTR_ICON) == ICON_PEDESTRIAN
async def test_bicycle(hass, requests_mock_credentials_check):
"""Test that bicycle works."""
origin = "41.9798,-87.8801"
destination = "41.9043,-87.9216"
modes = [ROUTE_MODE_FASTEST, TRAVEL_MODE_BICYCLE, TRAFFIC_MODE_DISABLED]
response_url = _build_mock_url(origin, destination, modes, APP_ID, APP_CODE, "now")
requests_mock_credentials_check.get(
response_url, text=load_fixture("here_travel_time/bike_response.json")
)
config = {
DOMAIN: {
"platform": PLATFORM,
"name": "test",
"origin_latitude": origin.split(",")[0],
"origin_longitude": origin.split(",")[1],
"destination_latitude": destination.split(",")[0],
"destination_longitude": destination.split(",")[1],
"app_id": APP_ID,
"app_code": APP_CODE,
"mode": TRAVEL_MODE_BICYCLE,
}
}
assert await async_setup_component(hass, DOMAIN, config)
sensor = hass.states.get("sensor.test")
assert sensor.state == "55"
assert sensor.attributes.get("unit_of_measurement") == UNIT_OF_MEASUREMENT
assert sensor.attributes.get(ATTR_ATTRIBUTION) is None
assert sensor.attributes.get(ATTR_DURATION) == 54.86666666666667
assert sensor.attributes.get(ATTR_DISTANCE) == 12.613
assert sensor.attributes.get(ATTR_ROUTE) == (
"Mannheim Rd; W Belmont Ave; Cullerton St; N Landen Dr; "
"E Fullerton Ave; N Wolf Rd; W North Ave; N Clinton Ave; "
"E Third St; N Caroline Ave"
)
assert sensor.attributes.get(CONF_UNIT_SYSTEM) == "metric"
assert sensor.attributes.get(ATTR_DURATION_IN_TRAFFIC) == 54.86666666666667
assert sensor.attributes.get(ATTR_ORIGIN) == origin
assert sensor.attributes.get(ATTR_DESTINATION) == destination
assert sensor.attributes.get(ATTR_ORIGIN_NAME) == "Mannheim Rd"
assert sensor.attributes.get(ATTR_DESTINATION_NAME) == ""
assert sensor.attributes.get(CONF_MODE) == TRAVEL_MODE_BICYCLE
assert sensor.attributes.get(CONF_TRAFFIC_MODE) is False
assert sensor.attributes.get(ATTR_ICON) == ICON_BICYCLE
async def test_location_zone(hass, requests_mock_truck_response):
"""Test that origin/destination supplied by a zone works."""
utcnow = dt_util.utcnow()
# Patching 'utcnow' to gain more control over the timed update.
with patch("homeassistant.util.dt.utcnow", return_value=utcnow):
zone_config = {
"zone": [
{
"name": "Destination",
"latitude": TRUCK_DESTINATION_LATITUDE,
"longitude": TRUCK_DESTINATION_LONGITUDE,
"radius": 250,
"passive": False,
},
{
"name": "Origin",
"latitude": TRUCK_ORIGIN_LATITUDE,
"longitude": TRUCK_ORIGIN_LONGITUDE,
"radius": 250,
"passive": False,
},
]
}
assert await async_setup_component(hass, "zone", zone_config)
config = {
DOMAIN: {
"platform": PLATFORM,
"name": "test",
"origin_entity_id": "zone.origin",
"destination_entity_id": "zone.destination",
"app_id": APP_ID,
"app_code": APP_CODE,
"mode": TRAVEL_MODE_TRUCK,
}
}
assert await async_setup_component(hass, DOMAIN, config)
sensor = hass.states.get("sensor.test")
_assert_truck_sensor(sensor)
# Test that update works more than once
async_fire_time_changed(hass, utcnow + SCAN_INTERVAL)
await hass.async_block_till_done()
sensor = hass.states.get("sensor.test")
_assert_truck_sensor(sensor)
async def test_location_sensor(hass, requests_mock_truck_response):
"""Test that origin/destination supplied by a sensor works."""
utcnow = dt_util.utcnow()
# Patching 'utcnow' to gain more control over the timed update.
with patch("homeassistant.util.dt.utcnow", return_value=utcnow):
hass.states.async_set(
"sensor.origin", ",".join([TRUCK_ORIGIN_LATITUDE, TRUCK_ORIGIN_LONGITUDE])
)
hass.states.async_set(
"sensor.destination",
",".join([TRUCK_DESTINATION_LATITUDE, TRUCK_DESTINATION_LONGITUDE]),
)
config = {
DOMAIN: {
"platform": PLATFORM,
"name": "test",
"origin_entity_id": "sensor.origin",
"destination_entity_id": "sensor.destination",
"app_id": APP_ID,
"app_code": APP_CODE,
"mode": TRAVEL_MODE_TRUCK,
}
}
assert await async_setup_component(hass, DOMAIN, config)
sensor = hass.states.get("sensor.test")
_assert_truck_sensor(sensor)
# Test that update works more than once
async_fire_time_changed(hass, utcnow + SCAN_INTERVAL)
await hass.async_block_till_done()
sensor = hass.states.get("sensor.test")
_assert_truck_sensor(sensor)
async def test_location_person(hass, requests_mock_truck_response):
"""Test that origin/destination supplied by a person works."""
utcnow = dt_util.utcnow()
# Patching 'utcnow' to gain more control over the timed update.
with patch("homeassistant.util.dt.utcnow", return_value=utcnow):
hass.states.async_set(
"person.origin",
"unknown",
{
"latitude": float(TRUCK_ORIGIN_LATITUDE),
"longitude": float(TRUCK_ORIGIN_LONGITUDE),
},
)
hass.states.async_set(
"person.destination",
"unknown",
{
"latitude": float(TRUCK_DESTINATION_LATITUDE),
"longitude": float(TRUCK_DESTINATION_LONGITUDE),
},
)
config = {
DOMAIN: {
"platform": PLATFORM,
"name": "test",
"origin_entity_id": "person.origin",
"destination_entity_id": "person.destination",
"app_id": APP_ID,
"app_code": APP_CODE,
"mode": TRAVEL_MODE_TRUCK,
}
}
assert await async_setup_component(hass, DOMAIN, config)
sensor = hass.states.get("sensor.test")
_assert_truck_sensor(sensor)
# Test that update works more than once
async_fire_time_changed(hass, utcnow + SCAN_INTERVAL)
await hass.async_block_till_done()
sensor = hass.states.get("sensor.test")
_assert_truck_sensor(sensor)
async def test_location_device_tracker(hass, requests_mock_truck_response):
"""Test that origin/destination supplied by a device_tracker works."""
utcnow = dt_util.utcnow()
# Patching 'utcnow' to gain more control over the timed update.
with patch("homeassistant.util.dt.utcnow", return_value=utcnow):
hass.states.async_set(
"device_tracker.origin",
"unknown",
{
"latitude": float(TRUCK_ORIGIN_LATITUDE),
"longitude": float(TRUCK_ORIGIN_LONGITUDE),
},
)
hass.states.async_set(
"device_tracker.destination",
"unknown",
{
"latitude": float(TRUCK_DESTINATION_LATITUDE),
"longitude": float(TRUCK_DESTINATION_LONGITUDE),
},
)
config = {
DOMAIN: {
"platform": PLATFORM,
"name": "test",
"origin_entity_id": "device_tracker.origin",
"destination_entity_id": "device_tracker.destination",
"app_id": APP_ID,
"app_code": APP_CODE,
"mode": TRAVEL_MODE_TRUCK,
}
}
assert await async_setup_component(hass, DOMAIN, config)
sensor = hass.states.get("sensor.test")
_assert_truck_sensor(sensor)
# Test that update works more than once
async_fire_time_changed(hass, utcnow + SCAN_INTERVAL)
await hass.async_block_till_done()
sensor = hass.states.get("sensor.test")
_assert_truck_sensor(sensor)
async def test_location_device_tracker_added_after_update(
hass, requests_mock_truck_response, caplog
):
"""Test that device_tracker added after first update works."""
caplog.set_level(logging.ERROR)
utcnow = dt_util.utcnow()
# Patching 'utcnow' to gain more control over the timed update.
with patch("homeassistant.util.dt.utcnow", return_value=utcnow):
config = {
DOMAIN: {
"platform": PLATFORM,
"name": "test",
"origin_entity_id": "device_tracker.origin",
"destination_entity_id": "device_tracker.destination",
"app_id": APP_ID,
"app_code": APP_CODE,
"mode": TRAVEL_MODE_TRUCK,
}
}
assert await async_setup_component(hass, DOMAIN, config)
sensor = hass.states.get("sensor.test")
assert len(caplog.records) == 2
assert "Unable to find entity" in caplog.text
caplog.clear()
# Device tracker appear after first update
hass.states.async_set(
"device_tracker.origin",
"unknown",
{
"latitude": float(TRUCK_ORIGIN_LATITUDE),
"longitude": float(TRUCK_ORIGIN_LONGITUDE),
},
)
hass.states.async_set(
"device_tracker.destination",
"unknown",
{
"latitude": float(TRUCK_DESTINATION_LATITUDE),
"longitude": float(TRUCK_DESTINATION_LONGITUDE),
},
)
# Test that update works more than once
async_fire_time_changed(hass, utcnow + SCAN_INTERVAL)
await hass.async_block_till_done()
sensor = hass.states.get("sensor.test")
_assert_truck_sensor(sensor)
assert len(caplog.records) == 0
async def test_location_device_tracker_in_zone(
hass, requests_mock_truck_response, caplog
):
"""Test that device_tracker in zone uses device_tracker state works."""
caplog.set_level(logging.DEBUG)
zone_config = {
"zone": [
{
"name": "Origin",
"latitude": TRUCK_ORIGIN_LATITUDE,
"longitude": TRUCK_ORIGIN_LONGITUDE,
"radius": 250,
"passive": False,
}
]
}
assert await async_setup_component(hass, "zone", zone_config)
hass.states.async_set(
"device_tracker.origin", "origin", {"latitude": None, "longitude": None}
)
config = {
DOMAIN: {
"platform": PLATFORM,
"name": "test",
"origin_entity_id": "device_tracker.origin",
"destination_latitude": TRUCK_DESTINATION_LATITUDE,
"destination_longitude": TRUCK_DESTINATION_LONGITUDE,
"app_id": APP_ID,
"app_code": APP_CODE,
"mode": TRAVEL_MODE_TRUCK,
}
}
assert await async_setup_component(hass, DOMAIN, config)
sensor = hass.states.get("sensor.test")
_assert_truck_sensor(sensor)
assert ", getting zone location" in caplog.text
async def test_route_not_found(hass, requests_mock_credentials_check, caplog):
"""Test that route not found error is correctly handled."""
caplog.set_level(logging.ERROR)
origin = "52.516,13.3779"
destination = "47.013399,-10.171986"
modes = [ROUTE_MODE_FASTEST, TRAVEL_MODE_CAR, TRAFFIC_MODE_DISABLED]
response_url = _build_mock_url(origin, destination, modes, APP_ID, APP_CODE, "now")
requests_mock_credentials_check.get(
response_url,
text=load_fixture("here_travel_time/routing_error_no_route_found.json"),
)
config = {
DOMAIN: {
"platform": PLATFORM,
"name": "test",
"origin_latitude": origin.split(",")[0],
"origin_longitude": origin.split(",")[1],
"destination_latitude": destination.split(",")[0],
"destination_longitude": destination.split(",")[1],
"app_id": APP_ID,
"app_code": APP_CODE,
}
}
assert await async_setup_component(hass, DOMAIN, config)
assert len(caplog.records) == 1
assert NO_ROUTE_ERROR_MESSAGE in caplog.text
async def test_pattern_origin(hass, caplog):
"""Test that pattern matching the origin works."""
caplog.set_level(logging.ERROR)
config = {
DOMAIN: {
"platform": PLATFORM,
"name": "test",
"origin_latitude": "138.90",
"origin_longitude": "-77.04833",
"destination_latitude": CAR_DESTINATION_LATITUDE,
"destination_longitude": CAR_DESTINATION_LONGITUDE,
"app_id": APP_ID,
"app_code": APP_CODE,
}
}
assert await async_setup_component(hass, DOMAIN, config)
assert len(caplog.records) == 1
assert "invalid latitude" in caplog.text
async def test_pattern_destination(hass, caplog):
"""Test that pattern matching the destination works."""
caplog.set_level(logging.ERROR)
config = {
DOMAIN: {
"platform": PLATFORM,
"name": "test",
"origin_latitude": CAR_ORIGIN_LATITUDE,
"origin_longitude": CAR_ORIGIN_LONGITUDE,
"destination_latitude": "139.0",
"destination_longitude": "-77.1",
"app_id": APP_ID,
"app_code": APP_CODE,
}
}
assert await async_setup_component(hass, DOMAIN, config)
assert len(caplog.records) == 1
assert "invalid latitude" in caplog.text
async def test_invalid_credentials(hass, requests_mock, caplog):
"""Test that invalid credentials error is correctly handled."""
caplog.set_level(logging.ERROR)
modes = [ROUTE_MODE_FASTEST, TRAVEL_MODE_CAR, TRAFFIC_MODE_DISABLED]
response_url = _build_mock_url(
",".join([CAR_ORIGIN_LATITUDE, CAR_ORIGIN_LONGITUDE]),
",".join([CAR_DESTINATION_LATITUDE, CAR_DESTINATION_LONGITUDE]),
modes,
APP_ID,
APP_CODE,
"now",
)
requests_mock.get(
response_url,
text=load_fixture("here_travel_time/routing_error_invalid_credentials.json"),
)
config = {
DOMAIN: {
"platform": PLATFORM,
"name": "test",
"origin_latitude": CAR_ORIGIN_LATITUDE,
"origin_longitude": CAR_ORIGIN_LONGITUDE,
"destination_latitude": CAR_DESTINATION_LATITUDE,
"destination_longitude": CAR_DESTINATION_LONGITUDE,
"app_id": APP_ID,
"app_code": APP_CODE,
}
}
assert await async_setup_component(hass, DOMAIN, config)
assert len(caplog.records) == 1
assert "Invalid credentials" in caplog.text
async def test_attribution(hass, requests_mock_credentials_check):
"""Test that attributions are correctly displayed."""
origin = "50.037751372637686,14.39233448220898"
destination = "50.07993838201255,14.42582157361062"
modes = [ROUTE_MODE_SHORTEST, TRAVEL_MODE_PUBLIC_TIME_TABLE, TRAFFIC_MODE_ENABLED]
response_url = _build_mock_url(origin, destination, modes, APP_ID, APP_CODE, "now")
requests_mock_credentials_check.get(
response_url, text=load_fixture("here_travel_time/attribution_response.json")
)
config = {
DOMAIN: {
"platform": PLATFORM,
"name": "test",
"origin_latitude": origin.split(",")[0],
"origin_longitude": origin.split(",")[1],
"destination_latitude": destination.split(",")[0],
"destination_longitude": destination.split(",")[1],
"app_id": APP_ID,
"app_code": APP_CODE,
"traffic_mode": True,
"route_mode": ROUTE_MODE_SHORTEST,
"mode": TRAVEL_MODE_PUBLIC_TIME_TABLE,
}
}
assert await async_setup_component(hass, DOMAIN, config)
sensor = hass.states.get("sensor.test")
assert (
sensor.attributes.get(ATTR_ATTRIBUTION)
== "With the support of HERE Technologies. All information is provided without warranty of any kind."
)

View File

@ -0,0 +1,276 @@
{
"response": {
"metaInfo": {
"timestamp": "2019-09-21T15:17:31Z",
"mapVersion": "8.30.100.154",
"moduleVersion": "7.2.201937-5251",
"interfaceVersion": "2.6.70",
"availableMapVersion": [
"8.30.100.154"
]
},
"route": [
{
"waypoint": [
{
"linkId": "+565790671",
"mappedPosition": {
"latitude": 50.0378591,
"longitude": 14.3924721
},
"originalPosition": {
"latitude": 50.0377513,
"longitude": 14.3923344
},
"type": "stopOver",
"spot": 0.3,
"sideOfStreet": "left",
"mappedRoadName": "V Bokách III",
"label": "V Bokách III",
"shapeIndex": 0,
"source": "user"
},
{
"linkId": "+748931502",
"mappedPosition": {
"latitude": 50.0798786,
"longitude": 14.4260037
},
"originalPosition": {
"latitude": 50.0799383,
"longitude": 14.4258216
},
"type": "stopOver",
"spot": 1.0,
"sideOfStreet": "left",
"mappedRoadName": "Štěpánská",
"label": "Štěpánská",
"shapeIndex": 116,
"source": "user"
}
],
"mode": {
"type": "shortest",
"transportModes": [
"publicTransportTimeTable"
],
"trafficMode": "enabled",
"feature": []
},
"leg": [
{
"start": {
"linkId": "+565790671",
"mappedPosition": {
"latitude": 50.0378591,
"longitude": 14.3924721
},
"originalPosition": {
"latitude": 50.0377513,
"longitude": 14.3923344
},
"type": "stopOver",
"spot": 0.3,
"sideOfStreet": "left",
"mappedRoadName": "V Bokách III",
"label": "V Bokách III",
"shapeIndex": 0,
"source": "user"
},
"end": {
"linkId": "+748931502",
"mappedPosition": {
"latitude": 50.0798786,
"longitude": 14.4260037
},
"originalPosition": {
"latitude": 50.0799383,
"longitude": 14.4258216
},
"type": "stopOver",
"spot": 1.0,
"sideOfStreet": "left",
"mappedRoadName": "Štěpánská",
"label": "Štěpánská",
"shapeIndex": 116,
"source": "user"
},
"length": 7835,
"travelTime": 2413,
"maneuver": [
{
"position": {
"latitude": 50.0378591,
"longitude": 14.3924721
},
"instruction": "Head <span class=\"heading\">northwest</span> on <span class=\"street\">Kosořská</span>. <span class=\"distance-description\">Go for <span class=\"length\">28 m</span>.</span>",
"travelTime": 32,
"length": 28,
"id": "M1",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 50.0380039,
"longitude": 14.3921542
},
"instruction": "Turn <span class=\"direction\">left</span> onto <span class=\"next-street\">Kosořská</span>. <span class=\"distance-description\">Go for <span class=\"length\">24 m</span>.</span>",
"travelTime": 24,
"length": 24,
"id": "M2",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 50.0380039,
"longitude": 14.3918109
},
"instruction": "Take the street on the <span class=\"direction\">left</span>, <span class=\"next-street\">Slivenecká</span>. <span class=\"distance-description\">Go for <span class=\"length\">343 m</span>.</span>",
"travelTime": 354,
"length": 343,
"id": "M3",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 50.0376499,
"longitude": 14.3871975
},
"instruction": "Turn <span class=\"direction\">left</span> onto <span class=\"next-street\">Slivenecká</span>. <span class=\"distance-description\">Go for <span class=\"length\">64 m</span>.</span>",
"travelTime": 72,
"length": 64,
"id": "M4",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 50.0373602,
"longitude": 14.3879807
},
"instruction": "Turn <span class=\"direction\">right</span> onto <span class=\"next-street\">Slivenecká</span>. <span class=\"distance-description\">Go for <span class=\"length\">91 m</span>.</span>",
"travelTime": 95,
"length": 91,
"id": "M5",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 50.0365448,
"longitude": 14.3878305
},
"instruction": "Turn <span class=\"direction\">left</span> onto <span class=\"next-street\">K Barrandovu</span>. <span class=\"distance-description\">Go for <span class=\"length\">124 m</span>.</span>",
"travelTime": 126,
"length": 124,
"id": "M6",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 50.0363168,
"longitude": 14.3894618
},
"instruction": "Go to the <span class=\"company\">Tram</span> station <span class=\"station\">Geologicka</span> and take the <span class=\"transit\">rail</span> <span class=\"line\">5</span> toward <span class=\"destination\">Ústřední dílny DP</span>. <span class=\"distance-description\">Follow for <span class=\"stops\">13 stations</span>.</span>",
"travelTime": 1440,
"length": 6911,
"id": "M7",
"stopName": "Geologicka",
"_type": "PublicTransportManeuverType"
},
{
"position": {
"latitude": 50.0800508,
"longitude": 14.423403
},
"instruction": "Get off at <span class=\"station\">Vodickova</span>.",
"travelTime": 0,
"length": 0,
"id": "M8",
"stopName": "Vodickova",
"nextRoadName": "Vodičkova",
"_type": "PublicTransportManeuverType"
},
{
"position": {
"latitude": 50.0800508,
"longitude": 14.423403
},
"instruction": "Head <span class=\"heading\">northeast</span> on <span class=\"street\">Vodičkova</span>. <span class=\"distance-description\">Go for <span class=\"length\">65 m</span>.</span>",
"travelTime": 74,
"length": 65,
"id": "M9",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 50.0804901,
"longitude": 14.4239759
},
"instruction": "Turn <span class=\"direction\">right</span> onto <span class=\"next-street\">V Jámě</span>. <span class=\"distance-description\">Go for <span class=\"length\">163 m</span>.</span>",
"travelTime": 174,
"length": 163,
"id": "M10",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 50.0796962,
"longitude": 14.4258857
},
"instruction": "Turn <span class=\"direction\">left</span> onto <span class=\"next-street\">Štěpánská</span>. <span class=\"distance-description\">Go for <span class=\"length\">22 m</span>.</span>",
"travelTime": 22,
"length": 22,
"id": "M11",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 50.0798786,
"longitude": 14.4260037
},
"instruction": "Arrive at <span class=\"street\">Štěpánská</span>. Your destination is on the left.",
"travelTime": 0,
"length": 0,
"id": "M12",
"_type": "PrivateTransportManeuverType"
}
]
}
],
"publicTransportLine": [
{
"lineName": "5",
"lineForeground": "#F5ADCE",
"lineBackground": "#F5ADCE",
"companyName": "HERE Technologies",
"destination": "Ústřední dílny DP",
"type": "railLight",
"id": "L1"
}
],
"summary": {
"distance": 7835,
"baseTime": 2413,
"flags": [
"noThroughRoad",
"builtUpArea"
],
"text": "The trip takes <span class=\"length\">7.8 km</span> and <span class=\"time\">40 mins</span>.",
"travelTime": 2413,
"departure": "2019-09-21T17:16:17+02:00",
"timetableExpiration": "2019-09-21T00:00:00Z",
"_type": "PublicTransportRouteSummaryType"
}
}
],
"language": "en-us",
"sourceAttribution": {
"attribution": "With the support of <span class=\"company\"><a href=\"https://transit.api.here.com/r?appId=Mt1bOYh3m9uxE7r3wuUx&u=https://wego.here.com\">HERE Technologies</a></span>. All information is provided without warranty of any kind.",
"supplier": [
{
"title": "HERE Technologies",
"href": "https://transit.api.here.com/r?appId=Mt1bOYh3m9uxE7r3wuUx&u=https://wego.here.com"
}
]
}
}
}

View File

@ -0,0 +1,274 @@
{
"response": {
"metaInfo": {
"timestamp": "2019-07-24T10:17:40Z",
"mapVersion": "8.30.98.154",
"moduleVersion": "7.2.201929-4522",
"interfaceVersion": "2.6.64",
"availableMapVersion": [
"8.30.98.154"
]
},
"route": [
{
"waypoint": [
{
"linkId": "-1230414527",
"mappedPosition": {
"latitude": 41.9797859,
"longitude": -87.8790879
},
"originalPosition": {
"latitude": 41.9798,
"longitude": -87.8801
},
"type": "stopOver",
"spot": 0.5079365,
"sideOfStreet": "right",
"mappedRoadName": "Mannheim Rd",
"label": "Mannheim Rd - US-12",
"shapeIndex": 0,
"source": "user"
},
{
"linkId": "+924115108",
"mappedPosition": {
"latitude": 41.90413,
"longitude": -87.9223502
},
"originalPosition": {
"latitude": 41.9043,
"longitude": -87.9216001
},
"type": "stopOver",
"spot": 0.1925926,
"sideOfStreet": "right",
"mappedRoadName": "",
"label": "",
"shapeIndex": 87,
"source": "user"
}
],
"mode": {
"type": "fastest",
"transportModes": [
"bicycle"
],
"trafficMode": "enabled",
"feature": []
},
"leg": [
{
"start": {
"linkId": "-1230414527",
"mappedPosition": {
"latitude": 41.9797859,
"longitude": -87.8790879
},
"originalPosition": {
"latitude": 41.9798,
"longitude": -87.8801
},
"type": "stopOver",
"spot": 0.5079365,
"sideOfStreet": "right",
"mappedRoadName": "Mannheim Rd",
"label": "Mannheim Rd - US-12",
"shapeIndex": 0,
"source": "user"
},
"end": {
"linkId": "+924115108",
"mappedPosition": {
"latitude": 41.90413,
"longitude": -87.9223502
},
"originalPosition": {
"latitude": 41.9043,
"longitude": -87.9216001
},
"type": "stopOver",
"spot": 0.1925926,
"sideOfStreet": "right",
"mappedRoadName": "",
"label": "",
"shapeIndex": 87,
"source": "user"
},
"length": 12613,
"travelTime": 3292,
"maneuver": [
{
"position": {
"latitude": 41.9797859,
"longitude": -87.8790879
},
"instruction": "Head <span class=\"heading\">south</span> on <span class=\"street\">Mannheim Rd</span> <span class=\"number\">(US-12/US-45)</span>. <span class=\"distance-description\">Go for <span class=\"length\">2.6 km</span>.</span>",
"travelTime": 646,
"length": 2648,
"id": "M1",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9579244,
"longitude": -87.8838551
},
"instruction": "Keep <span class=\"direction\">left</span> onto <span class=\"next-street\">Mannheim Rd</span> <span class=\"number\">(US-12/US-45)</span>. <span class=\"distance-description\">Go for <span class=\"length\">2.4 km</span>.</span>",
"travelTime": 621,
"length": 2427,
"id": "M2",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9364238,
"longitude": -87.8849387
},
"instruction": "Turn <span class=\"direction\">right</span> onto <span class=\"next-street\">W Belmont Ave</span>. <span class=\"distance-description\">Go for <span class=\"length\">595 m</span>.</span>",
"travelTime": 158,
"length": 595,
"id": "M3",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9362521,
"longitude": -87.8921163
},
"instruction": "Turn <span class=\"direction\">left</span> onto <span class=\"next-street\">Cullerton St</span>. <span class=\"distance-description\">Go for <span class=\"length\">669 m</span>.</span>",
"travelTime": 180,
"length": 669,
"id": "M4",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9305658,
"longitude": -87.8932428
},
"instruction": "Continue on <span class=\"next-street\">N Landen Dr</span>. <span class=\"distance-description\">Go for <span class=\"length\">976 m</span>.</span>",
"travelTime": 246,
"length": 976,
"id": "M5",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9217896,
"longitude": -87.8928781
},
"instruction": "Turn <span class=\"direction\">right</span> onto <span class=\"next-street\">E Fullerton Ave</span>. <span class=\"distance-description\">Go for <span class=\"length\">904 m</span>.</span>",
"travelTime": 238,
"length": 904,
"id": "M6",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.921618,
"longitude": -87.9038107
},
"instruction": "Turn <span class=\"direction\">left</span> onto <span class=\"next-street\">N Wolf Rd</span>. <span class=\"distance-description\">Go for <span class=\"length\">1.6 km</span>.</span>",
"travelTime": 417,
"length": 1604,
"id": "M7",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.907177,
"longitude": -87.9032314
},
"instruction": "Turn <span class=\"direction\">right</span> onto <span class=\"next-street\">W North Ave</span> <span class=\"number\">(IL-64)</span>. <span class=\"distance-description\">Go for <span class=\"length\">2.0 km</span>.</span>",
"travelTime": 574,
"length": 2031,
"id": "M8",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9065225,
"longitude": -87.9277039
},
"instruction": "Turn <span class=\"direction\">left</span> onto <span class=\"next-street\">N Clinton Ave</span>. <span class=\"distance-description\">Go for <span class=\"length\">275 m</span>.</span>",
"travelTime": 78,
"length": 275,
"id": "M9",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9040549,
"longitude": -87.9277253
},
"instruction": "Turn <span class=\"direction\">left</span> onto <span class=\"next-street\">E Third St</span>. <span class=\"distance-description\">Go for <span class=\"length\">249 m</span>.</span>",
"travelTime": 63,
"length": 249,
"id": "M10",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9040334,
"longitude": -87.9247105
},
"instruction": "Continue on <span class=\"next-street\">N Caroline Ave</span>. <span class=\"distance-description\">Go for <span class=\"length\">96 m</span>.</span>",
"travelTime": 37,
"length": 96,
"id": "M11",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9038832,
"longitude": -87.9236054
},
"instruction": "Turn <span class=\"direction\">slightly left</span>. <span class=\"distance-description\">Go for <span class=\"length\">113 m</span>.</span>",
"travelTime": 28,
"length": 113,
"id": "M12",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9039047,
"longitude": -87.9222536
},
"instruction": "Turn <span class=\"direction\">left</span>. <span class=\"distance-description\">Go for <span class=\"length\">26 m</span>.</span>",
"travelTime": 6,
"length": 26,
"id": "M13",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.90413,
"longitude": -87.9223502
},
"instruction": "Arrive at your destination on the right.",
"travelTime": 0,
"length": 0,
"id": "M14",
"_type": "PrivateTransportManeuverType"
}
]
}
],
"summary": {
"distance": 12613,
"baseTime": 3292,
"flags": [
"noThroughRoad",
"builtUpArea",
"park"
],
"text": "The trip takes <span class=\"length\">12.6 km</span> and <span class=\"time\">55 mins</span>.",
"travelTime": 3292,
"_type": "RouteSummaryType"
}
}
],
"language": "en-us"
}
}

View File

@ -0,0 +1,298 @@
{
"response": {
"metaInfo": {
"timestamp": "2019-07-21T21:21:31Z",
"mapVersion": "8.30.98.154",
"moduleVersion": "7.2.201928-4478",
"interfaceVersion": "2.6.64",
"availableMapVersion": [
"8.30.98.154"
]
},
"route": [
{
"waypoint": [
{
"linkId": "-1128310200",
"mappedPosition": {
"latitude": 38.9026523,
"longitude": -77.048338
},
"originalPosition": {
"latitude": 38.9029809,
"longitude": -77.048338
},
"type": "stopOver",
"spot": 0.3538462,
"sideOfStreet": "right",
"mappedRoadName": "K St NW",
"label": "K St NW",
"shapeIndex": 0,
"source": "user"
},
{
"linkId": "-18459081",
"mappedPosition": {
"latitude": 39.0422511,
"longitude": -77.1193526
},
"originalPosition": {
"latitude": 39.042158,
"longitude": -77.119116
},
"type": "stopOver",
"spot": 0.7253521,
"sideOfStreet": "left",
"mappedRoadName": "Commonwealth Dr",
"label": "Commonwealth Dr",
"shapeIndex": 283,
"source": "user"
}
],
"mode": {
"type": "fastest",
"transportModes": [
"car"
],
"trafficMode": "enabled",
"feature": []
},
"leg": [
{
"start": {
"linkId": "-1128310200",
"mappedPosition": {
"latitude": 38.9026523,
"longitude": -77.048338
},
"originalPosition": {
"latitude": 38.9029809,
"longitude": -77.048338
},
"type": "stopOver",
"spot": 0.3538462,
"sideOfStreet": "right",
"mappedRoadName": "K St NW",
"label": "K St NW",
"shapeIndex": 0,
"source": "user"
},
"end": {
"linkId": "-18459081",
"mappedPosition": {
"latitude": 39.0422511,
"longitude": -77.1193526
},
"originalPosition": {
"latitude": 39.042158,
"longitude": -77.119116
},
"type": "stopOver",
"spot": 0.7253521,
"sideOfStreet": "left",
"mappedRoadName": "Commonwealth Dr",
"label": "Commonwealth Dr",
"shapeIndex": 283,
"source": "user"
},
"length": 23381,
"travelTime": 1817,
"maneuver": [
{
"position": {
"latitude": 38.9026523,
"longitude": -77.048338
},
"instruction": "Head toward <span class=\"toward_street\">22nd St NW</span> on <span class=\"street\">K St NW</span>. <span class=\"distance-description\">Go for <span class=\"length\">140 m</span>.</span>",
"travelTime": 36,
"length": 140,
"id": "M1",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 38.9027703,
"longitude": -77.0494902
},
"instruction": "Take the <span class=\"exit\">3rd exit</span> from Washington Cir NW roundabout onto <span class=\"next-street\">K St NW</span>. <span class=\"distance-description\">Go for <span class=\"length\">325 m</span>.</span>",
"travelTime": 81,
"length": 325,
"id": "M2",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 38.9026523,
"longitude": -77.0529449
},
"instruction": "Keep <span class=\"direction\">left</span> onto <span class=\"next-street\">K St NW</span> <span class=\"number\">(US-29)</span>. <span class=\"distance-description\">Go for <span class=\"length\">201 m</span>.</span>",
"travelTime": 29,
"length": 201,
"id": "M3",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 38.9025235,
"longitude": -77.0552516
},
"instruction": "Keep <span class=\"direction\">right</span> onto <span class=\"next-street\">Whitehurst Fwy</span> <span class=\"number\">(US-29)</span>. <span class=\"distance-description\">Go for <span class=\"length\">1.4 km</span>.</span>",
"travelTime": 143,
"length": 1381,
"id": "M4",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 38.9050448,
"longitude": -77.0701969
},
"instruction": "Turn <span class=\"direction\">left</span> onto <span class=\"next-street\">M St NW</span>. <span class=\"distance-description\">Go for <span class=\"length\">784 m</span>.</span>",
"travelTime": 80,
"length": 784,
"id": "M5",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 38.9060318,
"longitude": -77.0790696
},
"instruction": "Turn <span class=\"direction\">slightly left</span> onto <span class=\"next-street\">Canal Rd NW</span>. <span class=\"distance-description\">Go for <span class=\"length\">4.2 km</span>.</span>",
"travelTime": 287,
"length": 4230,
"id": "M6",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 38.9303219,
"longitude": -77.1117926
},
"instruction": "Continue on <span class=\"next-street\">Clara Barton Pkwy</span>. <span class=\"distance-description\">Go for <span class=\"length\">844 m</span>.</span>",
"travelTime": 55,
"length": 844,
"id": "M7",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 38.9368558,
"longitude": -77.1166742
},
"instruction": "Continue on <span class=\"next-street\">Clara Barton Pkwy</span>. <span class=\"distance-description\">Go for <span class=\"length\">4.7 km</span>.</span>",
"travelTime": 294,
"length": 4652,
"id": "M8",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 38.9706838,
"longitude": -77.1461463
},
"instruction": "Keep <span class=\"direction\">right</span> onto <span class=\"next-street\">Cabin John Pkwy N</span> toward <span class=\"sign\"><span lang=\"en\">I-495 N</span></span>. <span class=\"distance-description\">Go for <span class=\"length\">2.1 km</span>.</span>",
"travelTime": 90,
"length": 2069,
"id": "M9",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 38.9858222,
"longitude": -77.1571326
},
"instruction": "Take <span class=\"direction\">left</span> ramp onto <span class=\"number\">I-495 N</span> <span class=\"next-street\">(Capital Beltway)</span>. <span class=\"distance-description\">Go for <span class=\"length\">2.9 km</span>.</span>",
"travelTime": 129,
"length": 2890,
"id": "M10",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 39.0104449,
"longitude": -77.1508026
},
"instruction": "Keep <span class=\"direction\">left</span> onto <span class=\"number\">I-270-SPUR</span> toward <span class=\"sign\"><span lang=\"en\">I-270</span>/<span lang=\"en\">Rockville</span>/<span lang=\"en\">Frederick</span></span>. <span class=\"distance-description\">Go for <span class=\"length\">1.1 km</span>.</span>",
"travelTime": 48,
"length": 1136,
"id": "M11",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 39.0192747,
"longitude": -77.144773
},
"instruction": "Take exit <span class=\"exit\">1</span> toward <span class=\"sign\"><span lang=\"en\">Democracy Blvd</span>/<span lang=\"en\">Old Georgetown Rd</span>/<span lang=\"en\">MD-187</span></span> onto <span class=\"next-street\">Democracy Blvd</span>. <span class=\"distance-description\">Go for <span class=\"length\">1.8 km</span>.</span>",
"travelTime": 205,
"length": 1818,
"id": "M12",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 39.0247464,
"longitude": -77.1253431
},
"instruction": "Turn <span class=\"direction\">left</span> onto <span class=\"next-street\">Old Georgetown Rd</span> <span class=\"number\">(MD-187)</span>. <span class=\"distance-description\">Go for <span class=\"length\">2.3 km</span>.</span>",
"travelTime": 230,
"length": 2340,
"id": "M13",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 39.0447772,
"longitude": -77.1203649
},
"instruction": "Turn <span class=\"direction\">right</span> onto <span class=\"next-street\">Nicholson Ln</span>. <span class=\"distance-description\">Go for <span class=\"length\">208 m</span>.</span>",
"travelTime": 31,
"length": 208,
"id": "M14",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 39.0448952,
"longitude": -77.1179724
},
"instruction": "Turn <span class=\"direction\">right</span> onto <span class=\"next-street\">Commonwealth Dr</span>. <span class=\"distance-description\">Go for <span class=\"length\">341 m</span>.</span>",
"travelTime": 75,
"length": 341,
"id": "M15",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 39.0422511,
"longitude": -77.1193526
},
"instruction": "Arrive at <span class=\"street\">Commonwealth Dr</span>. Your destination is on the left.",
"travelTime": 4,
"length": 22,
"id": "M16",
"_type": "PrivateTransportManeuverType"
}
]
}
],
"summary": {
"distance": 23381,
"trafficTime": 1782,
"baseTime": 1712,
"flags": [
"noThroughRoad",
"motorway",
"builtUpArea",
"park"
],
"text": "The trip takes <span class=\"length\">23.4 km</span> and <span class=\"time\">30 mins</span>.",
"travelTime": 1782,
"_type": "RouteSummaryType"
}
}
],
"language": "en-us"
}
}

View File

@ -0,0 +1,299 @@
{
"response": {
"metaInfo": {
"timestamp": "2019-07-19T07:38:39Z",
"mapVersion": "8.30.98.154",
"moduleVersion": "7.2.201928-4446",
"interfaceVersion": "2.6.64",
"availableMapVersion": [
"8.30.98.154"
]
},
"route": [
{
"waypoint": [
{
"linkId": "+732182239",
"mappedPosition": {
"latitude": 38.9,
"longitude": -77.0488358
},
"originalPosition": {
"latitude": 38.9,
"longitude": -77.0483301
},
"type": "stopOver",
"spot": 0.4946237,
"sideOfStreet": "right",
"mappedRoadName": "22nd St NW",
"label": "22nd St NW",
"shapeIndex": 0,
"source": "user"
},
{
"linkId": "+942865877",
"mappedPosition": {
"latitude": 38.9999735,
"longitude": -77.100141
},
"originalPosition": {
"latitude": 38.9999999,
"longitude": -77.1000001
},
"type": "stopOver",
"spot": 1,
"sideOfStreet": "left",
"mappedRoadName": "Service Rd S",
"label": "Service Rd S",
"shapeIndex": 279,
"source": "user"
}
],
"mode": {
"type": "fastest",
"transportModes": [
"car"
],
"trafficMode": "enabled",
"feature": []
},
"leg": [
{
"start": {
"linkId": "+732182239",
"mappedPosition": {
"latitude": 38.9,
"longitude": -77.0488358
},
"originalPosition": {
"latitude": 38.9,
"longitude": -77.0483301
},
"type": "stopOver",
"spot": 0.4946237,
"sideOfStreet": "right",
"mappedRoadName": "22nd St NW",
"label": "22nd St NW",
"shapeIndex": 0,
"source": "user"
},
"end": {
"linkId": "+942865877",
"mappedPosition": {
"latitude": 38.9999735,
"longitude": -77.100141
},
"originalPosition": {
"latitude": 38.9999999,
"longitude": -77.1000001
},
"type": "stopOver",
"spot": 1,
"sideOfStreet": "left",
"mappedRoadName": "Service Rd S",
"label": "Service Rd S",
"shapeIndex": 279,
"source": "user"
},
"length": 23903,
"travelTime": 1884,
"maneuver": [
{
"position": {
"latitude": 38.9,
"longitude": -77.0488358
},
"instruction": "Head toward <span class=\"toward_street\">I St NW</span> on <span class=\"street\">22nd St NW</span>. <span class=\"distance-description\">Go for <span class=\"length\">279 m</span>.</span>",
"travelTime": 95,
"length": 279,
"id": "M1",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 38.9021051,
"longitude": -77.048825
},
"instruction": "Turn <span class=\"direction\">left</span> toward <span class=\"sign\">Pennsylvania Ave NW</span>. <span class=\"distance-description\">Go for <span class=\"length\">71 m</span>.</span>",
"travelTime": 21,
"length": 71,
"id": "M2",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 38.902545,
"longitude": -77.0494151
},
"instruction": "Take the <span class=\"exit\">3rd exit</span> from Washington Cir NW roundabout onto <span class=\"next-street\">K St NW</span>. <span class=\"distance-description\">Go for <span class=\"length\">352 m</span>.</span>",
"travelTime": 90,
"length": 352,
"id": "M3",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 38.9026523,
"longitude": -77.0529449
},
"instruction": "Keep <span class=\"direction\">left</span> onto <span class=\"next-street\">K St NW</span> <span class=\"number\">(US-29)</span>. <span class=\"distance-description\">Go for <span class=\"length\">201 m</span>.</span>",
"travelTime": 30,
"length": 201,
"id": "M4",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 38.9025235,
"longitude": -77.0552516
},
"instruction": "Keep <span class=\"direction\">right</span> onto <span class=\"next-street\">Whitehurst Fwy</span> <span class=\"number\">(US-29)</span>. <span class=\"distance-description\">Go for <span class=\"length\">1.4 km</span>.</span>",
"travelTime": 131,
"length": 1381,
"id": "M5",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 38.9050448,
"longitude": -77.0701969
},
"instruction": "Turn <span class=\"direction\">left</span> onto <span class=\"next-street\">M St NW</span>. <span class=\"distance-description\">Go for <span class=\"length\">784 m</span>.</span>",
"travelTime": 78,
"length": 784,
"id": "M6",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 38.9060318,
"longitude": -77.0790696
},
"instruction": "Turn <span class=\"direction\">slightly left</span> onto <span class=\"next-street\">Canal Rd NW</span>. <span class=\"distance-description\">Go for <span class=\"length\">4.2 km</span>.</span>",
"travelTime": 277,
"length": 4230,
"id": "M7",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 38.9303219,
"longitude": -77.1117926
},
"instruction": "Continue on <span class=\"next-street\">Clara Barton Pkwy</span>. <span class=\"distance-description\">Go for <span class=\"length\">844 m</span>.</span>",
"travelTime": 55,
"length": 844,
"id": "M8",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 38.9368558,
"longitude": -77.1166742
},
"instruction": "Continue on <span class=\"next-street\">Clara Barton Pkwy</span>. <span class=\"distance-description\">Go for <span class=\"length\">4.7 km</span>.</span>",
"travelTime": 298,
"length": 4652,
"id": "M9",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 38.9706838,
"longitude": -77.1461463
},
"instruction": "Keep <span class=\"direction\">right</span> onto <span class=\"next-street\">Cabin John Pkwy N</span> toward <span class=\"sign\"><span lang=\"en\">I-495 N</span></span>. <span class=\"distance-description\">Go for <span class=\"length\">2.1 km</span>.</span>",
"travelTime": 91,
"length": 2069,
"id": "M10",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 38.9858222,
"longitude": -77.1571326
},
"instruction": "Take <span class=\"direction\">left</span> ramp onto <span class=\"number\">I-495 N</span> <span class=\"next-street\">(Capital Beltway)</span>. <span class=\"distance-description\">Go for <span class=\"length\">5.5 km</span>.</span>",
"travelTime": 238,
"length": 5538,
"id": "M11",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 39.0153587,
"longitude": -77.1221781
},
"instruction": "Take exit <span class=\"exit\">36</span> toward <span class=\"sign\"><span lang=\"en\">Bethesda</span></span> onto <span class=\"number\">MD-187 S</span> <span class=\"next-street\">(Old Georgetown Rd)</span>. <span class=\"distance-description\">Go for <span class=\"length\">2.4 km</span>.</span>",
"travelTime": 211,
"length": 2365,
"id": "M12",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 38.9981818,
"longitude": -77.1093571
},
"instruction": "Turn <span class=\"direction\">left</span> onto <span class=\"next-street\">Lincoln Dr</span>. <span class=\"distance-description\">Go for <span class=\"length\">506 m</span>.</span>",
"travelTime": 127,
"length": 506,
"id": "M13",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 38.9987397,
"longitude": -77.1037138
},
"instruction": "Turn <span class=\"direction\">right</span> onto <span class=\"next-street\">Service Rd W</span>. <span class=\"distance-description\">Go for <span class=\"length\">121 m</span>.</span>",
"travelTime": 36,
"length": 121,
"id": "M14",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 38.9976454,
"longitude": -77.1036172
},
"instruction": "Turn <span class=\"direction\">left</span> onto <span class=\"next-street\">Service Rd S</span>. <span class=\"distance-description\">Go for <span class=\"length\">510 m</span>.</span>",
"travelTime": 106,
"length": 510,
"id": "M15",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 38.9999735,
"longitude": -77.100141
},
"instruction": "Arrive at <span class=\"street\">Service Rd S</span>. Your destination is on the left.",
"travelTime": 0,
"length": 0,
"id": "M16",
"_type": "PrivateTransportManeuverType"
}
]
}
],
"summary": {
"distance": 23903,
"trafficTime": 1861,
"baseTime": 1803,
"flags": [
"noThroughRoad",
"motorway",
"builtUpArea",
"park",
"privateRoad"
],
"text": "The trip takes <span class=\"length\">23.9 km</span> and <span class=\"time\">31 mins</span>.",
"travelTime": 1861,
"_type": "RouteSummaryType"
}
}
],
"language": "en-us"
}
}

View File

@ -0,0 +1,231 @@
{
"response": {
"metaInfo": {
"timestamp": "2019-07-21T21:05:28Z",
"mapVersion": "8.30.98.154",
"moduleVersion": "7.2.201928-4478",
"interfaceVersion": "2.6.64",
"availableMapVersion": [
"8.30.98.154"
]
},
"route": [
{
"waypoint": [
{
"linkId": "-1128310200",
"mappedPosition": {
"latitude": 38.9026523,
"longitude": -77.048338
},
"originalPosition": {
"latitude": 38.9029809,
"longitude": -77.048338
},
"type": "stopOver",
"spot": 0.3538462,
"sideOfStreet": "right",
"mappedRoadName": "K St NW",
"label": "K St NW",
"shapeIndex": 0,
"source": "user"
},
{
"linkId": "-18459081",
"mappedPosition": {
"latitude": 39.0422511,
"longitude": -77.1193526
},
"originalPosition": {
"latitude": 39.042158,
"longitude": -77.119116
},
"type": "stopOver",
"spot": 0.7253521,
"sideOfStreet": "left",
"mappedRoadName": "Commonwealth Dr",
"label": "Commonwealth Dr",
"shapeIndex": 162,
"source": "user"
}
],
"mode": {
"type": "shortest",
"transportModes": [
"car"
],
"trafficMode": "enabled",
"feature": []
},
"leg": [
{
"start": {
"linkId": "-1128310200",
"mappedPosition": {
"latitude": 38.9026523,
"longitude": -77.048338
},
"originalPosition": {
"latitude": 38.9029809,
"longitude": -77.048338
},
"type": "stopOver",
"spot": 0.3538462,
"sideOfStreet": "right",
"mappedRoadName": "K St NW",
"label": "K St NW",
"shapeIndex": 0,
"source": "user"
},
"end": {
"linkId": "-18459081",
"mappedPosition": {
"latitude": 39.0422511,
"longitude": -77.1193526
},
"originalPosition": {
"latitude": 39.042158,
"longitude": -77.119116
},
"type": "stopOver",
"spot": 0.7253521,
"sideOfStreet": "left",
"mappedRoadName": "Commonwealth Dr",
"label": "Commonwealth Dr",
"shapeIndex": 162,
"source": "user"
},
"length": 18388,
"travelTime": 2493,
"maneuver": [
{
"position": {
"latitude": 38.9026523,
"longitude": -77.048338
},
"instruction": "Head <span class=\"heading\">west</span> on <span class=\"street\">K St NW</span>. <span class=\"distance-description\">Go for <span class=\"length\">79 m</span>.</span>",
"travelTime": 22,
"length": 79,
"id": "M1",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 38.9026523,
"longitude": -77.048825
},
"instruction": "Turn <span class=\"direction\">right</span> onto <span class=\"next-street\">22nd St NW</span>. <span class=\"distance-description\">Go for <span class=\"length\">141 m</span>.</span>",
"travelTime": 79,
"length": 141,
"id": "M2",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 38.9039075,
"longitude": -77.048825
},
"instruction": "Keep <span class=\"direction\">left</span> onto <span class=\"next-street\">22nd St NW</span>. <span class=\"distance-description\">Go for <span class=\"length\">841 m</span>.</span>",
"travelTime": 256,
"length": 841,
"id": "M3",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 38.9114928,
"longitude": -77.0487821
},
"instruction": "Turn <span class=\"direction\">left</span> onto <span class=\"next-street\">Massachusetts Ave NW</span>. <span class=\"distance-description\">Go for <span class=\"length\">145 m</span>.</span>",
"travelTime": 22,
"length": 145,
"id": "M4",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 38.9120293,
"longitude": -77.0502949
},
"instruction": "Take the <span class=\"exit\">1st exit</span> from Massachusetts Ave NW roundabout onto <span class=\"next-street\">Massachusetts Ave NW</span>. <span class=\"distance-description\">Go for <span class=\"length\">2.8 km</span>.</span>",
"travelTime": 301,
"length": 2773,
"id": "M5",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 38.9286053,
"longitude": -77.073158
},
"instruction": "Turn <span class=\"direction\">right</span> onto <span class=\"next-street\">Wisconsin Ave NW</span>. <span class=\"distance-description\">Go for <span class=\"length\">3.8 km</span>.</span>",
"travelTime": 610,
"length": 3801,
"id": "M6",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 38.9607918,
"longitude": -77.0857322
},
"instruction": "Continue on <span class=\"next-street\">Wisconsin Ave</span> <span class=\"number\">(MD-355)</span>. <span class=\"distance-description\">Go for <span class=\"length\">9.7 km</span>.</span>",
"travelTime": 1013,
"length": 9686,
"id": "M7",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 39.0447664,
"longitude": -77.1116638
},
"instruction": "Turn <span class=\"direction\">left</span> onto <span class=\"next-street\">Nicholson Ln</span>. <span class=\"distance-description\">Go for <span class=\"length\">559 m</span>.</span>",
"travelTime": 111,
"length": 559,
"id": "M8",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 39.0448952,
"longitude": -77.1179724
},
"instruction": "Turn <span class=\"direction\">left</span> onto <span class=\"next-street\">Commonwealth Dr</span>. <span class=\"distance-description\">Go for <span class=\"length\">341 m</span>.</span>",
"travelTime": 75,
"length": 341,
"id": "M9",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 39.0422511,
"longitude": -77.1193526
},
"instruction": "Arrive at <span class=\"street\">Commonwealth Dr</span>. Your destination is on the left.",
"travelTime": 4,
"length": 22,
"id": "M10",
"_type": "PrivateTransportManeuverType"
}
]
}
],
"summary": {
"distance": 18388,
"trafficTime": 2427,
"baseTime": 2150,
"flags": [
"noThroughRoad",
"builtUpArea",
"park"
],
"text": "The trip takes <span class=\"length\">18.4 km</span> and <span class=\"time\">40 mins</span>.",
"travelTime": 2427,
"_type": "RouteSummaryType"
}
}
],
"language": "en-us"
}
}

View File

@ -0,0 +1,308 @@
{
"response": {
"metaInfo": {
"timestamp": "2019-07-21T18:40:10Z",
"mapVersion": "8.30.98.154",
"moduleVersion": "7.2.201928-4478",
"interfaceVersion": "2.6.64",
"availableMapVersion": [
"8.30.98.154"
]
},
"route": [
{
"waypoint": [
{
"linkId": "-1230414527",
"mappedPosition": {
"latitude": 41.9797859,
"longitude": -87.8790879
},
"originalPosition": {
"latitude": 41.9798,
"longitude": -87.8801
},
"type": "stopOver",
"spot": 0.5079365,
"sideOfStreet": "right",
"mappedRoadName": "Mannheim Rd",
"label": "Mannheim Rd - US-12",
"shapeIndex": 0,
"source": "user"
},
{
"linkId": "+924115108",
"mappedPosition": {
"latitude": 41.90413,
"longitude": -87.9223502
},
"originalPosition": {
"latitude": 41.9043,
"longitude": -87.9216001
},
"type": "stopOver",
"spot": 0.1925926,
"sideOfStreet": "right",
"mappedRoadName": "",
"label": "",
"shapeIndex": 122,
"source": "user"
}
],
"mode": {
"type": "fastest",
"transportModes": [
"pedestrian"
],
"trafficMode": "disabled",
"feature": []
},
"leg": [
{
"start": {
"linkId": "-1230414527",
"mappedPosition": {
"latitude": 41.9797859,
"longitude": -87.8790879
},
"originalPosition": {
"latitude": 41.9798,
"longitude": -87.8801
},
"type": "stopOver",
"spot": 0.5079365,
"sideOfStreet": "right",
"mappedRoadName": "Mannheim Rd",
"label": "Mannheim Rd - US-12",
"shapeIndex": 0,
"source": "user"
},
"end": {
"linkId": "+924115108",
"mappedPosition": {
"latitude": 41.90413,
"longitude": -87.9223502
},
"originalPosition": {
"latitude": 41.9043,
"longitude": -87.9216001
},
"type": "stopOver",
"spot": 0.1925926,
"sideOfStreet": "right",
"mappedRoadName": "",
"label": "",
"shapeIndex": 122,
"source": "user"
},
"length": 12533,
"travelTime": 12631,
"maneuver": [
{
"position": {
"latitude": 41.9797859,
"longitude": -87.8790879
},
"instruction": "Head <span class=\"heading\">south</span> on <span class=\"street\">Mannheim Rd</span>. <span class=\"distance-description\">Go for <span class=\"length\">848 m</span>.</span>",
"travelTime": 848,
"length": 848,
"id": "M1",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9722581,
"longitude": -87.8776109
},
"instruction": "Take the street on the <span class=\"direction\">left</span>, <span class=\"next-street\">Mannheim Rd</span>. <span class=\"distance-description\">Go for <span class=\"length\">4.2 km</span>.</span>",
"travelTime": 4239,
"length": 4227,
"id": "M2",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9364238,
"longitude": -87.8849387
},
"instruction": "Turn <span class=\"direction\">right</span> onto <span class=\"next-street\">W Belmont Ave</span>. <span class=\"distance-description\">Go for <span class=\"length\">595 m</span>.</span>",
"travelTime": 605,
"length": 595,
"id": "M3",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9362521,
"longitude": -87.8921163
},
"instruction": "Turn <span class=\"direction\">left</span> onto <span class=\"next-street\">Cullerton St</span>. <span class=\"distance-description\">Go for <span class=\"length\">406 m</span>.</span>",
"travelTime": 411,
"length": 406,
"id": "M4",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9326043,
"longitude": -87.8919983
},
"instruction": "Turn <span class=\"direction\">right</span> onto <span class=\"next-street\">Cullerton St</span>. <span class=\"distance-description\">Go for <span class=\"length\">1.2 km</span>.</span>",
"travelTime": 1249,
"length": 1239,
"id": "M5",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9217896,
"longitude": -87.8928781
},
"instruction": "Turn <span class=\"direction\">right</span> onto <span class=\"next-street\">E Fullerton Ave</span>. <span class=\"distance-description\">Go for <span class=\"length\">786 m</span>.</span>",
"travelTime": 796,
"length": 786,
"id": "M6",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9216394,
"longitude": -87.9023838
},
"instruction": "Turn <span class=\"direction\">left</span> onto <span class=\"next-street\">La Porte Ave</span>. <span class=\"distance-description\">Go for <span class=\"length\">424 m</span>.</span>",
"travelTime": 430,
"length": 424,
"id": "M7",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9180024,
"longitude": -87.9028559
},
"instruction": "Turn <span class=\"direction\">right</span> onto <span class=\"next-street\">E Palmer Ave</span>. <span class=\"distance-description\">Go for <span class=\"length\">864 m</span>.</span>",
"travelTime": 875,
"length": 864,
"id": "M8",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9175196,
"longitude": -87.9132199
},
"instruction": "Turn <span class=\"direction\">left</span> onto <span class=\"next-street\">N Railroad Ave</span>. <span class=\"distance-description\">Go for <span class=\"length\">1.2 km</span>.</span>",
"travelTime": 1180,
"length": 1170,
"id": "M9",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9070268,
"longitude": -87.9130161
},
"instruction": "Turn <span class=\"direction\">right</span> onto <span class=\"next-street\">W North Ave</span>. <span class=\"distance-description\">Go for <span class=\"length\">638 m</span>.</span>",
"travelTime": 638,
"length": 638,
"id": "M10",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9068551,
"longitude": -87.9207087
},
"instruction": "Take the street on the <span class=\"direction\">left</span>, <span class=\"next-street\">E North Ave</span>. <span class=\"distance-description\">Go for <span class=\"length\">354 m</span>.</span>",
"travelTime": 354,
"length": 354,
"id": "M11",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9065869,
"longitude": -87.9249573
},
"instruction": "Take the street on the <span class=\"direction\">left</span>, <span class=\"next-street\">E North Ave</span>. <span class=\"distance-description\">Go for <span class=\"length\">228 m</span>.</span>",
"travelTime": 242,
"length": 228,
"id": "M12",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9065225,
"longitude": -87.9277039
},
"instruction": "Turn <span class=\"direction\">left</span>. <span class=\"distance-description\">Go for <span class=\"length\">409 m</span>.</span>",
"travelTime": 419,
"length": 409,
"id": "M13",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9040334,
"longitude": -87.9260409
},
"instruction": "Turn <span class=\"direction\">left</span> onto <span class=\"next-street\">E Third St</span>. <span class=\"distance-description\">Go for <span class=\"length\">206 m</span>.</span>",
"travelTime": 206,
"length": 206,
"id": "M14",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9038832,
"longitude": -87.9236054
},
"instruction": "Turn <span class=\"direction\">left</span>. <span class=\"distance-description\">Go for <span class=\"length\">113 m</span>.</span>",
"travelTime": 113,
"length": 113,
"id": "M15",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9039047,
"longitude": -87.9222536
},
"instruction": "Turn <span class=\"direction\">left</span>. <span class=\"distance-description\">Go for <span class=\"length\">26 m</span>.</span>",
"travelTime": 26,
"length": 26,
"id": "M16",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.90413,
"longitude": -87.9223502
},
"instruction": "Arrive at your destination on the right.",
"travelTime": 0,
"length": 0,
"id": "M17",
"_type": "PrivateTransportManeuverType"
}
]
}
],
"summary": {
"distance": 12533,
"baseTime": 12631,
"flags": [
"noThroughRoad",
"builtUpArea",
"park",
"privateRoad"
],
"text": "The trip takes <span class=\"length\">12.5 km</span> and <span class=\"time\">3:31 h</span>.",
"travelTime": 12631,
"_type": "RouteSummaryType"
}
}
],
"language": "en-us"
}
}

View File

@ -0,0 +1,294 @@
{
"response": {
"metaInfo": {
"timestamp": "2019-07-21T18:40:37Z",
"mapVersion": "8.30.98.154",
"moduleVersion": "7.2.201928-4478",
"interfaceVersion": "2.6.64",
"availableMapVersion": [
"8.30.98.154"
]
},
"route": [
{
"waypoint": [
{
"linkId": "-1230414527",
"mappedPosition": {
"latitude": 41.9797859,
"longitude": -87.8790879
},
"originalPosition": {
"latitude": 41.9798,
"longitude": -87.8801
},
"type": "stopOver",
"spot": 0.5079365,
"sideOfStreet": "right",
"mappedRoadName": "Mannheim Rd",
"label": "Mannheim Rd - US-12",
"shapeIndex": 0,
"source": "user"
},
{
"linkId": "+924115108",
"mappedPosition": {
"latitude": 41.90413,
"longitude": -87.9223502
},
"originalPosition": {
"latitude": 41.9043,
"longitude": -87.9216001
},
"type": "stopOver",
"spot": 0.1925926,
"sideOfStreet": "right",
"mappedRoadName": "",
"label": "",
"shapeIndex": 191,
"source": "user"
}
],
"mode": {
"type": "fastest",
"transportModes": [
"publicTransport"
],
"trafficMode": "disabled",
"feature": []
},
"leg": [
{
"start": {
"linkId": "-1230414527",
"mappedPosition": {
"latitude": 41.9797859,
"longitude": -87.8790879
},
"originalPosition": {
"latitude": 41.9798,
"longitude": -87.8801
},
"type": "stopOver",
"spot": 0.5079365,
"sideOfStreet": "right",
"mappedRoadName": "Mannheim Rd",
"label": "Mannheim Rd - US-12",
"shapeIndex": 0,
"source": "user"
},
"end": {
"linkId": "+924115108",
"mappedPosition": {
"latitude": 41.90413,
"longitude": -87.9223502
},
"originalPosition": {
"latitude": 41.9043,
"longitude": -87.9216001
},
"type": "stopOver",
"spot": 0.1925926,
"sideOfStreet": "right",
"mappedRoadName": "",
"label": "",
"shapeIndex": 191,
"source": "user"
},
"length": 22325,
"travelTime": 5350,
"maneuver": [
{
"position": {
"latitude": 41.9797859,
"longitude": -87.8790879
},
"instruction": "Head <span class=\"heading\">south</span> on <span class=\"street\">Mannheim Rd</span>. <span class=\"distance-description\">Go for <span class=\"length\">848 m</span>.</span>",
"travelTime": 848,
"length": 848,
"id": "M1",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9722581,
"longitude": -87.8776109
},
"instruction": "Take the street on the <span class=\"direction\">left</span>, <span class=\"next-street\">Mannheim Rd</span>. <span class=\"distance-description\">Go for <span class=\"length\">825 m</span>.</span>",
"travelTime": 825,
"length": 825,
"id": "M2",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9650483,
"longitude": -87.8769565
},
"instruction": "Go to the stop <span class=\"station\">Mannheim/Lawrence</span> and take the <span class=\"transit\">bus</span> <span class=\"line\">332</span> toward <span class=\"destination\">Palmer/Schiller</span>. <span class=\"distance-description\">Follow for <span class=\"stops\">7 stops</span>.</span>",
"travelTime": 475,
"length": 4360,
"id": "M3",
"stopName": "Mannheim/Lawrence",
"_type": "PublicTransportManeuverType"
},
{
"position": {
"latitude": 41.9541478,
"longitude": -87.9133594
},
"instruction": "Get off at <span class=\"station\">Irving Park/Taft</span>.",
"travelTime": 0,
"length": 0,
"id": "M4",
"stopName": "Irving Park/Taft",
"_type": "PublicTransportManeuverType"
},
{
"position": {
"latitude": 41.9541478,
"longitude": -87.9133594
},
"instruction": "Take the <span class=\"transit\">bus</span> <span class=\"line\">332</span> toward <span class=\"destination\">Cargo Rd./Delta Cargo</span>. <span class=\"distance-description\">Follow for <span class=\"stops\">1 stop</span>.</span>",
"travelTime": 155,
"length": 3505,
"id": "M5",
"stopName": "Irving Park/Taft",
"_type": "PublicTransportManeuverType"
},
{
"position": {
"latitude": 41.9599199,
"longitude": -87.9162776
},
"instruction": "Get off at <span class=\"station\">Cargo Rd./S. Access Rd./Lufthansa</span>.",
"travelTime": 0,
"length": 0,
"id": "M6",
"stopName": "Cargo Rd./S. Access Rd./Lufthansa",
"_type": "PublicTransportManeuverType"
},
{
"position": {
"latitude": 41.9599199,
"longitude": -87.9162776
},
"instruction": "Take the <span class=\"transit\">bus</span> <span class=\"line\">332</span> toward <span class=\"destination\">Palmer/Schiller</span>. <span class=\"distance-description\">Follow for <span class=\"stops\">41 stops</span>.</span>",
"travelTime": 1510,
"length": 11261,
"id": "M7",
"stopName": "Cargo Rd./S. Access Rd./Lufthansa",
"_type": "PublicTransportManeuverType"
},
{
"position": {
"latitude": 41.9041729,
"longitude": -87.9399669
},
"instruction": "Get off at <span class=\"station\">York/Third</span>.",
"travelTime": 0,
"length": 0,
"id": "M8",
"stopName": "York/Third",
"nextRoadName": "N York St",
"_type": "PublicTransportManeuverType"
},
{
"position": {
"latitude": 41.9041729,
"longitude": -87.9399669
},
"instruction": "Head <span class=\"heading\">east</span> on <span class=\"street\">N York St</span>. <span class=\"distance-description\">Go for <span class=\"length\">33 m</span>.</span>",
"travelTime": 43,
"length": 33,
"id": "M9",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9039476,
"longitude": -87.9398811
},
"instruction": "Turn <span class=\"direction\">left</span> onto <span class=\"next-street\">E Third St</span>. <span class=\"distance-description\">Go for <span class=\"length\">1.4 km</span>.</span>",
"travelTime": 1355,
"length": 1354,
"id": "M10",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9038832,
"longitude": -87.9236054
},
"instruction": "Turn <span class=\"direction\">left</span>. <span class=\"distance-description\">Go for <span class=\"length\">113 m</span>.</span>",
"travelTime": 113,
"length": 113,
"id": "M11",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9039047,
"longitude": -87.9222536
},
"instruction": "Turn <span class=\"direction\">left</span>. <span class=\"distance-description\">Go for <span class=\"length\">26 m</span>.</span>",
"travelTime": 26,
"length": 26,
"id": "M12",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.90413,
"longitude": -87.9223502
},
"instruction": "Arrive at your destination on the right.",
"travelTime": 0,
"length": 0,
"id": "M13",
"_type": "PrivateTransportManeuverType"
}
]
}
],
"publicTransportLine": [
{
"lineName": "332",
"companyName": "",
"destination": "Palmer/Schiller",
"type": "busPublic",
"id": "L1"
},
{
"lineName": "332",
"companyName": "",
"destination": "Cargo Rd./Delta Cargo",
"type": "busPublic",
"id": "L2"
},
{
"lineName": "332",
"companyName": "",
"destination": "Palmer/Schiller",
"type": "busPublic",
"id": "L3"
}
],
"summary": {
"distance": 22325,
"baseTime": 5350,
"flags": [
"noThroughRoad",
"builtUpArea",
"park"
],
"text": "The trip takes <span class=\"length\">22.3 km</span> and <span class=\"time\">1:29 h</span>.",
"travelTime": 5350,
"departure": "1970-01-01T00:00:00Z",
"_type": "PublicTransportRouteSummaryType"
}
}
],
"language": "en-us"
}
}

View File

@ -0,0 +1,308 @@
{
"response": {
"metaInfo": {
"timestamp": "2019-08-06T06:43:24Z",
"mapVersion": "8.30.99.152",
"moduleVersion": "7.2.201931-4739",
"interfaceVersion": "2.6.66",
"availableMapVersion": [
"8.30.99.152"
]
},
"route": [
{
"waypoint": [
{
"linkId": "-1230414527",
"mappedPosition": {
"latitude": 41.9797859,
"longitude": -87.8790879
},
"originalPosition": {
"latitude": 41.9798,
"longitude": -87.8801
},
"type": "stopOver",
"spot": 0.5079365,
"sideOfStreet": "right",
"mappedRoadName": "Mannheim Rd",
"label": "Mannheim Rd - US-12",
"shapeIndex": 0,
"source": "user"
},
{
"linkId": "+924115108",
"mappedPosition": {
"latitude": 41.90413,
"longitude": -87.9223502
},
"originalPosition": {
"latitude": 41.9043,
"longitude": -87.9216001
},
"type": "stopOver",
"spot": 0.1925926,
"sideOfStreet": "right",
"mappedRoadName": "",
"label": "",
"shapeIndex": 111,
"source": "user"
}
],
"mode": {
"type": "fastest",
"transportModes": [
"publicTransportTimeTable"
],
"trafficMode": "disabled",
"feature": []
},
"leg": [
{
"start": {
"linkId": "-1230414527",
"mappedPosition": {
"latitude": 41.9797859,
"longitude": -87.8790879
},
"originalPosition": {
"latitude": 41.9798,
"longitude": -87.8801
},
"type": "stopOver",
"spot": 0.5079365,
"sideOfStreet": "right",
"mappedRoadName": "Mannheim Rd",
"label": "Mannheim Rd - US-12",
"shapeIndex": 0,
"source": "user"
},
"end": {
"linkId": "+924115108",
"mappedPosition": {
"latitude": 41.90413,
"longitude": -87.9223502
},
"originalPosition": {
"latitude": 41.9043,
"longitude": -87.9216001
},
"type": "stopOver",
"spot": 0.1925926,
"sideOfStreet": "right",
"mappedRoadName": "",
"label": "",
"shapeIndex": 111,
"source": "user"
},
"length": 14775,
"travelTime": 4784,
"maneuver": [
{
"position": {
"latitude": 41.9797859,
"longitude": -87.8790879
},
"instruction": "Head <span class=\"heading\">south</span> on <span class=\"street\">Mannheim Rd</span>. <span class=\"distance-description\">Go for <span class=\"length\">848 m</span>.</span>",
"travelTime": 848,
"length": 848,
"id": "M1",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9722581,
"longitude": -87.8776109
},
"instruction": "Take the street on the <span class=\"direction\">left</span>, <span class=\"next-street\">Mannheim Rd</span>. <span class=\"distance-description\">Go for <span class=\"length\">812 m</span>.</span>",
"travelTime": 812,
"length": 812,
"id": "M2",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.965051,
"longitude": -87.8769591
},
"instruction": "Go to the <span class=\"company\">Bus</span> stop <span class=\"station\">Mannheim/Lawrence</span> and take the <span class=\"transit\">bus</span> <span class=\"line\">330</span> toward <span class=\"destination\">Archer/Harlem (Terminal)</span>. <span class=\"distance-description\">Follow for <span class=\"stops\">33 stops</span>.</span>",
"travelTime": 900,
"length": 7815,
"id": "M3",
"stopName": "Mannheim/Lawrence",
"_type": "PublicTransportManeuverType"
},
{
"position": {
"latitude": 41.896836,
"longitude": -87.883771
},
"instruction": "Get off at <span class=\"station\">Mannheim/Lake</span>.",
"travelTime": 0,
"length": 0,
"id": "M4",
"stopName": "Mannheim/Lake",
"_type": "PublicTransportManeuverType"
},
{
"position": {
"latitude": 41.896836,
"longitude": -87.883771
},
"instruction": "Walk to <span class=\"company\">Bus</span> <span class=\"station\">Lake/Mannheim</span>.",
"travelTime": 300,
"length": 72,
"id": "M5",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.897263,
"longitude": -87.8842648
},
"instruction": "Take the <span class=\"transit\">bus</span> <span class=\"line\">309</span> toward <span class=\"destination\">Elmhurst Metra Station</span>. <span class=\"distance-description\">Follow for <span class=\"stops\">18 stops</span>.</span>",
"travelTime": 1020,
"length": 4362,
"id": "M6",
"stopName": "Lake/Mannheim",
"_type": "PublicTransportManeuverType"
},
{
"position": {
"latitude": 41.9066347,
"longitude": -87.928671
},
"instruction": "Get off at <span class=\"station\">North/Berteau</span>.",
"travelTime": 0,
"length": 0,
"id": "M7",
"stopName": "North/Berteau",
"nextRoadName": "E Berteau Ave",
"_type": "PublicTransportManeuverType"
},
{
"position": {
"latitude": 41.9066347,
"longitude": -87.928671
},
"instruction": "Head <span class=\"heading\">north</span> on <span class=\"street\">E Berteau Ave</span>. <span class=\"distance-description\">Go for <span class=\"length\">23 m</span>.</span>",
"travelTime": 40,
"length": 23,
"id": "M8",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9067693,
"longitude": -87.9284549
},
"instruction": "Turn <span class=\"direction\">right</span> onto <span class=\"next-street\">E Berteau Ave</span>. <span class=\"distance-description\">Go for <span class=\"length\">40 m</span>.</span>",
"travelTime": 44,
"length": 40,
"id": "M9",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9065011,
"longitude": -87.9282939
},
"instruction": "Turn <span class=\"direction\">left</span> onto <span class=\"next-street\">E North Ave</span>. <span class=\"distance-description\">Go for <span class=\"length\">49 m</span>.</span>",
"travelTime": 56,
"length": 49,
"id": "M10",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9065225,
"longitude": -87.9277039
},
"instruction": "Turn <span class=\"direction\">slightly right</span>. <span class=\"distance-description\">Go for <span class=\"length\">409 m</span>.</span>",
"travelTime": 419,
"length": 409,
"id": "M11",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9040334,
"longitude": -87.9260409
},
"instruction": "Turn <span class=\"direction\">left</span> onto <span class=\"next-street\">E Third St</span>. <span class=\"distance-description\">Go for <span class=\"length\">206 m</span>.</span>",
"travelTime": 206,
"length": 206,
"id": "M12",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9038832,
"longitude": -87.9236054
},
"instruction": "Turn <span class=\"direction\">left</span>. <span class=\"distance-description\">Go for <span class=\"length\">113 m</span>.</span>",
"travelTime": 113,
"length": 113,
"id": "M13",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9039047,
"longitude": -87.9222536
},
"instruction": "Turn <span class=\"direction\">left</span>. <span class=\"distance-description\">Go for <span class=\"length\">26 m</span>.</span>",
"travelTime": 26,
"length": 26,
"id": "M14",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.90413,
"longitude": -87.9223502
},
"instruction": "Arrive at your destination on the right.",
"travelTime": 0,
"length": 0,
"id": "M15",
"_type": "PrivateTransportManeuverType"
}
]
}
],
"publicTransportLine": [
{
"lineName": "330",
"companyName": "PACE",
"destination": "Archer/Harlem (Terminal)",
"type": "busPublic",
"id": "L1"
},
{
"lineName": "309",
"companyName": "PACE",
"destination": "Elmhurst Metra Station",
"type": "busPublic",
"id": "L2"
}
],
"summary": {
"distance": 14775,
"baseTime": 4784,
"flags": [
"noThroughRoad",
"builtUpArea",
"park"
],
"text": "The trip takes <span class=\"length\">14.8 km</span> and <span class=\"time\">1:20 h</span>.",
"travelTime": 4784,
"departure": "2019-08-06T05:09:20-05:00",
"timetableExpiration": "2019-08-04T00:00:00Z",
"_type": "PublicTransportRouteSummaryType"
}
}
],
"language": "en-us"
}
}

View File

@ -0,0 +1,15 @@
{
"_type": "ns2:RoutingServiceErrorType",
"type": "PermissionError",
"subtype": "InvalidCredentials",
"details": "This is not a valid app_id and app_code pair. Please verify that the values are not swapped between the app_id and app_code and the values provisioned by HERE (either by your customer representative or via http://developer.here.com/myapps) were copied correctly into the request.",
"metaInfo": {
"timestamp": "2019-07-10T09:43:14Z",
"mapVersion": "8.30.98.152",
"moduleVersion": "7.2.201927-4307",
"interfaceVersion": "2.6.64",
"availableMapVersion": [
"8.30.98.152"
]
}
}

View File

@ -0,0 +1,21 @@
{
"_type": "ns2:RoutingServiceErrorType",
"type": "ApplicationError",
"subtype": "NoRouteFound",
"details": "Error is NGEO_ERROR_ROUTE_NO_END_POINT",
"additionalData": [
{
"key": "error_code",
"value": "NGEO_ERROR_ROUTE_NO_END_POINT"
}
],
"metaInfo": {
"timestamp": "2019-07-10T09:51:04Z",
"mapVersion": "8.30.98.152",
"moduleVersion": "7.2.201927-4307",
"interfaceVersion": "2.6.64",
"availableMapVersion": [
"8.30.98.152"
]
}
}

View File

@ -0,0 +1,187 @@
{
"response": {
"metaInfo": {
"timestamp": "2019-07-21T14:25:00Z",
"mapVersion": "8.30.98.154",
"moduleVersion": "7.2.201928-4478",
"interfaceVersion": "2.6.64",
"availableMapVersion": [
"8.30.98.154"
]
},
"route": [
{
"waypoint": [
{
"linkId": "+930461269",
"mappedPosition": {
"latitude": 41.9800687,
"longitude": -87.8805614
},
"originalPosition": {
"latitude": 41.9798,
"longitude": -87.8801
},
"type": "stopOver",
"spot": 0.5555556,
"sideOfStreet": "right",
"mappedRoadName": "",
"label": "",
"shapeIndex": 0,
"source": "user"
},
{
"linkId": "-1035319462",
"mappedPosition": {
"latitude": 41.9042909,
"longitude": -87.9216528
},
"originalPosition": {
"latitude": 41.9043,
"longitude": -87.9216001
},
"type": "stopOver",
"spot": 0,
"sideOfStreet": "left",
"mappedRoadName": "Eisenhower Expy E",
"label": "Eisenhower Expy E - I-290",
"shapeIndex": 135,
"source": "user"
}
],
"mode": {
"type": "fastest",
"transportModes": [
"truck"
],
"trafficMode": "disabled",
"feature": []
},
"leg": [
{
"start": {
"linkId": "+930461269",
"mappedPosition": {
"latitude": 41.9800687,
"longitude": -87.8805614
},
"originalPosition": {
"latitude": 41.9798,
"longitude": -87.8801
},
"type": "stopOver",
"spot": 0.5555556,
"sideOfStreet": "right",
"mappedRoadName": "",
"label": "",
"shapeIndex": 0,
"source": "user"
},
"end": {
"linkId": "-1035319462",
"mappedPosition": {
"latitude": 41.9042909,
"longitude": -87.9216528
},
"originalPosition": {
"latitude": 41.9043,
"longitude": -87.9216001
},
"type": "stopOver",
"spot": 0,
"sideOfStreet": "left",
"mappedRoadName": "Eisenhower Expy E",
"label": "Eisenhower Expy E - I-290",
"shapeIndex": 135,
"source": "user"
},
"length": 13049,
"travelTime": 812,
"maneuver": [
{
"position": {
"latitude": 41.9800687,
"longitude": -87.8805614
},
"instruction": "Take ramp onto <span class=\"number\">I-190</span>. <span class=\"distance-description\">Go for <span class=\"length\">631 m</span>.</span>",
"travelTime": 53,
"length": 631,
"id": "M1",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.98259,
"longitude": -87.8744352
},
"instruction": "Take exit <span class=\"exit\">1D</span> toward <span class=\"sign\"><span lang=\"en\">Indiana</span></span> onto <span class=\"number\">I-294 S</span> <span class=\"next-street\">(Tri-State Tollway)</span>. <span class=\"distance-description\">Go for <span class=\"length\">10.9 km</span>.</span>",
"travelTime": 573,
"length": 10872,
"id": "M2",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9059324,
"longitude": -87.9199362
},
"instruction": "Take exit <span class=\"exit\">33</span> toward <span class=\"sign\"><span lang=\"en\">Rockford</span>/<span lang=\"en\">US-20</span>/<span lang=\"en\">IL-64</span></span> onto <span class=\"number\">I-290 W</span> <span class=\"next-street\">(Eisenhower Expy W)</span>. <span class=\"distance-description\">Go for <span class=\"length\">475 m</span>.</span>",
"travelTime": 54,
"length": 475,
"id": "M3",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9067156,
"longitude": -87.9237771
},
"instruction": "Take exit <span class=\"exit\">13B</span> toward <span class=\"sign\"><span lang=\"en\">North Ave</span></span> onto <span class=\"number\">IL-64 W</span> <span class=\"next-street\">(E North Ave)</span>. <span class=\"distance-description\">Go for <span class=\"length\">435 m</span>.</span>",
"travelTime": 51,
"length": 435,
"id": "M4",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9065869,
"longitude": -87.9249573
},
"instruction": "Take ramp onto <span class=\"number\">I-290 E</span> <span class=\"next-street\">(Eisenhower Expy E)</span> toward <span class=\"sign\"><span lang=\"en\">Chicago</span>/<span lang=\"en\">I-294 S</span></span>. <span class=\"distance-description\">Go for <span class=\"length\">636 m</span>.</span>",
"travelTime": 81,
"length": 636,
"id": "M5",
"_type": "PrivateTransportManeuverType"
},
{
"position": {
"latitude": 41.9042909,
"longitude": -87.9216528
},
"instruction": "Arrive at <span class=\"street\">Eisenhower Expy E</span> <span class=\"number\">(I-290)</span>. Your destination is on the left.",
"travelTime": 0,
"length": 0,
"id": "M6",
"_type": "PrivateTransportManeuverType"
}
]
}
],
"summary": {
"distance": 13049,
"trafficTime": 812,
"baseTime": 812,
"flags": [
"tollroad",
"motorway",
"builtUpArea"
],
"text": "The trip takes <span class=\"length\">13.0 km</span> and <span class=\"time\">14 mins</span>.",
"travelTime": 812,
"_type": "RouteSummaryType"
}
}
],
"language": "en-us"
}
}