Vistapool Integration

@ DIeHarke Sure,

Here’s what I did.

I have a Raspberry Pi3 with raspbian installed close to my sugar valley computer.
I already used this Pi to share an RFXCOM controller with my domoticz server using ser2net.
(basically to share a USB module over ethernet)

In order to read the sugar valley’s modbus data, I bought this USB adapter from aliexpress (ch341).

FYI, I only want to read MODBUS data, not write it.

Use the “extern” RS485 connector on the sugar valley computer (right side).
On this connector you need PIN 3 and 4.
PIN 3 = white wire
PIN 4 = red wire

PIN3-white goes to ch341 PIN A
PIN4-red goes to ch341 PIN B

Connect the ch341 to the Pi, and install mbpoll

wget -O- http://www.piduino.org/piduino-key.asc | sudo apt-key add -
echo 'deb http://raspbian.piduino.org stretch piduino' | sudo tee /etc/apt/sources.list.d/piduino.list
sudo apt update
sudo apt install mbpoll

Find the USB ID using “dmesg | grep tty”

Use mbpoll to read a few registers, in order to test connectivity:
mbpoll -m rtu -b 19200 -t 4 -r 256 /dev/ttyUSB1 -P none -1 -c 31 -q -0

In this example, I read register 256 + the next 31 registers.
-0 is important here, because sugar valley starts with register 0, not register 1 like most devices do.

Then I created this script to import only the values I need, to pre-created domoticz sensors.
(I know my scripting skills are limited, but they do what I need so far :slight_smile: )

mbpoll -m rtu -b 19200 -t 4 -r 100 /dev/ttyUSB1 -P none -1 -c 31 -q -0 > /steegy/vistapool-modbusrtu-domot3/poll-part1
mbpoll -m rtu -b 19200 -t 4 -r 256 /dev/ttyUSB1 -P none -1 -c 31 -q -0 >> /steegy/vistapool-modbusrtu-domot3/poll-part1
mbpoll -m rtu -b 19200 -t 4 -r 1000 /dev/ttyUSB1 -P none -1 -c 31 -q -0 >> /steegy/vistapool-modbusrtu-domot3/poll-part1
mbpoll -m rtu -b 19200 -t 4 -r 1031 /dev/ttyUSB1 -P none -1 -c 31 -q -0 >> /steegy/vistapool-modbusrtu-domot3/poll-part1
mbpoll -m rtu -b 19200 -t 4 -r 1280 /dev/ttyUSB1 -P none -1 -c 31 -q -0 >> /steegy/vistapool-modbusrtu-domot3/poll-part1


##remove spaces and tabs from export file
cat /steegy/vistapool-modbusrtu-domot3/poll-part1 | tr -d "[:blank:]" > /steegy/vistapool-modbusrtu-domot3/poll-part2



############################################
# update Pool Hydrolysis [257] - IDX2537
###########################################

hydrosv=$(cat /steegy/vistapool-modbusrtu-domot3/poll-part2 | grep  '\[257\]' | sed 's/^.*://')
if [ -z "$hydrosv" ]
then
        echo "empty var not doing any update"
else
        hydrosv="$(( hydrosv / 10 ))"
        curl "http://domoticz.steegy.com/json.htm?type=command&param=udevice&idx=2537&nvalue=0&svalue=$hydrosv"
fi

############################################
# update Pool Current pH [258] - IDX2524
###########################################

phsv=$(cat /steegy/vistapool-modbusrtu-domot3/poll-part2 | grep  '\[258\]' | sed 's/^.*://')
if [ -z "$phsv" ]
then
        echo "empty var not doing any update"
else
        phsv=$(echo "scale=2; $phsv /100" | bc)
        curl "http://domoticz.steegy.com/json.htm?type=command&param=udevice&idx=2524&nvalue=0&svalue=$phsv"
fi

############################################
# update current Redox [259] - IDX2522
############################################

redoxcurrentsv=$(cat /steegy/vistapool-modbusrtu-domot3/poll-part2 | grep  '\[259\]' | sed 's/^.*://')
if [ -z "$redoxcurrentsv" ]
then
        echo "empty var not doing any update"
else
        curl "http://domoticz.steegy.com/json.htm?type=command&param=udevice&idx=2522&nvalue=0&svalue=$redoxcurrentsv"
fi

############################################
# update temperature [262] - IDX2514
############################################

tempsv=$(cat /steegy/vistapool-modbusrtu-domot3/poll-part2 | grep  '\[262\]' | sed 's/^.*://')
if [ -z "$tempsv" ]
then
        echo "empty var not doing any update"
