def push(msg): api_key = "kO3wYXQB6WQlQp7A5AN7WcPqdMOWy1Xx" pb = Pushbullet(api_key) # ip = subprocess.check_output("/sbin/ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'", shell=True) devlist = [x.nickname.encode('UTF-8') for x in pb.devices] if 'Rpi' not in devlist: pb.new_device('Rpi') for dev in pb.devices: push = dev.push_note('Rpi is up! ', msg)
def push(msg): api_key="kO3wYXQB6WQlQp7A5AN7WcPqdMOWy1Xx" pb = Pushbullet(api_key) # ip = subprocess.check_output("/sbin/ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'", shell=True) devlist=[x.nickname.encode('UTF-8') for x in pb.devices] if 'Rpi' not in devlist: pb.new_device('Rpi') for dev in pb.devices: push = dev.push_note('Rpi is up! ',msg)
class PushBulletRoute(Route): """SmartHome using pushbullet.""" def __init__(self, cfg): super(PushBulletRoute).__init__(cfg) self.lastFetch = time.time() self.apiKey = self.cfg.get('global', 'api_key') self.pb = Pushbullet(self.apiKey) def run(self): try: deviceIden = self.cfg.get('global', 'device_iden') except NoOptionError: deviceIden = self.pb.new_device('SmartHome').device_iden self.cfg.set('global', 'device_iden', deviceIden) with open(CONFIG_FILE, 'w') as f: self.cfg.write(f) def on_push(msg): journal.send('Got message: ' + json.dumps(msg)) try: pushes = self.pb.get_pushes(self.lastFetch) journal.send('Got pushes: ' + json.dumps(pushes)) self.lastFetch = time.time() if type(pushes) is types.TupleType and len(pushes)>1 \ and type(pushes[1]) is types.ListType: for push in pushes[1]: journal.send('Check push: ' + json.dumps(push)) if push.has_key('target_device_iden') and push['target_device_iden'] == deviceIden: cmd = json.loads(push['body']) self.home.followCommand(cmd) fromIden = push['source_device_iden'] fromDevice = self.getDevice(fromIden) if fromDevice is None: journal.send('get_status: Cannot find device with iden "' + fromIden + '"', PRIORITY=journal.LOG_ERR) return self.pb.push_note('status', self.home.getStatus(), fromDevice) except (PushbulletError, IOError, ValueError, KeyError), e: journal.send(str(e), PRIORITY=journal.LOG_ERR) lsr = Listener(Account(self.apiKey), on_push) lsr.run()
class PushBulletWSClient(WebSocketBaseClient): name = "pushbullet" def __init__(self, interface, url): """ Initializes the PB WS Client""" super().__init__(url) self.pb = Pushbullet(cfg.PUSHBULLET_KEY) self.manager = WebSocketManager() self.interface = interface self.device = None for i, device in enumerate(self.pb.devices): if device.nickname == 'pai': logger.debug("Device found") self.device = device break else: logger.exception("Device not found. Creating 'pai' device") self.device = self.pb.new_device(nickname='pai', icon='system') def stop(self): self.terminate() self.manager.stop() def handshake_ok(self): """ Callback trigger when connection succeeded""" logger.info("Handshake OK") self.manager.add(self) self.manager.start() for chat in self.pb.chats: logger.debug("Associated contacts: {}".format(chat)) # Receiving pending messages self.received_message(json.dumps({ "type": "tickle", "subtype": "push" })) self.send_message("Active") def received_message(self, message): """ Handle Pushbullet message. It should be a command """ logger.debug("Received Message {}".format(message)) try: message = json.loads(str(message)) except: logger.exception("Unable to parse message") return if message['type'] == 'tickle' and message['subtype'] == 'push': now = time.time() pushes = self.pb.get_pushes(modified_after=int(now) - 20, limit=1, filter_inactive=True) for p in pushes: # Ignore messages send by us if p.get('direction') == 'self' and p.get('title') == 'pai': #logger.debug('Ignoring message sent') continue if p.get('direction') == 'outgoing' or p.get('dismissed'): #logger.debug('Ignoring outgoing dismissed') continue if p.get('sender_email_normalized' ) in cfg.PUSHBULLET_CONTACTS or p.get( 'direction') == 'self': ret = self.interface.handle_command(p.get('body')) m = "PB {}: {}".format(p.get('sender_email_normalized'), ret) logger.info(m) else: m = "PB {} (UNK): {}".format( p.get('sender_email_normalized'), p.get('body')) logger.warning(m) self.send_message(m) ps.sendNotification( Notification(sender=self.name, message=m, level=EventLevel.INFO)) def unhandled_error(self, error): logger.error("{}".format(error)) try: self.terminate() except Exception: logger.exception("Closing Pushbullet WS") self.close() def send_message(self, msg, dstchat=None): if dstchat is None: dstchat = self.pb.chats if not isinstance(dstchat, list): dstchat = [dstchat] # Push to self self.device.push_note("pai", msg) for chat in dstchat: if chat.email in cfg.PUSHBULLET_CONTACTS: try: self.pb.push_note("pai", msg, chat=chat) except Exception: logger.exception("Sending message") time.sleep(5)
class PushbulletBackend(Backend): """ This backend will listen for events on a Pushbullet (https://pushbullet.com) channel and propagate them to the bus. This backend is quite useful if you want to synchronize events and actions with your mobile phone (through the Pushbullet app and/or through Tasker), synchronize clipboards, send pictures and files to other devices etc. You can also wrap Platypush messages as JSON into a push body to execute them. Triggers: * :class:`platypush.message.event.pushbullet.PushbulletEvent` if a new push is received Requires: * **pushbullet.py** (``pip install git+https://github.com/pushbullet.py/pushbullet.py``) """ def __init__(self, token: str, device: str = 'Platypush', proxy_host: Optional[str] = None, proxy_port: Optional[int] = None, **kwargs): """ :param token: Your Pushbullet API token, see https://docs.pushbullet.com/#authentication :param device: Name of the virtual device for Platypush (default: Platypush) :param proxy_host: HTTP proxy host (default: None) :param proxy_port: HTTP proxy port (default: None) """ super().__init__(**kwargs) self.token = token self.device_name = device self.proxy_host = proxy_host self.proxy_port = proxy_port self.device = None self.pb_device_id = None self.pb = None self.listener = None def _initialize(self): # noinspection PyPackageRequirements from pushbullet import Pushbullet self.pb = Pushbullet(self.token) try: self.device = self.pb.get_device(self.device_name) except Exception as e: self.logger.info( f'Device {self.device_name} does not exist: {e}. Creating it') self.device = self.pb.new_device(self.device_name) self.pb_device_id = self.get_device_id() def _get_latest_push(self): t = int(time.time()) - 5 pushes = self.pb.get_pushes(modified_after=str(t), limit=1) if pushes: return pushes[0] def on_push(self): def callback(data): try: # Parse the push try: data = json.loads(data) if isinstance(data, str) else data except Exception as e: self.logger.exception(e) return # If it's a push, get it if data['type'] == 'tickle' and data['subtype'] == 'push': push = self._get_latest_push() elif data['type'] == 'push': push = data['push'] else: return # Not a push notification if not push: return # Post an event, useful to react on mobile notifications if # you enabled notification mirroring on your PushBullet app event = PushbulletEvent(**push) self.on_message(event) if 'body' not in push: return self.logger.debug(f'Received push: {push}') body = push['body'] try: body = json.loads(body) self.on_message(body) except Exception as e: self.logger.debug( 'Unexpected message received on the ' + f'Pushbullet backend: {e}. Message: {body}') except Exception as e: self.logger.exception(e) return return callback def get_device_id(self): # noinspection PyBroadException try: return self.pb.get_device(self.device_name).device_iden except Exception: device = self.pb.new_device(self.device_name, model='Platypush virtual device', manufacturer='platypush', icon='system') self.logger.info(f'Created Pushbullet device {self.device_name}') return device.device_iden def close(self): if self.listener: self.listener.close() self.listener = None def on_stop(self): self.logger.info('Received STOP event on the Pushbullet backend') super().on_stop() self.close() self.logger.info('Pushbullet backend terminated') def on_close(self, err=None): def callback(*_): self.listener = None raise RuntimeError(err or 'Connection closed') return callback def on_error(self, *_): def callback(*args): self.logger.error(f'Pushbullet error: {args}') try: if self.listener: self.listener.close() except Exception as e: self.logger.error( 'Error on Pushbullet connection close upon error') self.logger.exception(e) finally: self.listener = None return callback def on_open(self): def callback(*_): self.logger.info('Pushbullet service connected') return callback def run_listener(self): from .listener import Listener self.logger.info( f'Initializing Pushbullet backend - device_id: {self.device_name}') self.listener = Listener(account=self.pb, on_push=self.on_push(), on_open=self.on_open(), on_close=self.on_close(), on_error=self.on_error(), http_proxy_host=self.proxy_host, http_proxy_port=self.proxy_port) self.listener.run_forever() def run(self): super().run() initialized = False while not initialized: try: self._initialize() initialized = True except Exception as e: self.logger.exception(e) self.logger.error(f'Pushbullet initialization error: {e}') time.sleep(10) while not self.should_stop(): try: self.run_listener() except Exception as e: self.logger.exception(e) time.sleep(10) self.logger.info('Retrying connection')
class PushbulletBackend(Backend): """ This backend will listen for events on a Pushbullet (https://pushbullet.com) channel and propagate them to the bus. This backend is quite useful if you want to synchronize events and actions with your mobile phone (through the Pushbullet app and/or through Tasker), synchronize clipboards, send pictures and files to other devices etc. You can also wrap Platypush messages as JSON into a push body to execute them. Triggers: * :class:`platypush.message.event.pushbullet.PushbulletEvent` if a new push is received Requires: * **requests** (``pip install requests``) * **pushbullet.py** (``pip install git+https://github.com/rbrcsk/pushbullet.py``) """ def __init__(self, token, device='Platypush', proxy_host=None, proxy_port=None, **kwargs): """ :param token: Your Pushbullet API token, see https://docs.pushbullet.com/#authentication :type token: str :param device: Name of the virtual device for Platypush (default: Platypush) :type device: str :param proxy_host: HTTP proxy host (default: None) :type proxy_host: str :param proxy_port: HTTP proxy port (default: None) :type proxy_port: int """ super().__init__(**kwargs) self.token = token self.device_name = device self.proxy_host = proxy_host self.proxy_port = proxy_port self.pb = Pushbullet(token) self.listener = None try: self.device = self.pb.get_device(self.device_name) except: self.device = self.pb.new_device(self.device_name) self.pb_device_id = self.get_device_id() def _get_latest_push(self): t = int(time.time()) - 5 pushes = self.pb.get_pushes(modified_after=str(t), limit=1) if pushes: return pushes[0] def on_push(self): def callback(data): try: # Parse the push try: data = json.loads(data) if isinstance(data, str) else data except Exception as e: self.logger.exception(e) return # If it's a push, get it if data['type'] == 'tickle' and data['subtype'] == 'push': push = self._get_latest_push() elif data['type'] == 'push': push = data['push'] else: return # Not a push notification if not push: return # Post an event, useful to react on mobile notifications if # you enabled notification mirroring on your PushBullet app event = PushbulletEvent(**push) self.on_message(event) if 'body' not in push: return self.logger.debug('Received push: {}'.format(push)) body = push['body'] try: body = json.loads(body) self.on_message(body) except Exception as e: self.logger.debug(('Unexpected message received on the ' + 'Pushbullet backend: {}. Message: {}') .format(str(e), body)) except Exception as e: self.logger.exception(e) return return callback def get_device_id(self): try: return self.pb.get_device(self.device_name).device_iden except Exception as e: device = self.pb.new_device(self.device_name, model='Platypush virtual device', manufacturer='platypush', icon='system') self.logger.info('Created Pushbullet device {}'.format( self.device_name)) return device.device_iden def send_message(self, msg): if isinstance(msg, dict): msg = json.dumps(msg) self.device.push_note(title=None, body=str(msg)) def close(self): if self.listener: self.listener.close() def on_stop(self): return self.close() def run(self): super().run() self.logger.info('Initialized Pushbullet backend - device_id: {}' .format(self.device_name)) self.listener = Listener(account=self.pb, on_push=self.on_push(), http_proxy_host=self.proxy_host, http_proxy_port=self.proxy_port) self.listener.run_forever()
class Pushlistener(threading.Thread): def __init__(self): threading.Thread.__init__(self, name="PbThread") self.api_key=api_key self.pb = Pushbullet(self.api_key) self.ws = websocket.WebSocket() self.ws.connect("wss://stream.pushbullet.com/websocket/{0}".format(self.api_key)) self.last_time=0 self.data='' self.setDaemon(True) self.interpreters=[] self.devices=[x.nickname.encode('UTF-8') for x in self.pb.devices] if DEVICE_NAME not in self.devices: self.pb.new_device('DEVICE_NAME') def run(self): while(1): self.result=json.loads(self.ws.recv()) self.res_type=self.result.get("type") if self.res_type!='nop': self.context_matcher() def context_matcher(self): if self.result.get("type")=='tickle': if self.result.get('subtype')=='push': pushes = self.pb.get_pushes() latest=pushes[1][0] if latest.get('target_device_iden')==PUSHBULLET_ID: self.body=latest['body'] os.system('mpg321 {0} 2>/dev/null'.format(MESSAGE_FILE)) self.notify({'text':self.body}) ny.show(self.body) def register(self, interpreter): """ Register interpreters to be notified of new input """ if not interpreter in self.interpreters: self.interpreters.append(interpreter) def unregister(self, interpreter): """ Unregisters an interpreter """ if interpreter in self.interpreters: self.interpreters.remove(interpreter) def notify(self, event): """ Notify all interpreters of a received input """ for interpreter in self.interpreters: interpreter.on_event(event, self) def send(self,device,msg): for dev in self.pb.devices: print dev.nickname if dev.nickname==device: dev.push_note(msg,None)