From c0ab73e413c0ecf56c86b660dda91952bd7359a1 Mon Sep 17 00:00:00 2001 From: Peter Zich Date: Fri, 10 Jan 2025 22:11:59 -0800 Subject: [PATCH 1/2] [feat] Add esptool logs to install web dialog --- src/install-web/index.ts | 38 +++++++++++++++- src/install-web/install-console.ts | 62 +++++++++++++++++++++++++++ src/install-web/install-web-dialog.ts | 52 +++++++++++++++++++++- src/web-serial/create-esploader.ts | 8 +++- 4 files changed, 155 insertions(+), 5 deletions(-) create mode 100644 src/install-web/install-console.ts diff --git a/src/install-web/index.ts b/src/install-web/index.ts index 9ace72d2..8cc9997a 100644 --- a/src/install-web/index.ts +++ b/src/install-web/index.ts @@ -1,7 +1,39 @@ +import type { IEspLoaderTerminal } from "esptool-js"; import { openNoPortPickedDialog } from "../no-port-picked"; import { createESPLoader } from "../web-serial/create-esploader"; import type { ESPHomeInstallWebDialog } from "./install-web-dialog"; +export class ESPLoaderTerminalStream { + public stream: ReadableStream; + public terminal: IEspLoaderTerminal; + private controller?: ReadableStreamDefaultController; + + constructor() { + const _this = this; + this.stream = new ReadableStream({ + start(controller) { + _this.controller = controller; + }, + }); + + this.terminal = { + clean: () => { + this.controller?.enqueue("\n\n\n"); + }, + writeLine: (data: string) => { + console.log(data); + this.controller?.enqueue(`${data}\n`); + }, + write: (data: string) => { + console.log(data); + // Fix "Connecting..." line break + if (data == "\n\r") this.controller?.enqueue("\n"); + else this.controller?.enqueue(data); + }, + }; + } +} + export const preloadInstallWebDialog = () => import("./install-web-dialog"); export const openInstallWebDialog = async ( @@ -30,7 +62,10 @@ export const openInstallWebDialog = async ( return; } } - const esploader = createESPLoader(port); + + const terminalStream = new ESPLoaderTerminalStream(); + + const esploader = createESPLoader(port, terminalStream.terminal); if (onDialogOpen) { onDialogOpen(); @@ -39,5 +74,6 @@ export const openInstallWebDialog = async ( const dialog = document.createElement("esphome-install-web-dialog"); dialog.params = params; dialog.esploader = esploader; + dialog.stream = terminalStream.stream; document.body.append(dialog); }; diff --git a/src/install-web/install-console.ts b/src/install-web/install-console.ts new file mode 100644 index 00000000..33c5d664 --- /dev/null +++ b/src/install-web/install-console.ts @@ -0,0 +1,62 @@ +import { ColoredConsole, coloredConsoleStyles } from "../util/console-color"; +import { Logger } from "../const"; + +export class InstallConsole extends HTMLElement { + public port!: SerialPort; + public logger!: Logger; + + private _console?: ColoredConsole; + + public logs(): string { + return this._console?.logs() || ""; + } + + public addLine(line: string) { + this._console?.addLine(line); + } + + public connectedCallback() { + if (this._console) { + return; + } + const shadowRoot = this.attachShadow({ mode: "open" }); + + shadowRoot.innerHTML = ` + +
+ `; + + this._console = new ColoredConsole(this.shadowRoot!.querySelector("div")!); + } +} + +customElements.define("install-console", InstallConsole); + +declare global { + interface HTMLElementTagNameMap { + "install-console": InstallConsole; + } +} diff --git a/src/install-web/install-web-dialog.ts b/src/install-web/install-web-dialog.ts index adff2de9..e6c8dde3 100644 --- a/src/install-web/install-web-dialog.ts +++ b/src/install-web/install-web-dialog.ts @@ -1,9 +1,11 @@ import { LitElement, html, PropertyValues, css, TemplateResult } from "lit"; -import { customElement, property, state } from "lit/decorators.js"; +import { customElement, property, query, state } from "lit/decorators.js"; import "@material/mwc-dialog"; import "@material/mwc-circular-progress"; import "@material/mwc-button"; import type { ESPLoader } from "esptool-js"; +import "./install-console"; +import type { InstallConsole } from "./install-console"; import { compileConfiguration, Configuration, @@ -43,6 +45,9 @@ export class ESPHomeInstallWebDialog extends LitElement { }; @property() public esploader!: ESPLoader; + @property() public stream?: ReadableStream; + + @query("install-console") private _console!: InstallConsole; @state() private _writeProgress?: number; @@ -56,6 +61,23 @@ export class ESPHomeInstallWebDialog extends LitElement { private _platform?: SupportedPlatforms; + @property() private _showLogs = false; + + connectedCallback() { + super.connectedCallback(); + + // this._console won't be defined until after the first paint + setTimeout(() => { + this.stream?.pipeTo( + new WritableStream({ + write: (chunk) => { + this._console.addLine(chunk); + }, + }), + ); + }); + } + protected render() { let heading; let content; @@ -106,6 +128,8 @@ export class ESPHomeInstallWebDialog extends LitElement { } } + hideActions = false; + return html` ${content} + + `; } @@ -148,7 +180,7 @@ export class ESPHomeInstallWebDialog extends LitElement {
${icon}
${label} - ${showClose + ${showClose || true ? html` { +export const createESPLoader = ( + port: SerialPort, + terminal?: IEspLoaderTerminal, +) => { const transport = new Transport(port); return new ESPLoader({ transport, baudrate: 115200, romBaudrate: 115200, enableTracing: false, + terminal, }); }; From 81ab259ff4acc5006a1f61784c71dc9c8de8e075 Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 18 Sep 2025 22:19:17 -0500 Subject: [PATCH 2/2] Address comments --- src/install-web/install-web-dialog.ts | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/install-web/install-web-dialog.ts b/src/install-web/install-web-dialog.ts index e6c8dde3..477c0840 100644 --- a/src/install-web/install-web-dialog.ts +++ b/src/install-web/install-web-dialog.ts @@ -63,19 +63,18 @@ export class ESPHomeInstallWebDialog extends LitElement { @property() private _showLogs = false; - connectedCallback() { + async connectedCallback() { super.connectedCallback(); - // this._console won't be defined until after the first paint - setTimeout(() => { - this.stream?.pipeTo( - new WritableStream({ - write: (chunk) => { - this._console.addLine(chunk); - }, - }), - ); - }); + await this.updateComplete; + + this.stream?.pipeTo( + new WritableStream({ + write: (chunk) => { + this._console.addLine(chunk); + }, + }), + ); } protected render() { @@ -180,7 +179,7 @@ export class ESPHomeInstallWebDialog extends LitElement {
${icon}
${label} - ${showClose || true + ${showClose ? html`