openHAB and Tankerkönig gas prices + Telegram integration - Second iteration
In my previous blog post about "Tankerkönig" I explained the details of how to integrate this binding into openHAB and provide a Telegram interface.
Someone on the openHAB community forum pointed out that Telegram bots allow queries, where one can present the user with options, and the user only has to click on one of the options. That makes it easier to use, and less typing is required as well. I went ahead and implemented that.
Most of the implementation does not change, especially all the Things and Items are the same. The Rules change however.
Initial question
The user can still send a "/tanken" question:
rule "Telegram Bot receive tanken"
when
Item telegramlastMessageDate received update
then
val telegramAction = getActions("telegram","telegram:telegramBot:HA_Bot")
if (telegramLastMessage.state.toString.toLowerCase == "/tanken") {
telegramAction.sendTelegramQuery(Long::parseLong(telegramLastMessageChatId.state.toString), "Tank Optionen:", Tanken_ReplyId, "E10", "Diesel", "E5")
}
end
The bot will pick the question up, and answer with a list of options:
The sendTelegramAnswer() function accepts the following parameters:
- Channel/Group ID
- The question (What the bot is asking or presenting to the user) - this text will remain after the query is answered
- A ReplyId
- One or multiple options
The ReplyId is unique for this question, Telegram will send back the ReplyId along with the answer (more about this later). I defined the ReplyId as a static variable ($Tanken_ReplyId) in the head of the rules file:
val Tanken_ReplyId = "Tankerkoenig_tanken"
Pick any string you want, it does not have to be a variable - but this way I ensure that I don't mix up different strings in the rules file.
The answer
This part became a bit more complicated. The Item "telegramLastMessageReplyId" is updated when the user selects one of the options. However a rule is only fired iff the value of the Item changes. This does not happen if the user sends the same "/tanken" question twice, and you have the same ReplyId. On the other hand, you can use unique ReplyIds, but then you have to keep track of all open questions. Telegram unfortunately does not allow a timeout for questions. I solve this part by resetting "telegramLastMessageReplyId" to "NULL" if it is equal $Tanken_ReplyId.
rule "Telegram Bot receive tanken answer"
when
Item telegramLastMessageReplyId received update Tankerkoenig_tanken
then
val telegramAction = getActions("telegram","telegram:telegramBot:HA_Bot")
if (telegramLastMessage.state.toString == "Diesel") {
var reply = "Dieselpreise:"
// place calculation here
telegramAction.sendTelegramAnswer(Long::parseLong(telegramLastMessageChatId.state.toString), telegramLastMessageReplyId.state.toString, reply)
} else if (telegramLastMessage.state.toString == "E10") {
// ...
} else if (telegramLastMessage.state.toString == "E5") {
// ...
} else {
telegramAction.sendTelegram(Long::parseLong(telegramLastMessageChatId.state.toString), "Unknown option!")
}
if (telegramLastMessageReplyId.state.toString == Tanken_ReplyId) {
// make sure the next request can see an update for "telegramLastMessageReplyId"
telegramLastMessageReplyId.postUpdate(NULL)
}
end
The part for "Diesel" shows how the bot sends a reply, once the reply string is available in $reply. The calculation has not changed from the previous blog post, and I'm not repeating that part here. At the end, I'm resetting $telegramLastMessageReplyId to NULL. This way the next reply will change/update this variable.
Comments
Display comments as Linear | Threaded