Peristaltic Pump / Autodoser upgrade / conversion to Home Assistant Control Project

Nice work on the timings!

I’m not totally sold on using HA for delicate dosing, but I’ve been running 2 reef-pi integrations seamlessly with HA for a few years now, including 2 peristaltic pump dosers, a ton of sensors, ATOs, lights, and a small aquaponic setup. Info is here in case anyone’s interested. The doser calibration happens in reef-pi and is just triggered through HA automation.

Reef-pi is a great standalone option as well, and I know they have a whole demo on calibration on the Adafruit tutorial.

@cowboy. you said :

Could you share an example of this automation ? Mine actually fail maybe due to conditions.

I find it. Sorry.
I don’t know why my conditions are not yet take in account.

What conditions are you having problems with?

Hello. I am very interesting about this topic. I have a reef with Jebao Led x3, Pulp x3 and I want integrat the statut in my Jeedom. How do you communicate with the autodoser ? Mqtt or other ? Thanks.

Hi Angeck,

Since I’m using Sonoff’s 220v AC 4chan switch for my dosers (Sonoff also makes a low voltage DC version of the 4chan switch) I’m able to use the TASMOTA firmware on the ESP chips that are in Sonoff switches. TASMOTA speaks MQTT natively, and I use MQTT to toggle the dosers state & monitoring everything to ensure it’s operating as expected.*

* - I have sanity check automations in Home Assistant that will watch for dosing activity outside of normal parameters. For instance, if I'm replacing Calcium, Iron, Magnesium, it can be that I have to re-prime the lines & may manually triggering the pump. But I knew it could be I could be distracted while doing something like that (imagine a wife who cuts her finger slicing tomatoes, one of 5 cats deciding to hack up a hairball, etc, etc, etc....or even a faulty WiFi connection, Sonoff malfunctions, cat walks across Sonoff switch mounted on doser at 4am, etc. etc.) So there's automations dedicated to these sanity checks in HA to check to see if a manual dose event runs for more than 1-10 minutes, raise alarm, and try to shut it down the dosing actions, so nothing get's "accidentally" dosed too much.

Ok so now I’m over in this thread asking for help!
This is a great function that I’m looking forward to implementing.
I was able to flash a relay with esphome (thanks Twinsen for pointing out that thread and for the calibration functions!) Also cowboy you mentioned controlling the relays directly from a micro controller. Would the ESP1 that is built onto the relay I’m using have enough memory onboard to support something like that?

So where I am currently stumbling is getting the automations to work. I think my problem is somewhere in the value templates but I’m really not sure. I’m going to post my code here so hopefully someone I can get pointed in the proper direction. I used the lovelace automation creator for the automation, but I was able to clean up the code directly from the yaml file.

- id: '1609876949696'
  alias: Pump 1 at specified frequency
  description: ''
  trigger:
  - platform: time_pattern
    hours: /1
  condition:
    condition: and
    conditions:
      - condition: template
        value_template: 'value_template: "{% if now().minute | int ==  states.input_number.doser_pump1_daily_mins.state | int %}true{% endif %}"'
      - condition: template
        value_template: 'value_template: "{{ now().hour % ( 24 / float(states(''input_select.doser_pump1_daily_freq'')))|int == 0 }}"'
      - condition: state
        entity_id: sensor.dosing_pump
        state: online
      - condition: state
        entity_id: input_boolean.d1p1
        state: 'on'
  action:
  - type: turn_on
    device_id: 3b4ef6a0493cf5e7e5af1ccc8bf25476
    entity_id: switch.d1p1
    domain: switch
  - delay: '''00:00:{{ states.sensor.doser_pump1_time_split.state | int }}'''
  - type: turn_off
    device_id: 3b4ef6a0493cf5e7e5af1ccc8bf25476
    entity_id: switch.d1p1
    domain: switch
  mode: single

and I’m going to post my sensors and booleans just in case something weird is in there as well:

