HABPanel widget: Virtual Thermostat/OnOff Appliance scheduling

Can anyone tell me if every minute, once a schedule is set, is it meant to keep changing the thermostat?

The set point item is set correctly. Whilst I know the rule runs every minute, if the Queue is empty, why would it keep running if the set point has been set? Is this because at the end of the schedule you need to know when to delete it and without running it frequently, youll go pass the end of the schedule?

[{"setItem":"HVAC_Bed1_Target_Temp","readItem":"HVAC_Bed1_Temp","label":"Bed 1"},{"setItem":"HVAC_Bed2_Target_Temp","readItem":"HVAC_Bed2_Temp","label":"Bed 2"},{"setItem":"HVAC_Bed3_Target_Temp","readItem":"HVAC_Bed3_Temp","label":"Bed 3"}]

When I set the schedule:

08:13:53.877 [INFO ] [smarthome.event.ItemCommandEvent     ] - Item 'HVAC_Schedule' received command {"HVAC_Bed2_Target_Temp":{"D1":{"T0815":18},"D4":{},"D7":{}},"HVAC_Bed3_Target_Temp":{"D1":{},"D2":{},"D5":{},"D7":{}}}
08:13:53.881 [INFO ] [smarthome.event.ItemStateChangedEvent] - HVAC_Schedule changed from {"HVAC_Bed1__Target_Temp":{"D4":{}},"HVAC_Bed2_Target_Temp":{"D1":{},"D4":{},"D7":{}},"HVAC_Bed3_Target_Temp":{"D1":{},"D2":{},"D5":{},"D7":{}}} to {"HVAC_Bed2_Target_Temp":{"D1":{"T0815":18},"D4":{},"D7":{}},"HVAC_Bed3_Target_Temp":{"D1":{},"D2":{},"D5":{},"D7":{}}}
08:13:53.892 [INFO ] [odel.script.temperature-control.rules] - [HEAT] Next change @2019-09-16T08:15:00.000+10:00 | Changes : HVAC_Bed2_Target_Temp=18
08:13:53.894 [INFO ] [smarthome.event.ItemStateChangedEvent] - HVAC_Next_Change_Time changed

Then it runs as per schedule:


08:15:00.003 [INFO ] [smarthome.event.ItemStateChangedEvent] - HVAC_Queue changed from  to HVAC_Bed2_Target_Temp=18
08:15:00.006 [INFO ] [odel.script.temperature-control.rules] - Target temperature for item HVAC_Bed2_Target_Temp changed from 24.00 to 18
08:15:00.023 [INFO ] [odel.script.temperature-control.rules] - Target Temperature Queue cleaned up
08:15:00.025 [INFO ] [smarthome.event.ItemCommandEvent     ] - Item 'HVAC_Bed2_Target_Temp' received command 18
08:15:00.026 [INFO ] [smarthome.event.ItemStateChangedEvent] - HVAC_Bed2_Target_Temp changed from 24.00 to 18
08:15:00.033 [INFO ] [odel.script.temperature-control.rules] - [HEAT] Next change @2019-09-16T08:15:00.000+10:00 | Changes : HVAC_Bed2_Target_Temp=18
08:15:00.039 [INFO ] [smarthome.event.ItemStateChangedEvent] - HVAC_Queue changed from HVAC_Bed2_Target_Temp=18 to
08:15:00.042 [INFO ] [smarthome.event.ItemStateChangedEvent] - HVAC_Queue changed from  to HVAC_Bed2_Target_Temp=18
08:15:00.043 [INFO ] [odel.script.temperature-control.rules] - Target temperature for item HVAC_Bed2_Target_Temp changed from 18 to 18
08:15:00.045 [INFO ] [smarthome.event.ItemCommandEvent     ] - Item 'HVAC_Bed2_Target_Temp' received command 18
08:15:00.056 [INFO ] [smarthome.event.ItemStateChangedEvent] - HVAC_Queue changed from HVAC_Bed2_Target_Temp=18 to
08:15:00.055 [INFO ] [odel.script.temperature-control.rules] - Target Temperature Queue cleaned up

Then every minute after

