Question - Tracking Water Softener Salt

I have recently had a completely dumb water softener installed at my house. The model I have takes two blocks of salt which are meant to last around a month each time. I don’t believe there is a way to make the softener smart in any way (someone can correct me if I’m wrong!) but what I would like to do is track the salt usage.

My plan is to have a connected button next to the water softener, and every time I put new salt blocks in, I can press that button which will then start a count up (not down!) timer. Obviously HA can help me with the connection of the button and the resetting of the timer, however I’d like to track how long between button presses (and therefore salt refills) over time somehow.

Has anyone implemented anything similar for

  1. Counting up timers
  2. Storing this kind of minimalistic data long term

Technically all that I’d really need would be a spreadsheet with the date the salt was added and the date of the next button press (signalling its replacement), which HA could potentially provide…However I’m not aware of any integrations that would achieve this, hence my query!

Thanks in advance :smiley:

Well you could get started with a input_datetime.

1 Like

Thanks very much, I’d seen that mentioned before but I won’t lie, I didn’t really know what it was. After a quick read of the documentation that will definitely allow me to have the date of each salt change saved as a value :+1:

Next step is how I can best track that data long term!

In the spreadsheet example I’d see the automation being roughly along the lines of:

trigger = button press
actions = write existing value of the input_datetime to column 1, set the input_datetime to today’s date, write the new value (ie. today’s date) to column 2 and then column 3 can calculate the number of days in between the two.

I’ve seen mention of Grafana or InfluxDB around the forum when searching but it’d seem a bit overkill in my eyes to set that up just for this (although I know I’d probably find other uses once I have it up and running!) and I wouldn’t even know where to start with implementing this idea (ie. I wouldn’t know what to search).

I’d recommend just using a json file, and calling it .db. You could also use IFTTT webhooks with Google sheets.
Side note: you can use logbook.log to add stuff to the logbook.

Thanks very much for the suggestion! I’ve had a look on the forum and come across this thread where they discuss writing to a .csv file. In the short term that’d be great but I’m now thinking that something like Grafana may be the way to go…My reason being that it’d be good if I was able to set up an average number of days between salt replacements. That way I could set up an automation / notification in HA saying (for example) “it’s been over the average number of days and you’re yet to replace your salt, you may want to check the levels”. I’m going to go away and see what I can piece together…

Thanks for the logbook tip, I was under the impression that the logbook is wiped after every restart though? Or is that just the homeassistant.log?

No, I think it lives with homeassistant.db, right next to the history. homeassistant.log != the logbook.

Ah okay, that’s my bad - Maybe one to look in to then.

I’ll update here if/when I manage to work something out…

There’s also a button card that can track when you press it:

1 Like

So I’ve managed to get this working the way I’d like - I have no idea if it’s the best way to do it but it definitely works for me…

The setup consists of:

  • An input_datetime (input_datetime.softener_salt)
  • A template sensor (sensor.softener_salt_last_replaced)
  • A file notification (notify.water_softener)
  • A file sensor (sensor.water_softener_average)
  • A couple of automations (automation.action_water_softener_salt_replacement & automation.notification_water_softener_salt)

First, I created the input_datetime and set it up to only record the date:

name: Softener Salt
has_date: true
has_time: false
icon: mdi:cube-outline

I then manually set that date to the last time I replaced the salt (only manually for the first time, afterwards it’ll be sorted with an automation).
After that I then created the template sensor that calculates the number of days that have passed between today and the timestamp of the input_datetime.softener_salt (I’m convinced there must be a way to calculate based on dates rather than timestamps but I’ve not found it yet!

platform: template
sensors:
  softener_salt_last_replaced:
    value_template: '{{ ((as_timestamp(now())-(states.input_datetime.softener_salt.attributes.timestamp)) | int /60/1440) | round(0) }}'
    unit_of_measurement: 'Days'
    entity_id: input_datetime.softener_salt, sensor.date
    friendly_name: 'Softener Salt'

I then needed a way to store the state of this sensor each time I refill the softener salt. For this I used the File integration where you’re able to log to a file when calling a notify service:

name: water_softener
platform: file
filename: water_softener.log
timestamp: true

Now I wanted a way to average the contents of the water_softener.log to allow for an automation to be set up when sensor.softener_salt_last_replaced went over the average number of days. For this, I couldn’t find anything native to Home Assistant, so instead I created my own Python script:

# Define the empty list to be added to later on
days = []

# Define a function to calculate the average of a list
def Average(lst): 
        return sum(lst) / len(lst)

# Open the water softener log
with open('/home/zander/homeassistant/water_softener.log') as file:
  # Read the lines in the file, ensuring to skip the first two lines as they aren't needed
  output = file.readlines()[2:]
  # Remove '/n' from each item in the list
  output = [item.rstrip() for item in output]
  # Start a For Loop for every item in the output list
  for items in output:
    # Split the items at each blank space (needed as the file has timestamp then the number)
    items_split = items.split(' ')
        # Add the second item from what we've just split to the 'days' list we defined at the start
    days.append(items_split[1])
  # As the original file had the numbers (integers) stored as text (strings) we need to convert them to integers to be able to carry out calculations
  days = list(map(int, days))
  # Calculate the average number of days utilising the function we defined earlier
  average_days = Average(days)
  average_days = round(average_days)
  # Close the file that we opened at the start
  file.close()

# Open the file where we store averages
file = open("/home/zander/homeassistant/water_softener_average.txt", "a")
# Write a new line with the newly calculated average
file.write('\n' + str(average_days))
# Close the file
file.close()

This script outputs the average to a file called water_softener_average.txt so I then needed to have this file as a sensor in Home Assistant. So I again utilised the File integration to allow me to create a sensor out of the contents of this file:

platform: file
file_path: /config/water_softener_average.txt
name: Water Softener Average
unit_of_measurement: 'Days'

Now I had everything I needed in order to create my automations. The first automation is what I will execute each time I refill the water softener salt:

  alias: Action - Water Softener Salt Replacement
  description: ''
  trigger: []
  condition: []
  action:
  - data:
      message: '{{states(''sensor.softener_salt_last_replaced'')}}

        '
    service: notify.water_softener
  - data: {}
    service: python_script.softener_average_calculation
  - data_template:
      date: '{{ as_timestamp(now())|timestamp_custom(''%Y-%m-%d'') }}'
    entity_id: input_datetime.softener_salt
    service: input_datetime.set_datetime
  mode: single

In its current state there are no triggers as I am utilising a button in lovelace to execute the automation until I can make / get my hands on a simple button device. The actions are pretty self explanatory:

  • Log the current state (number of days) of sensor.softener_salt_last_replaced to file by calling notify.water_softener.
  • Execute my python script to calculate the new average now that there has been another addition to the water_softener.log.
  • Reset input_datetime.softener_salt to today’s date to begin the count-up once again

Then my second automation simply notifies me if the value of sensor.softener_salt_last_replaced goes above sensor.water_softener_average:

  alias: Notification - Water Softener Salt
  description: ''
  trigger:
  - platform: template
    value_template: '{{states(''sensor.softener_salt_last_replaced'') | int > states(''sensor.water_softener_average'')
      | int}}'
  condition: []
  action:
  - data:
      message: Check the softener salt, it may need replacing soon
    service: notify.zanders_devices
  mode: single

And that’s it! Only time will tell whether it truly works but all of my tests thus far have proved it works as expected!

A massive thank you to @KTibow as they pointed me in the right direction for a lot of this, your help is massively appreciated! :smiley: :+1:

1 Like