Caperplus Q2 pH & TDS meter integration

Hello, this is a brief manual how to integrate Caperplus Q2 pH & TDS meter to HA.

As mentioned in another forum there is probably a possibility to sniff data between the device and mobile app, however I wasn’t able to do that, so I decided to flash onboard esp - for this purpose basic soldering skills and soldering iron pen type with a conical/sharp tip are required.

At first, to create original firmware backup and flash onboard ESP-12F, I soldered pins as described on this site and I used CP2102 USB-UART converter:

To create original firmware backup I used esptool with command (replace PORT for yours PORT of connected converter):

esptool -p PORT -b 460800 read_flash 0 0x400000 caperplus-orig.bin

Then I flashed esp with following code based on this configuration which also uses this library to decode data. Mentioned caperplus_q2_uart_sensor.h library need to be uploaded first to yours /homeassistant/esphome/ localization before code compilation.

esphome:
  name: esp-caperplus-q2
  friendly_name: esp-caperplus-q2
  includes:
    - ./caperplus_q2_uart_sensor.h

esp8266:
  board: d1_mini

# Enable logging
logger:
  baud_rate: 0 #disable logging over uart

# Enable Home Assistant API
api:
  encryption:
    key: "***"

ota:
  - platform: esphome
    password: "***"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esp-Caperplus-Q2"
    password: "***"

captive_portal:

uart:
  id: uart_bus
  rx_pin: GPIO3
  parity: NONE
  data_bits: 8
  stop_bits: 1
  baud_rate: 9600

sensor:
  - platform: custom
    lambda: |-
      auto caper = new CaperPlusQ2UartSensor(id(uart_bus));
      App.register_component(caper);

      return {caper->temperature_sensor, caper->ph_sensor, caper->tds_sensor}; 
    sensors:
      - name: "Temperature"
        unit_of_measurement: "°C"
        accuracy_decimals: 1
        state_class: measurement
        device_class: temperature
      - name: "pH"
        unit_of_measurement: "pH"
        icon: mdi:ph
        accuracy_decimals: 2
        state_class: measurement
      - name: "TDS"
        unit_of_measurement: "ppm"
        accuracy_decimals: 0
        state_class: measurement

After flashing onboard esp, desoldering pins and powering device, it appears in HA :partying_face:

