-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Smart plugs with a BL0942 power metering chip (and probably also BL0939 and BL0940) only processes messages from the BL0942 chip alternately. #14829
Comments
Thanks for the analysis |
@Dam5 I do agree and see
Do you want to make the change and test, then PR ? Should be: if (Bl09XX.received) {
Bl09XX.rx_buffer[Bl09XX.byte_counter++] = serial_in_byte;
if (Bl09XX.buffer_size == Bl09XX.byte_counter) { |
@barbudor The checksum calculation is (and was) correct. I've run my solution for the last 2 days and seemed OK. (EDIT: typo's) |
Yes, I change my original message Will you PR ? |
Let me do it. I need to do some checks first. |
@arendst |
Hi, I have 2 device here with similar problems no code expert but can assist with testing ? |
Probably superfluous, but just to be clear. |
Started working on it and first impressions are you're right regarding the buffer size checks. I was also surprised to find Will continue now first with the BL09xx driver. |
Fix BL0939, BL0940 and BL0942 energy monitoring buffer miscompares resulting in wrong daily energy values regression from v9.5.0.8 (#14829)
Thx for the thorough investigation. The suspected buffer overflow did not occur as the byte_counter is incremented AFTER it was used as index into the buffer. Anyway, I noticed my BL0940 device also skipped a beat and I was also wondering how come the daily result was offtrack too. Again. Keep em coming this way as it always reveals nice black spots. |
I have to disagree. Indeed byte_counter is incremented after used as an index, but byte_counter is at that point already out-of-bounds. buffer_size = 23; rx_buffer[0..22] ; But byte_counter = 23, incrementing to 24. But never mind: Love your project. (EDIT: Sorry, sounds pedantic, not intended) |
hi @Dam5 |
@ferbulous |
@Dam5 Thanks! Just another question, how can I determine the corrent gpio pin is for HLWBL CF1/HLWBL SELi? I tried googling around but I can't find clear answer on this |
@ferbulous The BL0942-based power plug uses a serial (4800 baud) protocol (to communicate whith the BL0942 chip). HLWBL CF1and HLWBL SELi (among others) are used in e.g. BL0937-based power plugs. Are you sure you're dealing whith a BL0942-based power plug? Beware that there are a lot of different, almost identically looking, smart plugs for sale. See attached images for a BL0937-based power plug (OctoPlug) and a BL0942-based power plug (Smartplug05) that I keep for reference. |
@Dam5 |
@ferbulous For Relay (probably the same, P26 on the Tuya), Pushbutton (trace is not visible) and blue LED (trace not visible) you have to trace the PCB. |
That looks like the same board I have modified (AU) works well now they fixed a small bug in the driver. :-) |
@Dam5 Hi, just swapped with ESP-02S and your template matches the exact pin with my power plug. I'll proceed with power calibration as per the tasmota guideline page which I've never done before so hopefully I'll get it right @PVerburg do you by any chance got it from aliexpress? |
@ferbulous |
@Dam5 yep did get it from ali. |
PROBLEM DESCRIPTION
In my Elivco smart plugs I replaced the Tuya CB2S module with a drop-in ESP-2S module, and flashed them with Tasmota 10.1.0 and calibrated them.
I observed 2 problems:
(Third problem is that calibrating the current for a BL0942 is in Amps, and the calibrating should be in mAmps, or visa versa, but that's a minor problem)
While investigation this strange energy consumption behaviour of my smartplugs with BL0942 chip, I discovered that half of the messages received from the BL0942 chip are disgarded.
It boils down to reading 24 bytes from the BL0942 chip before processing, while the packet is only 23 bytes long.
This 24th byte is the packet-header of the next (23 byte) packet, but is not saved and never handled, so the complete next packet is disgarded waiting for the subsequent BL09XX_PACKET_HEADER byte.
Unless there's a BL09XX_PACKET_HEADER byte (0x55) in the actual data of the (otherwise disgarded) packet, in which case the receive-buffer is filled with 24 bytes from that point on.
In that case, most of the time, this results in a checksum error.
But sometimes (once every few minutes) the (simple) checksum turns out to be correct, and the (shifted) bytes lead to processing of incorrect data.
For example resulting in huge (1 second) power spikes which adds up to the daily total energy.
This is the source of the power consumption I was observing.
These power spikes are so short that they are not displayed (as Watts) in the main webpage of the device (I've never observed one), and are not logged in the sensor-data via MQTT.
So the power is always 0 Watt, and the energy is slowly adding up.
(Btw, 0.8 kWh daily corresponds to ca 30 Watt continuously)
In Tasmota every second a poll request is sent out to the BL0942, and there's no synchronisation between sending and receiving data (which in this case is good, the communication is not blocked waiting for eachother)
Enabling debugging (DEBUG_BL09XX) reveals that indeed the data is processed only once per two seconds, while the poll is send out every second.
Another symptom: In a device like this, with ultra short communication lines, there shouldn't be checksum errors.
Third symptom: The time between the (2nd) poll and the processing of the received message (10 ms) is way too fast for 23 bytes at 4800 baud (should be ca 48 ms)
The bug seems a classic index/byte-count error.
I also expect memory corruption (store 24 bytes in a 23 byte malloced buffer), but I've not looked into that.
IMO the cullpit is in line 221 of xnrg_14_bl09xx.ino
replacing line 221 with
solves the alternating problem.(and memory corruption, and checksum errors, and energy creep)
I also checked the datasheets of the BL0939 and the BL0940 chips and I expect these have the same problem (packet is 35 bytes, while 36 bytes are read before processing).
(https://www.belling.com.cn/media/file_object/bel_product/BL0939/datasheet/BL0939_V1.2_cn.pdf, https://www.belling.com.cn/media/file_object/bel_product/BL0940/datasheet/BL0940_V1.1_en.pdf)
The chinese one was the only I could find.
Am I the only one observing this behaviour, or am I barking at the wrong tree (and making a fool of myself)?
REQUESTED INFORMATION
Make sure your have performed every step and checked the applicable boxes before submitting your issue. Thank you!
Backlog Template; Module; GPIO 255
:Backlog Rule1; Rule2; Rule3
:Status 0
:weblog
to 4 and then, when you experience your issue, provide the output of the Console log:BTW a number of AddLog()'s are in print-float format "%f" which are not by default resolved when building.
In my debugging I have replaced these with dtostrf() calls, but in the above output the stock "%f"'s are not resolved, resulting is empty strings for Voltage en Temp, or skipping these Voltage-strings alltogether.
TO REPRODUCE
It greatly depends if 0x55 is part of the actual data. In my case it is.
EXPECTED BEHAVIOUR
SCREENSHOTS
If applicable, add screenshots to help explain your problem.
ADDITIONAL CONTEXT
Add any other context about the problem here.
(Please, remember to close the issue when the problem has been addressed)
The text was updated successfully, but these errors were encountered: