diff --git a/homeassistant/components/python_script.py b/homeassistant/components/python_script.py index f80dea83944..b33766d84db 100644 --- a/homeassistant/components/python_script.py +++ b/homeassistant/components/python_script.py @@ -6,6 +6,7 @@ import datetime import voluptuous as vol +from homeassistant.const import SERVICE_RELOAD from homeassistant.exceptions import HomeAssistantError from homeassistant.loader import bind_hass from homeassistant.util import sanitize_filename @@ -36,6 +37,24 @@ def setup(hass, config): """Initialize the python_script component.""" path = hass.config.path(FOLDER) + if not os.path.isdir(path): + _LOGGER.warning('Folder %s not found in config folder', FOLDER) + return False + + discover_scripts(hass) + + def reload_scripts_handler(call): + """Handle reload service calls.""" + discover_scripts(hass) + hass.services.register(DOMAIN, SERVICE_RELOAD, reload_scripts_handler) + + return True + + +def discover_scripts(hass): + """Discover python scripts in folder.""" + path = hass.config.path(FOLDER) + if not os.path.isdir(path): _LOGGER.warning('Folder %s not found in config folder', FOLDER) return False @@ -44,12 +63,16 @@ def setup(hass, config): """Handle python script service calls.""" execute_script(hass, call.service, call.data) + existing = hass.services.services.get(DOMAIN, {}).keys() + for existing_service in existing: + if existing_service == SERVICE_RELOAD: + continue + hass.services.remove(DOMAIN, existing_service) + for fil in glob.iglob(os.path.join(path, '*.py')): name = os.path.splitext(os.path.basename(fil))[0] hass.services.register(DOMAIN, name, python_script_service_handler) - return True - @bind_hass def execute_script(hass, name, data=None): diff --git a/tests/components/test_python_script.py b/tests/components/test_python_script.py index 3ff32cc312a..660ed3c1b18 100644 --- a/tests/components/test_python_script.py +++ b/tests/components/test_python_script.py @@ -203,3 +203,38 @@ hass.states.set('hello.ab_list', '{}'.format(ab_list)) # No errors logged = good assert caplog.text == '' + + +@asyncio.coroutine +def test_reload(hass): + """Test we can re-discover scripts.""" + scripts = [ + '/some/config/dir/python_scripts/hello.py', + '/some/config/dir/python_scripts/world_beer.py' + ] + with patch('homeassistant.components.python_script.os.path.isdir', + return_value=True), \ + patch('homeassistant.components.python_script.glob.iglob', + return_value=scripts): + res = yield from async_setup_component(hass, 'python_script', {}) + + assert res + assert hass.services.has_service('python_script', 'hello') + assert hass.services.has_service('python_script', 'world_beer') + assert hass.services.has_service('python_script', 'reload') + + scripts = [ + '/some/config/dir/python_scripts/hello2.py', + '/some/config/dir/python_scripts/world_beer.py' + ] + with patch('homeassistant.components.python_script.os.path.isdir', + return_value=True), \ + patch('homeassistant.components.python_script.glob.iglob', + return_value=scripts): + yield from hass.services.async_call( + 'python_script', 'reload', {}, blocking=True) + + assert not hass.services.has_service('python_script', 'hello') + assert hass.services.has_service('python_script', 'hello2') + assert hass.services.has_service('python_script', 'world_beer') + assert hass.services.has_service('python_script', 'reload')