"Waste reminder" with telegram query

Hello,

at first: Excuse my english :wink:

The idea for this was in the german “openhabforum”. I have build it myself (with “some” code from the “original” - Thank you OP :slight_smile: ) and want to show you how I did it. Im open for ideas or if something “wrong”. Im new to OpenHab but think it could help other.

What does my solution do:
Everyday at 18:00 o’clock a rule is checking, if one of my “Waste item” (filled with the icalendar binding) is having a date of tomorrow. If so, a “question” is sent every hour by telegram whether the garbage cans have been taken out. If this question is not “answerd” the “question” is send every hour again.

How:
At first you need an item for every “waste” you have and link it to the icalender-Filter (In this examples the items with the waste event are beggining with “Abfall…”. For my solution you have to put all the items in one group (“Abfall”).

Now you have to check, if the Waste items are filled with a “date” and set the “state description” to “%1$td.%1$tm.%1$tY”

Okay. Now we are need some “help/variant” items.
(I dont have the textual item definiton - I build it with paper UI)

vAbfall_Aktuell = string. The string will be, if waste for tomorrow is found, the label of the waste-item
vAbfall_Benachrichtigung = A Switch for the notification
vAbfall_BenachrichtigungE = A Switch if the notification have to be send again

Its important to have a diffrent name for the “help/variant” items, because we are looping through the group

Now to the rules.

The first rule is running every day at 18:00 o’clock. The script checks, if the waste is tomorrow.


val tomorrow = now.plusDays(1)

//loop through the group Abfall, but only for the items "Abfall*"
Abfall.members.filter[ i | i.name.substring(0,6) == "Abfall" && i.state != NULL].forEach[ i |

        //Save the date 
        val Wert = (i.state as DateTimeType).zonedDateTime
         
         //check if the waste date tomorrow
        if (Wert.year == tomorrow.year && Wert.month == tomorrow.month && Wert.dayOfMonth == tomorrow.dayOfMonth)
                { 
                 //Save the label of the waste item to "vAbfall_Aktuell" and trigger "ON" to the notification
                  logInfo("Abfall-1", "Morgigen Abfall gefunden. Setze Benachrichtigungen aktiv")
                  vAbfall_Aktuell.sendCommand(i.label)
                  vAbfall_BenachrichtigungE.sendCommand(ON)
                  vAbfall_Benachrichtigung.sendCommand(ON)
                  
                  return
              }
 ]
  
  

The second rule is triggered, when the “vAbfall_Benachrichtigung” item was updatet to “on”:

The script is doing the following:
We will check if the “vAbfall_BenachrichtigungE” is “ON”.
In the “first” run, it will be “ON” because we have done this in the first rule. Then we will send an Telegram query and create an timer for one hour. After one hour we update vAbfall_Benachrichtigung to “ON” again (even though it was still ON). So the same rule is running again.

This means: This rule is running every hour and send a TeleframQuery until the “vAbfall_BenachrichtigungE” is "OFF"


//definition for the telegrambot
val telegramAction = getActions("telegram","telegram:telegramBot:yyyyyyyyy")	

//check if vAbfall_BenachrichtigungE.state is on.
if(vAbfall_BenachrichtigungE.state == ON){
    
    //If ON, we send the telegram query and create a timer for one hour
    logInfo("Abfall-2", "Benachrichtigung noch aktiv - Deshalb schicken wir Nachricht. Erneute prüfung in einer Stunde")

    telegramAction.sendTelegramQuery("Morgen wird " + vAbfall_Aktuell.state +" geleert.\nWurde die Tonne heraus gestellt?", "Abfall", "Ja!")
    
    createTimer(now.plusMinutes(60), [ | 
     // The timer is sending "ON" to  vAbfall_Benachrichtigung. This rule here is running again one hour later.
      vAbfall_Benachrichtigung.sendCommand(ON)
    ])
} else {
    //everthing off
    logInfo("Abfall-3", "Antwort erhalten. Benachrichtigung Abschalten - Kein neuer Timer")
    vAbfall_Benachrichtigung.sendCommand(OFF)
}


In the third rule, we will check if an answer was send from Telegram. If yes, we switch “vAbfall_BenachrichtigungE” to off.

I have changed the “when” to “lastMessageDate”. Because if the last answer is the same, the channel “Reply” was not “updatet”.

The script:

//Check if the Reply = "Abfall" (to be defined in the sendTelegramQuery string).
if(TelegramBot_ReplyId.state == "Abfall"){
     logInfo("Abfall-3", "Antwort erhalten. BenachrichtigungE Abschalten")
    //Send command off
    vAbfall_BenachrichtigungE.sendCommand(OFF)
} 

That’s all! I hope this can help you :wink:

PS: I dont know, if the solution is “good” to trigger the same timer-rule with a timer. But it work :smiley:
PS2: This solution is only working for ONE waste-date (“return” after found one date in script one)

Greetings from Germany
Mike

5 Likes

I don’t see any problem with that.

Next steps, a rule template. :wink:

Thanks for posting!

1 Like

Hey Mike,

This looks awesome.
I was thinking about doing some active messagging for my waste reminder too some days ago,
so this is a good inspiration.
I thought about using pushover first, but the active feedback may be useful.

One idea that would come to my mind, would be to use a cron based rule for the telegram notification and just enable it with th 18:00 check (if needed) and disable it with the telegram message answer.

Or just enable/disable the actual rule itself.

1 Like

i think that is a great idea.
do I have to build the 3 rules into one?

No, though that would make it easier to post and for the end users to use it. For now each rule would need its own thread on the marketplace. But that’s not unusual, look at the MQTT Event Bud and the Scene Control Suite templates for example. Someday we should be able to post more than one rule per post but not today.

Also have a look at the Alarm Clock Rule. One thing that can make the template flexible is to have your template call another rule written by the user. In that case the user writes a rule that does what the user wants to happen at the given date time in the Item. The Alarm Clock template handles the timer and calling that user written rule. In your case, let the user write a Rule to do the Telegram alert or eMail or what ever they prefer. Then your rule can just focus on handling the timers and timing and parsing the iCalendar entries and such.

Unfortunately I don’t know if it’s possible to call another rule using Rules DSL. So you’d potentially need to move that rule to using Blockly or JS Scripting.

thank you. i will have a look.

Hello!

After updating to openhab4 I get this error:

Script execution of rule with UID ‘smieci-1’ failed: Could not cast UNDEF to org.openhab.core.library.types.DateTimeType; line 7, column 21, length 23 in smieci

val tomorrow = now.plusDays(1)
Smieci.members.filter[ i | i.name.substring(0,6) == “Smieci” && i.state != NULL].forEach[ i |
val Wert = (i.state as DateTimeType).zonedDateTime
if (Wert.year == tomorrow.year && Wert.month == tomorrow.month && Wert.dayOfMonth == tomorrow.dayOfMonth)
logInfo(“Waste-1”, “Znaleziono jutrzejsze odpady. Włącz powiadomienia”)
{ Wywoz.sendCommand(i.label)
Powiadomienie1.sendCommand(ON)
Thread::sleep(1000);
Powiadomienie.sendCommand(ON)
return } ]

Regards!

Based on the error I would say that the rule doesn’t check for nor expect to work with DateTime Items that are NULL. Make sure all the relevant Items have a valid DateTime state.

1 Data Time was missing. Errors “failed: begin 0, end 6, length 5 in smieci”, no tomorrow’s date but the rule turns on notifications?

I don’t know this rule. The previous error was generic enough to identify the problem. This one isn’t.