homebridge-loxone-proxy
Version:
Homebridge Dynamic Platform Plugin which exposes a Loxone System to Homekit.
161 lines • 7.05 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.LoxonePlatform = void 0;
const LoxoneHandler_1 = __importDefault(require("./loxone/LoxoneHandler"));
class LoxonePlatform {
constructor(log, config, api) {
this.log = log;
this.config = config;
this.api = api;
this.AccessoryCount = 1;
this.msInfo = {};
this.LoxoneItems = {};
this.Service = this.api.hap.Service;
this.Characteristic = this.api.hap.Characteristic;
this.accessories = [];
this.mappedAccessories = new Set();
this.usedNames = new Set();
this.accessoryNameMap = new Map();
this.api.on('didFinishLaunching', async () => {
await this.LoxoneInit();
});
}
async LoxoneInit() {
this.usedNames.clear();
this.accessoryNameMap.clear();
this.LoxoneHandler = new LoxoneHandler_1.default(this);
await this.waitForLoxoneConfig();
this.log.debug(`[LoxoneInit] Got Structure File; Modified: ${this.LoxoneHandler.loxdata.lastModified}`);
this.parseLoxoneConfig(this.LoxoneHandler.loxdata);
this.log.info('[LoxoneInit] Loxone Platform initialized');
}
waitForLoxoneConfig() {
return new Promise((resolve) => {
const i = setInterval(() => {
if (this.LoxoneHandler.loxdata) {
clearInterval(i);
resolve();
}
}, 500);
});
}
parseLoxoneConfig(config) {
var _a, _b, _c, _d, _e, _f;
this.msInfo = config.msInfo;
const rooms = { ...config.rooms };
const cats = { ...config.cats };
this.LoxoneItems = { ...config.controls };
for (const uuid in this.LoxoneItems) {
const item = this.LoxoneItems[uuid];
item.room = (_b = (_a = rooms[item.room]) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : 'undefined';
item.catIcon = (_d = (_c = cats[item.cat]) === null || _c === void 0 ? void 0 : _c.image) !== null && _d !== void 0 ? _d : 'undefined';
item.cat = (_f = (_e = cats[item.cat]) === null || _e === void 0 ? void 0 : _e.type) !== null && _f !== void 0 ? _f : 'undefined';
}
this.mapLoxoneItems(Object.values(this.LoxoneItems)).then(() => {
this.removeUnmappedAccessories();
});
}
async mapLoxoneItems(items) {
var _a;
var _b, _c, _d, _e, _f, _g;
const cache = {};
const excludedTypes = (_c = (_b = this.config.Exclusions) === null || _b === void 0 ? void 0 : _b.split(',')) !== null && _c !== void 0 ? _c : [];
const roomFilterList = (_f = (_e = (_d = this.config.roomfilter) === null || _d === void 0 ? void 0 : _d.list) === null || _e === void 0 ? void 0 : _e.split(',')) !== null && _f !== void 0 ? _f : [];
const roomFilterType = ((_g = this.config.roomfilter) === null || _g === void 0 ? void 0 : _g.type) || 'exclusion';
for (const item of items) {
try {
const type = item.type;
const roomExcluded = (roomFilterType === 'exclusion' && roomFilterList.includes(item.room.toLowerCase())) ||
(roomFilterType === 'inclusion' && !roomFilterList.includes(item.room.toLowerCase()));
if (roomExcluded) {
continue;
}
if (excludedTypes.includes(type)) {
continue;
}
if (!cache[type]) {
cache[type] = await (_a = `./loxone/items/${type}`, Promise.resolve().then(() => __importStar(require(_a))));
}
const file = cache[type];
const constructorName = Object.keys(file)[0];
new file[constructorName](this, item);
}
catch (_h) {
this.log.info(`[mapLoxoneItem] Unsupported item type: ${item.name} → ${item.type}`);
}
}
}
removeUnmappedAccessories() {
const plugin = 'homebridge-loxone-proxy';
const platform = 'LoxonePlatform';
this.accessories.forEach((acc) => {
if (!this.mappedAccessories.has(acc.UUID)) {
this.log.info('[RemoveAccessory] Removing unused accessory:', acc.displayName);
this.api.unregisterPlatformAccessories(plugin, platform, [acc]);
}
});
this.mappedAccessories.clear();
}
configureAccessory(acc) {
this.log.debug('Loaded from cache:', acc.displayName);
this.accessories.push(acc);
}
generateUniqueName(room, base, uuid, isSubItem = false) {
const clean = (s) => s
.replace(/\((.*?)\)/g, '$1')
.replace(/[^\p{L}\p{N}\s']/gu, '')
.replace(/\s+/g, ' ')
.trim();
const cleanRoom = clean(room || 'Unknown');
const cleanBase = clean(base || 'Unnamed');
const alreadyPrefixed = cleanBase.toLowerCase().startsWith(cleanRoom.toLowerCase()) ||
cleanBase.toLowerCase().startsWith(cleanRoom.toLowerCase() + ' ');
const baseName = alreadyPrefixed
? cleanBase
: `${cleanRoom} ${cleanBase}`;
if (isSubItem) {
return baseName;
}
if (uuid && this.accessoryNameMap.has(uuid)) {
return this.accessoryNameMap.get(uuid);
}
let finalName = baseName;
let counter = 1;
while (this.usedNames.has(finalName)) {
finalName = `${baseName} ${counter++}`;
}
this.usedNames.add(finalName);
if (uuid) {
this.accessoryNameMap.set(uuid, finalName);
}
return finalName;
}
}
exports.LoxonePlatform = LoxonePlatform;
//# sourceMappingURL=LoxonePlatform.js.map