-
-
Notifications
You must be signed in to change notification settings - Fork 32.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Dominos Pizza platform #10379
Add Dominos Pizza platform #10379
Changes from 35 commits
3bca66e
b4c34c2
6a3813b
4faf97d
64adc01
27d63a9
b536647
18bbbca
2793808
a1ba981
2b9749f
456a1c4
fe574e6
03ad3ac
646cebc
c5f70d2
fd90800
c59fe34
bd1f914
7838ceb
f0d70ae
a6c0ca6
cffcd13
53f4acc
33e6062
db75ffb
ca1a115
28542ae
3172f43
fc9808d
810a248
6c049cb
b9815f1
483934d
81f7d10
0c1c81e
c91b719
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,234 @@ | ||
""" | ||
Support for Dominos Pizza ordering. | ||
|
||
The Dominos Pizza component ceates a service which can be invoked to order | ||
from their menu | ||
|
||
For more details about this platform, please refer to the documentation at | ||
https://home-assistant.io/components/dominos/. | ||
""" | ||
import logging | ||
from datetime import timedelta | ||
|
||
import voluptuous as vol | ||
|
||
import homeassistant.helpers.config_validation as cv | ||
from homeassistant.components import http | ||
from homeassistant.core import callback | ||
from homeassistant.helpers.entity import Entity | ||
from homeassistant.helpers.entity_component import EntityComponent | ||
from homeassistant.util import Throttle | ||
|
||
_LOGGER = logging.getLogger(__name__) | ||
|
||
# The domain of your component. Should be equal to the name of your component. | ||
DOMAIN = 'dominos' | ||
ENTITY_ID_FORMAT = DOMAIN + '.{}' | ||
|
||
ATTR_COUNTRY = 'country_code' | ||
ATTR_FIRST_NAME = 'first_name' | ||
ATTR_LAST_NAME = 'last_name' | ||
ATTR_EMAIL = 'email' | ||
ATTR_PHONE = 'phone' | ||
ATTR_ADDRESS = 'address' | ||
ATTR_ORDERS = 'orders' | ||
ATTR_SHOW_MENU = 'show_menu' | ||
ATTR_ORDER_ENTITY = 'order_entity_id' | ||
ATTR_ORDER_NAME = 'name' | ||
ATTR_ORDER_CODES = 'codes' | ||
|
||
MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=10) | ||
MIN_TIME_BETWEEN_STORE_UPDATES = timedelta(minutes=3330) | ||
|
||
REQUIREMENTS = ['pizzapi==0.0.3'] | ||
|
||
DEPENDENCIES = ['http'] | ||
|
||
_ORDERS_SCHEMA = vol.Schema({ | ||
vol.Required(ATTR_ORDER_NAME): cv.string, | ||
vol.Required(ATTR_ORDER_CODES): vol.All(cv.ensure_list, [cv.string]), | ||
}) | ||
|
||
CONFIG_SCHEMA = vol.Schema({ | ||
DOMAIN: vol.Schema({ | ||
vol.Required(ATTR_COUNTRY): cv.string, | ||
vol.Required(ATTR_FIRST_NAME): cv.string, | ||
vol.Required(ATTR_LAST_NAME): cv.string, | ||
vol.Required(ATTR_EMAIL): cv.string, | ||
vol.Required(ATTR_PHONE): cv.string, | ||
vol.Required(ATTR_ADDRESS): cv.string, | ||
vol.Optional(ATTR_SHOW_MENU): cv.boolean, | ||
vol.Optional(ATTR_ORDERS): vol.All(cv.ensure_list, [_ORDERS_SCHEMA]), | ||
}), | ||
}, extra=vol.ALLOW_EXTRA) | ||
|
||
|
||
def setup(hass, config): | ||
"""Set up is called when Home Assistant is loading our component.""" | ||
dominos = Dominos(hass, config) | ||
|
||
component = EntityComponent(_LOGGER, DOMAIN, hass) | ||
hass.data[DOMAIN] = {} | ||
entities = [] | ||
|
||
hass.services.register(DOMAIN, 'order', dominos.handle_order) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add a schema for validating the service data. |
||
|
||
if config[DOMAIN].get(ATTR_SHOW_MENU): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You keep doing |
||
dominos.show_menu(hass) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do this on startup instead of when it is called? That is slowing down the startup of Home Assistant unnecessarily. |
||
hass.http.register_view(DominosProductListView) | ||
|
||
for order_info in config[DOMAIN].get(ATTR_ORDERS): | ||
order = DominosOrder(order_info, dominos) | ||
entities.append(order) | ||
|
||
component.add_entities(entities) | ||
|
||
# Return boolean to indicate that initialization was successfully. | ||
return True | ||
|
||
|
||
class Dominos(): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 |
||
"""Main Dominos service.""" | ||
|
||
def __init__(self, hass, config): | ||
"""Set up main service.""" | ||
from pizzapi import Address, Customer, Store | ||
self.hass = hass | ||
self.customer = Customer( | ||
config[DOMAIN].get(ATTR_FIRST_NAME), | ||
config[DOMAIN].get(ATTR_LAST_NAME), | ||
config[DOMAIN].get(ATTR_EMAIL), | ||
config[DOMAIN].get(ATTR_PHONE), | ||
config[DOMAIN].get(ATTR_ADDRESS)) | ||
self.address = Address( | ||
*self.customer.address.split(','), | ||
country=config[DOMAIN].get(ATTR_COUNTRY)) | ||
self.country = config[DOMAIN].get(ATTR_COUNTRY) | ||
self.closest_store = Store() | ||
self.update_closest_store() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't seem to be async, yet you're calling it from an async context. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why would you do this on startup? It's already done when the entities are updated |
||
|
||
def handle_order(self, call): | ||
"""Handle ordering pizza.""" | ||
entity_ids = call.data.get(ATTR_ORDER_ENTITY, None) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
target_orders = [order for order in self.hass.data[DOMAIN]['entities'] | ||
if order.entity_id in entity_ids] | ||
|
||
for order in target_orders: | ||
order.place() | ||
|
||
@Throttle(MIN_TIME_BETWEEN_STORE_UPDATES) | ||
def update_closest_store(self): | ||
"""Update the shared closest store (if open).""" | ||
from pizzapi.address import StoreException | ||
try: | ||
self.closest_store = self.address.closest_store() | ||
except StoreException: | ||
self.closest_store = False | ||
|
||
def show_menu(self, hass): | ||
"""Dump the closest stores menu into the logs.""" | ||
if self.closest_store is False: | ||
_LOGGER.warning('Cannot get menu. Store may be closed') | ||
return | ||
|
||
menu = self.closest_store.get_menu() | ||
hass.data[DOMAIN]['products'] = [] | ||
|
||
for product in menu.products: | ||
item = {} | ||
if isinstance(product.menu_data['Variants'], list): | ||
variants = ', '.join(product.menu_data['Variants']) | ||
else: | ||
variants = product.menu_data['Variants'] | ||
item['name'] = product.name | ||
item['variants'] = variants | ||
hass.data[DOMAIN]['products'].append(item) | ||
|
||
|
||
class DominosProductListView(http.HomeAssistantView): | ||
"""View to retrieve product list content.""" | ||
|
||
url = '/api/dominos' | ||
name = "api:dominos" | ||
|
||
@callback | ||
def get(self, request): | ||
"""Retrieve if API is running.""" | ||
return self.json(request.app['hass'].data[DOMAIN]['products']) | ||
|
||
|
||
class DominosOrder(Entity): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 |
||
"""Represents a Dominos order entity.""" | ||
|
||
def __init__(self, order_info, dominos): | ||
"""Set up the entity.""" | ||
self._name = order_info['name'] | ||
self._product_codes = order_info['codes'] | ||
self._orderable = False | ||
self.dominos = dominos | ||
|
||
@property | ||
def name(self): | ||
"""Return the orders name.""" | ||
return self._name | ||
|
||
@property | ||
def product_codes(self): | ||
"""Return the orders product codes.""" | ||
return self._product_codes | ||
|
||
@property | ||
def orderable(self): | ||
"""Return the true if orderable.""" | ||
return self._orderable | ||
|
||
@property | ||
def state(self): | ||
"""Return the state either closed, orderable or unorderable.""" | ||
if self.dominos.closest_store is False: | ||
return 'closed' | ||
else: | ||
return 'orderable' if self._orderable else 'unorderable' | ||
|
||
@Throttle(MIN_TIME_BETWEEN_UPDATES) | ||
def update(self): | ||
"""Update the order state and refreshes the store.""" | ||
from pizzapi.address import StoreException | ||
try: | ||
self.dominos.update_closest_store() | ||
except StoreException: | ||
self._orderable = False | ||
return | ||
|
||
try: | ||
order = self.order() | ||
order.pay_with() | ||
self._orderable = True | ||
except StoreException: | ||
self._orderable = False | ||
|
||
def order(self): | ||
"""Create the order object.""" | ||
from pizzapi import Order | ||
order = Order( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. undefined name 'Order' |
||
self.dominos.closest_store, | ||
self.dominos.customer, | ||
self.dominos.address, | ||
self.dominos.country) | ||
|
||
for code in self._product_codes: | ||
order.add_item(code) | ||
|
||
return order | ||
|
||
def place(self): | ||
"""Place the order.""" | ||
from pizzapi.address import StoreException | ||
try: | ||
order = self.order() | ||
order.place() | ||
except StoreException: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might want to create a persistent notification when this happens? |
||
self._orderable = False | ||
_LOGGER.warning( | ||
'Attempted to order Dominos - Order invalid or store closed') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'homeassistant.helpers.entity.Entity' imported but unused