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?


 

435
Online

7.9k
Users

8.8k
Topics

93.8k
Posts