Skip to content

Commit

Permalink
Update 09.01.25 (#293)
Browse files Browse the repository at this point in the history
* Deps and updates

* fix Generic Switch for controller

* Add serialnumber

* changelog

* move controller up in settings

* prerelease still do not work correctly in CI

so default back to patch
  • Loading branch information
Apollon77 authored Jan 9, 2025
1 parent 9709031 commit bae7df0
Show file tree
Hide file tree
Showing 9 changed files with 209 additions and 363 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/create-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
versionBump:
description: 'Type of version bump'
required: true
default: 'prerelease'
default: 'patch'
type: choice
options:
- prerelease
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,10 @@ TBD
### **WORK IN PROGRESS**
* (@GermanBluefox) Fixed GUI errors
* (@GermanBluefox) Added `Controller fabric label` to configuration
* (@GermanBluefox) Solution for QR-Code scanning on non HTTPS pages
* (@GermanBluefox) Added solution for QR-Code scanning on non HTTPS pages
* (@Apollon77) Fixed Generic Switch Device type for controller
* (@Apollon77) Fixed Controller BLE initialization and activation
* (@Apollon77) Added serialNumber to all devices and bridges for better device re-detection by controllers

### 0.3.4 (2024-12-31)
* (@Apollon77) Updates matter.js to address several issues
Expand Down
386 changes: 108 additions & 278 deletions package-lock.json

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,35 +23,35 @@
"url": "https://github.com/ioBroker/ioBroker.matter"
},
"optionalDependencies": {
"@matter/nodejs-ble": "0.12.0-alpha.0-20241231-9ac20db97"
"@matter/nodejs-ble": "0.12.0-alpha.0-20250108-7ae2a767d"
},
"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-20241231-9ac20db97",
"@matter/nodejs": "0.12.0-alpha.0-20241231-9ac20db97",
"@project-chip/matter.js": "0.12.0-alpha.0-20241231-9ac20db97",
"@matter/main": "0.12.0-alpha.0-20250108-7ae2a767d",
"@matter/nodejs": "0.12.0-alpha.0-20250108-7ae2a767d",
"@project-chip/matter.js": "0.12.0-alpha.0-20250108-7ae2a767d",
"axios": "^1.7.9",
"jsonwebtoken": "^9.0.2"
},
"devDependencies": {
"@alcalzone/release-script": "^3.8.0",
"@alcalzone/release-script-plugin-iobroker": "^3.7.2",
"@alcalzone/release-script-plugin-license": "^3.7.0",
"@iobroker/build-tools": "^2.0.12",
"@iobroker/build-tools": "^2.0.14",
"@iobroker/dev-server": "^0.7.3",
"@iobroker/eslint-config": "^1.0.0",
"@iobroker/legacy-testing": "^2.0.1",
"@iobroker/types": "^7.0.6",
"@types/jsonwebtoken": "^9.0.7",
"@types/node": "^22.10.2",
"@types/node": "^22.10.5",
"chai": "^4.5.0",
"colorette": "^2.0.20",
"mocha": "^11.0.1",
"puppeteer": "^23.11.1",
"typescript": "~5.7.2"
"typescript": "~5.7.3"
},
"bugs": {
"url": "https://github.com/ioBroker/ioBroker.matter/issues"
Expand Down
50 changes: 25 additions & 25 deletions src-admin/src/Tabs/Options.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,31 @@ class Options extends Component<OptionsProps, OptionsState> {
</FormControl>
</Box>

<div style={{ marginTop: 50 }}>
<Typography sx={styles.header}>{I18n.t('Controller Settings')}</Typography>
<TextField
variant="standard"
label={I18n.t('Controller fabric label')}
value={this.props.native.controllerFabricLabel}
type="text"
onChange={e => this.props.onChange('controllerFabricLabel', e.target.value)}
margin="normal"
slotProps={{
input: {
endAdornment: this.props.native.controllerFabricLabel ? (
<IconButton
size="small"
onClick={() => this.props.onChange('controllerFabricLabel', '')}
>
<Clear />
</IconButton>
) : null,
},
}}
style={styles.input}
/>
</div>

<div style={{ marginTop: 50 }}>
<Typography sx={styles.header}>{I18n.t('Cloud Account')}</Typography>
<InfoBox type="info">
Expand Down Expand Up @@ -572,31 +597,6 @@ class Options extends Component<OptionsProps, OptionsState> {
/>
</div>

<div style={{ marginTop: 50 }}>
<Typography sx={styles.header}>{I18n.t('Controller Settings')}</Typography>
<TextField
variant="standard"
label={I18n.t('Controller fabric label')}
value={this.props.native.controllerFabricLabel}
type="text"
onChange={e => this.props.onChange('controllerFabricLabel', e.target.value)}
margin="normal"
slotProps={{
input: {
endAdornment: this.props.native.controllerFabricLabel ? (
<IconButton
size="small"
onClick={() => this.props.onChange('controllerFabricLabel', '')}
>
<Clear />
</IconButton>
) : null,
},
}}
style={styles.input}
/>
</div>

<div style={{ marginTop: 50 }}>
<Typography sx={styles.header}>{I18n.t('Maintenance Settings')}</Typography>
<Button
Expand Down
5 changes: 4 additions & 1 deletion src/matter/BridgedDevicesNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class BridgedDevices extends BaseServerNode {
if (mappingDevice) {
const name = mappingDevice.name;
const endpoints = mappingDevice.matterEndpoints;
const serialNumber = deviceOptions.uuid.replace(/-/g, '');
if (endpoints.length === 1 || deviceOptions.noComposed) {
let erroredCount = 0;
// When only one endpoint or non-composed we simply add all endpoints for itself to the bridge
Expand All @@ -94,6 +95,7 @@ class BridgedDevices extends BaseServerNode {
nodeLabel: matterName,
productName: matterName,
productLabel: name.substring(0, 64),
serialNumber,
uniqueId: md5(endpoint.id),
reachable: true,
});
Expand Down Expand Up @@ -133,6 +135,7 @@ class BridgedDevices extends BaseServerNode {
nodeLabel: matterName,
productName: matterName,
productLabel: name.substring(0, 64),
serialNumber,
uniqueId: md5(id),
reachable: true,
},
Expand Down Expand Up @@ -189,7 +192,7 @@ class BridgedDevices extends BaseServerNode {
const vendorId = this.#parameters.vendorId; // 0xfff1;
const productId = this.#parameters.productId; // 0x8000;

const uniqueId = this.#parameters.uuid.replace(/-/g, '').split('.').pop();
const uniqueId = this.#parameters.uuid.replace(/-/g, '');
if (uniqueId === undefined) {
throw new Error(`Could not determine device unique id from ${this.#parameters.uuid}`);
}
Expand Down
51 changes: 30 additions & 21 deletions src/matter/ControllerNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,37 +64,46 @@ class Controller implements GeneralNode {
}

init(): void {
this.applyConfiguration(this.#parameters);
}

applyConfiguration(config: MatterControllerConfig): MessageResponse {
const currentConfig: MatterControllerConfig = {
enabled: true,
defaultExposeMatterApplicationClusterData: false,
defaultExposeMatterSystemClusterData: false,
...(this.#parameters as Partial<MatterControllerConfig>),
};

this.#useBle = false;
if (config.ble !== currentConfig.ble || config.hciId !== currentConfig.hciId) {
if (this.#parameters.ble) {
if (
config.ble &&
((config.wifiSSID && config.wifiPassword) ||
(config.threadNetworkName !== undefined && config.threadOperationalDataSet !== undefined))
(this.#parameters.wifiSSID && this.#parameters.wifiPassword) ||
(this.#parameters.threadNetworkName !== undefined &&
this.#parameters.threadOperationalDataSet !== undefined)
) {
try {
const hciId = config.hciId === undefined ? undefined : parseInt(config.hciId);
const hciId = this.#parameters.hciId === undefined ? undefined : parseInt(this.#parameters.hciId);
Ble.get = singleton(() => new NodeJsBle({ hciId }));
this.#useBle = true;
} catch (error) {
this.#adapter.log.warn(`Failed to initialize BLE: ${error.message}`);
config.ble = false;
return {
error: `Can not adjust configuration and enable BLE because of error: ${error.message}`,
};
this.#parameters.ble = false;
return;
}
} else {
this.#adapter.log.warn(
`BLE enabled but no WiFi or Thread configuration provided. BLE will stay disabled.`,
);
this.#parameters.ble = false;
}
}
this.applyConfiguration(this.#parameters, true);
}

applyConfiguration(config: MatterControllerConfig, isInit = false): MessageResponse {
const currentConfig: MatterControllerConfig = {
enabled: true,
defaultExposeMatterApplicationClusterData: false,
defaultExposeMatterSystemClusterData: false,
...(this.#parameters as Partial<MatterControllerConfig>),
};

if (!isInit && (config.ble !== currentConfig.ble || config.hciId !== currentConfig.hciId)) {
this.#adapter.setTimeout(() => this.#adapter.restart(), 5000);
// Restart of the adapter needed
return {
error: `BLE configuration adjusted. The adapter will restart in 5 seconds.`,
};
}
this.#parameters = config;
return { result: true };
}
Expand Down
2 changes: 1 addition & 1 deletion src/matter/DeviceNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class Device extends BaseServerNode {
const productName = this.#deviceOptions.name || this.#parameters.productName;
const productId = this.#parameters.productId; // 0x8000;

const uniqueId = this.#parameters.uuid.replace(/-/g, '').split('.').pop();
const uniqueId = this.#parameters.uuid.replace(/-/g, '');
if (uniqueId === undefined) {
throw new Error(`Could not determine device unique id from ${this.#parameters.uuid}`);
}
Expand Down
57 changes: 29 additions & 28 deletions src/matter/to-iobroker/GenericSwitchToIoBroker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,51 +38,52 @@ export class GenericSwitchToIoBroker extends GenericDeviceToIoBroker {
this.#ioBrokerDevice = new ButtonSensor(
{ ...ChannelDetector.getPatterns().buttonSensor, isIoBrokerDevice: false } as DetectedDevice,
adapter,
this.enableDeviceTypeStates(),
this.enableMomentarySwitchDeviceTypeStates(),
);
} else {
// A Latching Switch (only other option) is mapped to a Socket
this.#ioBrokerDevice = new Socket(
{ ...ChannelDetector.getPatterns().socket, isIoBrokerDevice: false } as DetectedDevice,
adapter,
this.enableDeviceTypeStates(),
this.enableLatchingSwitchDeviceTypeStates(),
);
}
}

protected enableDeviceTypeStates(): DeviceOptions {
if (this.#ioBrokerDevice instanceof ButtonSensor) {
this.enableDeviceTypeStateForAttribute(PropertyType.Press, {
protected enableMomentarySwitchDeviceTypeStates(): DeviceOptions {
this.enableDeviceTypeStateForAttribute(PropertyType.Press, {
endpointId: this.appEndpoint.getNumber(),
clusterId: Switch.Cluster.id,
attributeName: 'currentPosition',
convertValue: value => value !== 0,
});

const hasLongPress = this.appEndpoint.getClusterClient(Switch.Complete)?.supportedFeatures
.momentarySwitchLongPress;
if (hasLongPress) {
this.enableDeviceTypeStateForEvent(PropertyType.PressLong, {
endpointId: this.appEndpoint.getNumber(),
clusterId: Switch.Cluster.id,
attributeName: 'currentPosition',
convertValue: value => value !== 0,
eventName: 'longPress',
convertValue: () => true,
});

const hasLongPress = this.appEndpoint.getClusterClient(Switch.Complete)?.supportedFeatures
.momentarySwitchLongPress;
if (hasLongPress) {
this.enableDeviceTypeStateForEvent(PropertyType.PressLong, {
endpointId: this.appEndpoint.getNumber(),
clusterId: Switch.Cluster.id,
eventName: 'longPress',
convertValue: () => true,
});
this.enableDeviceTypeStateForEvent(PropertyType.PressLong, {
endpointId: this.appEndpoint.getNumber(),
clusterId: Switch.Cluster.id,
eventName: 'longRelease',
convertValue: () => false,
});
}
} else {
this.enableDeviceTypeStateForAttribute(PropertyType.PowerActual, {
this.enableDeviceTypeStateForEvent(PropertyType.PressLong, {
endpointId: this.appEndpoint.getNumber(),
clusterId: Switch.Cluster.id,
attributeName: 'currentPosition',
convertValue: value => value !== 0,
eventName: 'longRelease',
convertValue: () => false,
});
}
return super.enableDeviceTypeStates();
}

protected enableLatchingSwitchDeviceTypeStates(): DeviceOptions {
this.enableDeviceTypeStateForAttribute(PropertyType.PowerActual, {
endpointId: this.appEndpoint.getNumber(),
clusterId: Switch.Cluster.id,
attributeName: 'currentPosition',
convertValue: value => value !== 0,
});

return super.enableDeviceTypeStates();
}
Expand Down

0 comments on commit bae7df0

Please sign in to comment.