OpenSprinkler Telegram rules

Hi,

In the last past weeks i’ve build a irrigation system and it soon became clear that i have to use my home automation system… so thanks for the OpenSprinkler binding… and here are my things, items and rules

The OSPI system runs great, but sometimes our family members and me want to start a short manual irrigation cycle. With the following telegram rules, i dont have to grant them access to the OSPI interface… they can easily start and stop the cycles via our telegram group chat…

2020-08-17 07_50_18-Window|506x164, 2020-08-17 07_54_52-Window 2020-08-17 07_55_10-Window

opensprinkler.things

Bridge opensprinkler:http:http "OpenSprinkler HTTP Interface" @ "OSPI" [hostname="127.0.0.1", port=8080, password="PASSWORD", refresh=20] {
    Thing station 01 "OpenSprinkler Station 01" @ "OSPI" [stationIndex=0]
    Thing station 02 "OpenSprinkler Station 02" @ "OSPI" [stationIndex=1]
    Thing device device "OpenSprinkler Rain Sensor" @ "OSPI" 
}

opensprinkler.items

Group:Switch:AND(ON,OFF) gOSPI_Station
Group:Switch:AND(ON,OFF) gOSPI_Station_Queued

Switch    OpenSprinklerDeviceRainsensor    "Rain Sensor"    {channel="opensprinkler:device:http:device:rainsensor"}

Switch         OpenSprinklerStation01StationState          "Station 1"              (gOSPI_Station)           {channel="opensprinkler:station:http:01:stationState"}
Switch         OpenSprinklerStation01Queued                "S1 in Warteschlange"    (gOSPI_Station_Queued)    {channel="opensprinkler:station:http:01:queued"}
Number:Time    OpenSprinklerStation01RemainingWaterTime    "restliche Laufzeit"                               {channel="opensprinkler:station:http:01:remainingWaterTime"}
Number:Time    OpenSprinklerStation01NextDuration          "S1 nächste Laufzeit"                              {channel="opensprinkler:station:http:01:nextDuration"}

Switch         OpenSprinklerStation02StationState          "Station 2"              (gOSPI_Station)           {channel="opensprinkler:station:http:02:stationState"}
Switch         OpenSprinklerStation02Queued                "S2 in Warteschlange"    (gOSPI_Station_Queued)    {channel="opensprinkler:station:http:02:queued"}
Number:Time    OpenSprinklerStation02RemainingWaterTime    "restliche Laufzeit"                               {channel="opensprinkler:station:http:02:remainingWaterTime"}
Number:Time    OpenSprinklerStation02NextDuration          "S2 nächste Laufzeit"                              {channel="opensprinkler:station:http:02:nextDuration"}

opensprinkler.rules

val OSPI_ReplyId = "OSPI_Reply"
var StationDuration = 600 // 10min
val Station01 = "Rasen oben"
val Station02 = "Rasen Hang"
val StationOFF = "Alle aus"

rule "Telegram Bot receive rasen"
when
    Item TelegramBotLastMessageDate received update
then
    val telegramAction = getActions("telegram","telegram:telegramBot:bot1")

    if (TelegramBotLastMessageText.state.toString.toLowerCase == "/rasen") {
       telegramAction.sendTelegramQuery(Long::parseLong(TelegramBotChatId.state.toString), "*Beregnungs-Optionen:*\nWelcher Bereich soll bewässert werden?", OSPI_ReplyId, Station01, Station02, StationOFF)
    }
end

rule "Telegram Bot receive rasen answer"
when
    Item TelegramBotReplyId received update OSPI_Reply
then
    val telegramAction = getActions("telegram","telegram:telegramBot:bot1")

    if (TelegramBotLastMessageText.state.toString == Station01) {
        var reply = "Bewässerung für *" + Station01 + "* wurde gestartet.\nLaufzeit *" + StationDuration / 60 + "* Minuten."

        OpenSprinklerStation01NextDuration.sendCommand(StationDuration)
        OpenSprinklerStation01StationState.sendCommand(ON)
        telegramAction.sendTelegramAnswer(Long::parseLong(TelegramBotChatId.state.toString), TelegramBotReplyId.state.toString, reply)

    } else if (TelegramBotLastMessageText.state.toString == Station02) {
        var reply = "Bewässerung für *" + Station02 + "* wurde gestartet.\nLaufzeit *" + StationDuration / 60 + "* Minuten."

        OpenSprinklerStation02NextDuration.sendCommand(StationDuration)
        OpenSprinklerStation02StationState.sendCommand(ON)
        telegramAction.sendTelegramAnswer(Long::parseLong(TelegramBotChatId.state.toString), TelegramBotReplyId.state.toString, reply)

    } else if (TelegramBotLastMessageText.state.toString == StationOFF) {
        var reply = "Bewässerung für alle Stationen ausgeschaltet."

        gOSPI_Station.members.filter[i|i.state == ON].forEach[i| { i.sendCommand(OFF)}]
        // we also need to cancel the queued stations
        gOSPI_Station_Queued.members.filter[i|i.state == ON].forEach[i| { i.sendCommand(OFF)}]
        telegramAction.sendTelegramAnswer(Long::parseLong(TelegramBotChatId.state.toString), TelegramBotReplyId.state.toString, reply)

    } else {
        telegramAction.sendTelegramAnswer(Long::parseLong(TelegramBotChatId.state.toString), TelegramBotReplyId.state.toString, "ungültige Angabe!")
    }

    if (TelegramBotReplyId.state.toString == OSPI_ReplyId) {
        // make sure the next request can see an update for "TelegramBotReplyId"
        TelegramBotReplyId.postUpdate(NULL)
    }
