Particle Photon Garage Controller "GarageControl" [DH and INO]

I humbly submit for your approval the Particle Photon GarageControl. Install steps in post two.


  1. Figure out how to have ST see the door open/close pins and garage door pins as open/close sensors and momentary switches respectively. I’d really like to get notifications from ST if a door is left open for too long, and “open door if” would be nice. Any community help with this would be great.
  2. Add some pictures and junk to this thread.

I bought myself a Particle Photon for Christmas, and this was the result. It uses a Particle RelayShield to toggle the garage doors. The Particle devices are a really good, gentle way to get into Arduino. I had always wanted to get into it, but it seemed like a steep learning curve. The web interface and WiFi flashing of the Photon leveled some of that out. Throw in a good amount of YouTube tutorial watching, and this is where I ended up. This was my first stab at Arduino/Particle coding and ST coding. So…it’s my first time coding. Be gentle, gods o’ the keyboard. :slight_smile:

The included files are heavily commented, but let me know if you have any questions about how they work. This started out as some really simple code and spiraled out of control as I (sort of) figured out what I was doing. It’s far less daunting than it looks at first glance. There are no included libraries in the Particle sketch to confuse you.

A huge thanks to @bscuderi13 for all of his help. I wouldn’t have been able to pull it off without his guidance and support. His pool controller is boss.

1 Like


Step A: Particle

  1. Set up your Particle Photon. Download the app on your phone (or tablet…I guess), add your new Photon, let it install Tinker. Do the obligatory tap on, tap off, tap on, tap off, tap on, tap off of the D7 led.

  2. Go to my GitHub (links in the OP), copy the Particle .ino file. Paste it to your new Particle sketch. Edit it as you see fit (or don’t…it’s basically perfect). Flash it to your device. Note that the first time you flash, it may take a while. It updates the firmware if it’s out of date. Don’t freak out.

  3. Physically set up your device. You can do 2 & 3 in either order really. The Photon is coded to have a common-cathode RGB LED (or three individual LEDs if you’re basic) plugged into A4, A5, and A7. The negative leg goes into ground. This is a flashing reminder LED. I have mine run up to the bedroom. It tells the wife that I’ve left a garage door open. She likes this feature.

Step B: SmartThings

  1. Copy the SmartThings Device Handler code from GitHub. Go to, and create a new DH under “My Device Handlers” from code using my code.

  2. Create a new device under “My Devices”, name it something memorable, and select the custom DH from the list. It’s called “GarageControl”, and it should be near the bottom with the other customs.

  3. Edit the preferences of this new device. Add your Device ID and super secret token here. You get these from the site. Note that if you changed the name of g1Status, g2Status, or g3Status (Why would you? Those are some sweet ass names!), you need to change the names here to match.

Step C: WebCoRE. Ahhhh, WebCoRE. How did I not know about you until now?

  1. Check out this thread for a video instruction on how to install: webCoRE Installation Video It’s way easier than it seems.

  2. Make a piston that calls the refresh() command in the ST device handler whenever a door state pin changes on the Photon. I don’t rightly remember all the steps to do it, but you’ll muddle through somehow.

Step D: IFTTT/Google Home/Alexa integration

  1. Use IFTTT to link GH/Alexa with Particle. Super easy. “This” is Alexa or Google Assistant; have it listen for a specific phrase of your choice. “That” is Particle; have it call the GarageRelay function on your device. A list of all the possible input commands are in the comments of the .ino, but I’m an nice guy, so I’ll put them here as well. Note that they are case and space sensitive. I suggest using the open/close commands because it has some amount of logic, and I worked really hard on them. :blush:

  2. GarageRelay commands are:
    “1” – toggle garage 1
    "2" – toggle garage 2
    "3" – toggle garage 3
    "open1" – open garage 1 only if it’s currently closed
    "close1" – close garage 1 only if it’s currently open
    "open2" – open garage 2 only if it’s currently closed
    "close2" – close garage 2 only if it’s currently open
    "open3" – open garage 3 only if it’s currently closed
    "close3" – close garage 3 only if it’s currently open
    "openAll" – trigger all doors only if they’re closed
    "closeAll" – trigger all doors only if they’re open

Thanks for the shout out man I’m glad I could help! Now you have a fancy new garage controller you did yourself! If anything me helping you out just helped hone my skills and refine my own project better since this was my first project too. If anyone likes this project and is curious about mine that he referred to you can find it here…

Its continually evolving and gets better and better everyday. I couldn’t be happier with the photon as a great development platform for almost any custom smartthings integration.

1 Like

What are you using to power the Photon?

Where is the power coming from to trigger the garage door opener? Or does closing the low voltage wires cause the opener to start?

I’m using a random phone USB charger plugged into the Photon. It’ll provide power to the shield. You can also plug a barrel connector into the shield itself. I think it’ll take 7V-20V.

The relay just closes and bridges the two connections. It doesn’t require power. If you touch a pair of pliers to the two terminals on the back of the garage door opener, it does the same thing.

Thanks for the detailed writeup. You and @bscuderi13’s explanations helped me a lot in understanding how things work.

I am using ST multi-sensors for my door contacts and I have two pistons that monitor the doors and send alerts when the doors stay open longer than a pre-defined time. I used the ones @bthrock created (Door Left Open Reminder) and modified them. They work like a charm.

Hope you will find these helpful.

1 Like

Nice! I need to do that with mine until I figure out how to have ST see the status variables as open/close sensors.

