Hi. Background: I am very new to HA, and have only been using the UI to configure some basic automations (so far). I’ve found articles on creating templates but haven’t yet understood how to use them.
I am trying to control my Solar inverter manually and want to set it to do something (charge the battery to 100%) only when there is more than a certain amount of time between sunset and midnight. This is because at midnight I can start using cheap grid electricity, and therefore I only need to store enough power in the battery to last until then, and I would prefer to export the power if it’s not needed in the battery to get me to midnight.
I’ve been unable to work out any way of forming a conditional IF or CHOOSE statement using the UI that will achieve this, and also don’t know how to go about trying to calculate the hours between sunset and midnight to use in an IF / CHOOSE statement.
You’re looking for an automation, but I am not sure you are giving enough information for a specific suggestion.
Supposing on a given day that there is enough time between sunset and midnight, at what point in the day would you want to trigger the automation to set your solar inverter to charge the battery? At sunrise?
I currently have triggers set for every minute of the day conditional on the state of charge of the battery and the forecast solar yield for the rest of the day. This is designed to maximise the export during the day, any only charge up the battery when it is necessary to start charging whilst there is sufficient forecast solar energy left today. This is all working as intended.
What I want to do now, is add an additional condition so that it only charges the battery the final step - to 100% - on days where there is a long time between sunset and midnight. This might happen early in the day, for example if there is a low forecast for solar energy for the rest of the day. Or it might happen towards on the end of a day. The key point is that I want to be able to test the condition at any point during the day, but the result at each test will always be the same (on that day) - i.e. there will always be, say, 4 hours between sunset and midnight on that particular day.
Examples of how I want this to work:
At 15:00 on a day in June, because there is a low forecast for the rest of the day it decides to start charging the battery, and because there are only 3 hours between sunset and midnight it decided to charge to only 80%.
At 11:00 on a day in Jan , because there is a low forecast for the rest of the day it decides to start charging the battery, and because there are 7 hours between sunset and midnight it decides to charge the battery to 100%.
I would recommend the Sun2 custom integration. This integration provides a number of a daylight sensor that provides the number of hours of daylight. It also has more “stable” sensors for sunset which you could use the calculate your sunset-midnight delta, if that’s the way you want to go.
I recommend taking a look at @Didgeridrew’s suggestion for several reasons. One that he doesn’t say outright that at least I notice is that although you’ve got things working with automations that fire every minute, as you say, that trigger alone sounds like your solution might be more complicated than it needs to be.
Regardless, since even if you change course, it’s going to take some time, here’s an answer to your immediate question. I can’t put this into the right form for you–e.g., whether it’s a condition in an automation or whether it’s something that’s going into an if statement or the like–since I’m not sure about the details of your automations.
The following YAML will define a variable sunset_to_midnight that contains an integer representing the number of minutes between sunset today and sunset tonight. If it’s after sunset but before midnight, the value is 0.
Thanks. I think that might work. I can use the “Night” sensor and then just test if it is more than a number of hours, assuming half of the darkness is before midnight and half after midnight. Only thing that doesn’t do is adjust for daylight saving - in the summer more the the darkness if after midnight. But I can probably live with that.
@d921 Thanks - I had replied to @Didgeridrew before I saw your post.
I’d love to try and use your variable solution if I can, but I’m struggling to know how to use the code you posted. If I use the UI to create an automation and then switch to the YAML mode - can I past the code in to that somehow?
there’s an IF statement with alias “Today’s remaining forecast PV > 5” which I want to add this new condition of there being more than, say, 6 hours between sunset and midnight
Hmm. I will show you how to do what you’re explicitly asking for; I’ll respond separately with that.
But based on what I understand of your automation, I don’t think it will achieve what you want.
The automation triggers every minute. So consider the corner case where the “PV > 5 kWh” is met exactly 6 hours before sunset. The condition you want to add will pass (at least six hours) and the automation will go into the then. But at some point before you get to 100% charge, isn’t the “PV > 5 kWh” condition going to start failing?
I edited this post; my original post misstated the details of issue but it’s the same high-level problem with reevaluating all the conditions every minute.
Yes. You are correct. I edited the post while you responded. But as my edited post notes, if I understand the automation, I think a similar issue remains.
I’ll respond with the YAML addition regardless; I just can’t do it right now because I’m not at a physical keyboard.
Thank you so much! Hopefully, once you have shown me how to integrate your code I’ll be able to see how it works and maybe tinker around a bit more.
I’ll have a think about what you are saying about the other condition failing. What I haven’t already explained is that although I am trying to set the inverter into export mode as much as possible during the day, I am limited to what I can export and if it’s sunny the battery will still slowly fill up with everything I generate and cannot export. So it is quite possible that the battery will get to 100% well before the PV > 5 test starts failing.
The other significant issue here is that, at sunset, the sun.sun attribute that gives us the sunset time, next_setting, is re-set to tomorrow’s sunset date and time. That’s why my original suggestion defaulted to 0 for the time between today’s sunset and tonight’s midnight if it’s already after sunset: because tonight’s sunset is no longer available. Keeping around tonight’s sunset date and time after the sun sets would require creating a datetime helper and a separate automation to update it.
It’s possible to approximate tonight’s sunset time with tomorrow’s sunset time for the period between sunset and midnight, but the logic gets more complicated, because next_setting includes the time as well as the date. I haven’t changed the code here to do that extra step; after sunset, the code below will understand that the time between sunset and midnight is 0, which means the condition will fail a minute after sunset even if it passed a minute before sunset.
If you really want to run with the optimization that causes your automation to charge to 100% if there is sufficient time between sunset and midnight, I think you probably need to consider a different approach. One idea… sunset times are about the same each year on a given date, so perhaps instead of doing a calculation each day, you instead check for whether today’s date is in the right range of summer winter dates?
I promised to post the code below so I’m doing so even though it probably won’t do what you need; at least hopefully it helps you understand the issues a little better. Let me know if this spurs other questions.
alias: 84.5%<SOC<98.5% between 7am & sunset
description: ""
triggers:
- trigger: time_pattern
hours: "*"
minutes: "*"
seconds: "1"
conditions:
- alias: "Time: 07:00 to Sunset"
condition: time
after: "07:00:00"
weekday:
- sun
- sat
- fri
- thu
- wed
- tue
- mon
before: sensor.sun_next_setting
- alias: "Solar Battery: 84.5%<SOC<97.5%"
type: is_battery_level
condition: device
device_id: 813a9d87a9f47512ab3e1eb629f88f0b
entity_id: 351e329b072b8a790074581a8b2aa2f3
domain: sensor
below: 97.5
above: 84.5
actions:
- alias: Check forecast and update mode of Inverter
if:
- alias: Today's remaining forecast PV > 5 kWh
type: is_energy
condition: device
device_id: 04349a76a9341ea8f53b1f46f7957183
entity_id: a14d01e3a140b9539ac7d0d1d0983e2f
domain: sensor
above: 5
# NEW CODE - but unlikely to accomplish stated goals
- alias: Before sunset, time between today's sunset and midnight is greater than 6 hours
condition: >
{% set midnight = as_timestamp(today_at("23:59:59")) %}
{% set sunset = as_timestamp(state_attr("sun.sun", "next_setting")) %}
{% set delta = int(max(0, (midnight - sunset) / 60)) %}
{# delta represents, in minutes, the time between sunset and midnight #}
{# delta is ZERO if at the time it is evaluated, it is after sunset #}
{{ delta >= 6*60 }}
# /NEW CODE
then:
- action: script.ensure_inverter_is_in_feed_in_first_mode
metadata: {}
data: {}
else:
- action: script.ensure_inverter_is_in_self_use_mode
metadata: {}
data: {}
alias: Ensure Inverter is in SELF USE mode
- action: script.ensure_eddi_is_in_stopped_mode
metadata: {}
data: {}
- choose:
- conditions:
- condition: numeric_state
entity_id: sensor.sun_next_setting
below: 100
sequence:
- device_id: d8c30322a1ff5498b95f7b8e5a19454e
domain: mobile_app
type: notify
message: Triggered
mode: single
I haven’t tested it, or given it enough thought, but perhaps this “hack” approach that tries to approximate the sunset time will work. Suggesting it since I don’t want to leave you in the cold–if I were in your place I’d rethink the once-every-minute approach to be honest. What you’re trying to accomplish is a little more nuanced than what can be done that way.
alias: 84.5%<SOC<98.5% between 7am & sunset
description: ""
triggers:
- trigger: time_pattern
hours: "*"
minutes: "*"
seconds: "1"
conditions:
- alias: "Time: 07:00 to Sunset"
condition: time
after: "07:00:00"
weekday:
- sun
- sat
- fri
- thu
- wed
- tue
- mon
before: sensor.sun_next_setting
- alias: "Solar Battery: 84.5%<SOC<97.5%"
type: is_battery_level
condition: device
device_id: 813a9d87a9f47512ab3e1eb629f88f0b
entity_id: 351e329b072b8a790074581a8b2aa2f3
domain: sensor
below: 97.5
above: 84.5
actions:
- alias: Check forecast and update mode of Inverter
if:
- alias: Today's remaining forecast PV > 5 kWh
type: is_energy
condition: device
device_id: 04349a76a9341ea8f53b1f46f7957183
entity_id: a14d01e3a140b9539ac7d0d1d0983e2f
domain: sensor
above: 5
# NEW CODE - hacky, barely tested
- alias: Time between today's sunset and midnight is at least 6 hours
condition: >
{% set midnight = as_timestamp(today_at("23:59:59")) %}
{% set sunset = as_timestamp(state_attr("sun.sun", "next_setting")) %}
{# NS.delta represents, in minutes, the time between sunset and midnight #}
{% set NS = namespace(delta=int((midnight - sunset) / 60)) %}
{# But if it's after sunset today, the next_setting attribute is set to tomorrow's #}
{# sunset (including tomorrow's date). Adjust by "subtracting" a day #}
{% if NS.delta < 0 %}
{% set NS.delta = NS.delta + 24*60 %}
{% endif %}
{# Return true if sunset and midnight are at least 6 hours apart #}
{{ NS.delta >= 6*60 }}
# /NEW CODE
then:
- action: script.ensure_inverter_is_in_feed_in_first_mode
metadata: {}
data: {}
else:
- action: script.ensure_inverter_is_in_self_use_mode
metadata: {}
data: {}
alias: Ensure Inverter is in SELF USE mode
- action: script.ensure_eddi_is_in_stopped_mode
metadata: {}
data: {}
- choose:
- conditions:
- condition: numeric_state
entity_id: sensor.sun_next_setting
below: 100
sequence:
- device_id: d8c30322a1ff5498b95f7b8e5a19454e
domain: mobile_app
type: notify
message: Triggered
mode: single
Thank you so much @d921. I’ve just enough programming nouse to see what you have done and how it works, and it gives me my very first step towards understanding how to go beyond the UI to implement more sophisticated algorithms. I’ll continue to think about your comments on the every-minute approach as I evolve my setup.