mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-09 18:36:35 +00:00
MVP Z-Wave JS Log Viewer (#9008)
* Add element to subscribe to ZJS logs * set log level and adjust styling * review comments * add ZWaveJS to function names * use flexbox * Review comments * import Co-authored-by: Paulus Schoutsen <balloob@gmail.com> Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
parent
9d33c0cfaf
commit
ebe0caba83
@ -173,9 +173,9 @@ export const reinterviewNode = (
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getIdentifiersFromDevice = function (
|
export const getIdentifiersFromDevice = (
|
||||||
device: DeviceRegistryEntry
|
device: DeviceRegistryEntry
|
||||||
): ZWaveJSNodeIdentifiers | undefined {
|
): ZWaveJSNodeIdentifiers | undefined => {
|
||||||
if (!device) {
|
if (!device) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
@ -193,3 +193,48 @@ export const getIdentifiersFromDevice = function (
|
|||||||
home_id: identifiers[0],
|
home_id: identifiers[0],
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export interface ZWaveJSLogMessage {
|
||||||
|
timestamp: string;
|
||||||
|
level: string;
|
||||||
|
primary_tags: string;
|
||||||
|
message: string | string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const subscribeZWaveJSLogs = (
|
||||||
|
hass: HomeAssistant,
|
||||||
|
entry_id: string,
|
||||||
|
callback: (message: ZWaveJSLogMessage) => void
|
||||||
|
) =>
|
||||||
|
hass.connection.subscribeMessage<ZWaveJSLogMessage>(callback, {
|
||||||
|
type: "zwave_js/subscribe_logs",
|
||||||
|
entry_id,
|
||||||
|
});
|
||||||
|
|
||||||
|
export interface ZWaveJSLogConfig {
|
||||||
|
level: string;
|
||||||
|
enabled: boolean;
|
||||||
|
filename: string;
|
||||||
|
log_to_file: boolean;
|
||||||
|
force_console: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const fetchZWaveJSLogConfig = (
|
||||||
|
hass: HomeAssistant,
|
||||||
|
entry_id: string
|
||||||
|
): Promise<ZWaveJSLogConfig> =>
|
||||||
|
hass.callWS({
|
||||||
|
type: "zwave_js/get_log_config",
|
||||||
|
entry_id,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const setZWaveJSLogLevel = (
|
||||||
|
hass: HomeAssistant,
|
||||||
|
entry_id: string,
|
||||||
|
level: string
|
||||||
|
): Promise<ZWaveJSLogConfig> =>
|
||||||
|
hass.callWS({
|
||||||
|
type: "zwave_js/update_log_config",
|
||||||
|
entry_id,
|
||||||
|
config: { level },
|
||||||
|
});
|
||||||
|
@ -7,7 +7,7 @@ import { HomeAssistant } from "../../../../../types";
|
|||||||
import { navigate } from "../../../../../common/navigate";
|
import { navigate } from "../../../../../common/navigate";
|
||||||
import { PageNavigation } from "../../../../../layouts/hass-tabs-subpage";
|
import { PageNavigation } from "../../../../../layouts/hass-tabs-subpage";
|
||||||
|
|
||||||
import { mdiServerNetwork } from "@mdi/js";
|
import { mdiServerNetwork, mdiMathLog } from "@mdi/js";
|
||||||
|
|
||||||
export const configTabs: PageNavigation[] = [
|
export const configTabs: PageNavigation[] = [
|
||||||
{
|
{
|
||||||
@ -15,6 +15,11 @@ export const configTabs: PageNavigation[] = [
|
|||||||
path: `/config/zwave_js/dashboard`,
|
path: `/config/zwave_js/dashboard`,
|
||||||
iconPath: mdiServerNetwork,
|
iconPath: mdiServerNetwork,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
translationKey: "ui.panel.config.zwave_js.navigation.logs",
|
||||||
|
path: `/config/zwave_js/logs`,
|
||||||
|
iconPath: mdiMathLog,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@customElement("zwave_js-config-router")
|
@customElement("zwave_js-config-router")
|
||||||
@ -41,6 +46,10 @@ class ZWaveJSConfigRouter extends HassRouterPage {
|
|||||||
tag: "zwave_js-node-config",
|
tag: "zwave_js-node-config",
|
||||||
load: () => import("./zwave_js-node-config"),
|
load: () => import("./zwave_js-node-config"),
|
||||||
},
|
},
|
||||||
|
logs: {
|
||||||
|
tag: "zwave_js-logs",
|
||||||
|
load: () => import("./zwave_js-logs"),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -0,0 +1,157 @@
|
|||||||
|
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||||
|
import {
|
||||||
|
css,
|
||||||
|
html,
|
||||||
|
property,
|
||||||
|
customElement,
|
||||||
|
LitElement,
|
||||||
|
CSSResultArray,
|
||||||
|
internalProperty,
|
||||||
|
query,
|
||||||
|
} from "lit-element";
|
||||||
|
import "@polymer/paper-listbox/paper-listbox";
|
||||||
|
import "@polymer/paper-dropdown-menu/paper-dropdown-menu";
|
||||||
|
import {
|
||||||
|
fetchZWaveJSLogConfig,
|
||||||
|
setZWaveJSLogLevel,
|
||||||
|
subscribeZWaveJSLogs,
|
||||||
|
ZWaveJSLogConfig,
|
||||||
|
} from "../../../../../data/zwave_js";
|
||||||
|
import { SubscribeMixin } from "../../../../../mixins/subscribe-mixin";
|
||||||
|
import { HomeAssistant, Route } from "../../../../../types";
|
||||||
|
import { configTabs } from "./zwave_js-config-router";
|
||||||
|
import "../../../../../layouts/hass-tabs-subpage";
|
||||||
|
import { haStyle } from "../../../../../resources/styles";
|
||||||
|
|
||||||
|
@customElement("zwave_js-logs")
|
||||||
|
class ZWaveJSLogs extends SubscribeMixin(LitElement) {
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property({ type: Object }) public route!: Route;
|
||||||
|
|
||||||
|
@property({ type: Boolean }) public narrow!: boolean;
|
||||||
|
|
||||||
|
@property() public configEntryId!: string;
|
||||||
|
|
||||||
|
@internalProperty() private _logConfig?: ZWaveJSLogConfig;
|
||||||
|
|
||||||
|
@query("textarea", true) private _textarea?: HTMLTextAreaElement;
|
||||||
|
|
||||||
|
public hassSubscribe(): Array<UnsubscribeFunc | Promise<UnsubscribeFunc>> {
|
||||||
|
return [
|
||||||
|
subscribeZWaveJSLogs(this.hass, this.configEntryId, (log) => {
|
||||||
|
if (!this.hasUpdated) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Array.isArray(log.message)) {
|
||||||
|
for (const line of log.message) {
|
||||||
|
this._textarea!.value += `${line}\n`;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this._textarea!.value += `${log.message}\n`;
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
return html`
|
||||||
|
<hass-tabs-subpage
|
||||||
|
.hass=${this.hass}
|
||||||
|
.narrow=${this.narrow}
|
||||||
|
.route=${this.route}
|
||||||
|
.tabs=${configTabs}
|
||||||
|
>
|
||||||
|
<div class="container">
|
||||||
|
<ha-card>
|
||||||
|
<div class="card-header">
|
||||||
|
<h1>
|
||||||
|
${this.hass.localize("ui.panel.config.zwave_js.logs.title")}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div class="card-content">
|
||||||
|
${this._logConfig
|
||||||
|
? html`
|
||||||
|
<paper-dropdown-menu
|
||||||
|
dynamic-align
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.zwave_js.logs.log_level"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<paper-listbox
|
||||||
|
slot="dropdown-content"
|
||||||
|
.selected=${this._logConfig.level}
|
||||||
|
attr-for-selected="value"
|
||||||
|
@iron-select=${this._dropdownSelected}
|
||||||
|
>
|
||||||
|
<paper-item value="error">Error</paper-item>
|
||||||
|
<paper-item value="warn">Warn</paper-item>
|
||||||
|
<paper-item value="info">Info</paper-item>
|
||||||
|
<paper-item value="verbose">Verbose</paper-item>
|
||||||
|
<paper-item value="debug">Debug</paper-item>
|
||||||
|
<paper-item value="silly">Silly</paper-item>
|
||||||
|
</paper-listbox>
|
||||||
|
</paper-dropdown-menu>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
|
</div>
|
||||||
|
</ha-card>
|
||||||
|
<textarea readonly></textarea>
|
||||||
|
</div>
|
||||||
|
</hass-tabs-subpage>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected firstUpdated(changedProps) {
|
||||||
|
super.firstUpdated(changedProps);
|
||||||
|
this._fetchData();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _fetchData() {
|
||||||
|
if (!this.configEntryId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._logConfig = await fetchZWaveJSLogConfig(
|
||||||
|
this.hass!,
|
||||||
|
this.configEntryId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _dropdownSelected(ev) {
|
||||||
|
if (ev.target === undefined || this._logConfig === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this._logConfig.level === ev.target.selected) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setZWaveJSLogLevel(this.hass!, this.configEntryId, ev.target.selected);
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResultArray {
|
||||||
|
return [
|
||||||
|
haStyle,
|
||||||
|
css`
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
textarea {
|
||||||
|
flex-grow: 1;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
ha-card {
|
||||||
|
margin: 16px 0;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"zwave_js-logs": ZWaveJSLogs;
|
||||||
|
}
|
||||||
|
}
|
@ -2562,7 +2562,8 @@
|
|||||||
},
|
},
|
||||||
"zwave_js": {
|
"zwave_js": {
|
||||||
"navigation": {
|
"navigation": {
|
||||||
"network": "Network"
|
"network": "Network",
|
||||||
|
"logs": "Logs"
|
||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"network": "Network",
|
"network": "Network",
|
||||||
@ -2649,6 +2650,10 @@
|
|||||||
"in_progress": "The device is being interviewed. This may take some time.",
|
"in_progress": "The device is being interviewed. This may take some time.",
|
||||||
"interview_failed": "The device interview failed. Additional information may be available in the logs.",
|
"interview_failed": "The device interview failed. Additional information may be available in the logs.",
|
||||||
"interview_complete": "Device interview complete."
|
"interview_complete": "Device interview complete."
|
||||||
|
},
|
||||||
|
"logs": {
|
||||||
|
"title": "Z-Wave JS Logs",
|
||||||
|
"log_level": "Log Level"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user