Skip to content
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

XMPP async #17283

Merged
merged 13 commits into from
Oct 13, 2018
58 changes: 37 additions & 21 deletions homeassistant/components/notify/xmpp.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
from homeassistant.const import (
CONF_PASSWORD, CONF_SENDER, CONF_RECIPIENT, CONF_ROOM)

REQUIREMENTS = ['sleekxmpp==1.3.2',
'dnspython3==1.15.0',
REQUIREMENTS = ['slixmpp==1.4.0',
'aiodns==1.1.1',
'pyasn1==0.3.7',
'pyasn1-modules==0.1.5']
flowolf marked this conversation as resolved.
Show resolved Hide resolved

Expand All @@ -34,76 +34,92 @@
})


def get_service(hass, config, discovery_info=None):
async def async_get_service(hass, config, discovery_info=None):
"""Get the Jabber (XMPP) notification service."""
_LOGGER.debug("async_get_service")
flowolf marked this conversation as resolved.
Show resolved Hide resolved
return XmppNotificationService(
config.get(CONF_SENDER), config.get(CONF_PASSWORD),
config.get(CONF_RECIPIENT), config.get(CONF_TLS),
config.get(CONF_VERIFY), config.get(CONF_ROOM))
config.get(CONF_VERIFY), config.get(CONF_ROOM), hass.loop)


class XmppNotificationService(BaseNotificationService):
"""Implement the notification service for Jabber (XMPP)."""

def __init__(self, sender, password, recipient, tls, verify, room):
def __init__(self, sender, password, recipient, tls, verify, room, loop):
"""Initialize the service."""
self._loop = loop
self._sender = sender
self._password = password
self._recipient = recipient
self._tls = tls
self._verify = verify
self._room = room
_LOGGER.debug("XmppNotificationService __init__")
flowolf marked this conversation as resolved.
Show resolved Hide resolved

def send_message(self, message="", **kwargs):
async def async_send_message(self, message="", **kwargs):
"""Send a message to a user."""
_LOGGER.debug("XmppNotificationService async_send_message 1")
flowolf marked this conversation as resolved.
Show resolved Hide resolved
title = kwargs.get(ATTR_TITLE, ATTR_TITLE_DEFAULT)
data = '{}: {}'.format(title, message) if title else message

send_message('{}/home-assistant'.format(self._sender),
self._password, self._recipient, self._tls,
self._verify, self._room, data)
# TODO allow /home-assistant part of the resource to be configured
flowolf marked this conversation as resolved.
Show resolved Hide resolved
await async_send_message(
'{}/home-assistant'.format(self._sender),
self._password, self._recipient, self._tls,
self._verify, self._room, self._loop, data)


def send_message(sender, password, recipient, use_tls,
verify_certificate, room, message):
async def async_send_message(sender, password, recipient, use_tls,
verify_certificate, room, loop, message):
"""Send a message over XMPP."""
import sleekxmpp
import slixmpp

class SendNotificationBot(sleekxmpp.ClientXMPP):
class SendNotificationBot(slixmpp.ClientXMPP):
"""Service for sending Jabber (XMPP) messages."""

def __init__(self):
"""Initialize the Jabber Bot."""
super(SendNotificationBot, self).__init__(sender, password)
flowolf marked this conversation as resolved.
Show resolved Hide resolved
_LOGGER.debug("async_send_message SendNotificationBot __init__")

self.use_tls = use_tls
# need hass.loop!!
self.loop = loop

self.force_starttls = use_tls
self.use_ipv6 = False
self.add_event_handler('failed_auth', self.check_credentials)
self.add_event_handler(
'failed_auth', self.disconnect_on_login_fail)
self.add_event_handler('session_start', self.start)

if room:
self.register_plugin('xep_0045') # MUC
if not verify_certificate:
self.add_event_handler('ssl_invalid_cert',
self.discard_ssl_invalid_cert)

self.connect(use_tls=self.use_tls, use_ssl=False)
self.process()
_LOGGER.debug("before connect")
self.connect(force_starttls=self.force_starttls, use_ssl=False)

def start(self, event):
"""Start the communication and sends the message."""
self.send_presence()
self.get_roster()
_LOGGER.debug("event handler callback called on start")

self.get_roster()
self.send_presence()
_LOGGER.debug("sender {}, message: {}".format(sender, message))
if room:
_LOGGER.debug("Joining room %s.", room)
self.plugin['xep_0045'].joinMUC(room, sender, wait=True)
self.plugin['xep_0045'].join_muc(room, sender, wait=True)
self.send_message(mto=room, mbody=message, mtype='groupchat')
else:
self.send_message(mto=recipient, mbody=message, mtype='chat')
self.disconnect(wait=True)

def check_credentials(self, event):
def disconnect_on_login_fail(self, event):
"""Disconnect from the server if credentials are invalid."""
_LOGGER.debug("event handler callback called "
"on disconnect on login fail")
self.disconnect()

@staticmethod
Expand Down
10 changes: 4 additions & 6 deletions requirements_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ afsapi==0.0.4
# homeassistant.components.device_tracker.automatic
aioautomatic==0.6.5

# homeassistant.components.notify.xmpp
# homeassistant.components.sensor.dnsip
aiodns==1.1.1

Expand Down Expand Up @@ -299,9 +300,6 @@ distro==1.3.0
# homeassistant.components.switch.digitalloggers
dlipower==0.7.165

# homeassistant.components.notify.xmpp
dnspython3==1.15.0

# homeassistant.components.sensor.dovado
dovado==0.4.1

Expand Down Expand Up @@ -1349,12 +1347,12 @@ skybellpy==0.1.2
# homeassistant.components.notify.slack
slacker==0.9.65

# homeassistant.components.notify.xmpp
sleekxmpp==1.3.2

# homeassistant.components.sleepiq
sleepyq==0.6

# homeassistant.components.notify.xmpp
slixmpp==1.4.0

# homeassistant.components.smappee
smappy==0.2.16

Expand Down