irrigation_unlimited
irrigation_unlimited copied to clipboard
Add optional "volume_entity" to a zone for tracking/controlling based on volume
Describe the solution you'd like It would be nice if a zone was able optionally able to track water usage, as many sprinkler controllers or hose end controllers that can integrate with home assistant provide a separate entity that provides either/or 'current flow rate' or 'current volume used'. For an initial implementation I would imagine the data would only be provided as informational and tracked along with historical runtime data. Eventually it would be great to also allow scheduling 'duration' to use water volume instead of time, for example: Run zone1 at 5:00 for 100 gallons, (with optional timeout).
Describe alternatives you've considered Currently I have custom netdaemon code integrated for managing volume related usage for my sprinklers, if there is interest on this I would be happy to start looking at coming up with a sample PR if you have any suggestions on where/how this would be best handled.
Curious if there is any interest for something like this
This is along the lines of issue #101. It would be great to be able use either volume or time as a base. Not sure how to monitor the volume 'ticks' or consumption. Maybe a notification mechanism for each unit of water used much like a water meter. Any thoughts on this?
I currently track water volume for each zone with the following code. There is one physical meter (sensor.556) that never resets Definition of helpers
utility_meter:
water_meter_id2:
name: Consommation eau kfé francois
source: sensor.556
unique_id: "water_meter_id2"
tariffs:
- "std"
water_meter_id3:
source: sensor.556
name: Consommation eau Serre
unique_id: "water_meter_id3"
tariffs:
- "std"
water_meter_id4:
source: sensor.556
name: Consommation eau Haie rue
unique_id: "water_meter_id4"
tariffs:
- "std"
water_meter_id5:
source: sensor.556
name: Consommation cuisine grande maison
unique_id: "water_meter_id5"
tariffs:
- "std"
water_meter_id6:
source: sensor.556
name: Consommation eau pare terre Julie
unique_id: "water_meter_id6"
tariffs:
- "std"
water_meter_id7:
source: sensor.556
name: Consommation eau Pelouse
unique_id: "water_meter_id7"
tariffs:
- "std"
water_meter_id8:
source: sensor.556
name: Consommation eau deux carrés
unique_id: "water_meter_id8"
tariffs:
- "std"
water_meter_id9:
source: sensor.556
name: Consommation eau un carré
unique_id: "water_meter_id9"
tariffs:
- "std"
water_meter_id10:
source: sensor.556
name: Consommation eau petits fruits
unique_id: "water_meter_id10"
tariffs:
- "std"
water_meter_id11:
source: sensor.556
name: Consommation eau Haie - Céanothe et fleurs
unique_id: "water_meter_id11"
tariffs:
- "std"
water_meter_id12:
source: sensor.556
name: Consommation eau Pommiers
unique_id: "water_meter_id12"
tariffs:
- "std"
water_meter_id13:
source: sensor.556
name: Haie Charme Hêtre pourpre
unique_id: "water_meter_id13"
tariffs:
- "std"
water_meter_id14:
source: sensor.556
name: Consommation non utilisé
unique_id: "water_meter_id14"
tariffs:
- "std"
water_meter_id15:
source: sensor.556
name: Consommation eau haie du fond
unique_id: "water_meter_id15"
tariffs:
- "std"
water_meter_id16:
source: sensor.556
name: Consommation eau Tilleul
unique_id: "water_meter_id16"
tariffs:
- "std"
input_number:
water_id2:
name: Consommation eau Kfé François
min: 0
max: 10000
step: 1
mode: box
water_id3:
name: Consommation eau Serre
min: 0
max: 10000
step: 1
mode: box
water_id4:
name: Consommation eau Haie rue
min: 0
max: 10000
step: 1
mode: box
water_id5:
name: Consommation cuisine grande maison
min: 0
max: 10000
step: 1
mode: box
water_id6:
name: Consommation pare-terre Julie
min: 0
max: 10000
step: 1
mode: box
water_id7:
name: Consommation eau Pelouse
min: 0
max: 10000
step: 1
mode: box
water_id8:
name: Consommation eaux deux carrés
min: 0
max: 10000
step: 1
mode: box
water_id9:
name: Consommation eau un carré
min: 0
max: 10000
step: 1
mode: box
water_id10:
name: Consommation eau petits fruits
min: 0
max: 10000
step: 1
mode: box
water_id11:
name: Consommation Haie Céanothe et fleurs
min: 0
max: 10000
step: 1
mode: box
water_id12:
name: Consommation eau Pommiers
min: 0
max: 10000
step: 1
mode: box
water_id13:
name: Consommation Haie Charme Hêtre pourpre
min: 0
max: 10000
step: 1
mode: box
water_id14:
name: Consommation eau TBD
min: 0
max: 10000
step: 1
mode: box
water_id15:
name: Consommation eau haie du fond
min: 0
max: 10000
step: 1
mode: box
water_id16:
name: Consommation eau Tilleul
min: 0
max: 10000
step: 1
mode: box
And automation. Irrigation_unlimited watering uses sequences, hence there is only one watering at a time. Each time a sprinkler is on is resets its corresponding virtual meter, and when the sprinkler goes to off the value of the virtual meter is sent to the input_number of corresponding water circuit.
- id: 670d8578-9b95-4538-89ff-3334ec429495
alias: Arrosage Consommation de chaque circuit
description: ""
# trace:
# stored_traces: 30
trigger:
- platform: state
entity_id:
- switch.562
- switch.564
- switch.565
- switch.566
- switch.568
- switch.569
- switch.713
- switch.714
- switch.715
- switch.716
- switch.717
- switch.718
- switch.719
- switch.720
variables:
indexes:
562: "id2" # Kfé François
564: "id3" # Serre
565: "id4" # Haie rue
568: "id5" # Cuisine grande maison
569: "id6" # Pare terre Julie
566: "id7" # Pelouse
713: "id8" # Deux carrés
714: "id9" # Un carré
715: "id10" # Petits fruits
716: "id11" # Haie Céanothe et fleurs
717: "id12" # Pommiers
718: "id13" # Haie Charme Hêtre pourpre
719: "id15" # Haie du fond
720: "id16" # Tilleul - Cerisier
id: "{{trigger.entity_id.split('.')[1]}}" # entity index (id1, id2, ...)
entity: "{{indexes.get(id, 'unknown')}}"
condition: "{{ entity != 'unknown' and trigger.from_state.state != 'unavailable' }}"
action:
- choose:
- conditions:
- condition: template
value_template: >
{{states(trigger.entity_id) == "on"}}
sequence:
- service: utility_meter.reset
data: {}
target:
entity_id:
- '{{"select.water_meter_" ~ entity}}'
- select.water_meter_arrosage
- conditions:
- condition: template
value_template: >
{{states(trigger.entity_id) == "off"}}
sequence:
- service: input_number.set_value
data:
value: >
{{states("sensor.water_meter_" ~ entity ~ "_std") | round(3)}}
target:
entity_id: "input_number.water_{{entity}}"
mode: queued
max: 20
@Kolia56 Thank you for the suggestion, that could definitely work as I already maintain total volume per zone run independently from irrigation_unlimited via pyscripts but I fear with upwards of 12 zones on two independent controllers the solution could become pretty cumbersome and difficult to maintain.
@rgc99 One way I could see this managed in irrigation_unlimited would be as followed:
- Every controller would have a integration created/controlled sensor created for example: "controller 1 current zone volume"
- An optional boolean value on the controller would allow me to set the controller to function in "volume set mode" instead of the current "time set mode"
- If volume set mode is configured, every zone in the controller would need to have an additional entity provided on top of the current switch entity, this entity would need to either provide "total volume of current watering"(preferred) or a "current rate of flow" value.
- Some zone devices for example my byhyve and my taplink devices already provide an entity sensor that amounts to "total volume of current watering run" in gallons or liters, I imagine that most would. If this type of sensor is provided irrigation_unlimited would simply be able to poll the value at a configurable time interval (say default 10s-30s) until the desired set volume in a sequence is met.
- For the zone devices that only have GPM/LPM flow rate value, irrigation_unlimited would poll this flow rate at a set time interval, say 10 seconds, and take the average of say 6 readings to update the controllers "current zone volume" value and use this as the cutoff, the times and values here being just examples.
- I think it would still be important to set a default and configurable fail safe shutoff time per zone run. For example one of my zone values flow rate sensors was clogged with debris and temporarily stopped updating flow rate and thus volume. Maybe this value is configurable and adjustable, for example if irrigation_unlimited has historical data of at least one previous run for a zone this value is set to 2x the time of the previous 10 or so runs. (just an idea).
Sorry to be a bit tardy. I am travelling across the Kimberley on a spot of vacation. Will follow up on this in due course.
I would like to gather some sensor sample data in a text file. This would be used feed the data to the test framework. Not exactly sure how to implement this but that is where we need to start. Perhaps this article might help to harvest the data we need. Probably a csv file with datetime stamp and state value on each line. More data the merrier. Also a variety of systems byhyve, taplink and whatever anyone else can provide would be great.
Rather than polling I think tracking the entity state change would be the way to go. Don't then have these agonising decisions about polling too much or too little.
I'm quite ready to volunteer on this matter. However I'm not too sure to understand what is the kind of sensor from which data is needed. Could you elaborate a bit further? Thank you
The idea is to capture data from the water usage sensor. This will write a file irrigation_sensor_log.txt
in the config directory with the sensor data.
notify:
- name: irrigation_sensor_log
platform: file
filename: irrigation_sensor_log.txt
timestamp: True
automation:
- alias: Write Irrigation Sensor Data
trigger:
- platform: state
entity_id: sensor.556
action:
- service: notify.irrigation_sensor_log
data:
message: "{{ trigger.to_state.state }}"
Thanks for the code, I had no idea of the existence of notify/platform: file. Code is in place. How may days do you wish?
Yeah, only learned about file platform a few days ago myself. I think a day would be enough but also the Irrigation Unlimited log file so I can see the on/off events that overlap with the water sensor log.
We'll have to wait a bit, we had 3 rainy days, so no watering data, HA Smart Irrigation has decided on its own;) I am expecting some data tomorrow. I added the state of the various sprinkler switches in the code in order to get everything in one file.
This is a first try. Watering was decreased to 17% of the nominal time hence the short watering times. You'll notice that except for the first one, switch on state is not logged. This is due I think to the two events arriving at the same time closing one valve opening the next one. I'm pretty sure if a 1" delay is set, it will be logged. I changed the config for the next run with such a delay. In the meantime you have to consider that each off state is followed by another on state. For instance when switch.562 is set to off switch.564 is set to on. Let me know whether the log file format could be improved to help processing on your side. We'll have to wait till Saturday night (UTC+2) to grad another sequence. irrigation_sensor_log.txt
Please find some more data irrigation_sensor_log-1.txt
Thanks, can I also get the current matching configuration. Also was there any adjustment in play?
Here it is. Sequence 1 / night was indeed adjusted. For the 26: 69% For the 27: 58% For the 28: 46%
irrigation_unlimited:
controllers:
- name: "Controleur 1"
all_zones_config:
show:
timeline: true
allow_manual: true
# duration: "0:10:00"
zones:
- name: Café François
zone_id: "1"
entity_id: switch.vanne_atelier_gui
maximum: "00:45:00"
- name: Serre
zone_id: "2"
entity_id: switch.vanne_maison_journalier_gui
maximum: "00:30:00"
- name: Pelouse
zone_id: "3"
entity_id : switch.vanne_jardin_devant_gui
maximum: "01:10:00"
- name: Deux carrés
zone_id: "4"
entity_id: switch.vanne_deux_carres_gui
maximum: "00:45:00"
- name: Un carré
zone_id: "5"
entity_id: switch.vanne_un_carre_gui
maximum: "00:30:00"
- name: Petits fruits
zone_id: "6"
entity_id: switch.vanne_petits_fruits_gui
maximum: "00:50:00"
- name: Haie - Céanothe - Fleurs
zone_id: "7"
entity_id: switch.vanne_haie_gui
maximum: "01:00:00"
- name: Pommiers
zone_id: "8"
entity_id: switch.vanne_pommiers_gui
maximum: "00:30:00"
- name: Pare-terre Julie
zone_id: "9"
entity_id: switch.vanne_buanderie_grande_maison_gui
maximum: "00:45:00"
- name : Haies pelouses
zone_id: "10"
entity_id: switch.718
maximum: "00:45:00"
- name: If Cour carrée
entity_id: switch.vanne_salle_claudine_gui
zone_id: "11"
maximum: "00:20:00"
- name: Haie du fond
zone_id: "12"
entity_id: switch.vanne_haie_fond_gui
maximum: "01:40:00"
- name: Tilleul
zone_id: "13"
entity_id: switch.vanne_tilleul_gui
maximum: "00:40:00"
sequences:
- name: nuit
schedules:
- name: 1
time: "22:00"
schedule_id: "s1"
delay : 1
zones:
- zone_id: 1 # Café François
duration: "00:30"
- zone_id: 2 # Serre et autres
duration: "00:20"
- zone_id: 9 # Pare-terre Julie
duration: "00:30"
- zone_id: 4 # Deux carrés
duration: "00:30"
- zone_id: 5 # Un carré
duration: "00:20"
- zone_id: 6 # Petits fruits
duration: "00:30"
- zone_id: 7 # Haie - Céanothe
duration: "00:40"
- zone_id: 8 # Pommiers
duration: "00:20"
- zone_id: 10 # Haies pelouse
duration: "00:25"
- zone_id: 11 # If cour carrée
duration: "00:10"
- zone_id: 12 # Haie du fond
duration: "00:30"
- zone_id: 13 # Tilleul - Cerisier
duration: "00:30"
- zone_id: 3 # Pelouse
duration: "00:40"
- name: jour
duration: "00:05"
delay: "02:25"
repeat: 3
schedules:
- name: 2
time: "12:00"
schedule_id: "s2"
zones:
- zone_id: 2
The timestamp is a bit inconvenient as it is in UTC while the config is in local time. Took a guess local time was GMT+2 and things seemed to line up. It would better to turn off the timestamp in the notify and add it manually in the automation message.
notify:
- name: irrigation_sensor_log
platform: file
filename: irrigation_sensor_log.txt
timestamp: False # <=== Change this
automation:
- alias: Write Irrigation Sensor Data
trigger:
- platform: state
entity_id: sensor.556
action:
- service: notify.irrigation_sensor_log
data:
message: "{{ now().isoformat() }}; {{ trigger.to_state.state }}"
Indeed this is GMT+2. I made the modification. How many days of data do you wish?
At the moment just a single sequence run would be great.
There's an initial draft in the repository. It's collecting the sensor information and displaying in a "volume" attribute in the zone i.e. binary_sensor.irrigation_unlimited_c1_z1. Add the following to the configuration:
zones:
- name: "Zone 1"
volume:
entity_id: sensor.556
...
As you use a common sensor it might be easier to do:
all_zones_config:
volume:
entity_id: sensor.556
Please check it out and see if the volumes on the zones tally to what you expect.
I made a first quick test with zone_id: 8. Volume attribute reports 9 liters which is exactly my figure. Well done! We shall wait until tomorrow morning (GMT+2 as you know) to get a complete cycle.
zone_id: 8
index: 7
enabled: true
suspended: null
status: off
schedule_count: 0
schedules:
adjustment:
current_schedule: null
percent_complete: 0
next_schedule: 1
today_total: 4
timeline:
- start: '2023-10-04T21:56:07+00:00'
end: '2023-10-04T22:07:43+00:00'
schedule_name: '1'
adjustment: '%58.0'
status: scheduled
- start: '2023-10-03T21:56:07+00:00'
end: '2023-10-03T22:07:43+00:00'
schedule_name: '1'
adjustment: '%58.0'
status: scheduled
- start: '2023-10-02T21:56:07+00:00'
end: '2023-10-02T22:07:43+00:00'
schedule_name: '1'
adjustment: '%58.0'
status: scheduled
- start: '2023-10-01T21:56:07+00:00'
end: '2023-10-01T22:07:43+00:00'
schedule_name: '1'
adjustment: '%58.0'
status: next
- start: '2023-10-01T08:44:40+00:00'
end: '2023-10-01T08:48:40+00:00'
schedule_name: Manual
adjustment: ''
status: history
- start: '2023-09-30T21:55:53+00:00'
end: '2023-09-30T22:07:29+00:00'
schedule_name: '1'
adjustment: '%58.0'
status: history
- start: '2023-09-29T21:35:53+00:00'
end: '2023-09-29T21:45:29+00:00'
schedule_name: '1'
adjustment: '%48.0'
status: history
- start: '2023-09-28T21:31:53+00:00'
end: '2023-09-28T21:41:05+00:00'
schedule_name: '1'
adjustment: '%46.0'
status: history
- start: '2023-09-27T21:55:53+00:00'
end: '2023-09-27T22:07:29+00:00'
schedule_name: '1'
adjustment: '%58.0'
status: history
- start: '2023-09-26T22:17:53+00:00'
end: '2023-09-26T22:31:41+00:00'
schedule_name: '1'
adjustment: '%69.0'
status: history
- start: '2023-09-25T20:35:53+00:00'
end: '2023-09-25T20:39:29+00:00'
schedule_name: '1'
adjustment: '%18.0'
status: history
volume: 0.009
icon: mdi:valve-closed
friendly_name: Pommiers
next_adjustment: %58.0
next_name: 1
next_start: 2023-10-01T23:56:07+02:00
next_duration: 0:11:36
After a complete night cycle I confirm that all volumes data are correct.
Great, now we have the volume monitoring accurate I would like to lock in a test. I need a new irrigation_sensor_log file with the updated timestamp, expected volume results for each zone, any adjustment in play and config if it has changed. This will help moving forward that changes do not effect these readings.
ok I will prepare that. To make sure I understand correctly, could you clarify what you are expecting in regards to "expected volume results for each zone". Are you after the watering nominal volume for each zone when there is no adjustment (i.e. 100%)?
No, as you would have calculated including the adjustment. The idea is to replay that one night sequence run every time there is a code change.
ok I see, so you want to make sure there is no code regression, when a code change is made. So I wait till you let me know there is a need for a new test. In the meantime I added the adjustment figure in the log file.
I think the code is fine. Would like to get an updated log file and complete the test unit for the volume metering. Could you also post the data collection automation. I will put all of this in the repository and we can move on.
Would it be useful to have a flow_rate
attribute on the zone? It would be simply volume / duration, probably displayed in seconds. Thinking it could be used in an automation for an alarm (low/no water flow etc.) or a graph.
Would it be useful to have a
flow_rate
attribute on the zone? It would be simply volume / duration, probably displayed in seconds. Thinking it could be used in an automation for an alarm (low/no water flow etc.) or a graph.
I think flow_rate
is definitely a good idea and in seconds.
From the above post I can see that this has been provisionally implemented and tested on all zones/each zone.
May I also suggest to add it on controller entity (in a similar way as switch entities are available there too).
From an alarm point of view, pressure
might be another common attribute to consider. I built a complex water filtering and supply system at our holiday house and have used water pressure sensors like this one.
Use case scenario as you suggest to disable zone/controller if pressure drops below certain threshold parameters that could be part of the irrigation_unlimited yaml configuration.
I think the code is fine. Would like to get an updated log file and complete the test unit for the volume metering. Could you also post the data collection automation. I will put all of this in the repository and we can move on.
Here is the log file irrigation_sensor_log.txt
Here is te code automation
- id: 670d8578-9b95-4538-89ff-3334ec429495
alias: Arrosage Consommation de chaque circuit
description: "Consommation chaque circuits et vérification état logique/physique
de chaque relais vis à vis de la commande"
trace:
stored_traces: 40
trigger:
- platform: state
entity_id:
- switch.562
- switch.564
- switch.565
- switch.566
- switch.568
- switch.569
- switch.713
- switch.714
- switch.715
- switch.716
- switch.717
- switch.718
- switch.719
- switch.720
id: valve_switch
variables:
indexes:
562: "id2" # Kfé François
564: "id3" # Serre
565: "id4" # Haie rue
568: "id5" # Cuisine grande maison
569: "id6" # Pare terre Julie
566: "id7" # Pelouse
713: "id8" # Deux carrés
714: "id9" # Un carré
715: "id10" # Petits fruits
716: "id11" # Haie Céanothe et fleurs
717: "id12" # Pommiers
718: "id13" # Haie Charme Hêtre pourpre
719: "id15" # Haie du fond
720: "id16" # Tilleul - Cerisier
id: "{{trigger.entity_id.split('.')[1]}}" # entity index (id1, id2, ...)
entity: "{{indexes.get(id, 'unknown')}}"
var: "{{trigger.from_state.state}}"
condition: "{{ entity != 'unknown' and (trigger.from_state.state == 'on'
or trigger.from_state.state == 'off') and has_value('sensor.556')}}"
action:
- choose:
- conditions:
- condition: template
value_template: >
{{states(trigger.entity_id) == "on"}}
sequence:
- service: utility_meter.reset
data: {}
target:
entity_id:
- '{{"select.water_meter_" ~ entity}}'
- select.water_meter_arrosage
- conditions:
- condition: template
value_template: >
{{states(trigger.entity_id) == "off"}}
sequence:
- service: input_number.set_value
data:
value: >
{{states("sensor.water_meter_" ~ entity ~ "_std") | round(3)}}
target:
entity_id: "input_number.water_{{entity}}"
default:
- delay:
hours: 0
minutes: 0
seconds: 2
milliseconds: 0
mode: queued
max: 20
Would it be useful to have a
flow_rate
attribute on the zone? It would be simply volume / duration, probably displayed in seconds. Thinking it could be used in an automation for an alarm (low/no water flow etc.) or a graph. Without any doubt. I already have done this with another automation using a derivative sensor. However it is a bit tricky because the derivative sensor is updated only when there is new data. In other words it never resets to 0
- trigger:
- platform: time_pattern
seconds: /15
sensor:
- name: Grand puits index timed
unique_id: grand_puits_index_timed
state: >
{% set sensor_value = states('sensor.grand_puits_index_en_litres') | float %}
{{ 0.001 * (this.state | float(0) == sensor_value) + sensor_value }}
state_class: measurement
unit_of_measurement: "l"
From an alarm point of view,
pressure
might be another common attribute to consider. I built a complex water filtering and supply system at our holiday house and have used water pressure sensors like this one.
I do have a pressure sensor as well, so integrating this into Irrigation unlimited is certainly nice to have.
I have taken the sample from 13-Oct 22:00pm through 14-Oct 04:00. These are the volume readings [0.128, 0.121, 0.060, 0.071, 0.030, 0.058, 0.095, 0.056, 0.134, 0.045, 0.031, 0.072, 0.671]
.
These are the flow rates I get per hour do they seem correct? [0.284, 0.403, 0.133, 0.158, 0.1, 0.097, 0.158, 0.124, 0.357, 0.3, 0.069, 0.16, 1.118]
.
Based on the same file I made the computation and confirm all your figures. I coud not check with my water meters because I was unaware that input_numbers that store the various values are not stored in statistics, only sensors and binary sensors are. So if you wish, I may include template sensors that will be feeded by these input_numbers and statistics will be available. I may also send these values to influxDB that is already set-up. Let me know.