Skip to content

Commit

Permalink
New version of the Pushsafer plugin, able to processing multiple Inputs
Browse files Browse the repository at this point in the history
  • Loading branch information
khenderick committed Nov 20, 2016
1 parent 25f20b1 commit 5e554b0
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 104 deletions.
76 changes: 41 additions & 35 deletions pushsafer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@ This is a work in progress and might or might not be suitable for real-life usag
feedback and/or contributions. Please only use this plugin if you know what you're doing and if you're willing to debug
issues you might encounter. As always, feel free to report issues and/or make pull requests.

## Todo

* Add more information in the readme

## Usecases

* A doorbell (to make sure you know when somebody is at the door, even if you're in the garden)
Expand All @@ -21,35 +17,45 @@ issues you might encounter. As always, feel free to report issues and/or make pu
```
config_description = [{'name': 'privatekey',
'type': 'str',
'description': 'Your private or alias key from pushsafer.com.'},
{'name': 'input_id',
'type': 'int',
'description': 'The ID of the input that will trigger the event.'},
{'name': 'title',
'type': 'str',
'description': 'The title of the message.'},
{'name': 'message',
'type': 'str',
'description': 'The message to be send.'}
{'name': 'device',
'type': 'str',
'description': 'The device or device group id where the message to be send.'}
{'name': 'icon',
'type': 'str',
'description': 'The icon which is displayed with the message (a number 1-98).'}
{'name': 'sound',
'type': 'str',
'description': 'The notification sound of message (a number 0-28 or empty).'}
{'name': 'vibration',
'type': 'str',
'description': 'How often the device should vibrate (a number 1-3 or empty).'}
{'name': 'url',
'type': 'str',
'description': 'A URL or URL scheme: https://www.pushsafer.com/en/url_schemes'}
{'name': 'urltitle',
'type': 'str',
'description': 'the URLs title'}
{'name': 'time2live',
'type': 'str',
'description': 'Integer number 0-43200: Time in minutes after which message automatically gets purged.'}]
'description': 'Your Private or Alias key.'},
{'name': 'input_mapping',
'type': 'section',
'description': 'The mapping between input_id and a given Pushsafer settings',
'repeat': True,
'min': 1,
'content': [{'name': 'input_id',
'type': 'int',
'description': 'The ID of the (virtual) input that will trigger the event.'},
{'name': 'message',
'type': 'str',
'description': 'The message to be send.'},
{'name': 'title',
'type': 'str',
'description': 'The title of message to be send.'},
{'name': 'device',
'type': 'str',
'description': 'The device or device group id where the message to be send.'},
{'name': 'icon',
'type': 'str',
'description': 'The icon which is displayed with the message (a number 1-98).'},
{'name': 'sound',
'type': 'int',
'description': 'The notification sound of message (a number 0-28 or empty).'},
{'name': 'vibration',
'type': 'str',
'description': 'How often the device should vibrate (a number 1-3 or empty).'},
{'name': 'url',
'type': 'str',
'description': 'A URL or URL scheme: https://www.pushsafer.com/en/url_schemes'},
{'name': 'urltitle',
'type': 'str',
'description': 'the URLs title'},
{'name': 'time2live',
'type': 'str',
'description': 'Integer number 0-43200: Time in minutes after which message automatically gets purged.'}]}]
```

The ```privatekey``` can be obtained on your [dashboard](https://www.pushsafer.com/dashboard).

The ```input_mapping``` contains a mapping between the ```input_id``` (the ID of the OpenMotics (virtual) Input), and a series of settings
related to Pushsafer. The information about these values can be found at the [API documentation](https://www.pushsafer.com/en/pushapi)
150 changes: 81 additions & 69 deletions pushsafer/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
A Pushsafer (http://www.pushsafer.com) plugin for pushing events through Pushsafer
"""

import requests
import collections
import simplejson as json
from threading import Thread
from plugins.base import om_expose, input_status, output_status, OMPluginBase, PluginConfigChecker

import requests
import simplejson as json
from plugins.base import om_expose, input_status, OMPluginBase, PluginConfigChecker


class Pushsafer(OMPluginBase):
Expand All @@ -15,44 +16,50 @@ class Pushsafer(OMPluginBase):
"""

name = 'Pushsafer'
version = '1.0.1'
version = '2.0.3'
interfaces = [('config', '1.0')]

config_description = [{'name': 'privatekey',
'type': 'str',
'description': 'Your Private or Alias key.'},
{'name': 'input_id',
'type': 'int',
'description': 'The ID of the input that will trigger the event.'},
{'name': 'message',
'type': 'str',
'description': 'The message to be send.'}
{'name': 'title',
'type': 'str',
'description': 'The title of message to be send.'}
{'name': 'device',
'type': 'str',
'description': 'The device or device group id where the message to be send.'}
{'name': 'icon',
'type': 'str',
'description': 'The icon which is displayed with the message (a number 1-98).'}
{'name': 'sound',
'type': 'str',
'description': 'The notification sound of message (a number 0-28 or empty).'}
{'name': 'vibration',
'type': 'str',
'description': 'How often the device should vibrate (a number 1-3 or empty).'}
{'name': 'url',
'type': 'str',
'description': 'A URL or URL scheme: https://www.pushsafer.com/en/url_schemes'}
{'name': 'urltitle',
'type': 'str',
'description': 'the URLs title'}
{'name': 'time2live',
'type': 'str',
'description': 'Integer number 0-43200: Time in minutes after which message automatically gets purged.'}]

default_config = {'privatekey': '', 'input_id': -1, 'message': '', 'title': 'OpenMotics', 'device': '', 'icon': '1', 'sound': '', 'vibration': '', 'url': '', 'urltitle': '', 'time2live': ''}
{'name': 'input_mapping',
'type': 'section',
'description': 'The mapping between input_id and a given Pushsafer settings',
'repeat': True,
'min': 1,
'content': [{'name': 'input_id',
'type': 'int',
'description': 'The ID of the (virtual) input that will trigger the event.'},
{'name': 'message',
'type': 'str',
'description': 'The message to be send.'},
{'name': 'title',
'type': 'str',
'description': 'The title of message to be send.'},
{'name': 'device',
'type': 'str',
'description': 'The device or device group id where the message to be send.'},
{'name': 'icon',
'type': 'str',
'description': 'The icon which is displayed with the message (a number 1-98).'},
{'name': 'sound',
'type': 'int',
'description': 'The notification sound of message (a number 0-28 or empty).'},
{'name': 'vibration',
'type': 'str',
'description': 'How often the device should vibrate (a number 1-3 or empty).'},
{'name': 'url',
'type': 'str',
'description': 'A URL or URL scheme: https://www.pushsafer.com/en/url_schemes'},
{'name': 'urltitle',
'type': 'str',
'description': 'the URLs title'},
{'name': 'time2live',
'type': 'str',
'description': 'Integer number 0-43200: Time in minutes after which message automatically gets purged.'}]}]

default_config = {'privatekey': '', 'input_id': -1, 'message': '', 'title': 'OpenMotics', 'device': '', 'icon': '1', 'sound': '', 'vibration': '',
'url': '', 'urltitle': '', 'time2live': ''}

def __init__(self, webinterface, logger):
super(Pushsafer, self).__init__(webinterface, logger)
Expand All @@ -67,59 +74,64 @@ def __init__(self, webinterface, logger):

def _read_config(self):
self._privatekey = self._config['privatekey']
self._input_id = self._config['input_id']
self._message = self._config['message']
self._title = self._config['title']
self._device = self._config['device']
self._icon = self._config['icon']
self._sound = self._config['sound']
self._vibration = self._config['vibration']
self._url = self._config['url']
self._urltitle = self._config['urltitle']
self._time2live = self._config['time2live']
self._mapping = self._config.get('input_mapping', [])

self._endpoint = 'https://www.pushsafer.com/api'
self._headers = {'Content-type': 'application/x-www-form-urlencoded',
'X-Requested-With': 'OpenMotics plugin: Pushsafer'}

self._enabled = self._privatekey != '' and self._message != ''
self._enabled = self._privatekey != '' and len(self._mapping) > 0
self.logger('Pushsafer is {0}'.format('enabled' if self._enabled else 'disabled'))

def convert(self,data):
if isinstance(data,basestring):
def convert(self, data):
if isinstance(data, basestring):
return str(data)
elif isinstance(data,collections.Mapping):
elif isinstance(data, collections.Mapping):
return dict(map(self.convert, data.iteritems()))
elif isinstance(data,collections.Iterable):
return type(data)(map(self.convert,data))
elif isinstance(data, collections.Iterable):
return type(data)(map(self.convert, data))
else:
return data

@input_status
def input_status(self, status):
if self._enabled is True:
input_id = status[0]
if input_id == self._input_id:
thread = Thread(target=self._process_input, args=(input_id,))
thread.start()

def _process_input(self,input_id):
for mapping in self._mapping:
if input_id == mapping['input_id']:
data = {'k': self._privatekey,
'm': mapping['message'],
't': mapping['title'],
'd': mapping['device'],
'i': mapping['icon'],
's': mapping['sound'],
'v': mapping['vibration'],
'u': mapping['url'],
'ut': mapping['urltitle'],
'l': mapping['time2live']}
thread = Thread(target=self._send_data, args=(data,))
thread.start()

def _send_data(self, data):
try:
data = {'k': self._privatekey,
'm': self._message,
't': self._title,
'd': self._device,
'i': self._icon,
's': self._sound,
'v': self._vibration,
'u': self._url,
'ut': self._urltitle,
'l': self._time2live}
self.logger('Sending: {0}'.format(data))
self.logger('Sending data')
response = requests.post(url=self._endpoint,
data=data,
headers=self._headers,
verify=False)
self.logger('Received: {0} ({1})'.format(response.text, response.status_code))
if response.status_code != 200:
self.logger('Got error response: {0} ({1})'.format(response.text, response.status_code))
else:
result = json.loads(response.text)
if result['status'] != 1:
self.logger('Got error response: {0}'.format(result['error']))
else:
self.logger('Got reply: {0}'.format(result['success']))
quotas = []
for data in result['available'].values():
device = data.keys()[0]
quotas.append('{0}: {1}'.format(device, data[device]))
self.logger('Remaining quotas: {0}'.format(', '.join(quotas)))
except Exception as ex:
self.logger('Error sending: {0}'.format(ex))

Expand Down

0 comments on commit 5e554b0

Please sign in to comment.