diff --git a/homeassistant/__main__.py b/homeassistant/__main__.py index d7cfd0a2f00..64eca13356a 100644 --- a/homeassistant/__main__.py +++ b/homeassistant/__main__.py @@ -10,7 +10,8 @@ import argparse from homeassistant import bootstrap import homeassistant.config as config_util -from homeassistant.const import __version__, EVENT_HOMEASSISTANT_START +from homeassistant.const import (__version__, EVENT_HOMEASSISTANT_START, + RESTART_EXIT_CODE) def validate_python(): @@ -76,6 +77,11 @@ def get_arguments(): '--demo-mode', action='store_true', help='Start Home Assistant in demo mode') + parser.add_argument( + '--debug', + action='store_true', + help='Start Home Assistant in debug mode. Runs in single process to ' + 'enable use of interactive debuggers.') parser.add_argument( '--open-ui', action='store_true', @@ -207,8 +213,11 @@ def uninstall_osx(): print("Home Assistant has been uninstalled.") -def setup_and_run_hass(config_dir, args): - """ Setup HASS and run. Block until stopped. """ +def setup_and_run_hass(config_dir, args, top_process=False): + """ + Setup HASS and run. Block until stopped. Will assume it is running in a + subprocess unless top_process is set to true. + """ if args.demo_mode: config = { 'frontend': {}, @@ -235,7 +244,11 @@ def setup_and_run_hass(config_dir, args): hass.bus.listen_once(EVENT_HOMEASSISTANT_START, open_browser) hass.start() - sys.exit(int(hass.block_till_stopped())) + exit_code = int(hass.block_till_stopped()) + + if not top_process: + sys.exit(exit_code) + return exit_code def run_hass_process(hass_proc): @@ -262,7 +275,10 @@ def run_hass_process(hass_proc): hass_proc.join() except KeyboardInterrupt: return False - return not requested_stop.isSet() and hass_proc.exitcode == 100 + + return (not requested_stop.isSet() and + hass_proc.exitcode == RESTART_EXIT_CODE, + hass_proc.exitcode) def main(): @@ -277,14 +293,14 @@ def main(): # os x launchd functions if args.install_osx: install_osx() - return + return 0 if args.uninstall_osx: uninstall_osx() - return + return 0 if args.restart_osx: uninstall_osx() install_osx() - return + return 0 # daemon functions if args.pid_file: @@ -294,12 +310,23 @@ def main(): if args.pid_file: write_pid(args.pid_file) + # Run hass in debug mode if requested + if args.debug: + sys.stderr.write('Running in debug mode. ' + 'Home Assistant will not be able to restart.\n') + exit_code = setup_and_run_hass(config_dir, args, top_process=True) + if exit_code == RESTART_EXIT_CODE: + sys.stderr.write('Home Assistant requested a ' + 'restart in debug mode.\n') + return exit_code + # Run hass as child process. Restart if necessary. keep_running = True while keep_running: hass_proc = Process(target=setup_and_run_hass, args=(config_dir, args)) - keep_running = run_hass_process(hass_proc) + keep_running, exit_code = run_hass_process(hass_proc) + return exit_code if __name__ == "__main__": - main() + sys.exit(main()) diff --git a/homeassistant/const.py b/homeassistant/const.py index cd711df44cd..42146895a01 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -197,3 +197,6 @@ HTTP_HEADER_EXPIRES = "Expires" CONTENT_TYPE_JSON = "application/json" CONTENT_TYPE_MULTIPART = 'multipart/x-mixed-replace; boundary={}' CONTENT_TYPE_TEXT_PLAIN = 'text/plain' + +# The exit code to send to request a restart +RESTART_EXIT_CODE = 100 diff --git a/homeassistant/core.py b/homeassistant/core.py index 936a068480f..c4dbd1562a5 100644 --- a/homeassistant/core.py +++ b/homeassistant/core.py @@ -20,7 +20,8 @@ from homeassistant.const import ( EVENT_TIME_CHANGED, EVENT_STATE_CHANGED, EVENT_CALL_SERVICE, ATTR_NOW, ATTR_DOMAIN, ATTR_SERVICE, MATCH_ALL, EVENT_SERVICE_EXECUTED, ATTR_SERVICE_CALL_ID, EVENT_SERVICE_REGISTERED, - TEMP_CELCIUS, TEMP_FAHRENHEIT, ATTR_FRIENDLY_NAME, ATTR_SERVICE_DATA) + TEMP_CELCIUS, TEMP_FAHRENHEIT, ATTR_FRIENDLY_NAME, ATTR_SERVICE_DATA, + RESTART_EXIT_CODE) from homeassistant.exceptions import ( HomeAssistantError, InvalidEntityFormatError) import homeassistant.util as util @@ -48,9 +49,6 @@ _LOGGER = logging.getLogger(__name__) # Temporary to support deprecated methods _MockHA = namedtuple("MockHomeAssistant", ['bus']) -# The exit code to send to request a restart -RESTART_EXIT_CODE = 100 - class HomeAssistant(object): """Root object of the Home Assistant home automation."""