08:16:00.014 [INFO ] [odel.script.temperature-control.rules] - [HEAT] Next change @2019-09-16T08:15:00.000+10:00 | Changes : HVAC_Bed2_Target_Temp=18
08:16:00.017 [INFO ] [smarthome.event.ItemStateChangedEvent] - HVAC_Queue changed from  to HVAC_Bed2_Target_Temp=18
08:16:00.019 [INFO ] [odel.script.temperature-control.rules] - Target temperature for item HVAC_Bed2_Target_Temp changed from 18.00 to 18
08:16:00.020 [INFO ] [smarthome.event.ItemCommandEvent     ] - Item 'HVAC_Bed2_Target_Temp' received command 18
08:16:00.023 [INFO ] [odel.script.temperature-control.rules] - Target Temperature Queue cleaned up
08:16:00.023 [INFO ] [smarthome.event.ItemStateChangedEvent] - HVAC_Queue changed from HVAC_Bed2_Target_Temp=18 to**strong text**
08:17:00.014 [INFO ] [odel.script.temperature-control.rules] - [HEAT] Next change @2019-09-16T08:15:00.000+10:00 | Changes : HVAC_Bed2_Target_Temp=18
08:17:00.020 [INFO ] [smarthome.event.ItemStateChangedEvent] - HVAC_Queue changed from  to HVAC_Bed2_Target_Temp=18
08:17:00.021 [INFO ] [odel.script.temperature-control.rules] - Target temperature for item HVAC_Bed2_Target_Temp changed from 18.00 to 18
08:17:00.023 [INFO ] [smarthome.event.ItemCommandEvent     ] - Item 'HVAC_Bed2_Target_Temp' received command 18
08:17:00.024 [INFO ] [odel.script.temperature-control.rules] - Target Temperature Queue cleaned up
08:17:00.025 [INFO ] [smarthome.event.ItemStateChangedEvent] - HVAC_Queue changed from HVAC_Bed2_Target_Temp=18 to


Is this normal?

Hi all,

thanks for the great Widget. Ist work fine for me if i want Change the temperature in the Manual Mode.

But i have Problems with the Schedule.

The Schedule is active if i Change the Mode on Auto.
The Temperature goes to the right value from the Schedule.
But 30 seconds later, the Mode Change to manuel and the Temerature Change to the last manuel Value.

I use the AVM Fritz! Binding (Link )

Temperature read, no problem.
Temperature write, with the manuel Temerature Channel ID. Works fine with manuel Mode.

But i have also channel IDs for Temperature and Datetime for the next Change. But this i cant use in the Widget. Allways i send the Temperatur i Change the Mode to manuel.

I think i can only use the Widget in manuel Mode because i need more items and other rules for the AVM Bindung?
Or where is my fault?

the log:

2019-09-28 20:59:28.551 [ome.event.ItemCommandEvent] - Item 'HVAC_Mode' received command AUTO

2019-09-28 20:59:28.572 [nt.ItemStatePredictedEvent] - HVAC_Mode predicted to become AUTO

2019-09-28 20:59:28.590 [vent.ItemStateChangedEvent] - HVAC_Mode changed from MANUAL to AUTO

2019-09-28 20:59:28.624 [ome.event.ItemCommandEvent] - Item 'HVAC_Mode' received command AUTO

2019-09-28 20:59:28.648 [nt.ItemStatePredictedEvent] - HVAC_Mode predicted to become AUTO

==> /var/log/openhab2/openhab.log <==

2019-09-28 20:59:28.965 [INFO ] [del.script.temperature-control.rules] - [AUTO] Next change @2019-09-28T10:00:00.000+02:00 | Changes : HVAC_LR_Target_Temp=21.5

==> /var/log/openhab2/events.log <==

2019-09-28 20:59:28.988 [vent.ItemStateChangedEvent] - HVAC_Queue changed from  to HVAC_LR_Target_Temp=21.5

==> /var/log/openhab2/openhab.log <==

2019-09-28 20:59:29.048 [INFO ] [del.script.temperature-control.rules] - Target temperature for item HVAC_LR_Target_Temp changed from 14.5 to 21.5

==> /var/log/openhab2/events.log <==

2019-09-28 20:59:29.062 [vent.ItemStateChangedEvent] - HVAC_LR_Target_Temp changed from 14.5 to 21.5

==> /var/log/openhab2/openhab.log <==

2019-09-28 20:59:29.071 [INFO ] [del.script.temperature-control.rules] - Target Temperature Queue cleaned up