else
        tempsv=$(echo "scale=1; $tempsv /10" | /usr/bin/bc)
        ### temp offset = 1.7 degrees
        temp2sv=$(echo "scale=2; $tempsv +1.7" | bc)
        curl "http://domoticz.steegy.com/json.htm?type=command&param=udevice&idx=2514&nvalue=0&svalue=$temp2sv"
fi

############################################
# update Pool Target pH [1284] - IDX2525
############################################

targetphsv=$(cat /steegy/vistapool-modbusrtu-domot3/poll-part2 | grep  '\[1284\]' | sed 's/^.*://')
if [ -z "$targetphsv" ]
then
        echo "empty var not doing any update"
else
        targetphsv=$(echo "scale=2; $targetphsv /100" | bc)
        curl "http://domoticz.steegy.com/json.htm?type=command&param=udevice&idx=2525&nvalue=0&svalue=$targetphsv"
fi

############################################
# update target Redox [1288] - IDX2523
############################################

redoxtargetsv=$(cat /steegy/vistapool-modbusrtu-domot3/poll-part2 | grep  '\[1288\]' | sed 's/^.*://')
if [ -z "$redoxtargetsv" ]
then
        echo "empty var not doing any update"
else
        curl "http://domoticz.steegy.com/json.htm?type=command&param=udevice&idx=2523&nvalue=0&svalue=$redoxtargetsv"
fi

############################################
# update Pool Filtration Status [1057] - IDX2518
############################################

filtrationstatsv=$(cat /steegy/vistapool-modbusrtu-domot3/poll-part2 | grep  '\[1057\]' | sed 's/^.*://')
if [ -z "$filtrationstatsv" ]
then
        echo "empty var not doing any update"
else
        if [ $filtrationstatsv = "0" ];then
                curl "http://domoticz.steegy.com/json.htm?type=command&param=udevice&idx=2518&nvalue=0&svalue=Off"
        elif [ $filtrationstatsv = "1" ];then
                curl "http://domoticz.steegy.com/json.htm?type=command&param=udevice&idx=2518&nvalue=0&svalue=On"
        fi
fi

############################################
# update Pool Filtration Mode [1041] - IDX2519
############################################

filtrationmodesv=$(cat /steegy/vistapool-modbusrtu-domot3/poll-part2 | grep  '\[1041\]' | sed 's/^.*://')
if [ -z "$filtrationmodesv" ]
then
        echo "empty var not doing any update"
else
        if [ $filtrationmodesv = "0" ];then
                curl "http://domoticz.steegy.com/json.htm?type=command&param=udevice&idx=2519&nvalue=0&svalue=Manual"
        elif [ $filtrationmodesv = "1" ];then
                curl "http://domoticz.steegy.com/json.htm?type=command&param=udevice&idx=2519&nvalue=0&svalue=Auto"
        else
                curl "http://domoticz.steegy.com/json.htm?type=command&param=udevice&idx=2519&nvalue=0&svalue=UNKNOWN"
        fi
fi

############################################
# update Pool Pump Flow Status [269] - IDX2711
## get bit number 3 (0x0008)
## 1 = flow running
## 0 = flow stopped
###########################################

flowsv=$(cat /steegy/vistapool-modbusrtu-domot3/poll-part2 | grep  '\[269\]' | sed 's/^.*://')


echo `date '+%d/%m/%Y_%H:%M:%S'` $flowsv >> /steegy/vistapool-modbusrtu-domot3/flow-log

if [ -z "$flowsv" ]
then
        echo "empty var not doing any update"
else


        ##echo "$flowsv"
        ##flowsvbinary=$(echo "obase=2;$flowsv" | bc)
        ##echo "$flowsvbinary"

        ##flowsvhex=$(echo "obase=16;$flowsv" | bc)
        ##echo "$flowsvhex"


flowsv=$((("$flowsv" & 0x0008) != 0))
        ##echo "$flowsv"

        if [ $flowsv = "1" ];then
                curl "http://domoticz.steegy.com/json.htm?type=command&param=udevice&idx=2711&nvalue=1"
                echo "flow running" >> /steegy/vistapool-modbusrtu-domot3/flow-log

        elif [ $flowsv = "0" ];then
                curl "http://domoticz.steegy.com/json.htm?type=command&param=udevice&idx=2711&nvalue=0"
                echo "flow stopped" >> /steegy/vistapool-modbusrtu-domot3/flow-log

        fi
fi

############################################
# update Pool Cover  [Also 269] - IDX4005
# get bit number 4 (0x0010)
# 0 = cover open
# 1 = cover closed
############################################


coversv=$(cat /steegy/vistapool-modbusrtu-domot3/poll-part2 | grep  '\[269\]' | sed 's/^.*://')


if [ -z "$coversv" ]
then
        echo "empty var not doing any update"
else

