Particle Cloud Variable set to Enum

I feel like I am missing something. I have a Particle Cloud Variable set in code to an enum variable. But when I pull that variable, even though I have hard-coded values 0 through 4, it always returns a six-digit number.

enum EnumState {Off=0, On=1, Up=2, Down=3, Unknown=4}enumState;

void setup() {
  Particle.variable("enumState", enumState);
  Particle.function("changeEnumState", changeEnumState);
}

void loop() {
}

int changeEnumState(String enumStateValue) {
  if (enumStateValue.toLowerCase() == "off")
    enumState = Off;
  else if (enumStateValue.toLowerCase() == "on")
    enumState = On;
  else if (enumStateValue.toLowerCase() == "up")
    enumState = Up;
  else if (enumStateValue.toLowerCase() == "down")
    enumState = Down;
  else
    enumState = Unknown;

  return enumState;
}

image

Interestingly, I return the “enumState” value as the return value for the Particle Function and it seems to work as expected.

image

Any thoughts?

That’s probably because the enum is not typed as full 32 bit integer but something shorter.
e.g. your 220929 would suggest it’s implicitly typed as uint16_t rather than int32_t.

Maybe the -fshort-enum switch is set by default.

You can try to explicitly type your enum like this

enum EnumState : int32_t { ... };

or implicitly forcing it to that like this

enum EnumState {Off=0, On=1, Up=2, Down=3, Unknown=0xFFFFFFFF} enumState;
1 Like

I was able to test your suggestions. The explicit type for the enum didn’t have any effect (same outcome as before.) The implicit forcing actually threw a compiler exception as the call to the Particle Variable registration resulted in a “ambiguous call”.

../wiring/inc/spark_wiring_cloud.h:81:25: error: call of overloaded '_variable(const char [10], EnumState&)' is ambiguous
         return _variable(name, std::forward<ArgsT>(args)...);

Hmm, the ambiguity does make sense since there are now three possible overloads (int, int32_t and uint32_t) which would all fit the 0xFFFFFFFF - I only knew about int :blush:

However, I don’t quite see why the typed enum still doesn’t get the desired result.
Maybe @rickkas7 can enlighten us both.

1 Like

I think I am going to chalk this up to the Particle Variable function having issues with enums.

I was able to find two different way to get this working.
image

The first working version is creating a new “currentEnumState” integer variable and then connected the Particle Variable to that. Then when the enumState changes, I just set the currentEnumState variable to the enumState (straight up, no casting on my part.)

This works. I am not sure why Particle Variable isn’t being handled the same way as I would figure it would perform the same internal conversion as assigning an enum to an int like I am doing here.

enum EnumState {Off=0, On=1, Up=2, Down=3, Unknown=4}enumState;

int currentEnumState = 0;

void setup() {
  currentEnumState = enumState;
  Particle.variable("enumState", currentEnumState);
  Particle.function("changeEnumState", changeEnumState);
}

void loop() {
}

int changeEnumState(String enumStateValue) {
  if (enumStateValue.toLowerCase() == "off")
    enumState = Off;
  else if (enumStateValue.toLowerCase() == "on")
    enumState = On;
  else if (enumStateValue.toLowerCase() == "up")
    enumState = Up;
  else if (enumStateValue.toLowerCase() == "down")
    enumState = Down;
  else
    enumState = Unknown;

  currentEnumState = enumState;
  
  return enumState;
}

The second way was to utilize the calculated Particle Variable and the ability to assign a function to a variable. I created a “getEnumState” function and assigned that to the variable. The function type was int and I just return the enum (without any cast.) This worked as well.

enum EnumState {Off=0, On=1, Up=2, Down=3, Unknown=4}enumState;

void setup() {
  Particle.variable("enumState", getEnumState);
  Particle.function("changeEnumState", changeEnumState);
}

void loop() {
}

int getEnumState() {
  return enumState;
}

int changeEnumState(String enumStateValue) {
  if (enumStateValue.toLowerCase() == "off")
    enumState = Off;
  else if (enumStateValue.toLowerCase() == "on")
    enumState = On;
  else if (enumStateValue.toLowerCase() == "up")
    enumState = Up;
  else if (enumStateValue.toLowerCase() == "down")
    enumState = Down;
  else
    enumState = Unknown;

  return enumState;
}
1 Like

While this is a workaround, it’s still odd and I’d be interested to learn the reason for that.

1 Like