Gradual auto dimming lights

Hi,

New to community / first post so bear with me:

My setup:

  • Raspberry Pi 4 B, 4GB RAM
  • openHAB 3.0.1 on openHABian
  • openjdk 11.0.9
  • Phillips Hue bridge

I wanted the Zigbee & Phillips Hue lights in my hallway and office to imperceptibly dim throughout the day between 2 easily configurable times. During that time to go from max brightness & brilliant white to a dim yellow. Ie: to do this:

I couldn’t find a ready-made solution so I wrote my own (1st openHAB) script. I suspect someone will tell me there’s a toggle I’ve missed somewhere or that there’s some other much easier way to do this. But regardless, I enjoyed this little exercise and hope it may be of some use to others.

Feedback/improvement suggestions welcome!

logInfo("RulesLog","Starting AutoDimHallLights script.")
var PercentType currentBrightness = HallZone_Brightness.getStateAs(PercentType)  
logInfo("RulesLog","Brightness = "+currentBrightness)

var PercentType currentColorTemp = HallZone_ColorTemperature.getStateAs(PercentType)
logInfo("RulesLog","ColorTemperature = "+currentColorTemp)

//get seconds elapsed since 00:00am
val LocalDateTime startOfDay = now.toLocalDate().atStartOfDay()
val Duration durationSinceStartofDay = Duration.between(startOfDay , now );
val int secondsOfDay = durationSinceStartofDay.toSeconds.intValue

//get START time
val int startHour = 6
val int startMinute = 0
val int start = (startHour*60*60)+(startMinute*60)
logInfo("RulesLog","start: "+start)  

//get END time
val int endHour = 23
val int endMinute = 00
val int end = (endHour*60*60)+(endMinute*60)
logInfo("RulesLog","end: "+end)  


//get DURATION 
val int duration = end - start
logInfo("RulesLog","duration: "+duration)  

//get step (ie: every x minutes, reduce brightness by 1%)
val int step = duration / 100
logInfo("RulesLog","step: "+step)  

//adjust now to be seconds from 00:00
val int adjustedNow = secondsOfDay - start

//default to nightlight mode
var int colorTemp = 100
var int brightness = 1  

//adjust as necessary
if (adjustedNow >= 0) {
  colorTemp = (adjustedNow / step)
  if (colorTemp < 100) {
    brightness = 100-colorTemp
  } else {
    colorTemp=100
  }
}

logInfo("RulesLog","Now is "+secondsOfDay)  
logInfo("RulesLog","Setting ColorTemperature to "+colorTemp)  
logInfo("RulesLog","Brightness Brightness "+brightness)  

//set the lamps!
HallZone_ColorTemperature.sendCommand(colorTemp)
HallZone_Brightness.sendCommand(brightness)
Office1Room_ColorTemperature.sendCommand(colorTemp)
//Office1Room_Brightness.sendCommand(brightness)
Office2Room_ColorTemperature.sendCommand(colorTemp)
//Office2Room_Brightness.sendCommand(brightness)

I have a rule to run the script every 1 minute:

triggers:
  - id: "1"
    configuration:
      cronExpression: 0 0/1 * * * ? *
    type: timer.GenericCronTrigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      considerConditions: true
      ruleUIDs:
        - 751537f296
    type: core.RunRuleAction

And I am having to auto-restart openHAB entirely every 4 hours due to this bug

My work-around is to edit this file:

/etc/systemd/system/multi-user.target.wants/openhab.service

and add the following:

Restart=always
RuntimeMaxSec=14400

I did something similar here:

I did it in javascript and I also converted all my DSL rules to javascript because of the bug you mentioned.

Thanks for posting! I’ve moved this to the Tutorials and Solutions category.

A few things I notice:

  • Why separate the Script Action from the Rule? It’s more self contained to put the Script Action in the Rule.

  • Add a time based script condition so the rule doesn’t run at all at the times where there is nothing to do (between 23:00 and 06:00). A Script condition for 06:00 to 23:00 will prevent it from running over night where there is nothing for the rule to do.

  • Avoid the use of primitives and over specifying types in Rules DSL. It makes it much harder for the parser to load and validate the code without actually adding anything. Rules DSL tries really hard to be a weakly typed language, let it be that.

  • Running once a minute might be a lot more than is necessary. You’ve only 100 steps for the color temp and brightness. There are 1020 minutes between 06:00 and 23:00 meaning that this rule is running more than 10 times more often than it needs to during the day. You can run it every ten minutes and get the same results.

Future enhancements to consider:

  • Base the start and end times on sunrise and sunset instead of fixed times.
  • Use DateTime Items to store the start time and end time so they can be manually adjusted on the UI.
  • Use a Group or Groups to define the Items that this rule controls instead of writing code for each Item individually.
  • Only send the commands to adjust the lights that are ON.

Nice work!

A completely different approach (if you want to practice you programming skills) would be to use the HUE API in combination with the ‘transition’ time.
From the HUE API Description:

The duration of the transition from the light’s current state to the new state. This is given as a multiple of 100ms and defaults to 4 (400ms). For example, setting transitiontime:10 will make the transition last 1 second.

Although I’m not sure it’s as flexible as your solution!
Thanks for posting

Thanks very much for the feedback and for the welcome!

All hints & recommendations above are entirely valid and exactly what I was hoping for (in order for me to continue my learning journey.)

Will act on recommendations when I have time. Thanks again.

I am running every minute because:

  • some of the lights are on regular light switches. Ie: power disconnects.
  • I don’t know of any event being triggered when power is restored. (That i could act on and then run the script)
  • So i just run it every minute and wait for the script to run/change the light values.

Not ideal. The only solutions I can think of are:

  • replace light switches with zigbee switches.
  • tape up the old switches and always use the app to toggle lights! (not practical)
  • act on appropriate OpenHAB event (unsure of existence)

I use zigbee and wifi lights.
The light switches are taped so you can’t operate them. (IE always on)
I have Phillips Hue motion sensors as they have motion, lux and temperature sensors.
The lights only come on if the lux value is below whatever I set it.
The Hue sensors are good and battery life is great and I can see the temperature of the room as well.
Works well.

Motion sensors! Of course. Thanks.

If you look at the example I posted earlier you will find the code etc.

Over all this is why I do not use and do not recommend smart bulbs. They are simple more trouble than they are worth unless you really want to mess with color.

I would imagine that when the power is pulled on a light bulb its Thing in OH will go offline eventually. There are events for that which can trigger a rule. When the Thing goes back to ONLINE you can trigger a rule and run the code for that bulb to set the color and temp then.

1 Like