Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
Nekmo committed Sep 23, 2018
2 parents f6d1830 + fb8c620 commit 9b3cdeb
Show file tree
Hide file tree
Showing 14 changed files with 166 additions and 13 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 1.2.0a1
current_version = 1.2.0
commit = True
tag = True

Expand Down
8 changes: 8 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@
History
=======

v1.3.0 (2018-09-23)
-------------------

- Pushbullet notifications
- Home Assistant ``access_token`` option
- Amazon-dash v2.0.0 disclaimer


v1.2.0 (2018-09-03)
-------------------

Expand Down
7 changes: 6 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ Also available on `AUR <https://aur.archlinux.org/packages/amazon-dash-git/>`_.
openhab: 192.168.1.140
item: open_door
state: "ON"
confirmation: send-pb
44:65:0D:75:A7:B2: # IFTTT example
name: Pompadour
ifttt: cdxxx-_gEJ3wdU04yyyzzz
Expand All @@ -104,6 +105,10 @@ Also available on `AUR <https://aur.archlinux.org/packages/amazon-dash-git/>`_.
token: '402642618:QwGDgiKE3LqdkNAtBkq0UEeBoDdpZYw8b4h'
to: 24291592
is_default: false
send-pb:
service: pushbullet
token: 'o.BbbPYjJizbPr2gSWgXGmqNTt6T9Rew51'
is_default: false
**UPGRADE** from `previous versions <http://docs.nekmo.org/amazon-dash/installation.html>`_
Expand All @@ -119,7 +124,7 @@ The following execution methods are supported with your Amazon Dash button with


Amazon-dash also allows you to **send a confirmation** after pressing a button. You will also receive a message in
case of failure. Currently only **Telegram** is supported.
case of failure. **Telegram** and **Pushbullet** are supported.


For more information see
Expand Down
Binary file modified amazon-dash.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion amazon_dash/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@

__version__ = '1.2.0a1'
__version__ = '1.2.0'
5 changes: 4 additions & 1 deletion amazon_dash/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,10 @@
"type": "object",
"properties": {
"service": {
"enum": ['telegram']
"enum": [
'telegram',
'pushbullet',
]
},
"token": {
"type": "string",
Expand Down
40 changes: 40 additions & 0 deletions amazon_dash/confirmations.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,48 @@ def send(self, message, success=True):
))


class PushbulletConfirmation(ConfirmationBase):
url_base = 'https://api.pushbullet.com/v2/pushes'
name = 'pushbullet'
required_fields = ('token',)
one_field_of = {'device_iden', 'email', 'channel_tag', 'client_id'}
to_field = None

def __init__(self, data):
one_fields = set(data) & self.one_field_of
if len(one_fields) > 1:
raise InvalidConfig(extra_body='Only one in {} is required for {} notifications'.format(
', '.join(one_fields), self.name))
elif one_fields:
self.to_field = one_fields.pop()
super(PushbulletConfirmation, self).__init__(data)

def get_data(self, body, title=''):
data = {
"type": "note",
"body": body,
}
if title:
data["title"] = title
if self.to_field:
data[self.to_field] = self.data[self.to_field]
return data

def send(self, message, success=True):
try:
r = requests.post(self.url_base, json=self.get_data(message),
headers={'Access-Token': self.data['token']})
except RequestException as e:
raise ConfirmationError('Unable to connect to Pushbullet servers on pushbullet confirmation: {}'.format(e))
try:
r.json()
except JSONDecodeError:
raise ConfirmationError('Invalid JSON response in pushbullet confirmation (server error?)')


CONFIRMATIONS = {
'telegram': TelegramConfirmation,
'pushbullet': PushbulletConfirmation,
'disabled': DisabledConfirmation,
}

Expand Down
10 changes: 7 additions & 3 deletions amazon_dash/execute.py
Original file line number Diff line number Diff line change
Expand Up @@ -341,9 +341,13 @@ def get_url(self):
return url

