Skip to content

Commit

Permalink
Update 27.12.2024 (#263)
Browse files Browse the repository at this point in the history
* Allows to trigger commands via matter also when state already matches the value

* Allows to trigger commands via matter also when state already matches the value

* Update matter.js

* Introduce fabric label

* Detects state deletion for ioBroker devices and updates UI

* Only check manual pairingcode when set

* Optimizations and restructuring

* Do not show commissioning QR codes in ioBroker log

* Use Fabric label to try to detect if ioBroker is the controller

* Adjust logging

* Fixes displaying error details for devices and bridges

* Fixes displaying error details for devices and bridges

* Return "ok" when commissioning is ok

* Readme

* Revert "Return "ok" when commissioning is ok"

This reverts commit 1c170b3.
  • Loading branch information
Apollon77 authored Dec 28, 2024
1 parent 489299e commit 399bf69
Show file tree
Hide file tree
Showing 23 changed files with 274 additions and 166 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ TODO

## Prerequisites to use this adapter

### Used adapters and apps
If you want to use the iobroker Visu App for device pairing you need:
* ioBroker Visu App at least v1.3.1
* iot Adapter at least v3.4.4

### General prerequisites
* One instance of the adapter is bound to one host (aka IP). Multiple instances require a multi-host setup.
* Make sure IPv6 is enabled in your network and the host you use this adapter on has an IPv6 address
Expand Down Expand Up @@ -220,6 +225,17 @@ TBD
-->

## Changelog

### __WORK IN PROGRESS__
* (@Apollon77) Allows to trigger commands via matter also when state already matches the value
* (@Apollon77) Sets and updates the fabric label for paired devices (default is "ioBroker matter.X")
* (@Apollon77) Detects state deletion for ioBroker devices and updates device in UI to show device state
* (@Apollon77) Several optimizations on commissioning
* (@Apollon77) Do not show commissioning QR codes in ioBroker log
* (@Apollon77) Use Fabric label to try to detect if ioBroker is the controller
* (@Apollon77) Fixes displaying error details for devices and bridges
* (@Apollon77) Fixes the device and type detection logic

### 0.3.2 (2024-12-21)
* (@Apollon77) Fixes several discovery issues

Expand Down
3 changes: 2 additions & 1 deletion io-package.json
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,8 @@
"debug": false,
"login": "",
"pass": "",
"defaultBridge": ""
"defaultBridge": "",
"controllerFabricLabel": ""
},
"objects": [],
"instanceObjects": [
Expand Down
134 changes: 67 additions & 67 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@
"url": "https://github.com/ioBroker/ioBroker.matter"
},
"optionalDependencies": {
"@matter/nodejs-ble": "0.12.0-alpha.0-20241220-755393a73"
"@matter/nodejs-ble": "0.12.0-alpha.0-20241227-9e7d81837"
},
"dependencies": {
"@iobroker/adapter-core": "^3.2.3",
"@iobroker/i18n": "^0.3.1",
"@iobroker/dm-utils": "^0.6.11",
"@iobroker/type-detector": "^4.1.1",
"@matter/main": "0.12.0-alpha.0-20241220-755393a73",
"@matter/nodejs": "0.12.0-alpha.0-20241220-755393a73",
"@project-chip/matter.js": "0.12.0-alpha.0-20241220-755393a73",
"@matter/main": "0.12.0-alpha.0-20241227-9e7d81837",
"@matter/nodejs": "0.12.0-alpha.0-20241227-9e7d81837",
"@project-chip/matter.js": "0.12.0-alpha.0-20241227-9e7d81837",
"axios": "^1.7.9",
"jsonwebtoken": "^9.0.2"
},
Expand Down
1 change: 1 addition & 0 deletions src/ioBrokerStorageTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export interface MatterAdapterConfig extends ioBroker.AdapterConfig {
login: string;
pass: string;
defaultBridge: string;
controllerFabricLabel: string;
}

export interface BridgeDeviceDescription {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/JsonConfigUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export function convertDataToJsonConfig(data: StructuredJsonFormData): JsonFormS
}

if (panelCount === 1) {
return items[`_tab_${Object.keys(data)[0]}`];
return Object.values(items)[0];
}

return {
Expand Down
4 changes: 2 additions & 2 deletions src/lib/SubscribeManager.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export type SubscribeCallback = (state: ioBroker.State) => Promise<void>;
export type SubscribeCallback = (state: ioBroker.State | null | undefined) => Promise<void>;

class SubscribeManager {
/** List of all registered subscribed state ids. */
Expand All @@ -14,7 +14,7 @@ class SubscribeManager {

static async observer(id: string, state: ioBroker.State | null | undefined): Promise<void> {
const callbacks = SubscribeManager.subscribes.get(id);
if (callbacks !== undefined && state) {
if (callbacks !== undefined) {
for (const callback of callbacks) {
await callback(state);
}
Expand Down
26 changes: 24 additions & 2 deletions src/lib/devices/DeviceStateObject.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { DetectorState, StateType } from '@iobroker/type-detector';
import SubscribeManager from '../SubscribeManager';
import { EventEmitter } from 'events';

export enum ValueType {
String = 'string',
Expand Down Expand Up @@ -146,7 +147,7 @@ function asCommonType(type: StateType | undefined): ioBroker.CommonType {
return 'mixed';
}

export class DeviceStateObject<T> {
export class DeviceStateObject<T> extends EventEmitter {
value?: T;
updateHandler?: (object: DeviceStateObject<T>) => Promise<void>;
isEnum = false;
Expand All @@ -161,6 +162,7 @@ export class DeviceStateObject<T> {

#isIoBrokerState: boolean;
#id: string;
#valid: boolean = true;

static async create<T>(
adapter: ioBroker.Adapter,
Expand All @@ -183,6 +185,7 @@ export class DeviceStateObject<T> {
protected readonly isEnabled: () => boolean,
protected readonly unitConversionMap: { [key: string]: (value: number, toDefaultUnit: boolean) => number } = {},
) {
super();
this.isEnum = valueType === ValueType.Enum;
this.#isIoBrokerState = state.isIoBrokerState;
this.#id = state.id;
Expand Down Expand Up @@ -266,6 +269,10 @@ export class DeviceStateObject<T> {
return this.object?.common.role ?? 'state';
}

get isValid(): boolean {
return this.#valid;
}

protected parseMinMax(percent = false): void {
if (!this.object) {
throw new Error(`Object not initialized`);
Expand Down Expand Up @@ -460,7 +467,22 @@ export class DeviceStateObject<T> {
}
}

updateState = async (state: ioBroker.State, ignoreEnabledStatus = false): Promise<void> => {
updateState = async (state: ioBroker.State | null | undefined, ignoreEnabledStatus = false): Promise<void> => {
if (!state) {
if (this.#isIoBrokerState) {
// State expired or object got deleted, verify if the object still exists
const obj = await this.adapter.getForeignObjectAsync(this.#id);
if (!obj) {
this.#valid = false;
this.emit('validChanged');
}
}
return;
} else if (!this.#valid) {
this.#valid = true;
this.emit('validChanged');
}

if (state.ack !== this.#isIoBrokerState || (!this.isEnabled() && !ignoreEnabledStatus)) {
// For Device implementation only acked values are considered to be forwarded to the controllers
return;
Expand Down
Loading

0 comments on commit 399bf69

Please sign in to comment.