diff --git a/esphome/__main__.py b/esphome/__main__.py index bda3dcbd05..efed6e6fc2 100644 --- a/esphome/__main__.py +++ b/esphome/__main__.py @@ -1692,6 +1692,11 @@ def command_bundle(args: ArgsProtocol, config: ConfigType) -> int | None: def command_dashboard(args: ArgsProtocol) -> int | None: + _LOGGER.warning( + "The 'dashboard' command is deprecated and will be removed in ESPHome " + "2027.1.0. Install the 'esphome-device-builder' package and run " + "'esphome-device-builder' instead." + ) from esphome.dashboard import dashboard return dashboard.start_dashboard(args) @@ -2356,9 +2361,9 @@ def parse_args(argv): "configuration", help="Your YAML file or configuration directory.", nargs="*" ) - parser_dashboard = subparsers.add_parser( - "dashboard", help="Create a simple web server for a dashboard." - ) + # Deprecated, will be removed in 2027.1.0. Omitting help= hides it from the + # main parser's command listing while keeping the subcommand functional. + parser_dashboard = subparsers.add_parser("dashboard") parser_dashboard.add_argument( "configuration", help="Your YAML configuration file directory." ) diff --git a/tests/unit_tests/test_main.py b/tests/unit_tests/test_main.py index acd39cedc6..c77744099d 100644 --- a/tests/unit_tests/test_main.py +++ b/tests/unit_tests/test_main.py @@ -32,6 +32,7 @@ from esphome.__main__ import ( command_clean_all, command_config, command_config_hash, + command_dashboard, command_idedata, command_rename, command_run, @@ -6283,3 +6284,25 @@ def test_command_idedata_esp_idf_no_build_errors() -> None: result = command_idedata(MagicMock(), CORE.config) assert result == 1 + + +def test_command_dashboard_warns_deprecated( + caplog: pytest.LogCaptureFixture, +) -> None: + """The dashboard command logs a deprecation warning and still starts.""" + args = MockArgs() + + with ( + patch( + "esphome.dashboard.dashboard.start_dashboard", return_value=0 + ) as mock_start, + caplog.at_level(logging.WARNING, logger="esphome.__main__"), + ): + result = command_dashboard(args) + + assert result == 0 + mock_start.assert_called_once_with(args) + assert any( + "deprecated" in rec.message and "2027.1.0" in rec.message + for rec in caplog.records + )