#Precense Detection  
- platform: ping
    hosts:
      dosing_pump: 192.168.1.106

#Sensors
  - platform: template
    sensors:
  # Dosers ONLINE status sensors
      dosing_pump:
        value_template: '{% if is_state("device_tracker.dosing_pump", "home") %}Online{% else %}OFFLINE{% endif %}'
        friendly_name: 'Dosing Pump Status'
        icon_template: >-
          {% if is_state('device_tracker.dosing_pump', 'home') %}
            mdi:power-plug
          {% else %}
            mdi:power-plug-off
          {% endif %}
  # Doser Runtime sensors
      #Pump 1
      doser_pump1_daily_runtime:
        value_template: "{{ (float(states('input_number.doser_pump1_daily_dosage')) / 0.4166666666667 ) | round(2) }}"
        friendly_name: 'Pump 1 Total Dosing Time'
        unit_of_measurement: 'sec'
      doser_pump1_dosage_split:
        value_template: "{{ (float( states('input_number.doser_pump1_daily_dosage')) / float(states('input_select.doser_pump1_daily_freq'))) | round(2) }}"
        friendly_name: 'Pump 1 Individual Dosage Amount'
        unit_of_measurement: 'ml'
      doser_pump1_time_split:
        value_template: "{{ (float(states('sensor.doser_pump1_daily_runtime')) / float(states('input_select.doser_pump1_daily_freq'))) | round(2) }}"
        friendly_name: 'Pump 1 Individual Dosing Time'
        unit_of_measurement: 'sec'

#Booleans
### Dosing Pump ###
#Pump 1#
doser_pump1_daily_dosage:
  name: Daily Dosage 1
  min: 1
  max: 500
  step: 1
  unit_of_measurement: ml
  icon: mdi:beaker
#    initial: 30

doser_pump1_daily_mins:
  name: Dosing Start Minute 1
  min: 00
  max: 59
  step: 1
  mode: box
# initial: 00
  unit_of_measurement: mins

doser_pump1_calibration_dosage:
  name: Calibration Dose in mL
  min: 1
  max: 100
  step: 0.5
  unit_of_measurement: ml
  mode: box
  icon: mdi:flask-outline
# initial: 30

doser_pump1_calibration_time:
  name: Calibration Run Time
  min: 1
  max: 60
  step: 1
  unit_of_measurement: sec
  icon: mdi:timer-sand
#    initial: 30
#    initial: 30

Hopefully I’m just missing something dumb as usual!

Ok so I made a little progress. I’m definitely having issues with my value templates. I don’t understand how they’re written very well so I’m mostly just copying and pasting. Initially nothing worked now I at least have the pump turning on and off at the specified interval.
Initially I had this in my code:

- delay: '''00:00:{{ states.sensor.doser_pump1_time_split.state | int }}'''

This is what made it actually work:

- delay: 00:00:{{ states.sensor.doser_pump1_time_split.state | int }}

So now I have to figure out where all those extra apostrophes need deleted.

And I’ve mostly got it working now. I’m not sure if building the automation through lovelace has changed how it works or if something has possibly changed in a home assistant update but I got the automation to work by putting this value template as a trigger: {{ now().hour % ( 24 / float(states(’‘input_select.doser_pump1_daily_freq’’)))|int == 0 }}.

So my automation reads like this:

  alias: Pump 1 at specified frequency
  description: ''
  trigger:
  - platform: template
    value_template: '{{ now().hour % ( 24 / float(states(''input_select.doser_pump1_daily_freq'')))|int
      == 0 }}'
  condition:
  - condition: and
    conditions:
    - condition: state
      entity_id: input_boolean.d1p1
      state: 'on'
  action:
  - service: switch.turn_on
    data: {}
    entity_id: switch.d1p1
  - delay: 00:00:{{ states.sensor.doser_pump1_time_split.state | int }}
  - service: switch.turn_off
    data: {}
    entity_id: switch.d1p1

This seems to shorten up the automation a tad as well. I haven’t gotten the start minute template to work yet either but I am trying that as a second trigger.
The other thing I’ve noticed is that selecting a daily frequency of 24 for an input number doesn’t work for some reason.

Hello! I just found this thread and am very interested in having HA manage my dosing regiment. I was just planning on grabbing a simple doser from Bulk Reef Supply and then having HA turn on/off the power for a determined amount of time (and i’ll calculate the ml of the doser to determine that length of time.)

My question is, what happens if HA crashes or becomes unresponsive while the doser is on? Do you have a strategy for a failure of the system and if it just keeps pumping additives? I struggle justifying using HA as my doser controller, even though my system is reasonably stable…but it has gone down randomly maybe once a month or so. What if it did that while dosing…that could kill my tank. Any strategies?

1 Like

Hi and Welcome to Home Assistant & our little thread(s) about using Home Assistant as an aquarium controller. I’m always personally really excited & happy to see other people who come around to thinking about doing this & solving some of the issues like the one you’ve asked about. Fortunately, I’ve tackled this issue already, but the actual implementation may vary for you, depending on the size of your total system.

For my deployment, I decided to focus on creating an implementation of High Availability Home Assistant (which I coined the acronym as a HA-HA setup). If you’re not familiar with High Availability setups, just to briefly cover this, there’s a couple of main ways High Availability setups can be constructed; probably the most commonly seen is an implementation at the Operating System layer, where every server of a High Availability setup is an exact duplicate / clone of the next. The other way to implement High Availability is at the Application Layer, and this is was the model I choose to implement. There’s a larger list of pros and cons to either strategy which I won’t go into full detail here, but will say that doing it at the Application layer allows me to more granularly decide on what aspect of Home Assistant needs to have High Availability implemented for, and what doesn’t. And further, by doing it at the Application layer let’s me also run Home Assistant on a variety of different hardware & Operating System choices, where High Availability at the OS level would not let me have this flexibility, as it would require everything (hardware and software) to be identical to each other.

Additionally, since my original idea for my own Aquarium Controller included the innovation to replace “dumb” remote probe boxes traditionally found on other aquarium controllers, with a new innovation of having every remote probe box as a redundant High Availability controller, the Application Layer model of High Availability works better for this, as the number of probes attached to each of my RaspberryPi’s will be a different configuration.

How this all looks might seem a bit extreme, but so is my marine aquarium setup, which I should explain probably first.

At the time (2017) I initially built my HA-HA setup, I was running 12 aquariums. My 3 largest tanks are my display tanks which are setup in my Living area and Dining area of a mostly open plan downstairs. In one of the closed off rooms downstairs is also my dedicated fish room where I had the remainder of all my “working / fragging / breeding” aquariums. All 12 tanks (now currently scaled back to just 7 for some internal and external renovations) are interconnected to a common sump and circulation pump in the Fishroom. The display tanks are connected by pipes that run under our floor. The house itself is a 120 year old traditional Dutch style home; narrow side to side, but multiple floors above.

So my HA-HA deployment is based on 5 Home Assistant “nodes” is spread out throughout the house, with two HA-HA nodes running on RaspberryPi’s downstairs - one in my dedicated Fishroom, and the other in the Livingroom for the Display tanks. On the first floor (or in American terms, the 2nd floor) is the next node of HA, which is what I call the Primary node (all other nodes are secondary slave nodes…more on that in just a bit). Also, unlike all the other RaspberryPi nodes, the Primary node runs on a Virtual Machine (if you don’t know what that is, it’s okay, not so important. Just know it’s running on more of a PC like computer with a lot more CPU power, than a RaspberryPi). The bedroom and loft floors have a RaspberryPi node each of their own as well.

