8000 Add discovery notify support and mysensors notify by MartinHjelmare · Pull Request #4014 · home-assistant/core · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
8000

Add discovery notify support and mysensors notify #4014

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

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion homeassistant/components/binary_sensor/mysensors.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/climate/mysensors.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/cover/mysensors.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/light/mysensors.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
25 changes: 16 additions & 9 deletions homeassistant/components/mysensors.py
< 8000 /tr>
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@

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
Expand Down Expand Up @@ -169,10 +169,13 @@ def gw_start(event):
'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."""
Expand All @@ -187,7 +190,10 @@ def mysensors_callback(gateway, node_id):
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].update_ha_state(True)
else:
devices[key].update()
continue
name = '{} {} {}'.format(
gateway.sensors[node_id].sketch_name, node_id, child.id)
Expand All @@ -197,11 +203,12 @@ def mysensors_callback(gateway, node_id):
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:
if add_devices:
_LOGGER.info('Adding new devices: %s', devices[key])
add_devices([devices[key]])
devices[key].update_ha_state(True)
else:
devices[key].update()
return mysensors_callback


Expand Down
32 changes: 24 additions & 8 deletions homeassistant/components/notify/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
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__)
Expand Down Expand Up @@ -66,27 +66,31 @@ def send_message(hass, message, title=None, data=None):

def setup(hass, config):
"""Setup the notify ser AE96 vices."""
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 not None:
p_config = discovery_info
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a good idea, using the passed discovery info directly as config for the platform?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.


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)

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."""
Expand Down Expand Up @@ -127,9 +131,21 @@ def notify_message(notify_service, call):
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):
Expand Down
22 changes: 10 additions & 12 deletions homeassistant/components/notify/apns.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,27 @@
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, PLATFORM_SCHEMA)
from homeassistant.const import (CONF_NAME)
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"
DEVICE_TRACKER_DOMAIN = "device_tracker"
SERVICE_REGISTER = "apns_register"

ATTR_PUSH_ID = "push_id"
ATTR_NAME = "name"

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_CERTFILE): cv.string,
vol.Required(CONF_NAME): cv.string,
vol.Required(CONF_TOPIC): cv.string,
})

REGISTER_SERVICE_SCHEMA = vol.Schema({
vol.Required(ATTR_PUSH_ID): cv.string,
vol.Optional(ATTR_NAME, default=None): cv.string,
Expand All @@ -37,19 +46,8 @@ def get_service(hass, config):
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))

Expand Down
63 changes: 63 additions & 0 deletions homeassistant/components/notify/mysensors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
"""
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):
"""Get the MySensors notification service."""
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 = [
device for gw_devs in self.platform_devices
for device in gw_devs.values()
if target_devices is None or
device.name in target_devices]

for device in devices:
device.send_msg(message)
2 changes: 1 addition & 1 deletion homeassistant/components/sensor/mysensors.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/switch/mysensors.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
2 changes: 1 addition & 1 deletion tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {}
Expand Down
37 changes: 0 additions & 37 deletions tests/components/notify/test_apns.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,43 +29,6 @@ def test_apns_setup_full(self):

self.assertTrue(notify.setup(hass, config))

def test_apns_setup_missing_name(self):
"""Test setup with missing name."""
config = {
'notify': {
'platform': 'apns',
'sandbox': 'True',
'topic': 'testapp.appname',
'cert_file': 'test_app.pem'
}
}
hass = get_test_home_assistant()
self.assertFalse(notify.setup(hass, config))

def test_apns_setup_missing_certificate(self):
"""Test setup with missing name."""
config = {
'notify': {
'platform': 'apns',
'topic': 'testapp.appname',
'name': 'test_app'
}
}
hass = get_test_home_assistant()
self.assertFalse(notify.setup(hass, config))

def test_apns_setup_missing_topic(self):
"""Test setup with missing topic."""
config = {
'notify': {
'platform': 'apns',
'cert_file': 'test_app.pem',
'name': 'test_app'
}
}
hass = get_test_home_assistant()
self.assertFalse(notify.setup(hass, config))

def test_register_new_device(self):
"""Test registering a new device with a name."""
config = {
Expand Down
11 changes: 1 addition & 10 deletions tests/components/notify/test_command_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'assert_setup_component' imported but unused



class TestCommandLine(unittest.TestCase):
Expand All @@ -29,15 +29,6 @@ def test_setup(self):
'command': 'echo $(cat); exit 1',
}})

def test_bad_config(self):
"""Test set up the platform with bad/missing configuration."""
self.assertFalse(setup_component(self.hass, notify.DOMAIN, {
'notify': {
'name': 'test',
'platform': 'bad_platform',
}
}))

def test_command_line_output(self):
"""Test the command line output."""
with tempfile.TemporaryDirectory() as tempdirname:
Expand Down
Loading
0