From 5cc06917a476ba194f509922e84bb29c82d967b6 Mon Sep 17 00:00:00 2001 From: Ingo Fischer Date: Sat, 14 Dec 2024 19:28:18 +0100 Subject: [PATCH] Improve details and error infos --- src/main.ts | 8 +- src/matter/BridgedDevicesNode.ts | 83 ++++++++++++++----- src/matter/DeviceNode.ts | 16 ++-- src/matter/to-matter/GenericDeviceToMatter.ts | 12 +-- 4 files changed, 84 insertions(+), 35 deletions(-) diff --git a/src/main.ts b/src/main.ts index 1378eff..d7e20aa 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1215,6 +1215,9 @@ export class MatterAdapter extends utils.Adapter { if (obj !== undefined) { await matterBridge.start(); } + } else { + this.log.error(`Cannot create device for ${bridge._id}`); + this.#devices.set(bridge._id, { error: 'Cannot create bridge' }); } } else { const config = await this.prepareMatterBridgeConfiguration( @@ -1261,6 +1264,9 @@ export class MatterAdapter extends utils.Adapter { if (obj !== undefined) { await matterDevice.start(); } + } else { + this.log.error(`Cannot create device for ${device._id}`); + this.#devices.set(device._id, { error: 'Cannot create device' }); } } else { const config = await this.prepareMatterDeviceConfiguration( @@ -1356,7 +1362,7 @@ export class MatterAdapter extends utils.Adapter { __header__error: 'Error information', __text__info: `${type === 'bridge' ? 'Bridge' : 'Device'} is in error state. Fix the error before enabling it again`, __text__error: error, - __text__uuid: `UUID: ${uuid}`, + uuid: `UUID: ${uuid}`, }, }; diff --git a/src/matter/BridgedDevicesNode.ts b/src/matter/BridgedDevicesNode.ts index b8cf192..8270c39 100644 --- a/src/matter/BridgedDevicesNode.ts +++ b/src/matter/BridgedDevicesNode.ts @@ -218,7 +218,7 @@ class BridgedDevices extends BaseServerNode { await this.serverNode.add(this.#aggregator); let erroredCount = 0; - for (const { device, error, options: deviceOptions } of this.#devices.values()) { + for (const [uuid, { device, error, options: deviceOptions }] of this.#devices.entries()) { if (!device || error) { erroredCount++; this.adapter.log.info(`Skipping device ${deviceOptions.uuid} because could not be initialized.`); @@ -230,6 +230,11 @@ class BridgedDevices extends BaseServerNode { erroredCount++; const errorText = inspect(error, { depth: 10 }); this.adapter.log.error(`Error adding device ${deviceOptions.uuid} to bridge: ${errorText}`); + const details = this.#devices.get(uuid); + if (details !== undefined) { + details.error = error.message; + this.#devices.set(uuid, details); + } } } if (erroredCount === this.#devices.size) { @@ -256,23 +261,30 @@ class BridgedDevices extends BaseServerNode { const newDeviceList = new Set(); for (const { device, error, options: deviceOptions } of options.devices.values()) { - this.adapter.log.debug(`Processing device ${deviceOptions.uuid} "${deviceOptions.name}" in bridge`); - const existingDevice = this.#devices.get(deviceOptions.uuid)?.device; + const uuid = deviceOptions.uuid; + this.adapter.log.debug(`Processing device ${uuid} "${deviceOptions.name}" in bridge`); + const existingDevice = this.#devices.get(uuid)?.device; if (existingDevice) { - newDeviceList.add(deviceOptions.uuid); - this.adapter.log.debug(`Device ${deviceOptions.uuid} already in bridge. Sync Configuration`); + newDeviceList.add(uuid); + this.adapter.log.debug(`Device ${uuid} already in bridge. Sync Configuration`); existingDevice.applyConfiguration(deviceOptions); continue; } if (!device || error) { - this.adapter.log.info(`Skipping device ${deviceOptions.uuid} because could not be initialized.`); - this.#devices.set(deviceOptions.uuid, { device, error, options: deviceOptions }); + this.adapter.log.info(`Skipping device ${uuid} because could not be initialized.`); + this.#devices.set(uuid, { device, error, options: deviceOptions }); continue; } - newDeviceList.add(deviceOptions.uuid); - this.adapter.log.info(`Adding device ${deviceOptions.uuid} "${deviceOptions.name}" to bridge`); - await this.addBridgedIoBrokerDevice(device, deviceOptions); - this.#devices.set(deviceOptions.uuid, { device, options: deviceOptions }); + newDeviceList.add(uuid); + this.adapter.log.info(`Adding device ${uuid} "${deviceOptions.name}" to bridge`); + try { + await this.addBridgedIoBrokerDevice(device, deviceOptions); + this.#devices.set(uuid, { device, options: deviceOptions }); + } catch (error) { + const errorText = inspect(error, { depth: 10 }); + this.adapter.log.error(`Error adding device ${uuid} to bridge: ${errorText}`); + this.#devices.set(uuid, { error: error.message, options: deviceOptions }); + } } for (const [uuid, endpoints] of this.#deviceEndpoints) { @@ -356,29 +368,54 @@ class BridgedDevices extends BaseServerNode { } getDeviceDetails(message: ioBroker.MessagePayload): StructuredJsonFormData { - const bridgedDeviceUuid = message.bridgedDeviceUuid as string; + const bridgedDeviceUuid = message.bridgedDeviceUuid; const details: StructuredJsonFormData = {}; - const isError = true; - if (isError) { + const { error } = this.#devices.get(bridgedDeviceUuid) ?? {}; + if (error) { details.error = { __header__error: 'Error information', __text__info: `Bridged Device is in error state. Fix the error before enabling it again`, - __text__uuid: `UUID: ${bridgedDeviceUuid} on ${this.uuid}`, + uuid: `UUID: ${bridgedDeviceUuid} on ${this.uuid}`, + __text__error: `Error: ${error}`, }; } - details.info = { - __header__info: 'Device information', - __text__uuid: `UUID: ${bridgedDeviceUuid}`, - }; + if (bridgedDeviceUuid !== undefined) { + const mappingDevice = this.#mappingDevices.get(bridgedDeviceUuid); - const mappingDevice = this.#mappingDevices.get(bridgedDeviceUuid); + if (mappingDevice) { + return { + ...details, + ...mappingDevice?.getDeviceDetails(), + }; + } - return { - ...details, - ...mappingDevice?.getDeviceDetails(), + return { + ...details, + noDevice: { + __header__error: 'Device not created', + uuid: `UUID: ${bridgedDeviceUuid} on ${this.uuid}`, + __text__error: `Error: The device does not exist on this bridge`, + }, + }; + } + + details.overview = { + __header__info: 'Bridge Overview', + uuid: this.uuid, + port: this.port, + deviceName: this.#parameters.deviceName, + productName: this.#parameters.productName, + vendorId: this.#parameters.vendorId, + productId: this.#parameters.productId, + numberOfBridgedDevices: [...this.#devices.values()].reduce( + (count, { device }) => count + (device ? 1 : 0), + 0, + ), }; + + return details; } } diff --git a/src/matter/DeviceNode.ts b/src/matter/DeviceNode.ts index 8002b2f..df337e3 100644 --- a/src/matter/DeviceNode.ts +++ b/src/matter/DeviceNode.ts @@ -213,13 +213,17 @@ class Device extends BaseServerNode { } getDeviceDetails(_message: ioBroker.MessagePayload): StructuredJsonFormData { - const details: StructuredJsonFormData = { - information: { - __header__info: 'Device information', - __text__uuid: `UUID: ${this.uuid}`, - }, + const details: StructuredJsonFormData = {}; + + details.overview = { + __header__info: 'Device Overview', + uuid: this.uuid, + port: this.port, + deviceName: this.#parameters.deviceName, + productName: this.#parameters.productName, + vendorId: this.#parameters.vendorId, + productId: this.#parameters.productId, }; - return { ...details, ...this.#mappingDevice?.getDeviceDetails(), diff --git a/src/matter/to-matter/GenericDeviceToMatter.ts b/src/matter/to-matter/GenericDeviceToMatter.ts index 5877144..661e0e7 100644 --- a/src/matter/to-matter/GenericDeviceToMatter.ts +++ b/src/matter/to-matter/GenericDeviceToMatter.ts @@ -109,9 +109,11 @@ export abstract class GenericDeviceToMatter { const details: StructuredJsonFormData = {}; details.detectedStates = { + __header__device: 'Detected ioBroker Device type', + deviceType: this.ioBrokerDevice.deviceType, __header__states: 'Detected device states', - __text__info: 'The following states were detected for this device.', - __devider__info: true, + __text__info: 'The following states were detected for this device:', + __divider__info: true, ...this.ioBrokerDevice.getStates(true, true), }; @@ -120,11 +122,11 @@ export abstract class GenericDeviceToMatter { details.endpoints = { __header__endpoints: 'Device Endpoints', __text__info: 'The following Matter endpoints are mapped for this device.', - __devider__info: true, + __divider__info: true, }; endpoints.forEach(endpoint => { - details.endpoints.__header__endpoint = `Endpoint ${endpoint.number}`; - details.endpoints.__text__deviceType = endpoint.type.name; + details.endpoints[`__header__endpoint${endpoint.number}`] = `Endpoint ${endpoint.number}`; + details.endpoints[`dt${endpoint.number}__deviceType`] = endpoint.type.name; // TODO expose potentially more }); }