def get_headers(self):
return {
'x-ha-access': self.data['access']
} if 'access' in self.data else {}
headers = {}
if 'access_token' in self.data:
headers['Authorization'] = 'Bearer {0}'.format(self.data['access_token'])
elif 'access' in self.data:
headers['x-ha-access'] = self.data['access']

return headers


class ExecuteOpenHab(ExecuteOwnApiBase):
Expand Down
4 changes: 4 additions & 0 deletions amazon_dash/install/amazon-dash.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ devices:
# token: '402642618:QwGDgiKE3LqdkNAtBkq0UEeBoDdpZYw8b4h' # Telegram token. Get it from Bothfather
# to: 24291592 # Your Telegram id. You can get it using @get_id_bot
# is_default: true # Use by default this confirmation for all devices
# send-pb:
# service: pushbullet
# token: 'o.BbbPYjJizbPr2gSWgXGmqNTt6T9Rew51'
# is_default: false

# Need help? See the documentation:
# http://docs.nekmo.org/amazon-dash/config_file.html
Expand Down
39 changes: 38 additions & 1 deletion amazon_dash/tests/test_confirmations.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import requests_mock

from amazon_dash.confirmations import get_confirmation, DisabledConfirmation, get_confirmation_instance, \
TelegramConfirmation, ConfirmationBase
TelegramConfirmation, ConfirmationBase, PushbulletConfirmation
from amazon_dash.exceptions import InvalidConfig, ConfirmationError


Expand Down Expand Up @@ -71,3 +71,40 @@ def test_server_error(self):
m.post(telegram.url_base.format('foo'), exc=requests.exceptions.ConnectTimeout)
with self.assertRaises(ConfirmationError):
telegram.send('spam')


class TestPushbulletConfirmation(unittest.TestCase):
def get_pushbullet(self, extra=None):
extra = extra or {}
return PushbulletConfirmation(dict({'token': 'foo'}, **extra))

def test_send(self):
pushbullet = self.get_pushbullet()
with requests_mock.mock() as m:
m.post(pushbullet.url_base, text='{}')
pushbullet.send('spam')
self.assertTrue(m.called_once)

def test_invalid_json(self):
pushbullet = self.get_pushbullet()
with requests_mock.mock() as m:
m.post(pushbullet.url_base, text='{"}invalid')
with self.assertRaises(ConfirmationError):
pushbullet.send('spam')

def test_server_error(self):
pushbullet = self.get_pushbullet()
with requests_mock.mock() as m:
m.post(pushbullet.url_base, exc=requests.exceptions.ConnectTimeout)
with self.assertRaises(ConfirmationError):
pushbullet.send('spam')

def test_extra_to(self):
with self.assertRaises(InvalidConfig):
self.get_pushbullet({'device_iden': 'foo', 'email': 'bar'})

def test_to_device_iden(self):
pushbullet = self.get_pushbullet({'device_iden': 'bar'})
with requests_mock.mock() as m:
m.post(pushbullet.url_base, additional_matcher=lambda r: r.json().get('device_iden') == 'bar', text='{}')
pushbullet.send('spam')
9 changes: 8 additions & 1 deletion amazon_dash/tests/test_execute.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ def test_get_shell(self):
class TestExecuteUrl(unittest.TestCase):
no_body_methods = ['get', 'head', 'delete', 'connect', 'options', 'trace']
url = 'http://domain.com'

def setUp(self):
super(TestExecuteUrl, self).setUp()
self.session_mock = requests_mock.Mocker()
Expand Down Expand Up @@ -297,6 +297,13 @@ def test_execute_with_access(self):
assis.execute()
self.assertTrue(m.called_once)

def test_execute_with_access_token(self):
with requests_mock.mock() as m:
m.post(self.url, text='success', request_headers={'Authorization': 'Bearer abcde12345'})
assis = ExecuteHomeAssistant('key', self.default_data(extra_data={'access_token': 'abcde12345'}))
assis.execute()
self.assertTrue(m.called_once)


