Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use power formatting factors for active power calculation #7978

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

bluemoehre
Copy link
Contributor

@bluemoehre bluemoehre commented Oct 17, 2024

Since some measurement devices provide calculation factors to format measured values correctly, we need to make them available. These factors may change with each report to adapt to the current power consumption range.
(This prevents spamming the network when the "minimum change" property of the reporting binding is set to a low value.)

Based on the specifications it should be the default to use the multiplier/divisors in the active power calculation.
Devices that report wrong factors or values must workaround the misbehavior via custom DDF.

DDF configs may use these attributes to guarantee API values are always in the same unit (Watts):

Item.val = Attr.val * R.item('state/power_multiplier').val / R.item('state/power_divisor').val;

Note

deCONZ defines its API units as Power in W, Consumption in wH, Current in mA

Example

ActivePower ACPowerMultiplier ACPowerDivisor Meaning Calculation Result
42 1 1000 42 mW 42 × 1 ÷ 1000 0.042 W
42 1 1 42 W 42 × 1 ÷ 1 42 W
42 1000 1 42 kW 42 × 1000 ÷ 1 42000 W

Screenshot

image

Specifications

4.9.2.2.6.10 ActivePower
Represents the single phase or Phase A, current demand of active power delivered or received at the premises, in Watts (W). Positive values indicate power delivered to the premises where negative values indicate power received from the premises

4.9.2.2.7.5 ACPowerMultiplier
Provides a value to be multiplied against the InstantaneousPower and ActivePower attributes. This attribute
must be used in conjunction with the ACPowerDivisor attribute. 0x0000 is an invalid value for this attribute.

4.9.2.2.7.6 ACPowerDivisor
Provides a value to be divided against the InstantaneousPower and ActivePower attributes. This attribute
must be used in conjunction with the ACPowerMultiplier attribute. 0x0000 is an invalid value for this attribute.

Copy link
Contributor

github-actions bot commented Oct 17, 2024

Hey @bluemoehre, thanks for your pull request!

Tip

Modified bundles can be downloaded here.
Relative expire date

DDB changes

