[SOLVED] Cloud API OK with curl, but...no action from device with other tools (despite getting 200 responses)

Hello Particle Folks,
I hope everyone is staying safe.

I’m looking to change product locked software using Python Requests.
The docs show how to do this clearly. link

What I have found though, is that this command only works using curl.
It does not seem to work when the command comes from other programs (Paw, Postman, Python Requests)

What is even stranger, is that in these other programs I was getting a <Response [200]>, and all the response data would show everything was OK, but… my electron was not changing software in response to the command.

Have other folks noticed this? I’d really like to use Particle Requests for my project.

Here’s a visual of what I’m seeing.
v1: successful curl request

v2: request that says success… but no response on the electron.
(PAW shown here, same Postman and Requests)
Request details:

Response details:

Thanks!

Just to not the obvious difference:

  • v1 uses a PUT request
  • v2 uses a GET request

Try PUTting things when GETtting won’t work :wink:

1 Like

Ah @ScruffR nice catch! Whoops! Yes that does change things!
-> Still not working. but here is the response when I use PUT request.

{“error”:“Nothing to do?”} looks interesting. Do you know if that is caused by Cloud API or my API tool?

Have you tried the same v475 again or uploaded a newer version and tried with that?
Have a try what curl does when you request the same upload twice.

Hi @ScruffR ,
I was able to check that: curl shows no action when you try the same software version.

curl:
(Requesting different software than on the device) ex. v475 -> v465: OK
(Requesting same software that is on the device) ex.v475 -> v475. : No action from Electron

PAW, Postman, Particle Requests:
(Requesting different software than on the device) ex. v475 -> v465: No action from Electron
(Requesting same software that is on the device) ex.v475 -> v475. : No action from Electron

Can you (re)post the exact PUT request you are issuing via your alternative tools?
I suspect the format for the parameters is not correct and hence the “defaults” are used instead of your intended parameters.

You can also try to redirect your requests (from curl and alternatives) to a different endpoint (e.g. requestbin.com) and compare the actual requests received there.

I’d think the parameters in a PUT request are best put into the data payload rather than URL-encoded.
BTW, this is what the -d parameter in curl stands for.

If you want (and haven’t already) you can also try adding application/x-www-form-urlencoded to the request header.

1 Like

I’m having similar problems with the API in both function calls via POST and variable requests via GET. I can successfully call the functions and get the variables using the console and the Particle app, so the function and variables are properly exposed and the firmware is working. I’m using Postman to tests the API.

When calling a function using Postman, the requests gets into the function in the device firmware but doesn’t trigger any action other than return the unique return number for that function, Whatever argument it is sending to the function is not correct.

When using GET—also with Postman—the API doesn’t recognize the variable name. Please visuals see below.

https://api.particle.io/v1/devices/e0xxxxxxxxxx674/reports?access_token=fexxxxxxxxx4fb&arg=noonRpt
{
  "id": "e0xxxxxxxxxx674",
  "last_app": "",
  "connected": true,
  "return_value": 7  this is the return value for the called function “reports”
}

And the GET request:

https://api.particle.io/v1/devices/e0xxxxxxxxx674/temp?access_token=fexxxxxxxxxxx4fb
{
  "ok": false,
  "error": "Unknown Variable: temp"
}

Thanks,

Steve

The action to trigger needs to be coded in your firmware.
We don’t know what your function is doing so we cannot advise.

For your variable GET we’d also need to know how you have registered that variable in your firmware.

Hey just wanted to share the error on my part was I needed to put the URL parameters are part of the Payload. “-d” on curl makes the parameters part of the payload.

Once I did that everything worked. Thanks for the suggest @ScruffR to use Postb.in. the difference between the 2 http requests showed up right away.

1 Like

ScruffR and Adam42,

Thanks for your prompt reply and I apologize for my tardy reply.

Again, I can get the expected result from the Particle.Function when I call it from the CLI or the Particle App.
When I call the function from outside the Particle ecosystem using Postman, I do not get the expected results.