class TestExecuteOpenHab(unittest.TestCase):
path = '/rest/items/test'
Expand Down
51 changes: 47 additions & 4 deletions docs/config_file.rst
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ Real example:
openhab: 192.168.1.140
item: open_door
state: "ON"
confirmation: send-pb
44:65:0D:75:A7:B2:
name: Pompadour
ifttt: cdxxx-_gEJ3wdU04yyyzzz
Expand All @@ -72,6 +73,10 @@ Real example:
token: '402642618:QwGDgiKE3LqdkNAtBkq0UEeBoDdpZYw8b4h'
to: 24291592
is_default: false
send-pb:
service: pushbullet
token: 'o.BbbPYjJizbPr2gSWgXGmqNTt6T9Rew51'
is_default: false
Common options
Expand All @@ -98,7 +103,7 @@ for each device. The available exection methods are:

* **cmd**: local command line command. Arguments can be placed after the command.
* **url**: Call a url.
* **homeassistant**: send event to Homeassistant. This argument must be the address to the hass server (protocol and
* **homeassistant**: send event to Home Assistant. This argument must be the address to the hass server (protocol and
port are optional. By default http and 8123, respectively).
* **openhab**: send event to OpenHAB. This argument must be the address to the hass server (protocol and
port are optional. By default http and 8080, respectively).
Expand Down Expand Up @@ -248,13 +253,21 @@ Example:
confirmation: send-tg
Homeassistant event
~~~~~~~~~~~~~~~~~~~
Home Assistant event
~~~~~~~~~~~~~~~~~~~~
When the **homeassistant execution method** is used, the following options are available.

* **event** (required): Event name to send.
* **data**: Event data to send. Use json as string.
* **access**: HomeAssistant password for API (``x-ha-access`` header).
* **access_token**: Long-lived Home Assistant access token.
* **access**: Home Assistant legacy API password (``x-ha-access`` header).

Starting with version 0.78 of Home Assistant, there are two ways Amazon Dash can authenticate:

1. By providing a long-lived access token (generated within your Home Assistant profile page) via the ``access_token`` option.
2. By providing the legacy Home Assistant API password via the ``access`` option.

Although both options currently work, the Home Assistant project plans to deprecate (and likely remove) the legacy API password in the future; therefore, to properly future proof your Amazon Dash setup, the long-lived access token option is recommended.

The protocol and the port in the address of the Homeassistant server are optional. The syntax of the address is:
``[<protocol>://]<server>[:<port>]. For example: ``https://hassio.local:1234``.
Expand Down Expand Up @@ -337,6 +350,7 @@ Confirmations
-------------
The following **services** are supported to send confirmation messages.


Telegram
~~~~~~~~
For use a telegram service you need to define:
Expand All @@ -361,3 +375,32 @@ have not started a conversation before.
token: '402642618:QwGDgiKE3LqdkNAtBkq0UEeBoDdpZYw8b4h'
to: 24291592
is_default: false
Pushbullet
~~~~~~~~~~
For use a pushbullet service you need to define:

* **token**: Get it in your pushbullet Access Token (create a token): https://www.pushbullet.com/#settings/account

Optional: set a target (you can only set a target):

* **device_iden**: Device identifier. To get your device identifier:
``$ curl --header 'Access-Token: <YOUR TOKEN>' https://api.pushbullet.com/v2/devices``
* **email**: Useful to send a message to your contacts.
* **channel_tag**: Send to all subscribers to your channel.
* **client_iden**: Send to all users who have granted access to your OAuth client.

.. code-block:: yaml
# amazon-dash.yml
# ---------------
settings:
delay: 10
devices:
# ...
confirmations:
send-pb:
service: pushbullet
token: 'o.BbbPYjJizbPr2gSWgXGmqNTt6T9Rew51'
is_default: false
2 changes: 2 additions & 0 deletions docs/troubleshooting.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ are:
* Tcpdump.
* Sudo

Amazon-dash v2.0.0 will only be compatible with Python 3.6+. This version is currently in development.


Why root is required
--------------------
Expand Down
Binary file modified images/amazon-dash.xcf
Binary file not shown.

0 comments on commit 9b3cdeb

Please sign in to comment.