You can get rid of that by using Functions$Function0<Boolean> in the arguments to the lambda.
Add logging to your rules to verify that they are triggering it not. If not, what ever event the roles the to trigger is not happening or the trigger is not working.
Add logging to your lambdas to see if they are being executed and where they are failing.
it took some time, but to save others from debugging the same snippet, please find included my working version of these rules, items en widget.
I translated them to English.
At least, the debugging of the snippets learned me a lot about working with lambdaās and groups
Full code is attached, here parts of it:
Group gAlarm (gPersistme)
//Alarm Monday
Switch PERSON1_ALARM_MON "ALARM Monday" <clock> (gAlarm)
Number PERSON1_ALARM_MON_H "Alarm start Monday Hour [%s]" <calendar> (gAlarm)
Number PERSON1_ALARM_MON_M "Alarm start Monday Minutes [%s]" <calendar> (gAlarm)
Number PERSON1_ALARM_MON_RUN "ALARM Monday Duration [%s]" <clock>
<../..>
****************************
import org.eclipse.xtext.xbase.lib.Functions
import java.util.Map
var Map<String, Timer> timers = newHashMap
val Functions$Function4
<String, Map<String, Timer>, Functions$Function0<Boolean> , Functions$Function0<Boolean> , Boolean>
processAlarm = [person, timers, alarmStart, alarmStop |
var dayTempName="NA"
switch now.getDayOfWeek()
{
case 1: dayTempName = "MON"
case 2: dayTempName = "TUE"
case 3: dayTempName = "WED"
case 4: dayTempName = "THU"
case 5: dayTempName = "FRI"
case 6: dayTempName = "SAT"
case 7: dayTempName = "SUN"
}
val dayName=dayTempName
val myPerson = gAlarm.members.filter[ s | s.name == person+dayName ].head.state
if(myPerson == ON)
{
val startMinutes = (gAlarm.members.filter[ s | s.name == person+dayName+"_M" ].head.state as Number).intValue
val startHour = (gAlarm.members.filter[ s | s.name == person+dayName+"_H" ].head.state as Number).intValue
val runTime = (gAlarm.members.filter[ s | s.name == person+dayName+"_RUN" ].head.state as Number).intValue
if(startMinutes == now.getMinuteOfHour && startHour == now.getHourOfDay)
{
sendCommand(person+"ACTIVE", "ON")
// alarmStart is a passed in lambda that implements the stuff to do for that person's alarm
alarmStart.apply()
timers.put(person, createTimer(now.plusMinutes(runTime), [|
// alarmStop is a passed in lambda that implements the stuff to do at the end of that person's alarm
alarmStop.apply()
sendCommand(person+"ACTIVE", "OFF")
timers.put(person, null)
]))
}
}
true
]
//===================================================================================
rule "Alarms"
when
Time cron "0 0/1 * * * ?"
then
val Functions$Function0 <Boolean> person1Start = [|
logInfo("Alarms", "alarm start code")// alarm start code
true
]
val Functions$Function0 <Boolean> person1Stop = [|
logInfo("Alarms", "alarm stop code")// alarm stop code
true
]
// define functions for each person, if there is nothing to do for that person you can use [| true]
// as illustrated with person2 below.
processAlarm.apply("PERSON1_ALARM_", timers, person1Start, person1Stop)
// processAlarm.apply("Ellen", timers, [| true], [| true]) // PERSON2 has nothing to do when the alarm starts and ends so we pass empty lambdas
end
rule "init"
when
System started
then
logInfo("init alarm", "Initialise alarm items if needed")
gAlarm.members.filter[ i | i.type.toString == "Switch" ].forEach[ s |
if (s.state.toString == "NULL")
{
s.postUpdate(OFF)
}
]
gAlarm.members.filter[ i | i.type.toString == "Number" ].forEach[ s |
if (s.state.toString == "NULL")
{
s.postUpdate(0)
}
]
end
This has been really useful - I have it as my alarm clock now
I have conacated the H/M variables to a time variable to display in the basic UI
However what I havenāt managed to do is to pass that time and date to another item that displays tomorrowās alarm time
eg - using above variables
if i=(now.getDayOfWeek) Person1_Alarm_Tomorrow=("Person1_Alarm"+TheDay+"_T")
Where Person1_Alarm_Tomorrow is the display item and _T is the time string used to display the label on the frame
What I want is a simple item to display tomorrows alarm time on a habpanel
Maybe Iām making too complicated using rules based approach
Trigger a rule once a day and on any change to any one of the alarm Items. Midnight is probably a good choice.
Get the current day. val today = now.getDayOfWeek
Get tomorrow. val tomorrow = (today + 1) % 7
Convert the number for tomorrow to the characters representation. I recommend using a .map file and the transform Action. val tomorrowStr = transform("MAP", "alarm.map", tomorrow.toString)
Now we can pull the parts of the alarm out from the gPerson1Wecker Group by name.
Rule āupdate Tommorows Alarmā: An error occurred during the script execution: Could not invoke method: org.eclipse.xtext.xbase.lib.IterableExtensions.findFirst(java.lang.Iterable,org.eclipse.xtext.xbase.lib.Functions$Function1) on instance: null
is what I get with
rule "update Tommorows Alarm"
when
Member of gPerson1Alarm changed
then
val today = now.getDayOfWeek
val tomorrow = (today + 1) % 7
val tomorrowStr = transform("MAP", "alarm.map", tomorrow.toString)
Person1_Alarm_Tomorrow.postUpdate(gPerson1Alarm.members.findFirst("Person1_Alarm_"+tomorrowStr+"_T"))
end
Yup thatās works - Thank you
Iāve also taken Person1_Alarm_Tomorrow out of the group gPerson1Alarmā¦hadnāt considered that changing the former would trigger the rule also!
Oddly I copied and pasted and it didnāt work as the quotation marks " were wrong - but sorted that
Is there a way to implement a limit in the widget so it doesnāt go below 0 or above 59 when setting the minutes? By default it is possible to set the alarm to ānegativeā minutes or beyond the end of the hour.
The sitemap version of the interface implements this, I just donāt know how to do this in the HABPanel version.
1 Like
MDAR
(Stuart Hanlon, UK importer of Velbus hardware)
31
Hi
Iāve been looking for something like this for a while.
Thank you so much for your efforts
To give a little back, I have added two rules to limit the hours and minutes.
I created two extra groups
Group gMinute
Group gHour
and assigned them to all the minutes and hour ITEMS like this
Group gAlarm (StartPersist) // Where "StartPersist" is the catch all for Peristance
Group gMinute
Group gHour
//Alarm Monday
Switch PERSON1_ALARM_MON "ALARM Monday" <clock> (gAlarm)
Number PERSON1_ALARM_MON_H "Alarm start Monday Hour [%s]" <calendar> (gAlarm,gHour)
Number PERSON1_ALARM_MON_M "Alarm start Monday Minutes [%s]" <calendar> (gAlarm,gMinute)
Number PERSON1_ALARM_MON_RUN "ALARM Monday Duration [%s]" <clock> (gAlarm)
//Alarm Tuesday
Switch PERSON1_ALARM_TUE "ALARM Tuesday" <clock> (gAlarm)
Number PERSON1_ALARM_TUE_H "Alarm start Tuesday Hour [%s]" <calendar> (gAlarm,gHour)
Number PERSON1_ALARM_TUE_M "Alarm start Tuesday Minutes [%s]" <calendar> (gAlarm,gMinute)
Number PERSON1_ALARM_TUE_RUN "ALARM Tuesday Duration [%s]" <clock> (gAlarm)
//Alarm Wednesday
Switch PERSON1_ALARM_WED "ALARM Wednesday" <clock> (gAlarm)
Number PERSON1_ALARM_WED_H "Alarm start Wednesday Hour [%s]" <calendar> (gAlarm,gHour)
Number PERSON1_ALARM_WED_M "Alarm start Wednesday Minutes [%s]" <calendar> (gAlarm,gMinute)
Number PERSON1_ALARM_WED_RUN "ALARM Wednesday Duration [%s]" <clock> (gAlarm)
//Alarm Thursday
Switch PERSON1_ALARM_THU "ALARM Thursday" <clock> (gAlarm)
Number PERSON1_ALARM_THU_H "Alarm start Thursday Hour [%s]" <calendar> (gAlarm,gHour)
Number PERSON1_ALARM_THU_M "Alarm start Thursday Minutes [%s]" <calendar> (gAlarm,gMinute)
Number PERSON1_ALARM_THU_RUN "ALARM Thursday Duration [%s]" <clock> (gAlarm)
//Alarm Friday
Switch PERSON1_ALARM_FRI "ALARM Friday" <clock> (gAlarm)
Number PERSON1_ALARM_FRI_H "Alarm start Friday Hour [%s]" <calendar> (gAlarm,gHour)
Number PERSON1_ALARM_FRI_M "Alarm start Friday Minutes [%s]" <calendar> (gAlarm,gMinute)
Number PERSON1_ALARM_FRI_RUN "ALARM Friday Duration [%s]" <clock> (gAlarm)
//Alarm Saturday
Switch PERSON1_ALARM_SAT "ALARM Saturday" <clock> (gAlarm)
Number PERSON1_ALARM_SAT_H "Alarm start Saturday Hour [%s]" <calendar> (gAlarm,gHour)
Number PERSON1_ALARM_SAT_M "Alarm start Saturday Minutes [%s]" <calendar> (gAlarm,gMinute)
Number PERSON1_ALARM_SAT_RUN "ALARM Saturday Duration [%s]" <clock> (gAlarm)
//Alarm Sunday
Switch PERSON1_ALARM_SUN "ALARM Sunday" <clock> (gAlarm)
Number PERSON1_ALARM_SUN_H "Alarm start Sunday Hour [%s]" <calendar> (gAlarm,gHour)
Number PERSON1_ALARM_SUN_M "Alarm start Sunday Minutes [%s]" <calendar> (gAlarm,gMinute)
Number PERSON1_ALARM_SUN_RUN "ALARM Sunday Duration [%s]" <clock> (gAlarm)
Switch PERSON1_ALARM_ACTIVE "ALARM PERSON1 Active" (gAlarm)
Number PERSON1_ALARM_PRESETS "ALARM Preset Load" <calendar> (gAlarm)
then just added these two rules
rule "Confine Minute"
when
Member of gMinute changed
then
logInfo("Minute Limiting", "Minute Value of "+triggeringItem.name+" Currently "+triggeringItem.state)
if (triggeringItem.state > 59) {
postUpdate(triggeringItem.name,"0")
}
if (triggeringItem.state < 0) {
postUpdate(triggeringItem.name,"59")
}
end
rule "Confine Hour"
when
Member of gHour changed
then
logInfo("Hour Limiting", "Hour Value of "+triggeringItem.name+" Currently "+triggeringItem.state)
if (triggeringItem.state > 23) {
postUpdate(triggeringItem.name,"0")
}
if (triggeringItem.state < 0) {
postUpdate(triggeringItem.name,"23")
}
end
The only thing I need to work out now is how to change the colours of the Glypths
Update
I couldnāt get 14 of those widgets to fit within the Android Tablet screen in an elegant way, so I had to create a custom layout using SVG files.
Considering that I would compare my artistic skills to that of a feral infant, Iām quite happy with the result.
Since you are using HABPanel, Iām pretty sure someone had created a time picker widget that you could use to set a DateTime I tem and save a lot of these Rules. Then you just need a ride to run one a day to change the date to today.
MDAR
(Stuart Hanlon, UK importer of Velbus hardware)
33
Thanks Rich
Iāve tried the other two timeline schedulers and using this seems to be the nearest I can get to a perfect solution for a particular use case.
You remember we chatted about using Google Calendarā¦ I suggested it and it wasnāt welcomed as well as I had hoped.
MDAR
(Stuart Hanlon, UK importer of Velbus hardware)
34
Hi
Iāve managed to tweak this widget to suit the Velbus alarm times,
it can be downloaded here
http:/ /www. mdar. co. uk /dl/ forum_assets/ Velbus_Alarm.widget.zip ā Removed
It requires the following naming convention, Where āAlarmNameā is the only variable that has to be set in the widget.
MDAR
(Stuart Hanlon, UK importer of Velbus hardware)
35
I was having a problem where the Widgets didnāt size nicely, so Iāve spent the morning adding two size options.
One for the Font & Glyphs, another for the IconSets
rule "update Tommorows Alarm"
when
Member of gPerson1Alarm changed or
Time is noon
then
val today = now.getDayOfWeek
val tomorrow = (today + 1) % 7
val tomorrowStr = transform("MAP", "alarm.map", tomorrow.toString)
Person1_Alarm_Tomorrow.postUpdate(gPerson1Alarm.members.findFirst[ a | a. name == "Person1_Alarm_"+tomorrowStr+"_T"].state)
end
I now have a problem where by it is returning 0 for tomorrow and therefore not mapping correctly - returns an error as cant mapto 0