diff --git a/homeassistant/components/camera/dispatcher.py b/homeassistant/components/camera/dispatcher.py new file mode 100644 index 00000000000..b5a846665ad --- /dev/null +++ b/homeassistant/components/camera/dispatcher.py @@ -0,0 +1,67 @@ +""" +Support for internal dispatcher image push to Camera. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/camera.dispatcher/ +""" +import asyncio +import logging + +import voluptuous as vol + +from homeassistant.core import callback +from homeassistant.const import CONF_NAME +from homeassistant.components.camera import PLATFORM_SCHEMA, Camera +from homeassistant.helpers import config_validation as cv +from homeassistant.helpers.dispatcher import async_dispatcher_connect + +_LOGGER = logging.getLogger(__name__) + +CONF_SIGNAL = 'signal' +DEFAULT_NAME = 'Dispatcher Camera' + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_SIGNAL): cv.slugify, + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, +}) + + +@asyncio.coroutine +def async_setup_platform(hass, config, async_add_devices, discovery_info=None): + """Setup a dispatcher camera.""" + if discovery_info: + config = PLATFORM_SCHEMA(discovery_info) + + async_add_devices( + [DispatcherCamera(config[CONF_NAME], config[CONF_SIGNAL])]) + + +class DispatcherCamera(Camera): + """A dispatcher implementation of an camera.""" + + def __init__(self, name, signal): + """Initialize a dispatcher camera.""" + super().__init__() + self._name = name + self._signal = signal + self._image = None + + @asyncio.coroutine + def async_added_to_hass(self): + """Register dispatcher and callbacks.""" + @callback + def async_update_image(image): + """Update image from dispatcher call.""" + self._image = image + + async_dispatcher_connect(self.hass, self._signal, async_update_image) + + @asyncio.coroutine + def async_camera_image(self): + """Return a still image response from the camera.""" + return self._image + + @property + def name(self): + """Return the name of this device.""" + return self._name diff --git a/tests/components/camera/test_dispatcher.py b/tests/components/camera/test_dispatcher.py new file mode 100644 index 00000000000..fad5a3de52f --- /dev/null +++ b/tests/components/camera/test_dispatcher.py @@ -0,0 +1,36 @@ +"""The tests for dispatcher camera component.""" +import asyncio + +from homeassistant.setup import async_setup_component +from homeassistant.helpers.dispatcher import async_dispatcher_send + + +@asyncio.coroutine +def test_run_camera_setup(hass, test_client): + """Test that it fetches the given dispatcher data.""" + yield from async_setup_component(hass, 'camera', { + 'camera': { + 'platform': 'dispatcher', + 'name': 'dispatcher', + 'signal': 'test_camera', + }}) + + client = yield from test_client(hass.http.app) + + async_dispatcher_send(hass, 'test_camera', b'test') + yield from hass.async_block_till_done() + + resp = yield from client.get('/api/camera_proxy/camera.dispatcher') + + assert resp.status == 200 + body = yield from resp.text() + assert body == 'test' + + async_dispatcher_send(hass, 'test_camera', b'test2') + yield from hass.async_block_till_done() + + resp = yield from client.get('/api/camera_proxy/camera.dispatcher') + + assert resp.status == 200 + body = yield from resp.text() + assert body == 'test2'