Recently, I've been trying to discover a way to control my OpenHab instance using Google Assistant.
It is rather easy to do this using IFTTT, but only when You use OpenHab in a cloud.
I prefer using private instalation of OpenHab in my LAN, so that was not an option for me. I was searching for another solution, but only app supported by IFTTT which might be usefull form me was Telegram messenger. The only problem is, that OpenHab does not support Telegram controling by default.
I google'd a little and it turned out that Telegram has a great public API with good Java support, so I decided to write a simple Spring Boot application as a bridge between Telegram Bot and OpenHab instance.
You can find source code of my application on my GitHub account:
https://github.com/aogorek/openhabtelegrambot
In order to run it there are few steps required:
1. Create Bot in Telegram Messenger
First You have to create Your own bot to communicate with. You need to contact @BotFather to do this. BotFather is a special Telegram bot used to control all Your bots.To contact him go to this link:
https://telegram.me/BotFather
Here is sample conversation with bot, to receive token required to contact Your new bot:
Your API token should be protected properly. Everybody who will gain access to this API token, will have access to control your OpenHab, so be warned :).
2. Build and run TelegramBot application
Next step is to download and build application from my GitHub. You need to have maven, GIT and java installed.
So type:
#git clone https://github.com/aogorek/openhabtelegrambot.git
#cd openhabtelegrambot/
#mvn clean install
After build completion, telegrambot-x.x.x-SNAPSHOT.jar should be present in target folder.
Then You need to prepare properties file. It is not present in jar, because it should contain Api Key, and as I wrote before it should be protected.
So, let's create application.properties file with that content:
#name of your bot created with BotFather
botUserName=my_private_openhab_bot
#Private API token for bot, received from BotFather
botToken=xxxxxxx:xxxxxxxxxxxxxxxxxxxxxxxxx
#URL of Your OpenHab instance.
openHabURL=http://192.168.1.8:8080
You should copy target jar file to destination folder, then create subfolder 'config' and put application.properties in it.
Jar is executable, so in destination folder type :
./telegrambot-x.x.x-SNAPSHOT.jar
Instructions are for Linux, but on Windows and Mac it should be very similar.
And that's it. You can control OpenHab using chat with your newly created bot.
3. Install app as a service (optional)
I use Raspberry Pi, so It was convenient for me to start my app as a service everytime machine boots.
In order to do this You need these steps (should work with other Linux distros too):
#sudo mkdir /var/telegrambot/config
copy application.properties to /var/telegrambot/config
copy telegrambot.jar to /var/telegrambot
Go to folder
/etc/systemd/system
and create file
telegrambot.service
with content:
[Unit]
Description=telegrambot
After=syslog.target
[Service]
User=telegrambot
ExecStart=/var/telegrambot/telegrambot.jar
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
call command:
#systemctl daemon-reload
and
#service telegrambot start
That's it... App should work.
4. Use Bot to control OpenHab
Currently there are four command supported.
EDIT:
I added another commands: CHART and STATE
Go to Bot Chat window, type HELP, and feel free to have a lot of fun :).
Take a look how it works in real life :)
5. What next
My application is easily extendable, so it is possible to add new commands quite fast. Feel free to fork my sourcecode end experiment with it. If You will be interested in further improvements, leave me a note, so I will prepare a tutorial how to implement new functionalities.
When we have working Telegram control, it is easy to connect it with IFTTT and use Google Assistant with voice activation, but this is a topic for next post.
Any feedback appreciated :)
Great man !
ReplyDeleteI really dig this and forked it over on GitHub to include some features I wanted. openhabtelegrambot can now be limited to specific chat IDs and items. I didn't want to allow everybody that found out the bot's name to control my smart home so I decided to limit it to me and my wife's Telegram chats with the bot. Furthermore items can be restricted as well to a) keep the list short and b) to now let your whole smart home be controllable from the outside.
ReplyDeleteHope you like it.
https://github.com/andreasbrett/openhabtelegrambot
PS: Better document the new meteo feature. I didn't know what URL was necessary for the properties file after I found out why the successfully compiled JAR did not run (your description of the properties file in this blog post is missing the meteo stuff).
Very interesting, thank you! One qustion: How do you ensure, that the bot does not talk to anyone other than you? I mean, everybody can contact that bot, but I think "he" should only talk to you, right?
ReplyDeleteYou are the owner of the Bot, You have your's BOT api key and You have to keep it in secret
DeleteI don't think it's a good idea to implement "security by obscurity". It doesn't matter how secure you make the bot's API key as the bot will talk to anybody that knows its name. That's why I created the fork of this great piece of code over on GitHub where you can define chat IDs that the bot is allowed to talk to. You can also define which items should be read only and which items should be hidden. That makes it much harder for an attacker to gain full access to your openHAB system.
DeleteYou can find the fork here:
https://github.com/andreasbrett/openhabtelegrambot
Can you point me towards the meteo stuff? I think I got everything right but I still can't use the bot (not even HELP) works. running the jar is returning "error creating bean with name "meteoApiService"
ReplyDeleteplease add
DeletemeteoURL=http://any.fake.url.com
to Your properties file.
Should help
Yes that did help in some way, now I get Unrecognized message. Type HELP for list of supported commands in Telegram!
ReplyDeleteBut I can't seem to return any commands, not even HELP is returning anything
Is there any exception in application output?
Deletehi @Emanul Baum
Deletedid you find solution for your problem?
Thanks!
ReplyDeleteThank you very much for sharing the code.
I have followed the tutorial but I can not get it to work, do you give me this error, any ideas?
sudo systemctl status telegrambot.service
● telegrambot.service - telegrambot
Loaded: loaded (/etc/systemd/system/telegrambot.service; disabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Tue 2019-02-19 11:54:33 CET; 1min 20s ago
Process: 11879 ExecStart=/var/telegrambot/telegrambot.jar (code=exited, status=217/USER)
Main PID: 11879 (code=exited, status=217/USER)
feb 19 11:54:33 raspberrypi systemd[1]: Started telegrambot.
feb 19 11:54:33 raspberrypi systemd[1]: telegrambot.service: Main process exited, code=exited, status=217/
feb 19 11:54:33 raspberrypi systemd[1]: telegrambot.service: Unit entered failed state.
feb 19 11:54:33 raspberrypi systemd[1]: telegrambot.service: Failed with result 'exit-code'.
Hi @Guille did you find solution?
DeleteThanks!
check what is logged in /var/log/messages
ReplyDelete"You should copy target jar file to destination folder, then create subfolder 'config' and put application.properties in it."
ReplyDeletewhich is this destination folder?
i run ./telegrambot-x.x.x-SNAPSHOT.jar directly in /home/ubuntu/openhabtelegrambot/target#
and get next error
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-05-28 11:12:28.375 ERROR 15934 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'offCommandHandler': Unsatisfied dependency expressed through field 'restApiService'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'restApiService': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'allowedItems' in value "${allowedItems}"