logo elektroda
logo elektroda
X
logo elektroda

Interior and reverse engineering of the Ariston Velis 80 Wi-Fi electric water heater on ESP32 (part1

p.kaczmarek2 5169 77

TL;DR

  • The Ariston Velis 80 Wi‑Fi electric water heater uses an ESP32-WATG-32D module, an extra microcontroller, and the Ariston NET app for scheduling, ECO mode, antifreeze, and anti-legionella functions.
  • Inside, the main panel contains a 7-segment display, a power supply based on LNK623DG, and FM25Q64A13 SPI flash with 64M-BIT capacity.
  • The 80 version cost €322, and the manual lists 27 kg weight, 65 litres capacity, 15 dB noise, and about 27 kWh/week in smart mode.
  • UART capture at 115200 baud exposed frames with a repeating C3 41 header, a length byte, and a checksum that appears to be a simple sum modulo 256.
  • Protocol decoding is unfinished, some packets needed byte-offset correction, and the next step is comparing app traffic to boiler control for custom firmware and Home Assistant integration.
Generated by the language model.
ADVERTISEMENT
Treść została przetłumaczona polish » english Zobacz oryginalną wersję tematu
📢 Listen (AI):
  • #61 21849248
    DeDaMrAz
    Level 22  
    Posts: 596
    Help: 34
    Rate: 125
    I am in a process of simulating that on a dry workbench (more convenient 😁) it is stable, and working, all the controls are up and running now so more test will follow. Right now no HA implementation (discovery) and index is still rough + log is debug heavy for testing purposes. Once the tests are done I'll post more findings and document everything for future reference.

    I think I posted this already but worth repeating

    ### CMD 0x33 — Control Write (ESP → Boiler, on demand)
    
    To change boiler settings, the ESP sends a CMD 0x33 with a 2-byte register ID and value:
    
    | Register | Value        | Description                         |
    | -------- | ------------ | ----------------------------------- |
    | `05 21`  | `01` / `00`  | App/UI power state ON / OFF         |
    | `06 21`  | `01` / `00`  | Mode selector (manual/eco, TBD map) |
    | `DD 27`  | `01`         | Power ON                            |
    | `DD 27`  | `05`         | Standby                             |
    | `DD 27`  | `09`         | Boost ON                            |
    | `79 2D`  | `XX XX` (LE) | Target temperature x 10             |
    | `0A 21`  | `01` / `00`  | Anti-legionella ON/OFF              |
    | `CC 4B`  | `08`         | WiFi STA connected                  |
    | `CC 4B`  | `06`         | WiFi connecting                     |
    | `CC 4B`  | `04`         | WiFi AP mode                        |
    | `CC 4B`  | `00`         | WiFi OFF                            |


    This is just the WiFi control command set, there is a telemetry set (cmd 0x23), system init/report (cmd 0x52) and generic (0x25) command set that I am in a process of fully understanding.

    ## Byte-Level Frame Maps (working decode)
    
    Conventions:
    - Offsets below are payload offsets (start at payload byte 0, not frame start).
    - `u16le@N` means little-endian 16-bit value using payload bytes `[N]` and `[N+1]`.
    - `?` means not yet fully decoded/confirmed.
    
    ### CMD23 response maps
    
    1) Water tuple response (len=12), query: `60 10 68 13 69 13 6A 13 6B 13 43 51`
    - `u16le@0`  : water/avg temp candidate #1 (x10 C)
    - `u16le@2`  : water/avg temp candidate #2 (x10 C)
    - `u16le@4`  : water/avg temp candidate #3 (x10 C)
    - `u16le@6`  : water/avg temp candidate #4 (x10 C)
    - `u16le@8`  : water/avg temp candidate #5 (x10 C)
    - `u16le@10` : often `0xFFFF` sentinel
    
    2) Current/target response (len=12), query: `4A D8 ... 71 9E`
    - bytes `0..7`   : status/unknown block (`?`)
    - `u16le@8`      : `TEMP_CUR` (x10 C)
    - `u16le@10`     : `TEMP_SET` (x10 C)
    
    3) Heater response (len=10), query: `4F 9D ... 57 D1`
    - bytes `0..1`   : status word (`?`) commonly `C9 00`
    - `u16le@2`      : heater power (W), observed `0` or `1500`
    - bytes `4..7`   : error/status reserved (`?`)
    - bytes `8..9`   : status tail (`?`) commonly `9B 00`
    
    4) Time-to-temp/showers response (len=7), query: `D3 4B ... CC 4B`
    - byte `0`       : status/flags (`?`) usually `00`
    - byte `1`       : status/flags (`?`) often `04`/`4E`
    - byte `2`       : showers candidate
    - byte `3`       : time-to-temp candidate
    - byte `4`       : status (`?`) often `00`
    - byte `5`       : constant-like `0x1B` in many captures (`?`)
    - byte `6`       : mode/state nibble-like (`?`) often `08/06/05/00`
    
    5) On-time response (len=6), query: `DA 40 ... CF 3D`
    - `u16le@0`      : uptime-like counter (minutes in current interpretation)
    - bytes `2..5`   : reserved/flags (`?`) usually zeros in baseline
    - Note: this is not heater-active runtime.
    
    6) Status block A response (len=12), query: `44 DC ... 4D DC`
    - payload often all zeros in idle/heating runs
    - field semantics unknown (`?`)
    
    7) Status block B response (len=6), query: `C0 F2 ... D0 F9`
    - `u16le@0`      : small state code (often `4`)
    - `u16le@2`      : usually `0`
    - `u16le@4`      : usually `0`
    
    8) Status block C response (len=7), query: `C0 F9 ... D4 3D`
    - `u16le@0`      : usually `0`
    - `u16le@2`      : often `0x024E` (=590, may correlate with target 59.0 C in some runs)
    - remaining bytes : flags/status (`?`)
    
    9) Status block D response (len=6), query: `D1 40 ... DB 40`
    - `u16le@0`, `u16le@2`, `u16le@4` are non-zero status words (`?`)
    - seen values drift with runtime/heating; semantics pending
    
    10) Status block E response (len=4), query: `D9 3E D0 3D D2 3D C4 3E`
    - often all zeros in current captures
    - semantics pending
    
    ### CMD25 response maps
    
    For registers where response len=8 (`44..47 24`, `79 2D`, `7A 2D`, etc.), payload is usually 4 little-endian words:
    - `u16le@0`, `u16le@2`, `u16le@4`, `u16le@6`
    
    Known high-confidence examples:
    - `44 24` -> `1500, 200, 3000, 1500`
    - `45 24` -> `1500, 0,   3000, 1000`
    - `46 24` -> `100,  50,  3000, 100`
    - `47 24` -> `10,   1,   100,  10`
    
    `CMD25` 4-byte responses are often:
    - word-like status pairs (`u16le@0`, `u16le@2`) or
    - byte flags in `[0..3]` depending on register.
    
    ### CMD52 payload maps (identity/init)
    
    `CMD52` is used for module identity and boot/session initialization.
    Frame format reminder: `C3 41 52 [LEN] [PAYLOAD...] [CHK]`
    
    1) MAC announcement (`LEN=9`)
    - Example payload: `03 0F 01 78 42 1C 14 3E 18`
    - byte `0`        : group/type (`03`)
    - byte `1`        : field id (`0F`)
    - byte `2`        : sub-id/version (`01`)
    - bytes `3..8`    : MAC address bytes (`78 42 1C 14 3E 18`)
    
    2) Serial announcement (`LEN=15`)
    - Example payload: `03 10 01 31 37 32 35 32 32 46 4B 30 37 30 30`
    - byte `0`        : group/type (`03`)
    - byte `1`        : field id (`10`)
    - byte `2`        : sub-id/version (`01`)
    - bytes `3..14`   : ASCII serial (e.g. `172522FK0700`)
    
    3) Combined/session info (`LEN=18`)
    - Example payload: `03 29 00 0E 73 19 31 37 32 35 32 32 46 4B 30 37 30 30`
    - byte `0`        : group/type (`03`)
    - byte `1`        : field id (`29`)
    - byte `2`        : mode/subtype (`00`)
    - bytes `3..5`    : session/config triplet (`0E 73 19`) (`?`)
    - bytes `6..17`   : ASCII serial echo (`172522FK0700`)
    
    4) Init request A (`LEN=3`)
    - Payload: `02 2C 00`
    - byte `0`        : init class (`02`)
    - byte `1`        : init opcode (`2C`) (`?`)
    - byte `2`        : arg/status (`00`)
    - Sent in retries during early startup.
    
    5) Init request B (`LEN=3`)
    - Payload: `03 21 00`
    - byte `0`        : init class (`03`)
    - byte `1`        : init opcode (`21`) (`?`)
    - byte `2`        : arg/status (`00`)
    
    6) Init request C (`LEN=3`)
    - Payload: `02 0B 00`
    - byte `0`        : init class (`02`)
    - byte `1`        : init opcode (`0B`) (`?`)
    - byte `2`        : arg/status (`00`)
    
    7) Boiler ACK to CMD52 (`RX`, len=4)
    - Example payload: `1D FE 00 13`
    - bytes `0..3`    : ACK/status block (`?`) used as handshake success marker.
  • ADVERTISEMENT
  • #62 21849286
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14400
    Help: 650
    Rate: 12332
    Very good job! I'm eager to see more progress!
    Please add a small text showing "Total bytes received" and "sent" under the device table, it's good to have such display for debugging.
    Helpful post? Buy me a coffee.
  • ADVERTISEMENT
  • #63 21849289
    DeDaMrAz
    Level 22  
    Posts: 596
    Help: 34
    Rate: 125
    Oh no I thought about that but the original module is super chatty - it will send something like 100+ frames a minute with this being one full frame


    Screenshot of UART Viewer showing TX/RX frame log table with hex payloads, heater state, and temperature readings

    Added after 2 [hours] 1 [minutes]:


    Screenshot of AristonESP32 dashboard with control buttons and water temperature status

    HA integration next.....


    Screenshot of AristonESP32 dashboard with Controls, Sensors, and Activity panels and MQTT logo.
  • ADVERTISEMENT
  • #64 21849431
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14400
    Help: 650
    Rate: 12332
    Nice! Why some controls are toggles, and some are presses?
    Helpful post? Buy me a coffee.
  • #65 21849434
    DeDaMrAz
    Level 22  
    Posts: 596
    Help: 34
    Rate: 125
    p.kaczmarek2 wrote:
    Why some controls are toggles, and some are presses?


    because this 😁


    Screenshot text showing “by Espressif” and “Firmware: ariston_alpha_1”.

    Added after 2 [hours] 36 [minutes]:


    Screenshot of AristonESP32 dashboard with controls, sensor readings, and MQTT activity log


    Screenshot of the AristonESP32 dashboard with control buttons and status readings for temperature and connectivity

    That is it for now..... driver needs polishing and some tweaks but it is finally ready to be put in operation and get some water in it and test long term before verifying driver and publishing it.

    I have to trace back the changes I made and get some data back from the real world test and I'll push this into a clean PR.
  • #66 21850651
    DeDaMrAz
    Level 22  
    Posts: 596
    Help: 34
    Rate: 125
    Ariston Water Heater control pop-up showing 27°C current temperature and 50°C target with +/- buttons

    It is working on the workbench, still waiting for DOWD chips to appear to replace the one in the original module and pack it up.

    Driver is in the alpha stage still and will require some real life testing time before I can push it into a PR.
  • #67 21865836
    n1bs
    Level 4  
    Posts: 8
    >>21850651 Awesome job! Thanks a lot for all your hard work on this!

    While we wait... Could you please share your idea about "non-wifi aristons" ? What did you want to try with that ? May be I can help with some legwork at this stage?
  • ADVERTISEMENT
  • #68 21866196
    DeDaMrAz
    Level 22  
    Posts: 596
    Help: 34
    Rate: 125
    n1bs wrote:
    Could you please share your idea about "non-wifi aristons" ?


    Still working on the WiFi enabled model and decoding more traffic. As mentioned before I have 2 boards that are not WiFi enabled and will work on them but general idea is that I can at least hijack the touch sensors and enable control that way - not perfect but I've done it before so that would be the initial step. After that I will try to investigate other options and maybe "enable" WiFi control on them, not yet sure as I am doing this in my free time and it is time consuming but a definitive goal is to have those HA compatible as well.

    Hope it makes sense. To be continued....
  • #69 21866970
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14400
    Help: 650
    Rate: 12332
    I've certainly heard it works for TuyaMCU devices. They are totally different, but it's still something to consider. You can buy a thermostat with no WiFi, just MCU, and add WiFi module there and MCU will already have TuyaMCU firmware flashed...
    Helpful post? Buy me a coffee.
  • #70 21877080
    n1bs
    Level 4  
    Posts: 8
    >>21866196
    Absolutely makes sense! Just wanted to help somehow :) Thanks for moving this project forward!

    Added after 2 [minutes]:

    >>21866970
    Yes, most of Tuya controllers use native MCUs and just talk via their own module over wifi, so having that on place it's relatively easy to hijack commands and investigate protocol. With these "old" / non-wifi aristons it's little bit harder since it's possible that firmware is also different (at least I didn't get any UART output on the same pins what wifi-version). But MCU here is pretty flexible, and can make UART on almost any pin, which makes blind checking pretty... useless. But probably more experienced person than me can see more potential places to check.
  • #71 21877168
    sq3evp
    Level 39  
    Posts: 6336
    Help: 210
    Rate: 833
    Board Language: polish
    But to do a water temperature measurement remotely is probably possible? In fact, at least that much is possible? Where the signal has to be fed from the sensors.
  • #72 21877212
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14400
    Help: 650
    Rate: 12332
    Is it known what sensors are in there? Maybe it would be possible to tap into the measurement of the external MCU.
    Helpful post? Buy me a coffee.
  • #73 21877695
    n1bs
    Level 4  
    Posts: 8
    >>21877212
    There are 2 tanks, each has separate probe with 2x thermistors. One is at very bottom of the tank, second one is in the middle.
    I was thinking to completely replace main MCB with own one (can be even arduino, not big deal to code pid regulator and re-use power board). Looking at current PCB I don't see any protection from temperature runaway, using 2 seconds per tank can be one of the reasons we don't see HW temperature relay/switch here.
    Anyway, if DeDaMrAz will not find anything useful from main PCB - I'd probably make custom board + esp as wifi/homeassistant interface.
  • #74 21894948
    QuanticComparatorLog
    Level 1  
    Posts: 1
    >>21847065 Hi ! I'm totally new to this but before trying on my side did you find any solution ? I also have the same boiler without any wifi and want to read as much information as I can. I also have ESP32 on hand and want to integrate it to Home Assistant
  • #76 21895074
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14400
    Help: 650
    Rate: 12332
    Cool, so, how in the end did you solve ESP32 flash protection?
    Helpful post? Buy me a coffee.
  • #77 21895183
    DeDaMrAz
    Level 22  
    Posts: 596
    Help: 34
    Rate: 125
    p.kaczmarek2 wrote:
    did you solve ESP32 flash protection?


    No, I decided to skip that part as e-fuses are all burned and I figured it was too much work to replace the chip. So I opted out to replace the module entirely.

    Also since we didn't have UART exposed on ESP32 I changed the default routing in the SDK for convenience (pins are closer together) in the PR.
  • #78 21895214
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14400
    Help: 650
    Rate: 12332
    How did you get module for replacement?
    Helpful post? Buy me a coffee.
