I’m pretty excited to be able to bring this project. It ties together and old Raspberry Pi running latest version of Raspbian with HTTPD and a PHP script. The PHP code runs the gpio command in order to trigger pin 4 of the RPi for a second then turns it off. This triggers a simple 5v relay which in-turn shorts out my gate.
The obvious difference of what I’m sharing here is the fact that I wrote a SmartThings Device Handler which uses a “hubaction” which means it can be triggered from a WAN connection w/o having to put your device out on the web with a public IP. The hub performs a local action on a local IP. The project is essentially a generic HTTP Device Handler for SmartThings. The goal was to keep it as small/simple as possible. So it consists only of a single PHP script and the SmartThings Device code. It depends on no other packages except the stock Raspbian Jessie that I’ve been testing for a while.
This project was tested successfully via an external IP using a custom port. It was also tested with an Amazon Echo/Alexa and Pollster. The PHP has a flag at the top that will require a configurable HTTP username & password to be entered. This offers another level security and completely contained within the PHP code. Arduino code also has a commented out section to enable basic HTTP authentication — uncomment section at about line 80 of the Arduino sketch.
I chose Raspberry Pi for gate trigger because of its wired/reliable LAN connection. Coupled with a Ethernet over Powerline adapter (like my Netgear XAV2001) — gotta already have power in that gate box (or garage motor). I already had a retired Pi 256MB Model B that was super-slow in doing anything else, it only made sense to use it . Add a $3 relay and I can trigger and customize anything about this solution. Hoping the Pi can withstand SoCal heat… I probably need to buy a heatsink ASAP (UPDATE: RPi 1 kept dying of outside heat so now using RPi 3 which needed one reboot during summer) The code was originally executing a Python script from PHP to trigger the GPIO (turning pins on and off on the Pi). I successfully replaced that Python code with the gpio command instead.
FULL INSTALLATION INSTRUCTIONS FOR RASPBERRY PI:
- enable SSH in newer Raspbian editions via raspi-config > Interfacing Options > SSH
- sudo su to start the shell as root then passwd to change the root password to whatever you want
- sudo vi /etc/ssh/sshd_config — change the line to allow root login: PermitRootLogin yes
- ssh in as pi/raspberry
- sudo raspi-config — to expand SD card (done automatically in 2017) and change timezone. Can also modify /etc/defaults/keyboard to be a “us” keyboard and not the default “gb”.
- sudo apt-get update
- sudo apt-get -y upgrade
- sudo apt-get -y install apache2 php5 php5-gd wiringpi raspi-gpio rpi-update --fix-missing
- sudo rpi-update — this was key step for network stability of the Raspberry Pi. Otherwise constantly received “actively refused” errors from HTTPD & SSHD requiring reboot to fix.
- sudo visudo — and add the following to the bottom otherwise no sudo functions will work from the PHP code: www-data ALL=NOPASSWD: ALL — more info here.
- sudo service apache2 restart — to restart Apache
INSTRUCTIONS FOR ARDUINO/NodeMCU/ESP8266:
After the RPi, @Casper introduced me to the ESP8266 NodeMCU module which is wireless & extremely efficient with relays, LEDs, etc. and has no OS to maintain like the RPi, I implemented compatibility with the hardware device and my code. In the GitHub source folder for this project you can find NodeMCU.ino file which you simply compile & write the Arduino sketch to the board. I successfully used 3.3v relays and even the 5v relays which grabbed the positive signal directly from a spliced USB cable and the negative signal is what is sent to the GPIO pin.
WIRED RJ45 ETHERNET:
For wired connection (due to reliability) using an Arduino Nano/UNO with an RJ45 ethernet shield (ENC28J60). Nano/UNO is VERY limited in memory so only the relay logic is shared on GitHub in a file called ArduinoNano.ino. For the ethernet shield, I used a library called UIPEthernet.
The ESP8266/NodeMCU are more difficult to work with the ENC28J60. You must use this modified UIPEthernet Library, originally done by @ntruchsess then updated for use with ESP8266 by @cassyarduino on this post. Using the ENC28J60 is unfortunately inconsistent and things like Android/IOS can’t read the web page while a desktop browser can.
SMARTAPP FOR AUTOMATION OF 2nd SWITCH & 2nd CONTACT SWITCH:
I created a SmartApp & TWO Device Type Handlers called Virtual Custom Switch & device. The SmartApp will keep the virtual switch synced up with the Custom Switch of the generic HTTP device. This will help to automate the secondary/custom button.
Grab VirtualCustomSwitch.groovy file from the regular GitHub location. Create a new device in ST API and obviously assign this custom device handler to it: https://github.com/JZ-SmartThings/SmartThings/tree/master/Devices/Generic%20HTTP%20Device
If using the 2nd Contact Switch, do the same using Virtual2ndContactSensor.groovy as the DTH.
Use the new SmartApp to choose the parent switch and the virtual one/two you created in the step above. This will force the CustomTrigger/secondary-switch state to be synced with the new/virtual device and the contact switch will do the same. Get the SmartApp from this folder on GitHub: https://github.com/JZ-SmartThings/SmartThings/tree/master/SmartApps/Virtual%20Custom%20Switch%20Sync%20App
For nerds: some explanation of how/what was done. It was a true pain with the 2nd switch only because I’m trying to use the same device to monitor the parent switch but also react to ON/OFF commands when you press it. Well, not so easy… that’s called an infinite loop because when I would switch the virtual device, it would cause the tile/state to also switch thus it would run the command again — because I’m using momentary toggle (rather than stateful on & off which worked well from the start of writing the SmartApp & DTH) it ended up in an infinite loop. My solution was to store the EPOCH time on the parent device handler of when the last time Custom was triggered. If 3 seconds have not passed, it will NOT run the CustomTrigger/2nd-switch command again. So that’s the only limitation at the moment. In order to avoid an infinite loop, I do the time check which may slow down some lightning-fast folks but it’s all worth it for the sake of automation.
Here is one of the videos I used to start me off with the Pi & relays: https://www.youtube.com/watch?v=p2abZ90-eU0
Useful command for checking the Raspberry Pi pin status & value. It’s pretty close to what WebIOPi offers but in text mode: watch -n0.5 gpio readall