homebridge-daikin-oneplus
Version:
Control a Daikin One+ thermostat.
465 lines • 27.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DaikinOnePlusPlatform = void 0;
const settings_1 = require("./settings");
const platformThermostat_1 = require("./platformThermostat");
const platformAQI_1 = require("./platformAQI");
const platformHumidity_1 = require("./platformHumidity");
const platformScheduleSwitch_1 = require("./platformScheduleSwitch");
const platformAwaySwitch_1 = require("./platformAwaySwitch");
const daikinapi_1 = require("./daikinapi");
const platformEmergencyHeatSwitch_1 = require("./platformEmergencyHeatSwitch");
const platformOneCleanFan_1 = require("./platformOneCleanFan");
const platformCirculateAirFan_1 = require("./platformCirculateAirFan");
const platformOutdoorTemperature_1 = require("./platformOutdoorTemperature");
/**
* HomebridgePlatform
* This class is the main constructor for your plugin, this is where you should
* parse the user config and discover/register accessories with Homebridge.
*/
class DaikinOnePlusPlatform {
constructor(log, config, api) {
var _a;
this.accessories = [];
this.api = api;
this.log = log;
this.log.debug = this.debug.bind(this);
this.Service = this.api.hap.Service;
this.Characteristic = this.api.hap.Characteristic;
//Don't start if not configured
if (!config) {
this.log.error('Not configured.');
return;
}
this.config = {
debug: config.debug === true,
user: config.user,
password: config.password,
includeDeviceName: (_a = config.includeDeviceName) !== null && _a !== void 0 ? _a : false,
name: config.name,
enableEmergencyHeatSwitch: 'enableEmergencyHeatSwitch' in config ? config.enableEmergencyHeatSwitch : false,
enableOneCleanFan: 'enableOneCleanFan' in config ? config.enableOneCleanFan : false,
enableCirculateAirFan: 'enableCirculateAirFan' in config ? config.enableCirculateAirFan : false,
enableScheduleSwitch: 'enableScheduleSwitch' in config ? config.enableScheduleSwitch : false,
enableAwaySwitch: 'enableAwaySwitch' in config ? config.enableAwaySwitch : false,
ignoreIndoorAqi: 'ignoreIndoorAqi' in config ? config.ignoreIndoorAqi : false,
ignoreOutdoorAqi: 'ignoreOutdoorAqi' in config ? config.ignoreOutdoorAqi : false,
ignoreIndoorHumSensor: 'ignoreIndoorHumSensor' in config ? config.ignoreIndoorHumSensor : false,
ignoreOutdoorHumSensor: 'ignoreOutdoorHumSensor' in config ? config.ignoreOutdoorHumSensor : false,
ignoreThermostat: 'ignoreThermostat' in config ? config.ignoreThermostat : false,
ignoreOutdoorTemp: 'ignoreOutdoorTemp' in config ? config.ignoreOutdoorTemp : false,
autoResumeSchedule: 'autoResumeSchedule' in config ? config.autoResumeSchedule : false,
};
if (!this.config.user || !this.config.password) {
this.log.error('No Daikin login credentials configured.');
return;
}
this.debug('Debug logging on. Expect lots of messages.');
this.debug('Using Include Device Name setting of %s.', this.config.includeDeviceName);
this.debug('Finished initializing platform: %s', this.config.name);
this.daikinApi = new daikinapi_1.DaikinApi(this.config.user, this.config.password, this.log);
// When this event is fired it means Homebridge has restored all cached accessories from disk.
// Dynamic Platform plugins should only register new accessories after this event was fired,
// in order to ensure they weren't added to homebridge already. This event can also be used
// to start discovery of new accessories.
this.api.on("didFinishLaunching" /* APIEvent.DID_FINISH_LAUNCHING */, this.discover.bind(this));
}
discover() {
this.log.debug('Executed didFinishLaunching callback');
clearTimeout(this.discoverTimer);
//If initialized, no need to try and discover devices again.
if (this.daikinApi.isInitialized()) {
return;
}
this.discoverTimer = setTimeout(() => {
void (async () => {
// run the method to discover / register your devices as accessories
await this.discoverDevices();
//Call discover again in case we failed to initialize the api and discover devices.
this.discover();
})();
}, 10 * 1000);
}
/**
* This function is invoked when homebridge restores cached accessories from disk at startup.
* It should be used to setup event handlers for characteristics and update respective values.
*/
configureAccessory(accessory) {
this.log.info('Loading accessory from cache:', accessory.displayName);
// add the restored accessory to the accessories cache so we can track if it has already been registered
this.accessories.push(accessory);
}
/**
* This is an example method showing how to register discovered accessories.
* Accessories must only be registered once, previously created accessories
* must not be registered again to prevent "duplicate UUID" errors.
*/
async discoverDevices() {
if (!this.config.user && !this.config.password) {
this.log.error('Credentials not set. Aborting discovery of devices.');
return;
}
await this.daikinApi.Initialize();
if (!this.daikinApi.isInitialized()) {
this.log.error('Unable to retrieve devices. Aborting discovery of devices.');
return;
}
const devices = this.daikinApi.getDeviceList() || [];
// loop over the discovered devices and register each one if it has not already been registered
for (const device of devices) {
this.log.info('Found device: %s', device.name);
const deviceData = await this.daikinApi.getDeviceData(device.id);
this.discoverThermostat(device);
this.discoverOutdoorTemp(device);
this.discoverOutdoorHumSensor(device);
this.discoverIndoorHumSensor(device);
this.discoverOutdoorAqi(device, deviceData);
this.discoverIndoorAqi(device, deviceData);
this.discoverScheduleSwitch(device);
this.discoverAwaySwitch(device);
this.discoverEmergencyHeatSwitch(device);
this.discoverOneCleanFan(device);
this.discoverCirculateAirFan(device);
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
discoverEmergencyHeatSwitch(device) {
const uuid = this.api.hap.uuid.generate(`${device.id}_emergency_heat`);
this.log.debug('Checking for Emergency Heat Switch...');
const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
if (this.config.enableEmergencyHeatSwitch) {
const dName = this.accessoryName(device, 'Emergency Heat');
if (existingAccessory) {
// the accessory already exists
existingAccessory.displayName = dName;
existingAccessory.context.device = device;
this.log.debug('Restoring existing emergency heat switch from cache:', existingAccessory.displayName);
new platformEmergencyHeatSwitch_1.DaikinOnePlusEmergencyHeatSwitch(this, existingAccessory, device.id, this.daikinApi);
}
else {
// the accessory does not yet exist, so we need to create it
this.log.debug('Adding new emergency heat switch:', dName);
const accessory = new this.api.platformAccessory(dName, uuid);
accessory.context.device = device;
new platformEmergencyHeatSwitch_1.DaikinOnePlusEmergencyHeatSwitch(this, accessory, device.id, this.daikinApi);
this.api.registerPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [accessory]);
}
}
else if (existingAccessory) {
//Delete any existing Emergency Heat switch
this.log.debug('Removing emergency heat switch from cache:', existingAccessory.displayName);
this.api.unregisterPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [existingAccessory]);
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
discoverOneCleanFan(device) {
const uuid = this.api.hap.uuid.generate(`${device.id}_one_clean_fan`);
this.log.debug('Checking for One Clean Fan...');
const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
if (this.config.enableOneCleanFan) {
const dName = this.accessoryName(device, 'One Clean');
if (existingAccessory) {
// the accessory already exists
existingAccessory.displayName = dName;
existingAccessory.context.device = device;
this.log.debug('Restoring existing one clean fan from cache:', existingAccessory.displayName);
new platformOneCleanFan_1.DaikinOnePlusOneCleanFan(this, existingAccessory, device.id, this.daikinApi);
}
else {
// the accessory does not yet exist, so we need to create it
this.log.debug('Adding new one clean fan:', dName);
const accessory = new this.api.platformAccessory(dName, uuid);
accessory.context.device = device;
new platformOneCleanFan_1.DaikinOnePlusOneCleanFan(this, accessory, device.id, this.daikinApi);
this.api.registerPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [accessory]);
}
}
else if (existingAccessory) {
//Delete any existing one clean fan
this.log.debug('Removing one clean fan from cache:', existingAccessory.displayName);
this.api.unregisterPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [existingAccessory]);
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
discoverCirculateAirFan(device) {
const uuid = this.api.hap.uuid.generate(`${device.id}_circ_air_fan`);
this.log.debug('Checking for Circulate Air Fan...');
const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
if (this.config.enableCirculateAirFan) {
const dName = this.accessoryName(device, 'Circulate Air');
if (existingAccessory) {
// the accessory already exists
existingAccessory.displayName = dName;
existingAccessory.context.device = device;
this.log.debug('Restoring existing circulate air fan from cache:', existingAccessory.displayName);
new platformCirculateAirFan_1.DaikinOnePlusCirculateAirFan(this, existingAccessory, device.id, this.daikinApi);
}
else {
// the accessory does not yet exist, so we need to create it
this.log.debug('Adding new circulate air fan:', dName);
const accessory = new this.api.platformAccessory(dName, uuid);
accessory.context.device = device;
new platformCirculateAirFan_1.DaikinOnePlusCirculateAirFan(this, accessory, device.id, this.daikinApi);
this.api.registerPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [accessory]);
}
}
else if (existingAccessory) {
//Delete any existing one clean fan
this.log.debug('Removing circulate air fan from cache:', existingAccessory.displayName);
this.api.unregisterPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [existingAccessory]);
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
discoverScheduleSwitch(device) {
const uuid = this.api.hap.uuid.generate(`${device.id}_schedule`);
this.log.debug('Checking for Schedule Switch...');
const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
if (this.config.enableScheduleSwitch) {
const dName = this.accessoryName(device, 'Schedule State');
if (existingAccessory) {
// the accessory already exists
existingAccessory.displayName = dName;
existingAccessory.context.device = device;
this.log.debug('Restoring existing schedule switch from cache:', existingAccessory.displayName);
new platformScheduleSwitch_1.DaikinOnePlusScheduleSwitch(this, existingAccessory, device.id, this.daikinApi);
}
else {
// the accessory does not yet exist, so we need to create it
this.log.debug('Adding new schedule switch:', dName);
const accessory = new this.api.platformAccessory(dName, uuid);
accessory.context.device = device;
new platformScheduleSwitch_1.DaikinOnePlusScheduleSwitch(this, accessory, device.id, this.daikinApi);
this.api.registerPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [accessory]);
}
}
else if (existingAccessory) {
//Delete any existing Schedule switch
this.log.debug('Removing Schedule switch from cache:', existingAccessory.displayName);
this.api.unregisterPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [existingAccessory]);
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
discoverAwaySwitch(device) {
const uuid = this.api.hap.uuid.generate(`${device.id}_away`);
this.log.debug('Checking for Away Switch...');
const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
if (this.config.enableAwaySwitch) {
const dName = this.accessoryName(device, 'Away State');
if (existingAccessory) {
// the accessory already exists
existingAccessory.displayName = dName;
existingAccessory.context.device = device;
this.log.debug('Restoring existing away switch from cache:', existingAccessory.displayName);
new platformAwaySwitch_1.DaikinOnePlusAwaySwitch(this, existingAccessory, device.id, this.daikinApi);
}
else {
// the accessory does not yet exist, so we need to create it
this.log.debug('Adding new away switch:', dName);
const accessory = new this.api.platformAccessory(dName, uuid);
accessory.context.device = device;
new platformAwaySwitch_1.DaikinOnePlusAwaySwitch(this, accessory, device.id, this.daikinApi);
this.api.registerPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [accessory]);
}
}
else if (existingAccessory) {
//Delete any existing Away switch
this.log.debug('Removing Away switch from cache:', existingAccessory.displayName);
this.api.unregisterPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [existingAccessory]);
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
discoverIndoorAqi(device, deviceData) {
const uuid = this.api.hap.uuid.generate(`${device.id}_iaqi`);
this.log.debug('Checking for indoor Air Quality sensor...');
const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
if (!this.config.ignoreIndoorAqi) {
const dName = this.accessoryName(device, 'Indoor AQI');
if (deviceData && deviceData.aqIndoorAvailable) {
if (existingAccessory) {
// the accessory already exists
existingAccessory.displayName = dName;
existingAccessory.context.device = device;
this.log.debug('Restoring existing indoor Air Quality sensor from cache:', existingAccessory.displayName);
new platformAQI_1.DaikinOnePlusAQSensor(this, existingAccessory, device.id, this.daikinApi, true);
}
else {
// the accessory does not yet exist, so we need to create it
this.log.debug('Adding new indoor Air Quality sensor:', dName);
const accessory = new this.api.platformAccessory(dName, uuid);
accessory.context.device = device;
new platformAQI_1.DaikinOnePlusAQSensor(this, accessory, device.id, this.daikinApi, true);
this.api.registerPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [accessory]);
}
}
else if (existingAccessory) {
this.log.debug('Removing legacy indoor Air Quality Sensor from cache:', existingAccessory.displayName);
this.api.unregisterPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [existingAccessory]);
}
}
else if (existingAccessory) {
//Delete any existing Indoor AQI switch
this.log.debug('Removing Indoor AQI sensor from cache:', existingAccessory.displayName);
this.api.unregisterPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [existingAccessory]);
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
discoverOutdoorAqi(device, deviceData) {
const uuid = this.api.hap.uuid.generate(`${device.id}_oaqi`);
this.log.debug('Checking for outdoor Air Quality sensor...');
const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
if (!this.config.ignoreOutdoorAqi) {
const dName = this.accessoryName(device, 'Outdoor AQI');
if (deviceData && deviceData.aqOutdoorAvailable) {
if (existingAccessory) {
// the accessory already exists
existingAccessory.displayName = dName;
existingAccessory.context.device = device;
this.log.debug('Restoring existing outdoor Air Quality sensor from cache:', existingAccessory.displayName);
new platformAQI_1.DaikinOnePlusAQSensor(this, existingAccessory, device.id, this.daikinApi, false);
}
else {
// the accessory does not yet exist, so we need to create it
this.log.debug('Adding new outdoor Air Quality sensor:', dName);
const accessory = new this.api.platformAccessory(dName, uuid);
accessory.context.device = device;
new platformAQI_1.DaikinOnePlusAQSensor(this, accessory, device.id, this.daikinApi, false);
this.api.registerPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [accessory]);
}
}
else if (existingAccessory) {
this.log.debug('Removing legacy outdoor Air Quality Sensor from cache:', existingAccessory.displayName);
this.api.unregisterPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [existingAccessory]);
}
}
else if (existingAccessory) {
//Delete any existing Outdoor AQI sensor
this.log.debug('Removing Outdoor AQI sensor from cache:', existingAccessory.displayName);
this.api.unregisterPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [existingAccessory]);
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
discoverIndoorHumSensor(device) {
const uuid = this.api.hap.uuid.generate(`${device.id}_ihum`);
this.log.debug('Checking for indoor humidity sensor...');
const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
if (!this.config.ignoreIndoorHumSensor) {
const dName = this.accessoryName(device, 'Indoor Humidity');
if (existingAccessory) {
// the accessory already exists
existingAccessory.displayName = dName;
existingAccessory.context.device = device;
this.log.debug('Restoring existing indoor humidity sensor from cache:', existingAccessory.displayName);
new platformHumidity_1.DaikinOnePlusHumidity(this, existingAccessory, device.id, this.daikinApi, true);
}
else {
// the accessory does not yet exist, so we need to create it
this.log.debug('Adding new indoor humidity sensor:', dName);
const accessory = new this.api.platformAccessory(dName, uuid);
accessory.context.device = device;
new platformHumidity_1.DaikinOnePlusHumidity(this, accessory, device.id, this.daikinApi, true);
this.api.registerPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [accessory]);
}
}
else if (existingAccessory) {
//Delete any existing Indoor Humidity sensor
this.log.debug('Removing Indoor Humidity sensor from cache:', existingAccessory.displayName);
this.api.unregisterPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [existingAccessory]);
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
discoverOutdoorHumSensor(device) {
const uuid = this.api.hap.uuid.generate(`${device.id}_ohum`);
this.log.debug('Checking for outdoor humidity sensor...');
const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
if (!this.config.ignoreOutdoorHumSensor) {
const dName = this.accessoryName(device, 'Outdoor Humidity');
if (existingAccessory) {
// the accessory already exists
existingAccessory.displayName = dName;
existingAccessory.context.device = device;
this.log.debug('Restoring existing outdoor humidity sensor from cache:', existingAccessory.displayName);
new platformHumidity_1.DaikinOnePlusHumidity(this, existingAccessory, device.id, this.daikinApi, false);
}
else {
// the accessory does not yet exist, so we need to create it
this.log.debug('Adding new outdoor humidity sensor:', dName);
const accessory = new this.api.platformAccessory(dName, uuid);
accessory.context.device = device;
new platformHumidity_1.DaikinOnePlusHumidity(this, accessory, device.id, this.daikinApi, false);
this.api.registerPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [accessory]);
}
}
else if (existingAccessory) {
//Delete any existing Outdoor Humidity sensor
this.log.debug('Removing Outdoor Humidity sensor from cache:', existingAccessory.displayName);
this.api.unregisterPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [existingAccessory]);
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
discoverThermostat(device) {
const uuid = this.api.hap.uuid.generate(`${device.id}_tstat`);
this.log.debug('Checking for thermostat...');
const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
if (!this.config.ignoreThermostat) {
const dName = this.accessoryName(device, 'Thermostat');
if (existingAccessory) {
// the accessory already exists
existingAccessory.displayName = dName;
existingAccessory.context.device = device;
this.log.debug('Restoring existing thermostat from cache:', existingAccessory.displayName);
new platformThermostat_1.DaikinOnePlusThermostat(this, existingAccessory, device.id, this.daikinApi);
}
else {
// the accessory does not yet exist, so we need to create it
this.log.debug('Adding new thermostat:', dName);
const accessory = new this.api.platformAccessory(dName, uuid);
accessory.context.device = device;
new platformThermostat_1.DaikinOnePlusThermostat(this, accessory, device.id, this.daikinApi);
this.api.registerPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [accessory]);
}
}
else if (existingAccessory) {
this.log.debug('Removing Thermostat from cache:', existingAccessory.displayName);
this.api.unregisterPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [existingAccessory]);
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
discoverOutdoorTemp(device) {
const uuid = this.api.hap.uuid.generate(`${device.id}_otemp`);
this.log.debug('checking for Outdoor Temperature...');
const existingaccessory = this.accessories.find(accessory => accessory.UUID === uuid);
if (!this.config.ignoreOutdoorTemp) {
const dname = this.accessoryName(device, 'Outdoor Temperature');
if (existingaccessory) {
// the accessory already exists
existingaccessory.displayName = dname;
existingaccessory.context.device = device;
this.log.debug('restoring existing Outdoor Temperature from cache:', existingaccessory.displayName);
new platformOutdoorTemperature_1.DaikinOnePlusOutdoorTemperature(this, existingaccessory, device.id, this.daikinApi);
}
else {
// the accessory does not yet exist, so we need to create it
this.log.debug('adding new Outdoor Temperature:', dname);
const accessory = new this.api.platformAccessory(dname, uuid);
accessory.context.device = device;
new platformOutdoorTemperature_1.DaikinOnePlusOutdoorTemperature(this, accessory, device.id, this.daikinApi);
this.api.registerPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [accessory]);
}
}
else if (existingaccessory) {
this.log.debug('removing Outdoor Temperature from cache:', existingaccessory.displayName);
this.api.unregisterPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [existingaccessory]);
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
accessoryName(device, accessory) {
return this.config.includeDeviceName ? `${device.name} ${accessory}` : accessory;
}
debug(message, ...parameters) {
if (this.config.debug) {
this.log.info(message, ...parameters);
}
}
}
exports.DaikinOnePlusPlatform = DaikinOnePlusPlatform;
//# sourceMappingURL=platform.js.map