From 4ff946ac15e8fbe040020b487dbe1a0d9c955974 Mon Sep 17 00:00:00 2001 From: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com> Date: Tue, 12 May 2026 21:52:07 +1000 Subject: [PATCH] [cli] Add --no-states flag to run command (#16366) --- esphome/__main__.py | 7 +++ tests/unit_tests/test_main.py | 95 +++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) diff --git a/esphome/__main__.py b/esphome/__main__.py index ce24f44b3a..988f28a55f 100644 --- a/esphome/__main__.py +++ b/esphome/__main__.py @@ -2170,6 +2170,13 @@ def parse_args(argv): parser_run.add_argument( "--no-logs", help="Disable starting logs.", action="store_true" ) + + parser_run.add_argument( + "--no-states", + action="store_true", + help="Do not show entity state changes in log output.", + ) + parser_run.add_argument( "--reset", "-r", diff --git a/tests/unit_tests/test_main.py b/tests/unit_tests/test_main.py index 3648de443d..0104854e1f 100644 --- a/tests/unit_tests/test_main.py +++ b/tests/unit_tests/test_main.py @@ -30,6 +30,7 @@ from esphome.__main__ import ( command_bundle, command_clean_all, command_rename, + command_run, command_update_all, command_wizard, compile_program, @@ -45,6 +46,7 @@ from esphome.__main__ import ( has_resolvable_address, has_web_server_ota, mqtt_get_ip, + parse_args, run_esphome, run_miniterm, show_logs, @@ -5823,3 +5825,96 @@ def test_upload_using_esptool_subprocess_passes_crystal_callback( call_kwargs = mock_run_external_process.call_args[1] assert "line_callbacks" in call_kwargs assert len(call_kwargs["line_callbacks"]) == 1 + + +def test_parse_args_run_no_states() -> None: + """Test that --no-states is parsed for the run command.""" + args = parse_args(["esphome", "run", "--no-states", "device.yaml"]) + assert args.no_states is True + + +def test_parse_args_run_no_states_default() -> None: + """Test that no_states defaults to False for the run command.""" + args = parse_args(["esphome", "run", "device.yaml"]) + assert args.no_states is False + + +def test_parse_args_logs_no_states() -> None: + """Test that --no-states is parsed for the logs command.""" + args = parse_args(["esphome", "logs", "--no-states", "device.yaml"]) + assert args.no_states is True + + +@patch("esphome.components.api.client.run_logs") +def test_command_run_passes_no_states_to_show_logs( + mock_run_logs: Mock, +) -> None: + """Test that command_run propagates --no-states through to run_logs.""" + setup_core( + config={ + "logger": {}, + CONF_API: {}, + CONF_MDNS: {CONF_DISABLED: False}, + }, + platform=PLATFORM_ESP32, + ) + mock_run_logs.return_value = 0 + + args = MockArgs() + args.no_states = True + args.no_logs = False + args.device = None + + with ( + patch("esphome.__main__.write_cpp", return_value=0), + patch("esphome.__main__.compile_program", return_value=0), + patch( + "esphome.__main__.choose_upload_log_host", + return_value=["192.168.1.100"], + ), + patch("esphome.__main__.upload_program", return_value=(0, "192.168.1.100")), + patch("esphome.__main__.get_serial_ports", return_value=[]), + ): + result = command_run(args, CORE.config) + + assert result == 0 + mock_run_logs.assert_called_once_with( + CORE.config, ["192.168.1.100"], subscribe_states=False + ) + + +@patch("esphome.components.api.client.run_logs") +def test_command_run_defaults_subscribe_states_true( + mock_run_logs: Mock, +) -> None: + """Test that command_run subscribes states by default (no --no-states).""" + setup_core( + config={ + "logger": {}, + CONF_API: {}, + CONF_MDNS: {CONF_DISABLED: False}, + }, + platform=PLATFORM_ESP32, + ) + mock_run_logs.return_value = 0 + + args = MockArgs() + args.no_logs = False + args.device = None + + with ( + patch("esphome.__main__.write_cpp", return_value=0), + patch("esphome.__main__.compile_program", return_value=0), + patch( + "esphome.__main__.choose_upload_log_host", + return_value=["192.168.1.100"], + ), + patch("esphome.__main__.upload_program", return_value=(0, "192.168.1.100")), + patch("esphome.__main__.get_serial_ports", return_value=[]), + ): + result = command_run(args, CORE.config) + + assert result == 0 + mock_run_logs.assert_called_once_with( + CORE.config, ["192.168.1.100"], subscribe_states=True + )