From 0b9699fd4b43ba24f93dfb40912b4a0452721a62 Mon Sep 17 00:00:00 2001 From: Robbie Trencheny Date: Thu, 24 Mar 2016 19:48:10 -0700 Subject: [PATCH 1/5] Uber sensor --- homeassistant/components/sensor/uber.py | 176 ++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 homeassistant/components/sensor/uber.py diff --git a/homeassistant/components/sensor/uber.py b/homeassistant/components/sensor/uber.py new file mode 100644 index 00000000000..128a36b9dd8 --- /dev/null +++ b/homeassistant/components/sensor/uber.py @@ -0,0 +1,176 @@ +""" +Support for the Uber API. +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/sensor.uber/ +""" +import logging +from datetime import timedelta + +from homeassistant.helpers.entity import Entity +from homeassistant.util import Throttle + +_LOGGER = logging.getLogger(__name__) +REQUIREMENTS = ['https://github.com/denismakogon/rides-python-sdk/archive/' + 'master.zip#' + 'uber_rides==0.1.2-dev'] + +ICON = 'mdi:taxi' + +# Return cached results if last scan was less then this time ago. +MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=30) + +def setup_platform(hass, config, add_devices, discovery_info=None): + """Get the Uber sensor.""" + + if None in (config.get('start_latitude'), config.get('start_longitude')): + _LOGGER.error("You must set start latitude and longitude to use the Uber sensor!") + return False + + if config.get('server_token') is None: + _LOGGER.error("You must set a server_token to use the Uber sensor!") + return False + + from uber_rides.session import Session + + session = Session(server_token=config.get('server_token')) + + wanted_product_ids = config.get('product_ids') + + dev = [] + timeandpriceest = UberEstimate(session, config.get('start_latitude'), config.get('start_longitude'), config.get('end_latitude'), config.get('end_longitude')) + for product_id, product in timeandpriceest.products.items(): + if wanted_product_ids is not None and product_id in wanted_product_ids: + dev.append(UberSensor('time', timeandpriceest, product_id, product)) + dev.append(UberSensor('price', timeandpriceest, product_id, product)) + elif wanted_product_ids is None: + dev.append(UberSensor('time', timeandpriceest, product_id, product)) + dev.append(UberSensor('price', timeandpriceest, product_id, product)) + add_devices(dev) + +# pylint: disable=too-few-public-methods +class UberSensor(Entity): + """Implementation of an Uber Time sensor.""" + + def __init__(self, sensorType, products, product_id, product): + """Initialize the sensor.""" + self.data = products + self._product_id = product_id + self._product = product + self._sensortype = sensorType + self._name = self._product.get('display_name') + " " +self._sensortype + if self._sensortype == "time": + self._unit_of_measurement = "min" + self._state = int(self._product.get('time_estimate_seconds', 0) / 60) + elif self._sensortype == "price": + if self._product.get('price_details').get('low_estimate') is None: + self._unit_of_measurement = self._product.get('price_details').get('currency_code') + self._state = int(self._product.get('price_details').get('minimum')) + else: + self._unit_of_measurement = self._product.get('price_details').get('currency_code') + self._state = int(self._product.get('price_details').get('low_estimate')) + self.update() + + @property + def name(self): + """Return the name of the sensor.""" + return self._name + + @property + def state(self): + """Return the state of the sensor.""" + return self._state + + @property + def unit_of_measurement(self): + """Return the unit of measurement of this entity, if any.""" + return self._unit_of_measurement + + @property + def device_state_attributes(self): + """Return the state attributes.""" + distance_key = 'Trip distance (in '+self._product.get('price_details').get('distance_unit')+'s)' + distance_val = self._product.get('distance') + if self._product.get('price_details').get('distance_unit') is None or self._product.get('distance') is None: + distance_key = 'Trip distance' + distance_val = 'N/A' + return { + 'Product ID': self._product.get('product_id'), + 'Product short description': self._product.get('short_description'), + 'Product display name': self._product.get('display_name'), + 'Product description': self._product.get('description'), + 'Pickup time estimate (in seconds)': self._product.get('time_estimate_seconds'), + 'Trip duration (in seconds)': self._product.get('duration', 'N/A'), + distance_key: distance_val, + 'Vehicle Capacity': self._product.get('capacity'), + 'Minimum price': self._product.get('price_details').get('minimum'), + 'Cost per minute': self._product.get('price_details').get('cost_per_minute'), + 'Distance units': self._product.get('price_details').get('distance_unit'), + 'Cancellation fee': self._product.get('price_details').get('cancellation_fee'), + 'Cost per distance unit': self._product.get('price_details').get('cost_per_distance'), + 'Base price': self._product.get('price_details').get('base'), + 'Price estimate': self._product.get('price_details').get('estimate', 'N/A'), + 'Price currency code': self._product.get('price_details').get('currency_code'), + 'High price estimate': self._product.get('price_details').get('high_estimate', 'N/A'), + 'Low price estimate': self._product.get('price_details').get('low_estimate', 'N/A'), + 'Surge multiplier': self._product.get('price_details').get('surge_multiplier', 'N/A') + } + + @property + def icon(self): + """Icon to use in the frontend, if any.""" + return ICON + + # pylint: disable=too-many-branches + def update(self): + """Get the latest data from the Uber API and update the states.""" + self.data.update() + self._product = self.data.products[self._product_id] + +# pylint: disable=too-few-public-methods +class UberEstimate(object): + """The Class for handling the data retrieval.""" + + def __init__(self, session, start_latitude, start_longitude, end_latitude=None, end_longitude=None): + """Initialize the data object.""" + self._session = session + self.start_latitude = start_latitude + self.start_longitude = start_longitude + self.end_latitude = end_latitude + self.end_longitude = end_longitude + self.products = None + self.update() + + @Throttle(MIN_TIME_BETWEEN_UPDATES) + def update(self): + """Get the latest estimates from the Uber API.""" + from uber_rides.client import UberRidesClient + client = UberRidesClient(self._session) + + self.products = {} + + productsResp = client.get_products(self.start_latitude, self.start_longitude) + + products = productsResp.json.get('products') + + for product in products: + self.products[product.get('product_id')] = product + + if self.end_latitude is not None and self.end_longitude is not None: + priceResp = client.get_price_estimates(self.start_latitude, self.start_longitude, self.end_latitude, self.end_longitude) + + prices = priceResp.json.get('prices') + + for price in prices: + self.products[price.get('product_id')]["duration"] = price.get('duration') + self.products[price.get('product_id')]["distance"] = price.get('distance') + self.products[price.get('product_id')]["price_details"]["estimate"] = price.get('estimate') + self.products[price.get('product_id')]["price_details"]["high_estimate"] = price.get('high_estimate') + self.products[price.get('product_id')]["price_details"]["low_estimate"] = price.get('low_estimate') + self.products[price.get('product_id')]["price_details"]["surge_multiplier"] = price.get('surge_multiplier') + + estimateResp = client.get_pickup_time_estimates(self.start_latitude, self.start_longitude) + + estimates = estimateResp.json.get('times') + + for estimate in estimates: + self.products[estimate.get('product_id')]["time_estimate_seconds"] = estimate.get('estimate') From 5b18ea42370aaa301d5aefea3df355534421fb5f Mon Sep 17 00:00:00 2001 From: Robbie Trencheny Date: Thu, 24 Mar 2016 22:30:10 -0700 Subject: [PATCH 2/5] Fix all pylint, flake8 and pydocstyle issues --- homeassistant/components/sensor/uber.py | 199 ++++++++++++++++-------- 1 file changed, 135 insertions(+), 64 deletions(-) diff --git a/homeassistant/components/sensor/uber.py b/homeassistant/components/sensor/uber.py index 128a36b9dd8..1bde91ad840 100644 --- a/homeassistant/components/sensor/uber.py +++ b/homeassistant/components/sensor/uber.py @@ -1,5 +1,6 @@ """ Support for the Uber API. + For more details about this platform, please refer to the documentation at https://home-assistant.io/components/sensor.uber/ """ @@ -11,7 +12,7 @@ from homeassistant.util import Throttle _LOGGER = logging.getLogger(__name__) REQUIREMENTS = ['https://github.com/denismakogon/rides-python-sdk/archive/' - 'master.zip#' + 'py3-support.zip#' 'uber_rides==0.1.2-dev'] ICON = 'mdi:taxi' @@ -19,11 +20,13 @@ ICON = 'mdi:taxi' # Return cached results if last scan was less then this time ago. MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=30) -def setup_platform(hass, config, add_devices, discovery_info=None): - """Get the Uber sensor.""" +def setup_platform(hass, config, add_devices, discovery_info=None): + """Set up the Uber sensor.""" if None in (config.get('start_latitude'), config.get('start_longitude')): - _LOGGER.error("You must set start latitude and longitude to use the Uber sensor!") + _LOGGER.error( + "You must set start latitude and longitude to use the Uber sensor!" + ) return False if config.get('server_token') is None: @@ -37,37 +40,64 @@ def setup_platform(hass, config, add_devices, discovery_info=None): wanted_product_ids = config.get('product_ids') dev = [] - timeandpriceest = UberEstimate(session, config.get('start_latitude'), config.get('start_longitude'), config.get('end_latitude'), config.get('end_longitude')) + start_lat_long = LatLong(config.get('start_latitude'), + config.get('start_longitude')) + end_lat_long = LatLong(config.get('end_latitude'), + config.get('end_longitude')) + timeandpriceest = UberEstimate(session, start_lat_long, end_lat_long) for product_id, product in timeandpriceest.products.items(): if wanted_product_ids is not None and product_id in wanted_product_ids: - dev.append(UberSensor('time', timeandpriceest, product_id, product)) - dev.append(UberSensor('price', timeandpriceest, product_id, product)) + dev.append(UberSensor('time', + timeandpriceest, + product_id, product)) + dev.append(UberSensor('price', + timeandpriceest, + product_id, product)) elif wanted_product_ids is None: - dev.append(UberSensor('time', timeandpriceest, product_id, product)) - dev.append(UberSensor('price', timeandpriceest, product_id, product)) + dev.append(UberSensor('time', + timeandpriceest, + product_id, + product)) + dev.append(UberSensor('price', + timeandpriceest, + product_id, + product)) add_devices(dev) + # pylint: disable=too-few-public-methods class UberSensor(Entity): - """Implementation of an Uber Time sensor.""" + """Implementation of an Uber sensor.""" def __init__(self, sensorType, products, product_id, product): - """Initialize the sensor.""" + """Initialize the Uber sensor.""" self.data = products self._product_id = product_id self._product = product self._sensortype = sensorType - self._name = self._product.get('display_name') + " " +self._sensortype + self._name = self._product.get('display_name') + " " + self._sensortype if self._sensortype == "time": - self._unit_of_measurement = "min" - self._state = int(self._product.get('time_estimate_seconds', 0) / 60) + self._unit_of_measurement = "min" + self._state = int(self._product.get( + 'time_estimate_seconds', 0 + ) / 60) elif self._sensortype == "price": - if self._product.get('price_details').get('low_estimate') is None: - self._unit_of_measurement = self._product.get('price_details').get('currency_code') - self._state = int(self._product.get('price_details').get('minimum')) - else: - self._unit_of_measurement = self._product.get('price_details').get('currency_code') - self._state = int(self._product.get('price_details').get('low_estimate')) + if self._product.get('price_details').get('low_estimate') is None: + self._unit_of_measurement = self._product.get( + 'price_details' + ).get( + 'currency_code' + ) + self._state = int(self._product.get( + 'price_details' + ).get( + 'minimum' + )) + else: + self._unit_of_measurement = self._product.get( + 'price_details').get('currency_code') + self._state = int( + self._product.get('price_details').get('low_estimate')) self.update() @property @@ -88,31 +118,49 @@ class UberSensor(Entity): @property def device_state_attributes(self): """Return the state attributes.""" - distance_key = 'Trip distance (in '+self._product.get('price_details').get('distance_unit')+'s)' + distance_key = 'Trip distance (in '+self._product.get( + 'price_details').get('distance_unit')+'s)' distance_val = self._product.get('distance') - if self._product.get('price_details').get('distance_unit') is None or self._product.get('distance') is None: - distance_key = 'Trip distance' - distance_val = 'N/A' + if self._product.get( + 'price_details' + ).get( + 'distance_unit' + ) is None or self._product.get( + 'distance' + ) is None: + distance_key = 'Trip distance' + distance_val = 'N/A' return { - 'Product ID': self._product.get('product_id'), - 'Product short description': self._product.get('short_description'), - 'Product display name': self._product.get('display_name'), - 'Product description': self._product.get('description'), - 'Pickup time estimate (in seconds)': self._product.get('time_estimate_seconds'), - 'Trip duration (in seconds)': self._product.get('duration', 'N/A'), - distance_key: distance_val, - 'Vehicle Capacity': self._product.get('capacity'), - 'Minimum price': self._product.get('price_details').get('minimum'), - 'Cost per minute': self._product.get('price_details').get('cost_per_minute'), - 'Distance units': self._product.get('price_details').get('distance_unit'), - 'Cancellation fee': self._product.get('price_details').get('cancellation_fee'), - 'Cost per distance unit': self._product.get('price_details').get('cost_per_distance'), - 'Base price': self._product.get('price_details').get('base'), - 'Price estimate': self._product.get('price_details').get('estimate', 'N/A'), - 'Price currency code': self._product.get('price_details').get('currency_code'), - 'High price estimate': self._product.get('price_details').get('high_estimate', 'N/A'), - 'Low price estimate': self._product.get('price_details').get('low_estimate', 'N/A'), - 'Surge multiplier': self._product.get('price_details').get('surge_multiplier', 'N/A') + 'Product ID': self._product.get('product_id'), + 'Product short description': self._product.get( + 'short_description'), + 'Product display name': self._product.get('display_name'), + 'Product description': self._product.get('description'), + 'Pickup time estimate (in seconds)': + self._product.get('time_estimate_seconds'), + 'Trip duration (in seconds)': self._product.get('duration', 'N/A'), + distance_key: distance_val, + 'Vehicle Capacity': self._product.get('capacity'), + 'Minimum price': self._product.get('price_details').get('minimum'), + 'Cost per minute': self._product.get( + 'price_details').get('cost_per_minute'), + 'Distance units': self._product.get( + 'price_details').get('distance_unit'), + 'Cancellation fee': self._product.get( + 'price_details').get('cancellation_fee'), + 'Cost per distance unit': self._product.get( + 'price_details').get('cost_per_distance'), + 'Base price': self._product.get('price_details').get('base'), + 'Price estimate': self._product.get( + 'price_details').get('estimate', 'N/A'), + 'Price currency code': self._product.get( + 'price_details').get('currency_code'), + 'High price estimate': self._product.get( + 'price_details').get('high_estimate', 'N/A'), + 'Low price estimate': self._product.get( + 'price_details').get('low_estimate', 'N/A'), + 'Surge multiplier': self._product.get( + 'price_details').get('surge_multiplier', 'N/A') } @property @@ -126,51 +174,74 @@ class UberSensor(Entity): self.data.update() self._product = self.data.products[self._product_id] + +class LatLong(object): + """A container for a latitude and longitude pair.""" + + def __init__(self, latitude, longitude): + """Initialize the LatLong object.""" + self.latitude = latitude + self.longitude = longitude + + # pylint: disable=too-few-public-methods class UberEstimate(object): - """The Class for handling the data retrieval.""" + """The class for handling the time and price estimate.""" - def __init__(self, session, start_latitude, start_longitude, end_latitude=None, end_longitude=None): - """Initialize the data object.""" + def __init__(self, session, start_latlong, end_latlong=None): + """Initialize the UberEstimate object.""" self._session = session - self.start_latitude = start_latitude - self.start_longitude = start_longitude - self.end_latitude = end_latitude - self.end_longitude = end_longitude + self.start_latitude = start_latlong.latitude + self.start_longitude = start_latlong.longitude + self.end_latitude = end_latlong.latitude + self.end_longitude = end_latlong.longitude self.products = None self.update() @Throttle(MIN_TIME_BETWEEN_UPDATES) def update(self): - """Get the latest estimates from the Uber API.""" + """Get the latest product info and estimates from the Uber API.""" from uber_rides.client import UberRidesClient client = UberRidesClient(self._session) self.products = {} - productsResp = client.get_products(self.start_latitude, self.start_longitude) + products_response = client.get_products( + self.start_latitude, self.start_longitude) - products = productsResp.json.get('products') + products = products_response.json.get('products') for product in products: self.products[product.get('product_id')] = product if self.end_latitude is not None and self.end_longitude is not None: - priceResp = client.get_price_estimates(self.start_latitude, self.start_longitude, self.end_latitude, self.end_longitude) + price_response = client.get_price_estimates( + self.start_latitude, + self.start_longitude, + self.end_latitude, + self.end_longitude) - prices = priceResp.json.get('prices') + prices = price_response.json.get('prices') for price in prices: - self.products[price.get('product_id')]["duration"] = price.get('duration') - self.products[price.get('product_id')]["distance"] = price.get('distance') - self.products[price.get('product_id')]["price_details"]["estimate"] = price.get('estimate') - self.products[price.get('product_id')]["price_details"]["high_estimate"] = price.get('high_estimate') - self.products[price.get('product_id')]["price_details"]["low_estimate"] = price.get('low_estimate') - self.products[price.get('product_id')]["price_details"]["surge_multiplier"] = price.get('surge_multiplier') + self.products[price.get('product_id')][ + "duration"] = price.get('duration') + self.products[price.get('product_id')][ + "distance"] = price.get('distance') + self.products[price.get('product_id')]["price_details"][ + "estimate"] = price.get('estimate') + self.products[price.get('product_id')]["price_details"][ + "high_estimate"] = price.get('high_estimate') + self.products[price.get('product_id')]["price_details"][ + "low_estimate"] = price.get('low_estimate') + self.products[price.get('product_id')]["price_details"][ + "surge_multiplier"] = price.get('surge_multiplier') - estimateResp = client.get_pickup_time_estimates(self.start_latitude, self.start_longitude) + estimate_response = client.get_pickup_time_estimates( + self.start_latitude, self.start_longitude) - estimates = estimateResp.json.get('times') + estimates = estimate_response.json.get('times') for estimate in estimates: - self.products[estimate.get('product_id')]["time_estimate_seconds"] = estimate.get('estimate') + self.products[estimate.get('product_id')][ + "time_estimate_seconds"] = estimate.get('estimate') From 01b216f6cbbe19c74a7ebaeb398e63b80b202f96 Mon Sep 17 00:00:00 2001 From: Robbie Trencheny Date: Thu, 24 Mar 2016 22:30:22 -0700 Subject: [PATCH 3/5] Block uber.py tests --- .coveragerc | 1 + 1 file changed, 1 insertion(+) diff --git a/.coveragerc b/.coveragerc index fa1eb376906..b1d30be172f 100644 --- a/.coveragerc +++ b/.coveragerc @@ -149,6 +149,7 @@ omit = homeassistant/components/sensor/torque.py homeassistant/components/sensor/transmission.py homeassistant/components/sensor/twitch.py + homeassistant/components/sensor/uber.py homeassistant/components/sensor/worldclock.py homeassistant/components/switch/arest.py homeassistant/components/switch/dlink.py From 72c40ab826821629c428cbb596062b7c181ab312 Mon Sep 17 00:00:00 2001 From: Robbie Trencheny Date: Thu, 24 Mar 2016 22:30:42 -0700 Subject: [PATCH 4/5] Add Uber requirements to requirements_all.txt --- requirements_all.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/requirements_all.txt b/requirements_all.txt index 397cf7cabbf..6a940d6618d 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -78,6 +78,9 @@ https://github.com/Xorso/pyalarmdotcom/archive/0.1.1.zip#pyalarmdotcom==0.1.1 # homeassistant.components.modbus https://github.com/bashwork/pymodbus/archive/d7fc4f1cc975631e0a9011390e8017f64b612661.zip#pymodbus==1.2.0 +# homeassistant.components.sensor.uber +https://github.com/denismakogon/rides-python-sdk/archive/py3-support.zip#uber_rides==0.1.2-dev + # homeassistant.components.sensor.sabnzbd https://github.com/jamespcole/home-assistant-nzb-clients/archive/616cad59154092599278661af17e2a9f2cf5e2a9.zip#python-sabnzbd==0.1 From 20f8935b86dc732ad8c74d36a67752a64730e3b5 Mon Sep 17 00:00:00 2001 From: Robbie Trencheny Date: Fri, 25 Mar 2016 19:32:49 -0700 Subject: [PATCH 5/5] Clean up a lot of pep8 and syntax errors. --- homeassistant/components/sensor/uber.py | 175 +++++++++--------------- 1 file changed, 68 insertions(+), 107 deletions(-) diff --git a/homeassistant/components/sensor/uber.py b/homeassistant/components/sensor/uber.py index 1bde91ad840..8c3a7d01e0e 100644 --- a/homeassistant/components/sensor/uber.py +++ b/homeassistant/components/sensor/uber.py @@ -18,7 +18,7 @@ REQUIREMENTS = ['https://github.com/denismakogon/rides-python-sdk/archive/' ICON = 'mdi:taxi' # Return cached results if last scan was less then this time ago. -MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=30) +MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=60) def setup_platform(hass, config, add_devices, discovery_info=None): @@ -40,28 +40,16 @@ def setup_platform(hass, config, add_devices, discovery_info=None): wanted_product_ids = config.get('product_ids') dev = [] - start_lat_long = LatLong(config.get('start_latitude'), - config.get('start_longitude')) - end_lat_long = LatLong(config.get('end_latitude'), - config.get('end_longitude')) - timeandpriceest = UberEstimate(session, start_lat_long, end_lat_long) + timeandpriceest = UberEstimate(session, config['start_latitude'], + config['start_longitude'], + config.get('end_latitude'), + config.get('end_longitude')) for product_id, product in timeandpriceest.products.items(): - if wanted_product_ids is not None and product_id in wanted_product_ids: - dev.append(UberSensor('time', - timeandpriceest, - product_id, product)) - dev.append(UberSensor('price', - timeandpriceest, - product_id, product)) - elif wanted_product_ids is None: - dev.append(UberSensor('time', - timeandpriceest, - product_id, - product)) - dev.append(UberSensor('price', - timeandpriceest, - product_id, - product)) + if (wanted_product_ids is not None) and \ + (product_id not in wanted_product_ids): + continue + dev.append(UberSensor('time', timeandpriceest, product_id, product)) + dev.append(UberSensor('price', timeandpriceest, product_id, product)) add_devices(dev) @@ -75,29 +63,20 @@ class UberSensor(Entity): self._product_id = product_id self._product = product self._sensortype = sensorType - self._name = self._product.get('display_name') + " " + self._sensortype + self._name = "{} {}".format(self._product['display_name'], + self._sensortype) if self._sensortype == "time": self._unit_of_measurement = "min" - self._state = int(self._product.get( - 'time_estimate_seconds', 0 - ) / 60) + time_estimate = self._product.get('time_estimate_seconds', 0) + self._state = int(time_estimate / 60) elif self._sensortype == "price": - if self._product.get('price_details').get('low_estimate') is None: - self._unit_of_measurement = self._product.get( - 'price_details' - ).get( - 'currency_code' - ) - self._state = int(self._product.get( - 'price_details' - ).get( - 'minimum' - )) + price_details = self._product['price_details'] + if price_details['low_estimate'] is None: + self._unit_of_measurement = price_details['currency_code'] + self._state = int(price_details['minimum']) else: - self._unit_of_measurement = self._product.get( - 'price_details').get('currency_code') - self._state = int( - self._product.get('price_details').get('low_estimate')) + self._unit_of_measurement = price_details['currency_code'] + self._state = int(price_details['low_estimate']) self.update() @property @@ -118,49 +97,35 @@ class UberSensor(Entity): @property def device_state_attributes(self): """Return the state attributes.""" - distance_key = 'Trip distance (in '+self._product.get( - 'price_details').get('distance_unit')+'s)' + price_details = self._product['price_details'] + distance_key = 'Trip distance (in {}s)'.format(price_details[ + 'distance_unit']) distance_val = self._product.get('distance') - if self._product.get( - 'price_details' - ).get( - 'distance_unit' - ) is None or self._product.get( - 'distance' - ) is None: + if (price_details.get('distance_unit') is None) or \ + (self._product.get('distance') is None): distance_key = 'Trip distance' distance_val = 'N/A' + time_estimate = self._product['time_estimate_seconds'] return { - 'Product ID': self._product.get('product_id'), - 'Product short description': self._product.get( - 'short_description'), - 'Product display name': self._product.get('display_name'), - 'Product description': self._product.get('description'), - 'Pickup time estimate (in seconds)': - self._product.get('time_estimate_seconds'), + 'Product ID': self._product['product_id'], + 'Product short description': self._product['short_description'], + 'Product display name': self._product['display_name'], + 'Product description': self._product['description'], + 'Pickup time estimate (in seconds)': time_estimate, 'Trip duration (in seconds)': self._product.get('duration', 'N/A'), distance_key: distance_val, - 'Vehicle Capacity': self._product.get('capacity'), - 'Minimum price': self._product.get('price_details').get('minimum'), - 'Cost per minute': self._product.get( - 'price_details').get('cost_per_minute'), - 'Distance units': self._product.get( - 'price_details').get('distance_unit'), - 'Cancellation fee': self._product.get( - 'price_details').get('cancellation_fee'), - 'Cost per distance unit': self._product.get( - 'price_details').get('cost_per_distance'), - 'Base price': self._product.get('price_details').get('base'), - 'Price estimate': self._product.get( - 'price_details').get('estimate', 'N/A'), - 'Price currency code': self._product.get( - 'price_details').get('currency_code'), - 'High price estimate': self._product.get( - 'price_details').get('high_estimate', 'N/A'), - 'Low price estimate': self._product.get( - 'price_details').get('low_estimate', 'N/A'), - 'Surge multiplier': self._product.get( - 'price_details').get('surge_multiplier', 'N/A') + 'Vehicle Capacity': self._product['capacity'], + 'Minimum price': price_details['minimum'], + 'Cost per minute': price_details['cost_per_minute'], + 'Distance units': price_details['distance_unit'], + 'Cancellation fee': price_details['cancellation_fee'], + 'Cost per distance unit': price_details['cost_per_distance'], + 'Base price': price_details['base'], + 'Price estimate': price_details.get('estimate', 'N/A'), + 'Price currency code': price_details.get('currency_code'), + 'High price estimate': price_details.get('high_estimate', 'N/A'), + 'Low price estimate': price_details.get('low_estimate', 'N/A'), + 'Surge multiplier': price_details.get('surge_multiplier', 'N/A') } @property @@ -173,28 +138,28 @@ class UberSensor(Entity): """Get the latest data from the Uber API and update the states.""" self.data.update() self._product = self.data.products[self._product_id] - - -class LatLong(object): - """A container for a latitude and longitude pair.""" - - def __init__(self, latitude, longitude): - """Initialize the LatLong object.""" - self.latitude = latitude - self.longitude = longitude + if self._sensortype == "time": + time_estimate = self._product.get('time_estimate_seconds', 0) + self._state = int(time_estimate / 60) + elif self._sensortype == "price": + price_details = self._product['price_details'] + min_price = price_details['minimum'] + self._state = int(price_details.get('low_estimate', min_price)) # pylint: disable=too-few-public-methods class UberEstimate(object): """The class for handling the time and price estimate.""" - def __init__(self, session, start_latlong, end_latlong=None): + # pylint: disable=too-many-arguments + def __init__(self, session, start_latitude, start_longitude, + end_latitude=None, end_longitude=None): """Initialize the UberEstimate object.""" self._session = session - self.start_latitude = start_latlong.latitude - self.start_longitude = start_latlong.longitude - self.end_latitude = end_latlong.latitude - self.end_longitude = end_latlong.longitude + self.start_latitude = start_latitude + self.start_longitude = start_longitude + self.end_latitude = end_latitude + self.end_longitude = end_longitude self.products = None self.update() @@ -212,7 +177,7 @@ class UberEstimate(object): products = products_response.json.get('products') for product in products: - self.products[product.get('product_id')] = product + self.products[product['product_id']] = product if self.end_latitude is not None and self.end_longitude is not None: price_response = client.get_price_estimates( @@ -224,18 +189,14 @@ class UberEstimate(object): prices = price_response.json.get('prices') for price in prices: - self.products[price.get('product_id')][ - "duration"] = price.get('duration') - self.products[price.get('product_id')][ - "distance"] = price.get('distance') - self.products[price.get('product_id')]["price_details"][ - "estimate"] = price.get('estimate') - self.products[price.get('product_id')]["price_details"][ - "high_estimate"] = price.get('high_estimate') - self.products[price.get('product_id')]["price_details"][ - "low_estimate"] = price.get('low_estimate') - self.products[price.get('product_id')]["price_details"][ - "surge_multiplier"] = price.get('surge_multiplier') + product = self.products[price['product_id']] + price_details = product["price_details"] + product["duration"] = price['duration'] + product["distance"] = price['distance'] + price_details["estimate"] = price['estimate'] + price_details["high_estimate"] = price['high_estimate'] + price_details["low_estimate"] = price['low_estimate'] + price_details["surge_multiplier"] = price['surge_multiplier'] estimate_response = client.get_pickup_time_estimates( self.start_latitude, self.start_longitude) @@ -243,5 +204,5 @@ class UberEstimate(object): estimates = estimate_response.json.get('times') for estimate in estimates: - self.products[estimate.get('product_id')][ - "time_estimate_seconds"] = estimate.get('estimate') + self.products[estimate['product_id']][ + "time_estimate_seconds"] = estimate.get('estimate', '0')