@dotwee/homebridge-z2m
Version:
Expose your Zigbee devices to HomeKit with ease, by integrating Zigbee2MQTT with Homebridge.
260 lines • 12 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.isGroupListEntry = exports.isGroupMember = exports.deviceListEntriesAreEqual = exports.isDeviceListEntryForGroup = exports.isDeviceListEntry = exports.isDeviceDefinition = exports.exposesCollectionsAreEqual = exports.exposesAreEqual = exports.exposesGetMergedEntry = exports.normalizeExposes = exports.exposesGetOverlap = exports.exposesHasAllRequiredFeatures = exports.exposesIsPublished = exports.exposesCanBeGet = exports.exposesCanBeSet = exports.exposesHasEnumProperty = exports.exposesHasBinaryProperty = exports.exposesHasNumericRangeProperty = exports.exposesHasNumericProperty = exports.exposesHasProperty = exports.exposesHasFeatures = exports.isExposesEntry = exports.ExposesKnownTypes = exports.ExposesAccessLevel = void 0;
var ExposesAccessLevel;
(function (ExposesAccessLevel) {
ExposesAccessLevel[ExposesAccessLevel["PUBLISHED"] = 1] = "PUBLISHED";
ExposesAccessLevel[ExposesAccessLevel["SET"] = 2] = "SET";
ExposesAccessLevel[ExposesAccessLevel["GET"] = 4] = "GET";
})(ExposesAccessLevel = exports.ExposesAccessLevel || (exports.ExposesAccessLevel = {}));
var ExposesKnownTypes;
(function (ExposesKnownTypes) {
ExposesKnownTypes["NUMERIC"] = "numeric";
ExposesKnownTypes["BINARY"] = "binary";
ExposesKnownTypes["SWITCH"] = "switch";
ExposesKnownTypes["LOCK"] = "lock";
ExposesKnownTypes["ENUM"] = "enum";
ExposesKnownTypes["TEXT"] = "text";
ExposesKnownTypes["COMPOSITE"] = "composite";
ExposesKnownTypes["LIGHT"] = "light";
ExposesKnownTypes["COVER"] = "cover";
ExposesKnownTypes["FAN"] = "fan";
ExposesKnownTypes["CLIMATE"] = "climate";
})(ExposesKnownTypes = exports.ExposesKnownTypes || (exports.ExposesKnownTypes = {}));
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const isExposesEntry = (x) => {
if (x === undefined || x.type === undefined) {
return false;
}
return (x.name !== undefined ||
x.property !== undefined ||
x.access !== undefined ||
x.endpoint !== undefined ||
x.values !== undefined ||
(x.value_off !== undefined && x.value_on !== undefined) ||
(x.value_min !== undefined && x.value_max !== undefined) ||
Array.isArray(x.features));
};
exports.isExposesEntry = isExposesEntry;
const exposesHasFeatures = (x) => 'features' in x;
exports.exposesHasFeatures = exposesHasFeatures;
const exposesHasProperty = (x) => x.name !== undefined && x.property !== undefined && x.access !== undefined;
exports.exposesHasProperty = exposesHasProperty;
const exposesHasNumericProperty = (x) => (0, exports.exposesHasProperty)(x) && x.type === ExposesKnownTypes.NUMERIC;
exports.exposesHasNumericProperty = exposesHasNumericProperty;
const exposesHasNumericRangeProperty = (x) => (0, exports.exposesHasNumericProperty)(x) && x.value_min !== undefined && x.value_max !== undefined;
exports.exposesHasNumericRangeProperty = exposesHasNumericRangeProperty;
const exposesHasBinaryProperty = (x) => (0, exports.exposesHasProperty)(x) && x.type === ExposesKnownTypes.BINARY && x.value_on !== undefined && x.value_off !== undefined;
exports.exposesHasBinaryProperty = exposesHasBinaryProperty;
const exposesHasEnumProperty = (x) => (0, exports.exposesHasProperty)(x) && x.type === ExposesKnownTypes.ENUM && Array.isArray(x.values) && x.values.length > 0;
exports.exposesHasEnumProperty = exposesHasEnumProperty;
function exposesCanBeSet(entry) {
return entry.access !== undefined && (entry.access & ExposesAccessLevel.SET) !== 0;
}
exports.exposesCanBeSet = exposesCanBeSet;
function exposesCanBeGet(entry) {
return entry.access !== undefined && (entry.access & ExposesAccessLevel.GET) !== 0;
}
exports.exposesCanBeGet = exposesCanBeGet;
function exposesIsPublished(entry) {
return entry.access !== undefined && (entry.access & ExposesAccessLevel.PUBLISHED) !== 0;
}
exports.exposesIsPublished = exposesIsPublished;
function exposesHasAllRequiredFeatures(entry, features) {
for (const f of features) {
if (entry.features.findIndex((e) => f(e)) < 0) {
// given feature not found
return false;
}
}
// All mentioned features where matched.
return true;
}
exports.exposesHasAllRequiredFeatures = exposesHasAllRequiredFeatures;
function exposesGetOverlap(first, second) {
const result = [];
const secondNormalized = normalizeExposes(second);
for (const entry of normalizeExposes(first)) {
const match = secondNormalized.find((x) => x.name === entry.name && x.property === entry.property && x.type === entry.type);
if (match !== undefined) {
const merged = exposesGetMergedEntry(entry, match);
if (merged !== undefined) {
result.push(merged);
}
}
}
return result;
}
exports.exposesGetOverlap = exposesGetOverlap;
// Removes endpoint specific info and possible duplicates
function normalizeExposes(entries) {
const result = [];
for (const entry of entries) {
const normalized = exposesRemoveEndpoint(entry);
if (result.findIndex((x) => exposesAreEqual(normalized, x)) < 0) {
result.push(normalized);
}
}
return result;
}
exports.normalizeExposes = normalizeExposes;
// Remove endpoint specific info from an exposes entry.
function exposesRemoveEndpoint(entry) {
const result = { ...entry };
if (entry.endpoint !== undefined) {
delete result.endpoint;
if (entry.property !== undefined && entry.name !== undefined) {
result.property = entry.name;
}
}
if ((0, exports.exposesHasFeatures)(entry)) {
result['features'] = entry.features.map(exposesRemoveEndpoint);
}
return result;
}
function exposesGetMergedEntry(first, second) {
var _a;
const result = {
type: first.type,
};
for (const member in first) {
if (!Array.isArray(first[member]) && member in second && second[member] === first[member]) {
result[member] = first[member];
}
}
switch (first.type) {
case ExposesKnownTypes.NUMERIC:
mergeNumericExposesEntry(first, second, result);
break;
case ExposesKnownTypes.BINARY:
if (first.value_on !== second.value_on || first.value_off !== second.value_off) {
return undefined;
}
break;
case ExposesKnownTypes.ENUM:
{
const matches = (_a = first.values) === null || _a === void 0 ? void 0 : _a.filter((x) => { var _a; return (_a = second.values) === null || _a === void 0 ? void 0 : _a.includes(x); });
if (matches === undefined || matches.length === 0) {
return undefined;
}
result.values = matches;
}
break;
default:
// no action needed
break;
}
// process features
mergeFeaturesInExposesEntry(first, second, result);
return result;
}
exports.exposesGetMergedEntry = exposesGetMergedEntry;
function mergeNumericExposesEntry(first, second, result) {
if (first.value_min !== second.value_min) {
if (first.value_min === undefined) {
result.value_min = second.value_min;
}
else if (second.value_min !== undefined) {
result.value_min = Math.max(first.value_min, second.value_min);
}
}
if (first.value_max !== second.value_max) {
if (first.value_max === undefined) {
result.value_max = second.value_max;
}
else if (second.value_max !== undefined) {
result.value_max = Math.min(first.value_max, second.value_max);
}
}
}
function mergeFeaturesInExposesEntry(first, second, result) {
if ((0, exports.exposesHasFeatures)(first) && (0, exports.exposesHasFeatures)(second)) {
result['features'] = [];
for (const feature of first.features) {
const match = second.features.find((x) => x.name === feature.name && x.property === feature.property && x.type === feature.type);
if (match !== undefined) {
const merged = exposesGetMergedEntry(feature, match);
if (merged !== undefined) {
result['features'].push(merged);
}
}
}
}
else if ('features' in result) {
delete result['features'];
}
}
function exposesAreEqual(first, second) {
var _a, _b;
if (first.type !== second.type ||
first.name !== second.name ||
first.property !== second.property ||
first.access !== second.access ||
first.endpoint !== second.endpoint ||
first.value_min !== second.value_min ||
first.value_max !== second.value_max ||
first.value_off !== second.value_off ||
first.value_on !== second.value_on ||
((_a = first.values) === null || _a === void 0 ? void 0 : _a.length) !== ((_b = second.values) === null || _b === void 0 ? void 0 : _b.length)) {
return false;
}
if (first.values !== undefined && (second === null || second === void 0 ? void 0 : second.values) !== undefined) {
const missing = first.values.filter((v) => { var _a, _b; return !((_b = (_a = second.values) === null || _a === void 0 ? void 0 : _a.includes(v)) !== null && _b !== void 0 ? _b : false); });
if (missing.length > 0) {
return false;
}
}
if ((0, exports.exposesHasFeatures)(first) || (0, exports.exposesHasFeatures)(second)) {
if (!(0, exports.exposesHasFeatures)(first) || !(0, exports.exposesHasFeatures)(second)) {
return false;
}
return exposesCollectionsAreEqual(first.features, second.features);
}
return true;
}
exports.exposesAreEqual = exposesAreEqual;
function exposesCollectionsAreEqual(first, second) {
if (first.length !== second.length) {
return false;
}
for (const firstEntry of first) {
if (second.findIndex((e) => exposesAreEqual(firstEntry, e)) < 0) {
return false;
}
}
return true;
}
exports.exposesCollectionsAreEqual = exposesCollectionsAreEqual;
const isDeviceDefinition = (x) => x.vendor && x.model && Array.isArray(x.exposes);
exports.isDeviceDefinition = isDeviceDefinition;
const isNullOrUndefined = (x) => x === null || x === undefined;
const isDeviceListEntry = (x) => x.ieee_address && x.friendly_name && x.supported;
exports.isDeviceListEntry = isDeviceListEntry;
const isDeviceListEntryForGroup = (x) => {
return (0, exports.isDeviceListEntry)(x) && 'group_id' in x && typeof x['group_id'] === 'number';
};
exports.isDeviceListEntryForGroup = isDeviceListEntryForGroup;
function deviceListEntriesAreEqual(first, second) {
if (first === undefined || second === undefined) {
return first === undefined && second === undefined;
}
if (first.friendly_name !== second.friendly_name ||
first.ieee_address !== second.ieee_address ||
first.supported !== second.supported ||
first.software_build_id !== second.software_build_id ||
first.date_code !== second.date_code) {
return false;
}
if (isNullOrUndefined(first.definition) || isNullOrUndefined(second.definition)) {
return isNullOrUndefined(first.definition) && isNullOrUndefined(second.definition);
}
return (first.definition.model === second.definition.model &&
first.definition.vendor === second.definition.vendor &&
exposesCollectionsAreEqual(first.definition.exposes, second.definition.exposes));
}
exports.deviceListEntriesAreEqual = deviceListEntriesAreEqual;
const isGroupMember = (x) => x.ieee_address && x.endpoint;
exports.isGroupMember = isGroupMember;
const isGroupListEntry = (x) => x.id && x.friendly_name && x.members;
exports.isGroupListEntry = isGroupListEntry;
//# sourceMappingURL=z2mModels.js.map