==> /var/log/openhab2/events.log <==

2019-09-28 20:59:29.076 [vent.ItemStateChangedEvent] - HVAC_Queue changed from HVAC_LR_Target_Temp=21.5 to 

2019-09-28 20:59:38.496 [vent.ItemStateChangedEvent] - HVAC_Mode changed from AUTO to MANUAL

2019-09-28 20:59:38.507 [ome.event.ItemCommandEvent] - Item 'HVAC_Mode' received command MANUAL

2019-09-28 20:59:38.522 [vent.ItemStateChangedEvent] - HVAC_LR_Target_Temp changed from 21.5 to 14.5

2019-09-28 20:59:38.531 [nt.ItemStatePredictedEvent] - HVAC_Mode predicted to become MANUAL

I have combine the “HVAC_Mode” withe the mode channel of the binding. This is the reason why the mode change in the widget.
But i have still the same problem.

log:

2019-09-28 22:28:00.320 [INFO ] [del.script.temperature-control.rules] - [AUTO] Next change @2019-09-28T10:00:00.000+02:00 | Changes : HVAC_LR_Target_Temp=21.5

==> /var/log/openhab2/events.log <==

2019-09-28 22:28:00.340 [vent.ItemStateChangedEvent] - HVAC_Queue changed from  to HVAC_LR_Target_Temp=21.5

==> /var/log/openhab2/openhab.log <==

2019-09-28 22:28:00.372 [INFO ] [del.script.temperature-control.rules] - Target temperature for item HVAC_LR_Target_Temp changed from 11.0 to 21.5

2019-09-28 22:28:00.386 [vent.ItemStateChangedEvent] - HVAC_LR_Target_Temp changed from 11.0 to 21.5

2019-09-28 22:28:00.390 [INFO ] [del.script.temperature-control.rules] - Target Temperature Queue cleaned up

2019-09-28 22:28:00.400 [vent.ItemStateChangedEvent] - HVAC_Queue changed from HVAC_LR_Target_Temp=21.5 to 

2019-09-28 22:28:09.482 [vent.ItemStateChangedEvent] - HVAC_LR_Target_Temp changed from 21.5 to 11.0

I dont understand why i have the last log entry. From where i get a changed of the set temperature?

I Had the same problem with the Code. I Changes the Line from Update to sendcommand.
Now it works.

Hi neputo,

Great work, thank you very much for the scheduler. It’s very usefull and i integrated it into the matrix-theme for my habpanels.
There is a little problem i cant solve. I set the step value to 0.5°C. When I load the page and the room has a temperature of e.g. 21.7 °C then 21.7 is shown in the middle of the knob. Whenever there is a change to the value, e.g. from 21.7 to 21.8 the knob is rounding up (or down) to 22.0 (which is the normal behaviour of the knob when step is 0.5). I guess it has something to do with the vm._updateKnobValue() and a different approach when initialising all the values. I would prefer to have the exact value in first place even after a value change, but I am not very familiar with javascript. Maybe you or someone could have a look at that?!?

Thanks
Jamoth

hi, can you please explain this to me as i am new, i have done all the steps but i was not sure what to do or where to put the image files??! i am trying to control my light with habpanel with diffrent time and day using virtual widget, the github instructions not clear enough to me. my widget is available but no image

Hi ,
I am quite new to openHAB.
I will begin to migrate my proprietary heating control system to this platform in the next months.

Up to now, my existing platform was working with a proprietary controller designed by a Belgian company supplying mainly solar thermic solutions but also heating system for houses.
In my scheduling interface, I used to have 3 temperature target ( normal/confort1/ confort2)


Color code is here grey for normal, blue for confort 1, orange for confort 2

@nepotu,
Do you think it would be easy to modify your widget to allow a second confort temperature?

I plan to integrate your widget in my config anyway
Feel free to comment

Pierre

Continuing the discussion from HABPanel widget: Virtual Thermostat/OnOff Appliance scheduling:

Hi I have the same problem. I see only blank widget in my openhab and this is the output from the console.


Did you manage to fix it?

I fixed it, It was problem with folder permissions

Hey, thanks for the great work on this. so far I have everything installed and mostly working. I’m a bit unclear as to what is meant by this

