Closed cornim closed 1 year ago
Can you please add the screenshot of the clusters list ?
Done
Hello this device is triphase or work for 3 devices ? Because from that I m reading there is 3 consumptions availables ?
Can start with this DDF
{
"schema": "devcap1.schema.json",
"manufacturername": "TS0601",
"modelid": "_TZE200_nslr42tt",
"product": "OWON - Single,Three Phase Zigbee Power Consumption Meter",
"sleeper": true,
"status": "Gold",
"subdevices": [
{
"type": "$TYPE_CONSUMPTION_SENSOR",
"restapi": "/sensors",
"uuid": [
"$address.ext",
"0x01",
"0x0702"
],
"items": [
{
"name": "attr/id"
},
{
"name": "attr/lastannounced"
},
{
"name": "attr/lastseen"
},
{
"name": "attr/manufacturername"
},
{
"name": "attr/modelid"
},
{
"name": "attr/name"
},
{
"name": "attr/swversion",
"parse": {"fn": "zcl", "ep": 1, "cl": "0x0000", "at": "0x0001", "script": "tuya_swversion.js"},
"read": {"fn": "zcl", "ep": 1, "cl": "0x0000", "at": "0x0001"}
},
{
"name": "attr/type"
},
{
"name": "attr/uniqueid"
},
{
"name": "config/offset",
"default": 0
},
{
"name": "config/on"
},
{
"name": "config/reachable"
},
{
"name": "state/consumption",
"parse": {"fn": "tuya", "dpid": 101, "eval": "Item.val = Attr.val / 1000;" },
"read": {"fn": "none"},
"default": 0
},
{
"name": "state/lastupdated"
}
]
},
{
"type": "$TYPE_CONSUMPTION_SENSOR",
"restapi": "/sensors",
"uuid": [
"$address.ext",
"0x02",
"0x0702"
],
"items": [
{
"name": "attr/id"
},
{
"name": "attr/lastannounced"
},
{
"name": "attr/lastseen"
},
{
"name": "attr/manufacturername"
},
{
"name": "attr/modelid"
},
{
"name": "attr/name"
},
{
"name": "attr/swversion",
"parse": {"fn": "zcl", "ep": 1, "cl": "0x0000", "at": "0x0001", "script": "tuya_swversion.js"},
"read": {"fn": "zcl", "ep": 1, "cl": "0x0000", "at": "0x0001"}
},
{
"name": "attr/type"
},
{
"name": "attr/uniqueid"
},
{
"name": "config/offset",
"default": 0
},
{
"name": "config/on"
},
{
"name": "config/reachable"
},
{
"name": "state/consumption",
"parse": {"fn": "tuya", "dpid": 111, "eval": "Item.val = Attr.val / 1000;" },
"read": {"fn": "none"},
"default": 0
},
{
"name": "state/lastupdated"
}
]
},
{
"type": "$TYPE_CONSUMPTION_SENSOR",
"restapi": "/sensors",
"uuid": [
"$address.ext",
"0x03",
"0x0702"
],
"items": [
{
"name": "attr/id"
},
{
"name": "attr/lastannounced"
},
{
"name": "attr/lastseen"
},
{
"name": "attr/manufacturername"
},
{
"name": "attr/modelid"
},
{
"name": "attr/name"
},
{
"name": "attr/swversion",
"parse": {"fn": "zcl", "ep": 1, "cl": "0x0000", "at": "0x0001", "script": "tuya_swversion.js"},
"read": {"fn": "zcl", "ep": 1, "cl": "0x0000", "at": "0x0001"}
},
{
"name": "attr/type"
},
{
"name": "attr/uniqueid"
},
{
"name": "config/offset",
"default": 0
},
{
"name": "config/on"
},
{
"name": "config/reachable"
},
{
"name": "state/consumption",
"parse": {"fn": "tuya", "dpid": 121, "eval": "Item.val = Attr.val / 1000;" },
"read": {"fn": "none"},
"default": 0
},
{
"name": "state/lastupdated"
}
]
}
]
}
It only enable the consumption for the moment.
It registers consumption for 3 phases.
I sold it already though, since it also needs a 3-phase power supply which is inconvenient for me. Hence I'm closing this ticket for now.
Hi, Worrking on implementing a DDF for this device, I asked a few questions on Discord. @Smanar asked me to continue the discussion here, so I copy the content from Discord.
The power datapoints (0x06, 0x07 and 0x08) have the datatype 0x00 (raw) with a 8 bytes data value. From my understanding, this data is formatted as follow:
2 bytes Uint16 Voltage in deciVolts
(max value of 65535 which seems coherent with commonly used voltage which is beetwen 120V and 380V)3 bytes Uint24 Current in mA
(max value 16777215, the device is sold with clamps up to 500A so this data type seems good for valus up to 500000mA)3 bytes Int24 Power in W
(value beetween -8388608 and 8388607 which allows to store 500A*1675V at 100% Power Factor)This is not what I have seen implemented in other projects, but I am confident in these choices. Please correct me if you think I am wrong!
Uint16, 1byte ignored, Uint16, 1 byte ignored, Int16
Uint16, Uint32, Int16
Uint16, 1byte ignored, Uint16, 1 byte ignored, Int16
Thoses dpid are not used yet in the DDF, I prefer wait to see if the user is able to use them before spent time on them, and yes its 2 byte for Voltage, 1 ignored, 2 for current, 1 ignored and 2 for power (from Z2m) Zigbee4domoticz can work too, and it's a good idea, in fact pipiche is taking a block composed by the ignored byte + the value on 2 bytes + 1 ignored byte
From deCONZ source code I see that devices/generic/items/state_voltage_item.json
and devices/generic/items/state_current_item.json
are both Uint16 and devices/generic/items/state_power_item.json
is Int16.
Can I just set "datatype" to the correct value for each item in the DDF, or do I need to do anything more?
I am asking because in the resource.cpp file I see lines like rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeInt16, QVariant::Double, RStatePower));
, so here it seems that there is a C++ data type hard coded for each item. But maybe I am not interpreting this code correctly. Also, during my tests with this device, without changing anything to default datatype, I have seen power values higher than 10000000, which does not fit in a Uint16, so I am a bit confused.
don't take care of type, the JS engine just need to generate a number (with JS code) deconz will convert it itself but yes you are right can need to decrease it because of value range and you can't change them, its deconz standard
This device provides datapoins for AC Frequency (in Hz) and Power Factor (in %). I could just ignore them for the moment, but what if want to take them into account? I doubt that I only need to create json files in devices/generic/items/ and add the item in resource.cpp and resource.h.
Could anyone tell me what else need to be implemented?
on last deconz versio, if you want to create new field like like state/acfrequency, you don't need to edit c++ code only add a json
This device has a faulty firmware giving erroneous values from time to time or in certain circumstences (high power usage or production).
For example while the Power for phase C should be 0, it rerports a few times in an hour a value of 0x999998 (10066328 W) ; the Power A+B+C reports a value of 0x19999998 (not necessarely at the same time as the single phase reports erroneous value).
There are already discussions about this bug in other projects with different solutions to overcome this issue, but none of them are fully satisfying (1, 2, 3...).
After a lot of trial and error, I ended up proposing the following fix which gives good results after a few days using it:
For phase A, B or C power:
let val = ZclFrame.at(13) | (ZclFrame.at(12) << 8) | (ZclFrame.at(11) << 16);
val = ZclFrame.at(11) == 0x99 ? -(val - 0x999998) : val;
Item.val = val;
0x999998 is the unexpected value I see when Power should be 0. When there there is Power usage, substracting 0x999998 gives a negative value, so I added the "-()" to invert the sign. Unfortanetly, I do not have solar panels to check if this is working as expected when there is power production.
For Power A+B+C, it is a bit more difficult to fix the value. When only one phase is consuming some energy, substracting 0x19999998 and inverting the sign is fine. But if the other phases starts using power it is getting whorse. For example:
Phase A:0 W Phase B: 0 W Phase C: 6800 W A+B+C: 429489928 W (0x19997F08 - 0x19999998 = -6800)
Phase A:1800 W Phase B: 0 W Phase C: 6800 W A+B+C: 429491728 W (0x19998610 - 0x19999998 = -5000)
I really don't know if it would be possible to compute the good value like this.
So I ended up creating 3 items in the Power A+B+C device, one for Phase A Power, one for Phase B Power, and one for Phase C Power. Like this I have the values for all 3 phases available in this device and I just compute the sum in deCONZ instead of relying on the sensor value.
Item.val = R.item('state/current_P1').val+R.item('state/current_P2').val+R.item('state/current_P3').val;
Remark: for the moment I am using state/current_P1 P2 and P3 to store the Power for each phase, just because there is no generic item defined in deCONZ for state/power_P1 P2 P3).
Do you think this proposed fix is acceptable or is it a bad idea to process like this?
for the bugs in firmwares, how often it happen ? we can't just ignore some reports ? I think this device is talkative enought for we can skip some of them ?
Based on the bug frequency, I agree that we could just ignore erroneous reports, as it happens a few times per hour.
But unfortunatelly, the bug also arises in certain circumstances. For example, As soon as I start charging my EV car, which drains around 7KW, the bug is present on both Power C and PowerA+B+C during the whole time the car is charging.
I am using this DDF since a few days, and I am satisfied with the results. However I need to make some adjustments for taking your answers into consideration.
On the first TYPE_POWER_SENSOR, you make state/power = current P1 + current P2+ current p3 ?
So to resume the firmware bug.
I can imagine the big number is just a signed/unsigned issue, the device probably reverse the current side on his measurement, but I don't see why you have the issue when charging your car, and with a persistent way? It happen if you have too a big consumption ?
You haven't a sample with raw value ?
Edit: Have understand for my fist comment ^^, I m reading again your post on discord
0x999998 is the unexpected value I see when Power should be 0. When there there is Power usage, substracting 0x999998 gives a negative value, so I added the "-()" to invert the sign. Unfortanetly, I do not have solar panels to check if this is working as expected when there is power production.
For Power A+B+C, it is a bit more difficult to fix the value. When only one phase is consuming some energy, substracting 0x19999998 and inverting the sign is fine. But if the other phases starts using power it is getting whorse. For example:
- Phase A:0 W Phase B: 0 W Phase C: 6800 W A+B+C: 429489928 W (0x19997F08 - 0x19999998 = -6800)
- Phase A:1800 W Phase B: 0 W Phase C: 6800 W A+B+C: 429491728 W (0x19998610 - 0x19999998 = -5000)
I really don't know if it would be possible to compute the good value like this.
So I ended up creating 3 items in the Power A+B+C device, one for Phase A Power, one for Phase B Power, and one for Phase C Power. Like this I have the values for all 3 phases available in this device and I just compute the sum in deCONZ instead of relying on the sensor value.
Item.val = R.item('state/current_P1').val+R.item('state/current_P2').val+R.item('state/current_P3').val;
Remark: for the moment I am using state/current_P1 P2 and P3 to store the Power for each phase, just because there is no generic item defined in deCONZ for state/power_P1 P2 P3).
About the signed/unsigned convertion
For example while the Power for phase C should be 0, it rerports a few times in an hour a value of 0x999998 (10066328 W) ; the Power A+B+C reports a value of 0x19999998 (not necessarely at the same time as the single phase reports erroneous value).
const int32UnsignedToSigned = (uint32) => Int32Array.from(Uint32Array.of(3))[0];
var arg1 = 10066328; var a = int32UnsignedToSigned(arg1); alert(a);
will return 3. both value in fact
Can try with arg1 = 0x999998 or 0x03, you will have same value => 3
Here is a file with sample data including raw values PC321-Z-TY sample data.xlsx I started charging the electric vehicle at 18h34
Timestamp Source Address DPID DPID Hex DP Description Datatype Length Value Raw
18:33:52:10 0xA4C138752438A330 134 0x06 Power A 0x00 8 2410;0;0 0x096A000000000000
18:33:55:15 0xA4C138752438A330 135 0x07 Power B 0x00 8 2412;217;27 0x096C0000D900001B
18:33:58:21 0xA4C138752438A330 136 0x08 Power C 0x00 8 2414;0;0 0x096E000000000000
18:34:01:27 0xA4C138752438A330 137 0x09 Power ABC 0x02 4 53 0x00000035
18:34:04:32 0xA4C138752438A330 138 0x01 Consumption ABC 0x02 4 7518 0x00001D5E
18:34:07:37 0xA4C138752438A330 139 0x65 Consumption A 0x02 4 17839 0x000045AF
18:34:10:43 0xA4C138752438A330 140 0x6F Consumption B 0x02 4 386 0x00000182
18:34:13:49 0xA4C138752438A330 141 0x79 Consumption C 0x02 4 56959 0x0000DE7F
18:34:25:71 0xA4C138752438A330 145 0x83 Current ABC 0x02 4 213 0x000000D5
18:34:37:93 0xA4C138752438A330 149 0x06 Power A 0x00 8 2334;0;0 0x091E000000000000
18:34:40:99 0xA4C138752438A330 150 0x07 Power B 0x00 8 2333;221;29 0x091D0000DD00001D
18:34:44:05 0xA4C138752438A330 151 0x08 Power C 0x00 8 2333;29585;10059473 0x091D007391997ED1
18:34:47:19 0xA4C138752438A330 152 0x09 Power ABC 0x02 4 429489878 0x19997ED6
18:34:50:16 0xA4C138752438A330 153 0x01 Consumption ABC 0x02 4 7521 0x00001D61
18:34:53:21 0xA4C138752438A330 154 0x65 Consumption A 0x02 4 17839 0x000045AF
18:34:56:27 0xA4C138752438A330 155 0x6F Consumption B 0x02 4 386 0x00000182
18:34:59:32 0xA4C138752438A330 156 0x79 Consumption C 0x02 4 57010 0x0000DEB2
18:35:11:55 0xA4C138752438A330 160 0x83 Current ABC 0x02 4 29831 0x00007487
On the first TYPE_POWER_SENSOR, you make state/power = current P1 + current P2+ current p3 ? Edit: Have understand for my fist comment ^^, I m reading again your post on discord
Sorry, didn't see I forgot a part of my Discord message for question 4. I updated my post with the full text to make things more readable.
but I don't see why you have the issue when charging your car, and with a persistent way? It happen if you have too a big consumption ?
Yes I think the bug is becoming permanent as soon as the power usage is reaching a certain value. The car is using around 6.8KW while charging. I am still trying to reach a high value on my wall plug monitored by phase A, but for moment I couldn't reach more than 4KW with the devices I plugged in, and it didn't make the bug happened.
const int32UnsignedToSigned = (uint32) => Int32Array.from(Uint32Array.of(3))[0]; var arg1 = 10066328; var a = int32UnsignedToSigned(arg1); alert(a);
will return 3. both value in fact Can try with arg1 = 0x999998 or 0x03, you will have same value => 3
I don't really understand what you meant on this post. 3 is hard coded in your function, so this is normal it always gives 3 whatever the arg1 value is. I believe that Int32Array.from(Uint32Array.of(3))[0];
should be Int32Array.from(Uint32Array.of(uint32))[0];
but even after fixing this, I don't see how this conversion can help fixing the bug.
Oups sorry, wanna say for exemple
const int32SignedToUnsigned = (int32) => Uint32Array.from(Int32Array.of(int32))[0];
const int32UnsignedToSigned = (uint32) => Int32Array.from(Uint32Array.of(uint32))[0];
var arg1 = 4294967294;
var a = int32UnsignedToSigned(arg1);
alert(a);
var arg1 = -2;
var a = int32UnsignedToSigned(arg1);
alert(a);
both give -2, but it's useless, was just a comment, you are making the same thing with substracting 0x999998 For me you can do nothing
Phase A:0 W Phase B: 0 W Phase C: 6800 W A+B+C: 429489928 W (0x19997F08 - 0x19999998 = -6800)
Phase A:1800 W Phase B: 0 W Phase C: 6800 W A+B+C: 429491728 W (0x19998610 - 0x19999998 = -5000)
On your side you have only consumption? so you can't have negative value, the device reverse randomly value itself, making sum from device totaly unusable. For me you are fine, you are reversing all negative value (using - 0x999998), and make custom sum with positive value.
As long as you haven't production (solar panel) I don't see what you can do better.
Device
Screenshots
Node Info
Cluster List
Basic
Identify
Alarms
Device Temperature
Groups
Scenes
On/Off
Level Control
Color Control
Simple Metering
Diagnostics
Other clusters that are not mentioned above
Tuya specific
Hitting "Trigger report all datapoints" get the following in the log: