Endpoints and put requests

hello there.
I have successfully added an enpoint and can successfully call it by using this link on a webbrowser:

http://graph.api.smartthings.com/api/smartapps/installations/IC/switches/DID/on/?access_token=AT

where:
IC = installation code (something like: 26d339b1-3cef-4d4e-ba95-xxxxxxxxxxxxxx)
DID = Device ID  (something like: 26d339b1-3cef-4d4e-ba95-xxxxxxxxxxxxxx)
AT= access token  (something like: 26d339b1-3cef-4d4e-ba95-xxxxxxxxxxxxxx)

For my next step which i am stuck i am trying to use an electric imp which will send out the request as an http put.
What i am struggling to understand from the documentation is what goes to the headers and what to body
is the access token going to the headers?
Is the command to turn on/off/toggle the switch part of the url or do i pass it as a parameter?

I have seen some php and python code that do the following:

def toggle_st():
    url = 'YOUR_API_ENDPOINT'
    headers = {"Authorization": "Bearer YOUR_API_TOKEN"}
    data = '{"command":"toggle"}'
    r = requests.put(url, data=data, headers=headers)


def toggle_st(light_name):
    info=oauth_setup()
    switch_id=light_name_to_id(light_name)
    url = "%s/switches/%s" % (info['endpoint_uri'], switch_id)
    syslog.syslog("Toggling %s with URL: %s" % ( light_name, url ))
    data = '{"command":"toggle"}'
    r = requests.put(url, data=data, headers=info['headers'])

So that means the access token goes to the headers?
Then i am supposed to send the command : toggle as the body?
Are there any examples? Is my url supposed to be something like:

http://graph.api.smartthings.com/api/smartapps/installations/IC/switches/DID/

thanks for the help

Yes, just as you have shown the access token can be sent as an Authorization: Bearer token.

You could use a URL param or send in the request body as you are doing.

Then in your endpoint for your SmartApp, you can access the command (assuming JSON content-type):

def updateSwitch() {
    def cmd = request.JSON.command
    if (cmd == "toggle") {
        if (theLight.currentSwitch == "on") {
            theLight.off()
        } else {
           theLight.on()
        }
    } else if (cmd == "on") {
        theLight.on()
    } else if (cmd == "off") {
       theLight.off()
    }
} 

Of course, the exact commands supported depends upon what type of endpoint scheme you’d like to have. If you want an endpoint just dedicated to toggling a switch, you wouldn’t need to send anything in the request body - just have an endpoint like /toggle, and that endpoint can simply toggle the switch. Or, you can have one endpoint defined for updating a switch or set of switches, and what it does depends upon the request’s parameters (e.g. {command: "toggle"} or {command: "on"}, etc.

In addition to the tutorial in the docs, there is this example that shows a SmartApp that exposes endpoints for getting switch status and updating it (on, off, or toggle) here.

hello there thanks for the email. So i followed the advice and now using python as below and it doesnt work:

import sys
import requests
import json

def device_request():

    command_url = "http://graph.api.smartthings.com/api/smartapps/installations/xxxxxxxxxxxxxxxxxxxxx/switches/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    command_paramd = {
        "access_token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    }
    command_headerd = {}

    command_response = requests.put(
        url=command_url, 
        params=command_paramd, 
        headers=command_headerd,
        data=({"command": "on"})
    )
    print command_response.text

device_request()

the response is:
{“error”:true,“type”:“SmartAppException”,“message”:“Method Not Allowed”}

I know i am close… anything you might think i am doing wrong?

Do you have a PUT in your endpoint mappings?

http://docs.smartthings.com/en/latest/smartapp-web-services-developers-guide/tutorial-part1.html#specify-endpoints

mappings {
  path("/switches") {
    action: [
      GET: "listSwitches"
    ]
  }
  path("/switches/:command") {
    action: [
      PUT: "updateSwitches"
    ]
  }
}
2 Likes

hmmm you are right i didnt have a PUT it was all gets! Let me try replacing with a PUT and let you know ! Great catch! I wish i should have caught that earlier…

Did you change the “method” of the client-side HTTP Request to “PUT” as well? Or did you just leave it as GET?
I changed it to PUT, and get an error: “physicalgraph.app.exception.SmartAppException: Method Not Allowed”.
If I use GET, then I’ve got 500 internal error, but the command is working.

I experimented with PUT and it didnt work for me , but i did GET and it worked fine, so i left it as is.