Hi there,
I have made some progress. I now have a lambda and a rule to calculate the average of the dates. I have modified a bit how I want to get the average of the dates:
- If today is a week day, calculate the average of the occurence of the item from the past 5 week days
- If today is during the weekend, calculate the average of the occurence of the item from the
last weekend
The lambda is shown below with some notes:
// Lambda function to get the first time a given item was triggered starting FROM a specific date
var historic = [
GenericItem item_to_look, //self explained
GenericItem minus_days, //number of days since today from when to look
GenericItem days, //stopping day
GenericItem start_hour | //start to look from this specified hour
val start_min = 0 //start to look from this specified minutes
val incr_min = 5 // increment
//The current lambda will do the following
//- start to look from minus_day at the specified start_hour and specified start_min (for instance from 5 days ago at 18h00). This will be the first value assigned to date_to_look_JDT
//- Return the start date (first value of date_to_look_JDT) if the state of item_to_look is null (in case item_to_look is not yet persisted, for instance)
//- compare the state of item_to_look at the speficied date (date_to_look_JDT) to the desired state (0 in this case)
//- if the state of item_to_look is not the desired one, increment date_to_look_JDT with the value incr_min
//- if the state of item_to_look is not the desired one and date_to_look_JDT is now the stopping date (fin_boucle_JDT), date_to_look_JDT is set to fin_boucle_JDT and retu$
//- if the state of item_to_look is the desired one, return date_to_look_JDT
val date_to_look_JDT = new DateTime(now.minusDays(minus_days).withTimeAtStartOfDay().plusHours(start_hour).plusMinutes(start_min)) //Initialization
val fin_boucle_JDT = new DateTime(now.minusDays(days).withTimeAtStartOfDay())
while(date_to_look_JDT <= fin_boucle_JDT && item_to_look.historicState(date_to_look_JDT,"influxdb").getState <= 0)
{
date_to_look_JDT = date_to_look_JDT.plusMinutes(incr_min)
start_min = start_min + incr_min
}
logInfo("erru","date_to_look_JDT: " + date_to_look_JDT)
date_to_look_JDT
]
The rule using the above lambda is shown below. I am using an array to store the values of
date_to_look_JDT
converted to minutes of day. This allows one to compute the average for an arbitrary amount of dates.
rule "presence"
when
Item Dummy received command
then
val start_hour = 20
val minus_days = 0
val minus = 7
val i = 1
val inrc_ctrl = 0
val infoarray = newArrayList() //Array where will be the storage of the numbers of minutes of day from the lambda return for each call of the said lambda
var Number day_of_week = now.getDayOfWeek
if(day_of_week < 6) //if now is during week days
{
while(minus_days < 7) //go through the last 7 days
{
if(day_of_week-i < 1) minus_days = i + 2 //allows to skip days of weekend
else minus_days = i
i = i + 1
infoarray.add(historic.apply(avg_MqttMuwaveSensorLampeSalon,minus_days,minus_days-1,start_hour).getMinuteOfDay())
//Convert date_to_look_JDT from the lambda to the equivalent number of minutes from that date
//populate infoarray with the converted number minutes of day from date_to_look_JDT
}
}
else //if now is during the weekend. Go through Saturday and Sunday from the week before
{
if(day_of_week == 6) inrc_ctrl = 0
else inrc_ctrl = 1
while(minus_days < (7 + inrc_ctrl))
{
minus_days = i + 5 + inrc_ctrl
i = i + 1
infoarray.add(historic.apply(avg_MqttMuwaveSensorLampeSalon,minus_days,minus_days-1,start_hour).getMinuteOfDay())
}
}
//The part below will calculate the average from minutes of day gathered from the above part of the rule
val buff = -1
val avg = 0
val it = infoarray.listIterator()
while(it.hasNext())
{
buff = it.next()
avg = avg + buff
}
avg = avg/infoarray.size()
// logInfo("erru","Average " + avg)
//Add the determined average to today
val estimated_JDT = new DateTime(now.withTimeAtStartOfDay().plusMinutes(avg))
logInfo("erru","Estimated time of event " + estimated_JDT)
end
The log showing the results is given below:
2018-10-31 20:38:44.319 [INFO ] [.eclipse.smarthome.model.script.erru] - date_to_look_JDT: 2018-10-30T21:10:00.000+01:00
2018-10-31 20:38:44.368 [INFO ] [.eclipse.smarthome.model.script.erru] - date_to_look_JDT: 2018-10-29T20:05:00.000+01:00
2018-10-31 20:38:44.506 [INFO ] [.eclipse.smarthome.model.script.erru] - date_to_look_JDT: 2018-10-26T20:40:00.000+02:00
2018-10-31 20:38:44.532 [INFO ] [.eclipse.smarthome.model.script.erru] - date_to_look_JDT: 2018-10-25T20:00:00.000+02:00
2018-10-31 20:38:44.586 [INFO ] [.eclipse.smarthome.model.script.erru] - date_to_look_JDT: 2018-10-24T20:10:00.000+02:00
2018-10-31 20:38:44.601 [INFO ] [.eclipse.smarthome.model.script.erru] - Estimated time of event 2018-10-31T20:25:00.000+01:00
It works! But it is still missing some generalization.
Ludovic
EDIT: modfied the lambda to take into consideration the case when the item is not yet persisted