homebridge-loxone-proxy
Version:
Homebridge Dynamic Platform Plugin which exposes a Loxone System to Homekit.
126 lines • 5.16 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.IntercomV2 = void 0;
const Intercom_1 = require("./Intercom");
const MotionSensor_1 = require("../../homekit/services/MotionSensor");
class IntercomV2 extends Intercom_1.Intercom {
async configureCamera() {
let isConfigured = false;
this.platform.LoxoneHandler.registerListenerForUUID(this.device.states.address, (value) => {
var _a;
if (isConfigured) {
return;
}
const address = this.normalizeAddress(value);
if (!address) {
return this.platform.log.debug(`[${this.device.name}] Invalid IP for IntercomV2.`);
}
const username = this.platform.config.username;
const password = this.platform.config.password;
const auth = Buffer.from(`${username}:${password}`, 'utf8').toString('base64');
const nativeMotionBound = this.bindNativeMotionSensor();
const enableHKSV = (_a = this.platform.config.enableHKSV) !== null && _a !== void 0 ? _a : false;
const useSnapshotMotion = enableHKSV && !nativeMotionBound;
const streamUrl = `http://${address}/mjpg/video.mjpg`;
const twoWayAudioContext = {
mode: 'loxone-intercom-v2',
signalingBaseUrl: `http://${address}`,
};
this.initializeCamera(streamUrl, undefined, auth, useSnapshotMotion, undefined, twoWayAudioContext);
isConfigured = true;
});
}
bindNativeMotionSensor() {
const deviceUuid = this.device.details.deviceUuid;
if (!deviceUuid) {
return false;
}
const uuidPrefix = deviceUuid.split('-')[0];
const candidates = Object.entries(this.platform.LoxoneItems)
.filter(([uuid, item]) => {
var _a;
return uuid.startsWith(uuidPrefix) &&
item.uuidAction !== this.device.uuidAction &&
item.type !== this.device.type &&
Object.keys((_a = item.states) !== null && _a !== void 0 ? _a : {}).length > 0;
});
if (!candidates.length) {
this.platform.log.debug(`[${this.device.name}] No native IntercomV2 motion candidate found.`);
return false;
}
const [, motionDevice] = this.pickBestMotionCandidate(candidates);
const serviceName = 'NativeMotion';
this.Service[serviceName] = new MotionSensor_1.MotionSensor(this.platform, this.Accessory, motionDevice);
for (const stateName in motionDevice.states) {
const stateUuid = motionDevice.states[stateName];
this.platform.LoxoneHandler.registerListenerForUUID(stateUuid, (message) => {
const normalized = this.normalizeBinaryValue(message);
if (normalized === undefined) {
return;
}
this.Service[serviceName].updateService({ value: normalized });
});
}
this.platform.log.info(`[${this.device.name}] Native IntercomV2 motion sensor bound.`);
return true;
}
pickBestMotionCandidate(candidates) {
const scored = candidates
.map(([uuid, item]) => ({
uuid,
item,
score: this.motionCandidateScore(item),
}))
.sort((a, b) => b.score - a.score);
return [scored[0].uuid, scored[0].item];
}
motionCandidateScore(item) {
const label = `${item.type} ${item.name}`.toLowerCase();
let score = 0;
if (item.type === 'InfoOnlyDigital') {
score += 10;
}
if (label.includes('motion') || label.includes('beweging') || label.includes('presence')) {
score += 6;
}
if (label.includes('intercom') || label.includes('doorbell')) {
score += 2;
}
return score;
}
normalizeAddress(value) {
var _a;
const rawValue = typeof value === 'string'
? value
: (value && typeof value === 'object' && 'value' in value)
? String((_a = value.value) !== null && _a !== void 0 ? _a : '')
: '';
const trimmed = rawValue.trim();
if (!trimmed) {
return undefined;
}
if (trimmed.startsWith('http://') || trimmed.startsWith('https://')) {
try {
return new URL(trimmed).host;
}
catch (_b) {
return undefined;
}
}
return trimmed.split('/')[0];
}
normalizeBinaryValue(message) {
const raw = typeof message === 'number' || typeof message === 'string'
? message
: (message && typeof message === 'object' && 'value' in message)
? message.value
: undefined;
const numeric = Number(raw);
if (!Number.isFinite(numeric)) {
return undefined;
}
return numeric === 0 ? 0 : 1;
}
}
exports.IntercomV2 = IntercomV2;
//# sourceMappingURL=IntercomV2.js.map