Help needed with light transition

30

The controller has a 0-10V output and a switched power output. At 0 the power relay can be heard to de-energise.

255

Normal ramp up/down would be ok.

I’ve never used packages, nor do I know how to.

The controller is on my ZigBee network, which is not heavily utilised, so I can’t see this being a problem.

I don’t think a jump of 1 or 2 steps will be particularly perceivable.

It’s a cheap Chinese dimmer and specifications are vague. https://www.zigbee2mqtt.io/devices/HLC610-Z.html

I tend to do maintenance with the lights at 100%, but I also tend to do it around the time when the lights would be at 80%+, so I wouldn’t need an override.

One final thing to say though. The delay automation appears to be working ok right now, but today is the first day where it should go through a full sequence, so I cannot be sure yet. I would be happy to stay with the current configuration if it proves to be effective, so if you choose to write something custom I will try it, but would also be happy to stay with delays if you did not.

I’m also at probably beginner to intermediate stages of HA, so whilst I can modify configuration.yaml and automation.yaml, it is at basic level.

The issue is you can’t queue transitions like this. When you issue them they take effect immediately. The fade-down is replacing the fade up transition.

So what you can do:

one automation triggered at 12 that turns on and fades from 30% to 100% over 5 hours.

a second automation triggered at 5 pm (12+5 hours) that fades from 100% to 30% over whatever time period you like - assume 5 hours.

This way if you need to you can push the automation at 5pm to start a bit later if you want more time @ 100% for whatever reason.

No, I’m proposing that the automation (runs now every 79 80 (again :roll_eyes: ) secs) calculates what level it should be at (according to the time of day, going up down whatever) and you write that value to the brightness

There’s the critical clue (explaining why the wait_template doesn’t wait). You also reminded me of how this works in the other home automation software I use (Premise). When the light is commanded to transition, Premise receives the first brightness status message from the light (a low value) and that’s the light’s brightness for the duration of the transition (because the light issues only one status report upon initial receipt of the transition command). It’s not ideal but that’s the way it works.

In other words, the situation with Premise is opposite to Home Assistant which immediately indicates the transition’s final (not initial) brightness value. Effectively, it “anticipates” and reports the light’s brightness to be its final (i.e. target) value.

This comparison highlights the challenge for any home automation software to accurately report transition status. Ultimately it depends on the light’s ability to report it’s changing brightness level. This ability depends upon the lighting technology. As far as I know, most lighting technologies do NOT report their transition status while it’s changing.

Because Premise reports only what the light reports, I can create an automation to periodically poll the light, while it’s transitioning, to acquire its latest brightness value. I can also do this with Home Assistant, however it will have an initial glitch because Home Assistant initially reports the transitioning light’s brightness to be its final brightness. It’s this initial “anticipated” value that renders the wait_template useless.

Seems like calculated delays are the way to go.

1 Like

Edit : There is a problem with brightnes: vs brightness_pct: (No Idea Why) Please go down to Post 95 for the workaround

Okay, Here we go : -

I have written for 30 to 255 (and it suspiciously/fortuitously comes out at 80s per 1/255)
Not sure if I needed the
{% set outp = 0.0 %}
line as I need a float but start off with integers (maybe I’m being pedantic)
But I’m sure the code could be improved/polished but try to keep it readable/easily maintainable as bedfellow is still learning.

Anyway here is the package : -

input_boolean:
  ib_fishtank01_brightness_overide:
    name: Brightness Overide
    icon: mdi:arrow-collapse-up

input_number:
  in_fishtank01_brightness_level:
    name: Brightness (/255)
    initial: 0
    min: 0
    max: 256
    step:1
    mode: box
    icon: mdi:arrow-expand-vertical

automation:
  - alias: au_fishtank01_brightness_overide_timer
    trigger:
      - platform: state
        entity_id: input_boolean.ib_fishtank01_brightness_overide
    action:
      - service: script.turn_off
        entity_id: script.sc_fishtank01_overide_timer
      - service_template: script_{{trigger.to_state.state}}
        entity_id: script.sc_fishtank01_overide_timer
  - alias: au_fishtank01_adjust_brightness
    trigger:
      - platform: state
        entity_id: input_number.in_fishtank01_brightness_level
      - platform: state
        entity_id: input_boolean.ib_fishtank01_brightness_overide
      - platform: time_pattern
        seconds: '/80'
    action:
      - service: script.sc_fishtank01_calc_level
      - delay: '00:00:01'
      - service: light.turn_on
        entity_id: light.fishtank01_level
        data_template:
          brightness: "{{ states('input_number.in_fishtank01_brightness_level') }}"
          transition: 10

