Koenkk / zigbee2mqtt

Zigbee 🐝 to MQTT bridge 🌉, get rid of your proprietary Zigbee bridges 🔨
https://www.zigbee2mqtt.io
GNU General Public License v3.0
11.67k stars 1.64k forks source link

[New device support]: EMIZB-141 Power Meter #19042

Open lSh4dowl opened 11 months ago

lSh4dowl commented 11 months ago

Link

https://www.amazon.de/Electricity-Zählerauslesung-Energieverbrauchsüberwachung-LED-Impulsen-funktioniert/dp/B0CGVB6LGC

Database entry

{"id":54,"type":"EndDevice","ieeeAddr":"0x0015bc001b100a56","nwkAddr":51420,"manufId":4117,"manufName":"frient A/S","powerSource":"Battery","modelId":"EMIZB-141","epList":[1,2],"endpoints":{"1":{"profId":49353,"epId":1,"devId":1,"inClusterList":[5,6],"outClusterList":[],"clusters":{},"binds":[],"configuredReportings":[],"meta":{}},"2":{"profId":260,"epId":2,"devId":83,"inClusterList":[0,1,3,32,1794,2817,2821],"outClusterList":[3,10,25],"clusters":{"genBasic":{"attributes":{}},"genPollCtrl":{"attributes":{"checkinInterval":14400}},"seMetering":{"attributes":{"currentSummDelivered":[0],"instantaneousDemand":354,"multiplier":1,"divisor":1000,"develcoPulseConfiguration":10000,"develcoInterfaceMode":0}}},"binds":[{"cluster":32,"type":"endpoint","deviceIeeeAddress":"0x00124b0024c2ad1c","endpointID":1},{"cluster":1794,"type":"endpoint","deviceIeeeAddress":"0x00124b0024c2ad1c","endpointID":1}],"configuredReportings":[{"cluster":1794,"attrId":1024,"minRepIntval":5,"maxRepIntval":3600,"repChange":1}],"meta":{}}},"dateCode":"2023-09-06 11:54","zclVersion":7,"interviewCompleted":true,"meta":{"configured":-570313272},"lastSeen":1695324832904,"defaultSendRequestWhen":"active","checkinInterval":3600}

Comments

