How to work out the position in the day relative to a time

This permits motion detection to operate

Edit 1 : No, that’s not right, I’m confusing myself now

Edit 2 : No, I assume that the light is set on from ‘dark’ till off time 1 (not as yet identified) and is then on motion detection till off time 2 and hence not to come on at all

I’ve scan read everything since last night and want to thank you for the comments.

@pnbruckner and I think @mutt yes, dividing the day might well be the solution. My first and very quick thoughts though are that I am not sure it is an any more ‘pure’ solution than including a date in the off time and updating that every day so allowing for a simple compare

Yes, @finity I think you have the ‘problem’ exactly right. And possibly the pseudo code but…

Unfortunately due to real life, I won’t be able to give this any real time until probably at least tomorrow.

I have to say I think that’s a mistake, when do you do the update, what happens if ha is unavailable at that time, how do you ever recover (as you can only add 24 * 60 * 60 on a working day (ie once you are behind 1 day…)
But this is up to you, not us
Good luck with it

Sorry, is what I’m saying falling below the threshold of human hearing?
You wanted something that started on ‘an event’ (darkness) and ended at a time during a condition (continued darkness) but the time may be before or after midnight?
I thought that the template I gave you did exactly that.
I asked you if it worked or (and if there is problem observed, what is it, how can it be improved) or not, but I got no response.
Now we are checking (presumably) a related action script?

I just deleted my previous post. The script wasn’t even doing what I wanted it to do…

No I didn’t.
This question isn’t about wanting to know when anything starts or ends.
It morphed into something like that during the too-ing and fro-ing.

My original post:

I just want to be able to know if ‘now’ is before or after a certain time (given that I don’t know the date).

Again, the template does the upto this time (be it before or after midnight) you just have to set a sticky start condition.

@mutt Ok, I had a good look at your template. I was originally put off going through it in detail because it was concerning itself with darkness and sun elevation which made me think it had veered off the problem I was trying to solve. Also I must admit to having been put off by its readability, those variable names looked like they had come out of the eighties :stuck_out_tongue_winking_eye:

BUT!

I took what you’d written, reworked it into a format that my 1980’s programming training could read :wink: and came up with something which I think works.

So whilst I haven’t obviously seen it working in a real life situation yet, it does look like I owe you some thanks for prodding me enough times.

Anyway,
For the record here is what I am going to try using. It isn’t the most elegant solution but sometimes I prefer legibility over elegance. I am however open to suggestions for improvement on the off chance that anyone is still remotely interested in this :slight_smile:

Either way, as always I am very grateful to all who contributed.

  #===========================================
  #=== Decide if lights should be normally on
  #===
  #=== Passed - room
  #===========================================
  check_for_lights_normally_on:
    sequence:
      - service_template: >
          {% set time_now = states('sensor.time') %}
          {% set normal_off_time = states('input_datetime.' + room + '_lights_normal_off_time') [0:5] %}
          {% if   normal_off_time > '12:00' and ('12:00' < time_now < '24:00')
                                            and time_now <= normal_off_time %}
              input_boolean.turn_on  
          {% elif normal_off_time > '12:00' and ('12:00' < time_now < '24:00')
                                            and time_now > normal_off_time %}
              input_boolean.turn_off 
          {% elif normal_off_time > '12:00' and ('00:00' <= time_now < '12:00')
                                            and time_now <= normal_off_time %}
              input_boolean.turn_off 
          {% elif normal_off_time < '12:00' and ('00:00' <= time_now < '12:00')
                                            and time_now <= normal_off_time %}
              input_boolean.turn_on 
          {% elif normal_off_time < '12:00' and ('00:00' < time_now < '12:00')
                                            and time_now > normal_off_time %}
              input_boolean.turn_off 
          {% elif normal_off_time < '12:00' and ('12:00' < time_now < '24:00') 
                                            and time_now > normal_off_time %}
              input_boolean.turn_on 
          {% endif %}
        data_template: 
          entity_id: input_boolean.{{ room }}_lights_normally_on

I took that from you… and you know… It’s a light so…

Wow!

That is a horribly wordy template.

Just out of curiosity, why couldn’t the way I wrote my code suggestion work (assuming you converted it to real code, of course)?

Indeed it is. I think you are being too kind. Not my finest piece of work but hey ho.
I started this whole thing off thinking I must have missed something obvious only to realise that what I probably had already wasn’t too far off being the best I could get.

As I said to mutt the whole thing ended up getting twisted and seemed to be trying to solve a problem I didn’t really have (almost certainly my fault, I’m not accusing anyone of anything).

In the end I took the nudges I got from you, pnbruckner and mutt and decided to start from the beginning. I ended up with that verbose bit of nonsense but it seems to work. So far.

I might revisit it later and make it more presentable. I should.

Anyway I am genuinely grateful. It really did become a situation where I had looked at something relatively simple for far too long making it something much harder than it was.

1 Like

Good enough but to be fair I think…I’m pretty sure…but I could be wrong…I guess…(is that wiggly enough?..:slightly_smiling_face:) I used your re-formulated question in post #6 to come up with my template.

Not a biggie tho. I’m glad it’s working for you.

1 Like

Well that was an entertaining read. 50+ posts to suss out when lights ought to be turned on/off. Kudos to everyone for patience and persistence.

Thank Science, my lighting requirements are comparatively simple.

Speaking of simple, that template can be simplified … but this thread is long enough! :wink:

1 Like

Far too wiggly :wink:
Your first post in this thread pretty much cut to the chase and made me wonder why there had been so many posts before it!!

@123 Ha ha! I am glad it entertained! It did become something of a Frankenstein-post.

As I have heard others say, this HA malarkey has become something of a hobby. I can safely say that the only part of my HA config that we wouldn’t want to do without is my garden irrigation. Everything else is really just frippery. So yes even turning on and off lights has taken on the proportions of something well above it’s station!

I’m interested in simplifications but I’m no Python programmer so I always like to be sure that I’m able to read it in 6 months and still follow what’s going on!

I was taught verbose is good. If it is verbose enough it is (almost) self commenting. But that was a long time ago…

1 Like

Gee, I reckon that gets a score of 11/10 on the sacasticometer :rofl:

If you try your hand at simplifying it you’ll discover the simplification process … ain’t that simple.

Here is a first-order reduction. It’s identical to the original except repeated expressions have been replaced with variables.

  check_for_lights_normally_on:
    sequence:
      - service_template: >
          {% set time_now = states('sensor.time') %}
          {% set normal_off_time = states('input_datetime.' + room + '_lights_normal_off_time') [0:5] %}
          {% set within = true if time_now <= normal_off_time else false %}
          {% set is_PM = true if '12:00' < time_now < '24:00' else false %}
          {% set in_PM = true if normal_off_time > '12:00' else false %}
          
          {% if in_PM and is_PM and within %}
              input_boolean.turn_on  
          {% elif in_PM and is_PM and not within %}
              input_boolean.turn_off 
          {% elif in_PM and not is_PM and within %}
              input_boolean.turn_off 
          {% elif not in_PM and not is_PM and within %}
              input_boolean.turn_on 
          {% elif not in_PM and not is_PM and not within %}
              input_boolean.turn_off 
          {% elif not in_PM and is_PM and not within %}
              input_boolean.turn_on 
          {% endif %}
        data_template: 
          entity_id: input_boolean.{{ room }}_lights_normally_on

Now comes the challenge of reorganizing the tests. I can’t seem to achieve symmetry because I think the original code overlooked to handle two possible combinations.

  check_for_lights_normally_on:
    sequence:
      - service_template: >
          {% set time_now = states('sensor.time') %}
          {% set normal_off_time = states('input_datetime.' + room + '_lights_normal_off_time') [0:5] %}
          {% set within = true if time_now <= normal_off_time else false %}
          {% set is_PM = true if '12:00' < time_now < '24:00' else false %}
          {% set in_PM = true if normal_off_time > '12:00' else false %}
          
          {% if in_PM %}
            {% if is_PM %}
              input_boolean.turn_{{'on' if within else 'off'}} 
            {% elif not is_PM and within %}
              input_boolean.turn_off
            {% endif %}
          {% else %}
            {% if not is_PM %}
              input_boolean.turn_{{'on' if within else 'off'}} 
            {% elif is_PM and not within %}
              input_boolean.turn_on
            {% endif %}
          {% endif %}
        data_template: 
          entity_id: input_boolean.{{ room }}_lights_normally_on

Here’s one example where it’s not symmetric:

            {% if is_PM %}
              input_boolean.turn_{{'on' if within else 'off'}} 
            {% elif not is_PM and within %}
              input_boolean.turn_off
            {% endif %}

That ought to be like this (to handle all combinations):

            {% if is_PM %}
              input_boolean.turn_{{'on' if within else 'off'}} 
            {% else %}
              input_boolean.turn_{{'off' if within else 'on'}} 
            {% endif %}

The problem is that klogg’s version only handles the combination of:

not is_PM and within

but doesn’t indicate what to do if:

not is_PM and not within

I don’t know how he wants that combination to be handled so my template is not quite symmetrical for is_PM and not is_PM.