📢 Listen (AI):

Topic summary

✨ The discussion focuses on the Ariston Velis 80 Wi-Fi electric water heater, exploring its hardware architecture, Wi-Fi module integration, and potential for firmware modification. The device includes two heaters and two temperature sensors per tank, likely enabling selective heating based on temperature differentials to maintain constant outlet temperature. The Wi-Fi module is based on an ESP32 chip with a 5V UART interface, connected only to test points on the board, complicating direct firmware flashing due to flash encryption and locked re-flash via UART. The community is analyzing the communication protocol between the MCU and Wi-Fi module using logic analyzers and PulseView with custom UART decoders, aiming to decode intermediate frames and commands. The device also features an RTC crystal with a supercapacitor backup and an NFC tag containing device metadata. Discussions include the possibility of replacing the Wi-Fi module with alternative ESP32 or ESP8266 modules, considering level shifting for UART signals. The goal is to develop open-source firmware to enable local control without reliance on manufacturer cloud services, enhancing user control and privacy. Service and maintenance aspects are also covered, including heater cleaning and magnesium electrode replacement every two years, with references to official manuals and service diagrams. The Wi-Fi functionality facilitates remote control and installation flexibility, although the hardware design imposes challenges for modification and firmware replacement.
Generated by the language model.

FAQ

