UNPKG

@hov3rcraft/homebridge-eufy-robovac

Version:
360 lines 13.7 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.RoboVac = exports.getErrorCodeFriendlyName = exports.errorCodeFriendlyNames = exports.ErrorCode = exports.CleanSpeed = exports.WorkStatus = exports.WorkMode = exports.Direction = exports.formatStatusResponse = exports.statusDpsFriendlyNames = exports.StatusDps = void 0; const consoleLogger_1 = require("./consoleLogger"); const tuyapi_1 = __importDefault(require("tuyapi")); var StatusDps; (function (StatusDps) { StatusDps["DEFAULT"] = "1"; StatusDps["RUNNING"] = "2"; StatusDps["DIRECTION"] = "3"; StatusDps["WORK_MODE"] = "5"; StatusDps["WORK_STATUS"] = "15"; StatusDps["GO_HOME"] = "101"; StatusDps["CLEAN_SPEED"] = "102"; StatusDps["FIND_ROBOT"] = "103"; StatusDps["BATTERY_LEVEL"] = "104"; StatusDps["ERROR_CODE"] = "106"; })(StatusDps || (exports.StatusDps = StatusDps = {})); exports.statusDpsFriendlyNames = new Map([ [StatusDps.DEFAULT, "Default Property (ignore)"], [StatusDps.RUNNING, "Running"], [StatusDps.DIRECTION, "Direction"], [StatusDps.WORK_MODE, "Work Mode"], [StatusDps.WORK_STATUS, "Work Status"], [StatusDps.GO_HOME, "Go Home"], [StatusDps.CLEAN_SPEED, "Clean Speed"], [StatusDps.FIND_ROBOT, "Find Robot"], [StatusDps.BATTERY_LEVEL, "Battery Level"], [StatusDps.ERROR_CODE, "Error Code"] ]); function formatStatusResponse(statusResponse) { let formattedStatus = `-- Status Start --\n`; for (const dps of Object.values(StatusDps)) { if (dps in statusResponse.dps) { formattedStatus += `- ${exports.statusDpsFriendlyNames.get(dps)}: ${(statusResponse.dps)[dps]}\n`; } } formattedStatus += `-- Status End --`; return formattedStatus; } exports.formatStatusResponse = formatStatusResponse; var Direction; (function (Direction) { Direction["FORWARD"] = "forward"; Direction["BACKWARD"] = "backward"; Direction["LEFT"] = "left"; Direction["RIGHT"] = "right"; })(Direction || (exports.Direction = Direction = {})); var WorkMode; (function (WorkMode) { WorkMode["AUTO"] = "auto"; WorkMode["SMALL_ROOM"] = "SmallRoom"; WorkMode["SPOT"] = "Spot"; WorkMode["EDGE"] = "Edge"; WorkMode["NO_SWEEP"] = "Nosweep"; })(WorkMode || (exports.WorkMode = WorkMode = {})); var WorkStatus; (function (WorkStatus) { // Cleaning WorkStatus["RUNNING"] = "Running"; // Not in the dock, paused WorkStatus["STAND_BY"] = "standby"; // Not in the dock - goes into this state after being paused for a while WorkStatus["SLEEPING"] = "Sleeping"; // In the dock, charging WorkStatus["CHARGING"] = "Charging"; // In the dock, full charged WorkStatus["CHARGING_COMPLETED"] = "completed"; // Going home because battery is depleted or home was pressed WorkStatus["RECHARGE_NEEDED"] = "Recharge"; })(WorkStatus || (exports.WorkStatus = WorkStatus = {})); var CleanSpeed; (function (CleanSpeed) { CleanSpeed["STANDARD"] = "Standard"; CleanSpeed["BOOST_IQ"] = "Boost_IQ"; CleanSpeed["MAX"] = "Max"; CleanSpeed["NO_SUCTION"] = "No_suction"; })(CleanSpeed || (exports.CleanSpeed = CleanSpeed = {})); var ErrorCode; (function (ErrorCode) { ErrorCode["NO_ERROR"] = "no_error"; ErrorCode["STUCK_5_MIN"] = "Stuck_5_min"; ErrorCode["CRASH_BAR_STUCK"] = "Crash_bar_stuck"; ErrorCode["SENSOR_DIRTY"] = "sensor_dirty"; ErrorCode["NOT_ENOUGH_POWER"] = "N_enough_pow"; ErrorCode["WHEEL_STUCK"] = "Wheel_stuck"; ErrorCode["S_BRUSH_STUCK"] = "S_brush_stuck"; ErrorCode["FAN_STUCK"] = "Fan_stuck"; ErrorCode["R_BRUSH_STUCK"] = "R_brush_stuck"; })(ErrorCode || (exports.ErrorCode = ErrorCode = {})); exports.errorCodeFriendlyNames = new Map([ [ErrorCode.NO_ERROR, "No Error"], [ErrorCode.STUCK_5_MIN, "Stuck (5 Minutes)"], [ErrorCode.CRASH_BAR_STUCK, "Crash Bar Stuck"], [ErrorCode.SENSOR_DIRTY, "Sensor Dirty"], [ErrorCode.NOT_ENOUGH_POWER, "Not Enough Power"], [ErrorCode.WHEEL_STUCK, "Wheel Stuck"], [ErrorCode.S_BRUSH_STUCK, "Brush Stuck"], [ErrorCode.FAN_STUCK, "Fan Stuck"], [ErrorCode.R_BRUSH_STUCK, "Brush Stuck"] ]); function getErrorCodeFriendlyName(errorCode) { var _a; return (_a = exports.errorCodeFriendlyNames.get(errorCode)) !== null && _a !== void 0 ? _a : errorCode; } exports.getErrorCodeFriendlyName = getErrorCodeFriendlyName; class RoboVac { constructor(config, dataReceivedCallback, cachingDuration, log = new consoleLogger_1.ConsoleLogger()) { this.cachingDuration = cachingDuration; this.log = log; if (log instanceof consoleLogger_1.ConsoleLogger) { this.consoleDebugLog = (log.logLevel <= 1); } else { this.consoleDebugLog = false; } this.directConnect = (config.deviceIp != null && config.deviceIp != ""); this.api = new tuyapi_1.default({ id: config.deviceId, key: config.localKey, ip: this.directConnect ? config.deviceIp : undefined, version: '3.3', issueRefreshOnConnect: true }); // Add event listeners this.api.on('connected', () => { log.info('Connected to device!'); }); this.api.on('disconnected', () => { log.info('Disconnected from device.'); }); this.api.on('error', (error) => { log.error('Error!', error); this.disconnect(); }); this.api.on('dp-refresh', (data) => { if (this.consoleDebugLog) { try { this.log.debug("Received dps refresh data from device:", "\n" + formatStatusResponse(data)); } catch (e) { this.log.debug("Received dps refresh data from device:", data); } } else { this.log.debug("Received dps refresh data from device:", data); } if (data.dps) { Object.assign(this.lastStatus.dps, data.dps); this.lastStatusUpdate = new Date(); dataReceivedCallback(data); } }); this.api.on('data', (data) => { if (this.consoleDebugLog) { try { this.log.debug("Received data from device:", "\n" + formatStatusResponse(data)); } catch (e) { this.log.debug("Received data from device:", data); } } else { this.log.debug("Received data from device:", data); } if (data.dps) { Object.assign(this.lastStatus.dps, data.dps); this.lastStatusUpdate = new Date(); this.lastStatusValid = true; dataReceivedCallback(data); } }); // init with default values this.lastStatus = { devId: "default - invalid", dps: { [StatusDps.DEFAULT]: false, [StatusDps.RUNNING]: false, [StatusDps.DIRECTION]: Direction.FORWARD, [StatusDps.WORK_MODE]: WorkMode.NO_SWEEP, [StatusDps.WORK_STATUS]: WorkStatus.CHARGING, [StatusDps.GO_HOME]: false, [StatusDps.CLEAN_SPEED]: CleanSpeed.NO_SUCTION, [StatusDps.FIND_ROBOT]: false, [StatusDps.BATTERY_LEVEL]: -1, [StatusDps.ERROR_CODE]: "default - invalid", } }; this.lastStatusUpdate = new Date(0); this.lastStatusValid = false; this.ongoingStatusUpdate = null; this.connect().catch((e) => { this.log.error("Error during initial connect:", e); }); } async connect() { if (!this.directConnect) { // Find device on network if there is no ip specified in config await this.api.find(); } // Connect to device await this.api.connect(); } async disconnect() { this.ongoingStatusUpdate = null; this.lastStatusValid = false; if (this.api.isConnected()) { await this.api.disconnect(); } } getStatusCached() { return this.lastStatusValid ? this.lastStatus : null; } async getStatus() { if (!this.lastStatusValid || Math.abs(new Date().getTime() - this.lastStatusUpdate.getTime()) > this.cachingDuration) { return this.getStatusFromDeviceSynchronized(); } else { this.log.debug("Status request within max status update age"); return this.lastStatus; } } async getStatusFromDeviceSynchronized() { if (this.ongoingStatusUpdate != null) { this.log.debug("Duplicate status update request detected"); return this.ongoingStatusUpdate; } this.ongoingStatusUpdate = this.getStatusFromDevice(); return this.ongoingStatusUpdate; } async getStatusFromDevice() { this.log.info("Fetching status update..."); try { if (!this.api.isConnected()) { await this.connect(); } const schema = await this.api.get({ schema: true }); this.lastStatus = schema; this.lastStatusUpdate = new Date(); this.lastStatusValid = true; this.ongoingStatusUpdate = null; this.log.debug("Status update retrieved."); return this.lastStatus; } catch (e) { this.log.error("An error occurred (during GET status update)!", e); try { this.disconnect(); } catch (e2) { } throw e; } } async set(dps, newValue) { this.log.debug("Setting", exports.statusDpsFriendlyNames.get(dps), "to", newValue, "..."); try { if (!this.api.isConnected()) { await this.connect(); } await this.api.set({ dps: parseInt(dps), set: newValue }); this.log.info("Setting", exports.statusDpsFriendlyNames.get(dps), "to", newValue, "successful."); } catch (e) { this.log.error("An error occurred! (during SET of", exports.statusDpsFriendlyNames.get(dps), "to", newValue, "): ", e); try { this.disconnect(); } catch (e2) { } throw e; } } async getRunning() { const robovacStatus = await this.getStatus(); return robovacStatus.dps[StatusDps.RUNNING]; } async getDirection() { const robovacStatus = await this.getStatus(); return robovacStatus.dps[StatusDps.DIRECTION]; } async getWorkMode() { const robovacStatus = await this.getStatus(); return robovacStatus.dps[StatusDps.WORK_MODE]; } async getWorkStatus() { const robovacStatus = await this.getStatus(); return robovacStatus.dps[StatusDps.WORK_STATUS]; } async getGoHome() { const robovacStatus = await this.getStatus(); return robovacStatus.dps[StatusDps.GO_HOME]; } async getCleanSpeed() { const robovacStatus = await this.getStatus(); return robovacStatus.dps[StatusDps.CLEAN_SPEED]; } async getFindRobot() { const robovacStatus = await this.getStatus(); return robovacStatus.dps[StatusDps.FIND_ROBOT]; } async getBatteryLevel() { const robovacStatus = await this.getStatus(); return robovacStatus.dps[StatusDps.BATTERY_LEVEL]; } async getErrorCode() { const robovacStatus = await this.getStatus(); return robovacStatus.dps[StatusDps.ERROR_CODE]; } getRunningCached() { return this.lastStatusValid ? this.lastStatus.dps[StatusDps.RUNNING] : null; } getDirectionCached() { return this.lastStatusValid ? this.lastStatus.dps[StatusDps.DIRECTION] : null; } getWorkModeCached() { return this.lastStatusValid ? this.lastStatus.dps[StatusDps.WORK_MODE] : null; } getWorkStatusCached() { return this.lastStatusValid ? this.lastStatus.dps[StatusDps.WORK_STATUS] : null; } getGoHomeCached() { return this.lastStatusValid ? this.lastStatus.dps[StatusDps.GO_HOME] : null; } getCleanSpeedCached() { return this.lastStatusValid ? this.lastStatus.dps[StatusDps.CLEAN_SPEED] : null; } getFindRobotCached() { return this.lastStatusValid ? this.lastStatus.dps[StatusDps.FIND_ROBOT] : null; } getBatteryLevelCached() { return this.lastStatusValid ? this.lastStatus.dps[StatusDps.BATTERY_LEVEL] : null; } getErrorCodeCached() { return this.lastStatusValid ? this.lastStatus.dps[StatusDps.ERROR_CODE] : null; } async setPlayPause(newValue) { return this.set(StatusDps.RUNNING, newValue); } async setDirection(newValue) { return this.set(StatusDps.DIRECTION, newValue); } async setWorkMode(newValue) { return this.set(StatusDps.WORK_MODE, newValue); } async setGoHome(newValue) { return this.set(StatusDps.GO_HOME, newValue); } async setCleanSpeed(newValue) { return this.set(StatusDps.CLEAN_SPEED, newValue); } async setFindRobot(newValue) { return this.set(StatusDps.FIND_ROBOT, newValue); } } exports.RoboVac = RoboVac; //# sourceMappingURL=robovac-api.js.map