I feel like it should be possible to send unavailable if there’s no update from the heater for X minutes. I’ll play around with it when I get a chance.
Thank you for this! Tried a couple other versions and this works well with my Vevor 8K with BLE. All the entities work and matches the onboard controller when in use. Using an esp32 dev (32 pin board), setup via EspHome 2025.10.4 addon in Home Assistant 2025.10.4. THank you for sharing this!
I’ve updated the code I shared on github, with a bunch of fixes:
- Reads the current level / temp setting.
- Fixes various issues with changing between modes.
- Fixes automatic mode if the device is in fahrenheit (sadly I had to normalize everything to celsius for now, still trying to figure out the best way to manage this).
As for setting the time, I’ve made some progress, but wanted to fix the core control / feedback issues first.
I have this one and everything works
https://pl.aliexpress.com/item/1005008040457444.html?gatewayAdapt=glo2pol
This is now implemented, along with every other setting the app exposes. The firmware provides no way (that I can find) to read the time, so setting the time is one way only; thus it shows up as a simple button that sets the time using home assistants clock.
Hi Andrew, it is working very good - good job !!! Thank you very much. I hope it will be posiible to synchro time with ntp server but right now (synchro with HA) is all OK. Thank you again - Adam
Hi All, after testing again I’ve modified ble_client section in yaml to automatic set time on connecting to API:
ble_client:
- mac_address: ${heater_mac}
id: heater_ble
on_connect:
- logger.log: "BLE connected to heater — waiting for telemetry"
# Set time on BLE connect
- delay: 2s
- ble_client.ble_write:
id: heater_ble
service_uuid: "0000FFE0-0000-1000-8000-00805F9B34FB"
characteristic_uuid: "0000FFE1-0000-1000-8000-00805F9B34FB"
value: !lambda |-
auto t = id(ha_time).now();
auto payload = heater_ble_payload_16(HeaterCommand::SET_CURRENT_TIME, t.hour * 60 + t.minute);
ESP_LOGD("BLE", "setting time: %s", format_hex_pretty(payload).c_str());
return payload;
Please check - I’m not yaml specialist but hope it will help.
BR- Adam
PS. Compiled for ESP32-S3 ZERO with ESPHome 2025.12.05 / ESP-IDF
PS. Time synchronisation with NTP also working.
Can you please share your PWM library? I have tested it with support of chat gpt. But i cant control it only listen communication
Hi everyone,
I’m the author of the Bruciatore-Ble code that some of you have used as a starting point for your implementations. I wanted to share a discovery that might be useful for further development efforts.
I’ve found that it’s possible to communicate with the VEVOR diesel heater using the ble-serial library:
Setup:
bash
ble-serial -d 21:47:08:1A:B1:1E
After establishing the connection, serial communication becomes available at 4800 baud through /tmp/ttyBLE, allowing you to send various commands directly.
Why this might be helpful:
- Provides an alternative approach to BLE communication
- Makes it easier to experiment with raw serial commands
- Could help reverse-engineer the command protocol
- Simpler testing without writing custom BLE code
- Might complement the work already done with Bruciatore-Ble
Has anyone else tried this approach? I’m happy to run tests and share any command/response data that might help with the integration development.
@Emvace @Cajda91 I knew pwm people will show up eventually ![]()
I have it configured a bit for my needs - with external Dallas type temperature probe (for air output temp.) and mq2 for smoke safety. Also a toggle button for longpress turning it on and shortpress toggling power state.
It may require a bit of tweaking for a different ESP32, standard devkit is used here, but you should be able to get it working.
Hey,
Thank you very much for the library—I hadn’t been able to figure it out on my own until today, and I’m very happy that you’re sharing your library with us.
How did you go about decoding the whole thing?
Also, can we just use the hardware from the Zatakon project?
Thank you very much
No problems to share, haven’t shared it yet beause no one asked, so here you go!
This protocol is most likely new, maybe clone board protocol, which is much simplified as only 8bits are sent and 16bits received. So not much data can be transmitted/received.
Recheck this image, you can see first 8bits sent and 16bits received. Bits are encoded in 33% and 66% PWM duty cycle. I had to make all timings precise, which was easy to do with ESPHome’s RMT library and some help of our AI friends. And I used cheap signal analyzer from Aliexpress with Pulseview, which many uses.
There is space for improvement too. Different error codes are not distinguished and I have only power toggle which goes from power level 6 down to 1 and then back to 6 again. It would be possible to find the right code (power level up) to send with the built in 8bit switches I have built in.
I have been using it for a while and it works perfectly. And yes, you can use Zatakon’s hardware, because signal levels are the same.
Good luck!
Heck, I even had some pictures of how I set the thing up.
Hello,
I also tried PulseView and a logic analyzer—unfortunately, the USB connection was always interrupted when the heating was switched on.
I have now flashed the ESP in my workshop, but without the sensors you added. (I wanted to do that in the next step.)
Unfortunately, I was unable to read and send any signals with my zatakon circuit. The status was always “no communication.”
I stored vevor_bus.cpp and vevor_bus.h in the Esp folder on HomeAssistant and flashed the yaml code onto the ESP (only changing the name of the ESP). I connected the Q2 contact to GPIO16 and the Q1 contact to GPIO17.
Unfortunately, it is not possible to switch on and I am not getting any values. Therefore, my circuit must be wrong, but I have checked it several times.
Do you have any ideas about the circuit?
I used 2N 7000 DIO MOSFETs, the resistors shown, and an AMS1117 3.3 volt regulator instead of the capacitors and fixed voltage regulator.
Thank you very much.
Best regards
Thats weird, maybe try some other computer? If the signal level is 5v, then it should feed perfectly into the analyzer. When using Pulseview, set the protocol view to PWM.
Time Level Tag Message
00:22:00 [I] [vevor:906]
Sent byte 0x59
00:22:00 [I] [vevor:141]e[1;31m[vevor_rx_task]e[0;32m
**Received byte: 0x59**
00:22:00 [I] [vevor:150]e[1;31m[vevor_rx_task]e[0;32m
Received 16-bit value: 0x9FF1
00:22:02 [I] [vevor:906]
Sent byte 0x59
00:22:03 [I] [vevor:141]e[1;31m[vevor_rx_task]e[0;32m
**Received byte: 0x59**
00:22:03 [I] [vevor:150]e[1;31m[vevor_rx_task]e[0;32m
Received 16-bit value: 0x9FF1
Do you capture loopback? See the 8bit sent value loops back. Then the 16bit response comes in. If there is no loopback, then your circuit is wrong.
Hello,
You mean the output in the esp Home log? I’ll take another close look at that.
Do you perhaps have a photo of your circuit? If so,
could you provide a short list of the parts you used?
Thanks and best regards
I used all parts which are on zatakon’s scematic, except AP2112K, I just skipped it, because the ESP32 devboard can be powered by 5v DC. My quick drawing and only picture available might be terribly hard to understand and tx/rx q1/q2 naming might be wrong. Also I used additional MQ2 and a LED.
The schematic is exact same, just without the 5v to 3.3v converter.
I used oscilliscope to test my circuit. If there is 5V out at DATA pin with pulses low on data sending, then output part works. I you get 0V DC at TX/RX pins with pulses high (3v3) at data receive (and also send), then receiving part should work.
Does anyone have a wiring for dummies design for this project? lol
Hey,
Thanks for the circuit. I built the circuit again on a breadboard because I can’t seem to get the heater to report a reasonable status or start the heater.
I used 2N7000 MOSFETs (ALLECIN 2N7000 Mosfet Transistor TO-92 N-Kanal Feldeffekttransistor für Haushaltsindustrie und DIY 200mA 60V (Packung mit 100 Stück) : Amazon.de: Gewerbe, Industrie & Wissenschaft) and an AMS1117 (AZDelivery 3 x AMS1117 3,3V Stromversorgungsmodul für Raspberry Pi inklusive E-Book!: Amazon.de: Computer & Zubehör) for the 3.3 volts so that I could save on capacitors, etc. I also supply my ESP directly with 5V, GND, GPIO16, and GPIO17.
Do I have to set any specific bits in my entity to start it, or how does it work exactly? I’m attaching some photos, including ones of my circuit.
Thank you very much for your help.
Best regards, Jan
Oh, and I don’t currently have an MQ-2 gas sensor or temperature sensor connected. However, I am using the YAML code from the description. Will that cause any problems?
**Log from ESPHome:**
INFO ESPHome 2026.1.4
INFO Reading configuration /config/esphome/esphome-web-effd74.yaml...
WARNING GPIO15 is a strapping PIN and should only be used for I/O with care.
Attaching external pullup/down resistors to strapping pins can cause unexpected failures.
See https://esphome.io/guides/faq/#why-am-i-getting-a-warning-about-strapping-pins
WARNING 'Button GPIO13 (on/off)' contains '/' which is reserved as a URL path separator. Automatically replacing with 'Button GPIO13 (on⁄off)' (Unicode FRACTION SLASH). Please update your configuration. This will become an error in ESPHome 2026.7.0.
WARNING 'Transmit Bit 6 (On/Off)' contains '/' which is reserved as a URL path separator. Automatically replacing with 'Transmit Bit 6 (On⁄Off)' (Unicode FRACTION SLASH). Please update your configuration. This will become an error in ESPHome 2026.7.0.
INFO Starting log output from 192.168.178.188 using esphome API
INFO Successfully resolved esphome-web-effd74 @ 192.168.178.188 in 0.000s
INFO Successfully connected to esphome-web-effd74 @ 192.168.178.188 in 0.007s
INFO Successful handshake with esphome-web-effd74 @ 192.168.178.188 in 0.014s
[19:46:13.156][I][app:206]: ESPHome version 2026.1.2 compiled on 2026-01-29 20:50:07 +0100
[19:46:13.163][I][app:213]: ESP32 Chip: ESP32 r3.1, 2 core(s)
[19:46:13.163][W][app:222]: Set minimum_chip_revision: "3.1" to reduce binary size
[19:46:13.186][W][gpio.one_wire:083]: Found no devices!
[19:46:13.561][I][vevor:604]: Sent byte 0x59
[19:46:13.829][W][dallas.temp.sensor:031]: Unable to select an address
[19:46:13.980][I][vevor:141][vevor_rx_task]: Received byte: 0x59
[19:46:13.984][I][vevor:150][vevor_rx_task]: Received 16-bit value: 0xDFF3
[19:46:14.748][I][vevor:604]: Sent byte 0x59
[19:46:15.164][I][vevor:141][vevor_rx_task]: Received byte: 0x59
[19:46:15.167][I][vevor:150][vevor_rx_task]: Received 16-bit value: 0xDFF3
[19:46:15.933][I][vevor:604]: Sent byte 0x59
[19:46:16.351][I][vevor:141][vevor_rx_task]: Received byte: 0x59
[19:46:16.356][I][vevor:150][vevor_rx_task]: Received 16-bit value: 0xDFF3
[19:46:17.118][I][vevor:604]: Sent byte 0x59
[19:46:17.547][I][vevor:141][vevor_rx_task]: Received byte: 0x59
[19:46:17.551][I][vevor:150][vevor_rx_task]: Received 16-bit value: 0xDFF3
[19:46:18.300][I][vevor:604]: Sent byte 0x59
[19:46:18.731][I][vevor:141][vevor_rx_task]: Received byte: 0x59
[19:46:18.736][I][vevor:150][vevor_rx_task]: Received 16-bit value: 0xDFF3
[19:46:19.484][I][vevor:604]: Sent byte 0x59
[19:46:19.919][I][vevor:141][vevor_rx_task]: Received byte: 0x59
[19:46:19.922][I][vevor:150][vevor_rx_task]: Received 16-bit value: 0xDFF3
[19:46:20.669][I][vevor:604]: Sent byte 0x59
[19:46:21.098][I][vevor:141][vevor_rx_task]: Received byte: 0x59
[19:46:21.104][I][vevor:150][vevor_rx_task]: Received 16-bit value: 0xDFF3
[19:46:21.848][I][vevor:604]: Sent byte 0x59
[19:46:22.267][I][vevor:141][vevor_rx_task]: Received byte: 0x59
[19:46:22.270][I][vevor:150][vevor_rx_task]: Received 16-bit value: 0xDFF3
[19:46:23.039][I][vevor:604]: Sent byte 0x59
[19:46:23.453][I][vevor:141][vevor_rx_task]: Received byte: 0x59
[19:46:23.458][I][vevor:150][vevor_rx_task]: Received 16-bit value: 0xDFF3
[19:46:24.221][I][vevor:604]: Sent byte 0x59
[19:46:24.657][I][vevor:141][vevor_rx_task]: Received byte: 0x59
[19:46:24.661][I][vevor:150][vevor_rx_task]: Received 16-bit value: 0xDFF3
[19:46:25.405][I][vevor:604]: Sent byte 0x59