TL;DR: Ariston Velis 80 Wi‑Fi logs show ~27 kWh/week in Smart mode, and “The aim is to reduce energy consumption.” This reverse‑engineering thread maps the ESP32 UART protocol, memory, and app features to enable local control without cloud lock‑in. [Elektroda, p.kaczmarek2, post #21717680]

Why it matters: If you want Home Assistant–style local control or futureproofing when vendor clouds change, this guide shows where to start and what to expect.

Quick Facts

What exactly is being reverse‑engineered here?

The thread disassembles an Ariston Velis 80 Wi‑Fi, documents the ESP32‑based control module, UART traffic with the main MCU, and app behaviors (ECO, schedules). It captures boot logs, pinouts, and sample frames, plus builds a PulseView decoder to verify packet length and checksum so the protocol can be mapped for local control or firmware swap. [Elektroda, p.kaczmarek2, post #21717680]

How many heaters and temperature sensors does the Velis use?

Service materials and discussion indicate two separate tanks with two heaters and two temperature sensors. The controller appears to switch heaters interchangeably based on temperature deltas across inlet and outlet tanks for stable delivery. “It probably heats the output tank first and then the input tank.” [Elektroda, Nargo, post #21722352]

What are the key electronics (Wi‑Fi, memory, power)?

Main panel: ESP32‑WATG‑32D Wi‑Fi module, separate MCU, 7‑segment display. SPI flash is FM25Q64 (64 Mbit = 8 MB). Power module uses LNK623DG with relay, EMI filtering, and a varistor. Boot logs confirm 8,388,608‑byte flash size. [Elektroda, p.kaczmarek2, post #21717680]

Does the ESP32 talk directly to the heaters?

No. The ESP32 module communicates with the main MCU over 5 V UART at 9600 baud. The MCU handles heating control. Replacing or modifying the ESP32 firmware requires speaking this UART protocol to influence setpoints or modes. [Elektroda, p.kaczmarek2, post #21717680]

Is there a risk that the ESP32 is locked or encrypted?

Yes. The boot log shows flash_crypt_cnt: 7, which indicates flash encryption. As one expert notes, that often blocks reflashing over UART; experimentation may require a new or substitute module. This is a common edge case during device hacking. [Elektroda, krzbor, post #21718354]

What does ECO mode actually do?

ECO analyzes usage for roughly a week, then adapts heating to habits to cut energy use while maintaining minimum hot water. The app shows time‑to‑heat and estimated shower count, supporting smarter scheduling without manual toggling. “The aim is to reduce energy consumption.” [Elektroda, p.kaczmarek2, post #21717680]

Can I keep everything local and avoid the manufacturer’s cloud?

That’s the project’s goal: understand the UART protocol and run open firmware so the unit works 100% locally, e.g., with Home Assistant. As one contributor puts it, “so that they can be run 100% locally.” Local control avoids cloud shutdown risks. [Elektroda, p.kaczmarek2, post #21717990]

How do I decode the UART traffic with PulseView? (3‑step quick start)

  1. Install PulseView, add the custom “uart exporter” decoder to the decoders folder. 2. Configure UART with RX/TX and 9600 baud, then stack the uart exporter. 3. Right‑click the bottom row and Export all annotations; parse with the shared Python GUI to visualize fields. [Elektroda, DeDaMrAz, post #21717956]

What checksum and framing did the team find?

Frames include a length byte (fourth byte in many cases). Checksums are simple sum modulo 256, with a direction quirk: one direction skips the first byte for the checksum. A custom PulseView plugin validates LEN and CHK and annotates payloads. [Elektroda, p.kaczmarek2, post #21717680]

Is horizontal installation supported and how are the tanks arranged?

The shared diagram and experiences indicate two tanks operated to maintain outlet temperature. Horizontal mounting is discussed in use, but follow manual constraints for mounting orientations and draining procedures to avoid trapped water and service hassles. [Elektroda, Nargo, post #21722352]

What regular maintenance does Ariston recommend?

Documentation notes Anti‑Legionella cycles (60 °C for 1 hour). Users discuss periodic magnesium anode checks and descaling. One user cites guidance suggesting inspection about every two years, varying by water hardness and usage. Always consult your exact model’s manual. [Elektroda, sq3evp, post #21720823]

Can I add Wi‑Fi to a non‑Wi‑Fi Velis model?

If the internal board has space and compatible connectors, an ESP32‑based add‑on could work. However, the OEM module uses 5 V UART levels. Any replacement needs level shifting (e.g., ADuM1201) and the same UART protocol to the MCU. [Elektroda, DeDaMrAz, post #21718484]

What is UART in this context?

UART is a simple serial interface used here between the ESP32 and the main MCU at 9600 baud. The team captured TX/RX waveforms, decoded bytes, verified length fields, and validated checksums to map commands and telemetry. [Elektroda, p.kaczmarek2, post #21717680]

What is OpenBeken (OpenBK7231T_App)?

OpenBeken is an open‑source firmware project for IoT Wi‑Fi chips, enabling local control without vendor clouds. The authors contribute to it and aim to apply similar open control to this ESP32‑based boiler module by replicating the UART protocol. [Elektroda, p.kaczmarek2, post #21718265]

Is there NFC on the board and what does it store?

Yes. A discovered NFC tag exposes structured fields like model codes, temperature limits, power ratings (e.g., PI1/PO1 1500), market region, and serials. These values mirror configuration seen on the bus, aiding correlation during protocol mapping. [Elektroda, DeDaMrAz, post #21724871]

What app features are verifiably available today?

Ariston NET pairing exposes schedules, automations, current/target temperature, time‑to‑heat, and an estimated “showers” count. Anti‑freeze and Anti‑Legionella are implemented features, and ECO learns usage for better efficiency. [Elektroda, p.kaczmarek2, post #21717680]
Generated by the language model.
ADVERTISEMENT