This piston is designed to execute an orderly system shutdown of an Ubuntu computer from Alexa which toggles a virtual switch which in turn executes an HTTP GET request to a Raspberry Pi running a CGI Script. The script runs from a web page hosted on the Raspberry Pi and issues a “sudo shutdown -P 0” to the target linux computer. This computer could be a windows machine with modification to the following procedure. Note that the Raspberry Pi and the target computer must be on the same LAN for this to work.
On your Raspberry Pi, from a command Window:
sudo apt-get update
sudo apt-get install apache2
a2enmod cgi
Add the following to the end of /etc/apache2/apache2.conf
<Directory /var/www/html>
Options +ExecCGI
AddHandler cgi-script .cgi
</Directory>
Restart Apache:
sudo service apache2 restart
Create a CGI Script:
In my example, “scott” is an account with sudo privilege to perform the following steps. Also, “mondo” in my example is the target computer that we want to develop the shutdown procedure for.
sudo nano /var/www/html/shutdowncomputer.cgi
#!/bin/bash
echo “Content-type: text/html”
echo “”
echo “<html><head><title>Shutdown Scott Mondo Computer on LAN”
echo “</title></head><body>”
echo “<h1>Shutting down Scott Mondo Computer</h1>”
echo “<pre> $(ssh scott@mondo ‘sudo shutdown -P 0’) </pre>”
echo “</body></html>”
Make the script executable:
chmod 755 /var/www/html/shutdowncomputer.cgi
Now that we have the script, we will be executing the script from a web browser on your local LAN that points to the address of the Raspberry Pi and the script we just created.
The Apache web server runs under the user account “www-data” and that account normally does not have a password and also has interactive logins disabled. This is done for security reasons and what I am describing below should NEVER be done on a public or corporate network. On a private LAN, like a home network, as long as the Raspberry Pi has no connection route from the public internet and you have secured your router and wireless access, the risk is manageable.
Change the password for www-data so that you can log into the “apache” web server account:
sudo passwd www-data
Add www-data to the sudoers group so it can execute the shutdown. (This is the dangerous part because normally there is no interactive login access to this account and it does not have sudo privilege) As mentioned earlier, on a Home network that is secured from the outside, this is a lesser concern.
sudo usermod -aG sudo www-data
You still won’t be able to easily log into the account without changing the /etc/passwd record to include shell access. To do this “sudo nano /etc/passwd” and find the www-data account and change it to the following:
www-data:x:33:33:Apache,,,:/var/www/html:/bin/bash
You are still logged into the Raspberry Pi but we need to log into the www-data account now:
sudo su -l www-data -s /bin/bash
sudo su
Create an ssh hidden folder for an “ssh key” to facilitate automatic login without manual password entry:
mkdir .ssh
Change ownership for the .ssh folder to www-data:
chown www-data .ssh
Now exit back to the shell without sudo privilege:
exit
Create an ssh key for automatic password entry for ssh login (This is very secure). Default all the entry prompts:
ssh-keygen
Copy the generated key over to the machine that you want to perform the automated remote shutdown. In my example, “scott” is the name of my account on the target node that has sudo privilege and “mondo” is the name of that machine:
ssh-copy-id -i~/.ssh/id_rsa.pub scott@mondo
You will be prompted for your password on the target machine after the command above is entered and this is so that the key can be registered there.
If all of this worked, you should be able to log into the target machine with “ssh” from the “www-data” account without a password requirement. Since you are on the “www-data” account now, try it. Again, “scott” is my username on the remote system and “mondo” is the name of the system we want to shutdown:
ssh scott@mondo
If that worked, you will be logged into your target machine without having to enter a password. This is required for the Web CGI script from above to work.
One final step while you are logged on to the target computer is:
sudo visudo
Add the following line to the file that opens (replace “scott” with your username and then save the file):
scott ALL = NOPASSWD: /sbin/shutdown
You can test this so far by going into a browser on any machine on your network and entering the target URL. My Raspberry Pi is addressed at 172.16.1.4 in the following example:
http://172.16.1.4/shutdowncomputer.cgi
If the above worked, the Linux computer should have performed an orderly shutdown and power off. Again, the ssh utilities exist for Windows and Macintosh, so modifying the .CGI script above with a shutdown command appropriate to those systems will work.
To automate this shutdown task from an Alexa Voice command, all you need to do is create a Virtual Switch in the SmartThings IDE that is named for your computer. In an earlier blog, I go into how a WakeOnLAN request can be created using many of the same steps to turn on and boot up a computer. In this example, when the virtual switch is turned off, a Webcore routine makes a web request to the URL above and the computer shuts down.
Once you create the virtual switch, add it to the Alexa SmartApp and to the Webcore SmartApp in the Samsung SmartThings Classic Mobile App. Don’t forget to tell Alexa to “Discover” to find your new Switch. Once this is done, create a Webcore Piston as follows:
I went a step further and created a group in the Alexa App called “Scott’s Computer” that contains only the virtual switch “ComputerScott”.
My Alexa command is “Alexa, turn off Scott’s Computer”.