Logs esp-caperplus-q2.yaml
INFO ESPHome 2024.12.2
INFO Reading configuration /config/esphome/esp-caperplus-q2.yaml...
INFO Starting log output from 192.168.1.144 using esphome API
INFO Successfully connected to esp-caperplus-q2 @ 192.168.1.144 in 0.006s
INFO Successful handshake with esp-caperplus-q2 @ 192.168.1.144 in 2.370s
[14:24:15][I][app:100]: ESPHome version 2024.12.2 compiled on Dec 27 2024, 11:00:18
[14:24:15][C][wifi:600]: WiFi:
[14:24:15][C][wifi:428]:   Local MAC: EC:64:C9:FC:CD:0E
[14:24:15][C][wifi:433]:   SSID: [redacted]
[14:24:15][C][wifi:436]:   IP Address: 192.168.1.144
[14:24:15][C][wifi:439]:   BSSID: [redacted]
[14:24:15][C][wifi:441]:   Hostname: 'esp-caperplus-q2'
[14:24:15][C][wifi:443]:   Signal strength: -56 dB ▂▄▆█
[14:24:15][C][wifi:447]:   Channel: 1
[14:24:15][C][wifi:448]:   Subnet: 255.255.255.0
[14:24:15][C][wifi:449]:   Gateway: 192.168.1.1
[14:24:15][C][wifi:450]:   DNS1: 192.168.1.1
[14:24:15][C][wifi:451]:   DNS2: 0.0.0.0
[14:24:15][C][logger:185]: Logger:
[14:24:15][C][logger:186]:   Level: DEBUG
[14:24:15][C][logger:188]:   Log Baud Rate: 0
[14:24:15][C][logger:189]:   Hardware UART: UART0
[14:24:15][C][uart.arduino_esp8266:118]: UART Bus:
[14:24:15][C][uart.arduino_esp8266:120]:   RX Pin: GPIO3
[14:24:15][C][uart.arduino_esp8266:122]:   RX Buffer Size: 256
[14:24:15][C][uart.arduino_esp8266:124]:   Baud Rate: 9600 baud
[14:24:15][C][uart.arduino_esp8266:125]:   Data Bits: 8
[14:24:15][C][uart.arduino_esp8266:126]:   Parity: NONE
[14:24:15][C][uart.arduino_esp8266:127]:   Stop bits: 1
[14:24:15][C][uart.arduino_esp8266:129]:   Using hardware serial interface.
[14:24:15][C][captive_portal:089]: Captive Portal:
[14:24:15][C][mdns:116]: mDNS:
[14:24:15][C][mdns:117]:   Hostname: esp-caperplus-q2
[14:24:15][C][esphome.ota:073]: Over-The-Air updates:
[14:24:15][C][esphome.ota:074]:   Address: esp-caperplus-q2.local:8266
[14:24:15][C][esphome.ota:075]:   Version: 2
[14:24:15][C][esphome.ota:078]:   Password configured
[14:24:15][C][safe_mode:018]: Safe Mode:
[14:24:15][C][safe_mode:019]:   Boot considered successful after 60 seconds
[14:24:15][C][safe_mode:021]:   Invoke after 10 boot attempts
[14:24:15][C][safe_mode:022]:   Remain in safe mode for 300 seconds
[14:24:15][C][api:140]: API Server:
[14:24:15][C][api:141]:   Address: esp-caperplus-q2.local:6053
[14:24:15][C][api:143]:   Using noise encryption: YES
[14:24:20][D][caperplus-q2:094]: Available bytes: 62
[14:24:20][D][caperplus-q2:100]: Found header!
[14:24:20][D][caperplus-q2:115]: pH: 9.16
[14:24:20][D][caperplus-q2:116]: TDS: 0
[14:24:20][D][caperplus-q2:117]: Temp: 21.8
[14:24:20][D][sensor:093]: 'Temperature': Sending state 21.80000 °C with 1 decimals of accuracy
[14:24:20][D][sensor:093]: 'pH': Sending state 9.16000 pH with 2 decimals of accuracy
[14:24:20][D][sensor:093]: 'TDS': Sending state 0.00000 ppm with 0 decimals of accuracy
[14:24:20][D][caperplus-q2:065]: Clearing Serial Buffer
[14:24:20][D][caperplus-q2:094]: Available bytes: 62
[14:24:20][D][caperplus-q2:100]: Found header!
[14:24:20][D][caperplus-q2:115]: pH: 9.16
[14:24:20][D][caperplus-q2:116]: TDS: 0
[14:24:20][D][caperplus-q2:117]: Temp: 21.8
[14:24:20][D][sensor:093]: 'Temperature': Sending state 21.80000 °C with 1 decimals of accuracy
[14:24:20][D][sensor:093]: 'pH': Sending state 9.16000 pH with 2 decimals of accuracy
[14:24:20][D][sensor:093]: 'TDS': Sending state 0.00000 ppm with 0 decimals of accuracy
[14:24:20][D][caperplus-q2:065]: Clearing Serial Buffer
[14:24:20][D][caperplus-q2:094]: Available bytes: 62
[14:24:20][D][caperplus-q2:100]: Found header!
[14:24:20][D][caperplus-q2:115]: pH: 9.16
[14:24:20][D][caperplus-q2:116]: TDS: 0
[14:24:20][D][caperplus-q2:117]: Temp: 21.8
[14:24:20][D][sensor:093]: 'Temperature': Sending state 21.80000 °C with 1 decimals of accuracy
[14:24:20][D][sensor:093]: 'pH': Sending state 9.16000 pH with 2 decimals of accuracy
[14:24:20][D][sensor:093]: 'TDS': Sending state 0.00000 ppm with 0 decimals of accuracy
[14:24:20][D][caperplus-q2:065]: Clearing Serial Buffer

To clear your doubts:

  • Caperplus mobile app is no longer working
  • physical calibration button still works as designed

Good luck!