coversv=$((("$coversv" & 0x0010) != 0))
        ##echo "$coversv"


        if [ $coversv = "0" ];then
                curl "http://domoticz.steegy.com/json.htm?type=command&param=udevice&idx=4005&nvalue=0&svalue=Open"
                echo "cover opened" >> /steegy/vistapool-modbusrtu-domot3/flow-log
        elif [ $coversv = "1" ];then
                curl "http://domoticz.steegy.com/json.htm?type=command&param=udevice&idx=4005&nvalue=0&svalue=Closed"
                echo "cover closed" >> /steegy/vistapool-modbusrtu-domot3/flow-log
        fi
fi


In case you want to add additional registers, you can get the register numbers from the sugar valley modbus PDF manual, just remeber to translate HEX to decimal first.
But in my case, these are the most important registers I need, in order to get my winter-anti-freeze protection automation up and running, which is automated through domoticz.

My first attempt was to share the ch341 USB adapter using ser2net, with my domoticz server, but this was unsuccessful, so I decided to have the Pi run the mbpoll script (or optinally, you can call the mbpoll export though SSH)

FYI, to explain the “-z $flowsv” routine:
I have about a 1/100 chance that a modbus read fails, in case it does, and my variables are empty, I want to prevent the script to update my domoticz sensors, and wait untill the next successful run to update the sensor.

1 Like

@steegy Thank you very much for your detailed explanation. This helps me a lot to get into the topic MODBUS. And I hope for many others as well for all that effort you have put in writing this.

1 Like

In case the new API access gets delayed or blocked, does anybody know if the same modbus approach can be done by using a UART to WiFi module like this one? The same module is used by the Visonic Alarm component in HA and works great. Any help reading values just for temp, pH, Rx and filtration on/off? Thanks.

I’m trying to access by Modbus with a HF5111B module. Can someone share a working config in HA and the correct settings in the module? I keep getting

Pymodbus: Modbus Error: [Input/Output] Modbus Error: [Invalid Message] No response received, expected at least 8 bytes (0 received)

Is there something that needs to be activated in the Hydrolife unit for the EXTERN modbus connector to work? Thanks.

I found a solution with a ESP8266 and Tasmota firmware, works super. And cheap… :slight_smile:

https://tasmota.github.io/docs/NeoPool/

Is there a chance you can resend it again? Thanks!

Here it is: Dropbox - MODBUS PARA CLIENTES (ENG).pdf - Simplify your life

I have the basic data also working now with the ESPHome firmware and the modbus controller component. And I use a level-shifter between the ESP and RS485 module. To convert the 5v level to 3.3. It should work without, but I found the RS485 module getting hot and not working properly…

My coding skills are not super, so I don’t know how to integrate the switches of the Oxilife, hopefully other reader’s can help out with that. :slight_smile:

This is my esphome code:

external_components:
  # use  GitHub
  - source:
      type: git
      url: https://github.com/martgras/esphome
      ref: modbus_component
    components: [ modbus_controller ]

esphome:
  name: oxilife
  platform: ESP8266
  board: d1_mini

wifi:
  ssid: "XXXXXXXX"
  password: "XXXXXXXXXXXXX"



# Enable logging
logger:


# Enable Home Assistant API
api:

ota:

web_server:
  port: 80

uart:
  id: mod_bus
  tx_pin: 3
  rx_pin: 1
  baud_rate: 19200
  stop_bits: 1
  
modbus_controller:
  id: oxilife
  ## the Modbus device addr
  address: 0x1
  uart_id: mod_bus
  command_throttle: 0ms
  # ctrl_pin: 5    # if you need to set the driver enable (DE) pin high before transmitting data configure it here
  setup_priority: -10
 
  sensors:
    - id: temperatuur
      name: "Water Temperatuur Zwembad"
      address: 0x0106
      offset: 0
      unit_of_measurement: "°C"
      modbus_functioncode: "read_input_registers"
      value_type: U_WORD
      accuracy_decimals: 2
      skip_updates: 60
      filters:
        - multiply: 0.1
        
    - id: pH
      name: "pH Waarde Zwembad"
      address: 0x0102
      offset: 0
      unit_of_measurement: "pH"
      modbus_functioncode: "read_input_registers"
      value_type: U_WORD
      accuracy_decimals: 2
      skip_updates: 60
      filters:
        - multiply: 0.01
        
    - id: cl
      name: "Vrije Chloor Waarde Zwembad"
      address: 0x0104
      offset: 0
      unit_of_measurement: "ppm"
      modbus_functioncode: "read_input_registers"
      value_type: U_WORD
      accuracy_decimals: 2
      skip_updates: 60
      filters:
        - multiply: 0.01
        
    - id: hydrolyse
      name: "Hydrolyse Percentage Zwembad"
      address: 0x0101
      offset: 0
      unit_of_measurement: "%"
      modbus_functioncode: "read_input_registers"
      value_type: U_WORD
      accuracy_decimals: 0
      skip_updates: 60
      filters:
        - multiply: 0.1

      
