Combine CASE and IF/ELIF
-
Not a programmer so all the sensor through trial and error. Need to combien the codes from two nodes (RGB dimmer and Heatpump).
The first one uses casevoid receive(const MyMessage &message) { if (message.isAck()) { Serial.println("This is an ack from gateway"); return; } Serial.print("Incoming message for: "); Serial.print(message.sensor); String recvData = message.data; recvData.trim(); Serial.print(", New status: "); Serial.println(recvData); switch (message.type) { case V_HVAC_SPEED: Serial.println("V_HVAC_SPEED"); if(recvData.equalsIgnoreCase("auto")) FAN_STATE = 0; else if(recvData.equalsIgnoreCase("min")) FAN_STATE = 1; else if(recvData.equalsIgnoreCase("normal")) FAN_STATE = 2; else if(recvData.equalsIgnoreCase("max")) FAN_STATE = 3; break; case V_HVAC_SETPOINT_COOL: Serial.println("V_HVAC_SETPOINT_COOL"); TEMP_STATE = message.getFloat(); Serial.println(TEMP_STATE); break; case V_HVAC_FLOW_STATE: Serial.println("V_HVAC_FLOW_STATE"); if (recvData.equalsIgnoreCase("coolon")) { POWER_STATE = 1; MODE_STATE = MODE_COOL; } else if (recvData.equalsIgnoreCase("heaton")) { POWER_STATE = 1; MODE_STATE = MODE_HEAT; } else if (recvData.equalsIgnoreCase("autochangeover")) { POWER_STATE = 1; MODE_STATE = MODE_AUTO; } else if (recvData.equalsIgnoreCase("off")){ POWER_STATE = 0; } break; } sendHeatpumpCommand(); sendNewStateToGateway(); }
The second one uses ifs
void receive(const MyMessage &message) { int val; if (message.type == V_RGB) { Serial.println( "V_RGB command: " ); Serial.println(message.data); long number = (long) strtol( message.data, NULL, 16); // Save old value strcpy(rgbstring, message.data); // Split it up into r, g, b values red = number >> 16; green = number >> 8 & 0xFF; blue = number & 0xFF; send_status(); set_hw_status(); } else if (message.type == V_LIGHT || message.type == V_STATUS) { Serial.println( "V_LIGHT command: " ); Serial.println(message.data); val = atoi(message.data); if (val == 0 or val == 1) { on_off_status = val; send_status(); set_hw_status(); } } else if (message.type == V_DIMMER || message.type == V_PERCENTAGE) { Serial.print( "V_DIMMER command: " ); Serial.println(message.data); val = atoi(message.data); if (val >= 0 and val <=100) { dimmerlevel = val; send_status(); set_hw_status(); } } else if (message.type == V_VAR1 ) { Serial.print( "V_VAR1 command: " ); Serial.println(message.data); val = atoi(message.data); if (val >= 0 and val <= 2000) { fadespeed = val; } } else { Serial.println( "Invalid command received..." ); return; } }
Do i understand correctly that i should still with HVAC code and use cases and rewrite the rgb code just substituting
if (message.type == V_RGB)
with
case V_RGB:
-
@moskovskiy82 yes that's correct.
And don't forget the break; at end of each case.
-
else if (message.type == V_LIGHT || message.type == V_STATUS)
How to da that? Internet tells me a can use
case V_LIGHT:
case V_STATUS:But that throws errors
-
@moskovskiy82 it would help if you could post those errors...
-
Well with this code
switch (message.type) { case V_RGB: { Serial.println( "V_RGB command: " ); Serial.println(message.data); long number = (long) strtol( message.data, NULL, 16); // Save old value strcpy(rgbstring, message.data); // Split it up into r, g, b values red = number >> 16; green = number >> 8 & 0xFF; blue = number & 0xFF; send_status(); set_hw_status(); } break; case V_LIGHT: case V_STATUS: { Serial.println( "V_LIGHT command: " ); Serial.println(message.data); val = atoi(message.data); if (val == 0 or val == 1) { on_off_status = val; send_status(); set_hw_status(); } } break; case V_DIMMER: case V_PERCENTAGE: { Serial.print( "V_DIMMER command: " ); Serial.println(message.data); val = atoi(message.data); if (val >= 0 and val <=100) { dimmerlevel = val; send_status(); set_hw_status(); } } break;
Get the following errors
In function 'void receive(const MyMessage&)': IR_TESTBED:232: error: duplicate case value case V_LIGHT: case V_STATUS: ^ IR_TESTBED:232: error: previously used here case V_LIGHT: case V_STATUS: ^ IR_TESTBED:245: error: duplicate case value case V_DIMMER: case V_PERCENTAGE: ^ IR_TESTBED:245: error: previously used here case V_DIMMER: case V_PERCENTAGE: ^ Using library MySensors at version 2.1.1 exit status 1 duplicate case value
-
@moskovskiy82 ah. You caught a very subtle problem.
From MyMessage.h:V_STATUS = 2, //!< S_BINARY, S_DIMMER, S_SPRINKLER, S_HVAC, S_HEATER. Used for setting/reporting binary (on/off) status. 1=on, 0=off V_LIGHT = 2, //!< \deprecated Same as V_STATUS, **** DEPRECATED, DO NOT USE ****
So behind the scenes, V_LIGHT is the same as V_STATUS (the integer 2).
That means your code, when compiling, looks like this:case 2: case 2:
and the compiler complains because the same value can only be used once in a switch clause.
Same thing for the other two:
V_PERCENTAGE = 3, //!< S_DIMMER. Used for sending a percentage value 0-100 (%). V_DIMMER = 3, //!< \deprecated Same as V_PERCENTAGE, **** DEPRECATED, DO NOT USE ****
So just remove the "case V_LIGHT" and "case V_DIMMER" parts and you'll be good to go.
-
@mfalkvidd Thank you! That solved everything. Well almost. At the end of the heatpump sensor there was a call to two functions
sendHeatpumpCommand();
sendNewStateToGateway();After moving the RGB code to the case switch - everytime i change the RGB light the AC beeps as it receives the command. Is there an easy solution for this?