script:
  sc_fishtank01_overide_timer:
    alias: FT Overide Timer Script
    sequence:
    - delay: "00:20:00"
    - service: input_boolean.turn_off
      entity_id: input_boolean.ib_fishtank01_brightness_overide
  sc_fishtank01_calc_level:
    alias: Fish Tank 01 Calc Brightness
    sequence:
    - service: input_number.set_value
      data_template:
        entity_id: input_number.in_fishtank01_brightness_level
        value: >
          {% set ovrd = is_state('input_boolean.ib_fishtank01_brightness_overide', 'on') %}
          {% set tnow = as_timestamp(now()) %}
          {% set frm12 = tnow - as_timestamp(now().strftime('%Y-%m-%d ' ~ '12:00')) %}
          {% set frm17 = tnow - as_timestamp(now().strftime('%Y-%m-%d ' ~ '17:00')) %}
          {% set frm22 = tnow - as_timestamp(now().strftime('%Y-%m-%d ' ~ '22:00')) %}
          {% set cnt = frm22 < 0 <= frm12 %}
          {% set rise = cnt and frm17 < 0 %}
          {% set fall = cnt and frm17 >= 0 %}
          {% set outp = 0.0 %}
          {% if ovrd %}
            {% set outp = 255 %}
          {% elif rise %}
            {% set outp = frm12 / 80 + 30 %}
          {% elif fall %}
            {% set outp = 255 - frm17 / 80 %}
          {% else %}
            {% set outp = 0 %}
          {% endif %}
          {{ (outp + 0.5) | int }}

I’d just bung this in a new file under packages but bedfellow may have to split it out for his particular configuration (I just keep it all together)

Obviously I have not tested this with real world entities nor over a 24 hour period, so theory now meets the real world.
Not this will maintain the desired level regardless of when HA is started.

Oh ! and it has a maintenance overide built in for 20 mins of 100% output - use it or ignore it, you choose.

@Mutt, thanks for the package. It may be some time before I can tell you if this works as TBH, at the moment I have no idea on how to implement this in HA

Hi @bedfellow,

As you gave me a brilliant idea to use your fish tank lighting idea for a different project, i’d like to return the favor to help you implement it in HA :slight_smile:

No worries, using packages is fairly easy. The extended documentation is overhere: https://www.home-assistant.io/docs/configuration/packages/, but i can understand that it’s a bit overwhelming.

Basically, there are 5 steps you have to take:

  1. Create a new folder in your Homeassistant-folder (where configuration.yaml is already at) and name it ‘packages’ without the quotes.
  2. In your newly created folder, create a file called ‘fishtank_light.yaml’ and paste the contents of @Mutt 's earlier code in the file. And of course, don’t forget to save :wink:
  3. Go back to your homeassistant-folder and open configuration.yaml. Add the following line at the line after homeassistant:, including the two spaces:
  packages: !include_dir_named packages

  1. Save configuration.yaml and restart Home Assistant.
  2. Enjoy your automatic fish tank light!

Good luck!

1 Like

@wouzziew, thanks, but somehow I thought it wouldn’t be that easy, as nothing ever seems to be in HA for me :smiley:

If I add the line to configuration.yaml I get:

bad indentation of a mapping entry at line 157, column 3:
      packages: .include_dir_named pac ... 
      ^

If I remove the indentation then I get:

Configuration invalid

Component error: packages - Integration 'packages' not found.

I suspect I need:

homeassistant:
  packages: !include_dir_named packages

@bedfellow Whoops, my bad! It’s not the end of the file (that just happens to be my own configuration-file format…)

Can you try adding it directly under the homeassistant: line (probably at the top of your file). Again, with the two spaces included. So it should look like this:

homeassistant:
  packages: !include_dir_named packages

I think there may be a space missing here:

It really is that easy

Here is the TOTAL of my configurageion.yaml
EVERYTHING else is in my Packages

homeassistant:
  packages: !include_dir_named packages
config:
discovery:
frontend:
  themes: !include themes.yaml
lovelace:
  mode: yaml
map:
media_player:
  - platform: squeezebox
    host: 192.168.192.233
    port: 9000
person:
sun:
system_health:
tts:    # Text to speech
  - platform: google_translate
updater:
weather:
  - platform: darksky
    api_key: !secret ky_darksky
    mode: daily
