mirror of
https://github.com/home-assistant/frontend.git
synced 2025-04-25 13:57:21 +00:00
Add zwave_js device statistics (#12794)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
parent
f020add6be
commit
54377225ec
@ -244,6 +244,41 @@ export interface ZWaveJSControllerStatisticsUpdatedMessage {
|
||||
timeout_callback: number;
|
||||
}
|
||||
|
||||
export enum RssiError {
|
||||
NotAvailable = 127,
|
||||
ReceiverSaturated = 126,
|
||||
NoSignalDetected = 125,
|
||||
}
|
||||
|
||||
export enum ProtocolDataRate {
|
||||
ZWave_9k6 = 0x01,
|
||||
ZWave_40k = 0x02,
|
||||
ZWave_100k = 0x03,
|
||||
LongRange_100k = 0x04,
|
||||
}
|
||||
|
||||
export interface ZWaveJSNodeStatisticsUpdatedMessage {
|
||||
event: "statistics updated";
|
||||
source: "node";
|
||||
commands_tx: number;
|
||||
commands_rx: number;
|
||||
commands_dropped_tx: number;
|
||||
commands_dropped_rx: number;
|
||||
timeout_response: number;
|
||||
rtt: number | null;
|
||||
rssi: RssiError | number | null;
|
||||
lwr: ZWaveJSRouteStatistics | null;
|
||||
nlwr: ZWaveJSRouteStatistics | null;
|
||||
}
|
||||
|
||||
export interface ZWaveJSRouteStatistics {
|
||||
protocol_data_rate: number;
|
||||
repeaters: string[];
|
||||
rssi: RssiError | number | null;
|
||||
repeater_rssi: (RssiError | number)[];
|
||||
route_failed_between: [string, string] | null;
|
||||
}
|
||||
|
||||
export interface ZWaveJSRemovedNode {
|
||||
node_id: number;
|
||||
manufacturer: string;
|
||||
@ -597,6 +632,19 @@ export const subscribeZwaveControllerStatistics = (
|
||||
}
|
||||
);
|
||||
|
||||
export const subscribeZwaveNodeStatistics = (
|
||||
hass: HomeAssistant,
|
||||
device_id: string,
|
||||
callbackFunction: (message: ZWaveJSNodeStatisticsUpdatedMessage) => void
|
||||
): Promise<UnsubscribeFunc> =>
|
||||
hass.connection.subscribeMessage(
|
||||
(message: any) => callbackFunction(message),
|
||||
{
|
||||
type: "zwave_js/subscribe_node_statistics",
|
||||
device_id,
|
||||
}
|
||||
);
|
||||
|
||||
export const getZwaveJsIdentifiersFromDevice = (
|
||||
device: DeviceRegistryEntry
|
||||
): ZWaveJSNodeIdentifiers | undefined => {
|
||||
|
@ -3,6 +3,7 @@ import { DeviceRegistryEntry } from "../../../../../../data/device_registry";
|
||||
import { fetchZwaveNodeStatus } from "../../../../../../data/zwave_js";
|
||||
import type { HomeAssistant } from "../../../../../../types";
|
||||
import { showZWaveJSHealNodeDialog } from "../../../../integrations/integration-panels/zwave_js/show-dialog-zwave_js-heal-node";
|
||||
import { showZWaveJSNodeStatisticsDialog } from "../../../../integrations/integration-panels/zwave_js/show-dialog-zwave_js-node-statistics";
|
||||
import { showZWaveJSReinterviewNodeDialog } from "../../../../integrations/integration-panels/zwave_js/show-dialog-zwave_js-reinterview-node";
|
||||
import { showZWaveJSRemoveFailedNodeDialog } from "../../../../integrations/integration-panels/zwave_js/show-dialog-zwave_js-remove-failed-node";
|
||||
import type { DeviceAction } from "../../../ha-config-device-page";
|
||||
@ -64,5 +65,14 @@ export const getZwaveDeviceActions = async (
|
||||
device_id: device.id,
|
||||
}),
|
||||
},
|
||||
{
|
||||
label: hass.localize(
|
||||
"ui.panel.config.zwave_js.device_info.node_statistics"
|
||||
),
|
||||
action: () =>
|
||||
showZWaveJSNodeStatisticsDialog(el, {
|
||||
device: device,
|
||||
}),
|
||||
},
|
||||
];
|
||||
};
|
||||
|
@ -0,0 +1,477 @@
|
||||
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import "@material/mwc-list/mwc-list";
|
||||
import "@material/mwc-list/mwc-list-item";
|
||||
import "../../../../../components/ha-expansion-panel";
|
||||
import "../../../../../components/ha-help-tooltip";
|
||||
import "../../../../../components/ha-svg-icon";
|
||||
import { mdiSwapHorizontal } from "@mdi/js";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||
import {
|
||||
DeviceRegistryEntry,
|
||||
computeDeviceName,
|
||||
subscribeDeviceRegistry,
|
||||
} from "../../../../../data/device_registry";
|
||||
import {
|
||||
subscribeZwaveNodeStatistics,
|
||||
ProtocolDataRate,
|
||||
ZWaveJSNodeStatisticsUpdatedMessage,
|
||||
ZWaveJSRouteStatistics,
|
||||
RssiError,
|
||||
} from "../../../../../data/zwave_js";
|
||||
import { haStyleDialog } from "../../../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../../../types";
|
||||
import { ZWaveJSNodeStatisticsDialogParams } from "./show-dialog-zwave_js-node-statistics";
|
||||
import { createCloseHeading } from "../../../../../components/ha-dialog";
|
||||
|
||||
type WorkingRouteStatistics =
|
||||
| (ZWaveJSRouteStatistics & {
|
||||
repeater_rssi_table?: TemplateResult;
|
||||
rssi_translated?: TemplateResult | string;
|
||||
route_failed_between_translated?: [string, string];
|
||||
})
|
||||
| undefined;
|
||||
|
||||
@customElement("dialog-zwave_js-node-statistics")
|
||||
class DialogZWaveJSNodeStatistics extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@state() private device?: DeviceRegistryEntry;
|
||||
|
||||
@state() private _nodeStatistics?: ZWaveJSNodeStatisticsUpdatedMessage & {
|
||||
rssi_translated?: TemplateResult | string;
|
||||
};
|
||||
|
||||
@state() private _deviceIDsToName: { [key: string]: string } = {};
|
||||
|
||||
@state() private _workingRoutes: {
|
||||
lwr?: WorkingRouteStatistics;
|
||||
nlwr?: WorkingRouteStatistics;
|
||||
} = {};
|
||||
|
||||
private _subscribedNodeStatistics?: Promise<UnsubscribeFunc>;
|
||||
|
||||
private _subscribedDeviceRegistry?: UnsubscribeFunc;
|
||||
|
||||
public showDialog(params: ZWaveJSNodeStatisticsDialogParams): void {
|
||||
this.device = params.device;
|
||||
this._subscribeDeviceRegistry();
|
||||
this._subscribeNodeStatistics();
|
||||
}
|
||||
|
||||
public closeDialog(): void {
|
||||
this._nodeStatistics = undefined;
|
||||
this.device = undefined;
|
||||
|
||||
this._unsubscribe();
|
||||
|
||||
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this.device) {
|
||||
return html``;
|
||||
}
|
||||
|
||||
return html`
|
||||
<ha-dialog
|
||||
open
|
||||
@closed=${this.closeDialog}
|
||||
.heading=${createCloseHeading(
|
||||
this.hass,
|
||||
this.hass.localize("ui.panel.config.zwave_js.node_statistics.title")
|
||||
)}
|
||||
>
|
||||
<mwc-list noninteractive>
|
||||
<mwc-list-item twoline hasmeta>
|
||||
<span>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.node_statistics.commands_tx.label"
|
||||
)}</span
|
||||
>
|
||||
<span slot="secondary">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.node_statistics.commands_tx.tooltip"
|
||||
)}
|
||||
</span>
|
||||
<span slot="meta">${this._nodeStatistics?.commands_tx}</span>
|
||||
</mwc-list-item>
|
||||
<mwc-list-item twoline hasmeta>
|
||||
<span>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.node_statistics.commands_rx.label"
|
||||
)}</span
|
||||
>
|
||||
<span slot="secondary">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.node_statistics.commands_rx.tooltip"
|
||||
)}
|
||||
</span>
|
||||
<span slot="meta">${this._nodeStatistics?.commands_rx}</span>
|
||||
</mwc-list-item>
|
||||
<mwc-list-item twoline hasmeta>
|
||||
<span>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.node_statistics.commands_dropped_tx.label"
|
||||
)}</span
|
||||
>
|
||||
<span slot="secondary">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.node_statistics.commands_dropped_tx.tooltip"
|
||||
)}
|
||||
</span>
|
||||
<span slot="meta"
|
||||
>${this._nodeStatistics?.commands_dropped_tx}</span
|
||||
>
|
||||
</mwc-list-item>
|
||||
<mwc-list-item twoline hasmeta>
|
||||
<span>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.node_statistics.commands_dropped_rx.label"
|
||||
)}</span
|
||||
>
|
||||
<span slot="secondary">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.node_statistics.commands_dropped_rx.tooltip"
|
||||
)}
|
||||
</span>
|
||||
<span slot="meta"
|
||||
>${this._nodeStatistics?.commands_dropped_rx}</span
|
||||
>
|
||||
</mwc-list-item>
|
||||
<mwc-list-item twoline hasmeta>
|
||||
<span>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.node_statistics.timeout_response.label"
|
||||
)}</span
|
||||
>
|
||||
<span slot="secondary">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.node_statistics.timeout_response.tooltip"
|
||||
)}
|
||||
</span>
|
||||
<span slot="meta">${this._nodeStatistics?.timeout_response}</span>
|
||||
</mwc-list-item>
|
||||
${this._nodeStatistics?.rtt
|
||||
? html`<mwc-list-item twoline hasmeta>
|
||||
<span>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.node_statistics.rtt.label"
|
||||
)}</span
|
||||
>
|
||||
<span slot="secondary">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.node_statistics.rtt.tooltip"
|
||||
)}
|
||||
</span>
|
||||
<span slot="meta">${this._nodeStatistics.rtt}</span>
|
||||
</mwc-list-item>`
|
||||
: ``}
|
||||
${this._nodeStatistics?.rssi_translated
|
||||
? html`<mwc-list-item twoline hasmeta>
|
||||
<span>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.node_statistics.rssi.label"
|
||||
)}</span
|
||||
>
|
||||
<span slot="secondary">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.node_statistics.rssi.tooltip"
|
||||
)}
|
||||
</span>
|
||||
<span slot="meta">${this._nodeStatistics.rssi_translated}</span>
|
||||
</mwc-list-item>`
|
||||
: ``}
|
||||
</mwc-list>
|
||||
${Object.entries(this._workingRoutes).map(([wrKey, wrValue]) =>
|
||||
wrValue
|
||||
? html`
|
||||
<ha-expansion-panel
|
||||
.header=${this.hass.localize(
|
||||
`ui.panel.config.zwave_js.node_statistics.${wrKey}`
|
||||
)}
|
||||
>
|
||||
<div class="row">
|
||||
<span>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.route_statistics.protocol.label"
|
||||
)}<ha-help-tooltip
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.route_statistics.protocol.tooltip"
|
||||
)}
|
||||
>
|
||||
</ha-help-tooltip
|
||||
></span>
|
||||
<span
|
||||
>${this.hass.localize(
|
||||
`ui.panel.config.zwave_js.route_statistics.protocol.protocol_data_rate.${
|
||||
ProtocolDataRate[wrValue.protocol_data_rate]
|
||||
}`
|
||||
)}</span
|
||||
>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.route_statistics.data_rate.label"
|
||||
)}<ha-help-tooltip
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.route_statistics.data_rate.tooltip"
|
||||
)}
|
||||
>
|
||||
</ha-help-tooltip
|
||||
></span>
|
||||
<span
|
||||
>${this.hass.localize(
|
||||
`ui.panel.config.zwave_js.route_statistics.data_rate.protocol_data_rate.${
|
||||
ProtocolDataRate[wrValue.protocol_data_rate]
|
||||
}`
|
||||
)}</span
|
||||
>
|
||||
</div>
|
||||
${wrValue.rssi_translated
|
||||
? html`<div class="row">
|
||||
<span>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.route_statistics.rssi.label"
|
||||
)}<ha-help-tooltip
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.route_statistics.rssi.tooltip"
|
||||
)}
|
||||
>
|
||||
</ha-help-tooltip
|
||||
></span>
|
||||
<span>${wrValue.rssi_translated}</span>
|
||||
</div>`
|
||||
: ``}
|
||||
<div class="row">
|
||||
<span>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.route_statistics.route_failed_between.label"
|
||||
)}<ha-help-tooltip
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.route_statistics.route_failed_between.tooltip"
|
||||
)}
|
||||
>
|
||||
</ha-help-tooltip
|
||||
></span>
|
||||
<span>
|
||||
${wrValue.route_failed_between_translated
|
||||
? html`${wrValue
|
||||
.route_failed_between_translated[0]}<ha-svg-icon
|
||||
.path=${mdiSwapHorizontal}
|
||||
></ha-svg-icon
|
||||
>${wrValue.route_failed_between_translated[1]}`
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.zwave_js.route_statistics.route_failed_between.not_applicable"
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.route_statistics.repeaters.label"
|
||||
)}<ha-help-tooltip
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.route_statistics.repeaters.tooltip"
|
||||
)}
|
||||
>
|
||||
</ha-help-tooltip></span
|
||||
><span>
|
||||
${wrValue.repeater_rssi_table
|
||||
? html`<div class="row">
|
||||
<span class="key-cell"
|
||||
><b
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.route_statistics.repeaters.repeaters"
|
||||
)}:</b
|
||||
></span
|
||||
>
|
||||
<span class="value-cell"
|
||||
><b
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.route_statistics.repeaters.rssi"
|
||||
)}:</b
|
||||
></span
|
||||
>
|
||||
</div>
|
||||
${wrValue.repeater_rssi_table}`
|
||||
: html`${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.route_statistics.repeaters.direct"
|
||||
)}`}</span
|
||||
>
|
||||
</div>
|
||||
</ha-expansion-panel>
|
||||
`
|
||||
: ``
|
||||
)}
|
||||
</ha-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
private _computeRSSI(
|
||||
rssi: number,
|
||||
includeUnit: boolean
|
||||
): TemplateResult | string {
|
||||
if (Object.values(RssiError).includes(rssi)) {
|
||||
return html`<ha-help-tooltip
|
||||
.label=${this.hass.localize(
|
||||
`ui.panel.config.zwave_js.rssi.rssi_error.${RssiError[rssi]}`
|
||||
)}
|
||||
></ha-help-tooltip>`;
|
||||
}
|
||||
if (includeUnit) {
|
||||
return `${rssi}
|
||||
${this.hass.localize("ui.panel.config.zwave_js.rssi.unit")}`;
|
||||
}
|
||||
return rssi.toString();
|
||||
}
|
||||
|
||||
private _computeDeviceNameById(device_id: string): "unknown device" | string {
|
||||
if (!this._deviceIDsToName) {
|
||||
return "unknown device";
|
||||
}
|
||||
const device = this._deviceIDsToName[device_id];
|
||||
if (!device) {
|
||||
return "unknown device";
|
||||
}
|
||||
|
||||
return this._deviceIDsToName[device_id] || "unknown device";
|
||||
}
|
||||
|
||||
private _subscribeNodeStatistics(): void {
|
||||
if (!this.hass) {
|
||||
return;
|
||||
}
|
||||
this._subscribedNodeStatistics = subscribeZwaveNodeStatistics(
|
||||
this.hass,
|
||||
this.device!.id,
|
||||
(message: ZWaveJSNodeStatisticsUpdatedMessage) => {
|
||||
this._nodeStatistics = {
|
||||
...message,
|
||||
rssi_translated: message.rssi
|
||||
? this._computeRSSI(message.rssi, false)
|
||||
: undefined,
|
||||
};
|
||||
|
||||
const workingRoutesValueMap: [
|
||||
string,
|
||||
WorkingRouteStatistics | null | undefined
|
||||
][] = [
|
||||
["lwr", this._nodeStatistics?.lwr],
|
||||
["nlwr", this._nodeStatistics?.nlwr],
|
||||
];
|
||||
|
||||
const workingRoutes: {
|
||||
lwr?: WorkingRouteStatistics;
|
||||
nlwr?: WorkingRouteStatistics;
|
||||
} = {};
|
||||
workingRoutesValueMap.forEach(([wrKey, wrValue]) => {
|
||||
workingRoutes[wrKey] = wrValue;
|
||||
|
||||
if (wrValue) {
|
||||
if (wrValue.rssi) {
|
||||
wrValue.rssi_translated = this._computeRSSI(wrValue.rssi, true);
|
||||
}
|
||||
|
||||
if (wrValue.route_failed_between) {
|
||||
wrValue.route_failed_between_translated = [
|
||||
this._computeDeviceNameById(wrValue.route_failed_between[0]),
|
||||
this._computeDeviceNameById(wrValue.route_failed_between[1]),
|
||||
];
|
||||
}
|
||||
|
||||
if (wrValue.repeaters && wrValue.repeaters.length) {
|
||||
wrValue.repeater_rssi_table = html`${wrValue.repeaters.map(
|
||||
(_, idx) =>
|
||||
html`<div class="row">
|
||||
<span class="key-cell"
|
||||
>${this._computeDeviceNameById(
|
||||
wrValue.repeaters[idx]
|
||||
)}:</span
|
||||
>
|
||||
<span class="value-cell"
|
||||
>${this._computeRSSI(
|
||||
wrValue.repeater_rssi[idx],
|
||||
true
|
||||
)}</span
|
||||
>
|
||||
</div>`
|
||||
)}`;
|
||||
}
|
||||
}
|
||||
});
|
||||
this._workingRoutes = workingRoutes;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private _subscribeDeviceRegistry(): void {
|
||||
if (!this.hass) {
|
||||
return;
|
||||
}
|
||||
this._subscribedDeviceRegistry = subscribeDeviceRegistry(
|
||||
this.hass.connection,
|
||||
(devices: DeviceRegistryEntry[]) => {
|
||||
const devicesIdToName = {};
|
||||
devices.forEach((device) => {
|
||||
devicesIdToName[device.id] = computeDeviceName(device, this.hass);
|
||||
});
|
||||
this._deviceIDsToName = devicesIdToName;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private _unsubscribe(): void {
|
||||
if (this._subscribedNodeStatistics) {
|
||||
this._subscribedNodeStatistics.then((unsub) => unsub());
|
||||
this._subscribedNodeStatistics = undefined;
|
||||
}
|
||||
if (this._subscribedDeviceRegistry) {
|
||||
this._subscribedDeviceRegistry();
|
||||
this._subscribedDeviceRegistry = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyleDialog,
|
||||
css`
|
||||
mwc-list-item {
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.table {
|
||||
display: table;
|
||||
}
|
||||
|
||||
.key-cell {
|
||||
display: table-cell;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.value-cell {
|
||||
display: table-cell;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
span[slot="meta"] {
|
||||
font-size: 0.95em;
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"dialog-zwave_js-node-statistics": DialogZWaveJSNodeStatistics;
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||
import { DeviceRegistryEntry } from "../../../../../data/device_registry";
|
||||
|
||||
export interface ZWaveJSNodeStatisticsDialogParams {
|
||||
device: DeviceRegistryEntry;
|
||||
}
|
||||
|
||||
export const loadNodeStatisticsDialog = () =>
|
||||
import("./dialog-zwave_js-node-statistics");
|
||||
|
||||
export const showZWaveJSNodeStatisticsDialog = (
|
||||
element: HTMLElement,
|
||||
nodeStatisticsDialogParams: ZWaveJSNodeStatisticsDialogParams
|
||||
): void => {
|
||||
fireEvent(element, "show-dialog", {
|
||||
dialogTag: "dialog-zwave_js-node-statistics",
|
||||
dialogImport: loadNodeStatisticsDialog,
|
||||
dialogParams: nodeStatisticsDialogParams,
|
||||
});
|
||||
};
|
@ -3103,7 +3103,87 @@
|
||||
"highest_security": "Highest Security",
|
||||
"unknown": "Unknown",
|
||||
"zwave_plus": "Z-Wave Plus",
|
||||
"zwave_plus_version": "Version {version}"
|
||||
"zwave_plus_version": "Version {version}",
|
||||
"node_statistics": "Show Device Statistics"
|
||||
},
|
||||
"node_statistics": {
|
||||
"title": "Device Statistics",
|
||||
"commands_tx": {
|
||||
"label": "Commands TX",
|
||||
"tooltip": "# of commands successfully sent to the node"
|
||||
},
|
||||
"commands_rx": {
|
||||
"label": "Commands RX",
|
||||
"tooltip": "# of commands received from the node, including responses to sent commands"
|
||||
},
|
||||
"commands_dropped_tx": {
|
||||
"label": "Commands Dropped TX",
|
||||
"tooltip": "# of outgoing commands that were dropped because they could not be sent"
|
||||
},
|
||||
"commands_dropped_rx": {
|
||||
"label": "Commands Dropped RX",
|
||||
"tooltip": "# of commands from the node that were dropped by the host"
|
||||
},
|
||||
"timeout_response": {
|
||||
"label": "Timeout Response",
|
||||
"tooltip": "# of Get-type commands where the node's response did not come in time"
|
||||
},
|
||||
"rtt": {
|
||||
"label": "RTT",
|
||||
"tooltip": "Average round-trip-time in ms of commands to this node"
|
||||
},
|
||||
"rssi": {
|
||||
"label": "RSSI",
|
||||
"tooltip": "Average RSSI in dBm of frames received by this node"
|
||||
},
|
||||
"lwr": "Last Working Route",
|
||||
"nlwr": "Next to Last Working Route"
|
||||
},
|
||||
"route_statistics": {
|
||||
"protocol": {
|
||||
"label": "Protocol",
|
||||
"tooltip": "The protocol for this route",
|
||||
"protocol_data_rate": {
|
||||
"ZWave_9k6": "Z-Wave",
|
||||
"ZWave_40k": "Z-Wave",
|
||||
"ZWave_100k": "Z-Wave",
|
||||
"LongRange_100k": "Z-Wave Long Range"
|
||||
}
|
||||
},
|
||||
"data_rate": {
|
||||
"label": "Data Rate",
|
||||
"tooltip": "The used data rate for this route",
|
||||
"protocol_data_rate": {
|
||||
"ZWave_9k6": "9.6 kbps",
|
||||
"ZWave_40k": "40 kbps",
|
||||
"ZWave_100k": "100 kbps",
|
||||
"LongRange_100k": "100 kbps"
|
||||
}
|
||||
},
|
||||
"repeaters": {
|
||||
"label": "Repeaters + RSSI",
|
||||
"tooltip": "Which nodes are repeaters for this route and their RSSI",
|
||||
"repeaters": "Repeater Device",
|
||||
"rssi": "RSSI",
|
||||
"direct": "None, direct connection"
|
||||
},
|
||||
"rssi": {
|
||||
"label": "RSSI",
|
||||
"tooltip": "The RSSI of the ACK frame received by the controller"
|
||||
},
|
||||
"route_failed_between": {
|
||||
"label": "Route Failed Between",
|
||||
"tooltip": "The nodes between which the transmission failed most recently",
|
||||
"not_applicable": "N/A"
|
||||
}
|
||||
},
|
||||
"rssi": {
|
||||
"unit": "dBm",
|
||||
"rssi_error": {
|
||||
"NotAvailable": "Not available",
|
||||
"ReceiverSaturated": "Receiver saturated",
|
||||
"NoSignalDetected": "No signal detected"
|
||||
}
|
||||
},
|
||||
"node_config": {
|
||||
"header": "Z-Wave Device Configuration",
|
||||
|
Loading…
x
Reference in New Issue
Block a user