Looking for some advice on creating rules

Over the years my openHAB solution has grown in terms of devices used and complexity. Although I’m no coder I’ve managed to pull together rules that work for me, where I’ve not been able to do so I’ve either put the idea to bed or found a work around.

I’m now at the stage where I need to clean up my code, not just so as to keep playing around but because I have no doubt rules that could be far less complicated or laid out in a more understandable way.

So the first bit of advice I’m looking for is around rules where I have multiple scenario’s. Let’s take my Kitchen Motion Sensor as an example to start with. I use this to switch on the lights in the kitchen when needed. I also use it to send notifications to the Sonos speaking, for weather information or travel.

Presently I have one big rule that covers every possible scenario for when the Motion Sensor is activated. Which makes updating the rule quite difficult, for me at least, when i think of a new idea. So do I try to rearrange the rule and keep it as one or do I create multiple rules?

I know there is no right or wrong answer, so feel free to offer whatever advice you have. I’m all ears.

Thanks

Garry

It’s impossible to provide concrete advice without seeing the Rule itself. But if it is hard to add to it that usually means that you have a lot of duplicated code. I recommend reviewing the Design Pattern: DRY, How Not to Repeat Yourself in Rules DSL post which has links to a lot of techniques for breaking up and simplifying Rules. But which techniques are appropriate for a given Rule is highly context dependent.

I recommend trying to apply the approaches that make sense to you and I think you will find whether it makes sense to split it into multiple Rules will become apparent.

Thanks for the reply, happy to publish my rule as it is. I didn’t do so in my first post as i didn’t want people to think I was just looking for someone to rewrite my rule.

I’ll take a look at the links also.

rule "Kitchen Motion Sensor On"
when
    Item Kitchen_SP3102_Motion changed to ON
then
postUpdate(Kitchen_Motion_Sensor_Last_Activation, new DateTimeType())
logInfo("org.openhab","Motion Sensors: Kitchen {}.",Kitchen_SP3102_Motion.state)
var dimmingState = -1
if(Kitchen_Strip_Light_Dimmer.state > 1 || Porch_ST815_Lux_Level.state > 400) return;
switch Time_Of_Day.state {
    case "MORNING": if(Porch_ST815_Lux_Level.state < 120) dimmingState = 25
    case "DAY": if(Porch_ST815_Lux_Level.state < 110) dimmingState = 35
    case "EVENING": dimmingState = 65 
    case "NIGHT": dimmingState = 55
    case "BED": dimmingState = 30
}
if(dimmingState != -1) {
    Kitchen_Strip_Light_Dimmer.sendCommand(dimmingState)
    logInfo("org.openhab","Kitchen: Strip Light level is " + dimmingState + "%")
}
if(Announcements.state == 3) return;
setMasterVolume(new PercentType(20))
if(now.getHourOfDay > 6 && Announcements.state == 0) {
    //val java.util.Random rand = new java.util.Random
    //var Greeting = newArrayList("Good Morning. ","Hi. ","Morning. ","Hello. ")
    //var i = rand.nextInt(4);
    //var greeting = Greeting.get(i)
    //{
        //var Weather = newArrayList("The current conditions are ")
        //var i = rand.nextInt(3);
        //var weather = Weather.get(i)
        announcement = "Good Morning, I hope you managed to sleep OK. The current weather conditions are " + Weather_OWM_Condition.state
        say(announcement)
        logInfo("org.openhab","Voice Announcement: First Morning Announcement Made")
        Announcements.sendCommand(1)
}
//}
if(Announcements.state == 1) {
    if(now.getHourOfDay > 7) {
        announcement = "Have you remembered to drink your bennycoll? The forecast temperature is expected to be " + Weather_OWM_Forecast_Maximum.state
        say(announcement)
        logInfo("org.openhab","Voice Announcement: Second Morning Announcement Made")
        Announcements.sendCommand(2)
        if(Weekend.state == ON) {
            say("It's the weekend so. Here's Heart Wiltshire for you.")
            Kitchen_URI.sendCommand("6894")
            Kitchen_Volume.sendCommand(12)
            Kitchen_Controller.sendCommand("PLAY")
            logInfo("org.openhab","Voice Announcement: Playing Heart Wiltshire as it's the weekend.")
        }
    if(Day_Of_The_Week.state == "Tuesday") {
        say("As your not at work today, Sarah; here's Heart Wiltshire.")
        Kitchen_URI.sendCommand("6894")
        Kitchen_Volume.sendCommand(12)
        Kitchen_Controller.sendCommand("PLAY")
        logInfo("org.openhab","Voice Announcement: Today is Tuesday, Playing Heart Wiltshire.")
    }
    if(Day_Of_The_Week.state == "Friday") {
        say("It's Friday working from home day Garry; here's Radio Two.")
        Kitchen_URI.sendCommand("24940")
        Kitchen_Volume.sendCommand(12)
        Kitchen_Controller.sendCommand("PLAY")
        logInfo("org.openhab","Voice Announcement: Today is Friday, Playing Radio Two.")
    }
//}
    }
}
if(now.getHourOfDay > 20) {
    if(Announcements.state == 2) {
        announcement = "Good Evening, just a reminder that it's getting late, have you remembered to lock the back door yet?"
        say(announcement)
        Announcements.sendCommand(3)
        logInfo("org.openhab","Voice Announcement: Evening Announcement Made.")
    }
}
end

This Rule isn’t so bad really. You could merge your conditions in Announcements.state == 1 using “Design Pattern: How to Structure a Rule”. All that is different between the if statements is the values used. That would save you a few lines of code but not a lot, but more importantly it would put the code that actually causes stuff to happen in one place which makes it easier to modify as needed.

You could move the calculations of the dimming state to it’s own Rule using Separation of Behaviors. I see that you are using Design Pattern Time of Day which is a special case of Separation of Behaviors so you can use that as a template. Just trigger the Rule on changes to Time_Of_Day and put the dimming state value into an Item. But that doesn’t really save you much.

You might be able to apply A simple scene management: finally a good use of scripts or one of the techniques from 3 different methods to use scenes with Google Home & openHAB. This will let you separate the calculation to figure out what scene is wanted and the steps to take place in a given scene.

Compared to a lot of Rules I’ve seen posted on this forum, this Rule isn’t so bad. Any of the techniques I’ve identified will not have a huge impact over all (e.g. sometimes I’ll shrink the lines of code by 75% by applying these techniques).

Thanks for the vote of confidence. It just looks untidy to me, but if don’t think there is much that can be changed that works for me. I’ll take a look at what you’ve suggested.