Skip to content

Commit

Permalink
Homekit: Handle devices with multiple time the same features (GladysA…
Browse files Browse the repository at this point in the history
  • Loading branch information
bertrandda authored Oct 25, 2024
1 parent 35864b5 commit e6d4272
Show file tree
Hide file tree
Showing 5 changed files with 370 additions and 909 deletions.
28 changes: 26 additions & 2 deletions server/services/homekit/lib/buildAccessory.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,32 @@ function buildAccessory(device) {

const accessory = new this.hap.Accessory(device.name, device.id);
Object.keys(categories).forEach((category) => {
const service = this.buildService(device, categories[category], mappings[category]);
accessory.addService(service);
const serviceConfigs = [];

categories[category].forEach((cat) => {
if (
serviceConfigs.length > 0 &&
!serviceConfigs[serviceConfigs.length - 1].find(
(config) => config.category === cat.category && config.type === cat.type,
)
) {
serviceConfigs[serviceConfigs.length - 1].push(cat);

return;
}

serviceConfigs.push([cat]);
});

serviceConfigs.forEach((config, i) => {
const service = this.buildService(
device,
config,
mappings[category],
serviceConfigs.length > 1 ? `${category} ${i + 1}` : undefined,
);
accessory.addService(service);
});
});

return accessory.services.length <= 1 ? null : accessory;
Expand Down
17 changes: 7 additions & 10 deletions server/services/homekit/lib/buildService.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@ const sleep = promisify(setTimeout);
* @param {object} device - Gladys device to format as HomeKit accessory.
* @param {object} features - Device features to associate to service.
* @param {object} categoryMapping - Homekit mapping for the current device category.
* @param {string} subtype - Optional subtype if multiple same service.
* @returns {object} HomeKit service to expose.
* @example
* buildService(device, features, categoryMapping)
*/
function buildService(device, features, categoryMapping) {
function buildService(device, features, categoryMapping, subtype) {
const { Characteristic, CharacteristicEventTypes, Perms, Service } = this.hap;

const service = new Service[categoryMapping.service](device.name);
const service = new Service[categoryMapping.service](subtype ? features[0].name : device.name, subtype);

features.forEach((feature) => {
switch (`${feature.category}:${feature.type}`) {
Expand All @@ -51,8 +52,7 @@ function buildService(device, features, categoryMapping) {
status: ACTIONS_STATUS.PENDING,
value: value ? 1 : 0,
device: device.selector,
feature_category: feature.category,
feature_type: feature.type,
device_feature: feature.selector,
};
this.gladys.event.emit(EVENTS.ACTION.TRIGGERED, action);
callback();
Expand Down Expand Up @@ -107,8 +107,7 @@ function buildService(device, features, categoryMapping) {
),
),
device: device.selector,
feature_category: feature.category,
feature_type: feature.type,
device_feature: feature.selector,
};
this.gladys.event.emit(EVENTS.ACTION.TRIGGERED, action);
callback();
Expand Down Expand Up @@ -136,8 +135,7 @@ function buildService(device, features, categoryMapping) {
status: ACTIONS_STATUS.PENDING,
value: rgbToInt(rgb),
device: device.selector,
feature_category: feature.category,
feature_type: feature.type,
device_feature: feature.selector,
};
this.gladys.event.emit(EVENTS.ACTION.TRIGGERED, action);
callback();
Expand All @@ -161,8 +159,7 @@ function buildService(device, features, categoryMapping) {
status: ACTIONS_STATUS.PENDING,
value: rgbToInt(rgb),
device: device.selector,
feature_category: feature.category,
feature_type: feature.type,
device_feature: feature.selector,
};
this.gladys.event.emit(EVENTS.ACTION.TRIGGERED, action);
callback();
Expand Down
Loading

0 comments on commit e6d4272

Please sign in to comment.