zwave:
  usb_path: /dev/ttyACM0
  network_key: !secret ky_zwave

Packages are new to me but I must say that I like them. I have a ZigBee join panel which has elements split all over configuration.yaml and it would be much smarter in packages.

Seems to be working now:
Screenshot_2020-03-14_16-58-04

Beat ya…

… And simultaneously realised that I can’t actually use the VSC addon from the mobile, otherwise I would’ve copy/pasted :confused:

Okay, I appear to have packages working now and there are entries in automations, but how do I apply these now to my light.0x680ae2fffeb18442_light?

I guess I need to create another automation to call it, but what would the trigger be?

Easy.
Open the file in an Editor, any will do and do a search and replace

where I have :

  • light.fishtank01_level
    you replace with :
  • light.0x680ae2fffeb18442_light
    (omit the leading dash blobby bullet point … PLEASE !)

And that’s it !
Do a config check, if it fails … errrrmm sorry I’ve left the country … nah comeback with your errors

if it passes, restart server to create the new entities.
It will just “work”

No the automations that are there are all the triggers you need.

The time_pattern, the input number changing and the change in the overide button are all built in

Yikes !

I need to revisit my config and move more stuff out.
I do actually have packages for media_player stuff so I’ve no excuse.

Not sure I can get it down to 7 lines though :thinking:

Okay, there seems to be an error with the fall value,
Give me a few minutes to test …

Okay found it … it was a typo, i wrote frm12 instead of frm17 on one line, the above code is corrected

This is what I have now… and it does nothing!

input_boolean:
  ib_fishtank01_brightness_overide:
    name: Brightness Overide
    icon: mdi:arrow-collapse-up

input_number:
  in_fishtank01_brightness_level:
    name: Brightness (/255)
    initial: 0
    min: 0
    max: 256
    step: 1
    mode: box
    icon: mdi:arrow-expand-vertical

automation:
  - alias: au_fishtank01_brightness_overide_timer
    trigger:
      - platform: state
        entity_id: input_boolean.ib_fishtank01_brightness_overide
    action:
      - service: script.turn_off
        entity_id: script.sc_fishtank01_overide_timer
      - service_template: script_{{trigger.to_state.state}}
        entity_id: script.sc_fishtank01_overide_timer
  - alias: au_fishtank01_adjust_brightness
    trigger:
      - platform: state
        entity_id: input_number.in_fishtank01_brightness_level
      - platform: state
        entity_id: input_boolean.ib_fishtank01_brightness_overide
      - platform: time_pattern
        seconds: '/80'
    action:
      - service: script.sc_fishtank01_calc_level
      - delay: '00:00:01'
      - service: light.turn_on
        entity_id: light.0x680ae2fffeb18442_light
        data_template:
          brightness: "{{ states('input_number.in_fishtank01_brightness_level') }}"
          transition: 10

script:
  sc_fishtank01_overide_timer:
    alias: FT Overide Timer Script
    sequence:
    - delay: "00:20:00"
    - service: input_boolean.turn_off
      entity_id: input_boolean.ib_fishtank01_brightness_overide
  sc_fishtank01_calc_level:
    alias: Fish Tank 01 Calc Brightness
    sequence:
    - service: input_number.set_value
      data_template:
        entity_id: input_number.in_fishtank01_brightness_level
        value: >
          {% set ovrd = is_state('input_boolean.ib_fishtank01_brightness_overide', 'on') %}
          {% set tnow = as_timestamp(now()) %}
          {% set frm12 = tnow - as_timestamp(now().strftime('%Y-%m-%d ' ~ '12:00')) %}
          {% set frm17 = tnow - as_timestamp(now().strftime('%Y-%m-%d ' ~ '17:00')) %}
          {% set frm22 = tnow - as_timestamp(now().strftime('%Y-%m-%d ' ~ '22:00')) %}
          {% set cnt = frm22 < 0 <= frm12 %}
          {% set rise = cnt and frm17 < 0 %}
          {% set fall = cnt and frm17 >= 0 %}
          {% set outp = 0.0 %}
          {% if ovrd %}
            {% set outp = 255 %}
          {% elif rise %}
            {% set outp = frm12 / 80 + 30 %}
          {% elif fall %}
            {% set outp = 255 - frm12 / 80 %}
          {% else %}
            {% set outp = 0 %}
          {% endif %}
          {{ (outp + 0.5) | int }}

see my post just above yours

it did work, it’s just that your input number didn’t like having -39 assigned to it (0 to 256 range) not sure why I did the 256 now, could get away with 255