You have to do a few different things that you can see the current state, that you can power on a device and that you can power off this device.
In openHAB 2 I have used the WOL Binding for power on my device and the Exec Binding to power off this device. I skipped the Network Binding. The disadvantage was that if I power on the device without openHAB (maybe via remote control or on-switch) I had to use a second item for the ping device state. This off course I have done with the Network Binding. What was missing was the linking of WOL, Exec and Network.
The solution for openHAB 3 is to use the Network Binding, the Exec Binding and the executeCommandLineAction. You have to use executeCommandLine for power off a device and not the Exec Binding. The Exec Binding is only used for Reboot a device over SSH and the Network Binding is used for sending a magic packet to do WOL.
Another important step is that you have to allow in /etc/openhab/misc/exec.whitlist
your commands and very important in /etc/sudoers
the shutdown, poweroff and reboot commands. For the WOL and the poweroff over SSH you have to create a rule. And you have to create things for using the Network Binding and the Exec Binding.
Also important is that from your openHAB device you have to connect once per SSH before running this commands because you have to add the SSH fingerprint to your device.
Change the /etc/sudoers file on the (remote) device
sudo su
<enter password>
nano /etc/sudoers
Then add following line to the end of the file:
<username> ALL=(ALL) NOPASSWD: /sbin/poweroff, /sbin/reboot, /sbin/shutdown
Please change <username>
to the user you want to connect to the computer via SSH.
Why? Because you canât enter the password for a sudo command over SSH!
Edit the exec.whitelist
In your /etc/openhab/misc/exec.whitelist
you have to add following:
/usr/bin/sshpass -p <password> /usr/bin/ssh -t -o StrictHostKeyChecking=no <username>@<hostname> '/usr/bin/sudo /sbin/shutdown -h now'
/usr/bin/sshpass -p <password> /usr/bin/ssh -t -o StrictHostKeyChecking=no <username>@<hostname> '/usr/bin/sudo /sbin/reboot'
Please replace the <password>
with the password for the user you want to access over SSH and off course the <username>
with this username. For <hostname>
you have to use the hostname for this device or the ip address.
Please also notice: Remember, however, that if you connected to the computer via the IP address, no SSH fingerprint will be created for the hostname. Then you would have to connect again via SSH with the hostname. Or accordingly vice versa!
Why using sshpass? As I have mentioned you canât enter any passwords if you run a switch item. There is no input option in openHAB.
Why do I use /usr/bin/
, /bin
or /sbin
etc.? Because sometimes there are problems with the PATH variable. I have one tip for this. You can use which
to see how you can run one of the programs you want to use without a PATH variable.
As example:
which shutdown
should deliever
/sbin/shutdown
If multiple users are installed, it is definitely better to be connected to the appropriate user and use which
instead of whereis
. With whereis
you may get multiple paths to an application, but not the path set for the current user to run an application.
Edit your Sitemap
You have to edit your sitemap and add as example following:
Frame label="Network" {
Switch item=MyDevice label="Device [%s]"
Switch item=MyDeviceReboot label="Reboot"
Text item=MyDeviceResponseTime label="Device Response Time [%s]"
Text item=MyDeviceLastSeen label="Device Last Seen [%s]"
}
Off course you can change the names of the items you want to use and off course you can change the representation. You shouldnât have to use a Frame as example.
Create your Things
You can create your things like following:
Thing network:pingdevice:devicename [ hostname="<hostname>", macAddress="<mac_address>", retry=1, timeout=5000, refreshInterval=60000 ]
Thing exec:command:devicename:poweroff [ command="/usr/bin/sshpass -p <password> /usr/bin/ssh -t -o StrictHostKeyChecking=no <username>@<hostname> '/usr/bin/sudo /sbin/shutdown -h now'", autorun=false ]
Thing exec:command:devicename:reboot [ command="/usr/bin/sshpass -p <password> /usr/bin/ssh -t -o StrictHostKeyChecking=no <username>@<hostname> '/usr/bin/sudo /sbin/reboot'", autorun=false ]
Please replace the <password>
with the password for the user you want to access over SSH and off course the <username>
with this username. For <hostname>
you have to use the hostname for this device or the ip address. Please change <mac_address>
to the MAC address you need for WOL. Please notice that on some devices there are maybe more than one Ethernet adapter and MAC addresses. And please ignore the MAC address for WLAN because Wake On WLAN does not work!
As you can see, I have also created a Thing for Shutdown or Poweroff. This would not have been necessary for executeCommandLine, but maybe you want to use another switch to shutdown the device separately.
As you cann see I use the Network Binding with a pingdevice and the Exec Binding for commands. The rest of the Thing name can vary at will. You just have to reuse the same name in your items.
Create your Items
Create a new item file or add to an existing item file as example following:
Switch MyDevice { channel="network:pingdevice:devicename:online" }
Switch MyDeviceReboot { channel="exec:command:devicename:reboot:run" }
Number:Time MyDeviceResponseTime { channel="network:pingdevice:devicename:latency" }
DateTime MyDeviceLastSeen { channel="network:pingdevice:devicename:lastseen" }
To run a command via an Exec Binding you have to add :run
as you can see on the MyDeviceReboot
switch.
This is the point that definitely works differently than in openHAB 2: You can use Exec Binding only with ON, but no longer with OFF, because run
will only run a command when an Item changes to ON.
Create Rules for WOL and Poweroff/Shutdown
The last point is that you have to create rules for WOL and poweroff. The WOL rule will use the Network Binding to send a magic packet which should power on your device. The poweroff rule will use the executeCommandLine Action:
rule "Wake on LAN MyDevice"
when
Item MyDevice received command ON
then
val actions = getActions("network", "network:pingdevice:devicename")
actions.sendWakeOnLanPacket()
end
rule "Poweroff MyDevice over SSH"
when
Item MyDevice changed from ON to OFF
then
executeCommandLine("/usr/bin/sshpass","-p","<password>","/usr/bin/ssh","-t","-o","StrictHostKeyChecking=no","<username>@<hostname>","/usr/bin/sudo","/sbin/shutdown","-h","now")
end
rule "Switch Reboot MyDevice off"
when
Item MyDeviceReboot changed to ON or Item MyDevice changed from ON to OFF
then
createTimer(now.plusNanos(10000000), [ |
MyDeviceReboot.sendCommand(OFF)
])
end
Please replace the <password>
with the password for the user you want to access over SSH and off course the <username>
with this username. For <hostname>
you have to use the hostname for this device or the ip address.
If you reboot a device the state of this Switch is still on. So after one second this Switch will change to OFF. And to avoid mistakes if the Device is OFF no matter if it is shut down or restarted and also no matter if at all via openHAB or not, this switch gets the status OFF.
Please notice: Another difference to openHAB 2 is that executeCommandLine replaces spaces with a comma. Looks a bit hard to get used to, but it works.
This will work fine because you can endless send magic packets to a device which is ON without any effect.
I used the Network Binding for WOL. The Exec Binding I used for Reboot. And the executeCommandLine Action I used for Shutdown if the Switch which will be ON after WOL or if I started my device without openHAB changed from OFF to ON. What will also work is if you shutdown the device without openHAB that the state changes from ON to OFF because the Network Binding can not ping it. This should currently be detected after one minute as you can see with the refreshInterval=60000
in the Things definition. If you start the device manually without openHAB after one minute at the latest, this device is then recognized as online.