Control Particle Photon with Smartthings App

sure bud no problem! Make no mistake all these photon smartthings projects are also my first attempt at coding too. I’m not a programmer but pilot by trade so I’m probably horrible about explaining what I have done. I can post my whole thing if you want but there is alot of extra crap in there it might be easy to lose what I have done for the part your interested in especially since I havent commented it the best. So with that in mind instead I will post a small example program that would do nothing but what you have asked for.

int microswitch = D0;   // 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
String garageContact = "open";
}
if (status == LOW){                   // check status if its low store closed in the garageContact string 
String garageContact = "closed";
}
}

its the particle variable that you would call with the smartthings app. If you look at my example for the pool controller you see my blurb that asks the photon for the variable and it would look like this to send for our sample “GarageStatus” variable…

httpGet("https://api.particle.io/v1/devices/yourdeviceID/GarageStatus?access_token=youraccessToken", closure)

if its not clear as mud or doesnt work let me know as we should be able to put our feeble crappy coding minds together and get something to work :wink:

okay I didnt look at your code before I sent mine but it looks like you have done essentially the same thing but I had a hard time finding an error. I would look on the particle photon console on the app and see if your particle variable show up correctly there. If they are then we at least know that the error is on the smarttings side of things reflecting the changes. Its difficult for me to troubleshoot since I cant see what your seeing when you control the device. From there the only thing I can think of is I used different names for my particle variable and the variable that stored the data for the particle variable. Im not sure if that matters or not maybe it’s confused what its asking for since they share the same name??

Third thought the more I look at it I wonder if it is working but you just think its not… When I look at your code it says you basically push a button and pass that info to particle to open or close your garage and then refresh which calls your get state functions. Well if you push a button the garage is going to start to close and it refreshes immediately but the garage takes a bit to close so the contact isn’t going to show closed for 30 seconds or however long the garage takes to close. By then you have already refreshed and it still shows the incorrect state unless you were to refresh again. It wont reffresh on its own you need some way to poll it. If this is what is happening you could combat that with your particle publishes you have in your code you could have a webhook fire when you publish the event that fires a webcore funtion to refresh the device. I use that alot in some of my devices. To easily fire a webhook when that event triggers go on the particle console and you will see create a webhook.

Okay so I decided to put some of the theory to test since I had a spare photon laying around. I did have some errors in my sample code Ill post the new ones here… But heres a video of my demo running

.ino

int microswitch = D0;   // 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";
}
}

groovy device handler

/**
 * sample garage status
 *
 * Author: Brennon Scuderi
 *
 * 
 *
 * 
 */

preferences {
    input name: "deviceId", type: "text", title: "Device ID", required: true
    input name: "token", type: "password", title: "Access Token", required: true
    input name: "GarageStatus", type: "text", title: "Garage Status Variable Name", required: true, defaultValue: "GarageStatus"
    }

metadata {
    definition (name: "sample garage status", author: "Brennon Scuderi") {
        capability "Polling"
        capability "Sensor"
        capability "Refresh"
        attribute "garagestatus", "string"
    }

    tiles(scale: 2) {
        valueTile("GarageStatus", "device.garagestatus", width: 4, height: 4) {
            state("garagestatus", label:'${currentValue}')
        }

      
        standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
            state "default", action:"refresh.refresh", icon:"st.secondary.refresh"
        }


    }
}


// create a new attribute called garagestatus
def updated() {
	initialize()
    // attempted fix
    log.debug "Updated !"
    state.garagestatus = 1    
    log.debug "device.garagestatus: ${device.garagestatus}"
}

def poll() {
    log.debug "Executing 'poll'"

    getStatus()
}

def refresh() {
    log.debug "Executing 'refresh'"

    getStatus()
}


// no clue what this does or if its needed
def parse(String description) {
    def pair = description.split(":")

    createEvent(name: pair[0].trim(), value: pair[1].trim())
}

// ask smartthings for the garage status
private getStatus() {
    def closure = { response ->
        log.debug "request was successful, $response.data"

        sendEvent(name: "garagestatus", value: response.data.result)
    }

    httpGet("https://api.particle.io/v1/devices/${deviceId}/${GarageStatus}?access_token=${token}", closure)
}
2 Likes

Dude. Above and beyond. Thanks for all of that. I’m implementing it now!

1 Like

@baconface The only thing I would for sure add to my code is a particle publish on a state change, (Which it looks like you had in yours), and a webcore piston that refreshes the status when you send a particle publish. That way it automatically shows the correct state from your sensor. To do that go to the console and click here. Make a webhook for when your event is published

For the url put the link found here in your piston. This url will execute your piston. So your piston doesn’t need any if statements just an action. IE refresh garage contact.

1 Like

I can confirm that your code works when I start from scratch with it, but I’m having problems integrating it into my code. I’m sure I’m missing something dumb. I’ll play with it more in the next day or so (and at a bigger screen!).

Thanks again, man!

1 Like

YES. I need to play with webhooks. I’ll also look at this in the next day or so.

The publish on state change was…wonky. I was getting integers of 8 instead of 0 or 1 sometimes. I think it was bouncing and giving 1 repeatedly, and they were being added together. It was odd. I didn’t have the _PULLDOWN after my INPUT though, so that may help. I am pretty sure that the state change code that I put in there is pretty basic, but I pulled that out of my ass and was pretty proud of it…right up to the point that it didn’t work!

