UPDATE, February 2, 2021: I’ve made a few edits to this tutorial so that it works for OH2 and OH3. It’s still written with text-based items and DSL rules that work in both versions. If you prefer to build your system in OH3’s UI, it should be pretty easy to convert the items and rules.
As I get deeper into openHAB, I’m finding that I have to reboot or shutdown my Raspberry Pi reasonably often. It seemed like a good idea to set up a switch on my sitemap for that purpose, but was not nearly as easy as I thought it would be. I learned almost everything I needed to know for this task from the openHAB community, but it was a challenge interpreting expert-level discussions that quickly went over my head.
So, this tutorial is written for folks like me who are at an introductory level. I’m going to go into a fair amount of detail, covering some of the basics that are not obvious if you’re just getting started. And even then, I’ll probably miss some of the little details that I already take for granted.
FYI, in my attempts to explain stuff at a Grade 5 reading level, I’m almost certainly going to over-simplify in a way that will drive the veterans crazy. Sorry in advance!
Assumptions
This tutorial assumes that you’ve installed openHAB 2.4 using the openHABian installation guide, and are comfortable installing bindings via Paper UI and creating items, rules, and sitemaps via configuration files.
Why openHAB 2.4 via the installation guide? Because that’s what I did. If you install openHAB manually on an RPi or on another type of machine, your configuration might be different and some of these instructions might not work.
1. Grant permission for openHAB to execute Linux commands
Same as any other operating system, a Linux system has users. Some users can run important commands (like rebooting or shutting down), and others are prevented from doing so.
When openHABian was installed, it created two important users:
- “openhabian” is a very powerful user that has extensive access to the OS. It was created with a default password of “openhabian”, which you might have already changed via the openHABian Configuration Tool.
- “openhab” is a user that has no password and limited permissions. When the openHAB program is running, it communicates with Linux as the “openhab” user. So in order to run the reboot and shutdown commands from openHAB, we have to grant permission to this user.
Basically, we’re going to log into the system as the very powerful “openhabian” user and grant reboot and shutdown permissions to the very limited “openhab” user.
Access your Raspberry Pi
You’ll need an SSH client program, which you’ll use to access your RPi over your home network using a “Secure Shell” (SSH). The client enables us to type Linux commands that will be run on the RPi. I use PuTTY on my Windows 10 laptop, because that’s what this article told me to do.
Connect to your Raspberry Pi using your SSH client:
- Host name: “openhabianpi” or your RPi’s IP address
- Port: 22
- Username: openhabian
- Password: If you didn’t change this using the openHABian Configuration Tool, then it’s “openhabian” (if it is, you should really change your password).
Make openhab a super user
We’re going to run some “sudo” commands in Linux. sudo stands for “super user do”. When you start a command with it, you’re telling Linux to run the command with administrator-level (e.g. super user) permissions. Because of this, you’ll have to re-enter your password a few times to confirm the commands we’ll type in the following sections.
Start by telling Linux to add “openhab” to the group of users who can run sudo commands:
sudo adduser openhab sudo
Specify commands that openhab can run
Now we have to tell Linux which commands the “openhab” user is allowed to run. We’ll use the “visudo” command to create a new text file and open a text editor:
sudo visudo -f /etc/sudoers.d/yourfilenamehere
When the text editor opens, add the following lines to the new (and blank) file:
# Allow openhab user to execute shutdown, poweroff, and systemctl commands
openhab ALL=(ALL) NOPASSWD: /sbin/shutdown, /sbin/poweroff, /sbin/systemctl, /sbin/reboot
The first line is a comment for the purposes of describing what we’re doing. You can change it to whatever you like, so long as it starts with #.
The second line specifies that the “openhab” user can run the Linux shutdown, poweroff, systemctl, and reboot commands without entering a password. I don’t entirely understand what the “ALL” part is for, so let’s just remember that this is a beginner’s guide and leave it alone. EDIT: (@rlkoshak explains below)
If you want to run other system commands from openHAB, just tack them on to the end of the line. It’s also possible to grant permission to run any command, but that’s a bad idea. It’s best to limit users to only the commands they need.
There’s a list of key commands at the bottom of the text editor. To save and exit, we’ll use the ^X command, which translates to CTRL+X on a Windows keyboard. Visudo will prompt you to save your changes:
Save Modified Buffer? Y for Yes
File Name to Write: /etc/sudoers.d/yourfilenamehere.tmp
I was confused that visudo added “.tmp” to the file name, and initially thought it was saving a new file. However, when I accepted the file name as is, the changes were updated in my original file. So, you can just press Enter on your keyboard to accept the file name. (EDIT: @Udo_Hartmann confirms below that visudo saves a copy, then overwrites the original).
If you want to confirm that your changes were saved, enter the “sudo visudo…” command above to re-open the text editor. You can do this quickly by using your keyboard’s Up/Down arrow keys to scroll through recent commands (you can even see commands from previous SSH sessions).
Test the new permissions
Test the permissions by running the reboot command. First, we’ll use a sudo command to change to the “openhab” user. Then, we’ll reboot the RPi:
sudo -u openhab /bin/bash
sudo shutdown -r
If all goes as planned, your SSH client will kick you out because your RPi is rebooting, and we are done with this step.
2. Create an item
Now we’ll create a virtual switch in an item file. Its sole purpose will be to trigger reboots and shutdowns via the sitemap, so it doesn’t need to be connected to a thing.
String Flag_System "System" <switch>
Call the item whatever you want, but make sure it’s a string so that it can have multiple states (not just On and Off). You could also make individual switches (one for reboot and one for shutdown), but I prefer this approach.
3. Add the item to your sitemap
I’ve added the switch to my sitemap as follows:
Selection item=Flag_System label="System" mappings=[NULL="Active", Reboot="Reboot", PowerOff="Shut down"]
With a string-type item and a selector, I have to purposefully select Reboot or Shut down from a popup menu to confirm the command, so it’s very difficult for me to accidentally trigger a reboot.
4. Set up rules
EDIT: I’ve updated the rules with syntax for OH2 and OH3. You only need one of the two executeCommandLine
commands in each rule.
Reboot rule
rule "Reboot openHAB"
when
Item Flag_System received command "Reboot"
then
logInfo("Flag_System", "Rebooting openHAB")
executeCommandLine("sudo@@reboot") //OH2 version
//or
executeCommandLine("sudo","reboot") //OH3 version with new executeCommandLine syntax
end
When I change the virtual switch in my sitemap to “Reboot”, two things happen:
1. The reboot is recorded in the system log.
If you don’t want the “Rebooting openHAB” message in your log, you can delete this line.
2. A reboot is triggered
“sudo reboot” is run using the Exec action “executeCommandLine()”. This is similar to using sendCommand() when you want to turn a light switch on or off, but in this case we’re running a system command.
Shutdown rule
This is basically the same thing as the reboot rule, but the system stays off. I use this when I want to unplug my RPi.
rule "Shut down openHAB"
when
Item Flag_System received command "PowerOff"
then
logInfo("Flag_System", "Shutting down openHAB")
executeCommandLine("sudo@@poweroff") //OH2 version
//or
executeCommandLine("sudo","poweroff") //OH3 version with new executeCommandLine syntax
end
Side note: persistence
I have mapdb persistence set up, so whenever openHAB starts it returns items to their last reported state. My original persistence strategy persisted every item in my system, but I wanted to exclude Flag_System so that it will always return to a NULL state. Otherwise, Flag_System would go back to “Reboot” every time the system starts.
The solution was to create a group and add only the items that I want to persist to it. Then, I changed my persistence strategy to only persist items in that group:
// mapdb persistence
Strategies
{
default = everyChange
}
Items
{
Group_Persist* : strategy = everyChange, restoreOnStartup
}
I encourage you to set up persistence if you haven’t done so already.
EDIT: I’ve abandoned this strategy after realizing it wasn’t necessary. Instead, I just send Flag_System
an empty command before rebooting or powering off my system, which becomes the state that’s restored by MapDB.
6. Test your rules
Once your rules are in place and saved, testing them is as simple as going to your sitemap and selecting Reboot or Shut down. I’m 93% confident that they’ll work.
Questions?
I’m really enjoying openHAB, and I’m grateful to all of the people who have contributed to this community, whether you’re asking basic questions or helping others solve tough problems. For this particular challenge, I learned a lot from these discussions:
- How to solve Exec binding problems
- System Uptime Info and an Automatic Reboot
- Exec Binding does nothing on executeCommandLine
- executeCommandLine on a Windows machine
- Openhab 2 and executeCommandLine / Exec
I hope this tutorial helps other beginners to better understand your openHAB systems and gain confidence in your abilities. If you have any feedback or suggestions, I’d love to hear them!