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 case

    void 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:


  • Mod

    @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


  • Mod

    @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
    

  • Mod

    @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?


Log in to reply
 

Looks like your connection to MySensors Forum was lost, please wait while we try to reconnect.