diff --git a/README.md b/README.md index 9f39300..fd30c65 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,8 @@ Sentry reporting is used starting with js-controller 3.0. Read data from Huawei SUN2000 inverter and LUNA2000 Storage using Modbus TCP. +Huawei products page: [solar.huawei.com](https://solar.huawei.com/at/professionals/all-products) + ## Settings * `address`: Inverters IP address @@ -33,6 +35,7 @@ Read data from Huawei SUN2000 inverter and LUNA2000 Storage using Modbus TCP. ### **WORK IN PROGRESS** * Added storage CurrentDayChargeCapacity and CurrentDayDischargeCapacity +* Changes from [Add sun2000-modbus to latest](https://github.com/ioBroker/ioBroker.repositories/pull/3038) ### 0.0.1 (2023-11-26) diff --git a/build/lib/states.js b/build/lib/states.js index efa00a5..a307a7a 100644 --- a/build/lib/states.js +++ b/build/lib/states.js @@ -34,64 +34,64 @@ class InverterStates { this.updateIntervals = updateIntervals; this.dataFields = [ { - state: { id: "info.model", name: "Model", type: "string", role: "state" }, + state: { id: "info.model", name: "Model", type: "string", role: "info.name" }, register: { reg: 3e4, type: import_modbus_types.ModbusDatatype.string, length: 15 } }, { - state: { id: "info.modelID", name: "Model ID", type: "number", role: "state" }, + state: { id: "info.modelID", name: "Model ID", type: "number", role: "info.hardware" }, register: { reg: 30070, type: import_modbus_types.ModbusDatatype.uint16, length: 1 } }, { - state: { id: "info.serialNumber", name: "Serial number", type: "string", role: "state" }, + state: { id: "info.serialNumber", name: "Serial number", type: "string", role: "info.serial" }, register: { reg: 30015, type: import_modbus_types.ModbusDatatype.string, length: 10 } }, { - state: { id: "info.ratedPower", name: "Rated power", type: "number", unit: "W", role: "state" }, + state: { id: "info.ratedPower", name: "Rated power", type: "number", unit: "W", role: "value.power" }, register: { reg: 30073, type: import_modbus_types.ModbusDatatype.int32, length: 2 } }, { - state: { id: "info.numberMPPTrackers", name: "Number of MPP trackers", type: "number", unit: "", role: "state" }, + state: { id: "info.numberMPPTrackers", name: "Number of MPP trackers", type: "number", unit: "", role: "value" }, register: { reg: 30072, type: import_modbus_types.ModbusDatatype.uint16, length: 1, gain: 1 } }, { interval: 0 /* HIGH */, - state: { id: "activePower", name: "Active power", type: "number", unit: "W", role: "value.power", desc: "Power currently used" }, + state: { id: "activePower", name: "Active power", type: "number", unit: "W", role: "value.power.active", desc: "Power currently used" }, register: { reg: 32080, type: import_modbus_types.ModbusDatatype.int32, length: 2 } }, { interval: 0 /* HIGH */, - state: { id: "inputPower", name: "Input power", type: "number", unit: "W", role: "value.power", desc: "Power from PV" }, + state: { id: "inputPower", name: "Input power", type: "number", unit: "W", role: "value.power.produced", desc: "Power from PV" }, register: { reg: 32064, type: import_modbus_types.ModbusDatatype.int32, length: 2 } }, { interval: 1 /* LOW */, - state: { id: "peakActivePowerCurrenDay", name: "Peak active power of current day", type: "number", unit: "W", role: "value.power.max" }, + state: { id: "peakActivePowerCurrenDay", name: "Peak active power of current day", type: "number", unit: "W", role: "value.power" }, register: { reg: 32078, type: import_modbus_types.ModbusDatatype.int32, length: 2 } }, { interval: 1 /* LOW */, - state: { id: "efficiency", name: "Efficiency", type: "number", unit: "%", role: "value.efficiency" }, + state: { id: "efficiency", name: "Efficiency", type: "number", unit: "%", role: "value" }, register: { reg: 32086, type: import_modbus_types.ModbusDatatype.uint16, length: 1, gain: 100 } }, { interval: 1 /* LOW */, - state: { id: "internalTemperature", name: "Internal temperature", type: "number", unit: "\xB0C", role: "value.temp" }, + state: { id: "internalTemperature", name: "Internal temperature", type: "number", unit: "\xB0C", role: "value.temperature" }, register: { reg: 32087, type: import_modbus_types.ModbusDatatype.int16, length: 1, gain: 10 } }, { interval: 1 /* LOW */, - state: { id: "deviceStatus", name: "Device status", type: "string", unit: "", role: "value.status" }, + state: { id: "deviceStatus", name: "Device status", type: "string", unit: "", role: "info.status" }, register: { reg: 32089, type: import_modbus_types.ModbusDatatype.uint16, length: 1 }, mapper: (value) => Promise.resolve(import_state_enums.InverterStatus[value]) }, { interval: 1 /* LOW */, - state: { id: "accumulatedEnergyYield", name: "Accumulated energy yield", type: "number", unit: "kWh", role: "value" }, + state: { id: "accumulatedEnergyYield", name: "Accumulated energy yield", type: "number", unit: "kWh", role: "value.energy.produced" }, register: { reg: 32106, type: import_modbus_types.ModbusDatatype.uint32, length: 2, gain: 100 } }, { interval: 1 /* LOW */, - state: { id: "dailyEnergyYield", name: "Daily energy yield", type: "number", unit: "kWh", role: "value" }, + state: { id: "dailyEnergyYield", name: "Daily energy yield", type: "number", unit: "kWh", role: "value.energy" }, register: { reg: 32114, type: import_modbus_types.ModbusDatatype.uint32, length: 2, gain: 100 } }, { @@ -116,13 +116,13 @@ class InverterStates { }, { interval: 1 /* LOW */, - state: { id: "storage.runningState", name: "Running state", type: "string", role: "value" }, + state: { id: "storage.runningState", name: "Running state", type: "string", role: "info.status" }, register: { reg: 37762, type: import_modbus_types.ModbusDatatype.uint16, length: 1 }, mapper: (value) => Promise.resolve(import_state_enums.StorageStatus[value]) }, { interval: 0 /* HIGH */, - state: { id: "storage.stateOfCapacity", name: "State of capacity", type: "number", unit: "%", role: "value.capacity", desc: "SOC" }, + state: { id: "storage.stateOfCapacity", name: "State of capacity", type: "number", unit: "%", role: "value.battery", desc: "SOC" }, register: { reg: 37760, type: import_modbus_types.ModbusDatatype.uint16, length: 1, gain: 10 } }, { @@ -138,23 +138,23 @@ class InverterStates { }, { interval: 1 /* LOW */, - state: { id: "storage.CurrentDayChargeCapacity", name: "CurrentDayChargeCapacity", type: "number", unit: "kWh", role: "value.power", desc: "TBD" }, + state: { id: "storage.CurrentDayChargeCapacity", name: "CurrentDayChargeCapacity", type: "number", unit: "kWh", role: "value.energy", desc: "TBD" }, register: { reg: 37015, type: import_modbus_types.ModbusDatatype.uint32, length: 2, gain: 100 } }, { interval: 1 /* LOW */, - state: { id: "storage.CurrentDayDischargeCapacity", name: "CurrentDayDischargeCapacity", type: "number", unit: "kWh", role: "value.power", desc: "TBD" }, + state: { id: "storage.CurrentDayDischargeCapacity", name: "CurrentDayDischargeCapacity", type: "number", unit: "kWh", role: "value.energy", desc: "TBD" }, register: { reg: 37786, type: import_modbus_types.ModbusDatatype.uint32, length: 2, gain: 100 } }, { interval: 1 /* LOW */, - state: { id: "grid.meterStatus", name: "Meter status", type: "string", role: "value.status" }, + state: { id: "grid.meterStatus", name: "Meter status", type: "string", role: "info.status" }, register: { reg: 37100, type: import_modbus_types.ModbusDatatype.uint16, length: 1 }, mapper: (value) => Promise.resolve(import_state_enums.MeterStatus[value]) }, { interval: 0 /* HIGH */, - state: { id: "grid.activePower", name: "Active power", type: "number", role: "value.power", unit: "W", desc: "(>0 feed-in to the power grid, <0: supply from the power grid)" }, + state: { id: "grid.activePower", name: "Active power", type: "number", role: "value.power.active", unit: "W", desc: "(>0 feed-in to the power grid, <0: supply from the power grid)" }, register: { reg: 37113, type: import_modbus_types.ModbusDatatype.int32, length: 2 }, postUpdateHook: async (adapter, value) => { return Promise.resolve(/* @__PURE__ */ new Map([ @@ -165,12 +165,12 @@ class InverterStates { }, { interval: 1 /* LOW */, - state: { id: "grid.reactivePower", name: "Reactive power", type: "number", role: "value.power", unit: "W" }, + state: { id: "grid.reactivePower", name: "Reactive power", type: "number", role: "value.power.reactive", unit: "W" }, register: { reg: 37115, type: import_modbus_types.ModbusDatatype.int32, length: 2 } }, { interval: 1 /* LOW */, - state: { id: "grid.powerFactor", name: "Power factor", type: "number", role: "value.power.factor", unit: "" }, + state: { id: "grid.powerFactor", name: "Power factor", type: "number", role: "value", unit: "" }, register: { reg: 37117, type: import_modbus_types.ModbusDatatype.int16, length: 1, gain: 1e3 } }, { @@ -210,12 +210,12 @@ class InverterStates { }, { interval: 1 /* LOW */, - state: { id: "grid.positiveActivePower", name: "Positive active power", type: "number", role: "value.power", unit: "kWh", desc: "Electricity fed by the inverter to the power grid." }, + state: { id: "grid.positiveActivePower", name: "Positive active power", type: "number", role: "value.power.active", unit: "kWh", desc: "Electricity fed by the inverter to the power grid." }, register: { reg: 37119, type: import_modbus_types.ModbusDatatype.int32, length: 2, gain: 100 } }, { interval: 1 /* LOW */, - state: { id: "grid.reverseActivePower", name: "Reverse active power", type: "number", role: "value.power", unit: "kWh", desc: "Power supplied from the power grid." }, + state: { id: "grid.reverseActivePower", name: "Reverse active power", type: "number", role: "value.power.active", unit: "kWh", desc: "Power supplied from the power grid." }, register: { reg: 37121, type: import_modbus_types.ModbusDatatype.int32, length: 2, gain: 100 } } ]; @@ -239,7 +239,7 @@ class InverterStates { async createStates(adapter) { for (const field of this.dataFields) { const state = field.state; - await adapter.setObjectAsync(state.id, { + adapter.extendObject(state.id, { type: "state", common: { name: state.name, diff --git a/build/lib/states.js.map b/build/lib/states.js.map index c2693d0..d12661a 100644 --- a/build/lib/states.js.map +++ b/build/lib/states.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../src/lib/states.ts"], - "sourcesContent": ["import {ModbusDatatype} from './modbus/modbus_types';\nimport {InverterStatus, MeterStatus, StorageStatus} from './state_enums';\nimport {AdapterInstance} from '@iobroker/adapter-core';\nimport {ModbusDevice} from './modbus/modbus_device';\n\ntype MapperFn = (value: any) => Promise\ntype PostUpdateHookFn = (adapter: AdapterInstance, value: any) => Promise>\ntype PostFetchUpdateHookFn = (adapter: AdapterInstance, toUpdate: Map) => Map\n\ninterface DataField {\n interval?: UpdateIntervalID;\n state: State;\n register: ModbusRegister;\n mapper?: MapperFn;\n postUpdateHook?: PostUpdateHookFn;\n}\n\ninterface StateToUpdate {\n id: string;\n value: any;\n postUpdateHook?: PostUpdateHookFn;\n}\n\ninterface State {\n id: string;\n name: string;\n type: ioBroker.CommonType;\n role: string;\n unit?: string;\n desc?: string;\n}\n\ninterface ModbusRegister {\n reg: number;\n type: ModbusDatatype;\n length: number;\n gain?: number;\n}\n\nexport enum UpdateIntervalID {\n HIGH,\n LOW\n}\n\ninterface UpdateIntervals {\n intervals: number[];\n}\n\ninterface PostFetchUpdateHook {\n interval: UpdateIntervalID;\n hookFn: PostFetchUpdateHookFn;\n}\n\nexport class InverterStates {\n\n private updateIntervals: UpdateIntervals\n private readonly dataFields: DataField[];\n private readonly postFetchUpdateHooks: PostFetchUpdateHook[];\n // private changingFields: DataField[];\n\n constructor(updateIntervals: UpdateIntervals) {\n this.updateIntervals = updateIntervals;\n this.dataFields = [\n // initial fields (no interval set) - no repetitive update\n {\n state: {id: 'info.model', name: 'Model', type: 'string', role: 'state'},\n register: {reg: 30000, type: ModbusDatatype.string, length: 15}\n },\n {\n state: {id: 'info.modelID', name: 'Model ID', type: 'number', role: 'state'},\n register: {reg: 30070, type: ModbusDatatype.uint16, length: 1}\n },\n {\n state: {id: 'info.serialNumber', name: 'Serial number', type: 'string', role: 'state'},\n register: {reg: 30015, type: ModbusDatatype.string, length: 10}\n },\n {\n state: {id: 'info.ratedPower', name: 'Rated power', type: 'number', unit: 'W', role: 'state'},\n register: {reg: 30073, type: ModbusDatatype.int32, length: 2}\n },\n {\n state: {id: 'info.numberMPPTrackers', name: 'Number of MPP trackers', type: 'number', unit: '', role: 'state'},\n register: {reg: 30072, type: ModbusDatatype.uint16, length: 1, gain: 1}\n },\n\n // ####################################################################################################################################\n // inverter\n {\n interval: UpdateIntervalID.HIGH,\n state: {id: 'activePower', name: 'Active power', type: 'number', unit: 'W', role: 'value.power', desc: 'Power currently used'},\n register: {reg: 32080, type: ModbusDatatype.int32, length: 2}\n },\n {\n interval: UpdateIntervalID.HIGH,\n state: {id: 'inputPower', name: 'Input power', type: 'number', unit: 'W', role: 'value.power', desc: 'Power from PV'},\n register: {reg: 32064, type: ModbusDatatype.int32, length: 2}\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'peakActivePowerCurrenDay', name: 'Peak active power of current day', type: 'number', unit: 'W', role: 'value.power.max'},\n register: {reg: 32078, type: ModbusDatatype.int32, length: 2}\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'efficiency', name: 'Efficiency', type: 'number', unit: '%', role: 'value.efficiency'},\n register: {reg: 32086, type: ModbusDatatype.uint16, length: 1, gain: 100}\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'internalTemperature', name: 'Internal temperature', type: 'number', unit: '\u00B0C', role: 'value.temp'},\n register: {reg: 32087, type: ModbusDatatype.int16, length: 1, gain: 10}\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'deviceStatus', name: 'Device status', type: 'string', unit: '', role: 'value.status'},\n register: {reg: 32089, type: ModbusDatatype.uint16, length: 1},\n mapper: value => Promise.resolve(InverterStatus[value])\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'accumulatedEnergyYield', name: 'Accumulated energy yield', type: 'number', unit: 'kWh', role: 'value'},\n register: {reg: 32106, type: ModbusDatatype.uint32, length: 2, gain: 100},\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'dailyEnergyYield', name: 'Daily energy yield', type: 'number', unit: 'kWh', role: 'value'},\n register: {reg: 32114, type: ModbusDatatype.uint32, length: 2, gain: 100}\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'PV1Voltage', name: 'PV1 voltage', type: 'number', unit: 'V', role: 'value.voltage'},\n register: {reg: 32016, type: ModbusDatatype.int16, length: 1, gain: 10}\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'PV1Current', name: 'PV1 current', type: 'number', unit: 'A', role: 'value.current'},\n register: {reg: 32017, type: ModbusDatatype.int16, length: 1, gain: 100}\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'PV2Voltage', name: 'PV2 voltage', type: 'number', unit: 'V', role: 'value.voltage'},\n register: {reg: 32018, type: ModbusDatatype.int16, length: 1, gain: 10}\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'PV2Current', name: 'PV2 current', type: 'number', unit: 'A', role: 'value.current'},\n register: {reg: 32019, type: ModbusDatatype.int16, length: 1, gain: 100}\n },\n\n // ####################################################################################################################################\n // storage\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'storage.runningState', name: 'Running state', type: 'string', role: 'value'},\n register: {reg: 37762, type: ModbusDatatype.uint16, length: 1},\n mapper: value => Promise.resolve(StorageStatus[value])\n },\n {\n interval: UpdateIntervalID.HIGH,\n state: {id: 'storage.stateOfCapacity', name: 'State of capacity', type: 'number', unit: '%', role: 'value.capacity', desc: 'SOC'},\n register: {reg: 37760, type: ModbusDatatype.uint16, length: 1, gain: 10}\n },\n {\n interval: UpdateIntervalID.HIGH,\n state: {id: 'storage.chargeDischargePower', name: 'Charge/Discharge power', desc: '(>0 charging, <0 discharging)', type: 'number', unit: 'W', role: 'value.power'},\n register: {reg: 37765, type: ModbusDatatype.int32, length: 2},\n postUpdateHook: async (adapter, value): Promise> => {\n return Promise.resolve(new Map([\n ['storage.chargePower', {id: 'storage.chargePower', value: Math.max(0, value)}],\n ['storage.dischargePower', {id: 'storage.dischargePower', value: Math.abs(Math.min(0, value))}]\n ]));\n }\n },\n {\n interval: UpdateIntervalID.LOW,\n state: { id: 'storage.CurrentDayChargeCapacity', name: 'CurrentDayChargeCapacity', type: 'number', unit: 'kWh', role: 'value.power', desc: 'TBD' },\n register: { reg: 37015, type: ModbusDatatype.uint32, length: 2, gain: 100 }\n },\n {\n interval: UpdateIntervalID.LOW,\n state: { id: 'storage.CurrentDayDischargeCapacity', name: 'CurrentDayDischargeCapacity', type: 'number', unit: 'kWh', role: 'value.power', desc: 'TBD' },\n register: { reg: 37786, type: ModbusDatatype.uint32, length: 2, gain: 100 }\n },\n\n // ####################################################################################################################################\n // grid (meter)\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'grid.meterStatus', name: 'Meter status', type: 'string', role: 'value.status'},\n register: {reg: 37100, type: ModbusDatatype.uint16, length: 1},\n mapper: value => Promise.resolve(MeterStatus[value])\n },\n {\n interval: UpdateIntervalID.HIGH,\n state: {id: 'grid.activePower', name: 'Active power', type: 'number', role: 'value.power', unit: 'W', desc: '(>0 feed-in to the power grid, <0: supply from the power grid)'},\n register: {reg: 37113, type: ModbusDatatype.int32, length: 2},\n postUpdateHook: async (adapter, value): Promise> => {\n return Promise.resolve(new Map([\n ['grid.feedIn', {id: 'grid.feedIn', value: Math.max(0, value)}],\n ['grid.supplyFrom', {id: 'grid.supplyFrom', value: Math.abs(Math.min(0, value))}]\n ]));\n }\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'grid.reactivePower', name: 'Reactive power', type: 'number', role: 'value.power', unit: 'W'},\n register: {reg: 37115, type: ModbusDatatype.int32, length: 2},\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'grid.powerFactor', name: 'Power factor', type: 'number', role: 'value.power.factor', unit: ''},\n register: {reg: 37117, type: ModbusDatatype.int16, length: 1, gain: 1000},\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'grid.gridFrequency', name: 'Grid frequency', type: 'number', role: 'value.frequency', unit: 'Hz'},\n register: {reg: 37118, type: ModbusDatatype.int16, length: 1, gain: 100},\n },\n\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'grid.phase1Voltage', name: 'Phase 1 voltage', type: 'number', role: 'value.voltage', unit: 'V', desc: 'also L1, or R voltage'},\n register: {reg: 37101, type: ModbusDatatype.int32, length: 2, gain: 10},\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'grid.phase2Voltage', name: 'Phase 2 voltage', type: 'number', role: 'value.voltage', unit: 'V', desc: 'also L2, or S voltage'},\n register: {reg: 37103, type: ModbusDatatype.int32, length: 2, gain: 10},\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'grid.phase3Voltage', name: 'Phase 3 voltage', type: 'number', role: 'value.voltage', unit: 'V', desc: 'also L3, or T voltage'},\n register: {reg: 37105, type: ModbusDatatype.int32, length: 2, gain: 10},\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'grid.phase1Current', name: 'Phase 1 current', type: 'number', role: 'value.current', unit: 'A'},\n register: {reg: 37107, type: ModbusDatatype.int32, length: 2, gain: 100},\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'grid.phase2Current', name: 'Phase 2 current', type: 'number', role: 'value.current', unit: 'A'},\n register: {reg: 37109, type: ModbusDatatype.int32, length: 2, gain: 100},\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'grid.phase3Current', name: 'Phase 3 current', type: 'number', role: 'value.current', unit: 'A'},\n register: {reg: 37111, type: ModbusDatatype.int32, length: 2, gain: 100},\n },\n\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'grid.positiveActivePower', name: 'Positive active power', type: 'number', role: 'value.power', unit: 'kWh', desc: 'Electricity fed by the inverter to the power grid.'},\n register: {reg: 37119, type: ModbusDatatype.int32, length: 2, gain: 100},\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'grid.reverseActivePower', name: 'Reverse active power', type: 'number', role: 'value.power', unit: 'kWh', desc: 'Power supplied from the power grid.'},\n register: {reg: 37121, type: ModbusDatatype.int32, length: 2, gain: 100},\n },\n ];\n this.postFetchUpdateHooks = [\n {\n interval: UpdateIntervalID.HIGH,\n hookFn: (adapter: AdapterInstance, toUpdate: Map) => {\n const powerGridActive = toUpdate.get('grid.activePower');\n const powerActiveInverter = toUpdate.get('activePower');\n const totalPowerUse = powerActiveInverter?.value - powerGridActive?.value;\n adapter.log.silly(`PostFetchHook: calculate totalPowerUse ${powerGridActive?.value}, ${powerActiveInverter?.value}, ${totalPowerUse}`);\n const result = new Map();\n if (totalPowerUse) {\n result.set('totalPowerUse', {id: 'totalPowerUse', value: totalPowerUse})\n }\n return result;\n }\n }\n ];\n }\n\n public async createStates(adapter: AdapterInstance): Promise {\n for (const field of this.dataFields) {\n const state = field.state\n await adapter.setObjectAsync(state.id, {\n type: 'state',\n common: {\n name: state.name,\n type: state.type,\n role: state.role,\n unit: state.unit,\n desc: state.desc,\n read: true,\n write: false\n },\n native: {},\n });\n }\n }\n\n\n public async updateStates(adapter: AdapterInstance, device: ModbusDevice, interval?: UpdateIntervalID): Promise {\n let toUpdate = new Map;\n for (const field of this.dataFields) {\n if (field.interval != interval) {\n continue;\n }\n try {\n let value = await device.readModbusHR(field.register.reg, field.register.type, field.register.length);\n\n if (field.register.gain) {\n value /= field.register.gain;\n }\n if (field.mapper) {\n value = await field.mapper(value);\n }\n toUpdate.set(field.state.id, {id: field.state.id, value: value})\n if (field.postUpdateHook) {\n const hookUpdates = await field.postUpdateHook(adapter, value);\n for (const entry of hookUpdates.entries()) {\n toUpdate.set(entry[0], entry[1]);\n }\n }\n } catch (e) {\n adapter.log.warn(`Error while reading from ${device.getIpAddress()}: [${field.register.reg}|${field.register.length}] '' with : ${e}`);\n break;\n }\n }\n\n toUpdate = this.runPostFetchHooks(adapter, toUpdate, interval);\n\n return this.updateAdapterStates(adapter, toUpdate);\n }\n\n public runPostFetchHooks(adapter: AdapterInstance, toUpdate: Map, interval: UpdateIntervalID | undefined): Map {\n for (const postFetchHook of this.postFetchUpdateHooks) {\n if (postFetchHook.interval == interval) {\n const hookUpdates = postFetchHook.hookFn(adapter, toUpdate);\n for (const entry of hookUpdates.entries()) {\n toUpdate.set(entry[0], entry[1]);\n }\n }\n }\n return toUpdate;\n }\n\n public async updateAdapterStates(adapter: AdapterInstance, toUpdate: Map): Promise {\n for(const updateEntry of toUpdate.values()) {\n if (updateEntry.value !== null) {\n await adapter.setStateAsync(updateEntry.id, {val: updateEntry.value, ack: true});\n if (updateEntry.postUpdateHook) {\n await updateEntry.postUpdateHook(adapter, updateEntry.value);\n }\n adapter.log.silly(`Fetched value ${updateEntry.id}, val=[${updateEntry.value}]`);\n }\n }\n return Promise.resolve(toUpdate.size);\n }\n}\n"], - "mappings": "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", + "sourcesContent": ["import {ModbusDatatype} from './modbus/modbus_types';\nimport {InverterStatus, MeterStatus, StorageStatus} from './state_enums';\nimport {AdapterInstance} from '@iobroker/adapter-core';\nimport {ModbusDevice} from './modbus/modbus_device';\n\ntype MapperFn = (value: any) => Promise\ntype PostUpdateHookFn = (adapter: AdapterInstance, value: any) => Promise>\ntype PostFetchUpdateHookFn = (adapter: AdapterInstance, toUpdate: Map) => Map\n\ninterface DataField {\n interval?: UpdateIntervalID;\n state: State;\n register: ModbusRegister;\n mapper?: MapperFn;\n postUpdateHook?: PostUpdateHookFn;\n}\n\ninterface StateToUpdate {\n id: string;\n value: any;\n postUpdateHook?: PostUpdateHookFn;\n}\n\ninterface State {\n id: string;\n name: string;\n type: ioBroker.CommonType;\n role: string;\n unit?: string;\n desc?: string;\n}\n\ninterface ModbusRegister {\n reg: number;\n type: ModbusDatatype;\n length: number;\n gain?: number;\n}\n\nexport enum UpdateIntervalID {\n HIGH,\n LOW\n}\n\ninterface UpdateIntervals {\n intervals: number[];\n}\n\ninterface PostFetchUpdateHook {\n interval: UpdateIntervalID;\n hookFn: PostFetchUpdateHookFn;\n}\n\nexport class InverterStates {\n\n private updateIntervals: UpdateIntervals\n private readonly dataFields: DataField[];\n private readonly postFetchUpdateHooks: PostFetchUpdateHook[];\n // private changingFields: DataField[];\n\n constructor(updateIntervals: UpdateIntervals) {\n this.updateIntervals = updateIntervals;\n this.dataFields = [\n // initial fields (no interval set) - no repetitive update\n {\n state: {id: 'info.model', name: 'Model', type: 'string', role: 'info.name'},\n register: {reg: 30000, type: ModbusDatatype.string, length: 15}\n },\n {\n state: {id: 'info.modelID', name: 'Model ID', type: 'number', role: 'info.hardware'},\n register: {reg: 30070, type: ModbusDatatype.uint16, length: 1}\n },\n {\n state: {id: 'info.serialNumber', name: 'Serial number', type: 'string', role: 'info.serial'},\n register: {reg: 30015, type: ModbusDatatype.string, length: 10}\n },\n {\n state: {id: 'info.ratedPower', name: 'Rated power', type: 'number', unit: 'W', role: 'value.power'},\n register: {reg: 30073, type: ModbusDatatype.int32, length: 2}\n },\n {\n state: {id: 'info.numberMPPTrackers', name: 'Number of MPP trackers', type: 'number', unit: '', role: 'value'},\n register: {reg: 30072, type: ModbusDatatype.uint16, length: 1, gain: 1}\n },\n\n // ####################################################################################################################################\n // inverter\n {\n interval: UpdateIntervalID.HIGH,\n state: {id: 'activePower', name: 'Active power', type: 'number', unit: 'W', role: 'value.power.active', desc: 'Power currently used'},\n register: {reg: 32080, type: ModbusDatatype.int32, length: 2}\n },\n {\n interval: UpdateIntervalID.HIGH,\n state: {id: 'inputPower', name: 'Input power', type: 'number', unit: 'W', role: 'value.power.produced', desc: 'Power from PV'},\n register: {reg: 32064, type: ModbusDatatype.int32, length: 2}\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'peakActivePowerCurrenDay', name: 'Peak active power of current day', type: 'number', unit: 'W', role: 'value.power'},\n register: {reg: 32078, type: ModbusDatatype.int32, length: 2}\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'efficiency', name: 'Efficiency', type: 'number', unit: '%', role: 'value'},\n register: {reg: 32086, type: ModbusDatatype.uint16, length: 1, gain: 100}\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'internalTemperature', name: 'Internal temperature', type: 'number', unit: '\u00B0C', role: 'value.temperature'},\n register: {reg: 32087, type: ModbusDatatype.int16, length: 1, gain: 10}\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'deviceStatus', name: 'Device status', type: 'string', unit: '', role: 'info.status'},\n register: {reg: 32089, type: ModbusDatatype.uint16, length: 1},\n mapper: value => Promise.resolve(InverterStatus[value])\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'accumulatedEnergyYield', name: 'Accumulated energy yield', type: 'number', unit: 'kWh', role: 'value.energy.produced'},\n register: {reg: 32106, type: ModbusDatatype.uint32, length: 2, gain: 100},\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'dailyEnergyYield', name: 'Daily energy yield', type: 'number', unit: 'kWh', role: 'value.energy'},\n register: {reg: 32114, type: ModbusDatatype.uint32, length: 2, gain: 100}\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'PV1Voltage', name: 'PV1 voltage', type: 'number', unit: 'V', role: 'value.voltage'},\n register: {reg: 32016, type: ModbusDatatype.int16, length: 1, gain: 10}\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'PV1Current', name: 'PV1 current', type: 'number', unit: 'A', role: 'value.current'},\n register: {reg: 32017, type: ModbusDatatype.int16, length: 1, gain: 100}\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'PV2Voltage', name: 'PV2 voltage', type: 'number', unit: 'V', role: 'value.voltage'},\n register: {reg: 32018, type: ModbusDatatype.int16, length: 1, gain: 10}\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'PV2Current', name: 'PV2 current', type: 'number', unit: 'A', role: 'value.current'},\n register: {reg: 32019, type: ModbusDatatype.int16, length: 1, gain: 100}\n },\n\n // ####################################################################################################################################\n // storage\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'storage.runningState', name: 'Running state', type: 'string', role: 'info.status'},\n register: {reg: 37762, type: ModbusDatatype.uint16, length: 1},\n mapper: value => Promise.resolve(StorageStatus[value])\n },\n {\n interval: UpdateIntervalID.HIGH,\n state: {id: 'storage.stateOfCapacity', name: 'State of capacity', type: 'number', unit: '%', role: 'value.battery', desc: 'SOC'},\n register: {reg: 37760, type: ModbusDatatype.uint16, length: 1, gain: 10}\n },\n {\n interval: UpdateIntervalID.HIGH,\n state: {id: 'storage.chargeDischargePower', name: 'Charge/Discharge power', desc: '(>0 charging, <0 discharging)', type: 'number', unit: 'W', role: 'value.power'},\n register: {reg: 37765, type: ModbusDatatype.int32, length: 2},\n postUpdateHook: async (adapter, value): Promise> => {\n return Promise.resolve(new Map([\n ['storage.chargePower', {id: 'storage.chargePower', value: Math.max(0, value)}],\n ['storage.dischargePower', {id: 'storage.dischargePower', value: Math.abs(Math.min(0, value))}]\n ]));\n }\n },\n {\n interval: UpdateIntervalID.LOW,\n state: { id: 'storage.CurrentDayChargeCapacity', name: 'CurrentDayChargeCapacity', type: 'number', unit: 'kWh', role: 'value.energy', desc: 'TBD' },\n register: { reg: 37015, type: ModbusDatatype.uint32, length: 2, gain: 100 }\n },\n {\n interval: UpdateIntervalID.LOW,\n state: { id: 'storage.CurrentDayDischargeCapacity', name: 'CurrentDayDischargeCapacity', type: 'number', unit: 'kWh', role: 'value.energy', desc: 'TBD' },\n register: { reg: 37786, type: ModbusDatatype.uint32, length: 2, gain: 100 }\n },\n\n // ####################################################################################################################################\n // grid (meter)\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'grid.meterStatus', name: 'Meter status', type: 'string', role: 'info.status'},\n register: {reg: 37100, type: ModbusDatatype.uint16, length: 1},\n mapper: value => Promise.resolve(MeterStatus[value])\n },\n {\n interval: UpdateIntervalID.HIGH,\n state: {id: 'grid.activePower', name: 'Active power', type: 'number', role: 'value.power.active', unit: 'W', desc: '(>0 feed-in to the power grid, <0: supply from the power grid)'},\n register: {reg: 37113, type: ModbusDatatype.int32, length: 2},\n postUpdateHook: async (adapter, value): Promise> => {\n return Promise.resolve(new Map([\n ['grid.feedIn', {id: 'grid.feedIn', value: Math.max(0, value)}],\n ['grid.supplyFrom', {id: 'grid.supplyFrom', value: Math.abs(Math.min(0, value))}]\n ]));\n }\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'grid.reactivePower', name: 'Reactive power', type: 'number', role: 'value.power.reactive', unit: 'W'},\n register: {reg: 37115, type: ModbusDatatype.int32, length: 2},\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'grid.powerFactor', name: 'Power factor', type: 'number', role: 'value', unit: ''},\n register: {reg: 37117, type: ModbusDatatype.int16, length: 1, gain: 1000},\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'grid.gridFrequency', name: 'Grid frequency', type: 'number', role: 'value.frequency', unit: 'Hz'},\n register: {reg: 37118, type: ModbusDatatype.int16, length: 1, gain: 100},\n },\n\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'grid.phase1Voltage', name: 'Phase 1 voltage', type: 'number', role: 'value.voltage', unit: 'V', desc: 'also L1, or R voltage'},\n register: {reg: 37101, type: ModbusDatatype.int32, length: 2, gain: 10},\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'grid.phase2Voltage', name: 'Phase 2 voltage', type: 'number', role: 'value.voltage', unit: 'V', desc: 'also L2, or S voltage'},\n register: {reg: 37103, type: ModbusDatatype.int32, length: 2, gain: 10},\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'grid.phase3Voltage', name: 'Phase 3 voltage', type: 'number', role: 'value.voltage', unit: 'V', desc: 'also L3, or T voltage'},\n register: {reg: 37105, type: ModbusDatatype.int32, length: 2, gain: 10},\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'grid.phase1Current', name: 'Phase 1 current', type: 'number', role: 'value.current', unit: 'A'},\n register: {reg: 37107, type: ModbusDatatype.int32, length: 2, gain: 100},\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'grid.phase2Current', name: 'Phase 2 current', type: 'number', role: 'value.current', unit: 'A'},\n register: {reg: 37109, type: ModbusDatatype.int32, length: 2, gain: 100},\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'grid.phase3Current', name: 'Phase 3 current', type: 'number', role: 'value.current', unit: 'A'},\n register: {reg: 37111, type: ModbusDatatype.int32, length: 2, gain: 100},\n },\n\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'grid.positiveActivePower', name: 'Positive active power', type: 'number', role: 'value.power.active', unit: 'kWh', desc: 'Electricity fed by the inverter to the power grid.'},\n register: {reg: 37119, type: ModbusDatatype.int32, length: 2, gain: 100},\n },\n {\n interval: UpdateIntervalID.LOW,\n state: {id: 'grid.reverseActivePower', name: 'Reverse active power', type: 'number', role: 'value.power.active', unit: 'kWh', desc: 'Power supplied from the power grid.'},\n register: {reg: 37121, type: ModbusDatatype.int32, length: 2, gain: 100},\n },\n ];\n this.postFetchUpdateHooks = [\n {\n interval: UpdateIntervalID.HIGH,\n hookFn: (adapter: AdapterInstance, toUpdate: Map) => {\n const powerGridActive = toUpdate.get('grid.activePower');\n const powerActiveInverter = toUpdate.get('activePower');\n const totalPowerUse = powerActiveInverter?.value - powerGridActive?.value;\n adapter.log.silly(`PostFetchHook: calculate totalPowerUse ${powerGridActive?.value}, ${powerActiveInverter?.value}, ${totalPowerUse}`);\n const result = new Map();\n if (totalPowerUse) {\n result.set('totalPowerUse', {id: 'totalPowerUse', value: totalPowerUse})\n }\n return result;\n }\n }\n ];\n }\n\n public async createStates(adapter: AdapterInstance): Promise {\n for (const field of this.dataFields) {\n const state = field.state\n adapter.extendObject(state.id, {\n type: 'state',\n common: {\n name: state.name,\n type: state.type,\n role: state.role,\n unit: state.unit,\n desc: state.desc,\n read: true,\n write: false\n },\n native: {},\n });\n }\n }\n\n\n public async updateStates(adapter: AdapterInstance, device: ModbusDevice, interval?: UpdateIntervalID): Promise {\n let toUpdate = new Map;\n for (const field of this.dataFields) {\n if (field.interval != interval) {\n continue;\n }\n try {\n let value = await device.readModbusHR(field.register.reg, field.register.type, field.register.length);\n\n if (field.register.gain) {\n value /= field.register.gain;\n }\n if (field.mapper) {\n value = await field.mapper(value);\n }\n toUpdate.set(field.state.id, {id: field.state.id, value: value})\n if (field.postUpdateHook) {\n const hookUpdates = await field.postUpdateHook(adapter, value);\n for (const entry of hookUpdates.entries()) {\n toUpdate.set(entry[0], entry[1]);\n }\n }\n } catch (e) {\n adapter.log.warn(`Error while reading from ${device.getIpAddress()}: [${field.register.reg}|${field.register.length}] '' with : ${e}`);\n break;\n }\n }\n\n toUpdate = this.runPostFetchHooks(adapter, toUpdate, interval);\n\n return this.updateAdapterStates(adapter, toUpdate);\n }\n\n public runPostFetchHooks(adapter: AdapterInstance, toUpdate: Map, interval: UpdateIntervalID | undefined): Map {\n for (const postFetchHook of this.postFetchUpdateHooks) {\n if (postFetchHook.interval == interval) {\n const hookUpdates = postFetchHook.hookFn(adapter, toUpdate);\n for (const entry of hookUpdates.entries()) {\n toUpdate.set(entry[0], entry[1]);\n }\n }\n }\n return toUpdate;\n }\n\n public async updateAdapterStates(adapter: AdapterInstance, toUpdate: Map): Promise {\n for(const updateEntry of toUpdate.values()) {\n if (updateEntry.value !== null) {\n await adapter.setStateAsync(updateEntry.id, {val: updateEntry.value, ack: true});\n if (updateEntry.postUpdateHook) {\n await updateEntry.postUpdateHook(adapter, updateEntry.value);\n }\n adapter.log.silly(`Fetched value ${updateEntry.id}, val=[${updateEntry.value}]`);\n }\n }\n return Promise.resolve(toUpdate.size);\n }\n}\n"], + "mappings": "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", "names": ["UpdateIntervalID"] } diff --git a/build/main.js b/build/main.js index 11954f3..77e8e17 100644 --- a/build/main.js +++ b/build/main.js @@ -31,7 +31,6 @@ class Sun2000Modbus extends utils.Adapter { this.watchdogInterval = null; this.scheduler = new import_scheduler.Scheduler(this); this.on("ready", this.onReady.bind(this)); - this.on("stateChange", this.onStateChange.bind(this)); this.on("unload", this.onUnload.bind(this)); } async onReady() { diff --git a/build/main.js.map b/build/main.js.map index 279135f..a4b3bab 100644 --- a/build/main.js.map +++ b/build/main.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../src/main.ts"], - "sourcesContent": ["/*\n * Created with @iobroker/create-adapter v2.5.0\n */\n\n// The adapter-core module gives you access to the core ioBroker functions\n// you need to create an adapter\nimport * as utils from '@iobroker/adapter-core';\n\n// Load your modules here, e.g.:\nimport {InverterStates, UpdateIntervalID} from './lib/states';\nimport {ModbusDevice} from './lib/modbus/modbus_device';\nimport {Scheduler} from './lib/scheduler';\n\nclass Sun2000Modbus extends utils.Adapter {\n\n private device!: ModbusDevice;\n private timeout: any = null;\n private watchdogInterval: any = null;\n private states!: InverterStates;\n private scheduler: Scheduler;\n private lastUpdated!: number;\n\n public constructor(options: Partial = {}) {\n super({\n ...options,\n name: 'sun2000-modbus',\n });\n this.scheduler = new Scheduler(this);\n this.on('ready', this.onReady.bind(this));\n this.on('stateChange', this.onStateChange.bind(this));\n this.on('unload', this.onUnload.bind(this));\n }\n\n /**\n * Is called when databases are connected and adapter received configuration.\n */\n private async onReady(): Promise {\n // Initialize your adapter here\n\n this.states = new InverterStates({intervals: [this.config.updateIntervalHigh, this.config.updateIntervalHigh, this.config.updateIntervalHigh]});\n\n // The adapters config (in the instance object everything under the attribute \"native\") is accessible via\n // this.config:\n await this.setStateAsync('info.ip', {val: this.config.address, ack: true});\n await this.setStateAsync('info.port', {val: this.config.port, ack: true});\n await this.setStateAsync('info.unitID', {val: this.config.modbusUnitId, ack: true});\n await this.setStateAsync('info.modbusUpdateIntervalHigh', {val: this.config.updateIntervalHigh, ack: true});\n await this.setStateAsync('info.modbusUpdateIntervalLow', {val: this.config.updateIntervalLow, ack: true});\n\n this.device = new ModbusDevice(this.config.address, this.config.port, this.config.modbusUnitId);\n\n this.log.info('Create states');\n await this.states.createStates(this);\n this.log.info('Update initial states');\n await this.states.updateStates(this, this.device); // no recurring update\n\n if (this.device.isConnected()) {\n await this.setStateAsync('info.connection', true, true);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n\n this.scheduler.addInterval('HIGH', this.config.updateIntervalHigh, async () => {\n return this.states.updateStates(self, this.device, UpdateIntervalID.HIGH);\n });\n this.scheduler.addInterval('LOW', this.config.updateIntervalLow, async () => {\n const countHigh = await this.states.updateStates(self, this.device, UpdateIntervalID.HIGH);\n const countLow = await this.states.updateStates(self, this.device, UpdateIntervalID.LOW);\n return Promise.resolve(countHigh + countLow)\n });\n\n this.scheduler.init();\n\n this.log.info('Start fetching data from inverter');\n await this.runSync();\n await this.runWatchDog();\n\n }\n\n private async runWatchDog(): Promise {\n this.watchdogInterval && this.clearInterval(this.watchdogInterval);\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n this.log.info('Start watchdog');\n const maxInterval = Math.max(this.config.updateIntervalHigh, this.config.updateIntervalLow)\n this.log.info(`Max interval: [${maxInterval}]`);\n this.watchdogInterval = this.setInterval(async () => {\n const timeSinceLastUpdate = (new Date().getTime() - self.lastUpdated) / 1000;\n this.log.debug(`Watchdog: ${timeSinceLastUpdate}`)\n if (timeSinceLastUpdate > 2 * maxInterval) {\n this.log.info(`Re-trigger sync... timeoutID: ${self.timeout}`)\n await this.runSync();\n }\n }, maxInterval * 1000);\n }\n\n private async runSync(): Promise {\n this.timeout && this.clearTimeout(this.timeout);\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n self.lastUpdated = new Date().getTime();\n await this.scheduler.run();\n this.timeout = this.setTimeout(async () => {\n await this.runSync();\n }, 1000);\n }\n\n /**\n * Is called when adapter shuts down - callback has to be called under any circumstances!\n */\n private onUnload(callback: () => void): void {\n try {\n this.setState('info.connection', false, true);\n this.timeout && this.clearTimeout(this.timeout);\n this.watchdogInterval && this.clearInterval(this.watchdogInterval);\n this.device.close();\n callback();\n } catch (e) {\n callback();\n }\n }\n\n /**\n * Is called if a subscribed state changes\n */\n private onStateChange(id: string, state: ioBroker.State | null | undefined): void {\n if (state) {\n // The state was changed\n this.log.info(`state ${id} changed: ${state.val} (ack = ${state.ack})`);\n } else {\n // The state was deleted\n this.log.info(`state ${id} deleted`);\n }\n }\n}\n\nif (require.main !== module) {\n // Export the constructor in compact mode\n module.exports = (options: Partial | undefined) => new Sun2000Modbus(options);\n} else {\n // otherwise start the instance directly\n (() => new Sun2000Modbus())();\n}\n"], - "mappings": "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", + "sourcesContent": ["/*\n * Created with @iobroker/create-adapter v2.5.0\n */\n\n// The adapter-core module gives you access to the core ioBroker functions\n// you need to create an adapter\nimport * as utils from '@iobroker/adapter-core';\n\n// Load your modules here, e.g.:\nimport {InverterStates, UpdateIntervalID} from './lib/states';\nimport {ModbusDevice} from './lib/modbus/modbus_device';\nimport {Scheduler} from './lib/scheduler';\n\nclass Sun2000Modbus extends utils.Adapter {\n\n private device!: ModbusDevice;\n private timeout: any = null;\n private watchdogInterval: any = null;\n private states!: InverterStates;\n private scheduler: Scheduler;\n private lastUpdated!: number;\n\n public constructor(options: Partial = {}) {\n super({\n ...options,\n name: 'sun2000-modbus',\n });\n this.scheduler = new Scheduler(this);\n this.on('ready', this.onReady.bind(this));\n //this.on('stateChange', this.onStateChange.bind(this));\n this.on('unload', this.onUnload.bind(this));\n }\n\n /**\n * Is called when databases are connected and adapter received configuration.\n */\n private async onReady(): Promise {\n // Initialize your adapter here\n\n this.states = new InverterStates({intervals: [this.config.updateIntervalHigh, this.config.updateIntervalHigh, this.config.updateIntervalHigh]});\n\n // The adapters config (in the instance object everything under the attribute \"native\") is accessible via\n // this.config:\n await this.setStateAsync('info.ip', {val: this.config.address, ack: true});\n await this.setStateAsync('info.port', {val: this.config.port, ack: true});\n await this.setStateAsync('info.unitID', {val: this.config.modbusUnitId, ack: true});\n await this.setStateAsync('info.modbusUpdateIntervalHigh', {val: this.config.updateIntervalHigh, ack: true});\n await this.setStateAsync('info.modbusUpdateIntervalLow', {val: this.config.updateIntervalLow, ack: true});\n\n this.device = new ModbusDevice(this.config.address, this.config.port, this.config.modbusUnitId);\n\n this.log.info('Create states');\n await this.states.createStates(this);\n this.log.info('Update initial states');\n await this.states.updateStates(this, this.device); // no recurring update\n\n if (this.device.isConnected()) {\n await this.setStateAsync('info.connection', true, true);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n\n this.scheduler.addInterval('HIGH', this.config.updateIntervalHigh, async () => {\n return this.states.updateStates(self, this.device, UpdateIntervalID.HIGH);\n });\n this.scheduler.addInterval('LOW', this.config.updateIntervalLow, async () => {\n const countHigh = await this.states.updateStates(self, this.device, UpdateIntervalID.HIGH);\n const countLow = await this.states.updateStates(self, this.device, UpdateIntervalID.LOW);\n return Promise.resolve(countHigh + countLow)\n });\n\n this.scheduler.init();\n\n this.log.info('Start fetching data from inverter');\n await this.runSync();\n await this.runWatchDog();\n\n }\n\n private async runWatchDog(): Promise {\n this.watchdogInterval && this.clearInterval(this.watchdogInterval);\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n this.log.info('Start watchdog');\n const maxInterval = Math.max(this.config.updateIntervalHigh, this.config.updateIntervalLow)\n this.log.info(`Max interval: [${maxInterval}]`);\n this.watchdogInterval = this.setInterval(async () => {\n const timeSinceLastUpdate = (new Date().getTime() - self.lastUpdated) / 1000;\n this.log.debug(`Watchdog: ${timeSinceLastUpdate}`)\n if (timeSinceLastUpdate > 2 * maxInterval) {\n this.log.info(`Re-trigger sync... timeoutID: ${self.timeout}`)\n await this.runSync();\n }\n }, maxInterval * 1000);\n }\n\n private async runSync(): Promise {\n this.timeout && this.clearTimeout(this.timeout);\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n self.lastUpdated = new Date().getTime();\n await this.scheduler.run();\n this.timeout = this.setTimeout(async () => {\n await this.runSync();\n }, 1000);\n }\n\n /**\n * Is called when adapter shuts down - callback has to be called under any circumstances!\n */\n private onUnload(callback: () => void): void {\n try {\n this.setState('info.connection', false, true);\n this.timeout && this.clearTimeout(this.timeout);\n this.watchdogInterval && this.clearInterval(this.watchdogInterval);\n this.device.close();\n callback();\n } catch (e) {\n callback();\n }\n }\n\n /**\n * Is called if a subscribed state changes.\n * Not used yet. But will be used in future to set certain states.\n */\n private onStateChange(id: string, state: ioBroker.State | null | undefined): void {\n if (state) {\n // The state was changed\n this.log.info(`state ${id} changed: ${state.val} (ack = ${state.ack})`);\n } else {\n // The state was deleted\n this.log.info(`state ${id} deleted`);\n }\n }\n}\n\nif (require.main !== module) {\n // Export the constructor in compact mode\n module.exports = (options: Partial | undefined) => new Sun2000Modbus(options);\n} else {\n // otherwise start the instance directly\n (() => new Sun2000Modbus())();\n}\n"], + "mappings": "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", "names": [] } diff --git a/io-package.json b/io-package.json index b580fd1..662644a 100644 --- a/io-package.json +++ b/io-package.json @@ -79,44 +79,6 @@ "admin": ">=5.1.13" } ], - "adminColumns": [ - { - "name": { - "en": "Inverter Address", - "de": "Wechselrichter Adresse" - }, - "path": "native.address", - "width": 500, - "align": "left" - }, - { - "name": { - "en": "Port", - "de": "Port" - }, - "path": "native.port", - "width": 100, - "align": "left" - }, - { - "name": { - "en": "Modbus unitID", - "de": "Modbus unitID" - }, - "path": "native.modbusUnitId", - "width": 100, - "align": "left" - }, - { - "name": { - "en": "Update interval fast", - "de": "Update Intervall Schnell" - }, - "path": "native.updateIntervalHigh", - "width": 100, - "align": "left" - } - ], "plugins": { "sentry": { "dsn": "https://37d37e6a0b134349fc81d3aac954c30b@o123466.ingest.sentry.io/4505792569868288" @@ -195,7 +157,7 @@ "zh-cn": "目标" }, "type": "string", - "role": "indicator.ip", + "role": "info.ip", "read": true, "write": false, "desc": "Inverter IP address" @@ -219,7 +181,7 @@ "zh-cn": "蒙德港" }, "type": "number", - "role": "indicator.port", + "role": "info.port", "read": true, "write": false, "desc": "Inverter modbus port" @@ -234,7 +196,7 @@ "de": "Modbus unit ID" }, "type": "number", - "role": "indicator.id", + "role": "value", "read": true, "write": false, "desc": "Inverter modbus unit id" @@ -260,7 +222,7 @@ "type": "number", "role": "value", "read": true, - "write": true, + "write": false, "desc": "High inverter modbus update interval", "unit": "sec" } @@ -285,7 +247,7 @@ "type": "number", "role": "value", "read": true, - "write": true, + "write": false, "desc": "Low inverter modbus update interval", "unit": "sec" } @@ -298,7 +260,7 @@ "en": "Total power use", "de": "Gesamtverbrauch" }, - "role": "value", + "role": "value.power", "type": "number", "unit": "W", "read": true, @@ -324,7 +286,6 @@ "uk": "Дані зберігання", "zh-cn": "储存数据" }, - "role": "info", "read": true, "write": false, "desc": "Storage 'realtime' data" @@ -341,7 +302,7 @@ }, "type": "number", "unit": "W", - "role": "value", + "role": "value.power", "read": true, "write": false, "desc": "Calculated: Only 0 and positive values from chargeDischargePower" @@ -358,7 +319,7 @@ }, "type": "number", "unit": "W", - "role": "value", + "role": "value.power", "read": true, "write": false, "desc": "Calculated: Only 0 and negative values from chargeDischargePower" @@ -381,8 +342,10 @@ "pl": "Grid", "uk": "Сітка", "zh-cn": "Grid" - } + }, + "desc": "Grid data" }, + "native": {} }, { @@ -395,7 +358,7 @@ }, "type": "number", "unit": "W", - "role": "value", + "role": "value.power", "read": true, "write": false, "desc": "Calculated: Only 0 and positive values from grid.activePower" @@ -412,7 +375,7 @@ }, "type": "number", "unit": "W", - "role": "value", + "role": "value.power", "read": true, "write": false, "desc": "Calculated: Only 0 and negative values from grid.activePower" diff --git a/src/lib/states.ts b/src/lib/states.ts index 7a86b66..29ac23d 100644 --- a/src/lib/states.ts +++ b/src/lib/states.ts @@ -63,23 +63,23 @@ export class InverterStates { this.dataFields = [ // initial fields (no interval set) - no repetitive update { - state: {id: 'info.model', name: 'Model', type: 'string', role: 'state'}, + state: {id: 'info.model', name: 'Model', type: 'string', role: 'info.name'}, register: {reg: 30000, type: ModbusDatatype.string, length: 15} }, { - state: {id: 'info.modelID', name: 'Model ID', type: 'number', role: 'state'}, + state: {id: 'info.modelID', name: 'Model ID', type: 'number', role: 'info.hardware'}, register: {reg: 30070, type: ModbusDatatype.uint16, length: 1} }, { - state: {id: 'info.serialNumber', name: 'Serial number', type: 'string', role: 'state'}, + state: {id: 'info.serialNumber', name: 'Serial number', type: 'string', role: 'info.serial'}, register: {reg: 30015, type: ModbusDatatype.string, length: 10} }, { - state: {id: 'info.ratedPower', name: 'Rated power', type: 'number', unit: 'W', role: 'state'}, + state: {id: 'info.ratedPower', name: 'Rated power', type: 'number', unit: 'W', role: 'value.power'}, register: {reg: 30073, type: ModbusDatatype.int32, length: 2} }, { - state: {id: 'info.numberMPPTrackers', name: 'Number of MPP trackers', type: 'number', unit: '', role: 'state'}, + state: {id: 'info.numberMPPTrackers', name: 'Number of MPP trackers', type: 'number', unit: '', role: 'value'}, register: {reg: 30072, type: ModbusDatatype.uint16, length: 1, gain: 1} }, @@ -87,43 +87,43 @@ export class InverterStates { // inverter { interval: UpdateIntervalID.HIGH, - state: {id: 'activePower', name: 'Active power', type: 'number', unit: 'W', role: 'value.power', desc: 'Power currently used'}, + state: {id: 'activePower', name: 'Active power', type: 'number', unit: 'W', role: 'value.power.active', desc: 'Power currently used'}, register: {reg: 32080, type: ModbusDatatype.int32, length: 2} }, { interval: UpdateIntervalID.HIGH, - state: {id: 'inputPower', name: 'Input power', type: 'number', unit: 'W', role: 'value.power', desc: 'Power from PV'}, + state: {id: 'inputPower', name: 'Input power', type: 'number', unit: 'W', role: 'value.power.produced', desc: 'Power from PV'}, register: {reg: 32064, type: ModbusDatatype.int32, length: 2} }, { interval: UpdateIntervalID.LOW, - state: {id: 'peakActivePowerCurrenDay', name: 'Peak active power of current day', type: 'number', unit: 'W', role: 'value.power.max'}, + state: {id: 'peakActivePowerCurrenDay', name: 'Peak active power of current day', type: 'number', unit: 'W', role: 'value.power'}, register: {reg: 32078, type: ModbusDatatype.int32, length: 2} }, { interval: UpdateIntervalID.LOW, - state: {id: 'efficiency', name: 'Efficiency', type: 'number', unit: '%', role: 'value.efficiency'}, + state: {id: 'efficiency', name: 'Efficiency', type: 'number', unit: '%', role: 'value'}, register: {reg: 32086, type: ModbusDatatype.uint16, length: 1, gain: 100} }, { interval: UpdateIntervalID.LOW, - state: {id: 'internalTemperature', name: 'Internal temperature', type: 'number', unit: '°C', role: 'value.temp'}, + state: {id: 'internalTemperature', name: 'Internal temperature', type: 'number', unit: '°C', role: 'value.temperature'}, register: {reg: 32087, type: ModbusDatatype.int16, length: 1, gain: 10} }, { interval: UpdateIntervalID.LOW, - state: {id: 'deviceStatus', name: 'Device status', type: 'string', unit: '', role: 'value.status'}, + state: {id: 'deviceStatus', name: 'Device status', type: 'string', unit: '', role: 'info.status'}, register: {reg: 32089, type: ModbusDatatype.uint16, length: 1}, mapper: value => Promise.resolve(InverterStatus[value]) }, { interval: UpdateIntervalID.LOW, - state: {id: 'accumulatedEnergyYield', name: 'Accumulated energy yield', type: 'number', unit: 'kWh', role: 'value'}, + state: {id: 'accumulatedEnergyYield', name: 'Accumulated energy yield', type: 'number', unit: 'kWh', role: 'value.energy.produced'}, register: {reg: 32106, type: ModbusDatatype.uint32, length: 2, gain: 100}, }, { interval: UpdateIntervalID.LOW, - state: {id: 'dailyEnergyYield', name: 'Daily energy yield', type: 'number', unit: 'kWh', role: 'value'}, + state: {id: 'dailyEnergyYield', name: 'Daily energy yield', type: 'number', unit: 'kWh', role: 'value.energy'}, register: {reg: 32114, type: ModbusDatatype.uint32, length: 2, gain: 100} }, { @@ -151,13 +151,13 @@ export class InverterStates { // storage { interval: UpdateIntervalID.LOW, - state: {id: 'storage.runningState', name: 'Running state', type: 'string', role: 'value'}, + state: {id: 'storage.runningState', name: 'Running state', type: 'string', role: 'info.status'}, register: {reg: 37762, type: ModbusDatatype.uint16, length: 1}, mapper: value => Promise.resolve(StorageStatus[value]) }, { interval: UpdateIntervalID.HIGH, - state: {id: 'storage.stateOfCapacity', name: 'State of capacity', type: 'number', unit: '%', role: 'value.capacity', desc: 'SOC'}, + state: {id: 'storage.stateOfCapacity', name: 'State of capacity', type: 'number', unit: '%', role: 'value.battery', desc: 'SOC'}, register: {reg: 37760, type: ModbusDatatype.uint16, length: 1, gain: 10} }, { @@ -173,12 +173,12 @@ export class InverterStates { }, { interval: UpdateIntervalID.LOW, - state: { id: 'storage.CurrentDayChargeCapacity', name: 'CurrentDayChargeCapacity', type: 'number', unit: 'kWh', role: 'value.power', desc: 'TBD' }, + state: { id: 'storage.CurrentDayChargeCapacity', name: 'CurrentDayChargeCapacity', type: 'number', unit: 'kWh', role: 'value.energy', desc: 'TBD' }, register: { reg: 37015, type: ModbusDatatype.uint32, length: 2, gain: 100 } }, { interval: UpdateIntervalID.LOW, - state: { id: 'storage.CurrentDayDischargeCapacity', name: 'CurrentDayDischargeCapacity', type: 'number', unit: 'kWh', role: 'value.power', desc: 'TBD' }, + state: { id: 'storage.CurrentDayDischargeCapacity', name: 'CurrentDayDischargeCapacity', type: 'number', unit: 'kWh', role: 'value.energy', desc: 'TBD' }, register: { reg: 37786, type: ModbusDatatype.uint32, length: 2, gain: 100 } }, @@ -186,13 +186,13 @@ export class InverterStates { // grid (meter) { interval: UpdateIntervalID.LOW, - state: {id: 'grid.meterStatus', name: 'Meter status', type: 'string', role: 'value.status'}, + state: {id: 'grid.meterStatus', name: 'Meter status', type: 'string', role: 'info.status'}, register: {reg: 37100, type: ModbusDatatype.uint16, length: 1}, mapper: value => Promise.resolve(MeterStatus[value]) }, { interval: UpdateIntervalID.HIGH, - state: {id: 'grid.activePower', name: 'Active power', type: 'number', role: 'value.power', unit: 'W', desc: '(>0 feed-in to the power grid, <0: supply from the power grid)'}, + state: {id: 'grid.activePower', name: 'Active power', type: 'number', role: 'value.power.active', unit: 'W', desc: '(>0 feed-in to the power grid, <0: supply from the power grid)'}, register: {reg: 37113, type: ModbusDatatype.int32, length: 2}, postUpdateHook: async (adapter, value): Promise> => { return Promise.resolve(new Map([ @@ -203,12 +203,12 @@ export class InverterStates { }, { interval: UpdateIntervalID.LOW, - state: {id: 'grid.reactivePower', name: 'Reactive power', type: 'number', role: 'value.power', unit: 'W'}, + state: {id: 'grid.reactivePower', name: 'Reactive power', type: 'number', role: 'value.power.reactive', unit: 'W'}, register: {reg: 37115, type: ModbusDatatype.int32, length: 2}, }, { interval: UpdateIntervalID.LOW, - state: {id: 'grid.powerFactor', name: 'Power factor', type: 'number', role: 'value.power.factor', unit: ''}, + state: {id: 'grid.powerFactor', name: 'Power factor', type: 'number', role: 'value', unit: ''}, register: {reg: 37117, type: ModbusDatatype.int16, length: 1, gain: 1000}, }, { @@ -250,12 +250,12 @@ export class InverterStates { { interval: UpdateIntervalID.LOW, - state: {id: 'grid.positiveActivePower', name: 'Positive active power', type: 'number', role: 'value.power', unit: 'kWh', desc: 'Electricity fed by the inverter to the power grid.'}, + state: {id: 'grid.positiveActivePower', name: 'Positive active power', type: 'number', role: 'value.power.active', unit: 'kWh', desc: 'Electricity fed by the inverter to the power grid.'}, register: {reg: 37119, type: ModbusDatatype.int32, length: 2, gain: 100}, }, { interval: UpdateIntervalID.LOW, - state: {id: 'grid.reverseActivePower', name: 'Reverse active power', type: 'number', role: 'value.power', unit: 'kWh', desc: 'Power supplied from the power grid.'}, + state: {id: 'grid.reverseActivePower', name: 'Reverse active power', type: 'number', role: 'value.power.active', unit: 'kWh', desc: 'Power supplied from the power grid.'}, register: {reg: 37121, type: ModbusDatatype.int32, length: 2, gain: 100}, }, ]; @@ -280,7 +280,7 @@ export class InverterStates { public async createStates(adapter: AdapterInstance): Promise { for (const field of this.dataFields) { const state = field.state - await adapter.setObjectAsync(state.id, { + adapter.extendObject(state.id, { type: 'state', common: { name: state.name, diff --git a/src/main.ts b/src/main.ts index 91a21da..e7e617d 100644 --- a/src/main.ts +++ b/src/main.ts @@ -27,7 +27,7 @@ class Sun2000Modbus extends utils.Adapter { }); this.scheduler = new Scheduler(this); this.on('ready', this.onReady.bind(this)); - this.on('stateChange', this.onStateChange.bind(this)); + //this.on('stateChange', this.onStateChange.bind(this)); this.on('unload', this.onUnload.bind(this)); } @@ -122,7 +122,8 @@ class Sun2000Modbus extends utils.Adapter { } /** - * Is called if a subscribed state changes + * Is called if a subscribed state changes. + * Not used yet. But will be used in future to set certain states. */ private onStateChange(id: string, state: ioBroker.State | null | undefined): void { if (state) {