UNPKG

node-miio

Version:

Control Mi Home devices, such as Mi Robot Vacuums, Mi Air Purifiers, Mi Smart Home Gateway (Aqara) and more

251 lines (225 loc) 6 kB
'use strict'; const { ChargingState, AutonomousCharging } = require('abstract-things'); const { Vacuum, AdjustableFanSpeed, AutonomousCleaning, SpotCleaning, } = require('abstract-things/climate'); const MiioApi = require('../../device'); const BatteryLevel = require('../capabilities/battery-level'); const checkResult = require('../../checkResult'); module.exports = class extends ( Vacuum.with( MiioApi, BatteryLevel, AutonomousCharging, AutonomousCleaning, SpotCleaning, AdjustableFanSpeed, ChargingState ) ) { static get type() { return 'miio:vacuum'; } constructor(options) { super(options); this.defineProperty('err_state', { name: 'error', mapper: (e) => { switch (e) { case 0: return null; default: return { code: e, message: 'Unknown error ' + e, }; } }, }); this.defineProperty('run_state', { name: 'state', mapper: (s) => { switch (s) { case 0: return 'paused'; case 1: return 'initiating'; case 2: return 'waiting'; case 3: return 'cleaning'; case 4: return 'returning'; case 5: return 'charging'; case 6: return 'cleaning-and-mopping'; } return 'unknown-' + s; }, }); // Define the batteryLevel property for monitoring battery this.defineProperty('battary_life', { name: 'batteryLevel', }); this.defineProperty('s_time', { name: 'cleanTime', }); this.defineProperty('s_area', { name: 'cleanArea', mapper: (v) => v / 1000000, }); this.defineProperty('suction_grade', { name: 'fanSpeed', }); // Consumable status - times for brushes and filters // From https://github.com/rytilahti/python-miio/issues/550#issuecomment-570808184 this.defineProperty('main_brush_life', { name: 'mainBrushWorkTime', }); this.defineProperty('side_brush_life', { name: 'sideBrushWorkTime', }); this.defineProperty('hypa_life', { name: 'filterWorkTime', }); this.defineProperty('mop_life', { name: 'mopWorkTime', }); // Monitor the property as is this.defineProperty('hw_info'); this._monitorInterval = 60000; } propertyUpdated(key, value, oldValue) { if (key === 'state') { // Update charging state this.updateCharging(value === 'charging'); switch (value) { case 'cleaning': case 'spot-cleaning': case 'zone-cleaning': case 'room-cleaning': // The vacuum is cleaning this.updateCleaning(true); break; case 'paused': // Cleaning has been paused, do nothing special break; case 'error': // An error has occurred, rely on error mapping this.updateError(this.property('error')); break; case 'charging-error': // Charging error, trigger an error this.updateError({ code: 'charging-error', message: 'Error during charging', }); break; case 'charger-offline': // Charger is offline, trigger an error this.updateError({ code: 'charger-offline', message: 'Charger is offline', }); break; default: // The vacuum is not cleaning this.updateCleaning(false); break; } } else if (key === 'fanSpeed') { this.updateFanSpeed(value); } super.propertyUpdated(key, value, oldValue); } getDeviceInfo() { return this.call('miIO.info'); } async getSerialNumber() { return this.property('hw_info') || 'Unknown'; // We don't know the command to retrieve this bit of info for these models } getRoomMap() { return this.call('get_room_mapping'); } cleanRooms(listOfRooms) { // From https://github.com/rytilahti/python-miio/issues/550#issuecomment-552780952 return this.call( 'set_mode_withroom', [0, 1, listOfRooms.length].concat(listOfRooms), { refresh: ['state'], refreshDelay: 1000, } ).then(checkResult); } resumeCleanRooms(listOfRooms) { return this.cleanRooms(listOfRooms); } getTimer() { return this.call('get_ordertime'); } /** * Start a cleaning session. */ activateCleaning() { return this.call('set_mode_withroom', [0, 1, 0], { refresh: ['state'], refreshDelay: 1000, }).then(checkResult); } /** * Pause the current cleaning session. */ pause() { return this.call('set_mode_withroom', [0, 2, 0], { refresh: ['state'], }).then(checkResult); } /** * Stop the current cleaning session. */ deactivateCleaning() { return this.call('set_mode', [0], { refresh: ['state'], refreshDelay: 1000, }).then(checkResult); } /** * Stop the current cleaning session and return to charge. */ activateCharging() { return this.pause() .then(() => new Promise((resolve) => setTimeout(resolve, 1000))) .then(() => this.call('set_charge', [1], { refresh: ['state'], refreshDelay: 1000, }) ) .then(checkResult); } /** * Set the power of the fan. * From https://github.com/rytilahti/python-miio/blob/20f915c9589fed55544a5417abe3fd3d9e12d08d/miio/viomivacuum.py#L16-L20 * class ViomiVacuumSpeed(Enum): * Silent = 0 * Standard = 1 * Medium = 2 * Turbo = 3 */ changeFanSpeed(speed) { return this.call('set_suction', [speed], { refresh: ['fanSpeed'], }).then(checkResult); } /** * Activate the find function, will make the device give off a sound. */ find() { return this.call('find_me', ['']).then(() => null); } };