@baconface Yeah the pin “floats” by default so it can bounce between high and low the pull down makes sure it stays low unless you add voltage so you don’t get undesired changes or vise versa you can pull it to high if you want depending on how the componant works your adding so you will definitely want that in your code. Also mechanical switches like a contact sensor “bounce” when they contact meaning they can go briefly back and forth between high and low really fast when they first change state. So depending on the accuracy you need for the state change you could add a capacitor to filter out the bounce by making it take a few milliseconds to actually charge up and deplete or try and do it with code too. Look up like a debounce filter code there should be examples out there. I don’t know how to do it just that you can or I’d help you. I ran into a similar issue with my particle photon mailbox but came across these two different solutions From members on their forums. Basically my mailbox would sometimes trigger an open event both when I opened and real quick when I closed it too. I decided for my application I didn’t care cause I just had my mailbox sensor only notify me on the first opening of the day anyways so I decided not to care.

Success!

It turned out that the issue was with reusing the same device in SmartThings. I made a whole new device, pointed it to the DH, and it worked. Weird.

I combined the individual state and command tiles into one for each door, added some icons and a splash of color, and updated my github with the working copy.

TO DO: Webhooks and/or(???) state change code with publishing.

Here is a screenshot of ST:

1 Like

Hoooooly crap. I’ve never used webCoRE before. It. Is. Amazing. I’ve got it firing off refreshes when any of the three doors change state.

NOW WITNESS THE FIREPOWER OF THIS FULLY ARMED AND OPERATIONAL GARAGE DOOR CONTROLLER!!!

Thank you so much for all of your help, @bscuderi13. I seriously couldn’t have done all this without you. I’ll definitely be creating my own DH post on the forum after a little testing. Again. THANKS! I’m geeked.

1 Like

Oh Oops I guess I kinda sssumed you had used web core already lol my bad but you were bound to go down that road eventually since your coding your own garage door controller. It looks really snazzy man I’m glad you got it all to work. And I was happy to help cause I frustratingly struggled through a lot of this myself since there isn’t much info out there. I really struggle with the groovy though. My device handlers definitely need to be spruced up with some color and more functionality. Yours looks very professional.

I’m sure I would have gotten there eventually. Thanks for the push. :grinning:

I agree that the groovy programming was rough. I am just learning Arduino/C++ and was just getting comfortable with that. Then – wham – SmartThings. Mah brain!

The color and sizing was easiest part. Just fiddle with the height/width and pull up a hex color site. The different colors for more than two states would be neat for your pump speed tile. The multi-attribute tiles would be really interesting for your setup.

Hi Jared,

I am very new to ST. I have a similar setup as you (except I am trying to use the multi-sensor for the doors instead of the wired magnetic sensor). I have the Photon working but am struggling with pulling in the sensor status from SmartThings. I looked at the WebCoRE and webhooks but can’t figure out how to use them to integrate Photon with ST. Would you mind sharing how you did it?

Thanks.

Hey, NT! Welcome to ST! I just posted my Particle sketch and ST device handler in a new thread. Check it out here.

I don’t know if getting webhooks set up will help you in this scenario. What exactly are you wanting the webhook to do? Mine just refreshes the ST door statuses when it get a state change from the Photon. Like, it just tells my SmartThings DH, “Hey, refresh().” It does nothing else. It may actually be the simplest, most boring webhook ever. WebCoRE even told me something to the effect of, “This doesn’t really do anything. Are you sure this is all you wanted to type?” when I saved the piston.

My setup uses only the Photon for all status and garage door opening functions. The DH is written specifically for that device. I’m not sure how to integrate another device (with it’s own DH) into my DH. I don’t know if it’s even possible. That said, I’m new to coding. I suppose you could have separate devices for the open/close side and the garage door toggling side.

In Jared’s post I showed making a contact sensor with the photon it’s the last post. Like Jared said you can see in my video I refresh it to get it to change status. To do that automatically you need to use particle publish and webcore to refresh.

I just re read that and realize you want to use the multi sensors inftead of the built in wired contact sensors? In that case you need to set up a particle function and pass data to that either with webcore or a device handler that way you can have certain actions tell the photon and the photon can handle them. If you can get more specific of your intentions I have examples of both webcore and device handlers sending data to the photon.

I finally took your advice on this… It wasnt too bad after reading a bit… This is what I settled on. So thanks for the push!


That looks great, man. Pretty colors and icons FTW!

1 Like

Hi, I have been trying to do the same thing, blinking an led on the particle photon using smartthings app. But I keep getting the following error in the Smartthings IDE simulator:

groovyx.net.http.HttpResponseException: Unauthorized @line -1 (off)

I put in my access token and device ID into the device that I created under My Devices. So I am uncertain as to why I get the unauthorized error. Could it just mean my access token is wrong?

Here is my particle photon code:

int ledToggle(String command);
int led = D7; 
void setup() 
{
  Particle.function("ledstate", ledToggle);    
  pinMode(led, OUTPUT);
}
void loop()
{}

int ledToggle(String command)
{
  if (command == "1") {   
    digitalWrite(led, HIGH);   
    return 1;
  } else {               
    digitalWrite(led, LOW);    
    return 0;
  }
}`

Here is my device handler code

preferences {
        input("token", "text", title:"Access Token")
        input("deviceID", "text", title:"Device ID")
    }
metadata {
	definition (name: "Photon", author: "calmraptor") {
    	capability "Switch"
    }
    tiles {
    	standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
    	state "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor:     "#79b821"
		state "off", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
		}

		main "switch"
		details "switch"
	}
}

def parse(String description) {
	log.error "This device does not support incoming events"
	return null
}    

def on() {
    httpPost(
    	uri: "https://api.particle.io/v1/devices/${deviceId}/ledstate",
        body: [access_token: token, command: '1'],  
    )
}

def off() {
    httpPost(
    	uri: "https://api.particle.io/v1/devices/${deviceID}/ledstate",
        body: [access_token: token, command: '0'],  
    )
}