Here is the request sent by Postman

:arrow_forward:

:arrow_forward:
POST https://api.particle.io/v1/devices/e00xxxxxxxxxxxxxxxxx674/reports?access_token=fecxxxxxxxxxxxxxx4fb&arg=noonRpt

<—- I’ve tried it with args as well

Here is the code in my program

// *************************************************************
In Setup():

Particle.function ("reports",reports);  <—— Particle function call in response to POST request

Loop(

Do stuff
)

****************************************
int reports (String command){  	<—- function called by *reports* in the Particle.function call

  if (command == "noonRpt"){    	<—— function identified by the *arg* in the POST request
    noonRpt ();
  }
  if (command == "Fix"){
    Fix ();
  }
  if (command == "boatStatus"){
    boatStatus ();
  }
return 7;						<—- Note the return number
}
********************************************
int noonRpt (void) {  			 <—- the function called by the function *reports*

    convertDataForSMS();
    strcpy (smsTxt, boatName); strcat (smsTxt, "\n");
    strcat (smsTxt, Time.format(TIME_FORMAT_ISO8601_FULL));
    strcat (smsTxt, "\nLat, Long\n");
    strcat (smsTxt, strLat);
    strcat (smsTxt, ", ");
    strcat (smsTxt, strLong);
    //strcat (smsTxt, "\nAccelerometer Vector:\n  Mag: ");
    //strcat (smsTxt, vectorMagnitude);
    //strcat (smsTxt, " m/sec/sec\n");
    //strcat (smsTxt, "  Direction: ");
    //strcat (smsTxt, vectorDirection);
    //strcat (smsTxt, " *Rel.\n");
    strcat (smsTxt, "\nSystem Voltage: ");
    strcat (smsTxt, voltTxt);
    strcat (smsTxt, " VDC\nTemp: ");
    strcat (smsTxt, strTemp);
    strcat (smsTxt, " *F\nHumidity: ");
    strcat (smsTxt, strHumidity);
    strcat (smsTxt, " %\nFence active: ");
    strcat (smsTxt, charFenceActive);
    Particle.publish ("reports", smsTxt ,PRIVATE);   <—- A Webhooks respond to this to 																send a SMS request to twilio.
    //strcat (smsTxt, "\x1A");
    //strcat (smsTxt, "\x0D"); 
   // startSMS();
    //delay (500); 

  return 0;
}

This is the Particle Boron’s response to Postman:

    "id": "e00fcexxxxxxxxxxxxxx2674",
    "last_app": "",
    "connected": true,
    "return_value": 7							<— Note number returned
}

When I call the noonRpt function via the Particle CLI or through the Particle app, the function, the Webhook and Twilio work perfectly. This leads me to believe that I am not structuring the arg portion of the Postman entry correctly.

Thanks for your help.

Steve

You should print out the received command.
I’m pretty positive you are seeing the same issue as @Adam42 saw when he provided the arguments the wrong way :wink:

I could repeat the advice that helped him, but haveing written it once should suffice.

BTW, returning 7 in all cases is less than usefull IMO.
Even returning command.length() would make more sense - I guess you’d get 0 due to what was said above :wink:

Thanks ScruffR,

I agree that the 7 at the end of the function doesn’t tell much. I put that there to see if the POST request got that far after using it in one of the if statements, and it does. The problem seems to be that I am not using the correct key (in Postman vernacular) to get the argument into the Particle.function and thus to the firmware function: reports.

The POST request reaches my Boron, suggesting that the DEVICE_ID is correctly entered. It reaches the firmware function reports() suggesting that the FUNCTION is identified correctly and that the access_token key and value in the arguments section of the Postman request form are correct.

As you suggested, I printed the value of command in the called firmware function reports and it came up blank. So, everything in the POST request is working except for the keyword arg or args – I’ve tried both. Is there another keyword that I should be using to pass an argument to Particle.fucntion?

SteveH

OK, I’ll reiterate

You still have the arg/args url-encoded and not in the data payload.