@george.talusan/homebridge-eufy-robovac
Version:
Homebridge Plugin for Eufy Robovac
144 lines • 5.83 kB
JavaScript
import { DefaultPlatformAccessory } from './defaultAccessory.js';
import { EufyRobovacMatterAccessory } from './matter/EufyRobovacMatterAccessory.js';
import { PLATFORM_NAME, PLUGIN_NAME } from './settings.js';
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const { RoboVac } = require('@george.talusan/eufy-robovac-js');
export class EufyRobovacHomebridgePlatform {
log;
config;
api;
Service;
Characteristic;
accessories = [];
matterAccessories = new Map();
robovac;
connected = false;
matterEnabled = false;
reconnecting = false;
constructor(log, config, api) {
this.log = log;
this.config = config;
this.api = api;
this.Service = api.hap.Service;
this.Characteristic = api.hap.Characteristic;
if (!this.parseConfig()) {
return;
}
// Check Matter availability
if (!this.api.isMatterAvailable?.()) {
this.log.warn('Matter is not available in this version of Homebridge. HAP accessories will still work.');
}
else if (!this.api.isMatterEnabled?.()) {
this.log.warn('Matter is not enabled in Homebridge. Enable Matter in settings to use Matter accessories.');
}
else {
this.matterEnabled = true;
this.log.info('Matter is available and enabled.');
}
this.log.debug('Finished initializing platform:', this.config.name);
this.api.on('didFinishLaunching', async () => {
log.debug('Executed didFinishLaunching callback');
try {
this.robovac = new RoboVac({ ip: config.ip, deviceId: config.deviceId, localKey: config.deviceKey });
this.robovac.on('tuya.connected', () => {
this.connected = true;
this.log.info('Connected');
});
this.robovac.on('tuya.disconnected', () => {
this.log.info('Disconnected. Attempting reconnect...');
this.connected = false;
if (this.reconnecting) {
return;
}
this.reconnecting = true;
const id = setInterval(async () => {
try {
await this.robovac.connect();
clearInterval(id);
this.reconnecting = false;
}
catch (error) {
this.log.error(error);
}
}, 2000);
});
this.robovac.on('error', (error) => {
this.log.info(error);
});
await this.robovac.initialize();
}
catch (error) {
this.log.error(error);
return;
}
this.discoverDevices();
if (this.matterEnabled) {
await this.registerMatterAccessories();
}
});
}
configureAccessory(accessory) {
this.log.info('Loading accessory from cache:', accessory.displayName);
this.accessories.push(accessory);
}
configureMatterAccessory(accessory) {
this.log.debug('Loading cached Matter accessory:', accessory.displayName);
this.matterAccessories.set(accessory.UUID, accessory);
}
async registerMatterAccessories() {
const vacuumAccessory = new EufyRobovacMatterAccessory(this.api, this.log, this.config, this.robovac);
const newAccessories = [];
if (!this.matterAccessories.has(vacuumAccessory.UUID)) {
newAccessories.push(vacuumAccessory.toAccessory());
this.log.info('Registering new Matter accessory:', vacuumAccessory.displayName);
}
else {
this.log.info('Restoring cached Matter accessory:', vacuumAccessory.displayName);
}
if (newAccessories.length > 0) {
await this.api.matter.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, newAccessories);
}
vacuumAccessory.setMatterReady();
}
discoverDevices() {
const accessories = [
{
displayName: () => {
return `${this.config.name}`;
},
uuid: () => {
return this.api.hap.uuid.generate(`${this.config.name}-${this.config.ip}`);
},
make: (accessory) => {
new DefaultPlatformAccessory(this, accessory);
},
},
];
for (const a of accessories) {
const uuid = a.uuid();
const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
if (existingAccessory) {
this.log.info('Restoring existing accessory from cache:', existingAccessory.displayName);
a.make(existingAccessory);
}
else {
this.log.info('Adding new accessory:', a.displayName());
const accessory = new this.api.platformAccessory(a.displayName(), uuid);
accessory.context.displayName = a.displayName();
a.make(accessory);
this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
}
}
}
parseConfig() {
['name', 'ip', 'deviceId', 'deviceKey'].forEach((required) => {
if (!this.config[required]) {
this.log.error(`Please configure ${PLATFORM_NAME} correctly. Missing key '${required}'`);
return false;
}
});
return true;
}
}
//# sourceMappingURL=platform.js.map