Help with heating/time rule

Hello,

I would like to create a customisable heating configuration in habpanel with rules in the background. If everything will work fine, I will try to create a widget for that but at the moment it looks like this:

In the background the time slots are numbers from a dimmer item (0=Off, 1=0:00, 2=0:30 and so on).
At the moment the rule would work but it seems that there is much room for improvements. Now there are only log entries.

rule "Heizungssteuerung"
when
    Time cron "0 0/30 * * * ? *"
then
    logInfo("EXTRA","Heizungssteuerung: Halbe Stunde vorbei")
    if (now.getHour() == 0 && now.getMinute() == 0) {
        logInfo("EXTRA","Heizungssteuerung: Es ist 00:00")
        if (WohnzimmerHeizung_TimerMorgensan.state==1) {
            logInfo("EXTRA","Heizungssteuerung: Wohnzimmer Timer Morgens an")
        }
        if (WohnzimmerHeizung_TimerMorgensaus.state==1) {
            logInfo("EXTRA","Heizungssteuerung: Wohnzimmer Timer Morgens aus")
        }
        if (WohnzimmerHeizung_TimerAbendsan.state==1) {
            logInfo("EXTRA","Heizungssteuerung: Wohnzimmer Timer Abends an")
        }
        if (WohnzimmerHeizung_TimerAbendsaus.state==1) {
            logInfo("EXTRA","Heizungssteuerung: Wohnzimmer Timer Abends aus")
        }
    }
    if (now.getHour() == 0 && now.getMinute() == 30) {
        logInfo("EXTRA","Heizungssteuerung: Es ist 00:30")
        if (WohnzimmerHeizung_TimerMorgensan.state==2) {
            logInfo("EXTRA","Heizungssteuerung: Wohnzimmer Timer Morgens an")
        }
        if (WohnzimmerHeizung_TimerMorgensaus.state==2) {
            logInfo("EXTRA","Heizungssteuerung: Wohnzimmer Timer Morgens aus")
        }
        if (WohnzimmerHeizung_TimerAbendsan.state==2) {
            logInfo("EXTRA","Heizungssteuerung: Wohnzimmer Timer Abends an")
        }
        if (WohnzimmerHeizung_TimerAbendsaus.state==2) {
            logInfo("EXTRA","Heizungssteuerung: Wohnzimmer Timer Abends aus")
        }
    }

So you can see it will be very much code for such a simple rule…

I hope someone has an idea to pimp the rule…

Regards,
Florian

Why run a rule every 30 minutes an only do something at certain times? Just trigger the rule at the times you need to do something. You could break it up into multiple rules, one for each time.

In MainUI you can enter a time into a DateTime Item directly which also makes the widget much simpler.

One approach would be to create a DateTime Item for each of the start times of your heating time periods. Put them into a custom widget on your sitemap, or separate widgets but use an oh-input with “time” as the input mode.

Then create a rule triggered with a Time is <item> trigger (it can be configured to only look at the time, not the date) for each DateTime Item. Put in the rule the code for what ever needs to be done at that time.

If you need something a little more complex, look at the Time Based State Machine on the marketplace to drive the time of day states which can set up a different schedule based on the type of day (e.g. weekends, holidays, etc.).

Then the question becomes what’s the difference between the three WohnzimmerHeizung_TimerX Items? Are these mutually exclusive? If so they could be consolidated. If not, there’s probably not something you can do to make these better.

The only thing I can think of is if you built this rule in the UI you could set up conditions. Then you’d trigger the rule for morning (for example) and in the condition only let it run if one or more of those Items are in the right state.

But it’s not really clear how this widget and rules are supposed to be working together.

In the widget I would like to set a flexible time for each heater in the house for the day and saving temperatures.
That’s the reason why the rule triggers every 30 minutes. All four timers are for different situations.
“WohnzimmerHeizung_TimerMorgensan” is for the beginning of the day.
“WohnzimmerHeizung_TimerMorgensaus” is for the time went away from home and can save some energy.
“WohnzimmerHeizung_TimerAbendsan” is for the return and the last one “WohnzimmerHeizung_TimerAbendsaus” is for the end of the day when we go to bed.

