diff --git a/src/fake_data/provide_hass.ts b/src/fake_data/provide_hass.ts index 297f4d4f8c71..111ebf6e3133 100644 --- a/src/fake_data/provide_hass.ts +++ b/src/fake_data/provide_hass.ts @@ -271,6 +271,7 @@ export const provideHass = ( }, dockedSidebar: "auto", vibrate: true, + debugConnection: false, suspendWhenHidden: false, moreInfoEntityId: null as any, // @ts-ignore diff --git a/src/panels/developer-tools/debug/developer-tools-debug.ts b/src/panels/developer-tools/debug/developer-tools-debug.ts new file mode 100644 index 000000000000..6a5aa730cd9d --- /dev/null +++ b/src/panels/developer-tools/debug/developer-tools-debug.ts @@ -0,0 +1,52 @@ +import { CSSResultGroup, LitElement, css, html } from "lit"; +import { customElement, property } from "lit/decorators"; +import { SubscribeMixin } from "../../../mixins/subscribe-mixin"; +import { haStyle } from "../../../resources/styles"; +import { HomeAssistant } from "../../../types"; +import "./ha-debug-connection-row"; + +@customElement("developer-tools-debug") +class HaPanelDevDebug extends SubscribeMixin(LitElement) { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property({ type: Boolean }) public narrow!: boolean; + + protected render() { + return html` +
+ +
+ + +
+ `; + } + + static get styles(): CSSResultGroup { + return [ + haStyle, + css` + .content { + padding: 28px 20px 16px; + display: block; + max-width: 600px; + margin: 0 auto; + } + `, + ]; + } +} + +declare global { + interface HTMLElementTagNameMap { + "developer-tools-debug": HaPanelDevDebug; + } +} diff --git a/src/panels/developer-tools/debug/ha-debug-connection-row.ts b/src/panels/developer-tools/debug/ha-debug-connection-row.ts new file mode 100644 index 000000000000..e4b1c5c3ff9b --- /dev/null +++ b/src/panels/developer-tools/debug/ha-debug-connection-row.ts @@ -0,0 +1,50 @@ +import { html, LitElement, TemplateResult } from "lit"; +import { customElement, property } from "lit/decorators"; +import "../../../components/ha-settings-row"; +import "../../../components/ha-switch"; +import type { HaSwitch } from "../../../components/ha-switch"; +import type { HomeAssistant } from "../../../types"; +import { storeState } from "../../../util/ha-pref-storage"; + +@customElement("ha-debug-connection-row") +class HaDebugConnectionRow extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property() public narrow!: boolean; + + protected render(): TemplateResult { + return html` + + + ${this.hass.localize( + "ui.panel.developer-tools.tabs.debug.debug_connection.title" + )} + + + ${this.hass.localize( + "ui.panel.developer-tools.tabs.debug.debug_connection.description" + )} + + + + `; + } + + private async _checkedChanged(ev: Event) { + const debugConnection = (ev.target as HaSwitch).checked; + if (debugConnection === this.hass.debugConnection) { + return; + } + this.hass.debugConnection = debugConnection; + storeState(this.hass); + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-debug-connection-row": HaDebugConnectionRow; + } +} diff --git a/src/panels/developer-tools/developer-tools-router.ts b/src/panels/developer-tools/developer-tools-router.ts index 5b8baf3899b4..72b9795a2cea 100644 --- a/src/panels/developer-tools/developer-tools-router.ts +++ b/src/panels/developer-tools/developer-tools-router.ts @@ -49,6 +49,10 @@ class DeveloperToolsRouter extends HassRouterPage { tag: "developer-tools-assist", load: () => import("./assist/developer-tools-assist"), }, + debug: { + tag: "developer-tools-debug", + load: () => import("./debug/developer-tools-debug"), + }, }, }; diff --git a/src/panels/developer-tools/ha-panel-developer-tools.ts b/src/panels/developer-tools/ha-panel-developer-tools.ts index 813cc014e7d5..de7ec5777c11 100644 --- a/src/panels/developer-tools/ha-panel-developer-tools.ts +++ b/src/panels/developer-tools/ha-panel-developer-tools.ts @@ -1,9 +1,14 @@ +import { mdiDotsVertical } from "@mdi/js"; import "@polymer/paper-tabs/paper-tab"; import "@polymer/paper-tabs/paper-tabs"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators"; +import type { ActionDetail } from "@material/mwc-list"; import { navigate } from "../../common/navigate"; import "../../components/ha-menu-button"; +import "../../components/ha-button-menu"; +import "../../components/ha-icon-button"; +import "../../components/ha-list-item"; import { haStyle } from "../../resources/styles"; import { HomeAssistant, Route } from "../../types"; import "./developer-tools-router"; @@ -34,6 +39,16 @@ class PanelDeveloperTools extends LitElement {
${this.hass.localize("panel.developer_tools")}
+ + + + ${this.hass.localize("ui.panel.developer-tools.tabs.debug.title")} + +
) { + switch (ev.detail.index) { + case 0: + navigate(`/developer-tools/debug`); + break; + } + } + private get _page() { return this.route.path.substr(1); } diff --git a/src/state/connection-mixin.ts b/src/state/connection-mixin.ts index bfcbabfd7095..08113c821a2c 100644 --- a/src/state/connection-mixin.ts +++ b/src/state/connection-mixin.ts @@ -73,6 +73,7 @@ export const connectionMixin = >( translationMetadata, dockedSidebar: "docked", vibrate: true, + debugConnection: false, suspendWhenHidden: true, enableShortcuts: true, moreInfoEntityId: null, @@ -84,7 +85,7 @@ export const connectionMixin = >( target, notifyOnError = true ) => { - if (__DEV__) { + if (__DEV__ || this.hass?.debugConnection) { // eslint-disable-next-line no-console console.log( "Calling service", @@ -109,7 +110,7 @@ export const connectionMixin = >( ) { return { context: { id: "" } }; } - if (__DEV__) { + if (__DEV__ || this.hass?.debugConnection) { // eslint-disable-next-line no-console console.error( "Error calling service", @@ -146,7 +147,7 @@ export const connectionMixin = >( ) => fetchWithAuth(auth, `${auth.data.hassUrl}${path}`, init), // For messages that do not get a response sendWS: (msg) => { - if (__DEV__) { + if (__DEV__ || this.hass?.debugConnection) { // eslint-disable-next-line no-console console.log("Sending", msg); } @@ -154,14 +155,14 @@ export const connectionMixin = >( }, // For messages that expect a response callWS: (msg) => { - if (__DEV__) { + if (__DEV__ || this.hass?.debugConnection) { // eslint-disable-next-line no-console console.log("Sending", msg); } const resp = conn.sendMessagePromise(msg); - if (__DEV__) { + if (__DEV__ || this.hass?.debugConnection) { resp.then( // eslint-disable-next-line no-console (result) => console.log("Received", result), diff --git a/src/translations/en.json b/src/translations/en.json index c21d6da366a0..330c4348c3a8 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -5562,6 +5562,13 @@ "no_match": "No intent matched", "language": "[%key:ui::components::language-picker::language%]" }, + "debug": { + "title": "Debug tools", + "debug_connection": { + "title": "Debug connection", + "description": "Observe requests to the server and responses from the server in browser console." + } + }, "events": { "title": "Events", "description": "Fire an event on the event bus.", diff --git a/src/types.ts b/src/types.ts index ced909e0ef01..8d0d37ee865b 100644 --- a/src/types.ts +++ b/src/types.ts @@ -230,6 +230,7 @@ export interface HomeAssistant { suspendWhenHidden: boolean; enableShortcuts: boolean; vibrate: boolean; + debugConnection: boolean; dockedSidebar: "docked" | "always_hidden" | "auto"; defaultPanel: string; moreInfoEntityId: string | null; diff --git a/src/util/ha-pref-storage.ts b/src/util/ha-pref-storage.ts index eb9b72291438..3b3bb9bff7b1 100644 --- a/src/util/ha-pref-storage.ts +++ b/src/util/ha-pref-storage.ts @@ -5,6 +5,7 @@ const STORED_STATE = [ "selectedTheme", "selectedLanguage", "vibrate", + "debugConnection", "suspendWhenHidden", "enableShortcuts", "defaultPanel",