" Please note that the lines 11,13 and 15 end with “{}”. There you should put your binding config for the temperature items. If no such binding available, and you want to set the item value manually (e.g. from rules for testing purposes) then you should remove those curly braces."

my OHScheduler.items has errors of course. just to be sure, I have my thermo items set in my binding config in it’s own .items file. can I just delete these items, are they just test demo items?

Number HVAC_LR_Temp “Livingroom Temp [%.0f °C]” (grpTemp) [“LRTemp”]
Number HVAC_LR_Target_Temp “Livingroom Target Temp [%.0f °C]” (grpTemp,grpTargetTemp) [“LRTargetTemp”]
Number HVAC_MB_Temp “Master Bedroom Temp [%.0f °C]” (grpTemp) [“MBTemp”]
Number HVAC_MB_Target_Temp “Master Bedroom Target Temp [%.0f °C]” (grpTemp,grpTargetTemp) [“MBTargetTemp”]
Number HVAC_KB_Temp “Kid’s Bedroom Temp [%.0f °C]” (grpTemp) [“KBTemp”]
Number HVAC_KB_Target_Temp “Kid’s Bedroom Target Temp [%.0f °C]” (grpTemp,grpTargetTemp) [“KBTargetTemp”]

thanks much++

Never mind, I figured it out. need to set the channel to my binding item on the default items. added. {heatmiser=“1:ROOMTEMP”} & {heatmiser=“1:SETTEMP”} to the respective items.

I’ll also note I needed to change OHSCedular.rules:

targetItem.postUpdate(DecimalType.valueOf(itemsTempArray.get(j.intValue()).split(‘=’).get(1)))
to targetItem.sendCommand(DecimalType.valueOf(itemsTempArray.get(j.intValue()).split(‘=’).get(1)))

in order to get the widget to update the item, otherwise it was just changing in the display, not actually updating the settings on the thermostat.

all works perfectly now++

Thanks first of all to nepotu for such a great job. Thank to guiott for his work too.
I write this to warn who is using ONOff rules. You have to add grpOnOff to the item you want to schedule. This is not clearly written in the instructions (or I didn’t notice it).
Another thing that people may spend time on is try to delete schedules on ipad/iphone, this is not possible. If anybody solved it, please share it. Thank you.
Andrea

1 Like

Yes, Ive not been able to delete schedules using Apple devices :frowning:

@butteryak
@Andrea_Viscovich
@dastrix80

Hi guys, anyone got the on off schedule to work properly? I have errors on latest openhab despite that the scheduler sets the time for on or off but doesn’t trigger the item at time of execution.

If it is working for you can you please share your files,

many thanks

Sorry I dont use the latest openhab, I use 2.4.0

@Nickthegr8
Yes, I use Openhab 2.5.5-1 and it works properly.
Be sure you add grpOnOff to the item you want to schedule.
I don’t know what files you want me to share.
In your Items.conf file you have to put a line like:
Switch Irrigazione_1 “Irrigazione principale” (grpOnOff) { channel=“xxxxx” }
Then it will trigger.
Andrea

I used a copy from guiott above which works fine and retranslated the italian to english and now it works fine. Thank you both for your feedback, i don’t have a channel binding to the item and with guiott version it works fine

Hi, i really like the idea of this widget, nice work.
i implemented it in my environment and initially it looked good, however as soon as i add a schedule for a second item only the first one gets triggered.

im running openhab 2.5.6-2 with the latest widget version and the sample rules and items. just added one more item, a light, for real testing.

i noticed the below entries in the log where the second one seems to be strange, its indicating the next change only based on the first item.

   2020-07-08 07:38:31.606 [vent.ItemStateChangedEvent] - OnOff_Schedule changed from {"OnOff_SP_Coffee":{"D2":{"T2250":10}},"S_DR_LIGHT_DiningTable1_S":{"D2":{},"D3":{"T0735":10}}} to {"OnOff_SP_Coffee":{"D2":{"T2250":10}},"S_DR_LIGHT_DiningTable1_S":{"D2":{},"D3":{"T0745":10}}}

   2020-07-08 07:38:32.088 [INFO ] [ome.model.script.onoff-control.rules] - [OnOff-Schedule] [SLEEPING] Next change @2020-07-14T22:50:00.000+02:00

i also noticed this errors showing in Visual Studio Code.