end

In the future will play a bit with the group items and labels… so maybe i can shorten the rules a bit and dont have to hardcode the station names… but for now its working as expected… and i’m quite happy with it…

If you have any questions or suggestions, please let me know :slight_smile:

Have fun…

Cheers
/Holger

10 Likes

so i found the time to rework these rules a bit and to make them more dynamic… so for each of your station, the button in the telegram chat is generated through the group items…

  • the rules are using group based items
  • buttons are created from those groups
  • button names are taken from the item labels

so no need to add a rule for each button press or station anymore…

opensprinkler.items

Group:Switch:AND(ON,OFF) gOSPI_Station
Group:Switch:AND(ON,OFF) gOSPI_Station_Queued

Switch    OpenSprinklerDeviceRainsensor    "Rain Sensor"    {channel="opensprinkler:device:http:device:rainsensor"}

// keep that name for the opensprinkler rules
Switch         OpenSprinklerAllStationsOff                 "Alle aus"               (gOSPI_Station)

Switch         OpenSprinklerStation01                      "Station 1"                         (gOSPI_Station)           {channel="opensprinkler:station:http:01:stationState"}
Switch         OpenSprinklerStation01Queued                "S1 in Warteschlange"               (gOSPI_Station_Queued)    {channel="opensprinkler:station:http:01:queued"}
Number:Time    OpenSprinklerStation01RemainingWaterTime    "Restliche Laufzeit [%.0f min]"                               {channel="opensprinkler:station:http:01:remainingWaterTime"}
Number:Time    OpenSprinklerStation01NextDuration          "S1 nächste Laufzeit [%.0f min]"                              {channel="opensprinkler:station:http:01:nextDuration"}

Switch         OpenSprinklerStation02                      "Station 2"                         (gOSPI_Station)           {channel="opensprinkler:station:http:02:stationState"}
Switch         OpenSprinklerStation02Queued                "S2 in Warteschlange"               (gOSPI_Station_Queued)    {channel="opensprinkler:station:http:02:queued"}
Number:Time    OpenSprinklerStation02RemainingWaterTime    "Restliche Laufzeit [%.0f min]"                               {channel="opensprinkler:station:http:02:remainingWaterTime"}
Number:Time    OpenSprinklerStation02NextDuration          "S2 nächste Laufzeit [%.0f min]"                              {channel="opensprinkler:station:http:02:nextDuration"}

opensprinkler.rules

import org.eclipse.smarthome.model.script.ScriptServiceUtil

val OSPI_ReplyId = "OSPI_Reply"

rule "Telegram Bot receive rasen"
when
    Item TelegramBotLastMessageDate received update
then
    val telegramAction = getActions("telegram","telegram:telegramBot:bot1")
    val reply_text = "*Beregnungs-Optionen:*\nWelcher Bereich soll bewässert werden?"

    val reply_buttons = gOSPI_Station.members.filter[ i | i.state != ON ].map[ label ]

    if (TelegramBotLastMessageText.state.toString.toLowerCase == "/rasen") {
        logInfo("OSPI_Reply", reply_buttons.toString)

        telegramAction.sendTelegramQuery(Long::parseLong(TelegramBotChatId.state.toString), reply_text, OSPI_ReplyId, reply_buttons)
    }
end

rule "Telegram Bot receive rasen answer"
when
    Item TelegramBotReplyId received update OSPI_Reply
then
    val telegramAction = getActions("telegram","telegram:telegramBot:bot1")

    gOSPI_Station.members.filter[ i | i.state != ON && i.label == TelegramBotLastMessageText.state.toString ].forEach[ j |

        logInfo("OSPI_Reply", j.label.toString + " -- " + j.name.toString)
        if (j.name == "OpenSprinklerAllStationsOff") {
            logInfo("OSPI_Reply", j.label.toString + " -- " + j.name.toString + " Alle Stationen aus")

            val reply = "Bewässerung für alle Stationen ausgeschaltet."

            gOSPI_Station.members.filter[i|i.state == ON].forEach[i| { i.sendCommand(OFF)}]
            // we also need to cancel the queued stations
            gOSPI_Station_Queued.members.filter[i|i.state == ON].forEach[i| { i.sendCommand(OFF)}]
            telegramAction.sendTelegramAnswer(Long::parseLong(TelegramBotChatId.state.toString), TelegramBotReplyId.state.toString, reply)
            OpenSprinklerAllStationsOff.postUpdate(NULL)
        }
        else {
            val station_name = j.name.toString
            val station_label = j.label.toString
            station_name.sendCommand("ON")
            val station_rwt = ScriptServiceUtil.getItemRegistry.getItem(station_name + "RemainingWaterTime").state.toString

            val reply = "Bewässerung für *" + station_label + "* wurde gestartet.\nLaufzeit *" + station_rwt + "*.\nAusgelöst von *" + TelegramBotLastMessageUsername.state.toString + "*."

            telegramAction.sendTelegramAnswer(Long::parseLong(TelegramBotChatId.state.toString), TelegramBotReplyId.state.toString, reply)
        }
    ]

    if (TelegramBotReplyId.state.toString == OSPI_ReplyId) {
        // make sure the next request can see an update for "TelegramBotReplyId"
        TelegramBotReplyId.postUpdate(NULL)
    }
end

If you have any questions or suggestions, please let me know :slight_smile:

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.