diff --git a/homeassistant/components/binary_sensor/mysensors.py b/homeassistant/components/binary_sensor/mysensors.py index e938f946457..6406dabd26f 100644 --- a/homeassistant/components/binary_sensor/mysensors.py +++ b/homeassistant/components/binary_sensor/mysensors.py @@ -47,7 +47,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): devices = {} gateway.platform_callbacks.append(mysensors.pf_callback_factory( - map_sv_types, devices, add_devices, MySensorsBinarySensor)) + map_sv_types, devices, MySensorsBinarySensor, add_devices)) class MySensorsBinarySensor( diff --git a/homeassistant/components/climate/mysensors.py b/homeassistant/components/climate/mysensors.py index 13a062a335e..6c55b3b4451 100755 --- a/homeassistant/components/climate/mysensors.py +++ b/homeassistant/components/climate/mysensors.py @@ -39,7 +39,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): } devices = {} gateway.platform_callbacks.append(mysensors.pf_callback_factory( - map_sv_types, devices, add_devices, MySensorsHVAC)) + map_sv_types, devices, MySensorsHVAC, add_devices)) class MySensorsHVAC(mysensors.MySensorsDeviceEntity, ClimateDevice): diff --git a/homeassistant/components/cover/mysensors.py b/homeassistant/components/cover/mysensors.py index 7dd63a8c745..a75ad36354b 100644 --- a/homeassistant/components/cover/mysensors.py +++ b/homeassistant/components/cover/mysensors.py @@ -35,7 +35,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): }) devices = {} gateway.platform_callbacks.append(mysensors.pf_callback_factory( - map_sv_types, devices, add_devices, MySensorsCover)) + map_sv_types, devices, MySensorsCover, add_devices)) class MySensorsCover(mysensors.MySensorsDeviceEntity, CoverDevice): diff --git a/homeassistant/components/light/mysensors.py b/homeassistant/components/light/mysensors.py index 86d033cf4ce..9a018192f63 100644 --- a/homeassistant/components/light/mysensors.py +++ b/homeassistant/components/light/mysensors.py @@ -58,7 +58,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): }) devices = {} gateway.platform_callbacks.append(mysensors.pf_callback_factory( - map_sv_types, devices, add_devices, device_class_map)) + map_sv_types, devices, device_class_map, add_devices)) class MySensorsLight(mysensors.MySensorsDeviceEntity, Light): diff --git a/homeassistant/components/mysensors.py b/homeassistant/components/mysensors.py index b6778760b1a..79e572defeb 100644 --- a/homeassistant/components/mysensors.py +++ b/homeassistant/components/mysensors.py @@ -9,10 +9,10 @@ import socket import voluptuous as vol -from homeassistant.bootstrap import setup_component import homeassistant.helpers.config_validation as cv -from homeassistant.const import (ATTR_BATTERY_LEVEL, CONF_OPTIMISTIC, - EVENT_HOMEASSISTANT_START, +from homeassistant.bootstrap import setup_component +from homeassistant.const import (ATTR_BATTERY_LEVEL, CONF_NAME, + CONF_OPTIMISTIC, EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP, STATE_OFF, STATE_ON) from homeassistant.helpers import discovery from homeassistant.loader import get_component @@ -169,10 +169,13 @@ def setup(hass, config): 'cover']: discovery.load_platform(hass, component, DOMAIN, {}, config) + discovery.load_platform( + hass, 'notify', DOMAIN, {CONF_NAME: DOMAIN}, config) + return True -def pf_callback_factory(map_sv_types, devices, add_devices, entity_class): +def pf_callback_factory(map_sv_types, devices, entity_class, add_devices=None): """Return a new callback for the platform.""" def mysensors_callback(gateway, node_id): """Callback for mysensors platform.""" @@ -187,7 +190,10 @@ def pf_callback_factory(map_sv_types, devices, add_devices, entity_class): value_type not in map_sv_types[child.type]: continue if key in devices: - devices[key].update_ha_state(True) + if add_devices: + devices[key].schedule_update_ha_state(True) + else: + devices[key].update() continue name = '{} {} {}'.format( gateway.sensors[node_id].sketch_name, node_id, child.id) @@ -197,11 +203,12 @@ def pf_callback_factory(map_sv_types, devices, add_devices, entity_class): device_class = entity_class devices[key] = device_class( gateway, node_id, child.id, name, value_type, child.type) - - _LOGGER.info('Adding new devices: %s', devices[key]) - add_devices([devices[key]]) - if key in devices: - devices[key].update_ha_state(True) + if add_devices: + _LOGGER.info('Adding new devices: %s', devices[key]) + add_devices([devices[key]]) + devices[key].schedule_update_ha_state(True) + else: + devices[key].update() return mysensors_callback diff --git a/homeassistant/components/notify/__init__.py b/homeassistant/components/notify/__init__.py index b9d595401b5..a5c1e53ef03 100644 --- a/homeassistant/components/notify/__init__.py +++ b/homeassistant/components/notify/__init__.py @@ -14,7 +14,7 @@ import homeassistant.bootstrap as bootstrap import homeassistant.helpers.config_validation as cv from homeassistant.config import load_yaml_config_file from homeassistant.const import CONF_NAME, CONF_PLATFORM -from homeassistant.helpers import config_per_platform +from homeassistant.helpers import config_per_platform, discovery from homeassistant.util import slugify _LOGGER = logging.getLogger(__name__) @@ -66,27 +66,32 @@ def send_message(hass, message, title=None, data=None): def setup(hass, config): """Setup the notify services.""" - success = False - descriptions = load_yaml_config_file( os.path.join(os.path.dirname(__file__), 'services.yaml')) targets = {} - for platform, p_config in config_per_platform(config, DOMAIN): + def setup_notify_platform(platform, p_config=None, discovery_info=None): + """Set up a notify platform.""" + if p_config is None: + p_config = {} + if discovery_info is None: + discovery_info = {} + notify_implementation = bootstrap.prepare_setup_platform( hass, config, DOMAIN, platform) if notify_implementation is None: _LOGGER.error("Unknown notification service specified") - continue + return False - notify_service = notify_implementation.get_service(hass, p_config) + notify_service = notify_implementation.get_service( + hass, p_config, discovery_info) if notify_service is None: _LOGGER.error("Failed to initialize notification service %s", platform) - continue + return False def notify_message(notify_service, call): """Handle sending notification message service calls.""" @@ -112,7 +117,9 @@ def setup(hass, config): service_call_handler = partial(notify_message, notify_service) if hasattr(notify_service, 'targets'): - platform_name = (p_config.get(CONF_NAME) or platform) + platform_name = ( + p_config.get(CONF_NAME) or discovery_info.get(CONF_NAME) or + platform) for name, target in notify_service.targets.items(): target_name = slugify('{}_{}'.format(platform_name, name)) targets[target_name] = target @@ -121,15 +128,29 @@ def setup(hass, config): descriptions.get(SERVICE_NOTIFY), schema=NOTIFY_SERVICE_SCHEMA) - platform_name = (p_config.get(CONF_NAME) or SERVICE_NOTIFY) + platform_name = ( + p_config.get(CONF_NAME) or discovery_info.get(CONF_NAME) or + SERVICE_NOTIFY) platform_name_slug = slugify(platform_name) hass.services.register( DOMAIN, platform_name_slug, service_call_handler, descriptions.get(SERVICE_NOTIFY), schema=NOTIFY_SERVICE_SCHEMA) - success = True - return success + return True + + for platform, p_config in config_per_platform(config, DOMAIN): + if not setup_notify_platform(platform, p_config): + _LOGGER.error("Failed to set up platform %s", platform) + continue + + def platform_discovered(platform, info): + """Callback to load a platform.""" + setup_notify_platform(platform, discovery_info=info) + + discovery.listen_platform(hass, DOMAIN, platform_discovered) + + return True class BaseNotificationService(object): diff --git a/homeassistant/components/notify/apns.py b/homeassistant/components/notify/apns.py index 26d20f3bc89..09716065751 100644 --- a/homeassistant/components/notify/apns.py +++ b/homeassistant/components/notify/apns.py @@ -11,18 +11,29 @@ import voluptuous as vol from homeassistant.helpers.event import track_state_change from homeassistant.config import load_yaml_config_file from homeassistant.components.notify import ( - ATTR_TARGET, ATTR_DATA, BaseNotificationService) + ATTR_TARGET, ATTR_DATA, BaseNotificationService, DOMAIN) +from homeassistant.const import CONF_NAME, CONF_PLATFORM import homeassistant.helpers.config_validation as cv from homeassistant.helpers import template as template_helper -DOMAIN = "apns" APNS_DEVICES = "apns.yaml" +CONF_CERTFILE = "cert_file" +CONF_TOPIC = "topic" +CONF_SANDBOX = "sandbox" DEVICE_TRACKER_DOMAIN = "device_tracker" SERVICE_REGISTER = "apns_register" ATTR_PUSH_ID = "push_id" ATTR_NAME = "name" +PLATFORM_SCHEMA = vol.Schema({ + vol.Required(CONF_PLATFORM): 'apns', + vol.Required(CONF_NAME): cv.string, + vol.Required(CONF_CERTFILE): cv.isfile, + vol.Required(CONF_TOPIC): cv.string, + vol.Optional(CONF_SANDBOX, default=False): cv.boolean, +}) + REGISTER_SERVICE_SCHEMA = vol.Schema({ vol.Required(ATTR_PUSH_ID): cv.string, vol.Optional(ATTR_NAME, default=None): cv.string, @@ -31,31 +42,19 @@ REGISTER_SERVICE_SCHEMA = vol.Schema({ REQUIREMENTS = ["apns2==0.1.1"] -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Return push service.""" descriptions = load_yaml_config_file( os.path.join(os.path.dirname(__file__), 'services.yaml')) - name = config.get("name") - if name is None: - logging.error("Name must be specified.") - return None - - cert_file = config.get('cert_file') - if cert_file is None: - logging.error("Certificate must be specified.") - return None - - topic = config.get('topic') - if topic is None: - logging.error("Topic must be specified.") - return None - - sandbox = bool(config.get('sandbox', False)) + name = config.get(CONF_NAME) + cert_file = config.get(CONF_CERTFILE) + topic = config.get(CONF_TOPIC) + sandbox = config.get(CONF_SANDBOX) service = ApnsNotificationService(hass, name, topic, sandbox, cert_file) hass.services.register(DOMAIN, - name, + 'apns_{}'.format(name), service.register, descriptions.get(SERVICE_REGISTER), schema=REGISTER_SERVICE_SCHEMA) @@ -202,8 +201,6 @@ class ApnsNotificationService(BaseNotificationService): def register(self, call): """Register a device to receive push messages.""" push_id = call.data.get(ATTR_PUSH_ID) - if push_id is None: - return False device_name = call.data.get(ATTR_NAME) current_device = self.devices.get(push_id) diff --git a/homeassistant/components/notify/aws_lambda.py b/homeassistant/components/notify/aws_lambda.py index 8db48b0000e..d18da5ae2f0 100644 --- a/homeassistant/components/notify/aws_lambda.py +++ b/homeassistant/components/notify/aws_lambda.py @@ -35,7 +35,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ }) -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the AWS Lambda notification service.""" context_str = json.dumps({'hass': hass.config.as_dict(), 'custom': config[CONF_CONTEXT]}) diff --git a/homeassistant/components/notify/aws_sns.py b/homeassistant/components/notify/aws_sns.py index f3af26cd8b4..f02b6b75a84 100644 --- a/homeassistant/components/notify/aws_sns.py +++ b/homeassistant/components/notify/aws_sns.py @@ -33,7 +33,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ }) -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the AWS SNS notification service.""" # pylint: disable=import-error import boto3 diff --git a/homeassistant/components/notify/aws_sqs.py b/homeassistant/components/notify/aws_sqs.py index 84826a2f32f..ecbadac46ce 100644 --- a/homeassistant/components/notify/aws_sqs.py +++ b/homeassistant/components/notify/aws_sqs.py @@ -32,7 +32,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ }) -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the AWS SQS notification service.""" # pylint: disable=import-error import boto3 diff --git a/homeassistant/components/notify/command_line.py b/homeassistant/components/notify/command_line.py index d59994e37ed..cd3bdfb16f3 100644 --- a/homeassistant/components/notify/command_line.py +++ b/homeassistant/components/notify/command_line.py @@ -22,7 +22,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ }) -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the Command Line notification service.""" command = config[CONF_COMMAND] diff --git a/homeassistant/components/notify/demo.py b/homeassistant/components/notify/demo.py index d3c4f9b8026..5b8e1f1688f 100644 --- a/homeassistant/components/notify/demo.py +++ b/homeassistant/components/notify/demo.py @@ -9,7 +9,7 @@ from homeassistant.components.notify import BaseNotificationService EVENT_NOTIFY = "notify" -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the demo notification service.""" return DemoNotificationService(hass) diff --git a/homeassistant/components/notify/ecobee.py b/homeassistant/components/notify/ecobee.py index befde9271ca..2d64a2d5b47 100644 --- a/homeassistant/components/notify/ecobee.py +++ b/homeassistant/components/notify/ecobee.py @@ -24,7 +24,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ }) -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the Ecobee notification service.""" index = config.get(CONF_INDEX) return EcobeeNotificationService(index) diff --git a/homeassistant/components/notify/file.py b/homeassistant/components/notify/file.py index 6b435ace6d4..749a6d4b330 100644 --- a/homeassistant/components/notify/file.py +++ b/homeassistant/components/notify/file.py @@ -25,7 +25,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ _LOGGER = logging.getLogger(__name__) -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the file notification service.""" filename = config[CONF_FILENAME] timestamp = config[CONF_TIMESTAMP] diff --git a/homeassistant/components/notify/free_mobile.py b/homeassistant/components/notify/free_mobile.py index d8631fe6106..74d9a80ad86 100644 --- a/homeassistant/components/notify/free_mobile.py +++ b/homeassistant/components/notify/free_mobile.py @@ -23,7 +23,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ }) -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the Free Mobile SMS notification service.""" return FreeSMSNotificationService(config[CONF_USERNAME], config[CONF_ACCESS_TOKEN]) diff --git a/homeassistant/components/notify/gntp.py b/homeassistant/components/notify/gntp.py index ee6d203a47a..5aaaf64577c 100644 --- a/homeassistant/components/notify/gntp.py +++ b/homeassistant/components/notify/gntp.py @@ -39,7 +39,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ }) -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the GNTP notification service.""" if config.get(CONF_APP_ICON) is None: icon_file = os.path.join(os.path.dirname(__file__), "..", "frontend", diff --git a/homeassistant/components/notify/group.py b/homeassistant/components/notify/group.py index d4c10ac884d..3de79f5a7be 100644 --- a/homeassistant/components/notify/group.py +++ b/homeassistant/components/notify/group.py @@ -38,13 +38,13 @@ def update(input_dict, update_source): return input_dict -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the Group notification service.""" return GroupNotifyPlatform(hass, config.get(CONF_SERVICES)) class GroupNotifyPlatform(BaseNotificationService): - """Implement the notification service for the group notify playform.""" + """Implement the notification service for the group notify platform.""" def __init__(self, hass, entities): """Initialize the service.""" diff --git a/homeassistant/components/notify/html5.py b/homeassistant/components/notify/html5.py index 6621b4be6ab..dbd698fd5a2 100644 --- a/homeassistant/components/notify/html5.py +++ b/homeassistant/components/notify/html5.py @@ -97,7 +97,7 @@ HTML5_SHOWNOTIFICATION_PARAMETERS = ('actions', 'badge', 'body', 'dir', 'vibrate') -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the HTML5 push notification service.""" json_path = hass.config.path(REGISTRATIONS_FILE) diff --git a/homeassistant/components/notify/instapush.py b/homeassistant/components/notify/instapush.py index d5f32d66a5e..1af08420726 100644 --- a/homeassistant/components/notify/instapush.py +++ b/homeassistant/components/notify/instapush.py @@ -32,7 +32,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ }) -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the Instapush notification service.""" headers = {'x-instapush-appid': config[CONF_API_KEY], 'x-instapush-appsecret': config[CONF_APP_SECRET]} diff --git a/homeassistant/components/notify/ios.py b/homeassistant/components/notify/ios.py index 5cd18640487..0db05b261b3 100644 --- a/homeassistant/components/notify/ios.py +++ b/homeassistant/components/notify/ios.py @@ -39,7 +39,7 @@ def log_rate_limits(target, resp, level=20): str(resetsAtTime).split(".")[0]) -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the iOS notification service.""" if "notify.ios" not in hass.config.components: # Need this to enable requirements checking in the app. diff --git a/homeassistant/components/notify/joaoapps_join.py b/homeassistant/components/notify/joaoapps_join.py index 6f0afddcca2..f79c7186359 100644 --- a/homeassistant/components/notify/joaoapps_join.py +++ b/homeassistant/components/notify/joaoapps_join.py @@ -27,7 +27,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ # pylint: disable=unused-variable -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the Join notification service.""" device_id = config.get(CONF_DEVICE_ID) api_key = config.get(CONF_API_KEY) diff --git a/homeassistant/components/notify/kodi.py b/homeassistant/components/notify/kodi.py index 1d95920d00b..0c648be5969 100644 --- a/homeassistant/components/notify/kodi.py +++ b/homeassistant/components/notify/kodi.py @@ -29,7 +29,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ ATTR_DISPLAYTIME = 'displaytime' -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Return the notify service.""" url = '{}:{}'.format(config.get(CONF_HOST), config.get(CONF_PORT)) diff --git a/homeassistant/components/notify/llamalab_automate.py b/homeassistant/components/notify/llamalab_automate.py index e7b6ab80455..bf000171c12 100644 --- a/homeassistant/components/notify/llamalab_automate.py +++ b/homeassistant/components/notify/llamalab_automate.py @@ -20,13 +20,13 @@ CONF_DEVICE = 'device' _RESOURCE = 'https://llamalab.com/automate/cloud/message' PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ - vol.Required(CONF_API_KEY): cv.string, - vol.Required(CONF_TO): cv.string, - vol.Optional(CONF_DEVICE): cv.string, + vol.Required(CONF_API_KEY): cv.string, + vol.Required(CONF_TO): cv.string, + vol.Optional(CONF_DEVICE): cv.string, }) -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the LlamaLab Automate notification service.""" secret = config.get(CONF_API_KEY) recipient = config.get(CONF_TO) diff --git a/homeassistant/components/notify/matrix.py b/homeassistant/components/notify/matrix.py index b7ce54f8838..b36721e8f80 100644 --- a/homeassistant/components/notify/matrix.py +++ b/homeassistant/components/notify/matrix.py @@ -34,7 +34,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ _LOGGER = logging.getLogger(__name__) -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the Matrix notification service.""" if not AUTH_TOKENS: load_token(hass.config.path(SESSION_FILE)) diff --git a/homeassistant/components/notify/message_bird.py b/homeassistant/components/notify/message_bird.py index 6d1d50d8a1a..7e9ce3b093f 100644 --- a/homeassistant/components/notify/message_bird.py +++ b/homeassistant/components/notify/message_bird.py @@ -25,7 +25,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ # pylint: disable=unused-argument -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the MessageBird notification service.""" import messagebird diff --git a/homeassistant/components/notify/mysensors.py b/homeassistant/components/notify/mysensors.py new file mode 100644 index 00000000000..ad747a7ae93 --- /dev/null +++ b/homeassistant/components/notify/mysensors.py @@ -0,0 +1,65 @@ +""" +MySensors notification service. + +For more details about this platform, please refer to the documentation +https://home-assistant.io/components/notify.mysensors/ +""" +from homeassistant.components import mysensors +from homeassistant.components.notify import (ATTR_TARGET, + BaseNotificationService) + + +def get_service(hass, config, discovery_info=None): + """Get the MySensors notification service.""" + if discovery_info is None: + return + platform_devices = [] + gateways = hass.data.get(mysensors.MYSENSORS_GATEWAYS) + if not gateways: + return + + for gateway in gateways: + pres = gateway.const.Presentation + set_req = gateway.const.SetReq + map_sv_types = { + pres.S_INFO: [set_req.V_TEXT], + } + devices = {} + gateway.platform_callbacks.append(mysensors.pf_callback_factory( + map_sv_types, devices, MySensorsNotificationDevice)) + platform_devices.append(devices) + + return MySensorsNotificationService(platform_devices) + + +class MySensorsNotificationDevice(mysensors.MySensorsDeviceEntity): + """Represent a MySensors Notification device.""" + + def send_msg(self, msg): + """Send a message.""" + for sub_msg in [msg[i:i + 25] for i in range(0, len(msg), 25)]: + # Max mysensors payload is 25 bytes. + self.gateway.set_child_value( + self.node_id, self.child_id, self.value_type, sub_msg) + + +class MySensorsNotificationService(BaseNotificationService): + """Implement MySensors notification service.""" + + # pylint: disable=too-few-public-methods + + def __init__(self, platform_devices): + """Initialize the service.""" + self.platform_devices = platform_devices + + def send_message(self, message="", **kwargs): + """Send a message to a user.""" + target_devices = kwargs.get(ATTR_TARGET) + devices = [] + for gw_devs in self.platform_devices: + for device in gw_devs.values(): + if target_devices is None or device.name in target_devices: + devices.append(device) + + for device in devices: + device.send_msg(message) diff --git a/homeassistant/components/notify/nfandroidtv.py b/homeassistant/components/notify/nfandroidtv.py index cd44b1f0cd3..6c4f7e49dde 100644 --- a/homeassistant/components/notify/nfandroidtv.py +++ b/homeassistant/components/notify/nfandroidtv.py @@ -83,7 +83,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ # pylint: disable=unused-argument -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the Notifications for Android TV notification service.""" remoteip = config.get(CONF_IP) duration = config.get(CONF_DURATION) diff --git a/homeassistant/components/notify/nma.py b/homeassistant/components/notify/nma.py index 7a05d08134f..1116b5728fd 100644 --- a/homeassistant/components/notify/nma.py +++ b/homeassistant/components/notify/nma.py @@ -24,7 +24,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ }) -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the NMA notification service.""" parameters = { 'apikey': config[CONF_API_KEY], diff --git a/homeassistant/components/notify/pushbullet.py b/homeassistant/components/notify/pushbullet.py index ec9c7ec4f54..4f50146ac61 100644 --- a/homeassistant/components/notify/pushbullet.py +++ b/homeassistant/components/notify/pushbullet.py @@ -25,7 +25,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ # pylint: disable=unused-argument -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the PushBullet notification service.""" from pushbullet import PushBullet from pushbullet import InvalidKeyError diff --git a/homeassistant/components/notify/pushetta.py b/homeassistant/components/notify/pushetta.py index b786fb5ba98..b1a71c57513 100644 --- a/homeassistant/components/notify/pushetta.py +++ b/homeassistant/components/notify/pushetta.py @@ -27,7 +27,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ }) -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the Pushetta notification service.""" pushetta_service = PushettaNotificationService(config[CONF_API_KEY], config[CONF_CHANNEL_NAME], diff --git a/homeassistant/components/notify/pushover.py b/homeassistant/components/notify/pushover.py index c77e5f7b85e..afaf4e6a7e9 100644 --- a/homeassistant/components/notify/pushover.py +++ b/homeassistant/components/notify/pushover.py @@ -27,7 +27,7 @@ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ # pylint: disable=unused-variable -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the Pushover notification service.""" from pushover import InitError diff --git a/homeassistant/components/notify/rest.py b/homeassistant/components/notify/rest.py index 20dbb4afaa1..41d100b3a09 100644 --- a/homeassistant/components/notify/rest.py +++ b/homeassistant/components/notify/rest.py @@ -39,7 +39,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ _LOGGER = logging.getLogger(__name__) -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the RESTful notification service.""" resource = config.get(CONF_RESOURCE) method = config.get(CONF_METHOD) diff --git a/homeassistant/components/notify/sendgrid.py b/homeassistant/components/notify/sendgrid.py index 54f0f4b8cb3..458113d1cdf 100644 --- a/homeassistant/components/notify/sendgrid.py +++ b/homeassistant/components/notify/sendgrid.py @@ -25,7 +25,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ }) -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the SendGrid notification service.""" api_key = config.get(CONF_API_KEY) sender = config.get(CONF_SENDER) diff --git a/homeassistant/components/notify/simplepush.py b/homeassistant/components/notify/simplepush.py index b3c2686f3aa..cda6a6952e0 100644 --- a/homeassistant/components/notify/simplepush.py +++ b/homeassistant/components/notify/simplepush.py @@ -25,7 +25,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ }) -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the Simplepush notification service.""" return SimplePushNotificationService(config.get(CONF_DEVICE_KEY)) diff --git a/homeassistant/components/notify/slack.py b/homeassistant/components/notify/slack.py index 2976b44d6e9..90944cbd308 100644 --- a/homeassistant/components/notify/slack.py +++ b/homeassistant/components/notify/slack.py @@ -29,7 +29,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ # pylint: disable=unused-variable -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the Slack notification service.""" import slacker diff --git a/homeassistant/components/notify/smtp.py b/homeassistant/components/notify/smtp.py index 6ef9bc32990..45b477cdfb8 100644 --- a/homeassistant/components/notify/smtp.py +++ b/homeassistant/components/notify/smtp.py @@ -47,7 +47,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ }) -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the mail notification service.""" mail_service = MailNotificationService( config.get(CONF_SERVER), diff --git a/homeassistant/components/notify/syslog.py b/homeassistant/components/notify/syslog.py index 4065b47f480..31689bdc9f0 100644 --- a/homeassistant/components/notify/syslog.py +++ b/homeassistant/components/notify/syslog.py @@ -67,7 +67,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ _LOGGER = logging.getLogger(__name__) -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the syslog notification service.""" import syslog diff --git a/homeassistant/components/notify/telegram.py b/homeassistant/components/notify/telegram.py index c133506e775..fd901016fc5 100644 --- a/homeassistant/components/notify/telegram.py +++ b/homeassistant/components/notify/telegram.py @@ -37,7 +37,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ }) -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the Telegram notification service.""" import telegram diff --git a/homeassistant/components/notify/telstra.py b/homeassistant/components/notify/telstra.py index ca727db9711..efe90dc51ba 100644 --- a/homeassistant/components/notify/telstra.py +++ b/homeassistant/components/notify/telstra.py @@ -27,7 +27,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ }) -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the Telstra SMS API notification service.""" consumer_key = config.get(CONF_CONSUMER_KEY) consumer_secret = config.get(CONF_CONSUMER_SECRET) diff --git a/homeassistant/components/notify/twilio_sms.py b/homeassistant/components/notify/twilio_sms.py index 3438ce92ee3..950e0eed221 100644 --- a/homeassistant/components/notify/twilio_sms.py +++ b/homeassistant/components/notify/twilio_sms.py @@ -28,7 +28,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ }) -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the Twilio SMS notification service.""" # pylint: disable=import-error from twilio.rest import TwilioRestClient diff --git a/homeassistant/components/notify/twitter.py b/homeassistant/components/notify/twitter.py index afa43057fa5..24128edd880 100644 --- a/homeassistant/components/notify/twitter.py +++ b/homeassistant/components/notify/twitter.py @@ -29,7 +29,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ }) -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the Twitter notification service.""" return TwitterNotificationService( config[CONF_CONSUMER_KEY], config[CONF_CONSUMER_SECRET], diff --git a/homeassistant/components/notify/webostv.py b/homeassistant/components/notify/webostv.py index 9b6514559ca..815e2ff750a 100644 --- a/homeassistant/components/notify/webostv.py +++ b/homeassistant/components/notify/webostv.py @@ -24,7 +24,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ }) -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Return the notify service.""" from pylgtv import WebOsClient from pylgtv import PyLGTVPairException diff --git a/homeassistant/components/notify/xmpp.py b/homeassistant/components/notify/xmpp.py index 5873e3997fa..27bfd2aa607 100644 --- a/homeassistant/components/notify/xmpp.py +++ b/homeassistant/components/notify/xmpp.py @@ -30,7 +30,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ }) -def get_service(hass, config): +def get_service(hass, config, discovery_info=None): """Get the Jabber (XMPP) notification service.""" return XmppNotificationService( config.get('sender'), diff --git a/homeassistant/components/sensor/mysensors.py b/homeassistant/components/sensor/mysensors.py index 2742713cb24..6c1f65606da 100644 --- a/homeassistant/components/sensor/mysensors.py +++ b/homeassistant/components/sensor/mysensors.py @@ -83,7 +83,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): devices = {} gateway.platform_callbacks.append(mysensors.pf_callback_factory( - map_sv_types, devices, add_devices, MySensorsSensor)) + map_sv_types, devices, MySensorsSensor, add_devices)) class MySensorsSensor(mysensors.MySensorsDeviceEntity, Entity): diff --git a/homeassistant/components/switch/mysensors.py b/homeassistant/components/switch/mysensors.py index 44bbfcb16d9..968166d4d65 100644 --- a/homeassistant/components/switch/mysensors.py +++ b/homeassistant/components/switch/mysensors.py @@ -89,7 +89,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): devices = {} gateway.platform_callbacks.append(mysensors.pf_callback_factory( - map_sv_types, devices, add_devices, device_class_map)) + map_sv_types, devices, device_class_map, add_devices)) platform_devices.append(devices) def send_ir_code_service(service): diff --git a/tests/common.py b/tests/common.py index 25a674dd995..514a4973202 100644 --- a/tests/common.py +++ b/tests/common.py @@ -399,7 +399,7 @@ def assert_setup_component(count, domain=None): Use as a context manager aroung bootstrap.setup_component with assert_setup_component(0) as result_config: - setup_component(hass, start_config, domain) + setup_component(hass, domain, start_config) # using result_config is optional """ config = {} diff --git a/tests/components/notify/test_apns.py b/tests/components/notify/test_apns.py index e0363f2d8b8..6949863280c 100644 --- a/tests/components/notify/test_apns.py +++ b/tests/components/notify/test_apns.py @@ -1,14 +1,26 @@ """The tests for the APNS component.""" -import unittest import os +import unittest +from unittest.mock import patch +from unittest.mock import Mock + +from apns2.errors import Unregistered import homeassistant.components.notify as notify -from homeassistant.core import State +from homeassistant.bootstrap import setup_component from homeassistant.components.notify.apns import ApnsNotificationService -from tests.common import get_test_home_assistant from homeassistant.config import load_yaml_config_file -from unittest.mock import patch -from apns2.errors import Unregistered +from homeassistant.core import State +from tests.common import assert_setup_component, get_test_home_assistant + +CONFIG = { + notify.DOMAIN: { + 'platform': 'apns', + 'name': 'test_app', + 'topic': 'testapp.appname', + 'cert_file': 'test_app.pem' + } +} class TestApns(unittest.TestCase): @@ -22,6 +34,13 @@ class TestApns(unittest.TestCase): """Stop everything that was started.""" self.hass.stop() + @patch('os.path.isfile', Mock(return_value=True)) + @patch('os.access', Mock(return_value=True)) + def _setup_notify(self): + with assert_setup_component(1) as handle_config: + assert setup_component(self.hass, notify.DOMAIN, CONFIG) + assert handle_config[notify.DOMAIN] + def test_apns_setup_full(self): """Test setup with all data.""" config = { @@ -41,53 +60,49 @@ class TestApns(unittest.TestCase): config = { 'notify': { 'platform': 'apns', - 'sandbox': 'True', 'topic': 'testapp.appname', - 'cert_file': 'test_app.pem' + 'cert_file': 'test_app.pem', } } - self.assertFalse(notify.setup(self.hass, config)) + with assert_setup_component(0) as handle_config: + assert setup_component(self.hass, notify.DOMAIN, config) + assert not handle_config[notify.DOMAIN] def test_apns_setup_missing_certificate(self): - """Test setup with missing name.""" + """Test setup with missing certificate.""" config = { 'notify': { 'platform': 'apns', + 'name': 'test_app', 'topic': 'testapp.appname', - 'name': 'test_app' } } - self.assertFalse(notify.setup(self.hass, config)) + with assert_setup_component(0) as handle_config: + assert setup_component(self.hass, notify.DOMAIN, config) + assert not handle_config[notify.DOMAIN] def test_apns_setup_missing_topic(self): """Test setup with missing topic.""" config = { 'notify': { 'platform': 'apns', + 'name': 'test_app', 'cert_file': 'test_app.pem', - 'name': 'test_app' } } - self.assertFalse(notify.setup(self.hass, config)) + with assert_setup_component(0) as handle_config: + assert setup_component(self.hass, notify.DOMAIN, config) + assert not handle_config[notify.DOMAIN] def test_register_new_device(self): """Test registering a new device with a name.""" - config = { - 'notify': { - 'platform': 'apns', - 'name': 'test_app', - 'topic': 'testapp.appname', - 'cert_file': 'test_app.pem' - } - } - devices_path = self.hass.config.path('test_app_apns.yaml') with open(devices_path, 'w+') as out: out.write('5678: {name: test device 2}\n') - notify.setup(self.hass, config) - self.assertTrue(self.hass.services.call('apns', - 'test_app', + self._setup_notify() + self.assertTrue(self.hass.services.call(notify.DOMAIN, + 'apns_test_app', {'push_id': '1234', 'name': 'test device'}, blocking=True)) @@ -107,21 +122,12 @@ class TestApns(unittest.TestCase): def test_register_device_without_name(self): """Test registering a without a name.""" - config = { - 'notify': { - 'platform': 'apns', - 'name': 'test_app', - 'topic': 'testapp.appname', - 'cert_file': 'test_app.pem' - } - } - devices_path = self.hass.config.path('test_app_apns.yaml') with open(devices_path, 'w+') as out: out.write('5678: {name: test device 2}\n') - notify.setup(self.hass, config) - self.assertTrue(self.hass.services.call('apns', 'test_app', + self._setup_notify() + self.assertTrue(self.hass.services.call(notify.DOMAIN, 'apns_test_app', {'push_id': '1234'}, blocking=True)) @@ -137,23 +143,14 @@ class TestApns(unittest.TestCase): def test_update_existing_device(self): """Test updating an existing device.""" - config = { - 'notify': { - 'platform': 'apns', - 'name': 'test_app', - 'topic': 'testapp.appname', - 'cert_file': 'test_app.pem' - } - } - devices_path = self.hass.config.path('test_app_apns.yaml') with open(devices_path, 'w+') as out: out.write('1234: {name: test device 1}\n') out.write('5678: {name: test device 2}\n') - notify.setup(self.hass, config) - self.assertTrue(self.hass.services.call('apns', - 'test_app', + self._setup_notify() + self.assertTrue(self.hass.services.call(notify.DOMAIN, + 'apns_test_app', {'push_id': '1234', 'name': 'updated device 1'}, blocking=True)) @@ -173,15 +170,6 @@ class TestApns(unittest.TestCase): def test_update_existing_device_with_tracking_id(self): """Test updating an existing device that has a tracking id.""" - config = { - 'notify': { - 'platform': 'apns', - 'name': 'test_app', - 'topic': 'testapp.appname', - 'cert_file': 'test_app.pem' - } - } - devices_path = self.hass.config.path('test_app_apns.yaml') with open(devices_path, 'w+') as out: out.write('1234: {name: test device 1, ' @@ -189,9 +177,9 @@ class TestApns(unittest.TestCase): out.write('5678: {name: test device 2, ' 'tracking_device_id: tracking456}\n') - notify.setup(self.hass, config) - self.assertTrue(self.hass.services.call('apns', - 'test_app', + self._setup_notify() + self.assertTrue(self.hass.services.call(notify.DOMAIN, + 'apns_test_app', {'push_id': '1234', 'name': 'updated device 1'}, blocking=True)) @@ -216,30 +204,20 @@ class TestApns(unittest.TestCase): def test_send(self, mock_client): """Test updating an existing device.""" send = mock_client.return_value.send_notification - config = { - 'notify': { - 'platform': 'apns', - 'name': 'test_app', - 'topic': 'testapp.appname', - 'cert_file': 'test_app.pem' - } - } devices_path = self.hass.config.path('test_app_apns.yaml') with open(devices_path, 'w+') as out: out.write('1234: {name: test device 1}\n') - notify.setup(self.hass, config) + self._setup_notify() - self.assertTrue(self.hass.services.call('notify', 'test_app', - {'message': 'Hello', - 'data': { - 'badge': 1, - 'sound': 'test.mp3', - 'category': 'testing' - } - }, - blocking=True)) + self.assertTrue(self.hass.services.call( + 'notify', 'test_app', + {'message': 'Hello', 'data': { + 'badge': 1, + 'sound': 'test.mp3', + 'category': 'testing'}}, + blocking=True)) self.assertTrue(send.called) self.assertEqual(1, len(send.mock_calls)) @@ -257,30 +235,20 @@ class TestApns(unittest.TestCase): def test_send_when_disabled(self, mock_client): """Test updating an existing device.""" send = mock_client.return_value.send_notification - config = { - 'notify': { - 'platform': 'apns', - 'name': 'test_app', - 'topic': 'testapp.appname', - 'cert_file': 'test_app.pem' - } - } devices_path = self.hass.config.path('test_app_apns.yaml') with open(devices_path, 'w+') as out: out.write('1234: {name: test device 1, disabled: True}\n') - notify.setup(self.hass, config) + self._setup_notify() - self.assertTrue(self.hass.services.call('notify', 'test_app', - {'message': 'Hello', - 'data': { - 'badge': 1, - 'sound': 'test.mp3', - 'category': 'testing' - } - }, - blocking=True)) + self.assertTrue(self.hass.services.call( + 'notify', 'test_app', + {'message': 'Hello', 'data': { + 'badge': 1, + 'sound': 'test.mp3', + 'category': 'testing'}}, + blocking=True)) self.assertFalse(send.called) @@ -328,20 +296,11 @@ class TestApns(unittest.TestCase): send = mock_client.return_value.send_notification send.side_effect = Unregistered() - config = { - 'notify': { - 'platform': 'apns', - 'name': 'test_app', - 'topic': 'testapp.appname', - 'cert_file': 'test_app.pem' - } - } - devices_path = self.hass.config.path('test_app_apns.yaml') with open(devices_path, 'w+') as out: out.write('1234: {name: test device 1}\n') - notify.setup(self.hass, config) + self._setup_notify() self.assertTrue(self.hass.services.call('notify', 'test_app', {'message': 'Hello'}, diff --git a/tests/components/notify/test_command_line.py b/tests/components/notify/test_command_line.py index 0d2235514f8..cebcd2a13fb 100644 --- a/tests/components/notify/test_command_line.py +++ b/tests/components/notify/test_command_line.py @@ -6,7 +6,7 @@ from unittest.mock import patch from homeassistant.bootstrap import setup_component import homeassistant.components.notify as notify -from tests.common import get_test_home_assistant +from tests.common import assert_setup_component, get_test_home_assistant class TestCommandLine(unittest.TestCase): @@ -22,34 +22,41 @@ class TestCommandLine(unittest.TestCase): def test_setup(self): """Test setup.""" - assert setup_component(self.hass, 'notify', { - 'notify': { - 'name': 'test', - 'platform': 'command_line', - 'command': 'echo $(cat); exit 1', - }}) + with assert_setup_component(1) as handle_config: + assert setup_component(self.hass, 'notify', { + 'notify': { + 'name': 'test', + 'platform': 'command_line', + 'command': 'echo $(cat); exit 1', } + }) + assert handle_config[notify.DOMAIN] def test_bad_config(self): """Test set up the platform with bad/missing configuration.""" - self.assertFalse(setup_component(self.hass, notify.DOMAIN, { - 'notify': { + config = { + notify.DOMAIN: { 'name': 'test', - 'platform': 'bad_platform', + 'platform': 'command_line', } - })) + } + with assert_setup_component(0) as handle_config: + assert setup_component(self.hass, notify.DOMAIN, config) + assert not handle_config[notify.DOMAIN] def test_command_line_output(self): """Test the command line output.""" with tempfile.TemporaryDirectory() as tempdirname: filename = os.path.join(tempdirname, 'message.txt') message = 'one, two, testing, testing' - self.assertTrue(setup_component(self.hass, notify.DOMAIN, { - 'notify': { - 'name': 'test', - 'platform': 'command_line', - 'command': 'echo $(cat) > {}'.format(filename) - } - })) + with assert_setup_component(1) as handle_config: + self.assertTrue(setup_component(self.hass, notify.DOMAIN, { + 'notify': { + 'name': 'test', + 'platform': 'command_line', + 'command': 'echo $(cat) > {}'.format(filename) + } + })) + assert handle_config[notify.DOMAIN] self.assertTrue( self.hass.services.call('notify', 'test', {'message': message}, @@ -63,13 +70,15 @@ class TestCommandLine(unittest.TestCase): @patch('homeassistant.components.notify.command_line._LOGGER.error') def test_error_for_none_zero_exit_code(self, mock_error): """Test if an error is logged for non zero exit codes.""" - self.assertTrue(setup_component(self.hass, notify.DOMAIN, { - 'notify': { - 'name': 'test', - 'platform': 'command_line', - 'command': 'echo $(cat); exit 1' - } - })) + with assert_setup_component(1) as handle_config: + self.assertTrue(setup_component(self.hass, notify.DOMAIN, { + 'notify': { + 'name': 'test', + 'platform': 'command_line', + 'command': 'echo $(cat); exit 1' + } + })) + assert handle_config[notify.DOMAIN] self.assertTrue( self.hass.services.call('notify', 'test', {'message': 'error'}, diff --git a/tests/components/notify/test_demo.py b/tests/components/notify/test_demo.py index ddf08d91127..1ccb3f5c56d 100644 --- a/tests/components/notify/test_demo.py +++ b/tests/components/notify/test_demo.py @@ -1,13 +1,19 @@ """The tests for the notify demo platform.""" import unittest +from unittest.mock import patch -from homeassistant.core import callback -from homeassistant.bootstrap import setup_component import homeassistant.components.notify as notify +from homeassistant.bootstrap import setup_component from homeassistant.components.notify import demo -from homeassistant.helpers import script +from homeassistant.core import callback +from homeassistant.helpers import discovery, script +from tests.common import assert_setup_component, get_test_home_assistant -from tests.common import get_test_home_assistant +CONFIG = { + notify.DOMAIN: { + 'platform': 'demo' + } +} class TestNotifyDemo(unittest.TestCase): @@ -16,11 +22,6 @@ class TestNotifyDemo(unittest.TestCase): def setUp(self): # pylint: disable=invalid-name """Setup things to be run when tests are started.""" self.hass = get_test_home_assistant() - self.assertTrue(setup_component(self.hass, notify.DOMAIN, { - 'notify': { - 'platform': 'demo' - } - })) self.events = [] self.calls = [] @@ -35,6 +36,59 @@ class TestNotifyDemo(unittest.TestCase): """"Stop down everything that was started.""" self.hass.stop() + def _setup_notify(self): + with assert_setup_component(1) as config: + assert setup_component(self.hass, notify.DOMAIN, CONFIG) + assert config[notify.DOMAIN] + + def test_setup(self): + """Test setup.""" + self._setup_notify() + + @patch('homeassistant.bootstrap.prepare_setup_platform') + def test_no_prepare_setup_platform(self, mock_prep_setup_platform): + """Test missing notify platform.""" + mock_prep_setup_platform.return_value = None + with self.assertLogs('homeassistant.components.notify', + level='ERROR') as log_handle: + self._setup_notify() + self.hass.block_till_done() + assert mock_prep_setup_platform.called + self.assertEqual( + log_handle.output, + ['ERROR:homeassistant.components.notify:' + 'Unknown notification service specified', + 'ERROR:homeassistant.components.notify:' + 'Failed to set up platform demo']) + + @patch('homeassistant.components.notify.demo.get_service') + def test_no_notify_service(self, mock_demo_get_service): + """Test missing platform notify service instance.""" + mock_demo_get_service.return_value = None + with self.assertLogs('homeassistant.components.notify', + level='ERROR') as log_handle: + self._setup_notify() + self.hass.block_till_done() + assert mock_demo_get_service.called + self.assertEqual( + log_handle.output, + ['ERROR:homeassistant.components.notify:' + 'Failed to initialize notification service demo', + 'ERROR:homeassistant.components.notify:' + 'Failed to set up platform demo']) + + @patch('homeassistant.components.notify.demo.get_service') + def test_discover_notify(self, mock_demo_get_service): + """Test discovery of notify demo platform.""" + assert notify.DOMAIN not in self.hass.config.components + discovery.load_platform( + self.hass, 'notify', 'demo', {'test_key': 'test_val'}, {}) + self.hass.block_till_done() + assert notify.DOMAIN in self.hass.config.components + assert mock_demo_get_service.called + assert mock_demo_get_service.call_args[0] == ( + self.hass, {}, {'test_key': 'test_val'}) + @callback def record_calls(self, *args): """Helper for recording calls.""" @@ -42,12 +96,14 @@ class TestNotifyDemo(unittest.TestCase): def test_sending_none_message(self): """Test send with None as message.""" + self._setup_notify() notify.send_message(self.hass, None) self.hass.block_till_done() self.assertTrue(len(self.events) == 0) def test_sending_templated_message(self): """Send a templated message.""" + self._setup_notify() self.hass.states.set('sensor.temperature', 10) notify.send_message(self.hass, '{{ states.sensor.temperature.state }}', '{{ states.sensor.temperature.name }}') @@ -58,6 +114,7 @@ class TestNotifyDemo(unittest.TestCase): def test_method_forwards_correct_data(self): """Test that all data from the service gets forwarded to service.""" + self._setup_notify() notify.send_message(self.hass, 'my message', 'my title', {'hello': 'world'}) self.hass.block_till_done() @@ -71,6 +128,7 @@ class TestNotifyDemo(unittest.TestCase): def test_calling_notify_from_script_loaded_from_yaml_without_title(self): """Test if we can call a notify from a script.""" + self._setup_notify() conf = { 'service': 'notify.notify', 'data': { @@ -97,6 +155,7 @@ class TestNotifyDemo(unittest.TestCase): def test_calling_notify_from_script_loaded_from_yaml_with_title(self): """Test if we can call a notify from a script.""" + self._setup_notify() conf = { 'service': 'notify.notify', 'data': { @@ -127,12 +186,14 @@ class TestNotifyDemo(unittest.TestCase): def test_targets_are_services(self): """Test that all targets are exposed as individual services.""" + self._setup_notify() self.assertIsNotNone(self.hass.services.has_service("notify", "demo")) service = "demo_test_target_name" self.assertIsNotNone(self.hass.services.has_service("notify", service)) def test_messages_to_targets_route(self): """Test message routing to specific target services.""" + self._setup_notify() self.hass.bus.listen_once("notify", self.record_calls) self.hass.services.call("notify", "demo_test_target_name", diff --git a/tests/components/notify/test_file.py b/tests/components/notify/test_file.py index 08407b20a58..ea0aaaaa71d 100644 --- a/tests/components/notify/test_file.py +++ b/tests/components/notify/test_file.py @@ -9,7 +9,7 @@ from homeassistant.components.notify import ( ATTR_TITLE_DEFAULT) import homeassistant.util.dt as dt_util -from tests.common import get_test_home_assistant, assert_setup_component +from tests.common import assert_setup_component, get_test_home_assistant class TestNotifyFile(unittest.TestCase): @@ -25,36 +25,38 @@ class TestNotifyFile(unittest.TestCase): def test_bad_config(self): """Test set up the platform with bad/missing config.""" - with assert_setup_component(0): - assert not setup_component(self.hass, notify.DOMAIN, { - 'notify': { - 'name': 'test', - 'platform': 'file', - }, - }) + config = { + notify.DOMAIN: { + 'name': 'test', + 'platform': 'file', + }, + } + with assert_setup_component(0) as handle_config: + assert setup_component(self.hass, notify.DOMAIN, config) + assert not handle_config[notify.DOMAIN] - @patch('homeassistant.components.notify.file.os.stat') - @patch('homeassistant.util.dt.utcnow') - def test_notify_file(self, mock_utcnow, mock_stat): + def _test_notify_file(self, timestamp, mock_utcnow, mock_stat): """Test the notify file output.""" mock_utcnow.return_value = dt_util.as_utc(dt_util.now()) mock_stat.return_value.st_size = 0 m_open = mock_open() with patch( - 'homeassistant.components.notify.file.open', - m_open, create=True + 'homeassistant.components.notify.file.open', + m_open, create=True ): filename = 'mock_file' message = 'one, two, testing, testing' - self.assertTrue(setup_component(self.hass, notify.DOMAIN, { - 'notify': { - 'name': 'test', - 'platform': 'file', - 'filename': filename, - 'timestamp': False, - } - })) + with assert_setup_component(1) as handle_config: + self.assertTrue(setup_component(self.hass, notify.DOMAIN, { + 'notify': { + 'name': 'test', + 'platform': 'file', + 'filename': filename, + 'timestamp': timestamp, + } + })) + assert handle_config[notify.DOMAIN] title = '{} notifications (Log started: {})\n{}\n'.format( ATTR_TITLE_DEFAULT, dt_util.utcnow().isoformat(), @@ -68,7 +70,26 @@ class TestNotifyFile(unittest.TestCase): self.assertEqual(m_open.call_args, call(full_filename, 'a')) self.assertEqual(m_open.return_value.write.call_count, 2) - self.assertEqual( - m_open.return_value.write.call_args_list, - [call(title), call(message + '\n')] - ) + if not timestamp: + self.assertEqual( + m_open.return_value.write.call_args_list, + [call(title), call('{}\n'.format(message))] + ) + else: + self.assertEqual( + m_open.return_value.write.call_args_list, + [call(title), call('{} {}\n'.format( + dt_util.utcnow().isoformat(), message))] + ) + + @patch('homeassistant.components.notify.file.os.stat') + @patch('homeassistant.util.dt.utcnow') + def test_notify_file(self, mock_utcnow, mock_stat): + """Test the notify file output without timestamp.""" + self._test_notify_file(False, mock_utcnow, mock_stat) + + @patch('homeassistant.components.notify.file.os.stat') + @patch('homeassistant.util.dt.utcnow') + def test_notify_file_timestamp(self, mock_utcnow, mock_stat): + """Test the notify file output with timestamp.""" + self._test_notify_file(True, mock_utcnow, mock_stat) diff --git a/tests/components/notify/test_group.py b/tests/components/notify/test_group.py index f0871c78322..14c8c46b6c3 100644 --- a/tests/components/notify/test_group.py +++ b/tests/components/notify/test_group.py @@ -19,7 +19,7 @@ class TestNotifyGroup(unittest.TestCase): self.service1 = MagicMock() self.service2 = MagicMock() - def mock_get_service(hass, config): + def mock_get_service(hass, config, discovery_info=None): if config['name'] == 'demo1': return self.service1 else: