Be Smart, Go Local.

How I Automated My Aquarium Using A Sonoff

Using a spare Sonoff 4CH Pro to automate my aquarium pump, heater, ambient light and UVB bulb.

Using a Sonoff 4CH Pro to Automate an Aquarium

My daughter is 2 years old and she has a pet turtle, a red eared slider named Lulu that she adores. As she is too young to care for it by herself, I decides I would automate its aquarium and living area to make it easier for her to enjoy the turtle. I used a spare Sonoff 4CH Pro I had lying around to wire everything up together and setup automations, reminders and trackers inside Home Assistant.

Wiring the components to the Sonoff 4CH Pro

Wiring everything together proved to be somewhat of a challenge, considering the terminals on the Sonoff are too close together. I needed to connect 4 wires of the components neutral to the neutral coming out of the mains.

After a failed attempt to connect the wires directly, I decides its best to use screw terminals and connector terminal clamps. I also needed to bridge the Live wire (L) between the Sonoff’s COM ports. I installed small terminal clamps and connected them without issues. All that remained, was the Live out wire, or the NO terminal on the switch wired to each of the devices L wire. The final wiring looked like this:

Integrating with Home Assistant

As I had not gotten around to flashing this particular Sonoff with Tasmota, I had to integrate it with Home Assistant via a custom integration. I used AlexxIT’s excellent SonoffLAN integration. This particular integration is capable of adding devices directly to Home Assistant, to be used in a couple of modes: Local and Cloud, Cloud only, Local mode with load config from cloud and Local only mode with manually getting the device key.

Whichever mode you choose, you need to first create a Sonoff account, using the eWelink app in the Play Store/App Store. Follow the instructions to pair your particular device to your account. After you confirm it is working, I suggest checking for a firmware update within the app.

The integration is available in HACS, or you can install it manually by copying the sonoff folder from the latest release page.

For my use case, I used the Local and Cloud mode:

#Add this to your configuration.yaml
sonoff:
  username: myemail@gmail.com #Your ewelink account
  password: mypassword #Your ewelink password

Important: Cloud mode cannot work simultaneously with two copies of the component: For example an eWelink account and a Home Assistant integration. You need to create a second account and share the device within the app with your second account, than use that in configuration.yaml

After you have configured everything, restart Home Assistant. Entities will be automatically discovered from the Sonoff 4CH Pro in our use case and added into Home Assistant.

The integration sets device_class: switch by default, but I wanted to change the Light and UVB light to device_class: light for better Home Assistant representation and control. The way we do this is we add the device ID under the sonoff: code in configuration.yaml. For example:

#Add this to your configuration.yaml
sonoff:
  username: myemail@gmail.com #Your ewelink account
  password: mypassword #Your ewelink password
  devices:
    10002bca76:
      name: Aquarium
      device_class:
        - switch
        - switch
        - light
        - light

Note: The easies way to find your Device ID is to open the eWelink app, click on the device, click on the three dots in the right corner and scroll to the bottom. You will see your Device ID here, after Model.

Because my Sonoff 4CH Pro has 4 terminals, we add them into a list. The first and second terminal will remain switches, because the aquarium pump and heater are connected to those. The third and forth will be converted to lights, as the Ambient light and UVB light are connected to them.
See all device_class options here. Again, restart Home Assistant to load the new configuration.

Automating the boring stuff

Turtles are very active little creatures, they like to swim a lot, dive, play and explore. The single most important thing about their well-being is the UVB light. If you are keeping an Aquarium inside such as myself, you MUST have an UVB light. They like to bask under the light for heat and to absorb the much needed UVB rays. It is important to turn of the light at sunset, to not mess with their circadian rhythms. So we setup two simple automations to turn the UVB light on at sunrise and turn it off at sunset. Example:

Turn ON UVB Light At Sunrise

#Turn ON UVB At Sunrise
alias: 'Aquarium: Turn On UVB'
description: Turn on UVB light each morning at sunrise
trigger:
  - platform: sun
    event: sunrise
    offset: '0'
condition: []
action:
  - service: light.turn_on
    data: {}
    target:
      entity_id: light.sonoff_aquarium_uvb
mode: single

Turn OFF UVB Light At Sunset

#Turn OFF UVB at sunset
alias: 'Aquarium: Turn OFF UVB '
description: Turn off UVB light each evening at sunset
trigger:
  - platform: sun
    event: sunset
    offset: '0'
condition: []
action:
  - service: light.turn_off
    data: {}
    target:
      entity_id: light.sonoff_aquarium_uvb
mode: single

This will turn on the UVB light without any conditions, because the turtle needs UVB whether you are home or not. We will use the same way to control the ambient light, which is a simple led light for humans to see into the tank and create a beautiful view. We setup two automations to turn the light on at sunset, and turn it off at midnight (because it is not needed after). Example:

Turn ON Ambient Light At Sunset

#Turn on Ambient Light After Sunset
alias: 'Aquarium: Turn On Ambient Light'
description: Turn on Ambient Light after sunset
trigger:
  - platform: sun
    event: sunset
    offset: '0'
condition: []
action:
  - service: light.turn_on
    data: {}
    target:
      entity_id: light.sonoff_aquarium_light
mode: single

Turn OFF Ambient Light at Midnight

#Turn off Ambient Light At Midnight
alias: 'Aquarium: Turn OFF Ambient Light at midnight'
description: Turn off Ambient Light At Midnight
trigger:
  - platform: time
    at: '00:00'
condition: []
action:
  - service: light.turn_off
    data: {}
    target:
      entity_id: light.sonoff_aquarium_light
mode: single

Cleaning Reminders with input_datetime helpers

Next we will setup simple reminders and notifications to track the cleaning of the tank.
For this, we need to setup two input_datetime helpers, one for weekly clean (partial) and one for monthly clean (full). You can use the UI of Home Assistant under Configuration >  Automations & Scenes > Helpers tab for creating the input_datetime and name them accordingly. For this particular use case, we do not heed a timestamp, as its only important to track which days the aquarium has been cleaned. Example:

#Add this to your configuration.yaml
input_datetime:
  aquarium_weekly_clean:
    name: Aquarium Weekly Clean Date
    has_date: true
    has_time: false
    icon: mdi:fishbowl-outline
  aquarium_monthly_clean:
    name: Aquarium Monthly Clean Date
    has_date: true
    has_time: false
    icon: mdi:fishbowl
    

Setting clean date with NFC Tags

You can add the input_datetime entity to your dashboard, and manually input todays date when you clean the tank. But where is the fun in that? We need to automate and streamline, as this is Home Assistant. I chose to use NFC tags glued to the side of the tank, to set todays date to the corresponding helper via a service call. Two tags were needed for my use case, one for the weekly clean and another for the full, monthly clean.

To add NFC tags to Home Assistant, you need to open the HA companion app, navigate to Configuration > Tags > + Add tag. Give it a name and a Tag ID, click Create and Write and scan the NFC tag. Than we can setup the automations to set todays date on the input_datetime helpers:

Tag Automation: Performed a weekly clean

alias: 'Aquarium: Performed a weekly clean'
description: 'Aquarium: Performed a weekly clean'
trigger:
  - platform: tag
    tag_id: Aquarium Weekly Clean
condition: []
action:
  - service: input_datetime.set_datetime
    data:
      date: "{{ now().strftime('%Y-%m-%d') }}"
    target:
      entity_id: input_datetime.aquarium_weekly_clean
mode: single

Tag Automation: Performed a monthly clean

alias: 'Aquarium: Performed a monthly clean'
description: 'Aquarium: Performed a monthly clean'
trigger:
  - platform: tag
    tag_id: Aquarium monthly Clean
condition: []
action:
  - service: input_datetime.set_datetime
    data:
      date: "{{ now().strftime('%Y-%m-%d') }}"
    target:
      entity_id: input_datetime.aquarium_monthly_clean
mode: single

Daily reminder for cleaning the tank

Next, we setup a simple automation to fire daily at 16:00 (this is the time convenient for me, as I get off work around 16:00), to remind us of the days remaining until the tank needs to be cleaned: both partially and fully.

alias: 'Aquarium: Clean Notify'
description: 'Aquarium: Clean notify'
trigger:
  - platform: time
    at: '16:00'
condition: []
action:
  - service: notify.mobile_app_s21ultra
    data:
      title: Aquarium Cleaning Reminder
      message: >-
        Partial Clean in: 
          {{ (((as_timestamp(now())-states.input_datetime.aquarium_weekly_clean.attributes.timestamp)) | int(0) /60/1440-7) | round(0) | abs}} day(s) <br> 
        Full Clean in:  
          {{ (((as_timestamp(now())-states.input_datetime.aquarium_monthly_clean.attributes.timestamp)) | int(0) /60/1440-30) | round(0) | abs}} day(s)
mode: single
We get a nice notification with a reminder countaing days to next clean!

Creating a custom dashboard

If you are a frequent UI user, you might want to represent the data in your dashboard and for quick toggles to turn off the pump and heater when cleaning the tank. I used some basic home assistant cards: Vertical Stack card, Entity card, Markdown card and the great and powerful custom card card-mod to remove card borders and background.

Configuration example

type: vertical-stack
cards:
  - type: entities
    title: Aquarium
    show_header_toggle: false
    style: |
      ha-card {
        background-color: var(--primary-primary-color);
        box-shadow: none;
      }
    entities:
      - type: section
      - entity: light.sonoff_aquarium_light
      - entity: light.sonoff_aquarium_uvb
      - type: divider
      - entity: switch.sonoff_aquarium_pump
        name: Water Pump
      - entity: switch.sonoff_aquarium_heater
        name: Water Heater
      - type: divider
      - entity: input_datetime.aquarium_weekly_clean
      - entity: input_datetime.aquarium_monthly_clean
      - type: section
  - type: markdown
    style: |
      ha-card {
        background-color: var(--primary-primary-color);
        box-shadow: none;
      }
    content: >-
      &nbsp;&nbsp;<ha-icon icon="mdi:fishbowl-outline"/></ha-icon>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
      **Last Partial Clean (week):** {{ (((as_timestamp(now())-states.input_datetime.aquarium_weekly_clean.attributes.timestamp)) | int(0) /60/1440-1) | round(0) }} day(s) ago <br>
      &nbsp;&nbsp;<ha-icon icon="mdi:fishbowl-outline"/></ha-icon>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
      **Next Partial Clean (week):** in {{ (((as_timestamp(now())-states.input_datetime.aquarium_weekly_clean.attributes.timestamp)) | int(0) /60/1440-7) | round(0) | abs}} day(s) <br>
      &nbsp;&nbsp;<ha-icon icon="mdi:fishbowl-outline"/></ha-icon>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
      **Last Partial Clean (month):** {{ ((as_timestamp(now())-states.input_datetime.aquarium_monthly_clean.attributes.timestamp)) | int(0) /60/1440) | round(0) }} day(s) ago <br>
      &nbsp;&nbsp;<ha-icon icon="mdi:fishbowl-outline"/></ha-icon>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
      **Next Partial Clean (month):** in {{ (((as_timestamp(now())-states.input_datetime.aquarium_monthly_clean.attributes.timestamp)) | int(0) /60/1440-30) | round() | abs}} day(s) 
  - type: entities
    style: |
      ha-card {
        background-color: var(--primary-primary-color);
        box-shadow: none;
      }
    entities:
      - type: section

Summary

Because turtles are messy little creatures, its best to leave the aquarium filter pump running 24/7. That is why no automations are needed for this entity. I use the toggle to turn it off when cleaning the tank. The same applies to the water heater, as it has its own thermostat and a knob from which you can set the desired temperature. It turns itself on/off automatically to keep the water conditions optimal. Now Lulu is a happy little red eared slider!

She likes to climb the plants and smile 🙂

Sources:

1 thought on “How I Automated My Aquarium Using A Sonoff”

  1. hello,

    I don’t get this to work

    “{{ (((as_timestamp(now())-states.input_datetime.aquarium_weekly_clean.attributes.timestamp)) | int(0) /60/1440-1) | round(0) }}”

Comments are closed.