UNPKG

zigbee-herdsman-converters

Version:

Collection of device converters to be used with zigbee-herdsman

397 lines • 16.9 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.definitions = void 0; const zigbee_herdsman_1 = require("zigbee-herdsman"); const constants = __importStar(require("../lib/constants")); const exposes = __importStar(require("../lib/exposes")); const logger_1 = require("../lib/logger"); const m = __importStar(require("../lib/modernExtend")); const reporting = __importStar(require("../lib/reporting")); const utils = __importStar(require("../lib/utils")); const NS = "zhc:amina"; const e = exposes.presets; const ea = exposes.access; const manufacturerOptions = { manufacturerCode: 0x143b }; const aminaControlAttributes = { cluster: 0xfee7, alarms: 0x02, ev_status: 0x03, connect_status: 0x04, single_phase: 0x05, offline_current: 0x06, offline_single_phase: 0x07, time_to_offline: 0x08, enable_offline: 0x09, total_active_energy: 0x10, last_session_energy: 0x11, }; const aminaAlarms = [ "welded_relay", "wrong_voltage_balance", "rdc_dd_dc_leakage", "rdc_dd_ac_leakage", "high_temperature", "overvoltage", "undervoltage", "overcurrent", "car_communication_error", "charger_processing_error", "critical_overcurrent", "critical_powerloss", "unknown_alarm_bit_12", "unknown_alarm_bit_13", "unknown_alarm_bit_14", "unknown_alarm_bit_15", ]; const fzLocal = { poll_energy: { cluster: "haElectricalMeasurement", type: ["attributeReport"], convert: (model, msg, publish, options, meta) => { if (msg.data.totalActivePower != null) { // Device does not support reporting of energy attributes, so we poll them manually when power is updated msg.endpoint.read("aminaControlCluster", ["totalActiveEnergy"]).catch((error) => { logger_1.logger.error(`Failed to poll energy of '${msg.device.ieeeAddr}' (${error})`, NS); }); } }, }, ev_status: { cluster: "aminaControlCluster", type: ["attributeReport", "readResponse"], convert: (model, msg, publish, options, meta) => { const result = {}; if (msg.type === "attributeReport") { // Device does not support reporting of energy attributes, so we poll them manually when charging is stopped if ((msg.data.evStatus & (1 << 2)) === 0) { msg.endpoint .read("aminaControlCluster", ["totalActiveEnergy", "lastSessionEnergy"]) .catch((error) => { logger_1.logger.error(`Failed to poll energy of '${msg.device.ieeeAddr}' (${error})`, NS); }); } } if (msg.data.evStatus !== undefined) { let statusText = "Not Connected"; const evStatus = msg.data.evStatus; result.ev_connected = (evStatus & (1 << 0)) !== 0; result.charging = (evStatus & (1 << 2)) !== 0; result.derated = (evStatus & (1 << 15)) !== 0; if (result.ev_connected === true) statusText = "EV Connected"; if ((evStatus & (1 << 1)) !== 0) statusText = "Ready to charge"; if (result.charging === true) statusText = "Charging"; if ((evStatus & (1 << 3)) !== 0) statusText = "Charging Paused"; if (result.derated === true) statusText += ", Derated"; result.ev_status = statusText; return result; } }, }, alarms: { cluster: "aminaControlCluster", type: ["attributeReport", "readResponse"], convert: (model, msg, publish, options, meta) => { const result = {}; if (msg.data.alarms !== undefined) { result.alarm_active = false; if (msg.data.alarms !== 0) { result.alarms = aminaAlarms.filter((_, i) => (msg.data.alarms & (1 << i)) !== 0); result.alarm_active = true; } return result; } }, }, }; const tzLocal = { charge_limit: { key: ["charge_limit"], convertSet: async (entity, key, value, meta) => { await entity.command("genLevelCtrl", "moveToLevel", { level: value, transtime: 0, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity)); }, convertGet: async (entity, key, meta) => { await entity.read("genLevelCtrl", ["currentLevel"]); }, }, ev_status: { key: ["ev_status"], convertGet: async (entity, key, meta) => { await entity.read("aminaControlCluster", ["evStatus"], manufacturerOptions); }, }, alarms: { key: ["alarms"], convertGet: async (entity, key, meta) => { await entity.read("aminaControlCluster", ["alarms"], manufacturerOptions); }, }, charge_limit_with_on_off: { key: ["charge_limit_with_on_off"], convertSet: async (entity, key, value, meta) => { const level = value; await entity.command("genLevelCtrl", "moveToLevelWithOnOff", { level, transtime: 0, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity)); }, convertGet: async (entity, key, meta) => { await entity.read("genLevelCtrl", ["currentLevel"]); }, }, }; exports.definitions = [ { zigbeeModel: ["amina S"], model: "amina S", vendor: "Amina Distribution AS", description: "Amina S EV Charger", ota: true, fromZigbee: [fzLocal.ev_status, fzLocal.alarms, fzLocal.poll_energy], toZigbee: [tzLocal.ev_status, tzLocal.alarms, tzLocal.charge_limit, tzLocal.charge_limit_with_on_off], exposes: [ e.text("ev_status", ea.STATE_GET).withDescription("Current charging status"), e.list("alarms", ea.STATE_GET, e.enum("alarm", ea.STATE_GET, aminaAlarms)).withDescription("List of active alarms"), e.binary("ev_connected", ea.STATE, true, false).withDescription("An EV is connected to the charger"), e.binary("charging", ea.STATE, true, false).withDescription("Power is being delivered to the EV"), e.binary("derated", ea.STATE, true, false).withDescription("Charging derated due to high temperature"), e.binary("alarm_active", ea.STATE, true, false).withDescription("An active alarm is present"), e .numeric("charge_limit_with_on_off", ea.ALL) .withDescription("Sets the maximum charge amperage and turns charging on/off.") .withUnit("A") .withValueMin(0) .withValueMax(32), ], extend: [ m.deviceAddCustomCluster("aminaControlCluster", { name: "aminaControlCluster", ID: aminaControlAttributes.cluster, manufacturerCode: manufacturerOptions.manufacturerCode, attributes: { alarms: { name: "alarms", ID: aminaControlAttributes.alarms, type: zigbee_herdsman_1.Zcl.DataType.BITMAP16, write: true }, evStatus: { name: "evStatus", ID: aminaControlAttributes.ev_status, type: zigbee_herdsman_1.Zcl.DataType.BITMAP16, write: true }, connectStatus: { name: "connectStatus", ID: aminaControlAttributes.connect_status, type: zigbee_herdsman_1.Zcl.DataType.BITMAP16, write: true }, singlePhase: { name: "singlePhase", ID: aminaControlAttributes.single_phase, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff }, offlineCurrent: { name: "offlineCurrent", ID: aminaControlAttributes.offline_current, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff, }, offlineSinglePhase: { name: "offlineSinglePhase", ID: aminaControlAttributes.offline_single_phase, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff, }, timeToOffline: { name: "timeToOffline", ID: aminaControlAttributes.time_to_offline, type: zigbee_herdsman_1.Zcl.DataType.UINT16, write: true, max: 0xffff, }, enableOffline: { name: "enableOffline", ID: aminaControlAttributes.enable_offline, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff, }, totalActiveEnergy: { name: "totalActiveEnergy", ID: aminaControlAttributes.total_active_energy, type: zigbee_herdsman_1.Zcl.DataType.UINT32, write: true, max: 0xffffffff, }, lastSessionEnergy: { name: "lastSessionEnergy", ID: aminaControlAttributes.last_session_energy, type: zigbee_herdsman_1.Zcl.DataType.UINT32, write: true, max: 0xffffffff, }, }, commands: {}, commandsResponse: {}, }), m.onOff({ powerOnBehavior: false, }), m.numeric({ name: "charge_limit", cluster: "genLevelCtrl", attribute: "currentLevel", description: "Maximum allowed amperage draw", reporting: { min: 0, max: "MAX", change: 1 }, unit: "A", valueMin: 6, valueMax: 32, valueStep: 1, access: "ALL", }), m.numeric({ name: "total_active_power", cluster: "haElectricalMeasurement", attribute: "totalActivePower", description: "Instantaneous measured total active power", reporting: { min: "10_SECONDS", max: "MAX", change: 10 }, unit: "kW", scale: 1000, precision: 2, access: "STATE_GET", }), m.numeric({ name: "total_active_energy", cluster: "aminaControlCluster", attribute: "totalActiveEnergy", description: "Sum of consumed energy", //reporting: {min: '10_SECONDS', max: 'MAX', change: 5}, // Not Reportable atm, updated using onEvent unit: "kWh", scale: 1000, precision: 2, access: "STATE_GET", }), m.numeric({ name: "last_session_energy", cluster: "aminaControlCluster", attribute: "lastSessionEnergy", description: "Sum of consumed energy last session", //reporting: {min: '10_SECONDS', max: 'MAX', change: 5}, // Not Reportable atm, updated using onEvent unit: "kWh", scale: 1000, precision: 2, access: "STATE_GET", }), m.electricityMeter({ cluster: "electrical", acFrequency: true, threePhase: true, }), m.binary({ name: "single_phase", cluster: "aminaControlCluster", attribute: "singlePhase", description: "Enable single phase charging. A restart of charging is required for the change to take effect.", valueOn: ["enable", 1], valueOff: ["disable", 0], entityCategory: "config", }), m.binary({ name: "enable_offline", cluster: "aminaControlCluster", attribute: "enableOffline", description: "Enable offline mode when connection to the network is lost", valueOn: ["enable", 1], valueOff: ["disable", 0], entityCategory: "config", }), m.numeric({ name: "time_to_offline", cluster: "aminaControlCluster", attribute: "timeToOffline", description: "Time until charger will behave as offline after connection has been lost", valueMin: 0, valueMax: 60, valueStep: 1, unit: "s", entityCategory: "config", }), m.numeric({ name: "offline_current", cluster: "aminaControlCluster", attribute: "offlineCurrent", description: "Maximum allowed amperage draw when device is offline", valueMin: 6, valueMax: 32, valueStep: 1, unit: "A", entityCategory: "config", }), m.binary({ name: "offline_single_phase", cluster: "aminaControlCluster", attribute: "offlineSinglePhase", description: "Use single phase charging when device is offline", valueOn: ["enable", 1], valueOff: ["disable", 0], entityCategory: "config", }), ], endpoint: (device) => { return { default: 10 }; }, configure: async (device, coordinatorEndpoint) => { const endpoint = device.getEndpoint(10); const binds = ["genBasic", "genLevelCtrl", "aminaControlCluster"]; await reporting.bind(endpoint, coordinatorEndpoint, binds); await endpoint.configureReporting("aminaControlCluster", [ { attribute: "evStatus", minimumReportInterval: 0, maximumReportInterval: constants.repInterval.MAX, reportableChange: 1, }, ]); await endpoint.configureReporting("aminaControlCluster", [ { attribute: "alarms", minimumReportInterval: 0, maximumReportInterval: constants.repInterval.MAX, reportableChange: 1, }, ]); await endpoint.read("aminaControlCluster", [ "alarms", "evStatus", "connectStatus", "singlePhase", "offlineCurrent", "offlineSinglePhase", "timeToOffline", "enableOffline", "totalActiveEnergy", "lastSessionEnergy", ]); }, }, ]; //# sourceMappingURL=amina.js.map