@baconface You can have see your particle variables. I’m not sure why we couldn’t get it to work when we were playing with this concept before it’s really quite simple. You posting this prompted me to try it out for my sake… I’ve gotten better since then with all the practice lately tinkering with my own. Here’s a video of the test setup working showing proof of the concept…

And some code…

Photon Code

int microswitch = D7;   // define a pin for the microswitch
String garageContact = "unknown"; // on startup set the garageContact status to unknown and define the vaiable

void setup() {
Particle.variable("GarageStatus", garageContact);  // register a particle cloud variable called garage status with the value of the garageContact variable

pinMode(microswitch, INPUT_PULLDOWN);  // set pin on microswitch as input with the pulldown resistor engaged

void loop() {
int status = digitalRead(microswitch); // read the microswitch pin and store the value to status
if (status == HIGH){                   // check status if its high store open in the garageContact string
garageContact = "open";
if (status == LOW){                   // check status if its low store closed in the garageContact string 
garageContact = "closed";

And the Device Handler I commented the crap out of the small blurb of code

  * garage contact from photon
Copyright 2014 SmartThings
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License. You may obtain a copy of the License at:
 *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
 *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
 *  for the specific language governing permissions and limitations under the License.
// user input preferences  
  preferences {
    input name: "deviceId", type: "text", title: "Device ID", required: true
    input name: "token", type: "password", title: "Access Token", required: true
    input name: "contactVar", type: "text", title: "Contact Variable Name", required: true, defaultValue: "GarageStatus"

// name the capabilities app author etc
 metadata {
	definition (name: "testgaragecontact", namespace: "Brennons Apps", author: "bscuderi") {      
		   capability 	"Contact Sensor"
           capability "Sensor"
           capability "Refresh"
// make the tiles for the device handler		
	tiles {
		standardTile("contact", "", width: 2, height: 2) {
			state "open",   label: '${name}', icon: "",   backgroundColor: "#e86d13"
			state "closed", label: '${name}', icon: "", backgroundColor: "#00A0DC"
        standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 1, height: 1) {
            state "", action:"refresh.refresh", icon:"st.secondary.refresh"
		details(["contact", "refresh"])						

// Refresh value
def refresh() {
    log.debug "Executing 'refresh'"
//execute get value command on refresh
// Get value of contact sensor variable from particle
private getvalue() {
    def closure = { response ->
        log.debug "Contact request was successful, $"
        // This is the line that sends the contact sensors response value of either open or closed to the contact sensor
        sendEvent(name: "contact", value:
// part that gets sent to particle to get the value of the variable
    httpGet("${deviceId}/${contactVar}?access_token=${token}", closure)

Hope this helps bud be sure to report back if you get this thing working at the next level!

@bscuderi13 I thought of doing this same thing with a photon, while assembling the parts for the pool controller and find you have a hand in this one too. I work in industrial automation and the 2 to 36 inch valves, not a typo, have open and closed contacts, so to me, having it show intermediate tells me that the door might have hung up on something, leading to me to possibly add two reed switches. Heck, with enough reed switches, you could track it all the way open or closed. That’s how the determine how much of a reactor control rod is inserted (that’s a past life).

1 Like

You magnificent bastard! Now I just need some time to try implementing this.

1 Like

I’ve thought about using two magnetic switches on each door so I could have the status be open, closed, or moving. Maybe one day.

1 Like

That is some big valves haha yeah tracking the valve position with reed switches could be useful data for sure. How I handled all valve tracking with my pool was that on boot I had the relays activate to swing the valve all the way to one side. The valve has a built in limit switch that stops it. I then know where it is theoretically and can set a variable track or from then on and send a refresh command to smartthings. It doesn’t actually track valve position if it were to get stuck however I wouldn’t know. It just tracks that the photon received the command and activated the appropriate relay. But a valve getting stuck has never happened at least yet and I’ve never had them mismatch so it seems reliable enough to me. Especially since with my setup it would be difficult to do any harm to the equipment if the valve position was wrong. I thought about splicing directly into the limit switches of the valve to give me some valve position sensing data for the photon but it seemed like a lot of unnecessary work especially trying to shift the electric 24 volt ac down to a small enough dc logic so the photon can actually use the data and not fry.

so I am super noob to this whole coding thing, I think I got the device ID and super secret code entered into the right spot in your code but I’m not sure, could you elaborate a little more on that?

Which spot are you talking about? You should enter the ID and token into the device’s menu in SmartThings. You shouldn’t be adding it directly to the code. You can do it from the app, but it’s easier to do from the api. Image attached.

Sir baconface! Thank you for replying. Turns out I was just not reading your directions the right way. Now I have a new question. I do have a ST multisensor the triggers light to come on when the garage door opens, is it possible to have the g1status read the status of that sensor instead of looking at the particle status? I see where I would input that data in your code, I just don’t know what to enter there.

That is absolutely doable, but I’m pretty weak on ST/groovy. @bscuderi13?

If it were me I’d just use webcore to virtually mimic and change the status when the other sensor changes?

I have one last question, I’m so noob sorry about all of this. I have been trying to change your code in many different ways to get the alexa command to be “open hatch” instead of “open1” . Where in the code do I need to change the command word?

No problem at all, man! It’s the bit at the end after the loop. Just change the commands that are sent to the GarageRelay function. These:

So it took me a bit, but I finally found that you were using magnetic switches on the garage door in your .ino file. You are using D0 D1 and D3 for one wire of the switch, but where do you connect the other wire, assuming I’m using a normally open switch, that is closed when the magnet is near? If it is a normally closed, I just have to switch the high or low in the file, right?