Hi Kajmaj,
Is this correct ?
Sorry for my ignorance, I don’t handle this very well.
Regards.
What you’ve marked is dedicated for Vistapool wifi module.
I have the HF2211 connected to the next on the right and pins 2/3 are used for modbus data (A,B)
I did not try to connect 1/4 from Hydrolife to 1/4 of HF2211 (to power HF) not sure if Hydrolife has sufficient power capacity, it might work or it might burn hydrolife.
I use external pover unit to power HF2211.
Ok, thanks you for information.
Hi Thomas,
You know if the hf2211 module can help communicate with vistapool. I need to connect the hf2211 to the Hydrolife team and connect to the cloud.
Regards,
@Josser If I understood well, you don¨t have the Vistapool wifi module.
In general, there are 3 ways how to operate Vistapool Hydrolife.
My conclusion
Hi kajmaj,
ok, now i have it clearer.
Excuse my ignorance. We will try to connect by modbus and I will tell you the result.
Thank you.
Version of filtration control only with modified timers and warning in the case of time conflicts.
#---------------------------------------------------#
# HIDROLIFE filtration control via MODBUS (no cloud)#
#---------------------------------------------------#
automation:
#-------------------------------------------------
# Run cycles in the right time
#-------------------------------------------------
# Cycle 1
- alias: Filtration_run_cycle1
initial_state: 'on'
trigger:
- platform: template
value_template: >
{{ states('sensor.time') == states('sensor.timer_1_mb') }}
condition:
condition: and
conditions:
- condition: state
entity_id: input_boolean.bazen
state: 'on'
- condition: state
entity_id: input_boolean.cycle1_on
state: 'on'
action:
- service: input_boolean.turn_on
entity_id: input_boolean.filtrace_mb_auto
- service: script.filtration_mb_toggle
- alias: Filtration_end_cycle1
initial_state: 'on'
trigger:
- platform: template
value_template: >
{{ states('sensor.time') == states('sensor.timer_1_mb_end') }}
condition:
condition: and
conditions:
- condition: state
entity_id: input_boolean.bazen
state: 'on'
- condition: state
entity_id: input_boolean.cycle1_on
state: 'on'
action:
- service: input_boolean.turn_off
entity_id: input_boolean.filtrace_mb_auto
- service: script.filtration_mb_toggle
# Cycle 2
- alias: Filtration_run_cycle2
initial_state: 'on'
trigger:
- platform: template
value_template: >
{{ states('sensor.time') == states('sensor.timer_2_mb') }}
condition:
condition: and
conditions:
- condition: state
entity_id: input_boolean.bazen
state: 'on'
- condition: state
entity_id: input_boolean.cycle2_on
state: 'on'
action:
- service: input_boolean.turn_on
entity_id: input_boolean.filtrace_mb_auto
- service: script.filtration_mb_toggle
- alias: Filtration_end_cycle2
initial_state: 'on'
trigger:
- platform: template
value_template: >
{{ states('sensor.time') == states('sensor.timer_2_mb_end') }}
condition:
condition: and
conditions:
- condition: state
entity_id: input_boolean.bazen
state: 'on'
- condition: state
entity_id: input_boolean.cycle2_on
state: 'on'
action:
- service: input_boolean.turn_off
entity_id: input_boolean.filtrace_mb_auto
- service: script.filtration_mb_toggle
# Cycle 3
- alias: Filtration_run_cycle3
initial_state: 'on'
trigger:
- platform: template
value_template: >
{{ states('sensor.time') == states('sensor.timer_3_mb') }}
condition:
condition: and
conditions:
- condition: state
entity_id: input_boolean.bazen
state: 'on'
- condition: state
entity_id: input_boolean.cycle3_on
state: 'on'
action:
- service: input_boolean.turn_on
entity_id: input_boolean.filtrace_mb_auto
- service: script.filtration_mb_toggle
- alias: Filtration_end_cycle3
initial_state: 'on'
trigger:
- platform: template
value_template: >
{{ states('sensor.time') == states('sensor.timer_3_mb_end') }}
condition:
condition: and
conditions:
- condition: state
entity_id: input_boolean.bazen
state: 'on'
- condition: state
entity_id: input_boolean.cycle3_on
state: 'on'
action:
- service: input_boolean.turn_off
entity_id: input_boolean.filtrace_mb_auto
- service: script.filtration_mb_toggle
#-------------------------------------------------
# Script for "MODBUS write" to control filtration
#-------------------------------------------------
script:
# script Ovladani filtrace bazenu
filtration_mb_toggle:
sequence:
- service: modbus.write_register
data:
hub: bazen
unit: 1
address: 1041
value: [0]
- service: modbus.write_register
data:
hub: bazen
unit: 1
address: 1043
data_template:
value: ["{{states('sensor.filtrace_mb_num') | int}}"]
- service: modbus.write_register
data:
hub: bazen
unit: 1
address: 752
value: [1]
- delay: 00:00:01
- service: modbus.write_register
data:
hub: bazen
unit: 1
address: 757
value: [1]
#---------------------------------------------------#
# Timers for filtration #
#---------------------------------------------------#
input_boolean:
filtrace_mb_auto:
cycle1_on:
cycle2_on:
cycle3_on:
binary_sensor:
- platform: template
sensors:
konflikt_casu_mb:
value_template: >
{% set c1_start = states('sensor.timer_1_mb') %}
{% set c1_end = states('sensor.timer_1_mb_end') %}
{% set c2_start = states('sensor.timer_2_mb') %}
{% set c2_end = states('sensor.timer_2_mb_end') %}
{% set c3_start = states('sensor.timer_3_mb') %}
{% set c3_end = states('sensor.timer_3_mb_end') %}
{% if c1_start > c1_end %}
false
{% elif c1_start == c1_end %}
false
{% elif c2_start > c2_end %}
false
{% elif c2_start == c2_end %}
false
{% elif c3_start > c3_end %}
false
{% elif c3_start == c3_end %}
false
{% else %}
true
{% endif %}
attribute_templates:
clash_text: >
{% set c1_start = states('sensor.timer_1_mb') %}
{% set c1_end = states('sensor.timer_1_mb_end') %}
{% set c2_start = states('sensor.timer_2_mb') %}
{% set c2_end = states('sensor.timer_2_mb_end') %}
{% set c3_start = states('sensor.timer_3_mb') %}
{% set c3_end = states('sensor.timer_3_mb_end') %}
{% if c1_start > c1_end %}
Nesprávné zadání
{% elif c1_start == c1_end %}
Nesprávné zadání
{% elif c2_start > c2_end %}
Nesprávné zadání
{% elif c2_start == c2_end %}
Nesprávné zadání
{% elif c3_start > c3_end %}
Nesprávné zadání
{% elif c3_start == c3_end %}
Nesprávné zadání
{% else %}
Správné zadání
{% endif %}
input_select:
cycle1_time:
name: Cyklus 1 - začátek
options:
- '05:00'
- '06:00'
- '07:00'
- '07:30'
- '08:00'
- '09:00'
- '10:00'
cycle2_time:
name: Cyklus 2 - začátek
options:
- '11:00'
- '12:00'
- '13:00'
- '14:00'
- '15:00'
cycle3_time:
name: Cyklus 3 - začátek
options:
- '16:00'
- '17:00'
- '18:00'
- '19:00'
- '20:00'
cycle1_end_time:
name: Cyklus 1 - konec
options:
- '06:00'
- '07:00'
- '07:30'
- '08:00'
- '09:00'
- '10:00'
- '11:00'
cycle2_end_time:
name: Cyklus 2 - konec
options:
- '12:00'
- '13:00'
- '14:00'
- '15:00'
- '16:00'
cycle3_end_time:
name: Cyklus 3 - konec
options:
- '17:00'
- '18:00'
- '19:00'
- '20:00'
- '21:00'
- '22:00'
sensor:
- platform: template
sensors:
timer_1_mb:
value_template: "{{ states('input_select.cycle1_time') }}"
timer_2_mb:
value_template: "{{ states('input_select.cycle2_time') }}"
timer_3_mb:
value_template: "{{ states('input_select.cycle3_time') }}"
timer_1_mb_end:
value_template: "{{ states('input_select.cycle1_end_time') }}"
timer_2_mb_end:
value_template: "{{ states('input_select.cycle2_end_time') }}"
timer_3_mb_end:
value_template: "{{ states('input_select.cycle3_end_time') }}"
# Conflict of time warning #
chybove_hlaseni_filtration_timer:
value_template: "{{ state_attr('binary_sensor.konflikt_casu_mb', 'clash_text') }}"
# Automated set up of value to be written #
filtrace_mb_num:
# automaticke nastaveni hodnot k zapisu do registru pri automatickem ovladani filtrace
friendly_name: “Filtrace zap-vyp”
value_template: >
{% if is_state('input_boolean.filtrace_mb_auto', 'on') %} 1 {% else %} 0 {% endif %}
Hello there. Thank you for your work on this. I just installed a Vistapool wifi module on my Hayward AquaRite+ controller & chlorinator. It pops up OK in the Vistapool website and I can control it there. But when I add and configure the HACS integration, I don’t see any devices or entities. What should happen after I add the integration?
Would you mind posting the Vistapool document with the modbus details again?
If you want to use Vistapool wifi module you do not need modbus. If you want to use modbus, there is no need to use Vistapool wifi module.
Hi everyone,
Appologies to reply to and older thread. Since the last vistapool update earlier this week, pulling the JSON values from the public vistapool site seems impossible now.
So I’ve decided to try Kajmaj’s approach, and use a HF2211 module in order to get all values through MODBUS.
I followed the wiring example in this thread (pin 2 and 3), but basically, I tried all the pins just to be sure (except pin 1 of course: power).
However, I cannot pull any data from the device when connecting to port 23.
I’ve tried to use any register in this thread (dec and hex) using qModMaster, a tool which I used before with other MODBUS devices, but no luck, I cannot get any data from the HF2211.
Does anyone have any recommendations or ideas please?
thanks in advance
Fixed my own issue using an RS485 USB adapter (ch341) + Raspberry Pi.
@steegy I am also a “victim” of the vistapool update.
Connecting the hidrolife directly with the Raspberry Pi sounds like the perfect solution for me.
So you used the mentioned RS485 USB adapter (ch341) together with the Raspberry Pi without the HF2211?
How did you connected the RS485 USB adapter (ch341) to the hidrolife?
And could you maybe share a link / picture of the RS485 USB adapter (ch341) you are using?
Thanks you
@ 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 )
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¶m=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¶m=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¶m=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¶m=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¶m=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¶m=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¶m=udevice&idx=2518&nvalue=0&svalue=Off"
elif [ $filtrationstatsv = "1" ];then
curl "http://domoticz.steegy.com/json.htm?type=command¶m=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¶m=udevice&idx=2519&nvalue=0&svalue=Manual"
elif [ $filtrationmodesv = "1" ];then
curl "http://domoticz.steegy.com/json.htm?type=command¶m=udevice&idx=2519&nvalue=0&svalue=Auto"
else
curl "http://domoticz.steegy.com/json.htm?type=command¶m=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¶m=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¶m=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¶m=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¶m=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.
@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.
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…
Is there a chance you can resend it again? Thanks!