iobroker.lovelace
Version:
With this adapter you can build visualization for ioBroker with Home Assistant Lovelace UI
459 lines (458 loc) • 19 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var climateEntity_exports = {};
__export(climateEntity_exports, {
ClimateEntity: () => ClimateEntity,
applyClimateStates: () => applyClimateStates,
supportedFlags: () => supportedFlags
});
module.exports = __toCommonJS(climateEntity_exports);
var import_type_detector = require("@iobroker/type-detector");
var import_baseEntity = require("./baseEntity");
var import_sensorEntity = require("./sensorEntity");
const adapterData = require("../../../lib/dataSingleton");
const CLIMATE_SUPPORT_TARGET_TEMPERATURE = 1;
const CLIMATE_SUPPORT_FAN_MODE = 8;
const CLIMATE_SUPPORT_PRESET_MODE = 16;
const CLIMATE_SUPPORT_SWING_MODE = 32;
const supportedFlags = {
CLIMATE_SUPPORT_TARGET_TEMPERATURE,
CLIMATE_SUPPORT_FAN_MODE,
CLIMATE_SUPPORT_PRESET_MODE,
CLIMATE_SUPPORT_SWING_MODE
};
function translateModeNameForLovelace(modeNameIn) {
const lower = modeNameIn.toLowerCase();
switch (lower) {
case "dehumid":
return "dry";
case "fan":
return "fan_only";
case "cold":
return "cool";
case "hot":
return "heat";
default:
return lower;
}
}
function applyClimateStates(states, objects, entity, iobType) {
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
entity.fillFromStates(states, objects);
entity.attributes.supported_features = CLIMATE_SUPPORT_TARGET_TEMPERATURE;
entity.context.COMMANDS = [];
if (states.state || states.hvac_mode) {
entity.context.COMMANDS.push({
service: "set_hvac_mode",
setId: (_a = states.hvac_mode) != null ? _a : states.state,
parseCommand: async (ent, _command, data, user) => {
var _a2;
const hvac_attr = ent.context.ATTRIBUTES.find((a) => a.attribute === "hvac_mode");
const value = data.service_data.hvac_mode;
if (ent.context.STATE.setId) {
await adapterData.adapter.setForeignStateAsync(ent.context.STATE.setId, value !== "off", false, {
user
});
}
if (hvac_attr) {
const target = (_a2 = hvac_attr.lovelaceToIob) == null ? void 0 : _a2[value];
if (target !== void 0) {
await adapterData.adapter.setForeignStateAsync(hvac_attr.setId, target, false, { user });
}
}
ent.attributes.hvac_action = void 0;
return void 0;
}
});
}
if (states.state || states.stateRead) {
if (!entity.attributes.hvac_modes) {
entity.attributes.hvac_modes = [];
}
entity.attributes.hvac_modes.push("off");
if (!states.hvac_mode) {
entity.attributes.hvac_modes.push(iobType === import_type_detector.Types.airCondition ? "cool" : "heat");
}
entity.context.STATE.getParser = (ent, _attrName, state) => {
var _a2, _b2;
const s = state != null ? state : { val: null };
ent.context.iobPower = s.val;
const target = s.val ? iobType === import_type_detector.Types.airCondition ? "cool" : "heat" : "off";
const hvac_attr = ent.context.ATTRIBUTES.find((a) => a.attribute === "hvac_mode");
if (hvac_attr) {
if (!s.val) {
ent.attributes.hvac_mode = "off";
} else if (ent.context.iobMode !== void 0) {
const mode = ent.context.iobMode;
ent.attributes.hvac_mode = (_b2 = (_a2 = hvac_attr.iobToLovelace) == null ? void 0 : _a2[mode]) != null ? _b2 : String(mode);
} else {
adapterData.log.warn(
`No mode for ${ent.entity_id} received, yet. Asking database. Will delay update.`
);
adapterData.adapter.getForeignStateAsync(hvac_attr.getId).then((stateVal) => {
var _a3, _b3;
const val = stateVal ? stateVal.val : null;
if (ent.context.iobMode === void 0) {
ent.context.iobMode = val;
const resolved = (_b3 = (_a3 = hvac_attr.iobToLovelace) == null ? void 0 : _a3[val]) != null ? _b3 : iobType === import_type_detector.Types.airCondition ? "cool" : "heat";
ent.state = resolved;
ent.attributes.hvac_mode = resolved;
}
}).catch((e) => {
adapterData.log.error(
`Error fetching HVAC mode for ${ent.entity_id} during power state update: ${e}`
);
});
}
} else {
ent.attributes.hvac_mode = target;
}
ent.state = ent.attributes.hvac_mode;
ent.attributes.hvac_action = void 0;
};
entity.context.STATE.historyParser = (_id, val) => val ? iobType === import_type_detector.Types.airCondition ? "cool" : "heat" : "off";
}
if (states.hvac_mode) {
const hvac_attr = entity.context.ATTRIBUTES.find((a) => a.attribute === "hvac_mode");
if (hvac_attr) {
hvac_attr.setId = states.hvac_mode;
const obj = objects[hvac_attr.getId];
if ((_b = obj == null ? void 0 : obj.common) == null ? void 0 : _b.states) {
entity.attributes.hvac_modes = (_c = entity.attributes.hvac_modes) != null ? _c : [];
const rawStates = obj.common.states;
hvac_attr.iobToLovelace = { ...rawStates };
hvac_attr.lovelaceToIob = {};
for (const key of Object.keys(rawStates)) {
const mode = rawStates[key];
const modeName = translateModeNameForLovelace(mode);
entity.attributes.hvac_modes.push(modeName);
hvac_attr.lovelaceToIob[modeName] = parseInt(key, 10);
hvac_attr.iobToLovelace[key] = modeName;
}
} else {
hvac_attr.lovelaceToIob = { auto: 1, heat_cool: 2, heat: 3, cool: 4, dry: 5, fan_only: 6, off: 7 };
hvac_attr.iobToLovelace = {
1: "auto",
2: "heat_cool",
3: "heat",
4: "cool",
5: "dry",
6: "fan_only",
7: "off"
};
entity.attributes.hvac_modes = ["auto", "heat_cool", "heat", "cool", "dry", "fan_only", "off"];
}
if ((states.state || states.stateRead) && !entity.attributes.hvac_modes.includes("off")) {
entity.attributes.hvac_modes.push("off");
}
hvac_attr.getParser = (ent, attr, state) => {
var _a2, _b2;
const s = state != null ? state : { val: null };
ent.context.iobMode = s.val;
ent.attributes.hvac_mode = (_b2 = (_a2 = attr.iobToLovelace) == null ? void 0 : _a2[s.val]) != null ? _b2 : String(s.val);
if (!ent.context.iobPower && (states.state || states.stateRead) && ent.state === "off") {
ent.attributes.hvac_mode = ent.state;
} else {
ent.state = ent.attributes.hvac_mode;
}
ent.attributes.hvac_action = void 0;
};
hvac_attr.historyParser = (_id, val) => {
var _a2, _b2;
return (_b2 = (_a2 = hvac_attr.iobToLovelace) == null ? void 0 : _a2[val]) != null ? _b2 : String(val);
};
}
}
if (states.preset_mode) {
entity.attributes.supported_features = entity.attributes.supported_features | CLIMATE_SUPPORT_PRESET_MODE;
entity.attributes.preset_mode = "none";
entity.attributes.preset_modes = ["none"];
const boost_attr = entity.context.ATTRIBUTES.find((a) => a.attribute === "boost");
if (boost_attr) {
entity.attributes.preset_modes.push("boost");
boost_attr.getParser = (ent, _attr, state) => {
const val = state ? state.val : null;
ent.attributes.boost = val ? "on" : "off";
ent.attributes.preset_mode = val ? "boost" : ent.attributes.party === "on" ? "party" : "none";
};
boost_attr.historyParser = (_id, val) => val ? "boost" : "none";
}
const party_attr = entity.context.ATTRIBUTES.find((a) => a.attribute === "party");
if (party_attr) {
entity.attributes.preset_modes.push("party");
party_attr.getParser = (ent, _attr, state) => {
const val = state ? state.val : null;
ent.attributes.party = val ? "on" : "off";
ent.attributes.preset_mode = val ? "party" : ent.attributes.boost === "on" ? "boost" : "none";
};
party_attr.historyParser = (_id, val) => val ? "party" : "none";
}
const preset_attr = entity.context.ATTRIBUTES.find((a) => a.attribute === "preset_mode");
if (preset_attr) {
delete preset_attr.getId;
}
entity.context.COMMANDS.push({
service: "set_preset_mode",
parseCommand: async (_ent, _command, data, user) => {
const preset = data.service_data.preset_mode;
const boostVal = preset === "boost";
const partyVal = preset === "party";
const promises = [];
if (party_attr == null ? void 0 : party_attr.getId) {
promises.push(
adapterData.adapter.setForeignStateAsync(party_attr.getId, partyVal, false, { user })
);
}
if (boost_attr == null ? void 0 : boost_attr.getId) {
promises.push(
adapterData.adapter.setForeignStateAsync(boost_attr.getId, boostVal, false, { user })
);
}
return Promise.all(promises);
}
});
}
if (states.swing_mode) {
entity.attributes.supported_features = entity.attributes.supported_features | CLIMATE_SUPPORT_SWING_MODE;
const swing_attr = entity.context.ATTRIBUTES.find((a) => a.attribute === "swing_mode");
if (swing_attr) {
const swing_obj = objects[swing_attr.getId];
const swingCommon = (_d = swing_obj == null ? void 0 : swing_obj.common) != null ? _d : {};
if (swingCommon.type === "boolean") {
swing_attr.isBoolean = true;
swing_attr.states = { false: "off", true: "on" };
entity.attributes.swing_modes = ["off", "on"];
} else if ((_e = swing_obj == null ? void 0 : swing_obj.common) == null ? void 0 : _e.states) {
swing_attr.states = swing_obj.common.states;
entity.attributes.swing_modes = Object.values(swing_attr.states);
} else {
swing_attr.states = {};
entity.attributes.swing_modes = [0, 1, 2, 3, 4, 5, 6, 7];
}
swing_attr.getParser = (ent, attr, state) => {
const val = state ? state.val : null;
ent.attributes.swing_mode = attr.states && attr.states[val] !== void 0 ? attr.states[val] : val;
};
swing_attr.historyParser = (_id, val) => String(
swing_attr.states && swing_attr.states[val] !== void 0 ? swing_attr.states[val] : val
);
entity.context.COMMANDS.push({
service: "set_swing_mode",
parseCommand: async (ent, _command, data, user) => {
const mode = data.service_data.swing_mode;
const swingAttr = ent.context.ATTRIBUTES.find((a) => a.attribute === "swing_mode");
let val;
if (swingAttr && swingAttr.getId) {
if (swingAttr == null ? void 0 : swingAttr.isBoolean) {
val = mode === "on";
} else {
val = parseInt(mode, 10);
if (swingAttr.states) {
for (const key of Object.keys(swingAttr.states)) {
if (swingAttr.states[key] === mode) {
val = parseInt(key, 10);
}
}
}
}
return adapterData.adapter.setForeignStateAsync(swingAttr.getId, val, false, { user });
}
}
});
}
}
if (states.fan_mode) {
entity.attributes.supported_features = entity.attributes.supported_features | CLIMATE_SUPPORT_FAN_MODE;
const fan_attr = entity.context.ATTRIBUTES.find((a) => a.attribute === "fan_mode");
if (fan_attr) {
const fan_obj = objects[fan_attr.getId];
if ((_f = fan_obj == null ? void 0 : fan_obj.common) == null ? void 0 : _f.states) {
fan_attr.states = fan_obj.common.states;
entity.attributes.fan_modes = Object.values(fan_attr.states);
} else {
fan_attr.states = {};
entity.attributes.fan_modes = [0, 1, 2, 3, 4, 5, 6, 7];
}
fan_attr.getParser = (ent, attr, state) => {
const val = state ? state.val : null;
ent.attributes.fan_mode = attr.states && attr.states[val] !== void 0 ? attr.states[val] : val;
};
fan_attr.historyParser = (_id, val) => String(
fan_attr.states && fan_attr.states[val] !== void 0 ? fan_attr.states[val] : val
);
entity.context.COMMANDS.push({
service: "set_fan_mode",
parseCommand: async (ent, _command, data, user) => {
const mode = data.service_data.fan_mode;
const fanAttr = ent.context.ATTRIBUTES.find((a) => a.attribute === "fan_mode");
let val = parseInt(mode, 10);
if (fanAttr && fanAttr.getId) {
if (fanAttr.states) {
for (const key of Object.keys(fanAttr.states)) {
if (fanAttr.states[key] === mode) {
val = parseInt(key, 10);
}
}
}
return adapterData.adapter.setForeignStateAsync(fanAttr.getId, val, false, { user });
}
}
});
}
}
if (states.hvac_action) {
const actionObj = objects[states.hvac_action];
const actionAttr = entity.context.ATTRIBUTES.find((a) => a.attribute === "hvac_action");
if (actionAttr) {
const actionCommon = (_g = actionObj == null ? void 0 : actionObj.common) != null ? _g : {};
const type = (_h = actionCommon.type) != null ? _h : "string";
if (type === "number" && actionCommon.states) {
actionAttr.states = actionCommon.states;
}
actionAttr.getParser = (ent, attr, state) => {
const val = state ? state.val : null;
if (type === "number" && attr.states) {
ent.attributes.hvac_action = attr.historyParser ? attr.historyParser(attr.getId, val) : String(val);
} else if (type === "string") {
ent.attributes.hvac_action = translateModeNameForLovelace(String(val));
} else {
ent.attributes.hvac_action = val ? iobType === import_type_detector.Types.thermostat ? "heating" : "cooling" : "idle";
}
};
actionAttr.historyParser = (_id, val) => translateModeNameForLovelace(
String(
actionAttr.states && actionAttr.states[val] !== void 0 ? actionAttr.states[val] : val
)
);
}
}
if (!entity.attributes.hvac_modes) {
entity.attributes.hvac_modes = [iobType === import_type_detector.Types.airCondition ? "cool" : "heat"];
}
entity.attributes.min_temp = 7;
entity.attributes.max_temp = 35;
entity.attributes.target_temp_step = 1;
entity.attributes.min_humidity = 30;
entity.attributes.max_humidity = 99;
if (states.temperature) {
entity.context.COMMANDS.push({
service: "set_temperature",
setId: states.temperature,
parseCommand: async (_ent, command, data, user) => {
const sd = data.service_data;
if (sd.temperature === void 0) {
adapterData.log.warn(
`No temperature in service call for ${_ent.entity_id}. Range not yet supported.`
);
}
return adapterData.adapter.setForeignStateAsync(
command.setId,
sd.temperature,
false,
{ user }
);
}
});
const tempCommon = (_j = (_i = objects[states.temperature]) == null ? void 0 : _i.common) != null ? _j : {};
entity.attributes.min_temp = (_k = tempCommon.min) != null ? _k : 7;
entity.attributes.max_temp = (_l = tempCommon.max) != null ? _l : 35;
entity.attributes.target_temp_step = (_m = tempCommon.step) != null ? _m : 1;
}
}
class ClimateEntity extends import_baseEntity.BaseEntity {
/**
* Build a climate entity (and optional companion temperature/humidity sensors).
*
* @param params - converter parameters
* @returns array starting with the climate entity, followed by 0..2 companion sensors.
*/
static build(params) {
var _a;
const { friendlyName, room, func, objects, id, forcedEntityId, controls } = params;
const entity = new ClimateEntity(friendlyName, room, func, objects[id], forcedEntityId);
const states = {};
let entityTemp;
let entityHum;
const baseName = entity.entity_id.split(".")[1];
const tempId = `sensor.${baseName}_Temperature`;
const humId = `sensor.${baseName}_Humidity`;
for (const state of controls.states) {
if (state == null ? void 0 : state.id) {
switch (state.name) {
case "SET":
states.temperature = state.id;
break;
case "MODE":
states.hvac_mode = state.id;
break;
case "POWER":
states.state = state.id;
break;
case "HUMIDITY":
states.current_humidity = state.id;
entityHum = import_sensorEntity.SensorEntity.humidity(state.id, friendlyName, room, func, objects[id], humId);
break;
case "ACTUAL":
states.current_temperature = state.id;
entityTemp = import_sensorEntity.SensorEntity.temperature(state.id, friendlyName, room, func, objects[id], tempId);
break;
case "BOOST":
states.preset_mode = state.id;
states.boost = state.id;
break;
case "PARTY":
states.preset_mode = state.id;
states.party = state.id;
break;
case "SPEED":
states.fan_mode = state.id;
break;
case "SWING":
states.swing_mode = state.id;
break;
default:
if (!["WORKING", "UNREACH", "LOWBAT", "MAINTAIN", "ERROR"].includes((_a = state.name) != null ? _a : "")) {
adapterData.log.info(
`Unknown state ${state.name} while creating climate entity for ${id}. Please report.`
);
}
}
}
}
applyClimateStates(states, objects, entity, controls.type);
const result = [entity];
if (entityHum) {
result.push(entityHum);
}
if (entityTemp) {
result.push(entityTemp);
}
return result;
}
constructor(name, room, func, obj, forcedEntityId) {
super(name, room, func, obj, "climate", forcedEntityId);
}
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
ClimateEntity,
applyClimateStates,
supportedFlags
});
//# sourceMappingURL=climateEntity.js.map