1 Like

Doesn’t work !
Integrations does not generate the integration after HACS install

Is there any update the above projects?

1 Like

This works in all Hayward models?

1 Like

Do I understand correctly that it is no longer possible to integrate the vistapool cloud in HA (using the vistapool wifi device)?
That means the only way to get vistapool data in HA is using modbus and direct communication (PI with usb adapter or HF2211 )?

I want to order the vistapool wifi device, but if I can’t use it for HA integration I don’t think I’m interested.

You are right. Latest API changes disabled cloud access. Modbus works great though, and you can use either an ethernet or wifi modbus module.

1 Like

Correct, buying a vistapool wifi device would be a waste of money since they disabled cloud API access.
Using MODBUS is the only way to get data from the sugar valley now.
I never got the HF2211 to work, but the PI + usb adapter solution is still working fine for me.

1 Like

There is a tasmota project that talks to it directly, exposes sensors and also switches for the various parts.
https://tasmota.github.io/docs/NeoPool/

Can anyone share their full configuration (modbus)? The one shared by @kajmaj is using the old modbus syntax I think.

I am planning to use a pi with RS485 dongle in combination with ser2net. This way my HA server can use modbus communication to the remote pi.

Current, working, modbus sensors reading data from Vistapool Hidrolife:

modbus:
- name: bazen
  type: tcp
  host: 192.168.1.3
  port: 8899
  delay: 5
  timeout: 5
  sensors:
    - name: MBF_MEASURE_PH #  hodnota pH
      slave: 1
      address: 258
      input_type: holding
      data_type: uint16
      scale: 0.01
      precision: 2
      scan_interval: 90
      unit_of_measurement: pH
#    - name: MBF_PAR_PH1 #  horni hranice pH
#      slave: 1
#      address: 1284
#      input_type: holding
#      data_type: uint16
#      scale: 0.01
#      precision: 1
#    - name: MBF_PAR_PH2  #   dolni hranice pH
#      slave: 1
#      address: 1285
#      input_type: holding
#      data_type: uint16
#      scale: 0.01
#      precision: 1
    - name: MBF_MEASURE_TEMPERATURE #  teplota vody
      slave: 1
      address: 262
      input_type: holding
      data_type: uint16
      unit_of_measurement: °C
      scale: 0.1
      precision: 1
      scan_interval: 90
    - name: MBF_PH_STATUS #  AL3, stav pH, peristaltika 
      slave: 1
      address: 263
      input_type: holding
      data_type: uint16
      scan_interval: 90
    - name: MBF_PAR_FILTRATION_STATE # stav filtrace (zap/vyp)
      slave: 1
      address: 1057
      input_type: holding
      data_type: uint16
      scan_interval: 90
    - name: MBF_PAR_FILT_MANUAL_STATE # MBF_PAR_FILT_MANUAL_STATE-stav filtrace zap/vyp
      slave: 1
      address: 1043
      input_type: holding
      data_type: uint16
      scan_interval: 90
    - name: MBF_PAR_FILT_MODE #  režim filtrace
      slave: 1
      address: 1041
      input_type: holding
      data_type: uint16
      scan_interval: 90
    - name: MBF_RELAY_STATE #  stav jednotlivych rele
      slave: 1
      address: 270
      input_type: holding
      data_type: uint16
    - name: MBF_PAR_HIDRO_COVER_ENABLE #  aktivace krytu 1/0
      slave: 1
      address: 1068
      input_type: holding
      data_type: uint16
      scan_interval: 90
    - name: MBF_PAR_HIDRO_COVER_REDUCTION # redukce hydrolyzy v % 
      slave: 1
      address: 1069
      input_type: holding
      data_type: uint16
      scan_interval: 90
    - name: MBF_HIDRO_STATUS # stav systemu hydrolyzy 
      slave: 1
      address: 269
      input_type: holding
      data_type: uint16 
      scan_interval: 90
1 Like

Hello,

Excuse my English, I’m Spanish.
It is not clear to me, for it to work in HA I have to buy vistapool? or do I have to use this option with tasmota (Sugar Valley NeoPool Controller - Tasmota)? The tasmota option is far from my knowledge.

Thanks for the help

Helo here another spanish with the same problem.

This part its in spanish, sorry.

Hola tio.

Yo voy a intentarlo con esa opción con Tasmota, si quieres podemos compartir experiencias.

Saludos.

Brilliant,

Well, I’ll try, I’m waiting for it to arrive and install the equipment, as soon as I have it, I’ll start.

At the moment I can start by buying the TTL UART to RS485 converter.

let’s go!