It works reasonable, but shows no battery for example. I basically just copied an old Version of the previous version (https://www.zigbee2mqtt.io/devices/ZHEMI101.html) I only linked a German Amazon Page, because the Vendor doesn't have a site for the product yet (this is the old version: https://frient.com/products/electricity-meter-interface/)

External converter

const exposes = require('zigbee-herdsman-converters/lib/exposes');
const fz = {...require('zigbee-herdsman-converters/converters/fromZigbee'), legacy: require('zigbee-herdsman-converters/lib/legacy').fromZigbee};
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const constants = require('zigbee-herdsman-converters/lib/constants');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
const globalStore = require('zigbee-herdsman-converters/lib/store');
const utils = require('zigbee-herdsman-converters/lib/utils');
const ota = require('zigbee-herdsman-converters/lib/ota');
const e = exposes.presets;
const ea = exposes.access;

// develco specific cosntants
const manufacturerOptions = {manufacturerCode: 0x1015};

/* MOSZB-1xx - ledControl - bitmap8 - r/w
 * 0x00 Disable LED when movement is detected.
 * 0x01 Enables periodic fault flashes. These flashes are used to indicate e.g. low battery level.
 * 0x02 Enables green application defined LED. This is e.g. used to indicate motion detection.
 * Default value 0xFF ( seems to be fault + motion)
 */
const develcoLedControlMap = {
    0x00: 'off',
    0x01: 'fault_only',
    0x02: 'motion_only',
    0xFF: 'both',
};

// develco specific convertors
const develco = {
    configure: {
        read_sw_hw_version: async (device, logger) => {
            for (const ep of device.endpoints) {
                if (ep.supportsInputCluster('genBasic')) {
                    try {
                        const data = await ep.read('genBasic', ['develcoPrimarySwVersion', 'develcoPrimaryHwVersion'],
                            manufacturerOptions);

                        if (data.hasOwnProperty('develcoPrimarySwVersion')) {
                            device.softwareBuildID = data.develcoPrimarySwVersion.join('.');
                        }

                        if (data.hasOwnProperty('develcoPrimaryHwVersion')) {
                            device.hardwareVersion = data.develcoPrimaryHwVersion.join('.');
                        }
                    } catch (error) {/* catch timeouts of sleeping devices */}
                    break;
                }
            }
        },
    },
    fz: {
        // Some Develco devices report strange values sometimes
        // https://github.com/Koenkk/zigbee2mqtt/issues/13329
        electrical_measurement: {
            ...fz.electrical_measurement,
            convert: (model, msg, publish, options, meta) => {
                if (msg.data.rmsVoltage !== 0xFFFF && msg.data.rmsCurrent !== 0xFFFF && msg.data.activePower !== -0x8000) {
                    return fz.electrical_measurement.convert(model, msg, publish, options, meta);
                }
            },
        },
        device_temperature: {
            ...fz.device_temperature,
            convert: (model, msg, publish, options, meta) => {
                if (msg.data.currentTemperature !== -0x8000) {
                    return fz.device_temperature.convert(model, msg, publish, options, meta);
                }
            },
        },
        temperature: {
            ...fz.temperature,
            convert: (model, msg, publish, options, meta) => {
                if (msg.data.measuredValue !== -0x8000 && msg.data.measuredValue !== 0xFFFF) {
                    return fz.temperature.convert(model, msg, publish, options, meta);
                }
            },
        },
        metering: {
            ...fz.metering,
            convert: (model, msg, publish, options, meta) => {
                if (msg.data.instantaneousDemand !== -0x800000) {
                    return fz.metering.convert(model, msg, publish, options, meta);
                }
            },
        },
        pulse_configuration: {
            cluster: 'seMetering',
            type: ['attributeReport', 'readResponse'],
            convert: (model, msg, publish, options, meta) => {
                const result = {};
                if (msg.data.hasOwnProperty('develcoPulseConfiguration')) {
                    result[utils.postfixWithEndpointName('pulse_configuration', msg, model, meta)] =
                        msg.data['develcoPulseConfiguration'];
                }

                return result;
            },
        },
        interface_mode: {
            cluster: 'seMetering',
            type: ['attributeReport', 'readResponse'],
            convert: (model, msg, publish, options, meta) => {
                const result = {};
                if (msg.data.hasOwnProperty('develcoInterfaceMode')) {
                    result[utils.postfixWithEndpointName('interface_mode', msg, model, meta)] =
                        constants.develcoInterfaceMode.hasOwnProperty(msg.data['develcoInterfaceMode']) ?
                            constants.develcoInterfaceMode[msg.data['develcoInterfaceMode']] :
                            msg.data['develcoInterfaceMode'];
                }
                if (msg.data.hasOwnProperty('status')) {
                    result['battery_low'] = (msg.data.status & 2) > 0;
                    result['check_meter'] = (msg.data.status & 1) > 0;
                }

                return result;
            },
        },
        fault_status: {
            cluster: 'genBinaryInput',
            type: ['attributeReport', 'readResponse'],
            convert: (model, msg, publish, options, meta) => {
                const result = {};
                if (msg.data.hasOwnProperty('reliability')) {
                    const lookup = {0: 'no_fault_detected', 7: 'unreliable_other', 8: 'process_error'};
                    result.reliability = lookup[msg.data['reliability']];
                }
                if (msg.data.hasOwnProperty('statusFlags')) {
                    result.fault = (msg.data['statusFlags']===1);
                }
                return result;
            },
        },
        voc: {
            cluster: 'develcoSpecificAirQuality',
            type: ['attributeReport', 'readResponse'],
            options: [exposes.options.precision('voc'), exposes.options.calibration('voc')],
            convert: (model, msg, publish, options, meta) => {
                // from Sensirion_Gas_Sensors_SGP3x_TVOC_Concept.pdf
                // "The mean molar mass of this mixture is 110 g/mol and hence,
                // 1 ppb TVOC corresponds to 4.5 μg/m3."
                const vocPpb = parseFloat(msg.data['measuredValue']);
                const voc = vocPpb * 4.5;
                const vocProperty = utils.postfixWithEndpointName('voc', msg, model, meta);

                // from aqszb-110-technical-manual-air-quality-sensor-04-08-20.pdf page 6, section 2.2 voc
                // this contains a ppb to level mapping table.
                let airQuality;
                const airQualityProperty = utils.postfixWithEndpointName('air_quality', msg, model, meta);
                if (vocPpb <= 65) {
                    airQuality = 'excellent';
                } else if (vocPpb <= 220) {
                    airQuality = 'good';
                } else if (vocPpb <= 660) {
                    airQuality = 'moderate';
                } else if (vocPpb <= 2200) {
                    airQuality = 'poor';
                } else if (vocPpb <= 5500) {
                    airQuality = 'unhealthy';
                } else if (vocPpb > 5500) {
                    airQuality = 'out_of_range';
                } else {
                    airQuality = 'unknown';
                }
                return {[vocProperty]: utils.calibrateAndPrecisionRoundOptions(voc, options, 'voc'), [airQualityProperty]: airQuality};
            },
        },
        voc_battery: {
            cluster: 'genPowerCfg',
            type: ['attributeReport', 'readResponse'],
            convert: (model, msg, publish, options, meta) => {
                /*
                 * Per the technical documentation for AQSZB-110:
                 * To detect low battery the system can monitor the "BatteryVoltage" by setting up a reporting interval of every 12 hour.
                 * When a voltage of 2.5V is measured the battery should be replaced.
                 * Low batt LED indication–RED LED will blink twice every 60 second.
                 */
                const result = fz.battery.convert(model, msg, publish, options, meta);
                result.battery_low = (result.voltage <= 2500);
                return result;
            },
        },
        led_control: {
            cluster: 'genBasic',
            type: ['attributeReport', 'readResponse'],
            options: [],
            convert: (model, msg, publish, options, meta) => {
                const state = {};

                if (msg.data.hasOwnProperty('develcoLedControl')) {
                    state['led_control'] = develcoLedControlMap[msg.data['develcoLedControl']];
                }

                return state;
            },
        },
        ias_occupancy_timeout: {
            cluster: 'ssIasZone',
            type: ['attributeReport', 'readResponse'],
            options: [],
            convert: (model, msg, publish, options, meta) => {
                const state = {};

                if (msg.data.hasOwnProperty('develcoAlarmOffDelay')) {
                    state['occupancy_timeout'] = msg.data['develcoAlarmOffDelay'];
                }

                return state;
            },
        },
        input: {
            cluster: 'genBinaryInput',
            type: ['attributeReport', 'readResponse'],
            convert: (model, msg, publish, options, meta) => {
                const result = {};
                if (msg.data.hasOwnProperty('presentValue')) {
                    const value = msg.data['presentValue'];
                    result[utils.postfixWithEndpointName('input', msg, model, meta)] = value == 1;
                }
                return result;
            },
        },
    },
    tz: {
        pulse_configuration: {
            key: ['pulse_configuration'],
            convertSet: async (entity, key, value, meta) => {
                await entity.write('seMetering', {'develcoPulseConfiguration': value}, manufacturerOptions);
                return {readAfterWriteTime: 200, state: {'pulse_configuration': value}};
            },
            convertGet: async (entity, key, meta) => {
                await entity.read('seMetering', ['develcoPulseConfiguration'], manufacturerOptions);
            },
        },
        interface_mode: {
            key: ['interface_mode'],
            convertSet: async (entity, key, value, meta) => {
                const payload = {'develcoInterfaceMode': utils.getKey(constants.develcoInterfaceMode, value, undefined, Number)};
                await entity.write('seMetering', payload, manufacturerOptions);
                return {readAfterWriteTime: 200, state: {'interface_mode': value}};
            },
            convertGet: async (entity, key, meta) => {
                await entity.read('seMetering', ['develcoInterfaceMode'], manufacturerOptions);
            },
        },
        current_summation: {
            key: ['current_summation'],
            convertSet: async (entity, key, value, meta) => {
                await entity.write('seMetering', {'develcoCurrentSummation': value}, manufacturerOptions);
                return {state: {'current_summation': value}};
            },
        },
        led_control: {
            key: ['led_control'],
            convertSet: async (entity, key, value, meta) => {
                const ledControl = utils.getKey(develcoLedControlMap, value, value, Number);
                await entity.write('genBasic', {'develcoLedControl': ledControl}, manufacturerOptions);
                return {state: {led_control: value}};
            },
            convertGet: async (entity, key, meta) => {
                await entity.read('genBasic', ['develcoLedControl'], manufacturerOptions);
            },
        },
        ias_occupancy_timeout: {
            key: ['occupancy_timeout'],
            convertSet: async (entity, key, value, meta) => {
                let timeoutValue = value;
                if (timeoutValue < 20) {
                    meta.logger.warn(`Minimum occupancy_timeout is 20, using 20 instead of ${timeoutValue}!`);
                    timeoutValue = 20;
                }
                await entity.write('ssIasZone', {'develcoAlarmOffDelay': timeoutValue}, manufacturerOptions);
                return {state: {occupancy_timeout: timeoutValue}};
            },
            convertGet: async (entity, key, meta) => {
                await entity.read('ssIasZone', ['develcoAlarmOffDelay'], manufacturerOptions);
            },
        },
        input: {
            key: ['input'],
            convertGet: async (entity, key, meta) => {
                await entity.read('genBinaryInput', ['presentValue']);
            },
        },
    },
};

const definition = {
    zigbeeModel: ['EMIZB-141'], // The model ID from: Device with modelID 'lumi.sens' is not supported.
    model: 'EMIZB-141', // Vendor model number, look on the device for a model number
    vendor: 'frient A/S', // Vendor of the device (only used for documentation and startup logging)
    description: 'frient Powermeter', // Description of the device, copy from vendor site. (only used for documentation and startup logging)
    fromZigbee: [develco.fz.metering, develco.fz.pulse_configuration, develco.fz.interface_mode],
        toZigbee: [develco.tz.pulse_configuration, develco.tz.interface_mode, develco.tz.current_summation],
        endpoint: (device) => {
            return {'default': 2};
        },
        configure: async (device, coordinatorEndpoint, logger) => {
            const endpoint = device.getEndpoint(2);
            await reporting.bind(endpoint, coordinatorEndpoint, ['seMetering']);
            await reporting.instantaneousDemand(endpoint);
            await reporting.readMeteringMultiplierDivisor(endpoint);
        },
        exposes: [
            e.power(),
            e.energy(),
            e.battery_low(),
            exposes.numeric('pulse_configuration', ea.ALL).withValueMin(0).withValueMax(65535)
                .withDescription('Pulses per kwh. Default 1000 imp/kWh. Range 0 to 65535'),
            exposes.enum('interface_mode', ea.ALL,
                ['electricity', 'gas', 'water', 'kamstrup-kmp', 'linky', 'IEC62056-21', 'DSMR-2.3', 'DSMR-4.0'])
                .withDescription('Operating mode/probe'),
            exposes.numeric('current_summation', ea.SET)
                .withDescription('Current summation value sent to the display. e.g. 570 = 0,570 kWh').withValueMin(0)
                .withValueMax(268435455),
            exposes.binary('check_meter', ea.STATE, true, false)
                .withDescription('Is true if communication problem with meter is experienced'),
        ],
};

module.exports = definition;

Supported color modes

No response

Color temperature range

No response

penroseg commented 6 months ago

just switched to the newer convertor. Seems to work ok. But my battery is still reading 100% but the device is new so maybe that's accurate but I would have expected it to read around 98% or similar after 8 weeks.

{ "battery": 100, "battery_low": false, "energy": 1462.53, "interface_mode": "electricity", "linkquality": 51, "power": 1553, "pulse_configuration": 1000, "voltage": 3100, "check_meter": null, "current_summation": null }

Mine is showing 95% after 4+ months so I think it could be okay. Frient do say 2 years but that's at room temperature so likely less with winter weather but at least it's an indication. In general, I find most battery indicators on Zigbee devices are pretty rough and have seen them go from 60%+ to dead, but that's mainly on coin cells. It's a function of how they calculate based on the voltage but with that being so low anyway a tiny change can be a huge % drop.

I think the AA batteries ussd in this are much better at that so I am hoping that 12-15 months may be achievable.

jeppester commented 6 months ago

I set up the latest configuration posted and it works almost flawlessly (only issue is that the energy resets to 0 when I attempt to update it).

Thank you all for working this out!

As I'm an experienced programmer I might have a go at the resetting issue (I imagine it could have something to do with how the input value formatted). I can't promise much though as this type of programming is not something I'm intimately familiar with.

nivek1612 commented 6 months ago

Why do you want to update the energy ? The value to me is irrelevant I just want to know how much it has changed per day per hour etc

just curious

jeppester commented 6 months ago

Why do you want to update the energy ? The value to me is irrelevant I just want to know how much it has changed per day per hour etc

just curious

One might want to sync it with the display on the device it gets connected to.

I'm not personally going to need that, I mostly just don't like like that there's an input field that doesn't work. If resetting is all we can do, then the control should be button with a "reset" label instead.

nivek1612 commented 6 months ago

Why do you want to update the energy ? The value to me is irrelevant I just want to know how much it has changed per day per hour etc just curious

One might want to sync it with the display on the device it gets connected to.

I'm not personally going to need that, I mostly just don't like like that there's an input field that doesn't work. If resetting is all we can do, then the control should be button with a "reset" label instead.

Fair although my meter has different rates so there are two readings so not much use being able to synch it for me.

Datortarp5 commented 4 months ago

Hello team.

With all external converter, latest coordinator firmware and latest Z2M version I still have issues with this power meter. Looks like all working except Energy KwH field. Also what I discovered, all my powered zigbee devices fall offline if external converter is activated.

image

Bronti90 commented 3 months ago

Hi, sorry for picking up this old topic again. I purchased a EMIZB-141 a while ago and worked around the limited functionality myself, yesterday upgraded to lSh4dowl external converter and could fix wrong pulse config and not working energy variable by that - so first of all thanks for that help!

Nevertheless I am still facing the issue I initially had, after implementation of solar power plant, I do have negative power / supply to grid power in peak solar phases that are detected by EMIZB-141 as positive. So my energy dashboard looks weird and my overall electricity parameter in HomeAssistant needs to be corrected by supply grid manually (reading from meter and offsetting value in HomeAssistant).

Am I doing something wrong or is it simply not feasible to read negative values? I was reading about Tasmota IR readers which are capable to read supply power to grid and was assuming EMIZB-141 could do same. There is unfortunately no reasonable way to get WiFi to the electricity meter, so I am limited to Zigbee devices.

Apologies upfront, my coding skill are very basic to not existing. I tried to read and understand the code, but wasn't able to read the information I am looking for. Any help would be greatly appreciated.


My MQTT says following: { "battery": 100, "battery_low": false, "energy": 878.12, "interface_mode": "electricity", "linkquality": 63, "power": 216, "pulse_configuration": 5000, "voltage": 3000, "check_meter": null, "current_summation": null }


I am using HomeAssistant as below with latest MQTT integration. Core 2024.4.4 Supervisor 2024.04.4 Operating System 12.2 Frontend 20240404.2

mnaved37 commented 3 months ago

I got it working by changing the power sensor to energy sensor and then using that energy sensor to add to my energy grid. I used the helper - Integration - Riemann sum surgical - I tried both left and trapezoid - slight difference but not significant. I am now using the left integration sensor as my default. HA Then add anime and then use the power sensor to covert it to energy sensor and kWh. HA1

Now it is all working HA2

How that helps

nilsbyte commented 2 months ago

I wanted to add my experience after purchasing a EMIZB-141.

Home Assistant Core 2024.5.5 Zigbee2MQTT 1.37.1-1

Results:

My smart meter uses EN 62056-21 for optical communication but i can not change the interface mode. I get an error:

Publish 'set' 'interface_mode' to 'frient Electricity Meter 2 LED' failed: 'Error: ZCL command 0x0015bc001b100841/2 seMetering.write({"develcoInterfaceMode":258}, {"timeout":10000,"disableResponse":false,"disableRecovery":false,"disableDefaultResponse":true,"direction":0,"srcEndpoint":null,"reservedBits":0,"manufacturerCode":4117,"transactionSequenceNumber":null,"writeUndiv":false}) failed (Status 'INVALID_VALUE')'

Firmware for the devices is available at https://github.com/Develco-Products/frient_upgrade_images The firmware file for the EMIZB-141 is EMI2LED_3.1.2.zigbee. Maybe OTA is possible @lSh4dowl ? On the supported Hubs (Homey, Smart Things, Smart Home by Hornbach) it should be supported, stated by the frient website.

The detailed technical manual can be found here: https://www.develcoproducts.com/media/5110/emizb-141-technical-manual.pdf

Bronti90 commented 2 months ago

I got it working by changing the power sensor to energy sensor and then using that energy sensor to add to my energy grid. I used the helper - Integration - Riemann sum surgical - I tried both left and trapezoid - slight difference but not significant. I am now using the left integration sensor as my default.

Now it is all working

How that helps

But from what I see you do not feed energy right? So this is still an issue for me. I have correct values for power and energy both available for the device, but the power value is always plus - when my solar panel is supplying more than I use, it shows a positive value instead of an negative and by that destroys my energy evaluation. I have an work around which works ok. I monitor power of main devices by a script and calculate my current power estimation, compare this to the power value of the sensor and my solar power feed and depending on the conditions offset the sensor value by *-1. This approach works with a accurency of +/- 0.1 kWh a day and is good enough for the moment.

grafik

ebbeknudsen commented 2 months ago

Apologies for that @penroseg I left a bit of code on that adapter that shouldnt be there.

this is the screenshoot of my Adapter Screenshot 2024-02-10 at 20 30 32

The modification of the original adapter (the first one on this thread) is as simple as changing this

exposes: [ e.power(), e.energy(), e.battery_low(), exposes.numeric('pulse_configuration', ea.ALL).withValueMin(0).withValueMax(65535) .withDescription('Pulses per kwh. Default 1000 imp/kWh. Range 0 to 65535'), exposes.enum('interface_mode', ea.ALL, ['electricity', 'gas', 'water', 'kamstrup-kmp', 'linky', 'IEC62056-21', 'DSMR-2.3', 'DSMR-4.0']) .withDescription('Operating mode/probe'), exposes.numeric('current_summation', ea.SET) .withDescription('Current summation value sent to the display. e.g. 570 = 0,570 kWh').withValueMin(0) .withValueMax(268435455), exposes.binary('check_meter', ea.STATE, true, false) .withDescription('Is true if communication problem with meter is experienced'), ] to this (just add e.battery()) exposes: [ e.power(), e.energy(), e.battery_low(), e.battery(), exposes.numeric('pulse_configuration', ea.ALL).withValueMin(0).withValueMax(65535) .withDescription('Pulses per kwh. Default 1000 imp/kWh. Range 0 to 65535'), exposes.enum('interface_mode', ea.ALL, ['electricity', 'gas', 'water', 'kamstrup-kmp', 'linky', 'IEC62056-21', 'DSMR-2.3', 'DSMR-4.0']) .withDescription('Operating mode/probe'), exposes.numeric('current_summation', ea.SET) .withDescription('Current summation value sent to the display. e.g. 570 = 0,570 kWh').withValueMin(0) .withValueMax(268435455), exposes.binary('check_meter', ea.STATE, true, false) .withDescription('Is true if communication problem with meter is experienced'), ]

And this is the file (hopefully this time is right for everyone) emizb_141.txt

Again just change "txt" to "js"

This latest external converter by @jllarraz seems to work great for me, thanks!

image

nilsbyte commented 2 months ago

@jllarraz I can set the current summation but the energy value stays at "Null" kWh. I am thinking the energy value is calculated by the current power and not read by the sensor?

jllarraz commented 2 months ago

Unfortunately I dont have the answer to that. Maybe try to do a factory reset of the device (instructions are in this thread)

El mié, 5 jun 2024 a las 19:14, Nils @.***>) escribió:

@jllarraz https://github.com/jllarraz I can set the current summation but the energy value stays at "Null" kWh. I am thinking the energy value is calculated by the current power and not read by the sensor?

— Reply to this email directly, view it on GitHub https://github.com/Koenkk/zigbee2mqtt/issues/19042#issuecomment-2150671429, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABFQ575PNNQ4AX2U5APPOR3ZF5IR5AVCNFSM6AAAAAA5CBYLX6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNJQGY3TCNBSHE . You are receiving this because you were mentioned.Message ID: @.***>

djreaper2 commented 1 month ago

How to have the current kilowatts from the electricity meter recorded in the entity energy? thanks

Snímek obrazovky pořízený 2024-07-21 20-51-33

Stooovie commented 3 weeks ago

@jllarraz I can set the current summation but the energy value stays at "Null" kWh. I am thinking the energy value is calculated by the current power and not read by the sensor?

Same. Energy is Null even with the convertor.

EDIT: the original convertor code plus resetting the device helped. I see Energy now.