eufy-security-client
Version:
Client to comunicate with Eufy-Security devices
789 lines (788 loc) • 30.5 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.loadEventImage = exports.loadImageOverP2P = exports.getWaitSeconds = exports.isSmartLockNotification = exports.switchSmartLockNotification = exports.getLockEventType = exports.getFloodLightT8425Notification = exports.isFloodlightT8425NotitficationEnabled = exports.getIndoorNotification = exports.isIndoorNotitficationEnabled = exports.getIndoorS350DetectionMode = exports.isIndoorS350DetectionModeEnabled = exports.getT8170DetectionMode = exports.isT8170DetectionModeEnabled = exports.decryptTrackerData = exports.isPrioritySourceType = exports.getImage = exports.getImagePath = exports.decodeImage = exports.getImageKey = exports.getImageSeed = exports.getImageBaseCode = exports.getIdSuffix = exports.randomNumber = exports.hexStringScheduleToSchedule = exports.hexWeek = exports.hexTime = exports.hexDate = exports.encodePasscode = exports.ParsePayload = exports.WritePayload = exports.getAdvancedLockTimezone = exports.getEufyTimezone = exports.getHB3DetectionMode = exports.isHB3DetectionModeEnabled = exports.getDistances = exports.getBlocklist = exports.decryptAPIData = exports.encryptAPIData = exports.calculateCellularSignalLevel = exports.calculateWifiSignalLevel = exports.switchNotificationMode = exports.isNotificationSwitchMode = exports.getImageFilePath = exports.getAbsoluteFilePath = exports.getTimezoneGMTString = exports.pad = exports.isGreaterEqualMinVersion = void 0;
const crypto_1 = require("crypto");
const const_1 = require("./const");
const md5_1 = __importDefault(require("crypto-js/md5"));
const enc_hex_1 = __importDefault(require("crypto-js/enc-hex"));
const sha256_1 = __importDefault(require("crypto-js/sha256"));
const types_1 = require("./types");
const error_1 = require("../error");
const error_2 = require("./error");
const types_2 = require("./../push/types");
const logging_1 = require("../logging");
const utils_1 = require("../utils");
const normalizeVersionString = function (version) {
const trimmed = version ? version.replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1") : "";
const pieces = trimmed.split(RegExp("\\."));
const parts = [];
let value, piece, num, i;
for (i = 0; i < pieces.length; i += 1) {
piece = pieces[i].replace(RegExp("\\D"), "");
num = parseInt(piece, 10);
if (isNaN(num)) {
num = 0;
}
parts.push(num);
}
const partsLength = parts.length;
for (i = partsLength - 1; i >= 0; i -= 1) {
value = parts[i];
if (value === 0) {
parts.length -= 1;
}
else {
break;
}
}
return parts;
};
const isGreaterEqualMinVersion = function (minimal_version, current_version) {
const x = normalizeVersionString(minimal_version);
const y = normalizeVersionString(current_version);
const size = Math.min(x.length, y.length);
let i;
for (i = 0; i < size; i += 1) {
if (x[i] !== y[i]) {
return x[i] < y[i] ? true : false;
}
}
if (x.length === y.length) {
return true;
}
return (x.length < y.length) ? true : false;
};
exports.isGreaterEqualMinVersion = isGreaterEqualMinVersion;
const pad = function (num) {
const norm = Math.floor(Math.abs(num));
return (norm < 10 ? "0" : "") + norm;
};
exports.pad = pad;
const getTimezoneGMTString = function () {
const tzo = -new Date().getTimezoneOffset();
const dif = tzo >= 0 ? "+" : "-";
return `GMT${dif}${(0, exports.pad)(tzo / 60)}:${(0, exports.pad)(tzo % 60)}`;
};
exports.getTimezoneGMTString = getTimezoneGMTString;
const getAbsoluteFilePath = function (device_type, channel, filename) {
if (device_type === types_1.DeviceType.FLOODLIGHT) {
return `/mnt/data/Camera${String(channel).padStart(2, "0")}/${filename}.dat`;
}
return `/media/mmcblk0p1/Camera${String(channel).padStart(2, "0")}/${filename}.dat`;
};
exports.getAbsoluteFilePath = getAbsoluteFilePath;
const getImageFilePath = function (device_type, channel, filename) {
if (device_type === types_1.DeviceType.FLOODLIGHT) {
return `/mnt/data/video/${filename}_c${String(channel).padStart(2, "0")}.jpg`;
}
return `/media/mmcblk0p1/video/${filename}_c${String(channel).padStart(2, "0")}.jpg`;
};
exports.getImageFilePath = getImageFilePath;
const isNotificationSwitchMode = function (value, mode) {
if (value === 1)
value = 240;
return (value & mode) !== 0;
};
exports.isNotificationSwitchMode = isNotificationSwitchMode;
const switchNotificationMode = function (currentValue, mode, enable) {
let result = 0;
if (!enable && currentValue === 1 /* ALL */) {
currentValue = 240;
}
if (enable) {
result = mode | currentValue;
}
else {
result = ~mode & currentValue;
}
if ((0, exports.isNotificationSwitchMode)(result, types_1.NotificationSwitchMode.SCHEDULE) && (0, exports.isNotificationSwitchMode)(result, types_1.NotificationSwitchMode.APP) && (0, exports.isNotificationSwitchMode)(result, types_1.NotificationSwitchMode.GEOFENCE) && (0, exports.isNotificationSwitchMode)(result, types_1.NotificationSwitchMode.KEYPAD)) {
result = 1; /* ALL */
}
return result;
};
exports.switchNotificationMode = switchNotificationMode;
const calculateWifiSignalLevel = function (device, rssi) {
if (device.isWiredDoorbell()) {
if (rssi >= -65) {
return types_1.SignalLevel.FULL;
}
if (rssi >= -75) {
return types_1.SignalLevel.STRONG;
}
return rssi >= -80 ? types_1.SignalLevel.NORMAL : types_1.SignalLevel.WEAK;
}
else if (device.isCamera2Product()) {
if (rssi >= 0) {
return types_1.SignalLevel.NO_SIGNAL;
}
if (rssi >= -65) {
return types_1.SignalLevel.FULL;
}
if (rssi >= -75) {
return types_1.SignalLevel.STRONG;
}
return rssi >= -85 ? types_1.SignalLevel.NORMAL : types_1.SignalLevel.WEAK;
}
else if (device.isFloodLight()) {
if (rssi >= 0) {
return types_1.SignalLevel.NO_SIGNAL;
}
if (rssi >= -60) {
return types_1.SignalLevel.FULL;
}
if (rssi >= -70) {
return types_1.SignalLevel.STRONG;
}
return rssi >= -80 ? types_1.SignalLevel.NORMAL : types_1.SignalLevel.WEAK;
}
else if (device.isBatteryDoorbell()) {
if (rssi >= -65) {
return types_1.SignalLevel.FULL;
}
if (rssi >= -75) {
return types_1.SignalLevel.STRONG;
}
return rssi >= -85 ? types_1.SignalLevel.NORMAL : types_1.SignalLevel.WEAK;
}
else {
if (rssi >= 0) {
return types_1.SignalLevel.NO_SIGNAL;
}
if (rssi >= -65) {
return types_1.SignalLevel.FULL;
}
if (rssi >= -75) {
return types_1.SignalLevel.STRONG;
}
return rssi >= -85 ? types_1.SignalLevel.NORMAL : types_1.SignalLevel.WEAK;
}
};
exports.calculateWifiSignalLevel = calculateWifiSignalLevel;
const calculateCellularSignalLevel = function (rssi) {
if (rssi >= 0) {
return types_1.SignalLevel.NO_SIGNAL;
}
if (rssi >= -90) {
return types_1.SignalLevel.FULL;
}
if (rssi >= -95) {
return types_1.SignalLevel.STRONG;
}
return rssi >= -105 ? types_1.SignalLevel.NORMAL : types_1.SignalLevel.WEAK;
};
exports.calculateCellularSignalLevel = calculateCellularSignalLevel;
const encryptAPIData = (data, key) => {
const cipher = (0, crypto_1.createCipheriv)("aes-256-cbc", key, key.subarray(0, 16));
return (cipher.update(data, "utf8", "base64") +
cipher.final("base64"));
};
exports.encryptAPIData = encryptAPIData;
const decryptAPIData = (data, key) => {
const cipher = (0, crypto_1.createDecipheriv)("aes-256-cbc", key, key.subarray(0, 16));
return Buffer.concat([
cipher.update(data, "base64"),
cipher.final()
]);
};
exports.decryptAPIData = decryptAPIData;
const getBlocklist = function (directions) {
const result = [];
for (let distance = 1; distance <= 5; distance++) {
let i = 0;
let j = 0;
let k = 1;
for (const directionDistance of directions) {
if (directionDistance >= distance) {
j += k;
}
k <<= 1;
}
if (j == 0) {
i = 65535;
}
else if (!(j == 255 || j == 65535)) {
i = (j ^ 255) + 65280;
}
result.push(65535 & i);
}
return result;
};
exports.getBlocklist = getBlocklist;
const getDistances = function (blocklist) {
const result = [3, 3, 3, 3, 3, 3, 3, 3];
let calcDistance = 0;
for (const blockElement of blocklist) {
let valueOf = blockElement ^ 65535;
calcDistance++;
if (valueOf !== 0) {
for (let i = 0; i < result.length; i++) {
const intValue = valueOf & 1;
if (intValue > 0) {
result[i] = calcDistance;
}
valueOf = valueOf >> 1;
}
}
}
return result;
};
exports.getDistances = getDistances;
const isHB3DetectionModeEnabled = function (value, type) {
if (type === types_1.HB3DetectionTypes.HUMAN_RECOGNITION) {
return (type & value) == type && (value & 65536) == 65536;
}
else if (type === types_1.HB3DetectionTypes.HUMAN_DETECTION) {
return (type & value) == type && (value & 1) == 1;
}
return (type & value) == type;
};
exports.isHB3DetectionModeEnabled = isHB3DetectionModeEnabled;
const getHB3DetectionMode = function (value, type, enable) {
let result = 0;
if (!enable) {
if (type === types_1.HB3DetectionTypes.HUMAN_RECOGNITION) {
const tmp = (type & value) == type ? type ^ value : value;
result = (value & 65536) == 65536 ? tmp ^ 65536 : tmp;
}
else if (type === types_1.HB3DetectionTypes.HUMAN_DETECTION) {
const tmp = (type & value) == type ? type ^ value : value;
result = (value & 1) == 1 ? tmp ^ 1 : tmp;
}
else {
result = type ^ value;
}
}
else {
if (type === types_1.HB3DetectionTypes.HUMAN_RECOGNITION) {
result = type | value | 65536;
}
else if (type === types_1.HB3DetectionTypes.HUMAN_DETECTION) {
result = type | value | 1;
}
else {
result = type | value;
}
}
return result;
};
exports.getHB3DetectionMode = getHB3DetectionMode;
const getEufyTimezone = function () {
for (const timezone of const_1.timeZoneData) {
if (timezone.timeId === Intl.DateTimeFormat().resolvedOptions().timeZone) {
return timezone;
}
}
return undefined;
};
exports.getEufyTimezone = getEufyTimezone;
const getAdvancedLockTimezone = function (stationSN) {
const timezone = (0, exports.getEufyTimezone)();
if (timezone !== undefined) {
if (stationSN.startsWith("T8520") && (0, exports.isGreaterEqualMinVersion)("1.2.8.6", stationSN))
return `${timezone.timeZoneGMT}|1.${timezone.timeSn}`;
else
return timezone.timeZoneGMT;
}
return "";
};
exports.getAdvancedLockTimezone = getAdvancedLockTimezone;
class WritePayload {
split_byte = -95;
data = Buffer.from([]);
write(bytes) {
const tmp_data = Buffer.from(bytes);
this.data = Buffer.concat([this.data, Buffer.from([this.split_byte]), Buffer.from([tmp_data.length & 255]), tmp_data]);
this.split_byte += 1;
}
getData() {
return this.data;
}
}
exports.WritePayload = WritePayload;
class ParsePayload {
data;
constructor(data) {
this.data = data;
}
readUint32BE(indexValue) {
return this.readData(indexValue).readUint32BE();
}
readUint32LE(indexValue) {
return this.readData(indexValue).readUint32LE();
}
readUint16BE(indexValue) {
return this.readData(indexValue).readUint16BE();
}
readUint16LE(indexValue) {
return this.readData(indexValue).readUint16LE();
}
readString(indexValue) {
return this.readData(indexValue).toString();
}
readStringHex(indexValue) {
return this.readData(indexValue).toString("hex");
}
readInt8(indexValue) {
let dataPosition = this.getDataPosition(indexValue);
if (dataPosition == -1) {
return 0;
}
dataPosition = dataPosition + 2;
if (dataPosition >= this.data.length) {
return 0;
}
return this.data.readInt8(dataPosition);
}
readData(indexValue) {
let dataPosition = this.getDataPosition(indexValue);
if (dataPosition == -1) {
return Buffer.from("");
}
dataPosition++;
if (dataPosition >= this.data.length) {
return Buffer.from("");
}
const nextStep = this.getNextStep(indexValue, dataPosition, this.data);
let tmp;
if (nextStep == 1) {
tmp = this.data.readInt8(dataPosition);
}
else {
tmp = this.data.readUint16LE(dataPosition);
}
if (dataPosition + nextStep + tmp > this.data.length) {
return Buffer.from("");
}
return this.data.subarray(dataPosition + nextStep, dataPosition + nextStep + tmp);
}
getDataPosition(indexValue) {
if (this.data && this.data.length >= 1) {
for (let currentPosition = 0; currentPosition < this.data.length;) {
if (this.data.readInt8(currentPosition) == indexValue) {
return currentPosition;
}
else {
const value = this.data.readInt8(currentPosition);
currentPosition++;
if (currentPosition >= this.data.length) {
break;
}
const nextStep = this.getNextStep(value, currentPosition, this.data);
if ((currentPosition + nextStep) >= this.data.length) {
break;
}
if (nextStep == 1) {
currentPosition = this.data.readInt8(currentPosition) + currentPosition + nextStep;
}
else {
currentPosition = this.data.readUint16LE(currentPosition) + currentPosition + nextStep;
}
}
}
}
return -1;
}
getNextStep(indexValue, position, data) {
const newPosition = position + 1 + data.readUInt8(position);
return (newPosition == data.length || newPosition > data.length || data.readInt8(newPosition) == indexValue + 1) ? 1 : 2;
}
}
exports.ParsePayload = ParsePayload;
/*export const generateHash = function(data: Buffer): number {
let result = 0;
for (const value of data) {
result = result ^ value;
}
return result;
}
export const encodeSmartSafeData = function(command: number, payload: Buffer): Buffer {
const header = Buffer.from(SmartSafe.DATA_HEADER);
const size = Buffer.allocUnsafe(2);
size.writeInt16LE(payload.length + 9);
const versionCode = Buffer.from([SmartSafe.VERSION_CODE]);
const dataType = Buffer.from([-1]);
const commandCode = Buffer.from([command]);
const packageFlag = Buffer.from([-64]);
const data = Buffer.concat([header, size, versionCode, dataType, commandCode, packageFlag, payload]);
const hash = generateHash(data);
return Buffer.concat([data, Buffer.from([hash])]);
}*/
const encodePasscode = function (pass) {
let result = "";
for (let i = 0; i < pass.length; i++)
result += pass.charCodeAt(i).toString(16);
return result;
};
exports.encodePasscode = encodePasscode;
const hexDate = function (date) {
const buf = Buffer.allocUnsafe(4);
buf.writeUint8(date.getDate());
buf.writeUint8(date.getMonth() + 1, 1);
buf.writeUint16BE(date.getFullYear(), 2);
return buf.readUInt32LE().toString(16).padStart(8, "0");
};
exports.hexDate = hexDate;
const hexTime = function (date) {
const buf = Buffer.allocUnsafe(2);
buf.writeUint8(date.getHours());
buf.writeUint8(date.getMinutes(), 1);
return buf.readUInt16BE().toString(16).padStart(4, "0");
};
exports.hexTime = hexTime;
const hexWeek = function (schedule) {
const SUNDAY = 1;
const MONDAY = 2;
const TUESDAY = 4;
const WEDNESDAY = 8;
const THUERSDAY = 16;
const FRIDAY = 32;
const SATURDAY = 64;
let result = 0;
if (schedule.week !== undefined) {
if (schedule.week.sunday) {
result |= SUNDAY;
}
if (schedule.week.monday) {
result |= MONDAY;
}
if (schedule.week.tuesday) {
result |= TUESDAY;
}
if (schedule.week.wednesday) {
result |= WEDNESDAY;
}
if (schedule.week.thursday) {
result |= THUERSDAY;
}
if (schedule.week.friday) {
result |= FRIDAY;
}
if (schedule.week.saturday) {
result |= SATURDAY;
}
return result.toString(16);
}
return "ff";
};
exports.hexWeek = hexWeek;
const hexStringScheduleToSchedule = function (startDay, startTime, endDay, endTime, week) {
const SUNDAY = 1;
const MONDAY = 2;
const TUESDAY = 4;
const WEDNESDAY = 8;
const THUERSDAY = 16;
const FRIDAY = 32;
const SATURDAY = 64;
const weekNumber = Number.parseInt(week, 16);
return {
startDateTime: startDay === "00000000" ? undefined : new Date(Number.parseInt(`${startDay.substring(2, 4)}${startDay.substring(0, 2)}`, 16), Number.parseInt(startDay.substring(4, 6), 16) - 1, Number.parseInt(startDay.substring(6, 8), 16), Number.parseInt(startTime.substring(0, 2), 16), Number.parseInt(startTime.substring(2, 4), 16)),
endDateTime: endDay === "ffffffff" ? undefined : new Date(Number.parseInt(`${endDay.substring(2, 4)}${endDay.substring(0, 2)}`, 16), Number.parseInt(endDay.substring(4, 6), 16) - 1, Number.parseInt(endDay.substring(6, 8), 16), Number.parseInt(endTime.substring(0, 2), 16), Number.parseInt(endTime.substring(2, 4), 16)),
week: {
monday: (weekNumber & MONDAY) == MONDAY,
tuesday: (weekNumber & TUESDAY) == TUESDAY,
wednesday: (weekNumber & WEDNESDAY) == WEDNESDAY,
thursday: (weekNumber & THUERSDAY) == THUERSDAY,
friday: (weekNumber & FRIDAY) == FRIDAY,
saturday: (weekNumber & SATURDAY) == SATURDAY,
sunday: (weekNumber & SUNDAY) == SUNDAY,
},
};
};
exports.hexStringScheduleToSchedule = hexStringScheduleToSchedule;
const randomNumber = function (min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
};
exports.randomNumber = randomNumber;
const getIdSuffix = function (p2pDid) {
let result = 0;
const match = p2pDid.match(/^[A-Z]+-(\d+)-[A-Z]+$/);
if (match?.length == 2) {
const num1 = Number.parseInt(match[1][0]);
const num2 = Number.parseInt(match[1][1]);
const num3 = Number.parseInt(match[1][3]);
const num4 = Number.parseInt(match[1][5]);
result = num1 + num2 + num3;
if (num3 < 5) {
result = result + num3;
}
result = result + num4;
}
return result;
};
exports.getIdSuffix = getIdSuffix;
const getImageBaseCode = function (serialnumber, p2pDid) {
let nr = 0;
try {
nr = Number.parseInt(`0x${serialnumber[serialnumber.length - 1]}`);
}
catch (err) {
const error = (0, error_1.ensureError)(err);
throw new error_2.ImageBaseCodeError("Error generating image base code", { cause: error, context: { serialnumber: serialnumber, p2pDid: p2pDid } });
}
nr = (nr + 10) % 10;
const base = serialnumber.substring(nr);
return `${base}${(0, exports.getIdSuffix)(p2pDid)}`;
};
exports.getImageBaseCode = getImageBaseCode;
const getImageSeed = function (p2pDid, code) {
try {
const ncode = Number.parseInt(code.substring(2));
const prefix = 1000 - (0, exports.getIdSuffix)(p2pDid);
return (0, md5_1.default)(`${prefix}${ncode}`).toString(enc_hex_1.default).toUpperCase();
}
catch (err) {
const error = (0, error_1.ensureError)(err);
throw new error_2.ImageBaseCodeError("Error generating image seed", { cause: error, context: { p2pDid: p2pDid, code: code } });
}
};
exports.getImageSeed = getImageSeed;
const getImageKey = function (serialnumber, p2pDid, code) {
const basecode = (0, exports.getImageBaseCode)(serialnumber, p2pDid);
const seed = (0, exports.getImageSeed)(p2pDid, code);
const data = `01${basecode}${seed}`;
const hash = (0, sha256_1.default)(data);
const hashBytes = [...Buffer.from(hash.toString(enc_hex_1.default), "hex")];
const startByte = hashBytes[10];
for (let i = 0; i < 32; i++) {
const byte = hashBytes[i];
let fixed_byte = startByte;
if (i < 31) {
fixed_byte = hashBytes[i + 1];
}
if ((i == 31) || ((i & 1) != 0)) {
hashBytes[10] = fixed_byte;
if ((126 < byte) || (126 < hashBytes[10])) {
if (byte < hashBytes[10] || (byte - hashBytes[10]) == 0) {
hashBytes[i] = hashBytes[10] - byte;
}
else {
hashBytes[i] = byte - hashBytes[10];
}
}
}
else if ((byte < 125) || (fixed_byte < 125)) {
hashBytes[i] = fixed_byte + byte;
}
}
return `${Buffer.from(hashBytes.slice(16)).toString("hex").toUpperCase()}`;
};
exports.getImageKey = getImageKey;
const decodeImage = function (p2pDid, data) {
if (data.length >= 12) {
const header = data.subarray(0, 12).toString();
if (header === "eufysecurity") {
const serialnumber = data.subarray(13, 29).toString();
const code = data.subarray(30, 40).toString();
const imageKey = (0, exports.getImageKey)(serialnumber, p2pDid, code);
const otherData = data.subarray(41);
const encryptedData = otherData.subarray(0, 256);
const cipher = (0, crypto_1.createDecipheriv)("aes-128-ecb", Buffer.from(imageKey, "utf-8").subarray(0, 16), null);
cipher.setAutoPadding(false);
const decryptedData = Buffer.concat([
cipher.update(encryptedData),
cipher.final()
]);
decryptedData.copy(otherData);
return otherData;
}
}
return data;
};
exports.decodeImage = decodeImage;
const getImagePath = function (path) {
const splittedPath = path.split("~");
if (splittedPath.length === 2) {
return splittedPath[1];
}
return path;
};
exports.getImagePath = getImagePath;
const getImage = async function (api, serial, url) {
const { default: imageType } = await import("image-type");
const image = await api.getImage(serial, url);
const type = await imageType(image);
return {
data: image,
type: type !== null && type !== undefined ? type : { ext: "unknown", mime: "application/octet-stream" }
};
};
exports.getImage = getImage;
const isPrioritySourceType = function (current, update) {
if (((current === "http" || current === "p2p" || current === "push" || current === "mqtt" || current === undefined) && (update === "p2p" || update === "push" || update === "mqtt")) ||
((current === "http" || current === undefined) && update === "http")) {
return true;
}
return false;
};
exports.isPrioritySourceType = isPrioritySourceType;
const decryptTrackerData = (data, key) => {
const decipher = (0, crypto_1.createDecipheriv)("aes-128-ecb", key, null);
decipher.setAutoPadding(false);
return Buffer.concat([
decipher.update(data),
decipher.final()
]);
};
exports.decryptTrackerData = decryptTrackerData;
const isT8170DetectionModeEnabled = function (value, type) {
return (type & value) == type;
};
exports.isT8170DetectionModeEnabled = isT8170DetectionModeEnabled;
const getT8170DetectionMode = function (value, type, enable) {
let result = 0;
if ((Object.values(types_1.T8170DetectionTypes).includes(type) && Object.values(types_1.T8170DetectionTypes).includes(value)) && !enable)
return value;
if (!enable) {
result = type ^ value;
}
else {
result = type | value;
}
return result;
};
exports.getT8170DetectionMode = getT8170DetectionMode;
const isIndoorS350DetectionModeEnabled = function (value, type) {
return (type & value) == type;
};
exports.isIndoorS350DetectionModeEnabled = isIndoorS350DetectionModeEnabled;
const getIndoorS350DetectionMode = function (value, type, enable) {
let result = 0;
if ((Object.values(types_1.IndoorS350DetectionTypes).includes(type) && Object.values(types_1.IndoorS350DetectionTypes).includes(value)) && !enable)
return value;
if (!enable) {
result = type ^ value;
}
else {
result = type | value;
}
return result;
};
exports.getIndoorS350DetectionMode = getIndoorS350DetectionMode;
const isIndoorNotitficationEnabled = function (value, type) {
return (type & value) == type;
};
exports.isIndoorNotitficationEnabled = isIndoorNotitficationEnabled;
const getIndoorNotification = function (value, type, enable) {
let result = 0;
if (!enable) {
result = (type ^ value) + 800;
}
else {
result = type | value;
}
return result;
};
exports.getIndoorNotification = getIndoorNotification;
const isFloodlightT8425NotitficationEnabled = function (value, type) {
return (type & value) == type;
};
exports.isFloodlightT8425NotitficationEnabled = isFloodlightT8425NotitficationEnabled;
const getFloodLightT8425Notification = function (value, type, enable) {
let result = 0;
if (!enable) {
result = (type ^ value);
}
else {
result = type | value;
}
return result;
};
exports.getFloodLightT8425Notification = getFloodLightT8425Notification;
const getLockEventType = function (event) {
switch (event) {
case types_2.LockPushEvent.AUTO_LOCK:
case types_2.LockPushEvent.AUTO_UNLOCK:
return 1;
case types_2.LockPushEvent.MANUAL_LOCK:
case types_2.LockPushEvent.MANUAL_UNLOCK:
return 2;
case types_2.LockPushEvent.APP_LOCK:
case types_2.LockPushEvent.APP_UNLOCK:
return 3;
case types_2.LockPushEvent.PW_LOCK:
case types_2.LockPushEvent.PW_UNLOCK:
return 4;
case types_2.LockPushEvent.FINGER_LOCK:
case types_2.LockPushEvent.FINGERPRINT_UNLOCK:
return 5;
case types_2.LockPushEvent.TEMPORARY_PW_LOCK:
case types_2.LockPushEvent.TEMPORARY_PW_UNLOCK:
return 6;
case types_2.LockPushEvent.KEYPAD_LOCK:
return 7;
}
return 0;
};
exports.getLockEventType = getLockEventType;
const switchSmartLockNotification = function (currentValue, mode, enable) {
let result = 0;
if (enable) {
result = mode | currentValue;
}
else {
result = ~mode & currentValue;
}
return result;
};
exports.switchSmartLockNotification = switchSmartLockNotification;
const isSmartLockNotification = function (value, mode) {
return (value & mode) !== 0;
};
exports.isSmartLockNotification = isSmartLockNotification;
const getWaitSeconds = (device) => {
let seconds = 60;
const workingMode = device.getPropertyValue(types_1.PropertyName.DevicePowerWorkingMode);
if (workingMode !== undefined && workingMode === 2) {
const customValue = device.getPropertyValue(types_1.PropertyName.DeviceRecordingClipLength);
if (customValue !== undefined) {
seconds = customValue;
}
}
return seconds;
};
exports.getWaitSeconds = getWaitSeconds;
const loadImageOverP2P = function (station, device, id, p2pTimeouts) {
if (station.hasCommand(types_1.CommandName.StationDatabaseQueryLatestInfo) && p2pTimeouts.get(id) === undefined) {
const seconds = (0, exports.getWaitSeconds)(device);
p2pTimeouts.set(id, setTimeout(async () => {
station.databaseQueryLatestInfo();
p2pTimeouts.delete(id);
}, seconds * 1000));
}
};
exports.loadImageOverP2P = loadImageOverP2P;
const loadEventImage = function (station, api, device, message, p2pTimeouts) {
if (message.notification_style === types_1.NotificationType.MOST_EFFICIENT) {
(0, exports.loadImageOverP2P)(station, device, device.getSerial(), p2pTimeouts);
}
else {
if (!(0, utils_1.isEmpty)(message.pic_url)) {
(0, exports.getImage)(api, device.getSerial(), message.pic_url).then((image) => {
if (image.data.length > 0) {
if (p2pTimeouts.get(device.getSerial()) !== undefined) {
clearTimeout(p2pTimeouts.get(device.getSerial()));
p2pTimeouts.delete(device.getSerial());
}
device.updateProperty(types_1.PropertyName.DevicePicture, image, true);
}
else {
//fallback
(0, exports.loadImageOverP2P)(station, device, device.getSerial(), p2pTimeouts);
}
}).catch((err) => {
const error = (0, error_1.ensureError)(err);
logging_1.rootHTTPLogger.debug(`Device load event image - Fallback Error`, { error: (0, utils_1.getError)(error), stationSN: station.getSerial(), deviceSN: device.getSerial(), message: JSON.stringify(message) });
(0, exports.loadImageOverP2P)(station, device, device.getSerial(), p2pTimeouts);
});
}
else {
//fallback
(0, exports.loadImageOverP2P)(station, device, device.getSerial(), p2pTimeouts);
}
}
};
exports.loadEventImage = loadEventImage;
//# sourceMappingURL=utils.js.map