iobroker.melcloud
Version:
626 lines (554 loc) • 24.7 kB
JavaScript
"use strict";
/*
* Created with @iobroker/create-adapter v1.24.1
*/
// The adapter-core module gives you access to the core ioBroker functions
const utils = require("@iobroker/adapter-core");
// Needed modules
const cloudPlatform = require("./lib/melcloudPlatform");
const commonDefines = require("./lib/commonDefines");
let gthis = null; // global to 'this' of Melcloud main instance
let CloudPlatform = null;
const stateValueCache = {}; // used to store all adapter state values to check for unchanged values
class Melcloud extends utils.Adapter {
/**
* @param {Partial<ioBroker.AdapterOptions>} [options={}]
*/
constructor(options) {
// @ts-ignore
super({
...options,
name: "melcloud",
});
this.on("ready", this.onReady.bind(this));
this.on("stateChange", this.onStateChange.bind(this));
this.on("unload", this.onUnload.bind(this));
gthis = this;
this.deviceObjects = []; // array of all device objects
this.currentKnownDeviceIDs = []; // array of all current known device IDs
}
async checkSettings() {
this.log.debug("Checking adapter settings...");
if (this.config.melCloudEmail == null || this.config.melCloudEmail == "") {
throw new Error("MELCloud username empty! Check settings.");
}
if (this.config.melCloudPassword == null || this.config.melCloudPassword == "") {
throw new Error("MELCloud password empty! Check settings.");
}
// Minimum pollingInterval = 5 to prevent rate limiting
if (this.config.pollingInterval < 5) {
this.config.pollingInterval = 5;
this.log.warn("Polling interval can't be set lower than 5 minutes to avoid being throttled by the MELCloud servers. Now set to 5 minutes.");
}
if (this.config.ignoreSslErrors) {
this.log.info("SSL errors are ignored when communicating with the cloud. This is potentially insecure!");
}
}
async setAdapterConnectionState(isConnected) {
await this.setStateChangedAsync(`${commonDefines.AdapterDatapointIDs.Info}.${commonDefines.AdapterStateIDs.Connection}`, isConnected, true);
await this.setForeignState(`system.adapter.${this.namespace}.connected`, isConnected, true);
}
async saveKnownDeviceIDs() {
this.log.debug("Getting current known devices...");
const prefix = `${this.namespace}.${commonDefines.AdapterDatapointIDs.Devices}.`;
const objects = await this.getAdapterObjectsAsync();
for (const id of Object.keys(objects)) {
if (!id.startsWith(prefix)) {
continue;
}
const deviceIdTemp = id.replace(prefix, "");
const deviceId = parseInt(deviceIdTemp.substring(0, deviceIdTemp.lastIndexOf(".")), 10);
// Add each device only one time
if (!isNaN(deviceId) && !this.currentKnownDeviceIDs.includes(deviceId)) {
this.currentKnownDeviceIDs.push(deviceId);
this.log.debug(`Found known device: ${deviceId}`);
}
}
if (this.currentKnownDeviceIDs.length == 0) {
this.log.debug("No known devices found.");
}
}
async deleteMelDevice(id) {
const prefix = `${this.namespace}.${commonDefines.AdapterDatapointIDs.Devices}.${id}`;
const objects = await this.getAdapterObjectsAsync();
for (const id of Object.keys(objects)) {
if (id.startsWith(prefix)) {
const objID = id.replace(`${this.namespace}.`, "");
this.log.debug(`Deleting state '${objID}'`);
await this.delObjectAsync(objID);
}
}
}
async initObjects() {
this.log.debug("Initializing objects...");
await this.setObjectNotExistsAsync(commonDefines.AdapterDatapointIDs.Devices, {
type: "folder",
common: {
name: "Devices",
},
native: {},
});
//#region INFO
await this.setObjectNotExistsAsync(commonDefines.AdapterDatapointIDs.Info, {
type: "channel",
common: {
name: "Adapter information"
},
native: {}
});
await this.setObjectNotExistsAsync(`${commonDefines.AdapterDatapointIDs.Info}.${commonDefines.AdapterStateIDs.Connection}`, {
type: "state",
common: {
name: "Connection to cloud",
type: "boolean",
role: "indicator.connected",
read: true,
write: false,
def: false,
desc: "Indicates if connection to MELCloud was successful or not"
},
native: {}
});
this.setAdapterConnectionState(false);
//#endregion
//#region REPORTS (cumulated for all supported devices)
let reportsPrefix = `${commonDefines.AdapterDatapointIDs.Reports}`;
await this.setObjectNotExistsAsync(reportsPrefix, {
type: "channel",
common: {
name: "Cumulated report for all supported devices"
},
native: {}
});
reportsPrefix += ".";
await this.setObjectNotExistsAsync(reportsPrefix + commonDefines.CommonDeviceStateIDs.PowerConsumptionReportStartDate, {
type: "state",
common: {
name: "Report start date (format: YYYY-MM-DD)",
type: "string",
role: "date",
read: true,
write: true,
desc: "Report data will be collected starting at this date"
},
native: {}
});
await this.setObjectNotExistsAsync(reportsPrefix + commonDefines.CommonDeviceStateIDs.PowerConsumptionReportEndDate, {
type: "state",
common: {
name: "Report end date (format: YYYY-MM-DD)",
type: "string",
role: "date",
read: true,
write: true,
desc: "Report data will be collected until this date"
},
native: {}
});
await this.setObjectNotExistsAsync(reportsPrefix + commonDefines.CommonDeviceStateIDs.GetCumulatedPowerConsumptionReport, {
type: "state",
common: {
name: "Get current power consumption report for all supported devices",
type: "boolean",
role: "button",
read: false,
write: true,
def: false,
desc: "Get current power consumption report for all supported devices"
},
native: {}
});
let lastReportDataPrefix = `${commonDefines.AdapterDatapointIDs.Reports}.${commonDefines.AdapterDatapointIDs.LastReportData}`;
await this.setObjectNotExistsAsync(lastReportDataPrefix, {
type: "channel",
common: {
name: "Last report data for all supported devices"
},
native: {}
});
lastReportDataPrefix += ".";
const reportModes = [commonDefines.AtaDeviceOperationModes.HEAT.id, commonDefines.AtaDeviceOperationModes.COOL.id, commonDefines.AtaDeviceOperationModes.AUTO.id, commonDefines.AtaDeviceOperationModes.VENT.id, commonDefines.AtaDeviceOperationModes.DRY.id, "HotWater"];
reportModes.forEach(mode => {
this.setObjectNotExistsAsync(lastReportDataPrefix + commonDefines.CommonDeviceStateIDs.TotalPowerConsumptionPrefix + mode, {
type: "state",
common: {
name: `Total power consumption for mode '${mode}'`,
type: "number",
role: "value.power.consumption",
min: 0,
read: true,
write: false,
unit: "kWh",
def: 0,
desc: `Total power consumption for mode '${mode}'`
},
native: {}
});
if (mode == commonDefines.AtaDeviceOperationModes.AUTO.id || mode == commonDefines.AtaDeviceOperationModes.DRY.id || mode == commonDefines.AtaDeviceOperationModes.VENT.id) return;
this.setObjectNotExistsAsync(lastReportDataPrefix + commonDefines.CommonDeviceStateIDs.TotalPowerProductionPrefix + mode, {
type: "state",
common: {
name: `Total power production for mode '${mode}'`,
type: "number",
role: "value.power.consumption",
min: 0,
read: true,
write: false,
unit: "kWh",
def: 0,
desc: `Total power production for mode '${mode}'`
},
native: {}
});
});
await this.setObjectNotExistsAsync(lastReportDataPrefix + commonDefines.CommonDeviceStateIDs.TotalPowerConsumptionPrefix, {
type: "state",
common: {
name: "Total power consumption for all modes",
type: "number",
role: "value.power.consumption",
min: 0,
read: true,
write: false,
unit: "kWh",
def: 0,
desc: "Total power consumption for all modes"
},
native: {}
});
await this.setObjectNotExistsAsync(lastReportDataPrefix + commonDefines.CommonDeviceStateIDs.TotalPowerProductionPrefix, {
type: "state",
common: {
name: "Total power production for all modes",
type: "number",
role: "value.power.consumption",
min: 0,
read: true,
write: false,
unit: "kWh",
def: 0,
desc: "Total power production for all modes"
},
native: {}
});
await this.setObjectNotExistsAsync(lastReportDataPrefix + commonDefines.CommonDeviceStateIDs.TotalReportedMinutes, {
type: "state",
common: {
name: "Total power consumption minutes",
type: "number",
role: "value",
min: 0,
read: true,
write: false,
unit: "min",
def: 0,
desc: "Total operation time"
},
native: {}
});
//#endregion
}
/**
* Is called when databases are connected and adapter received configuration.
*/
async onReady() {
this.initObjects()
.then(() => this.checkSettings()
.then(() => this.saveKnownDeviceIDs()
.then(() => {
this.connectToCloud();
this.subscribeStates("devices.*.control.*"); // subscribe to states changes under "devices.X.control."
this.subscribeStates("devices.*.reports.getPowerConsumptionReport"); // subscribe to state "devices.X.reports.getPowerConsumptionReport"
this.subscribeStates("reports.getCumulatedPowerConsumptionReport"); // subscribe to state "reports.getCumulatedPowerConsumptionReport"
})
)
)
.catch(err => this.log.error(err));
}
async connectToCloud() {
gthis.log.info(`Connecting initially to MELCloud and retrieving device data. Polling is ${this.config.enablePolling ? `enabled (interval: ${this.config.pollingInterval} minutes)` : "disabled"}.`);
// Connect to cloud and retrieve/update registered devices initially
CloudPlatform = new cloudPlatform.MelCloudPlatform(gthis);
if (this.config.enablePolling) {
CloudPlatform.GetContextKey(CloudPlatform.CreateAndSaveDevices, CloudPlatform.startPolling);
}
else {
CloudPlatform.GetContextKey(CloudPlatform.CreateAndSaveDevices);
}
}
/**
* Is called when adapter shuts down - callback has to be called under any circumstances!
* @param {() => void} callback
*/
onUnload(callback) {
try {
this.setAdapterConnectionState(false);
this.deviceObjects.length = 0;
if (CloudPlatform != null) {
CloudPlatform.stopPolling();
CloudPlatform.stopContextKeyInvalidation();
}
this.log.debug("onUnload(): Cleaned everything up...");
callback();
// eslint-disable-next-line no-unused-vars
} catch (e) {
callback();
}
}
/**
* Is called if a subscribed state changes
* @param {string} id
* @param {ioBroker.State | null | undefined} state
*/
onStateChange(id, state) {
// The state was changed
if (state) {
// always trigger on "getPowerConsumptionReport" and "getCumulatedPowerConsumptionReport" ignoring if the value has changed or not
if (!id.includes(commonDefines.CommonDeviceStateIDs.GetPowerConsumptionReport) && !id.includes(commonDefines.CommonDeviceStateIDs.GetCumulatedPowerConsumptionReport)
&& stateValueCache[id] != undefined && stateValueCache[id] != null && stateValueCache[id] == state.val) {
this.log.silly(`state ${id} unchanged: ${state.val} (ack = ${state.ack})`);
return;
}
stateValueCache[id] = state.val;
this.log.silly(`state ${id} changed: ${state.val} (ack = ${state.ack})`);
// ack is true when state was updated by MELCloud --> in this case, we don't need to send it again
if (state.ack) {
this.log.silly("Updated data was retrieved from MELCloud. No need to process changed data.");
return;
}
if (this.deviceObjects.length == 0) {
this.log.error("No objects for MELCloud devices constructed yet. Try again in a few seconds...");
return;
}
// "reports.getCumulatedPowerConsumptionReport"
if (id.includes(commonDefines.CommonDeviceStateIDs.GetCumulatedPowerConsumptionReport)) {
this.log.debug(`Processing command '${commonDefines.CommonDeviceStateIDs.GetCumulatedPowerConsumptionReport}' with value '${state.val}' for all devices...`);
this.GetCumulatedReport();
}
// "devices.XXX.control.*" and "devices.XXX.reports.getPowerConsumptionReport"
else {
let deviceId = id.replace(`${this.namespace}.${commonDefines.AdapterDatapointIDs.Devices}.`, "");
deviceId = deviceId.substring(0, deviceId.indexOf("."));
// Get the device object that should be changed
this.log.debug(`Trying to get device object with id ${deviceId}...`);
const device = this.deviceObjects.find(obj => {
return obj.id === parseInt(deviceId);
});
if (device == null) {
let knownIds = "";
this.deviceObjects.forEach(obj => knownIds += `${obj.id}, `);
this.log.error(`Failed to get device object. Known object IDs: ${knownIds}`);
this.log.error("This should not happen - report this to the developer!");
return;
}
const controlOption = id.substring(id.lastIndexOf(".") + 1, id.length);
this.log.debug(`Processing command '${controlOption}' with value '${state.val}' for device object with id ${device.id} (${device.name})...`);
const type = device.deviceType;
switch (type) {
case commonDefines.DeviceTypes.AirToAir: this.processAtaDeviceCommand(controlOption, state, device); break;
case commonDefines.DeviceTypes.AirToWater: this.processAtwDeviceCommand(controlOption, state, device); break;
default: this.log.error(`Unsupported device type: '${type}' - Please report this to the developer!`); break;
}
}
}
// The state was deleted
else {
this.log.silly(`state ${id} deleted`);
if (stateValueCache[id]) {
delete stateValueCache[id];
}
}
}
async GetCumulatedReport() {
const promises = [];
for (const obj of this.deviceObjects) {
promises.push(obj.getPowerConsumptionReport(true));
}
Promise.all(promises).then(() => {
this.UpdateCumulatedReportData(this.deviceObjects);
});
}
async UpdateCumulatedReportData(deviceObjs) {
const cumulatedLastReportDataPrefix = `${commonDefines.AdapterDatapointIDs.Reports}.${commonDefines.AdapterDatapointIDs.LastReportData}.`;
let totalConsumption = 0, totalConsumptionCool = 0, totalConsumptionHeat = 0, totalConsumptionDry = 0, totalConsumptionVent = 0, totalConsumptionAuto = 0, totalConsumptionMinutes = 0;
const aggregatedDeviceGroups = [];
for (const obj of deviceObjs) {
// Check if device is already part of aggregation group to exclude duplicated values
if (obj.linkedDevicesIncludedInArregateEnergyReport && obj.linkedDevicesIncludedInArregateEnergyReport != "") {
if (aggregatedDeviceGroups.length == 0) aggregatedDeviceGroups.push({ groupName: obj.linkedDevicesIncludedInArregateEnergyReport, alreadyProcessed: false });
let isKnownGroup = false;
for (let i = 0; i < aggregatedDeviceGroups.length; i++) {
const aggregatedGroup = aggregatedDeviceGroups[i];
if (aggregatedGroup.groupName.includes(obj.name) && !aggregatedGroup.alreadyProcessed) {
this.log.debug(`Device '${obj.name}' is part of the aggregated group '${aggregatedGroup.groupName}'. Excluding the other devices from this group for cumulated reports.`);
totalConsumptionCool += obj.totalPowerConsumptionCooling;
totalConsumptionHeat += obj.totalPowerConsumptionHeating;
totalConsumptionAuto += obj.totalPowerConsumptionAuto;
totalConsumptionDry += obj.totalPowerConsumptionDry;
totalConsumptionVent += obj.totalPowerConsumptionVent;
totalConsumptionMinutes = obj.totalPowerConsumptionMinutes; // same for all devices
totalConsumption += totalConsumptionCool + totalConsumptionHeat + totalConsumptionAuto + totalConsumptionDry + totalConsumptionVent;
aggregatedGroup.alreadyProcessed = true;
isKnownGroup = true;
break;
}
}
if (!isKnownGroup) aggregatedDeviceGroups.push({ groupName: obj.linkedDevicesIncludedInArregateEnergyReport, alreadyProcessed: false });
}
// Device is not part of any aggregation group, just take thhe values as they are
else {
totalConsumptionCool += obj.totalPowerConsumptionCooling;
totalConsumptionHeat += obj.totalPowerConsumptionHeating;
totalConsumptionAuto += obj.totalPowerConsumptionAuto;
totalConsumptionDry += obj.totalPowerConsumptionDry;
totalConsumptionVent += obj.totalPowerConsumptionVent;
totalConsumptionMinutes += obj.totalPowerConsumptionMinutes;
totalConsumption += totalConsumptionCool + totalConsumptionHeat + totalConsumptionAuto + totalConsumptionDry + totalConsumptionVent;
}
}
await this.setStateChangedAsync(cumulatedLastReportDataPrefix + commonDefines.CommonDeviceStateIDs.TotalPowerConsumptionPrefix + commonDefines.AtaDeviceOperationModes.COOL.id, commonDefines.roundValue(totalConsumptionCool, 3), true);
await this.setStateChangedAsync(cumulatedLastReportDataPrefix + commonDefines.CommonDeviceStateIDs.TotalPowerConsumptionPrefix + commonDefines.AtaDeviceOperationModes.HEAT.id, commonDefines.roundValue(totalConsumptionHeat, 3), true);
await this.setStateChangedAsync(cumulatedLastReportDataPrefix + commonDefines.CommonDeviceStateIDs.TotalPowerConsumptionPrefix + commonDefines.AtaDeviceOperationModes.AUTO.id, commonDefines.roundValue(totalConsumptionAuto, 3), true);
await this.setStateChangedAsync(cumulatedLastReportDataPrefix + commonDefines.CommonDeviceStateIDs.TotalPowerConsumptionPrefix + commonDefines.AtaDeviceOperationModes.DRY.id, commonDefines.roundValue(totalConsumptionDry, 3), true);
await this.setStateChangedAsync(cumulatedLastReportDataPrefix + commonDefines.CommonDeviceStateIDs.TotalPowerConsumptionPrefix + commonDefines.AtaDeviceOperationModes.VENT.id, commonDefines.roundValue(totalConsumptionVent, 3), true);
await this.setStateChangedAsync(cumulatedLastReportDataPrefix + commonDefines.CommonDeviceStateIDs.TotalPowerConsumptionPrefix, commonDefines.roundValue(totalConsumption, 3), true);
await this.setStateChangedAsync(cumulatedLastReportDataPrefix + commonDefines.CommonDeviceStateIDs.TotalReportedMinutes, totalConsumptionMinutes, true);
this.log.debug(`Updated cumulated report data for all devices`);
}
mapAtaDeviceOperationMode(value) {
switch (value) {
case (commonDefines.AtaDeviceOperationModes.HEAT.value):
return commonDefines.AtaDeviceOperationModes.HEAT;
case (commonDefines.AtaDeviceOperationModes.DRY.value):
return commonDefines.AtaDeviceOperationModes.DRY;
case (commonDefines.AtaDeviceOperationModes.COOL.value):
return commonDefines.AtaDeviceOperationModes.COOL;
case (commonDefines.AtaDeviceOperationModes.VENT.value):
return commonDefines.AtaDeviceOperationModes.VENT;
case (commonDefines.AtaDeviceOperationModes.AUTO.value):
return commonDefines.AtaDeviceOperationModes.AUTO;
default:
this.log.error(`Unsupported ATA operation mode: '${value}' - Please report this to the developer!`);
return commonDefines.AtaDeviceOperationModes.UNDEF;
}
}
mapAtwDeviceZoneOperationMode(value) {
switch (value) {
case (commonDefines.AtwDeviceZoneOperationModes.HEATTHERMOSTAT.value):
return commonDefines.AtwDeviceZoneOperationModes.HEATTHERMOSTAT;
case (commonDefines.AtwDeviceZoneOperationModes.HEATFLOW.value):
return commonDefines.AtwDeviceZoneOperationModes.HEATFLOW;
case (commonDefines.AtwDeviceZoneOperationModes.CURVE.value):
return commonDefines.AtwDeviceZoneOperationModes.CURVE;
case (commonDefines.AtwDeviceZoneOperationModes.COOLTHERMOSTAT.value):
return commonDefines.AtwDeviceZoneOperationModes.COOLTHERMOSTAT;
case (commonDefines.AtwDeviceZoneOperationModes.COOLFLOW.value):
return commonDefines.AtwDeviceZoneOperationModes.COOLFLOW;
default:
this.log.error(`Unsupported ATW zone operation mode: '${value}' - Please report this to the developer!`);
return commonDefines.AtwDeviceZoneOperationModes.UNDEF;
}
}
processAtaDeviceCommand(controlOption, state, device) {
switch (controlOption) {
case (commonDefines.AtaDeviceStateIDs.Power):
if (state.val) {
// switch on using current operation mode
device.getDeviceInfo(device.setDevice, commonDefines.AtaDeviceOptions.PowerState, commonDefines.DevicePowerStates.ON);
}
else {
// switch off
device.getDeviceInfo(device.setDevice, commonDefines.AtaDeviceOptions.PowerState, commonDefines.DevicePowerStates.OFF);
}
break;
case (commonDefines.AtaDeviceStateIDs.Mode):
device.getDeviceInfo(device.setDevice, commonDefines.AtaDeviceOptions.TargetHeatingCoolingState, this.mapAtaDeviceOperationMode(state.val));
break;
case (commonDefines.AtaDeviceStateIDs.TargetTemp):
device.getDeviceInfo(device.setDevice, commonDefines.AtaDeviceOptions.TargetTemperature, state.val);
break;
case (commonDefines.AtaDeviceStateIDs.FanSpeedManual):
device.getDeviceInfo(device.setDevice, commonDefines.AtaDeviceOptions.FanSpeed, state.val);
break;
case (commonDefines.AtaDeviceStateIDs.VaneVerticalDirection):
device.getDeviceInfo(device.setDevice, commonDefines.AtaDeviceOptions.VaneVerticalDirection, state.val);
break;
case (commonDefines.AtaDeviceStateIDs.VaneHorizontalDirection):
device.getDeviceInfo(device.setDevice, commonDefines.AtaDeviceOptions.VaneHorizontalDirection, state.val);
break;
case (commonDefines.AtaDeviceStateIDs.TimerToogle):
device.toggleTimerState(state.val);
break;
case (commonDefines.CommonDeviceStateIDs.GetPowerConsumptionReport):
device.getPowerConsumptionReport();
break;
default:
this.log.error(`Unsupported ATA control option: ${controlOption} - Please report this to the developer!`);
break;
}
}
processAtwDeviceCommand(controlOption, state, device) {
switch (controlOption) {
case (commonDefines.AtwDeviceStateIDs.Power):
if (state.val) {
// switch on using current operation mode
device.getDeviceInfo(device.setDevice, commonDefines.AtwDeviceOptions.PowerState, commonDefines.DevicePowerStates.ON);
}
else {
// switch off
device.getDeviceInfo(device.setDevice, commonDefines.AtwDeviceOptions.PowerState, commonDefines.DevicePowerStates.OFF);
}
break;
case (commonDefines.AtwDeviceStateIDs.ForcedHotWaterMode):
device.getDeviceInfo(device.setDevice, commonDefines.AtwDeviceOptions.ForcedHotWaterMode, state.val);
break;
case (commonDefines.AtwDeviceStateIDs.OperationModeZone1):
device.getDeviceInfo(device.setDevice, commonDefines.AtwDeviceOptions.OperationModeZone1, this.mapAtwDeviceZoneOperationMode(state.val));
break;
case (commonDefines.AtwDeviceStateIDs.OperationModeZone2):
device.getDeviceInfo(device.setDevice, commonDefines.AtwDeviceOptions.OperationModeZone2, this.mapAtwDeviceZoneOperationMode(state.val));
break;
case (commonDefines.AtwDeviceStateIDs.SetTankWaterTemperature):
device.getDeviceInfo(device.setDevice, commonDefines.AtwDeviceOptions.SetTankWaterTemperature, state.val);
break;
case (commonDefines.AtwDeviceStateIDs.SetTemperatureZone1):
device.getDeviceInfo(device.setDevice, commonDefines.AtwDeviceOptions.SetTemperatureZone1, state.val);
break;
case (commonDefines.AtwDeviceStateIDs.SetTemperatureZone2):
device.getDeviceInfo(device.setDevice, commonDefines.AtwDeviceOptions.SetTemperatureZone2, state.val);
break;
case (commonDefines.AtwDeviceStateIDs.SetHeatFlowTemperatureZone1):
device.getDeviceInfo(device.setDevice, commonDefines.AtwDeviceOptions.SetHeatFlowTemperatureZone1, state.val);
break;
case (commonDefines.AtwDeviceStateIDs.SetHeatFlowTemperatureZone2):
device.getDeviceInfo(device.setDevice, commonDefines.AtwDeviceOptions.SetHeatFlowTemperatureZone2, state.val);
break;
case (commonDefines.AtwDeviceStateIDs.SetCoolFlowTemperatureZone1):
device.getDeviceInfo(device.setDevice, commonDefines.AtwDeviceOptions.SetCoolFlowTemperatureZone1, state.val);
break;
case (commonDefines.AtwDeviceStateIDs.SetCoolFlowTemperatureZone2):
device.getDeviceInfo(device.setDevice, commonDefines.AtwDeviceOptions.SetCoolFlowTemperatureZone2, state.val);
break;
case (commonDefines.AtwDeviceStateIDs.TimerToogle):
device.toggleTimerState(state.val);
break;
case (commonDefines.CommonDeviceStateIDs.GetPowerConsumptionReport):
device.getPowerConsumptionReport();
break;
default:
this.log.error(`Unsupported ATW control option: ${controlOption} - Please report this to the developer!`);
break;
}
}
}
// @ts-ignore parent is a valid property on module
if (module.parent) {
// Export the constructor in compact mode
/**
* @param {Partial<ioBroker.AdapterOptions>} [options={}]
*/
module.exports = (options) => new Melcloud(options);
} else {
// otherwise start the instance directly
new Melcloud();
}