This all should be implemented for every room, because the usage of the rooms is different over the hole day. Before our kid was born it was really easy and all was in fixed rules but now I have to adjust the rules very often. So I decided to but a customisable time selector in the frontend (habpanel) and write a dynamic rule for the check.
But the dynamic rule isn’t that dynamic as I aspected.

I will have a look on the DateTime Items and will check if the widget with an oh-input will fix some of my problems. For sure the selector should be more simple and perhaps the rules can then also be modified with a single argument for all time slots.

Thank you for the hint. Do you know if something like that will work:

if (now.getHour() == DateTimeItem.getHour() && now.getMinute() == DateTimeItem.getMinute()) {

Regards,
Florian

It would be more dynamic if you used timers instead of a 30 minute polling period. Then you could trigger the rule only when one of the times change and around midnight to reschedule the timers for the next day.

If you use MainUI or can figure out how to update a DateTime Item in HABPanel you could trigger rules based on the state of those Items.

So these are mutually exclusive. You’ve never have TimerMorgensan and TimerMorgensaus active at the same time. So just have one Item and set its state based on the currently active state. For example, have a String Item named WohnzimmerHeizung_State and set it to “TimerMorgensan”, “TimerMorgensaus” etc.

If I were to implement this I’d do the following.

  1. Create a separate DateTime Item for each room and each time state (i.e. TimerMorgensan, TimerMorgensaus, etc.). This assumes that each room has a different set of times. So if you have four rooms and four states, you’d have 16 Items.
  2. Use an input card with the “type” set to “time” This generates a widget that looks like this.

  1. If these Items are in the semantic model, they will automatically appear on the locations tab of the Overview Page in the right rooms. Otherwise I’d crate a page for them to have a place to edit them. But the semantic model makes it really nice, the UI creates itself.

  2. The rules could be handled in a bunch of different ways. Probably the simplest would be to create separate rules which could be triggered by one of the Items above using the Time is <item> trigger. Then all you need to do is command the Item as appropriate (presumably setting the thermostat setpoint in that room). You could use just UI rules and not even need to write code for that and you don’t need a separate Item to keep track of the current time state.
    Another approach could be to consolidate all the rules for a given rule into one but this will require keeping track of the time of day state separately from the rules that do the work. You could use Time Based State Machine, or just create a separate simple rule triggered by Time is <item> triggers that commands a String Item with the current time of day state (e.g. “TimerMorgensan”). If you have more than one “schedule” per room, you’d have one String Item per room. Then you’d have a rule triggered when that String Item receives a command or changes and you can use a simple switch statement to set the setpoint based on the String the state Item changed to.
    Yet another approach would be to create a universal rule for all rooms. In this approach I would use the Time Based State Machine to send a command to a String Item. The command will include the room name and the time of day state. This will trigger a rule which has a switch statement on the room+state to update the setpoint accordingly. That rule could be made simpler by using Design Pattern: Associated Items. So, for example, if the room is the first part of your setpoint’s Item name and “thermostat” is the second part the consolidated rule and you put the setpoints into Items with a predictable pattern using those it would look something like:

import org.eclipse.smarthome.model.script.ScriptServiceUtil

rule "Heizungssteuerung"
when
    Item Thermostat_State received command
then
    val parts = receivedCommand.toString.split('_')
    val roomName = parts.get(0)
    val timeState = parts.get(1)
    val setpointItemName = roomName+"_"+timeState+"_Setpoint"
    val setpointItem = ScriptServiceUtil.getItemRegistry.getItem(setpointItemName)
    val setpoint = setpointItem.state as Number

    sendCommand(roomName+"_Thermostat", setpoint)
end

That’s it. That’s the full rule which handles all your rooms. But you are trading lots of Items for a simpler rule. And I don’t show the rule that updates the Thermostat_State Item (which drives this whole thing) because you’d just install that from the marketplace.