[Solved] Strange Behavior in post requests

I’ve been using the spark core for home automation. It’s been going well. That said, I am having one very strange issue.
Any function I write that is simply a return statement, for example:
int state = 0;
function getState(String args){
return state;
}

refuses to be called as a post. It simply times out. If, however, I change it to

function getState(String args){
digitalWrite(D0, HIGH);
return state;
}

it works just fine.

Is this intended behaviour? I understand that posts are for changing data and gets are for retrieving it, but it seems like extremely bad UX to have the post simply time out with no information.

Hi @Tadgh

I think you have some strange syntax problems–try this instead:

int state = 0;

int getState(String args) {
  return state;
  }

1 Like

Sorry I made a mistake in my original post by not copy-pasting my actual code.

int state = 0;
int getState(String args){
    return state;
}

is my exact code.

Can you show us your Spark.Function call in Setup. Just covering all the bases.

I agree with @cloris that we can help more if we see all your code.

Another idea is to turn off the Spark/Arduino preprocessor. You may have to rearrange or slightly rewrite your code to make it truly C compatible with the preprocessor turned off.

#pragma SPARK_NO_PREPROCESSOR
#include "application.h"

Sorry for the delay. Here’s the full code. The problem in question lies with retrieveState()

int relay1 = D0; // This one is the built-in tiny one to the right of the USB jack
int relay3 = D7;
int state1 = 0;

int turnOff(String args);
int turnOn(String args);
int toggleOnOff(String args);
int retrieveState(String args);

// This routine runs only once upon reset
void setup() {
  Spark.function("state", retrieveState);
  Spark.function("toggle", toggleOnOff);
  pinMode(relay1, OUTPUT);
  pinMode(relay3, OUTPUT);
}

int retrieveState(String args){
    digitalWrite(relay3, HIGH); //If I comment out this line my post requests fail. 
    return state1;
}

int turnOn(String args) {
    digitalWrite(relay1, HIGH);
    state1 = 1;
    return state1;
}

int turnOff(String args) {
    digitalWrite(relay1, LOW);
    state1 = 0;
    return state1;
}

int toggleOnOff(String args) {
    if(state1 == 1){
      turnOff("");
    }
    else if(state1 == 0){
        turnOn("");
    }
    return state1;
}


// This routine gets called repeatedly, like once every 5-15 milliseconds.
// Spark firmware interleaves background CPU activity associated with WiFi + Cloud activity with your code. 
// Make sure none of your code delays or blocks for too long (like more than 5 seconds), or weird things can happen.
void loop() {
    
}

Hi @Tadgh

I tried your code and it works for me with the digitalWrite both present and commented out. Obviously I don’t see the LED change state when it is commented out (your first comment is wrong by the way, D7 is the on-board LED, not D0).

Any time you call a Spark function (both for toggle and state) you need to pass parameters even if they are not used, so I just passed the empty string via curl. Here’s a sample command with core id and access_token modified:

curl https://api.spark.io/v1/devices/4747...8989/state -d access_token=aabbcc...eeff -d params=""

Maybe the problem is the LED pin? Or with how you are calling the Spark functions?

1 Like

I know the comment is wrong. It’s from the boilerplate code provided.

Literally the only thing i change is commenting out that one line.

With the line uncommented, my post request works fine. When i comment the line, it times out. Nothing changes on my android code for making the API call. It generates a standard post request. This works fine, except for when the only line of the function is a return statement. The fact that it works when I uncomment that line indicates that my post request is correctly formed(at least I think it does).

There is no problem with the LED pin(i’m also not using it).

The issue is that the post request is timing out.

Any other ideas?

Hi @Tadgh

The fact that I was able to make your code work with and without the line commented out indicates that the problem is not in your core firmware.

I would try curl rather than your Android app and see if that works better. If you don’t like curl you can use Javascript or postman or a variety of other ways, but I think the problem is on the web side, not on the core side.

1 Like

I’ve made this curl command

curl https://api.spark.io/v1/devices/53ff7006666asdad2412317202567/state -d access_token=mytoken1234 -d params=""

with my token and device id modified, same exact issue. I’ve also tried it without params=""

Can you post the results returned by the curl command? Feel free to change your core-id.

Certainly! this is the exact response given by curl

{
“ok”: false,
“error”: “Timed out.”
}

and when it works here is the response:

{
“id”: “12387618736198273618972361792836”,
“name”: “Tadgh”,
“last_app”: null,
“connected”: true,
“return_value”: 1
}

OK, that also can mean that you don’t have a function by that name–let’s check:

curl https://api.spark.io/v1/devices/aabb...ff/?access_token=99....00

this returns

{
  "id": "<hex number here>",
  "name": "<name here>",
  "connected": true,
  "variables": {},
  "functions": [],
  "cc3000_patch_version": "1.28"
}

What does it return for your core in the failing case under “functions”?

{
“id”: “2323423423424234234”,
“name”: “Tadgh”,
“connected”: true,
“variables”: { },
“functions”: [
“state”,
“toggle”,
],
“cc3000_patch_version”: “1.29”

in both cases, this is the response, whether i have that line commented out or not.

OK, thanks for working through that.

I think we should get @Dave to check the Spark cloud server logs and see why this is failing for you. He will need your actual core id which you can send to him via private message if you like.

So after all this, I decided, what the hell, I’ll wipe the core, and re-flash the firmware. Lo and behold, everything now magically works. I’m super confused as to the behaviour I was getting though…

That;s a lesson i guess. Before digging too deep, wipe the device and try again.

Thanks for your patience

1 Like

Glad it is working–marking this one solved. Feel free to post here again if it comes back.

Weird! We’ve been chatting about making it easier for you to be sure the firmware running on the core is the latest version you’ve been working on locally or in the IDE, sounds like that might have helped here. :slight_smile:

It’s possible there was a timing issue, when the cloud calls an exposed function, the core sends back an acknowledgement message, and then will later send back a function response message. It’s possible those wires got crossed somehow and the second message was missed. I’ll make a note to look into it and try to reproduce it if I can.

Thanks!
David

1 Like