From d7971c69ad3f34e81e3afb2933f5d0671748c985 Mon Sep 17 00:00:00 2001 From: Raman Gupta <7243222+raman325@users.noreply.github.com> Date: Wed, 25 May 2022 05:36:27 -0400 Subject: [PATCH] Add controller statistics to zwave_js config dashboard (#12668) --- src/data/zwave_js.ts | 27 ++ .../zwave_js/zwave_js-config-dashboard.ts | 230 ++++++++++++++++-- src/translations/en.json | 41 +++- 3 files changed, 277 insertions(+), 21 deletions(-) diff --git a/src/data/zwave_js.ts b/src/data/zwave_js.ts index eb54cd7147..b920f1f9de 100644 --- a/src/data/zwave_js.ts +++ b/src/data/zwave_js.ts @@ -230,6 +230,20 @@ export interface ZWaveJSHealNetworkStatusMessage { heal_node_status: { [key: number]: string }; } +export interface ZWaveJSControllerStatisticsUpdatedMessage { + event: "statistics updated"; + source: "controller"; + messages_tx: number; + messages_rx: number; + messages_dropped_tx: number; + messages_dropped_rx: number; + nak: number; + can: number; + timeout_ack: number; + timeout_response: number; + timeout_callback: number; +} + export interface ZWaveJSRemovedNode { node_id: number; manufacturer: string; @@ -559,6 +573,19 @@ export const subscribeHealZwaveNetworkProgress = ( } ); +export const subscribeZwaveControllerStatistics = ( + hass: HomeAssistant, + entry_id: string, + callbackFunction: (message: ZWaveJSControllerStatisticsUpdatedMessage) => void +): Promise => + hass.connection.subscribeMessage( + (message: any) => callbackFunction(message), + { + type: "zwave_js/subscribe_controller_statistics", + entry_id, + } + ); + export const getZwaveJsIdentifiersFromDevice = ( device: DeviceRegistryEntry ): ZWaveJSNodeIdentifiers | undefined => { diff --git a/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-config-dashboard.ts b/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-config-dashboard.ts index 1ffed77303..63b59efae1 100644 --- a/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-config-dashboard.ts +++ b/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-config-dashboard.ts @@ -1,4 +1,5 @@ -import "@material/mwc-button/mwc-button"; +import "@material/mwc-list/mwc-list"; +import "@material/mwc-list/mwc-list-item"; import { mdiAlertCircle, mdiCheckCircle, @@ -11,9 +12,12 @@ import { customElement, property, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; import "../../../../../components/ha-card"; import "../../../../../components/ha-icon-button"; +import "../../../../../components/ha-expansion-panel"; import "../../../../../components/ha-fab"; +import "../../../../../components/ha-help-tooltip"; import "../../../../../components/ha-icon-next"; import "../../../../../components/ha-svg-icon"; +import { UnsubscribeFunc } from "home-assistant-js-websocket"; import { fetchZwaveDataCollectionStatus, fetchZwaveNetworkStatus, @@ -22,7 +26,9 @@ import { setZwaveDataCollectionPreference, stopZwaveExclusion, stopZwaveInclusion, + subscribeZwaveControllerStatistics, ZWaveJSClient, + ZWaveJSControllerStatisticsUpdatedMessage, ZWaveJSNetwork, ZwaveJSProvisioningEntry, } from "../../../../../data/zwave_js"; @@ -41,9 +47,10 @@ import { showZWaveJSRemoveNodeDialog } from "./show-dialog-zwave_js-remove-node" import { configTabs } from "./zwave_js-config-router"; import { showOptionsFlowDialog } from "../../../../../dialogs/config-flow/show-dialog-options-flow"; import { computeRTL } from "../../../../../common/util/compute_rtl"; +import { SubscribeMixin } from "../../../../../mixins/subscribe-mixin"; @customElement("zwave_js-config-dashboard") -class ZWaveJSConfigDashboard extends LitElement { +class ZWaveJSConfigDashboard extends SubscribeMixin(LitElement) { @property({ type: Object }) public hass!: HomeAssistant; @property({ type: Object }) public route!: Route; @@ -52,7 +59,7 @@ class ZWaveJSConfigDashboard extends LitElement { @property({ type: Boolean }) public isWide!: boolean; - @property() public configEntryId?: string; + @property() public configEntryId!: string; @state() private _configEntry?: ConfigEntry; @@ -66,12 +73,30 @@ class ZWaveJSConfigDashboard extends LitElement { @state() private _dataCollectionOptIn?: boolean; + @state() + private _statistics?: ZWaveJSControllerStatisticsUpdatedMessage; + protected firstUpdated() { if (this.hass) { this._fetchData(); } } + public hassSubscribe(): Array> { + return [ + subscribeZwaveControllerStatistics( + this.hass, + this.configEntryId, + (message) => { + if (!this.hasUpdated) { + return; + } + this._statistics = message; + } + ), + ]; + } + protected render(): TemplateResult { if (!this._configEntry) { return html``; @@ -211,22 +236,178 @@ class ZWaveJSConfigDashboard extends LitElement {
- ${this.hass.localize( - "ui.panel.config.zwave_js.dashboard.driver_version" - )}: - ${this._network.client.driver_version}
- ${this.hass.localize( - "ui.panel.config.zwave_js.dashboard.server_version" - )}: - ${this._network.client.server_version}
- ${this.hass.localize( - "ui.panel.config.zwave_js.dashboard.home_id" - )}: - ${this._network.controller.home_id}
- ${this.hass.localize( - "ui.panel.config.zwave_js.dashboard.server_url" - )}: - ${this._network.client.ws_server_url}
+
+ + ${this.hass.localize( + "ui.panel.config.zwave_js.dashboard.driver_version" + )}: + + ${this._network.client.driver_version} +
+
+ + ${this.hass.localize( + "ui.panel.config.zwave_js.dashboard.server_version" + )}: + + ${this._network.client.server_version} +
+
+ + ${this.hass.localize( + "ui.panel.config.zwave_js.dashboard.home_id" + )}: + + ${this._network.controller.home_id} +
+
+ + ${this.hass.localize( + "ui.panel.config.zwave_js.dashboard.server_url" + )}: + + ${this._network.client.ws_server_url} +
+
+ + + + + ${this.hass.localize( + "ui.panel.config.zwave_js.dashboard.statistics.messages_tx.label" + )} + + + ${this.hass.localize( + "ui.panel.config.zwave_js.dashboard.statistics.messages_tx.tooltip" + )} + + ${this._statistics?.messages_tx ?? 0} + + + + ${this.hass.localize( + "ui.panel.config.zwave_js.dashboard.statistics.messages_rx.label" + )} + + + ${this.hass.localize( + "ui.panel.config.zwave_js.dashboard.statistics.messages_rx.tooltip" + )} + + ${this._statistics?.messages_rx ?? 0} + + + + ${this.hass.localize( + "ui.panel.config.zwave_js.dashboard.statistics.messages_dropped_tx.label" + )} + + + ${this.hass.localize( + "ui.panel.config.zwave_js.dashboard.statistics.messages_dropped_tx.tooltip" + )} + + ${this._statistics?.messages_dropped_tx ?? 0} + + + + ${this.hass.localize( + "ui.panel.config.zwave_js.dashboard.statistics.messages_dropped_rx.label" + )} + + + ${this.hass.localize( + "ui.panel.config.zwave_js.dashboard.statistics.messages_dropped_rx.tooltip" + )} + + ${this._statistics?.messages_dropped_rx ?? 0} + + + + ${this.hass.localize( + "ui.panel.config.zwave_js.dashboard.statistics.nak.label" + )} + + + ${this.hass.localize( + "ui.panel.config.zwave_js.dashboard.statistics.nak.tooltip" + )} + + ${this._statistics?.nak ?? 0} + + + + ${this.hass.localize( + "ui.panel.config.zwave_js.dashboard.statistics.can.label" + )} + + + ${this.hass.localize( + "ui.panel.config.zwave_js.dashboard.statistics.can.tooltip" + )} + + ${this._statistics?.can ?? 0} + + + + ${this.hass.localize( + "ui.panel.config.zwave_js.dashboard.statistics.timeout_ack.label" + )} + + + ${this.hass.localize( + "ui.panel.config.zwave_js.dashboard.statistics.timeout_ack.tooltip" + )} + + ${this._statistics?.timeout_ack ?? 0} + + + + ${this.hass.localize( + "ui.panel.config.zwave_js.dashboard.statistics.timeout_response.label" + )} + + + ${this.hass.localize( + "ui.panel.config.zwave_js.dashboard.statistics.timeout_response.tooltip" + )} + + ${this._statistics?.timeout_response ?? 0} + + + + ${this.hass.localize( + "ui.panel.config.zwave_js.dashboard.statistics.timeout_callback.label" + )} + + + ${this.hass.localize( + "ui.panel.config.zwave_js.dashboard.statistics.timeout_callback.tooltip" + )} + + ${this._statistics?.timeout_callback ?? 0} + + +
entry.entry_id === this.configEntryId! + (entry) => entry.entry_id === this.configEntryId ); if (ERROR_STATES.includes(this._configEntry!.state)) { @@ -508,6 +689,11 @@ class ZWaveJSConfigDashboard extends LitElement { padding-right: 40px; } + .row { + display: flex; + justify-content: space-between; + } + .network-status div.heading { display: flex; align-items: center; @@ -530,6 +716,10 @@ class ZWaveJSConfigDashboard extends LitElement { font-size: 1rem; } + mwc-list-item { + height: 60px; + } + .card-header { display: flex; } diff --git a/src/translations/en.json b/src/translations/en.json index d1a1d44f08..2a933afea7 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -3045,7 +3045,46 @@ "server_url": "Server URL", "devices": "{count} {count, plural,\n one {device}\n other {devices}\n}", "provisioned_devices": "Provisioned devices", - "not_ready": "{count} not ready" + "not_ready": "{count} not ready", + "statistics": { + "title": "Controller Statistics", + "messages_tx": { + "label": "Messages TX", + "tooltip": "Number of messages successfully sent to the controller" + }, + "messages_rx": { + "label": "Messages RX", + "tooltip": "Number of messages successfully received by the controller" + }, + "messages_dropped_tx": { + "label": "Dropped Messages TX", + "tooltip": "Number of messages from the controller that were dropped by the host" + }, + "messages_dropped_rx": { + "label": "Dropped Messages RX", + "tooltip": "Number of outgoing messages that were dropped because they could not be sent" + }, + "nak": { + "label": "NAK", + "tooltip": "Number of messages that the controller did not accept" + }, + "can": { + "label": "CAN", + "tooltip": "Number of collisions while sending a message to the controller" + }, + "timeout_ack": { + "label": "Timeout ACK", + "tooltip": "Number of transmission attempts where an ACK was missing from the controller" + }, + "timeout_response": { + "label": "Timeout Response", + "tooltip": "Number of transmission attempts where the controller response did not come in time" + }, + "timeout_callback": { + "label": "Timeout Callback", + "tooltip": "Number of transmission attempts where the controller callback did not come in time" + } + } }, "device_info": { "zwave_info": "Z-Wave Info",