A few advantages to spreading my cluster of 5 HA installs through out the house include:

  • GPIO, I2C, One-Wire and USB inputs for sensors throughout the house and for my aquariums. The same kind of GPIO circuit used for a functional button can also be used for water level sensors and window/door sensors as well. 1-Wire temp probes can easily be run for my aquariums or my house. Same thing for I2C and USB inputs as well.
  • This also gives the advantage of spreading each Home Assistant node out on to its own electrical circuit & associated breaker; thus if a breaker trips in the house for any reason, it might take out a Home Assistant node, but it doesn’t take out all the Home Assistant nodes at once. And if you’ve ever had an aquarium heater fail, causing a circuit breaker / GFCI trip which takes out your aquarium (and the aquarium controller) you’ll probably instantly understand how valuable this feature is. I’ve had that happen a few times before my HA-HA setup, and it always seemed to happen at night, and we’d discover the disaster the next morning. Since my HA-HA setup, we’ve never had that kind of “Silent but deadly failure” situation, and we have had heaters fail & trip breakers in the middle of the night, and we knew about it within seconds of it happening.
  • Cats. We have 5 of them. And they like to play Wrestle Mania a lot. And when they do, they can accidentally take other things out too. I’ve had it twice in 4 years that they went crashing into one of my RaspberryPi’s, despite taking some pretty good measures to set them up where the cats wouldn’t get to them. But cats will always find a way. :slight_smile:

Now, back to the point about Primary vs. Secondary nodes. Just a reminder, this is all implemented at the Home Assistant Level, and that means while functionality is literally copy and pasted from one HA configuration to the next, the secondary node configurations required a bit of extra code added on top.

Basically what this means, is where my AutoDoser functionality on my Primary node (again, runs on a PC Virtual Machine upstairs) is what usually runs by default, my secondaries also include that same functionality, with some extra “conditions” added. Those conditions quite literally prohibit the same code from running on the secondary nodes unless the primary node fails / disappears in some way. And then I have those conditions on each node fine tuned further to determine an order of priority between the slaves, when to act. For instance, if the primary Home Assistant node fails/ disappears from the network, than I don’t want all 4 secondaries to start trying to control the doser pumps, I only need one to do that. So the RaspberryPi in the Fishroom is set first to jump in with auto-doser control. The RaspberryPi Home Assistant in the Livingroom will only jump in to assume control of the auto-dosers, when:
1.) The primary node failed/disappeared
2.) the Fishroom node failed/disappeared (this would be really weird for 1 & 2 to happen, but not impossible)
3.) The Livingroom node can still see and talk to the auto-dosers in the Fishroom
If these three conditions are met, then the Livingroom node will assume control.

The tools to do this are all there in Home Assistant. Ping Device Trackers, Web requests, MQTT Heartbeats, etc. I even uses these to make some evaluative decisions about the nature of the failure. If Web accessibility & MQTT heartbeats ceases, but Pings from the operating system are returned, we know then that HA crashed but the OS is probably still running, so we can automate a soft-restart over an SSH based command. But if the OS doesn’t return pings even, we know we need to cycle the smart socket that that Node is plugged into for a hard reboot. In the meantime, another function can look at the Autodosers & see if they have gone outside of their programmed runtime (my autodosers are controlled via MQTT, so all nodes can see / monitor the activity in real time.), and if so, shut them down. As an additional safety measure, I even have my autodosers plugged into a hardwired smart socket so that if the autodosers become unresponsive or fail in some other way, any node can shutdown the dosers by powering them off.

The same kind of High Availability functionality also controls / monitors my ATO and Kalkwasser additions, since they’e basically the same types of dosing pumps, which gives me the ability to track my daily evaporation rates.

BTW, I forgot to mention, I have failover for Temp regulation too. If the Fishroom node where my sump temp probe is located were to fail, the Primary would switch over to the Livingroom node to pull Temp data from the display tanks for Temp regulation. Every tank has it’s own temp sensor. Which you can also use to determine if you’ve had a main circulation pump mechanical failure. If my sump temp stays normal, but all my display tanks get cold - pump failure has occurred.

