That worked for me. Thanks!
Great - hope that it proves interesting to you. Amazingly it needs to be fairly bright so you can see the on/off sequence with your eyes closed. Blue is a good choice of colour. The sequence between off-to-on and on-to-off in this setup is equal. The on-to-off step is supposed to be longer. The sequence is suppose to run for about 15 minutes what I have works for me.
Did a Yaml version of this happen? Iām interested if so. Donāt have NR so not keen to pursue that route.
@Isablend - no a yaml version does not exist (yet). I renamed the flow.json file to flow.yaml so that I could upload it. To import this you will need node-red.
I couldnāt resist having a go, but ultimately failed in writing this in yaml, just couldnāt get the timing right, so i gave it a go using appdaemon, and it turns out to be a relatively easy thing to do. Having spent a bit of time learning about appdaemon, I think I will use it for more complex automations in future.
So I have a light defined and in input boolean to allow switching on and off (also allows for an Alexa initiation). Iāve defined 5 variables in the accompanying .yaml file which define the number of minutes for the thing to run, the starting breaths per minute and the ending breaths per minute, along with the maximum and minimum light settings (expressed as a percentage).
The appdaemon code is then as follows;
import appdaemon.plugins.hass.hassapi as hass
import time
# App to turn a light into a sleep inducer
# Turns the light on and off to mirror breathing pattern
# slowly reducing the rate of breaths over a stated period of time
class Sleep_Inducer(hass.Hass):
# Initialise all of the necessary variables for the app
def initialize(self):
self.si_min = int(self.args["sleep_inducer_minutes"])
self.st_bpm = int(self.args["starting_breaths_per_minute"])
self.end_bpm = int(self.args["ending_breaths_per_minute"])
self.max_bri = int((255/100)*int( self.args["max_brightness"]))
self.min_bri = int((255/100)*int( self.args["min_brightness"]))
self.listen_state(self.SleepInducerOn, "input_boolean.sleep_inducer", new="on")
def SleepInducerOn(self, entity, attribute, old, new, kwargs):
if new == 'on' :
# execute for a set number of minutes
for minute_count in range(self.si_min):
# calculate the breath time for this minute's iteration
breath_number = int( ( ( -0.125 * ( self.st_bpm - self.end_bpm ) ) * minute_count ) + self.st_bpm )
breath_time = float( 60 / ( ( ( -0.125 * ( self.st_bpm - self.end_bpm ) ) * minute_count ) + self.st_bpm ) )
# set number of times in the current minute to breath
for breath_count in range(int(breath_number)):
# breath in - 3/5 of breath_time
breath_in=breath_time*(3/5)
self.turn_on("light.sleep_inducer",
color_name = "blue",
transition = int(breath_in),
brightness = self.max_bri)
# pause to let the light catch-up
time.sleep(breath_in)
breath_out=breath_time*(2/5)
# breath out - 2/5 of breath_time
self.turn_on("light.sleep_inducer",
transition = int(breath_out),
brightness = self.min_bri)
# pause to let the light catch-up
time.sleep(breath_out)
# check that it has not been cancelled
continue_si=self.get_state('input_boolean.sleep_inducer')
# drop out of breath_count loop
if continue_si=='off' :
break
# drop out of minute_count loop
if continue_si=='off' :
break
# turn off the sleep_inducer switch
self.turn_off("input_boolean.sleep_inducer")
# turn the light off
self.turn_off("light.sleep_inducer")
Iām sure itās not perfect, but it works and has opened up a whole new area for me to investigate.
Hi seems to be working fine but it doesnāt turn off with the button manually , it turns of by itself after certain time only ? I used the flow that you sent @GeoffAtHome
Tried rewriting in as a package in yaml and using scenes to set what required. Appears to work and simpler to edit.
#
# Based on the Dodow video
# Duration: 8 minutes (480 seconds)
# Initial breathing: 11 breaths a minute (once every 5.45 seconds (60/11) )
# Final breathing: 5 breaths a minute (once every 12 seconds (60/5) )
#
# This equates to slowing down from breathing once every 5.45 seconds
# to once every 12 seconds over eight minutes
# which is about 55 cycles
# Each cycle we need to add a delay of about 0.08727 seconds
#
# The scenes need to be create for the light that is going to be used.
# The scenes are:
# scene.spl_breathing_in
# scene.spl_breathing_out
# scene.spl_breathing_end
#
# scene.spl_breathing_in - turns the light on. Must be bright enough to see with you eyes closed but not too bright
# scene.spl_breathing_out - dims the light down. Could be total off if needed
# scene.spl_breathing_end - turns the light off at the end running the script
# Everything needs to be divided by two as we are breathing in and out
#
input_number:
initial_breathing:
initial: 2.72
min: 0.0
max: 60.0
final_breathing:
initial: 6.00
min: 0.0
max: 60.0
delta:
initial: 0.43535
min: 0.0
max: 1.0
current_breathing:
initial: 5.45
min: 0.0
max: 60.0
script:
sleepy_lights_start:
alias: Start sleepy
sequence:
- service: input_number.set_value
entity_id: input_number.current_breathing
data_template:
value: '{{ states("input_number.initial_breathing") | float }}'
- repeat:
while:
- condition: template
value_template: '{{ states("input_number.current_breathing") | float < states("input_number.final_breathing")| float }}'
sequence:
- service: input_number.set_value
entity_id: input_number.current_breathing
data_template:
value: '{{ states("input_number.current_breathing") | float + states("input_number.delta") | float}}'
- service: scene.turn_on
target:
entity_id: scene.spl_breathing_in
data_template:
transition: '{{ states("input_number.current_breathing") | float }}'
- delay: '{{ states("input_number.current_breathing") | float }}'
- service: scene.turn_on
target:
entity_id: scene.spl_breathing_out
data_template:
transition: '{{ states("input_number.current_breathing") | float }}'
- delay: '{{ states("input_number.current_breathing") | float }}'
- service: scene.turn_on
target:
entity_id: scene.spl_breathing_end