thanks in advance for any advice
Matt

This is a great widget that I have been using for a couple years to manage my multi-zone home heating needs. I have mostly baseboard electric heat and thermostats in every room. I am slowly switching them out to smart zwave thermostats (StelPro & Go Control).

Still on my to-do list is to modify the widget/rules to accommodate groupings of thermostats and related “Away” schedules (maybe someday).

Anyway, over the holiday period I jumped in and upgraded to OH3. I haven’t really been a developer in a number of years, so it was what I like to call an “educational experience”. It took me more than a few minutes to update scheduling rules to function again after the upgrade. The shift from Joda Time to the Java Time API being the main culprit.

I thought I would post my updated rules in case it would helpful to anyone else doing the upgrade.


// --- By Geo Magadan | nepotu.ro --- //
// ---        version 1.2        --- //
//HVAC Scheduler - Target Temperature Management Rules
import java.util.concurrent.locks.ReentrantLock

//Global variables
var ReentrantLock tempCtlLock = new ReentrantLock()
var ReentrantLock tempQueueLock = new ReentrantLock()
var Timer tempCtlTimer = null

// HVAC Scheduler - Target Temperature Management
rule "HVAC Scheduler - Target Temperature Management"
when
    Time   cron "0 0/1 * * * ?"           or
    Item   HVAC_Mode received update      or
    Item   HVAC_Mode received command     or
    Item   HVAC_Schedule received update  or
    Item   HVAC_Schedule received command
then
    if (tempCtlLock.tryLock()) {
        try {
            //tempCtlLock.lock()
            if (HVAC_Mode.state == 'AUTO' || HVAC_Mode.state == 'COOL' || HVAC_Mode.state == 'HEAT') {
                val timeNow = now()
                val String runningMode = (HVAC_Mode.state as StringType).toString
                var String triggeredBy = null
                try {
                    triggeredBy = triggeringItem.name
                } catch(Exception e) {
                    triggeredBy = receivedCommand
                }
// 	logInfo("OHSchedulerHVAC Target MGMT", "1-Cancel Timer  CMD: " + receivedCommand)
				// Cancel the timer if the command was received on HVAC_Mode or HVAC_Schedule change
                if (tempCtlTimer !== null && triggeredBy !== null) {
//	logInfo("OHSchedulerHVAC Target MGMT", "2-Cancel Timer " + triggeredBy)
                    tempCtlTimer.cancel()
                    tempCtlTimer = null
                }
                if (tempCtlTimer === null || tempCtlTimer.hasTerminated) {
//	logInfo("OHSchedulerHVAC Target MGMT", "3-Timer Expired " + timeNow)
				var String currentTime = null
                    var String temperatureQueue = null
					var ZonedDateTime upToTime = null
                    if (timeNow.getHour() < 10) {
                        currentTime = 'T0' + timeNow.getHour() + timeNow.getMinute
                    } else {
                        currentTime = 'T' + timeNow.getHour() + timeNow.getMinute
                    }
                    if (HVAC_Schedule.state != NULL) {
                        grpTargetTemp.members.forEach [ targetItem | {
                                var String jsonHVACSchedule = (HVAC_Schedule.state as StringType).toString
                                var String jsonItemSchedule = null
                                var String jsonItemDaySchedule = null
                                // Parse the item schedule
                                if (jsonHVACSchedule.contains('"' + targetItem.name.toString + '"')) {
                                    jsonItemSchedule = transform('JSONPATH', '$.' + targetItem.name, jsonHVACSchedule)
                                    // Replace the equal with colon
                                    jsonItemSchedule = jsonItemSchedule.replaceAll('=', ':')
                                    if (jsonItemSchedule !== null && jsonItemSchedule != '') {
                                        var Number i = 0
                                        var String nextDay = null
                                        var String prevDay = null
                                        var String nextTime = null
                                        var String prevTime = null
                                        var Number nextVal = null
                                        var Number prevVal = null
                                        var String nextTimeVal = null
                                        var String[] nextTimeValArray = null
                                        var String[] jsonItemDayScheduleArray = null
                                        // Loop: week days
                                        while ((i=i+1) <= 7) {
                                            // Parse the (item) daily schedule
                                            var Number j = -1
                                            if (jsonItemSchedule.contains('D' + i)) {
                                                jsonItemDaySchedule = transform('JSONPATH', '$.D'+i, jsonItemSchedule)
                                                // Remove empty objects
                                                jsonItemDaySchedule = jsonItemDaySchedule.replaceAll('[{}]', '')
                                                if (jsonItemDaySchedule !== null && jsonItemDaySchedule != '') {
                                                    jsonItemDayScheduleArray = jsonItemDaySchedule.split(',')
                                                    // Loop: each day schedule
                                                    while ((j=j+1) < jsonItemDayScheduleArray.length) {
                                                        nextDay = 'D' + i
                                                        nextTimeVal = jsonItemDayScheduleArray.get(j.intValue()).replaceAll(' ', '')
                                                        nextTimeValArray = nextTimeVal.split('=')
                                                        nextTime = nextTimeValArray.get(0)
                                                        nextVal = DecimalType.valueOf(nextTimeValArray.get(1))
                                                        if (prevDay !== null && ('D' + i + nextTime) > ('D' + timeNow.getDayOfWeek.getValue() + currentTime)) {
                                                            // Force exit from both i and j while loops
                                                            j = jsonItemDayScheduleArray.length
                                                            i = 8
                                                        } else if (('D' + i + nextTime) <= ('D' + timeNow.getDayOfWeek + currentTime)) {
                                                            prevDay = 'D' + i
                                                            prevTime = nextTime
                                                            prevVal = nextVal
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                        // If no previous value found so far, then use the last available
                                        if (prevDay === null && nextTime !== null && nextVal !== null) {
                                            prevDay = nextDay
                                            prevTime = nextTime
                                            prevVal = nextVal
                                        }
                                        // Validate next. If no other future values, then use the first one available as next
                                        if (prevDay == nextDay && prevTime == nextTime && prevVal == nextVal) {
                                            i = 0
                                            while ((i=i+1) <= 7) {
                                                if (jsonItemSchedule.contains('D' + i)) {
                                                    jsonItemDaySchedule = transform('JSONPATH', '$.D'+i, jsonItemSchedule)
                                                    // Remove empty objects
                                                    jsonItemDaySchedule = jsonItemDaySchedule.replaceAll('[{}]', '')
                                                    if (jsonItemDaySchedule !== null && jsonItemDaySchedule != '') {
                                                        nextDay = 'D' + i
                                                        jsonItemDayScheduleArray = jsonItemDaySchedule.split(',')
                                                        nextTimeVal = jsonItemDayScheduleArray.get(0)
                                                        nextTimeValArray = nextTimeVal.split('=')
                                                        nextTime = nextTimeValArray.get(0).replaceAll(' ', '')
                                                        nextVal = DecimalType.valueOf(nextTimeValArray.get(1))
                                                        i = 8
                                                    }
                                                }
                                            }
                                        }
                                        // Process the schedule values
                                        if (nextDay !== null && nextTime !== null && nextVal !== null) {
                                            // The changeTime is computed from the Dx-Txxxx pair and marks the next schedule change
                                            var Number upToNext = null
											var ZonedDateTime changeTime = null
											val DayOfWeek dayOfWeek = timeNow.getDayOfWeek()
											val dayOfWeekInt = dayOfWeek.getValue()
					
                                            if (dayOfWeekInt <= Integer.valueOf(nextDay.substring(1,2))) {
                                                upToNext = Integer.valueOf(nextDay.substring(1,2)) - dayOfWeekInt
                                            } else {
                                                upToNext = 7 - dayOfWeekInt + Integer.valueOf(nextDay.substring(1,2))
                                            }
                                            // upToNext = minutes since midnight until the next schedule change
											upToNext = upToNext*24*60 + Integer.valueOf(nextTime.substring(1,3))*60 + Integer.valueOf(nextTime.substring(3,5))
                                            //changeTime = timeNow.withTimeAtStartOfDay().plusMinutes(upToNext.intValue())
											changeTime = timeNow.with(LocalTime.of(0, 0, 0, 0)).plusMinutes(upToNext.intValue)
                                            if (upToTime === null) {
                                                // Init the queue
                                                upToTime = changeTime
                                                temperatureQueue = targetItem.name + '=' + nextVal
                                            } else {
											
											
                                                if (upToTime > changeTime) {
                                                    // Reset the queue
                                                    upToTime = changeTime
                                                    temperatureQueue = targetItem.name + '=' + nextVal
                                                } else if (upToTime == changeTime) {
                                                    // Add item to queue
                                                    temperatureQueue = temperatureQueue + ';' + targetItem.name + '=' + nextVal
                                                }
                                            }
                                            // [fail-safe] Init target temperature if not set
                                            if (prevVal !== null && (targetItem.state == NULL || targetItem.state == '')) {
                                                logInfo('temperature-control.rules', 'Target temperature for item ' + targetItem.name + ' initiated to : ' + prevVal)
                                                targetItem.sendCommand(prevVal)
												//targetItem.postUpdate(prevVal)
                                            }
                                        }
                                    }
                                }
                            }
                        ]
                        // Activate the timer
					 	//logInfo('temperature-control.rules.checkUpToTime', '[' + runningMode + '] Next change @' + upToTime)
                        if (upToTime !== null) {
                            HVAC_Next_Change_Time.postUpdate(upToTime.toLocalDateTime().toString())
                            tempCtlTimer = createTimer(upToTime, [|
									HVAC_Queue.postUpdate(temperatureQueue)
                                    tempCtlTimer.cancel()
                                    tempCtlTimer = null
                                ])
                        }
                    }
                }
            } else {
                // Cancel the timer
                if (tempCtlTimer !== null) {
                    tempCtlTimer.cancel()
                    tempCtlTimer = null
                }
            }
        } catch(Exception e) {
            logInfo('temperature-control.rules', 'Temperature control error: ' + e.toString)
        } finally {
            tempCtlLock.unlock()
        }
//logInfo("OHSchedulerHVAC Target Temp MGMT", "4-HVAC_Queue " + HVAC_Queue.state)
	}
end

// HVAC Scheduler - A queue item, used to set the target temperature for multiple items at the same time
rule "HVAC Scheduler - Target Temperature Queue"
when
    Item HVAC_Queue received update  or
    Item HVAC_Queue received command or
    Item HVAC_Queue changed
then
//logInfo("OHSchedulerHVAC Target Temp", "4-HVAC_Queue " + HVAC_Queue.state)
    if (tempQueueLock.tryLock()) {
        try {
            if (HVAC_Queue.state != NULL && HVAC_Queue.state != '') {
                grpTargetTemp.members.forEach [ targetItem | {
                        var Number j = -1
                        var String[] itemsTempArray = null
                        itemsTempArray = (HVAC_Queue.state as StringType).toString.split(';')
                        while ((j=j+1) < itemsTempArray.length) {
                            if (itemsTempArray.get(j.intValue()).split('=').get(0) == targetItem.name) {
                                logInfo('temperature-control.rules', 'Target temperature for item ' + targetItem.name
                                    + ' changed from ' + targetItem.state
                                    + ' to ' + DecimalType.valueOf(itemsTempArray.get(j.intValue()).split('=').get(1)))
                                targetItem.sendCommand(DecimalType.valueOf(itemsTempArray.get(j.intValue()).split('=').get(1)))
					targetItem.postUpdate(DecimalType.valueOf(itemsTempArray.get(j.intValue()).split('=').get(1)))
                            }
                        }
                    }
                ]
                // Cleanup the queue
                HVAC_Queue.postUpdate('')
                logInfo('temperature-control.rules', 'Target Temperature Queue cleaned up')
            }
        } catch(Exception e) {
                logInfo('temperature-control.rules', 'Target Temperature Queue control error: ' + e.toString)
        } finally {
                tempQueueLock.unlock()
        }
    }
end

Hello John,

I am glad the widget and rules were useful.

@ everyone else,
Sorry for not replying, but I wasn’t around for a while.

In the meantime OH3 was launched and it has a great and powerful default UI. Currently I am rebuilding from scratch my environment. Right now I am not sure if this “hack” is still needed in order to create schedules.

Regards,
Geo

1 Like

Da poco approdato su HA con scarse conoscenze di tutto, e da diversi giorni alla ricerca di qualcosa di simile, e guarda caso quello che avevo in mette lo ha fatto un Italiano. grazieeeee

Recently landed on HA with little knowledge of everything, and for several days looking for something similar, and coincidentally what I had in mind was done by an Italian. thankseeee