Compare datetime item with today

This is only going to do anything when today BirthdayDate0 is today. If only BirthdayDate1 or BirthdayDate2 are today, nothing happens. If you want it to log if it’s anyone’s birthday put those two lines after the }.

If all three share the same birthday, this rule is way overly complex. Just check the one date and have a hard coded message for everyone.

If the number of kids is going to change over time and/or birthday dates change, this rule won’t work as written and it’s going to be a huge pain to maintain.

Put all the BirthdayDate Items into a Group Birthdays and all the Result Items into a Group called Kalender_Filter_Geburtstag_Results. Then loop through the Group members (note below is easier to implement in Blockly or JS Scripting)

import org.openhab.model.script.ScriptServiceUtil

rule "Filter Birthday Entry"
when
    Time cron "5 0 0 * * ?" or // Run the rule daily at midnight
    Item vSwitch1 changed
then
    // Get all the birthdays that are today
    val todayBirthdays = Birthdays.members.filter[ bd | (bd.state as DateTimeType).getZonedDateTime.toLocalDate == now.toLocalDate]
    // exit if there are no birthdays today
    if(todayBirthdays.size == 0) {
        return;
    }
    // Get the names of all of today's birthdays
    val names = todayBirthdays.map[ bd | Kalender_Filter_Geburtstag_Results.members.findFirst[ item | "Kalender_Filter_Geburtstag_Result_"+bd.name.replace("BirthdayDate", "")+"_Begin" ].state.toString.replace("Geburtstag", "") ]
                              .reduce[ list, name | list + ", " + name]
    val message = "Today is " + names + "'s birthday"
    //Alexa_EchoDot_TTS.sendCommand(message)   
    logInfo("rule birthdayfilter", "message: " + message)
end

The first line filters all the BirthdayDate Items down to only those that are toady.

The second clause immediately exits if there are no birthdays today.

The third line uses a map loops through all of today’s birthdays, extracts the number part of the Item name, then finds the Kalender_Filter_Geburstag_Result Item with the same number in the name, and gets the state, replacing the Geburstag with an empty string, presumably leaving just the name. the result of the map is an array of just the names of the children.

Then we use a reduce on the result of the map to convert the list to a single comma separated String, e.g. "kid1, kid2, kid3".

Finally we create the message and send it.

With this approach, it works with any number of birthdays and it only does something when there is a birthday today.

Note, I just typed in the above, there might be typos. See Design Pattern: Working with Groups in Rules for details on filter, findFirst, map and reduce.