Skip to content

Commit 3954534

Browse files
committed
toMatterAccessory()
1 parent 2f1a8a3 commit 3954534

4 files changed

Lines changed: 123 additions & 9 deletions

File tree

src/accessory/abstract/base.ts

Lines changed: 89 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { MatterAccessory } from 'homebridge';
2+
13
import { MQTTAccessory } from './mqtt.js';
24

35
import { Battery } from '../addons/battery.js';
@@ -10,26 +12,38 @@ import { strings } from '../../i18n/i18n.js';
1012

1113
import { CharacteristicKey } from '../../model/enums.js';
1214
import { HomeKitCharacteristicKey } from '../../model/homekit.js';
15+
import { MATTER_SERIAL_MAX_LEN, MatterType } from '../../model/matter.js';
1316
import { BaseAccessoryConfig, MQTTAccessoryDependency } from '../../model/types.js';
1417

1518
import getVersion from '../../tools/version.js';
1619

1720
export abstract class BaseAccessory<C extends BaseAccessoryConfig = BaseAccessoryConfig> extends MQTTAccessory<C> {
1821

22+
private _UUID?: string;
23+
24+
private readonly manufacturer: string;
25+
private readonly model: string;
26+
private readonly serialNumber: string;
27+
private readonly softwareVersion: string;
28+
1929
constructor(dependency: MQTTAccessoryDependency<C>) {
2030
super(dependency);
2131

32+
this.manufacturer = dependency.config.info.manufacturer ?? PLATFORM_NAME;
33+
this.model = dependency.config.info.model ?? dependency.config.info.type;
34+
this.serialNumber = this.identifier.length <= MATTER_SERIAL_MAX_LEN ? this.identifier : this.identifier.substring(0, MATTER_SERIAL_MAX_LEN - 1) + '…';
35+
this.softwareVersion = dependency.config.info.version ?? getVersion();
36+
2237
if (!dependency.isGrouped) {
23-
this.homekitAccessory.getService(this.Service.AccessoryInformation)!
24-
.setCharacteristic(this.Characteristic.Name, dependency.config.info.name)
25-
.setCharacteristic(this.Characteristic.ConfiguredName, dependency.config.info.name)
26-
.setCharacteristic(this.Characteristic.Manufacturer, dependency.config.info.manufacturer ?? PLATFORM_NAME)
27-
.setCharacteristic(this.Characteristic.Model, dependency.config.info.model ?? dependency.config.info.type)
28-
.setCharacteristic(this.Characteristic.SerialNumber, dependency.config.info.serialNumber ?? this.identifier)
29-
.setCharacteristic(this.Characteristic.FirmwareRevision, dependency.config.info.version ?? getVersion());
38+
this.homekitAccessory.getService(this.Service.AccessoryInformation)!
39+
.setCharacteristic(this.Characteristic.Name, dependency.config.info.name)
40+
.setCharacteristic(this.Characteristic.ConfiguredName, dependency.config.info.name)
41+
.setCharacteristic(this.Characteristic.Manufacturer, this.manufacturer)
42+
.setCharacteristic(this.Characteristic.Model, this.model)
43+
.setCharacteristic(this.Characteristic.SerialNumber, dependency.config.info.serialNumber ?? this.identifier)
44+
.setCharacteristic(this.Characteristic.FirmwareRevision, this.softwareVersion);
3045
}
3146

32-
3347
this.setup(HomeKitCharacteristicKey.StatusActive, true,
3448
'topicGetStatusActive',
3549
this.bindOnUpdateBooleanSingle(HomeKitCharacteristicKey.StatusActive, 'valueStatusActive',
@@ -42,4 +56,71 @@ export abstract class BaseAccessory<C extends BaseAccessoryConfig = BaseAccessor
4256
override isOptionalCharacteristic(key: CharacteristicKey): boolean {
4357
return super.isOptionalCharacteristic(key) || isOptionalHKCharacteristic(key, this.config.info.type);
4458
}
59+
60+
protected getMatterType(): MatterType | undefined {
61+
return undefined;
62+
};
63+
64+
private get matter() {
65+
const matter = this.dependency.getMatter();
66+
if (matter === undefined) {
67+
throw new Error(`${this.displayName} unable to get MatterAPI instance`);
68+
}
69+
return matter;
70+
}
71+
72+
private get deviceType() {
73+
74+
const type = this.getMatterType();
75+
if (type !== undefined) {
76+
return this.matter.deviceTypes[type];
77+
}
78+
79+
throw new Error(`${this.getMatterType.name} not implemented for ${this.getHomeKitType()}`);
80+
}
81+
82+
public get UUID(): string {
83+
if (!this._UUID) {
84+
this._UUID = this.matter.uuid.generate(this.identifier);
85+
}
86+
return this._UUID;
87+
}
88+
89+
protected get clusters(): MatterAccessory['clusters'] | undefined {
90+
return undefined;
91+
}
92+
93+
protected get handlers(): MatterAccessory['handlers'] | undefined {
94+
return undefined;
95+
}
96+
97+
protected get parts(): MatterAccessory['parts'] | undefined {
98+
return undefined; // Use this for sensors and groups
99+
}
100+
101+
public toMatterAccessory(): MatterAccessory {
102+
return {
103+
UUID: this.UUID,
104+
displayName: this.displayName,
105+
deviceType: this.deviceType,
106+
serialNumber: this.serialNumber,
107+
manufacturer: this.manufacturer,
108+
model: this.model,
109+
context: {
110+
UUID: this.UUID,
111+
deviceType: this.deviceType,
112+
displayName: this.displayName,
113+
serialNumber: this.serialNumber,
114+
manufacturer: this.manufacturer,
115+
model: this.model,
116+
softwareVersion: this.softwareVersion,
117+
clusters: this.clusters,
118+
handlers: this.handlers,
119+
parts: this.parts,
120+
},
121+
clusters: this.clusters,
122+
handlers: this.handlers,
123+
parts: this.parts,
124+
};
125+
}
45126
}

src/accessory/abstract/mqtt.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export abstract class MQTTAccessory<C extends MQTTAccessoryConfig> extends Commo
2020
private readonly homekitService: Service;
2121

2222
constructor(
23-
private readonly dependency: MQTTAccessoryDependency<C>,
23+
protected readonly dependency: MQTTAccessoryDependency<C>,
2424
) {
2525
super(dependency.config.info.name);
2626

src/homebridge/platform.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,24 @@ export class HomebridgeEasyMQTT implements DynamicPlatformPlugin {
154154
continue;
155155
}
156156

157+
const dependency: AccessoryDependency = {
158+
protocol: accessoryConfig.info.protocol,
159+
getHomeKit: () => undefined,
160+
getMatter: () => this.api.matter,
161+
log: this.log,
162+
};
163+
164+
const accessory = createAccessory(dependency, accessoryConfig);
165+
166+
if (accessory === undefined) {
167+
continue;
168+
}
169+
170+
await this.registerMatterAccessory(accessory.toMatterAccessory());
171+
172+
matterKeepIdentifiers.add(accessory.UUID);
173+
this.mqttAccessories.push(accessory);
174+
157175
} else {
158176
this.log.warning(strings.startup.unsupportedProtocol, `'${accessoryConfig.info.protocol}'`, printableValues(Protocol));
159177
continue;

src/model/matter.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
export const MATTER_SERIAL_MAX_LEN = 32;
2+
3+
export enum MatterClusterKey {
4+
onOff = 'onOff',
5+
}
6+
7+
export enum MatterValueKey {
8+
onOff = 'onOff',
9+
}
10+
11+
export enum MatterType {
12+
OnOffSwitch = 'OnOffSwitch',
13+
}
14+
15+
export type MatterValue = boolean | number;

0 commit comments

Comments
 (0)