I second this.
Though my advice isn’t worth much here. I have a grand total of three lamps controlled (have no need for more at this time).
However, I have comment on the logic/programming/rules side of things.
-
You will want to get very comfortable with Groups and [State Machines(A State Machine Primer with HABlladin, the openHAB Genie). A state machine is just a fancy way to think about and code a bunch of “if this then that” rules to control your house.
-
Think about your lighting as state transitions. You can put everything into a table if it is easier for you. For example:
State/Event Group 1 Group 2 Group 3
-------------------------------------------------------------------------
Morning 25% / blue OFF 100% - Warm White
Day + Someone Home OFF OFF 50% - Warm White
Day + No one Home OFF OFF OFF
...
Once you have your “scenes” configured it is a simple matter of setting up a rule that triggers when ever the events on the left occur, calculates which State your house is in, and then issues the proper commands to the members of the Groups.
Note that you can have as many Groups as you need and a Light can be a member of multiple Groups. However, if a Light is a member of multiple Groups you need to be careful of your states and figuring out which one takes precedence.
I also found it handy to use a Time of Day state machine to drive stuff that needs to change based on the time of day.
So for example, I’d have a Switch which gets turned ON when the weather says it is cloudy and a Rule that gets triggered when the Time of Day changes. Note: my rule actual rule looks difference from this as I’m doing some tricks with Groups.
rule "Lighting scene change"
when
Item TimeOfDay changed or
Item Weather_Cloudy changed
then
switch TimeOfDay {
case "MORNING": {
gMorningLightsON.members.filter[l|l.state != ON].forEach[l| l.sendCommand(ON)]
gMorningLightsOFF.members.filter[l|l.state != OFF].forEach[l| l.sendCommand(OFF)]
}
case "DAY": {
gDayLightsON.members.filter[l|l.state != ON].forEach[l | l.sendCommand(ON)]
gDayLightsOFF.members.filter[l|l.state != OFF].forEach[l | l.sendCommand(OFF)]
if(Weather_Cloudy.state == ON) gWeatherLightsON.members.filter[l|l.state != ON].forEach[l|l.sendCommand(ON)]
else gWeatherLightsON.members.filter[l.state != OFF].forEach[l | l.sendCommand(OFF)]
}
case ...
}
end
Obviously there is a lot that can be done to simplify the above even further with a lambda or Associated Items but I think this illustrates the main thrust of a State Machine of this type. For illustrative purposes my actual rule looks like:
val logName = "lights"
rule "Set lights based on Time of Day"
when
Item vTimeOfDay changed or
Item Weather_Cloudy changed
then
val offGroupName = "gLights_OFF_"+vTimeOfDay.state.toString
val onGroupName = "gLights_ON_"+vTimeOfDay.state.toString
logInfo(logName, "Turning off lights in " + offGroupName)
val GroupItem offItems = gLights_OFF.members.filter[g|g.name == offGroupName].head as GroupItem
offItems.members.filter[l|l.state != OFF].forEach[l | l.sendCommand(OFF)
]
logInfo(logName, "Turning on lights for " + onGroupName)
val GroupItem onItems = gLights_ON.members.filter[g|g.name == onGroupName].head as GroupItem
onItems.members.filter[l|l.state != ON].forEach[l | l.sendCommand(ON)
]
if(vTimeOfDay.state == "DAY"){
if(Weather_Cloudy.state == ON) gLights_Weather_ON.members.filter[l | l.state != ON].forEach[l | l.sendCommand(ON)]
else gLights_Weather_ON.members.filter[l|l.state != OFF].forEach[l| l.sendCommand(OFF)]
}
end