Modified

  • eva/powermeter.json : Meter Reader ✔️

  • legrand/Contactor.json : Contactor ✔️

  • Jasco-GE/GE45856_wall_switch.json : GE ZigBee in-wall smart switch (45856GE) ✔️

  • bosch/plug_compact.json : Plug compact EU (BSP-FZ2) ✔️

  • develco/zhemi101_external_meter_interface.json : Electricity meter interface (ZHEMI101) ✔️

  • legrand/cable_outlet.json : Cable outlet 3000W (064879) ➰ (unvalidated)

  • lixee/zlinky_tic_standard_mono_base.json : ZLinky_TIC mode standard base ✔️

  • immax/07048L_smart_plug.json : Neo smart plug (07048L) ✔️

  • lixee/zlinky_tic_historique_mono_hphc.json : ZLinky_TIC mode historique HPHC ✔️

  • lixee/zlinky_tic_historique_mono_base.json : ZLinky_TIC mode historique base ✔️

  • sengled/e1c-nb7.json : Smart plug with power monitoring (E1C-NB7) ✔️

  • sonoff/ck-bl702-swp-01(7020)_plug.json : Smart Plug (eWeLink) ✔️

  • third_reality/3RSP02028BZ_smart_plug.json : Smart plug (3RSP02028BZ) ✔️

  • tuya/_TZE204_ac0fhfiq_energy_meter.json : BiDirectional zigbee energy meter (TS0601) ✔️

  • develco/emizb-141_electricity_meter_interface_2.json : Electricity meter interface 2 EMIZB-141 ✔️

  • adeo/ldsenk02f_plug.json : Plug 16A ✔️

  • frient/emizb-141_electricity_meter_interface_2.json : Electricity meter interface 2 EMIZB-141 ✔️

  • lixee/zlinky_tic_histo_tri_hphc.json : ZLinky_TIC mode historique HPHC triphase ✔️

  • lixee/zlinky_tic_standard_tri_hphc.json : ZLinky_TIC mode standard HPHC triphase ✔️

  • robb_smarrt/rob_200-017-0_plug.json : Smart plug 3680W (ROB_200-017-0) ✔️

  • aubess/aubess_plug_TZ3000_hdopuwv6.json : Smart plug 16A EU (TS011F) ✔️

  • heiman/smartplug.json : Metering Plug (HS2SK) ✔️

  • innr/sp_234.json : Smart plug (SP 234) ✔️

  • innr/sp_120.json : Smart plug (SP 120) ✔️

  • innr/sp_240.json : Smart plug (SP 240) ✔️

  • niko/170-33505_170-33605_smart_socket.json : Smart socket (170-33505/170-33605) ✔️

  • sinope/sp2610zb_smart_switch.json : Smart in-wall outlet US (SP2610ZB) ✔️

  • tuya/_TZ3000_cehuw1lw_smartplug_EU.json : Standard plug (TS011F) ✔️

  • third_reality/3RSPE01044BZ_smart_plug.json : Smart plug ✔️

  • wiser/fuga_socket_outlet.json : LK Fuga Wiser wireless socket outlet 16A (545D6115) ✔️

  • wiser/smart-plug-single-16A.json : Wiser smart plug 16A (CCT711119) ✔️

  • wiser/socket-outlet-double-16A-connected.json : Elko smart socket double 16A plus PW (EKO09738) ✔️

  • xiaomi/xiaomi_dcm-k01_t2_dual_relay.json : Aqara Dual Relay Module T2 (DCM-K01) ✔️

  • blitzwolf/bw_shp13_smart_plug.json : Electricity metering 16A EU plug (BW-SHP13) ✔️

  • xiaomi/xiaomi_wp-p01d_h2_wall_outlet.json : Aqara wall outlet H2 EU (WP-P01D) ✔️

  • blitzwolf/bw_shp15_smart_plug.json : Power monitoring 16A 3680W EU plug (BW-SHP15) ✔️

  • develco/splzb-131_smart_plug.json : Smart plug mini type F - Schuko (SPLZB-131) ✔️

  • frient/splzb-131_smart_plug.json : Smart plug mini (SPLZB-131/SPLZB-134/SPLZB-141) ✔️

  • lidl/hg08673.json : SilverCrest smart plug (HG08673) ✔️

  • neo/NAS-WR01B_TS011F.json : Smart plug 16A with power monitoring EU (NAS-WR01B) ✔️

  • tuya/_TZ3000_TS011F_smart_plug.json : Smart plug power monitor (TS011F) ✔️

  • tuya/_TZ3000_typdpbpg_smart_plug_eu.json : Smart plug EU (TS011F) ✔️

  • tuya/_TZE200_byzdayie_din_enrgy_meter.json : Single phase 65A DIN rail smart energy meter (TS0601) ✔️

  • tuya/nous_a1z_smart_plug.json : Smart zigbee socket (A1Z) ✔️

  • xiaomi/xiaomi_zncz12lm_smart_plug.json : Smart plug (ZNCZ12LM) ✔️

  • namron/4512737_thermostat.json : Thermostat touch zigbee 16A (4512737/4512738) ✔️

  • xiaomi/xiaomi_lumi.relay.c2acn01.json : 2 way control module wireless relay ✔️

  • xiaomi/xiaomi_sp-euc01_smart_plug.json : Smart plug (SP-EUC01) ✔️

  • namron/5401395_heater.json : Panel heater 1000W (5401395/5401399) ✔️

  • xiaomi/xiaomi_ws-euk04_h1_switch.json : H1 dual rocker switch neutral wire (WS-EUK04) ✔️

  • xiaomi/xiaomi_zncz04lm_smart_plug_v24.json : Smart plug (ZNCZ04LM) ✔️

  • xiaomi/xiaomi_zncz04lm_smart_plug.json : Smart plug (ZNCZ04LM) ✔️

  • ubisys/s1_5501_s1r_5601.json : Power switch (S1 (5501)/S1-R (5601)) ✔️

  • ubisys/s2_5502.json : Power switch (S2 (5502)) ✔️

  • ubisys/s2r_5602.json : Power switch (S2-R (5602)) ✔️

  • xiaomi/xiaomi_ws-euk03_h1_switch.json : H1 single rocker switch neutral wire (WS-EUK03) ✔️

  • xiaomi/xiaomi_ssm-u01_t1_switch.json : T1 single rocker switch with neutral wire (SSM-U01) ✔️

  • bosch/bmct-slz_shutter_light_control2.json : Light and shutter control II (BMCT-SLZ) ✔️

  • ubisys/j1r_5602.json : Cover controller (J1-R (5602)) ✔️

  • ubisys/j1_5502.json : Cover controller (J1 (5502)) ✔️

  • icasa/ICZB-IW21D.json : Zigbee Dimmer PRO ✔️

  • ouellet/OTH4000-ZB.json : Smart thermostat (OTH4000-ZB) ✔️

  • sinope/th1124zb.json : Smart thermostat for electric heating (TH1123ZB/TH1124ZB) ✔️

  • ubisys/d1_5503_d1r_5603.json : Universal dimmer (D1 (5503)/D1-R (5603)) ✔️

Validation

Tip

Everything is fine !

🕧 Updated for commit 8d423a3

@bluemoehre
Copy link
Contributor Author

@ebaauw :

… so this wouldn’t require any C++ changes.

Just for safety: Won't these files interfere?

@bluemoehre bluemoehre changed the title add read-only attributes for power formatting factors respect dynamic power formatting factors for active power calculation Oct 17, 2024
@bluemoehre bluemoehre changed the title respect dynamic power formatting factors for active power calculation use power formatting factors for active power calculation Oct 18, 2024
@bluemoehre bluemoehre marked this pull request as ready for review October 18, 2024 13:14
@ebaauw
Copy link
Collaborator

