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 6852 79

TL;DR LABEL_AI_GENERATED

  • 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.
AI summary based on the discussion. May contain errors.
ADVERTISEMENT
Treść została przetłumaczona polish » english Zobacz oryginalną wersję tematu
Listen:
  • ESP32 control write register map for Ariston Velis

    #61 21849248
    DeDaMrAz
    Level 23  
    Posts: 621
    Help: 34
    Rate: 130
    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: 14770
    Help: 659
    Rate: 12913
    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 23  
    Posts: 621
    Help: 34
    Rate: 130
    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.
  • #64 21849431
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14770
    Help: 659
    Rate: 12913
    Nice! Why some controls are toggles, and some are presses?
    Helpful post? Buy me a coffee.
  • Driver nearly ready for long-term water heater testing

    #65 21849434
    DeDaMrAz
    Level 23  
    Posts: 621
    Help: 34
    Rate: 130
    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 23  
    Posts: 621
    Help: 34
    Rate: 130
    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?
  • Touch sensor hijack planned for non-wifi models

    #68 21866196
    DeDaMrAz
    Level 23  
    Posts: 621
    Help: 34
    Rate: 130
    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....
  • ADVERTISEMENT
  • #69 21866970
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14770
    Help: 659
    Rate: 12913
    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.
  • Tuya controllers use native MCUs with Wi-Fi modules

    #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: 6723
    Help: 226
    Rate: 901
    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.
  • ADVERTISEMENT
  • #72 21877212
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14770
    Help: 659
    Rate: 12913
    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.
  • Two-tank probe layout and custom controller plan

    #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: 14770
    Help: 659
    Rate: 12913
    Cool, so, how in the end did you solve ESP32 flash protection?
    Helpful post? Buy me a coffee.
  • #77 21895183
    DeDaMrAz
    Level 23  
    Posts: 621
    Help: 34
    Rate: 130
    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: 14770
    Help: 659
    Rate: 12913
    How did you get module for replacement?
    Helpful post? Buy me a coffee.
  • Support for repairable appliances over consumerism

    #79 21896825
    Anonymous
    Level 1  
  • Request for Q3 and capacitor values on main board

    #80 21917569
    meteoropata
    Level 1  
    Posts: 1
    Hello everyone!
    I found this site while looking for information related to device repair.
    What you do is commendable and I wish you much success in it!
    I know it's not related to the topic, but I would like to ask if anyone is willing to read the values of some components from the main board for me. The boiler is new, but during installation some SMD components were damaged, and I cannot find their values. These are transistor Q3 and capacitors C7, C8, C9 and C11.
    Thank you in advance!
    Green PCB with “88” seven-segment display, spring contacts, and surface-mount electronic components
Listen:

Topic summary

LABEL_AI_GENERATED
The discussion follows reverse engineering of the Ariston Velis 80 Wi‑Fi electric water heater, focusing on its internal ESP32-based Wi‑Fi module, the Ariston NET app, and the communication link between the main MCU and the Wi‑Fi board. The hardware was opened, photographed, and analyzed with a logic analyzer and UART captures at 9600 baud; participants discussed service manuals, tank/heater layout, temperature sensors, NFC tag data, and the possibility of replacing or bypassing the original module with open firmware. Progress included decoding protocol frames, identifying commands for power and temperature control, reading inlet/outlet temperatures, shower counter, heater state, and building a local Raspberry Pi Zero W logger / MITM setup with ADUM1200 isolation and CH342 USB-UART hardware. Later messages extended the work to Home Assistant integration, custom driver development, and experiments with non-Wi‑Fi Ariston variants and ESP32 replacement modules, while noting flash encryption / eFuse protection on some ESP32 boards.
AI summary based on the discussion. May contain errors.

FAQ LABEL_AI_GENERATED

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]
AI summary based on the discussion. May contain errors.
ADVERTISEMENT