If you’ve only got one tank & sump, you probably do not need 5 nodes for your HA-HA setup. Two would be minimum to create a HA-HA setup, and a 3 node HA-HA would give you a really good level of redundancy with an extra level of safety built in. And you can use them distributed through your house as additional hardware based I/O sensor ports, if you want/need too. I also use each RaspberryPi’s analogue sound output to create sound effects throughout the whole house for notifications and alarms. Anytime you open an exterior door to the house, I have sounds of Star-Trek-like doors opening / closing. If HA-HA shuts off the main circulation pump to prevent water from hitting the floor, I give a submarine DIVE or SURFACING klaxon. A failed HA-HA node generates a Nuclear PowerPlant type of Klaxon. Etc, etc.

I’ve got to run and do some exterior painting of my house now, but if you’ve got more questions, just drop them here. I’ll be curious if and how you decide to proceed, so keep us updated please. And good luck. :slight_smile:

Thanks so much for the detailed walkthrough of your home system, cowboy! You’ve got an amazing setup and a seriously impressive workflow of failure-triggers, backups and redundancies. First things first, I need to set up a secondary/backup HA! I don’t know why I haven’t done this yet but I guess I needed to see other people doing it first to know it was possible. I run HA in a VM as well using the qcow2 image. So my plan would be to install HA on a separate machine (I have two Unraid servers each running VMs/dockers) and set up a similar set of ‘secondary node conditions’ so that nothing runs without first confirming the primary is down. Do you have any more details on how you set up those conditions? I use Node-Red/MQTT for 90% of my automations.

As for dosing…there’s a lot of consider. I’ve already installed a Reef Pi (running on a Pi Zero) and I have a pH probe reporting to my HA system. it works wonderfully. Given I can do more with this Reef Pi, my two options are:

A) Add a Reef Pi doser and make it part of that system - independent of HA and open to failures on its own (adding redundancy here seems very difficult and I’m honestly very if the risk is worth the ‘simplicity’ reward.)

or B) get an AC powered doser and trigger it via HA and Z-wave. I need to set up my secondary HA before I’d be comfortable going down this route.

All 12 tanks (now currently scaled back to just 7 for some internal and external renovations) are interconnected to a common sump and circulation pump in the Fishroom. The display tanks are connected by pipes that run under our floor.

Also this is just so fantastic. Certainly something to aspire to creating in my own home (of which just has one tiny 22g with a sump.)

Since we’re getting more on HA-HA setup, I’m redirecting this convo back to the main automation thread here:

Hi, nice work!

I’m new to HA, be gentle…:slight_smile:
just a quick question, does all this code you attached go into configuration.yaml or split between the other yaml files?
i tried to split them, but got error on the Configuration validation → saying error in groups.yaml

1 Like

@cowboy , any help will be appreciated.
Thank you for your help.

Hi Ofer,

Normally, when you have everything in the configuration file, you would begin your subsections with the name of what they are and a colon. For instance, automation section in the configuration.yaml file would begin with:

automation:

And that would typically follow with the next line being an automation alias declaration.

However, when you break out these sections to separate files, you should have instead:

automation: !include automations.yaml

And at that very start of the automations.yaml file you should NOT have another "automation: " declaration. If you do have that, it will produce errors. Check that, and see if that’s the case. If not, maybe you can copy and paste the relevant error statements here so I can help further. (BTW, you probably do not need to copy paste the entire error output, only the beginning part, which should be highlighted in a different color, if you’re using a color supporting VT terminal.

Let us know how / if that helps you or not.

Will try next week after the vacation…
Thank you for your help!

Hi Cowboy!
Congratulations for this amazing work!!
Could you help me with your automation?
I get the automation stopped because of the second template condition:

Thank you!

Hi, can you tell me how to add this code in Home assistant? Any YouTube video on it? I’ve figured out the hardware connections part and linked tesmota and HA.

I’m new to HA, could you please help me where to add this code so that I can control my pumps with dosing.