ebaauw commented Oct 18, 2024

I wouldn't change the logic on the generic state/power item, unless you can test each and every one of the impacted devices. We've seen too many devices that don't use the multiplier/devisor correctly. Best just define the generic multiplier and divisor items, and overwrite the (unchanged) generic state/power item in the DDF for the IKEA (and later for other plugs with the same behaviour).

Just for safety: Won't these files interfere?

Interfere with what? The methods are invoked only for non-managed devices (exposed by legacy code instead of DDF), see

if (!DEV_TestStrict() && !devManaged) { handleElectricalMeasurementClusterIndication(ind, zclFrame); }

I think the DDF_AnnoteZclParse() is used when creating a new DDF from the GUI.

@bluemoehre
Copy link
Contributor Author

I wouldn't change the logic on the generic state/power item, unless you can test each and every one of the impacted devices.

Most of the affected DDFs already have a custom eval prop with their own calculation. As long as their config has precedence over the generic files, we are totally fine to change that. For those which haven't I can add a custom eval prop as well, so they gonna behave the same as before.
I would prefer to make things right in first place and meet the specs, then fix all the aberrations. Should be more future proof.

The methods are invoked only for non-managed devices

Perfect. I was just checking if there are additional conflicts for this change.

@@ -15,7 +15,7 @@
"at": "0x050b",
"cl": "0x0b04",
"ep": 0,
"eval": "if (Attr.val != -32768 && Attr.val != 32768) { Item.val = Attr.val; }"
"eval": "if (Attr.val != -32768 && Attr.val != 32768) { Item.val = Attr.val * R.item('state/power_multiplier').val / R.item('state/power_divisor').val; }"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Might want to add Math.round() to make sure the reported value is integer.
  • Signed s16 supports values from -32768 to 32767, so Attr.val != 32768 is superfluous. Typically the lowest value, -32768 is used to indicate an invalid value.
    Unsigned u16 supports values from 0 to 65535, and uses for 65535 as invalid value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Signed s16 supports values from -32768 to 32767, so Attr.val != 32768 is superfluous.

Actually I didn't change that. This code is already in master. Do we need to clean it up?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I saw that. Better cleanup while you’re touching it anyways. Sorry to put this on you.

Copy link
Contributor Author

@bluemoehre bluemoehre Oct 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might want to add Math.round() to make sure the reported value is integer.

The reported value is not required to be Integer - am I wrong? JavaScript Number(s) are always floating point. Normally it is up to the UI to take care about display and formatting.
While I was testing with the plug's, I already had problems reporting the standby demand (it was always 0W in Phoscon, while the RAW value was 4 in deCONZ). I can't tell if that's related to this specific code, but for sure if we reduce precision here, we throw away information and my end up not being able to show fractions.

EDIT: if we do not want to have float in the JSON, we need to make public alle fields of the 600 formatting block. Then the API client can decide how to deal with that information.

Copy link
Contributor Author

@bluemoehre bluemoehre Oct 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I saw that. Better cleanup while you’re touching it anyways. Sorry to put this on you.

Because the issue is not only related to the files I am touching here, I would like to issue another PR for the cleanup only, to not mix up topics. (It should not matter if that one then gets merged before or after this one, since we can rebase)

#7984

@bluemoehre
Copy link
Contributor Author

bluemoehre commented Oct 19, 2024

For those which haven't I can add a custom eval prop as well, so they gonna behave the same as before.

Devices which may get affected by this change (if their formatting block contains bad values):

  • legrand/Contactor.json
  • bosch/plug_compact.json
  • legrand/cable_outlet.json
  • immax/07048L_smart_plug.json
  • adeo/ldsenk02f_plug.json
  • innr/sp_234.json
  • innr/sp_120.json
  • innr/sp_240.json
  • tuya/_TZ3000_cehuw1lw_smartplug_EU.json
  • wiser/smart-plug-single-16A.json
  • blitzwolf/bw_shp13_smart_plug.json
  • blitzwolf/bw_shp15_smart_plug.json
  • lidl/hg08673.json
  • neo/NAS-WR01B_TS011F.json
  • tuya/_TZ3000_typdpbpg_smart_plug_eu.json
  • tuya/nous_a1z_smart_plug.json
  • namron/4512737_thermostat.json
  • namron/5401395_heater.json
  • ubisys/s1_5501_s1r_5601.json
  • ubisys/s2_5502.json
  • ubisys/s2r_5602.json
  • bosch/bmct-slz_shutter_light_control2.json
  • ubisys/j1r_5602.json
  • ubisys/j1_5502.json
  • ouellet/OTH4000-ZB.json
  • sinope/th1124zb.json
  • ubisys/d1_5503_d1r_5603.json

To prevent any possible breaking, we could add "eval": "if (Attr.val != -32768) { Item.val = Attr.val; }" to these.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants