Need help with controlling relays

So I am trying to make a home automation system where I can control 16 relays with my phone using esp rainmaker and an ir receiver with a esp32, and I have written this code, but when I turn it on, all the relays seem to be turned on. Please help


#include "RMaker.h"
#include "WiFi.h"
#include "WiFiProv.h"
#include <IRremote.h>
#include <Preferences.h>
Preferences pref;

const char *service_name = "PROV_1234";
const char *pop = "1234";

// define the Chip Id
uint32_t espChipId = 0;

// define the Node Name
char nodeName[] = "ESP32_Relay_8B";

// define the Device Names
char deviceName_1[] = "Switch1";
char deviceName_2[] = "Switch2";
char deviceName_3[] = "Switch3";
char deviceName_4[] = "Switch4";
char deviceName_5[] = "Switch5";
char deviceName_6[] = "Switch6";
char deviceName_7[] = "Switch7";
char deviceName_8[] = "Switch8";
char deviceName_9[] = "Switch9";
char deviceName_10[] = "Switch10";
char deviceName_11[] = "Switch11";
char deviceName_12[] = "Switch12";
char deviceName_13[] = "Switch13";
char deviceName_14[] = "Switch14";
char deviceName_15[] = "Switch15";
char deviceName_16[] = "Switch16";

//Update the HEX code of IR Remote buttons 0x<HEX CODE>
#define IR_Button_1   0x10
#define IR_Button_2   0x810
#define IR_Button_3   0x410
#define IR_Button_4   0xC10
#define IR_Button_5   0x210
#define IR_Button_6   0xA10
#define IR_Button_7   0x610
#define IR_Button_8   0xE10
#define IR_Button_9   0x110
#define IR_Button_10   0xFD0
#define IR_Button_11   0x910
#define IR_Button_12   0xDD0
#define IR_Button_13   0x490
#define IR_Button_14   0x90
#define IR_Button_15   0xC90
#define IR_Button_16   0x890
#define IR_All_Off    0xA90
#define IR_All_On     0x5D0

// define the GPIO connected with Relays and switches
static uint8_t RelayPin1 = 4;     //D4
static uint8_t RelayPin2 = 5;     //D5
static uint8_t RelayPin3 = 18;    //D18
static uint8_t RelayPin4 = 19;    //D19
static uint8_t RelayPin5 = 21;    //D21
static uint8_t RelayPin6 = 22;    //D22
static uint8_t RelayPin7 = 23;    //D23
static uint8_t RelayPin8 = 25;    //D25
static uint8_t RelayPin9 = 26;    //D26
static uint8_t RelayPin10 = 27;   //D27
static uint8_t RelayPin11 = 32;   //D32
static uint8_t RelayPin12 = 33;   //D33
static uint8_t RelayPin13 = 13;   //D13
static uint8_t RelayPin14 = 12;   //D12
static uint8_t RelayPin15 = 14;   //D14
static uint8_t RelayPin16 = 15;  //D15

static uint8_t wifiLed      = 2;  // D2
static uint8_t gpio_reset   = 0;  // Press BOOT for reset WiFi
int IR_RECV_PIN  = 35; // D35 (IR receiver pin)

// Relay State
bool toggleState_1 = LOW; //Define integer to remember the toggle state for relay 1
bool toggleState_2 = LOW; //Define integer to remember the toggle state for relay 2
bool toggleState_3 = LOW; //Define integer to remember the toggle state for relay 3
bool toggleState_4 = LOW; //Define integer to remember the toggle state for relay 4
bool toggleState_5 = LOW; //Define integer to remember the toggle state for relay 5
bool toggleState_6 = LOW; //Define integer to remember the toggle state for relay 6
bool toggleState_7 = LOW; //Define integer to remember the toggle state for relay 7
bool toggleState_8 = LOW; //Define integer to remember the toggle state for relay 8
bool toggleState_9 = LOW; //Define integer to remember the toggle state for relay 9
bool toggleState_10 = LOW; //Define integer to remember the toggle state for relay 10
bool toggleState_11 = LOW; //Define integer to remember the toggle state for relay 11
bool toggleState_12 = LOW; //Define integer to remember the toggle state for relay 12
bool toggleState_13 = LOW; //Define integer to remember the toggle state for relay 13
bool toggleState_14 = LOW; //Define integer to remember the toggle state for relay 14
bool toggleState_15 = LOW; //Define integer to remember the toggle state for relay 15
bool toggleState_16 = LOW; //Define integer to remember the toggle state for relay 16

// Switch State
bool SwitchState_1 = LOW;
bool SwitchState_2 = LOW;
bool SwitchState_3 = LOW;
bool SwitchState_4 = LOW;
bool SwitchState_5 = LOW;
bool SwitchState_6 = LOW;
bool SwitchState_7 = LOW;
bool SwitchState_8 = LOW;
bool SwitchState_9 = LOW;
bool SwitchState_10 = LOW;
bool SwitchState_11 = LOW;
bool SwitchState_12 = LOW;
bool SwitchState_13 = LOW;
bool SwitchState_14 = LOW;
bool SwitchState_15 = LOW;
bool SwitchState_16 = LOW;

IRrecv irrecv(IR_RECV_PIN);
decode_results results;

//The framework provides some standard device types like switch, lightbulb, fan, temperature sensor.
static Switch my_switch1(deviceName_1, &RelayPin1);
static Switch my_switch2(deviceName_2, &RelayPin2);
static Switch my_switch3(deviceName_3, &RelayPin3);
static Switch my_switch4(deviceName_4, &RelayPin4);
static Switch my_switch5(deviceName_5, &RelayPin5);
static Switch my_switch6(deviceName_6, &RelayPin6);
static Switch my_switch7(deviceName_7, &RelayPin7);
static Switch my_switch8(deviceName_8, &RelayPin8);
static Switch my_switch9(deviceName_9, &RelayPin9);
static Switch my_switch10(deviceName_10, &RelayPin10);
static Switch my_switch11(deviceName_11, &RelayPin11);
static Switch my_switch12(deviceName_12, &RelayPin12);
static Switch my_switch13(deviceName_13, &RelayPin13);
static Switch my_switch14(deviceName_14, &RelayPin14);
static Switch my_switch15(deviceName_15, &RelayPin15);
static Switch my_switch16(deviceName_16, &RelayPin16);

void sysProvEvent(arduino_event_t *sys_event)
{
    switch (sys_event->event_id) {      
        case ARDUINO_EVENT_PROV_START:
#if CONFIG_IDF_TARGET_ESP32
        Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on BLE\n", service_name, pop);
        printQR(service_name, pop, "ble");
#else
        Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on SoftAP\n", service_name, pop);
        printQR(service_name, pop, "softap");
#endif        
        break;
        case ARDUINO_EVENT_WIFI_STA_CONNECTED:
        Serial.printf("\nConnected to Wi-Fi!\n");
        digitalWrite(wifiLed, true);
        break;
    }
}

void write_callback(Device *device, Param *param, const param_val_t val, void *priv_data, write_ctx_t *ctx)
{
  const char *device_name = device->getDeviceName();
  const char *param_name = param->getParamName();

  if(strcmp(device_name, deviceName_1) == 0) {
    
    Serial.printf("Lightbulb = %s\n", val.val.b? "true" : "false");
    
    if(strcmp(param_name, "Power") == 0) {
        Serial.printf("Received value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
      toggleState_1 = val.val.b;
      (toggleState_1 == false) ? digitalWrite(RelayPin1, HIGH) : digitalWrite(RelayPin1, LOW);
      param->updateAndReport(val);
      pref.putBool("Relay1", toggleState_1);
    }
    
  } else if(strcmp(device_name, deviceName_2) == 0) {
    
    Serial.printf("Switch value = %s\n", val.val.b? "true" : "false");

    if(strcmp(param_name, "Power") == 0) {
      Serial.printf("Received value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
      toggleState_2 = val.val.b;
      (toggleState_2 == false) ? digitalWrite(RelayPin2, HIGH) : digitalWrite(RelayPin2, LOW);
      param->updateAndReport(val);
      pref.putBool("Relay2", toggleState_2);
    }

  } else if(strcmp(device_name, deviceName_3) == 0) {
    
    Serial.printf("Switch value = %s\n", val.val.b? "true" : "false");

    if(strcmp(param_name, "Power") == 0) {
      Serial.printf("Received value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
      toggleState_3 = val.val.b;
      (toggleState_3 == false) ? digitalWrite(RelayPin3, HIGH) : digitalWrite(RelayPin3, LOW);
      param->updateAndReport(val);
      pref.putBool("Relay3", toggleState_3);
    }

  } else if(strcmp(device_name, deviceName_4) == 0) {
    
    Serial.printf("Switch value = %s\n", val.val.b? "true" : "false");

    if(strcmp(param_name, "Power") == 0) {
      Serial.printf("Received value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
      toggleState_4 = val.val.b;
      (toggleState_4 == false) ? digitalWrite(RelayPin4, HIGH) : digitalWrite(RelayPin4, LOW);
      param->updateAndReport(val);
      pref.putBool("Relay4", toggleState_4);
    } 
     
  } else if(strcmp(device_name, deviceName_5) == 0) {
    
    Serial.printf("Lightbulb = %s\n", val.val.b? "true" : "false");
    
    if(strcmp(param_name, "Power") == 0) {
        Serial.printf("Received value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
      toggleState_5 = val.val.b;
      (toggleState_5 == false) ? digitalWrite(RelayPin5, HIGH) : digitalWrite(RelayPin5, LOW);
      param->updateAndReport(val);
      pref.putBool("Relay5", toggleState_5);
    }
    
  } else if(strcmp(device_name, deviceName_6) == 0) {
    
    Serial.printf("Switch value = %s\n", val.val.b? "true" : "false");

    if(strcmp(param_name, "Power") == 0) {
      Serial.printf("Received value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
      toggleState_6 = val.val.b;
      (toggleState_6 == false) ? digitalWrite(RelayPin6, HIGH) : digitalWrite(RelayPin6, LOW);
      param->updateAndReport(val);
      pref.putBool("Relay6", toggleState_6);
    }

  } else if(strcmp(device_name, deviceName_7) == 0) {
    
    Serial.printf("Switch value = %s\n", val.val.b? "true" : "false");

    if(strcmp(param_name, "Power") == 0) {
      Serial.printf("Received value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
      toggleState_7 = val.val.b;
      (toggleState_7 == false) ? digitalWrite(RelayPin7, HIGH) : digitalWrite(RelayPin7, LOW);
      param->updateAndReport(val);
      pref.putBool("Relay7", toggleState_7);
    }

  } else if(strcmp(device_name, deviceName_8) == 0) {
    
    Serial.printf("Switch value = %s\n", val.val.b? "true" : "false");

    if(strcmp(param_name, "Power") == 0) {
      Serial.printf("Received value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
      toggleState_8 = val.val.b;
      (toggleState_8 == false) ? digitalWrite(RelayPin8, HIGH) : digitalWrite(RelayPin8, LOW);
      param->updateAndReport(val);
      pref.putBool("Relay8", toggleState_8);
    }  
  } else if(strcmp(device_name, deviceName_9) == 0) {
    
    Serial.printf("Switch value = %s\n", val.val.b? "true" : "false");

    if(strcmp(param_name, "Power") == 0) {
      Serial.printf("Received value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
      toggleState_9 = val.val.b;
      (toggleState_9 == false) ? digitalWrite(RelayPin9, HIGH) : digitalWrite(RelayPin9, LOW);
      param->updateAndReport(val);
      pref.putBool("Relay9", toggleState_9);
    }

  } else if(strcmp(device_name, deviceName_10) == 0) {
    
    Serial.printf("Switch value = %s\n", val.val.b? "true" : "false");

    if(strcmp(param_name, "Power") == 0) {
      Serial.printf("Received value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
      toggleState_10 = val.val.b;
      (toggleState_10 == false) ? digitalWrite(RelayPin10, HIGH) : digitalWrite(RelayPin10, LOW);
      param->updateAndReport(val);
      pref.putBool("Relay10", toggleState_10);
    }

  } else if(strcmp(device_name, deviceName_11) == 0) {
    
    Serial.printf("Switch value = %s\n", val.val.b? "true" : "false");

    if(strcmp(param_name, "Power") == 0) {
      Serial.printf("Received value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
      toggleState_11 = val.val.b;
      (toggleState_11 == false) ? digitalWrite(RelayPin11, HIGH) : digitalWrite(RelayPin11, LOW);
      param->updateAndReport(val);
      pref.putBool("Relay11", toggleState_11);
    } 
     
  } else if(strcmp(device_name, deviceName_5) == 0) {
    
    Serial.printf("Lightbulb = %s\n", val.val.b? "true" : "false");
    
    if(strcmp(param_name, "Power") == 0) {
        Serial.printf("Received value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
      toggleState_12 = val.val.b;
      (toggleState_12 == false) ? digitalWrite(RelayPin12, HIGH) : digitalWrite(RelayPin12, LOW);
      param->updateAndReport(val);
      pref.putBool("Relay12", toggleState_12);
    }
    
  } else if(strcmp(device_name, deviceName_13) == 0) {
    
    Serial.printf("Switch value = %s\n", val.val.b? "true" : "false");

    if(strcmp(param_name, "Power") == 0) {
      Serial.printf("Received value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
      toggleState_13 = val.val.b;
      (toggleState_13 == false) ? digitalWrite(RelayPin13, HIGH) : digitalWrite(RelayPin13, LOW);
      param->updateAndReport(val);
      pref.putBool("Relay13", toggleState_13);
    }

  } else if(strcmp(device_name, deviceName_14) == 0) {
    
    Serial.printf("Switch value = %s\n", val.val.b? "true" : "false");

    if(strcmp(param_name, "Power") == 0) {
      Serial.printf("Received value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
      toggleState_14 = val.val.b;
      (toggleState_14 == false) ? digitalWrite(RelayPin14, HIGH) : digitalWrite(RelayPin14, LOW);
      param->updateAndReport(val);
      pref.putBool("Relay14", toggleState_14);
    }

  } else if(strcmp(device_name, deviceName_15) == 0) {
    
    Serial.printf("Switch value = %s\n", val.val.b? "true" : "false");

    if(strcmp(param_name, "Power") == 0) {
      Serial.printf("Received value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
      toggleState_15 = val.val.b;
      (toggleState_15 == false) ? digitalWrite(RelayPin15, HIGH) : digitalWrite(RelayPin15, LOW);
      param->updateAndReport(val);
      pref.putBool("Relay15", toggleState_15);
    }  
  } else if(strcmp(device_name, deviceName_16) == 0) {
    
    Serial.printf("Switch value = %s\n", val.val.b? "true" : "false");

    if(strcmp(param_name, "Power") == 0) {
      Serial.printf("Received value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
      toggleState_16 = val.val.b;
      (toggleState_16 == false) ? digitalWrite(RelayPin16, HIGH) : digitalWrite(RelayPin16, LOW);
      param->updateAndReport(val);
      pref.putBool("Relay16", toggleState_16);
    }
  }
}


void ir_remote(){
  if (irrecv.decode(&results)) {
      switch(results.value){
          case IR_Button_1:  
            digitalWrite(RelayPin1, toggleState_1);
            toggleState_1 = !toggleState_1;
            pref.putBool("Relay1", toggleState_1);
            my_switch1.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_1);
            delay(100);            
            break;
          case IR_Button_2:  
            digitalWrite(RelayPin2, toggleState_2);
            toggleState_2 = !toggleState_2;
            pref.putBool("Relay2", toggleState_2);
            my_switch2.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_2);
            delay(100);            
            break;
          case IR_Button_3:  
            digitalWrite(RelayPin3, toggleState_3);
            toggleState_3 = !toggleState_3;
            pref.putBool("Relay3", toggleState_3);
            my_switch3.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_3);
            delay(100);            
            break;
          case IR_Button_4:  
            digitalWrite(RelayPin4, toggleState_4);
            toggleState_4 = !toggleState_4;
            pref.putBool("Relay4", toggleState_4);
            my_switch4.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_4);
            delay(100);            
            break;
          case IR_Button_5:  
            digitalWrite(RelayPin5, toggleState_5);
            toggleState_5 = !toggleState_5;
            pref.putBool("Relay5", toggleState_5);
            my_switch5.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_5);
            delay(100);            
            break;
          case IR_Button_6:  
            digitalWrite(RelayPin6, toggleState_6);
            toggleState_6 = !toggleState_6;
            pref.putBool("Relay6", toggleState_6);
            my_switch6.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_6);
            delay(100);            
            break;
          case IR_Button_7:  
            digitalWrite(RelayPin7, toggleState_7);
            toggleState_7 = !toggleState_7;
            pref.putBool("Relay7", toggleState_7);
            my_switch7.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_7);
            delay(100);            
            break;
          case IR_Button_8:  
            digitalWrite(RelayPin8, toggleState_8);
            toggleState_8 = !toggleState_8;
            pref.putBool("Relay8", toggleState_8);
            my_switch8.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_8);
            delay(100);            
            break;
          case IR_Button_9:  
            digitalWrite(RelayPin9, toggleState_9);
            toggleState_9 = !toggleState_9;
            pref.putBool("Relay9", toggleState_9);
            my_switch9.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_9);
            delay(100);            
            break;
          case IR_Button_10:  
            digitalWrite(RelayPin10, toggleState_10);
            toggleState_10 = !toggleState_10;
            pref.putBool("Relay10", toggleState_10);
            my_switch10.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_10);
            delay(100);            
            break;
          case IR_Button_11:  
            digitalWrite(RelayPin11, toggleState_11);
            toggleState_11 = !toggleState_11;
            pref.putBool("Relay11", toggleState_11);
            my_switch11.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_11);
            delay(100);            
            break;
          case IR_Button_12:  
            digitalWrite(RelayPin12, toggleState_12);
            toggleState_12 = !toggleState_12;
            pref.putBool("Relay12", toggleState_12);
            my_switch12.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_12);
            delay(100);            
            break;
          case IR_Button_13:  
            digitalWrite(RelayPin13, toggleState_13);
            toggleState_13 = !toggleState_13;
            pref.putBool("Relay13", toggleState_13);
            my_switch13.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_13);
            delay(100);            
            break;
          case IR_Button_14:  
            digitalWrite(RelayPin14, toggleState_14);
            toggleState_14 = !toggleState_14;
            pref.putBool("Relay14", toggleState_14);
            my_switch14.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_14);
            delay(100);            
            break;
          case IR_Button_15:  
            digitalWrite(RelayPin15, toggleState_15);
            toggleState_15 = !toggleState_15;
            pref.putBool("Relay15", toggleState_15);
            my_switch15.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_15);
            delay(100);            
            break;
          case IR_Button_16:  
            digitalWrite(RelayPin16, toggleState_16);
            toggleState_16 = !toggleState_16;
            pref.putBool("Relay16", toggleState_16);
            my_switch16.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_16);
            delay(100);            
            break;
          case IR_All_Off:
            all_SwitchOff();  
            break;
          case IR_All_On:
            all_SwitchOn();  
            break;
          default : break;         
        }   
        //Serial.println(results.value, HEX);    
        irrecv.resume();   
  } 
}

void all_SwitchOff(){
  toggleState_1 = 0; digitalWrite(RelayPin1, HIGH); pref.putBool("Relay1", toggleState_1); my_switch1.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_1); delay(100);
  toggleState_2 = 0; digitalWrite(RelayPin2, HIGH); pref.putBool("Relay2", toggleState_2); my_switch2.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_2); delay(100);
  toggleState_3 = 0; digitalWrite(RelayPin3, HIGH); pref.putBool("Relay3", toggleState_3); my_switch3.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_3); delay(100);
  toggleState_4 = 0; digitalWrite(RelayPin4, HIGH); pref.putBool("Relay4", toggleState_4); my_switch4.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_4); delay(100);
  toggleState_5 = 0; digitalWrite(RelayPin5, HIGH); pref.putBool("Relay5", toggleState_5); my_switch5.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_5); delay(100);
  toggleState_6 = 0; digitalWrite(RelayPin6, HIGH); pref.putBool("Relay6", toggleState_6); my_switch6.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_6); delay(100);
  toggleState_7 = 0; digitalWrite(RelayPin7, HIGH); pref.putBool("Relay7", toggleState_7); my_switch7.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_7); delay(100);
  toggleState_8 = 0; digitalWrite(RelayPin8, HIGH); pref.putBool("Relay8", toggleState_8); my_switch8.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_8); delay(100);
  toggleState_9 = 0; digitalWrite(RelayPin9, HIGH); pref.putBool("Relay1", toggleState_9); my_switch1.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_9); delay(100);
  toggleState_10 = 0; digitalWrite(RelayPin10, HIGH); pref.putBool("Relay2", toggleState_10); my_switch2.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_10); delay(100);
  toggleState_11 = 0; digitalWrite(RelayPin11, HIGH); pref.putBool("Relay3", toggleState_11); my_switch3.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_11); delay(100);
  toggleState_12 = 0; digitalWrite(RelayPin12, HIGH); pref.putBool("Relay4", toggleState_12); my_switch4.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_12); delay(100);
  toggleState_13 = 0; digitalWrite(RelayPin13, HIGH); pref.putBool("Relay5", toggleState_13); my_switch5.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_13); delay(100);
  toggleState_14 = 0; digitalWrite(RelayPin14, HIGH); pref.putBool("Relay6", toggleState_14); my_switch6.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_14); delay(100);
  toggleState_15 = 0; digitalWrite(RelayPin15, HIGH); pref.putBool("Relay7", toggleState_15); my_switch7.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_15); delay(100);
  toggleState_16 = 0; digitalWrite(RelayPin16, HIGH); pref.putBool("Relay8", toggleState_16); my_switch8.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_16); delay(100);
}

void all_SwitchOn(){
  toggleState_1 = 1; digitalWrite(RelayPin1, LOW); pref.putBool("Relay1", toggleState_1); my_switch1.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_1); delay(100);
  toggleState_2 = 1; digitalWrite(RelayPin2, LOW); pref.putBool("Relay2", toggleState_2); my_switch2.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_2); delay(100);
  toggleState_3 = 1; digitalWrite(RelayPin3, LOW); pref.putBool("Relay3", toggleState_3); my_switch3.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_3); delay(100);
  toggleState_4 = 1; digitalWrite(RelayPin4, LOW); pref.putBool("Relay4", toggleState_4); my_switch4.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_4); delay(100);
  toggleState_5 = 1; digitalWrite(RelayPin5, LOW); pref.putBool("Relay5", toggleState_5); my_switch5.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_5); delay(100);
  toggleState_6 = 1; digitalWrite(RelayPin6, LOW); pref.putBool("Relay6", toggleState_6); my_switch6.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_6); delay(100);
  toggleState_7 = 1; digitalWrite(RelayPin7, LOW); pref.putBool("Relay7", toggleState_7); my_switch7.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_7); delay(100);
  toggleState_8 = 1; digitalWrite(RelayPin8, LOW); pref.putBool("Relay8", toggleState_8); my_switch8.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_8); delay(100);
  toggleState_9 = 1; digitalWrite(RelayPin9, LOW); pref.putBool("Relay1", toggleState_9); my_switch1.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_9); delay(100);
  toggleState_10 = 1; digitalWrite(RelayPin10, LOW); pref.putBool("Relay2", toggleState_10); my_switch2.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_10); delay(100);
  toggleState_11 = 1; digitalWrite(RelayPin11, LOW); pref.putBool("Relay3", toggleState_11); my_switch3.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_11); delay(100);
  toggleState_12 = 1; digitalWrite(RelayPin12, LOW); pref.putBool("Relay4", toggleState_12); my_switch4.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_12); delay(100);
  toggleState_13 = 1; digitalWrite(RelayPin13, LOW); pref.putBool("Relay5", toggleState_13); my_switch5.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_13); delay(100);
  toggleState_14 = 1; digitalWrite(RelayPin14, LOW); pref.putBool("Relay6", toggleState_14); my_switch6.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_14); delay(100);
  toggleState_15 = 1; digitalWrite(RelayPin15, LOW); pref.putBool("Relay7", toggleState_15); my_switch7.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_15); delay(100);
  toggleState_16 = 1; digitalWrite(RelayPin16, LOW); pref.putBool("Relay8", toggleState_16); my_switch8.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_16); delay(100);
}



void getRelayState()
{
  toggleState_1 = pref.getBool("Relay1", 0);
  digitalWrite(RelayPin1, !toggleState_1); 
  my_switch1.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_1);
  delay(200);
  toggleState_2 = pref.getBool("Relay2", 0);
  digitalWrite(RelayPin2, !toggleState_2); 
  my_switch2.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_2);
  delay(200);
  toggleState_3 = pref.getBool("Relay3", 0);
  digitalWrite(RelayPin3, !toggleState_3); 
  my_switch3.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_3);
  delay(200);
  toggleState_4 = pref.getBool("Relay4", 0);
  digitalWrite(RelayPin4, !toggleState_4); 
  my_switch4.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_4);
  delay(200);
  toggleState_5 = pref.getBool("Relay5", 0);
  digitalWrite(RelayPin5, !toggleState_5); 
  my_switch5.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_5);
  delay(200);
  toggleState_6 = pref.getBool("Relay6", 0);
  digitalWrite(RelayPin6, !toggleState_6); 
  my_switch6.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_6);
  delay(200);
  toggleState_7 = pref.getBool("Relay7", 0);
  digitalWrite(RelayPin7, !toggleState_7); 
  my_switch7.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_7);
  delay(200);
  toggleState_8 = pref.getBool("Relay8", 0);
  digitalWrite(RelayPin8, !toggleState_8); 
  my_switch8.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_8);
  delay(200);
  toggleState_9 = pref.getBool("Relay1", 0);
  digitalWrite(RelayPin9, !toggleState_9); 
  my_switch1.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_9);
  delay(200);
  toggleState_10 = pref.getBool("Relay2", 0);
  digitalWrite(RelayPin10, !toggleState_10); 
  my_switch2.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_10);
  delay(200);
  toggleState_11 = pref.getBool("Relay3", 0);
  digitalWrite(RelayPin11, !toggleState_11); 
  my_switch3.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_11);
  delay(200);
  toggleState_12 = pref.getBool("Relay4", 0);
  digitalWrite(RelayPin12, !toggleState_12); 
  my_switch4.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_12);
  delay(200);
  toggleState_13 = pref.getBool("Relay5", 0);
  digitalWrite(RelayPin13, !toggleState_13); 
  my_switch5.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_13);
  delay(200);
  toggleState_14 = pref.getBool("Relay6", 0);
  digitalWrite(RelayPin14, !toggleState_14); 
  my_switch6.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_14);
  delay(200);
  toggleState_15 = pref.getBool("Relay7", 0);
  digitalWrite(RelayPin15, !toggleState_15); 
  my_switch7.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_15);
  delay(200);
  toggleState_16 = pref.getBool("Relay8", 0);
  digitalWrite(RelayPin16, !toggleState_16); 
  my_switch8.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_16);
  delay(200);
}  

void setup()
{   
    Serial.begin(115200);
    pref.begin("Relay_State", false);
    
    // Set the Relays GPIOs as output mode
    pinMode(RelayPin1, OUTPUT);
    pinMode(RelayPin2, OUTPUT);
    pinMode(RelayPin3, OUTPUT);
    pinMode(RelayPin4, OUTPUT);
    pinMode(RelayPin5, OUTPUT);
    pinMode(RelayPin6, OUTPUT);
    pinMode(RelayPin7, OUTPUT);
    pinMode(RelayPin8, OUTPUT);  
    pinMode(RelayPin9, OUTPUT);
    pinMode(RelayPin10, OUTPUT);
    pinMode(RelayPin11, OUTPUT);
    pinMode(RelayPin12, OUTPUT);
    pinMode(RelayPin13, OUTPUT);
    pinMode(RelayPin14, OUTPUT);
    pinMode(RelayPin15, OUTPUT);
    pinMode(RelayPin16, OUTPUT); 
    pinMode(wifiLed, OUTPUT);

    // Write to the GPIOs the default state on booting
    digitalWrite(RelayPin1, !toggleState_1);
    digitalWrite(RelayPin2, !toggleState_2);
    digitalWrite(RelayPin3, !toggleState_3);
    digitalWrite(RelayPin4, !toggleState_4);
    digitalWrite(RelayPin5, !toggleState_5);
    digitalWrite(RelayPin6, !toggleState_6);
    digitalWrite(RelayPin7, !toggleState_7);
    digitalWrite(RelayPin8, !toggleState_8);
    digitalWrite(RelayPin9, !toggleState_9);
    digitalWrite(RelayPin10, !toggleState_10);
    digitalWrite(RelayPin11, !toggleState_11);
    digitalWrite(RelayPin12, !toggleState_12);
    digitalWrite(RelayPin13, !toggleState_13);
    digitalWrite(RelayPin14, !toggleState_14);
    digitalWrite(RelayPin15, !toggleState_15);
    digitalWrite(RelayPin16, !toggleState_16);
    digitalWrite(wifiLed, LOW);

    irrecv.enableIRIn(); // Enabling IR sensor

    Node my_node;    
    my_node = RMaker.initNode(nodeName);

    //Standard switch device
    my_switch1.addCb(write_callback);
    my_switch2.addCb(write_callback);
    my_switch3.addCb(write_callback);
    my_switch4.addCb(write_callback);
    my_switch5.addCb(write_callback);
    my_switch6.addCb(write_callback);
    my_switch7.addCb(write_callback);
    my_switch8.addCb(write_callback);
    my_switch9.addCb(write_callback);
    my_switch10.addCb(write_callback);
    my_switch11.addCb(write_callback);
    my_switch12.addCb(write_callback);
    my_switch13.addCb(write_callback);
    my_switch14.addCb(write_callback);
    my_switch15.addCb(write_callback);
    my_switch16.addCb(write_callback);


    //Add switch device to the node   
    my_node.addDevice(my_switch1);
    my_node.addDevice(my_switch2);
    my_node.addDevice(my_switch3);
    my_node.addDevice(my_switch4);
    my_node.addDevice(my_switch5);
    my_node.addDevice(my_switch6);
    my_node.addDevice(my_switch7);
    my_node.addDevice(my_switch8);
    my_node.addDevice(my_switch9);
    my_node.addDevice(my_switch10);
    my_node.addDevice(my_switch11);
    my_node.addDevice(my_switch12);
    my_node.addDevice(my_switch13);
    my_node.addDevice(my_switch14);
    my_node.addDevice(my_switch15);
    my_node.addDevice(my_switch16);

    //This is optional 
    RMaker.enableOTA(OTA_USING_PARAMS);
    //If you want to enable scheduling, set time zone for your region using setTimeZone(). 
    //The list of available values are provided here https://rainmaker.espressif.com/docs/time-service.html
    // RMaker.setTimeZone("Asia/Shanghai");
    // Alternatively, enable the Timezone service and let the phone apps set the appropriate timezone
    RMaker.enableTZService();
    RMaker.enableSchedule();

    //Service Name
    for(int i=0; i<17; i=i+8) {
      espChipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
    }

    Serial.printf("\nChip ID:  %d Service Name: %s\n", espChipId, service_name);

    Serial.printf("\nStarting ESP-RainMaker\n");
    RMaker.start();

    WiFi.onEvent(sysProvEvent);
#if CONFIG_IDF_TARGET_ESP32
    WiFiProv.beginProvision(WIFI_PROV_SCHEME_BLE, WIFI_PROV_SCHEME_HANDLER_FREE_BTDM, WIFI_PROV_SECURITY_1, pop, service_name);
#else
    WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE, WIFI_PROV_SECURITY_1, pop, service_name);
#endif

    getRelayState(); // Get the last state of Relays
    



}

void loop()
{
    // Read GPIO0 (external button to reset device
    if(digitalRead(gpio_reset) == LOW) { //Push button pressed
        Serial.printf("Reset Button Pressed!\n");
        // Key debounce handling
        delay(100);
        int startTime = millis();
        while(digitalRead(gpio_reset) == LOW) delay(50);
        int endTime = millis();

        if ((endTime - startTime) > 10000) {
          // If key pressed for more than 10secs, reset all
          Serial.printf("Reset to factory.\n");
          RMakerFactoryReset(2);
        } else if ((endTime - startTime) > 3000) {
          Serial.printf("Reset Wi-Fi.\n");
          // If key pressed for more than 3secs, but less than 10, reset Wi-Fi
          RMakerWiFiReset(2);
        }
    }
    delay(100);

    if (WiFi.status() != WL_CONNECTED)
    {
      //Serial.println("WiFi Not Connected");
      digitalWrite(wifiLed, false);
    }
    else
    {
      //Serial.println("WiFi Connected");
      digitalWrite(wifiLed, true);
    }

    ir_remote(); //IR remote Control
}

??

Is toggleState initialized correctly? Is this code what you want?

Hello iystreem186

I did made a small code review and I´ve found alot of code dublicates.

Do you have experience with programming in C++?

The task can easily be realised with an object.
A structured array contains all the information, such as the pin addresses for the I/O devices, as well as the information for the timing.
A single service takes care of this information and initiates the intended action.
The structured array makes the sketch scalable until all I/O pins are used up without having to adapt the code for the service.
It is cool stuff, isn´t it?

1 Like

Hi!

I'm playing with OP code to learn something.

Following the suggestion of @paulpaulson I did in this way:

#define NUM_RELAYS 16
#define IR_All_Off 0xA90
#define IR_All_On 0x5D0

struct INFOS
{
  const char deviceName[8];
  const uint8_t relayPin;
  bool relayState;
  uint16_t irCode;
};

INFOS info[NUM_RELAYS] =
{
  {"Relay1", 4, LOW, 0x10},
  {"Relay2", 5, LOW, 0x810},
  {"Relay3", 18, LOW, 0x410},
  {"Relay4", 19, LOW, 0xC10},
  {"Relay5", 21, LOW, 0x210},
  {"Relay6", 22, LOW, 0xA10},
  {"Relay7", 23, LOW, 0x610},
  {"Relay8", 25, LOW, 0xE10},
  {"Relay9", 26, LOW, 0x110},
  {"Relay10", 27, LOW, 0xFD0},
  {"Relay11", 32, LOW, 0x910},
  {"Relay12", 33, LOW, 0xDD0},
  {"Relay13", 13, LOW, 0x490},
  {"Relay14", 12, LOW, 0x90},
  {"Relay15", 14, LOW, 0xC90},
  {"Relay16", 15, LOW, 0x5D0}
};

Now how I can put this objects in an array?

static Switch my_switch1(deviceName_1, &RelayPin1);

my_switch1.addCb(write_callback);

Node my_node;
my_node = RMaker.initNode(nodeName);
my_node.addDevice(my_switch1);

Initially I was thinking I could pass infos to first object in this way:

static Switch my_switch[NUM_RELAYS];
my_switch[0](info[0].deviceName, &info[0].relayPin);

But I have this compiling errors:

For info[0].deviceName:
 a value of type "const char *" cannot be used to initialize an entity of type "Switch [0]"
For &info[0].relayPin:
too many initializer values
expression list treated as compound expression in initializer [-fpermissive]

Thanks in advance.
Best regards.

Hi, @iystreem186
Did you write your code in stages?
Have you bits of code that check each piece of hardware INDIVIDUALLY and proves you have the control you need?

You have a lot of code there to suddenly find the response from the relays you have.

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:

Hi!

Here my version of OP code.

There's a compiling error that I don't know how to solve.

If someone can help me I will be grateful.

src/main.cpp: In function 'void setup()':
src/main.cpp:179:62: error: expression list treated as compound expression in initializer [-fpermissive]
     Switch my_switch[i](info[i].deviceName, &info[i].relayPin);
                                                              ^
src/main.cpp:179:62: error: array must be initialized with a brace-enclosed initializer
#include "RMaker.h"
#include "WiFi.h"
#include "WiFiProv.h"
#include <IRremote.h>
#include <Preferences.h>
Preferences pref;

const char *service_name = "PROV_1234";
const char *pop = "1234";

// define the Chip Id
uint32_t espChipId = 0;

// define the Node Name
char nodeName[] = "ESP32_Relay_8B";

#define NUM_RELAYS 16
#define IR_All_Off 0xA90
#define IR_All_On 0x5D0

struct INFOS
{
  const char deviceName[8];
  const uint8_t relayPin;
  bool relayState;
  uint16_t irCode;
};

INFOS info[NUM_RELAYS] =
{
  {"Relay1", 4, LOW, 0x10},
  {"Relay2", 5, LOW, 0x810},
  {"Relay3", 18, LOW, 0x410},
  {"Relay4", 19, LOW, 0xC10},
  {"Relay5", 21, LOW, 0x210},
  {"Relay6", 22, LOW, 0xA10},
  {"Relay7", 23, LOW, 0x610},
  {"Relay8", 25, LOW, 0xE10},
  {"Relay9", 26, LOW, 0x110},
  {"Relay10", 27, LOW, 0xFD0},
  {"Relay11", 32, LOW, 0x910},
  {"Relay12", 33, LOW, 0xDD0},
  {"Relay13", 13, LOW, 0x490},
  {"Relay14", 12, LOW, 0x90},
  {"Relay15", 14, LOW, 0xC90},
  {"Relay16", 15, LOW, 0x5D0}
};


static uint8_t wifiLedPin      = 2; // D2
static uint8_t gpio_reset   = 0;    // Press BOOT for reset WiFi
int IR_RECV_PIN  = 35;              // D35 (IR receiver pin)

IRrecv irrecv(IR_RECV_PIN);
decode_results results;

static Switch my_switch[NUM_RELAYS];

void all_SwitchOn();
void all_SwitchOff();

void sysProvEvent(arduino_event_t *sys_event)
{
  switch (sys_event->event_id)
  {
    case ARDUINO_EVENT_PROV_START:
      #if CONFIG_IDF_TARGET_ESP32
        Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on BLE\n", service_name, pop);
        printQR(service_name, pop, "ble");
      #else
        Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on SoftAP\n", service_name, pop);
        printQR(service_name, pop, "softap");
      #endif
      break;
    case ARDUINO_EVENT_WIFI_STA_CONNECTED:
      Serial.printf("\nConnected to Wi-Fi!\n");
      digitalWrite(wifiLedPin, true);
      break;
  }
}

void write_callback(Device *device, Param *param, const param_val_t val, void *priv_data, write_ctx_t *ctx)
{
  const char *device_name = device->getDeviceName();
  const char *param_name = param->getParamName();

  for(byte i = 0; i < NUM_RELAYS; i++)
  {
    if(strcmp(device_name, info[i].deviceName) == 0)
    {

      Serial.printf("Lightbulb = %s\n", val.val.b? "true" : "false");

      if(strcmp(param_name, "Power") == 0)
      {
        Serial.printf("Received value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
        info[i].relayState = val.val.b;
        digitalWrite(info[i].relayPin, info[i].relayState);
        param->updateAndReport(val);
        pref.putBool(info[i].deviceName, info[i].relayState);
      }
    }
  }
}

void ir_remote()
{
  if (irrecv.decode())
  {
    for(byte i = 0; i < NUM_RELAYS; i++)
    {
      if(irrecv.decodedIRData.command == info[i].irCode)
      {
        info[i].relayState = !info[i].relayState;
        digitalWrite(info[i].relayPin, info[i].relayState);
        pref.putBool(info[i].deviceName, info[i].relayState);
        my_switch[i].updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, info[i].relayState);
        delay(100);
        // Serial.println(results.value, HEX);
      }
    }
    if(irrecv.decodedIRData.command == IR_All_Off)
    {
      all_SwitchOff();
    }
    else if (irrecv.decodedIRData.command == IR_All_On)
    {
      all_SwitchOn();
    }
    irrecv.resume();
  }
}

void all_SwitchOff()
{
  for(byte i = 0; i < NUM_RELAYS; i++)
  {
    info[i].relayState = LOW;
    digitalWrite(info[i].relayPin, info[i].relayState);
    pref.putBool(info[i].deviceName, info[i].relayState);
    my_switch[i].updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, info[i].relayState);
  }
}

void all_SwitchOn()
{
  for(byte i = 0; i < NUM_RELAYS; i++)
  {
    info[i].relayState = HIGH;
    digitalWrite(info[i].relayPin, info[i].relayState);
    pref.putBool(info[i].deviceName, info[i].relayState);
    my_switch[i].updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, info[i].relayState);
  }
}

void getRelayState()
{
  for(byte i = 0; i < NUM_RELAYS; i++)
  {
    info[i].relayState = pref.getBool(info[i].deviceName, 0);
    digitalWrite(info[i].relayPin, info[i].relayState);
    my_switch[i].updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, info[i].relayState);
  }
  delay(200);
}

void setup()
{
  Serial.begin(115200);
  pref.begin("Relay_State", false);

  Node my_node[NUM_RELAYS];

  for(byte i = 0; i < NUM_RELAYS; i++)
  {
    pinMode(info[i].relayPin, OUTPUT);
    digitalWrite(info[i].relayPin, info[i].relayState);

    Switch my_switch[i](info[i].deviceName, &info[i].relayPin);
    my_node[i] = RMaker.initNode(nodeName);
    my_switch[i].addCb(write_callback);
    my_node[i].addDevice(my_switch[i]);

  }

  pinMode(wifiLedPin, OUTPUT);
  digitalWrite(wifiLedPin, LOW);

  irrecv.enableIRIn();   // Enabling IR sensor

  // This is optional
  RMaker.enableOTA(OTA_USING_PARAMS);
  // If you want to enable scheduling, set time zone for your region using setTimeZone().
  // The list of available values are provided here https://rainmaker.espressif.com/docs/time-service.html
  // RMaker.setTimeZone("Asia/Shanghai");
  // Alternatively, enable the Timezone service and let the phone apps set the appropriate timezone
  RMaker.enableTZService();
  RMaker.enableSchedule();

  // Service Name
  for(int i = 0; i < 17; i = i + 8)
  {
    espChipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
  }

  Serial.printf("\nChip ID:  %d Service Name: %s\n", espChipId, service_name);

  Serial.printf("\nStarting ESP-RainMaker\n");
  RMaker.start();

  WiFi.onEvent(sysProvEvent);
  #if CONFIG_IDF_TARGET_ESP32
    WiFiProv.beginProvision(WIFI_PROV_SCHEME_BLE, WIFI_PROV_SCHEME_HANDLER_FREE_BTDM, WIFI_PROV_SECURITY_1, pop, service_name);
  #else
    WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE, WIFI_PROV_SECURITY_1, pop, service_name);
  #endif

  getRelayState();   // Get the last state of Relays
}

void loop()
{
  // Read GPIO0 (external button to reset device
  if(digitalRead(gpio_reset) == LOW)     // Push button pressed
  {
    Serial.printf("Reset Button Pressed!\n");
    // Key debounce handling
    delay(100);
    int startTime = millis();
    while(digitalRead(gpio_reset) == LOW)
    {
      delay(50);
    }
    int endTime = millis();

    if ((endTime - startTime) > 10000)
    {
      // If key pressed for more than 10secs, reset all
      Serial.printf("Reset to factory.\n");
      RMakerFactoryReset(2);
    }
    else if ((endTime - startTime) > 3000)
    {
      Serial.printf("Reset Wi-Fi.\n");
      // If key pressed for more than 3secs, but less than 10, reset Wi-Fi
      RMakerWiFiReset(2);
    }
  }
  delay(100);

  if (WiFi.status() != WL_CONNECTED)
  {
    // Serial.println("WiFi Not Connected");
    digitalWrite(wifiLedPin, false);
  }
  else
  {
    // Serial.println("WiFi Connected");
    digitalWrite(wifiLedPin, true);
  }

  ir_remote();   // IR remote Control
}

Best regards.

i dont think so

to be honest I am not good when it comes to c++

thanks for the suggestion

Hi @J-M-L!

Please could you help me fix this compiling error?

Thanks in advance.

Best regards.

the statement definitely cannot start with Switch as this would be a new definition of a variable

usually when you don't initialise the instance (call the constructor) at definition time you would have a begin() or init() method where you can provide the necessary information. Something like

my_switch[i].init(info[i].deviceName, &info[i].relayPin);

where is the Switch class defined ? can you create switch instances without passing anything as you do here

static Switch my_switch[NUM_RELAYS];

and have a method to pass the name and pin later ?

otherwise you have to create a new instance and copy

my_switch[i] = Switch(info[i].deviceName, &info[i].relayPin);

(given the compiler did not complain for the array, I would try first the latter option)

Thanks for your attention!

I don't have experience with this library/framework I'm just trying help OP.

I'm following examples but all I can find is like OP code. There's no example using array.

This class is defined here in this way:

class Switch : public Device
{
    public:
        Switch()
        {
            standardSwitchDevice("Switch", NULL, true);
        }
        Switch(const char *dev_name, void *priv_data = NULL, bool power = true)
        {
            standardSwitchDevice(dev_name, priv_data, power);
        }
        void standardSwitchDevice(const char *dev_name, void *priv_data, bool power)
        {
            esp_rmaker_device_t *dev_handle = esp_rmaker_switch_device_create(dev_name, priv_data, power);
            setDeviceHandle(dev_handle);
            if(dev_handle == NULL){
                log_e("Switch device not created");
            }   
        } 
};

Removing Switch from setup the error changes to:

rc/main.cpp: In function 'void setup()':
src/main.cpp:179:55: error: no match for call to '(Switch) (const char [8], const uint8_t*)'
     my_switch[i](info[i].deviceName, &info[i].relayPin);

OK - so there is a constructor that does take no param and initialise the Switch with default parameters ("Switch", NULL, true)

just replace the buggy line by this

my_switch[i] = Switch(info[i].deviceName, &info[i].relayPin);

and you should be good to go

Unfortunately no. :neutral_face:

/rainMaker/rainMaker.ino: In function 'void setup()':
/rainMaker/rainMaker.ino:179:47: error: invalid conversion from 'const void*' to 'void*' [-fpermissive]
     my_switch[i] = Switch(info[i].deviceName, &info[i].relayPin);
                                               ^~~~~~~~~~~~~~~~~
/home/fernandogarcia/.arduino15/packages/esp32/hardware/esp32/2.0.2/libraries/RainMaker/src/RMakerDevice.h:77:44: note:   initializing argument 2 of 'Switch::Switch(const char*, void*, bool)'
Switch(const char *dev_name, void *priv_data = NULL, bool power = true)
                                            ^
exit status 1

Compilation error: invalid conversion from 'const void*' to 'void*' [-fpermissive]

I had assumed the parameters were right

change

struct INFOS
{
  const char deviceName[8];
  const uint8_t relayPin;
  bool relayState;
  uint16_t irCode;
};

into

struct INFOS
{
  const char * deviceName;
  const uint8_t relayPin;
  bool relayState;
  uint16_t irCode;
};

as you don't need a modifiable deviceName and you'll get directly a const char pointer

my_switch[i] = Switch(info[i].deviceName, &(info[i].relayPin));

You INFOS structure is probably redundant with the Switch class, you don't need to keep the name and PIN number in both and I assume the class maintains the switch state as well...

You could want to subclass the Switch class and and the irCode as a new instance variable

on second thoughts I would rewrite that Switch class thingy, it's weird on how you need to duplicate things

Same problem.

/rainMaker/rainMaker.ino: In function 'void setup()':
rainMaker/rainMaker.ino:179:47: error: invalid conversion from 'const void*' to 'void*' [-fpermissive]
   delay(200);
                                               ^                  
In file included from /home/fernandogarcia/.arduino15/packages/esp32/hardware/esp32/2.0.2/libraries/RainMaker/src/RMakerNode.h:4,
from /home/fernandogarcia/.arduino15/packages/esp32/hardware/esp32/2.0.2/libraries/RainMaker/src/RMaker.h:5,
from /rainMaker/rainMaker.ino:1:
/home/fernandogarcia/.arduino15/packages/esp32/hardware/esp32/2.0.2/libraries/RainMaker/src/RMakerDevice.h:77:44: note:   initializing argument 2 of 'Switch::Switch(const char*, void*, bool)'
Switch(const char *dev_name, void *priv_data = NULL, bool power = true)

on second thoughts I would rewrite that Switch class thingy, it's weird on how you need to duplicate things

No way to me, I'm completely lost. A pull request to up stream could be welcome. :slight_smile:

I tried many things following your edited advice but with no luck.

Thanks for your time.

Looking for this example it's declared in similar way but I don't know why it doesn't work with array.

static Switch my_switch;
static int gpio_switch = 16;

void setup()
{
  my_switch = Switch("Switch", &gpio_switch);
}

this might be because of

try removing the const

It did the trick! Thank you for your help.

Now the problem is make the rainMaker work even with basic example.

I have lots of errors.

E (575) esp_rmaker_device: Failed to allocate me����y for Device Switch
[     1][E][RMakerDevice.h:100] standardSwitchDevice(): Switch device not created
E (19) esp_rmaker_fctry: NVS Flash init failed
E (19) esp_rmaker_core: Failed to initialise storage
[    24][E][RMaker.cpp:75] initNode(): Node init failed
E (21) esp_rmaker_device: Failed to allocate memory for Device Switch
[    33][E][RMakerDevice.h:100] standardSwitchDevice(): Switch device not created
E (35) esp_rmaker_device: Device handle cannot be NULL
[    45][E][RMakerDevice.cpp:48] addCb(): Callback register error
E (45) esp_rmaker_node: Node or Device/Service handle cannot be NULL.
[    57][E][RMakerNode.cpp:10] addDevice(): Device was not added to the Node
E (58) esp_rmaker_device: Failed to allocate memory for Service Time
E (65) esp_rmaker_time_service: Failed to create Time Service
[    75][E][RMaker.cpp:131] enableTZService(): Timezone service enable failed
E (77) esp_rmaker_schedule: Couldn't allocate schedule_priv_data
[    88][E][RMaker.cpp:122] enableSchedule(): Schedule enable failed
E (89) esp_rmaker_scenes: Couldn't allocate scenes_priv_data
[    99][E][RMaker.cpp:154] enableScenes(): Scenes enable failed

@iystreem186 can you try the code below?

#include "RMaker.h"
#include "WiFi.h"
#include "WiFiProv.h"
#include <IRremote.h>
#include <Preferences.h>
Preferences pref;

const char *service_name = "PROV_1234";
const char *pop = "1234";

// define the Chip Id
uint32_t espChipId = 0;

// define the Node Name
char nodeName[] = "ESP32_Relay_16";

#define NUM_RELAYS 16
#define IR_All_Off 0xA90
#define IR_All_On 0x5D0

struct INFOS
{
  const char * deviceName;
  uint8_t relayPin;
  bool relayState;
  uint16_t irCode;
};

INFOS info[NUM_RELAYS] =
{
  {"Relay1", 4, LOW, 0x10},
  {"Relay2", 5, LOW, 0x810},
  {"Relay3", 18, LOW, 0x410},
  {"Relay4", 19, LOW, 0xC10},
  {"Relay5", 21, LOW, 0x210},
  {"Relay6", 22, LOW, 0xA10},
  {"Relay7", 23, LOW, 0x610},
  {"Relay8", 25, LOW, 0xE10},
  {"Relay9", 26, LOW, 0x110},
  {"Relay10", 27, LOW, 0xFD0},
  {"Relay11", 32, LOW, 0x910},
  {"Relay12", 33, LOW, 0xDD0},
  {"Relay13", 13, LOW, 0x490},
  {"Relay14", 12, LOW, 0x90},
  {"Relay15", 14, LOW, 0xC90},
  {"Relay16", 15, LOW, 0x5D0}
};


static uint8_t wifiLedPin      = 2; // D2
static uint8_t gpio_reset   = 0;    // Press BOOT for reset WiFi
int IR_RECV_PIN  = 35;              // D35 (IR receiver pin)

IRrecv irrecv(IR_RECV_PIN);
decode_results results;

static Switch my_switch[NUM_RELAYS];

void all_SwitchOn();
void all_SwitchOff();

void sysProvEvent(arduino_event_t *sys_event)
{
  switch (sys_event->event_id)
  {
    case ARDUINO_EVENT_PROV_START:
      #if CONFIG_IDF_TARGET_ESP32
        Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on BLE\n", service_name, pop);
        printQR(service_name, pop, "ble");
      #else
        Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on SoftAP\n", service_name, pop);
        printQR(service_name, pop, "softap");
      #endif
      break;
    case ARDUINO_EVENT_WIFI_STA_CONNECTED:
      Serial.printf("\nConnected to Wi-Fi!\n");
      digitalWrite(wifiLedPin, true);
      break;
  }
}

void write_callback(Device *device, Param *param, const param_val_t val, void *priv_data, write_ctx_t *ctx)
{
  const char *device_name = device->getDeviceName();
  const char *param_name = param->getParamName();

  for(byte i = 0; i < NUM_RELAYS; i++)
  {
    if(strcmp(device_name, info[i].deviceName) == 0)
    {

      Serial.printf("Lightbulb = %s\n", val.val.b? "true" : "false");

      if(strcmp(param_name, "Power") == 0)
      {
        Serial.printf("Received value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
        info[i].relayState = val.val.b;
        digitalWrite(info[i].relayPin, info[i].relayState);
        param->updateAndReport(val);
        pref.putBool(info[i].deviceName, info[i].relayState);
      }
    }
  }
}

void ir_remote()
{
  if (irrecv.decode())
  {
    for(byte i = 0; i < NUM_RELAYS; i++)
    {
      if(irrecv.decodedIRData.command == info[i].irCode)
      {
        info[i].relayState = !info[i].relayState;
        digitalWrite(info[i].relayPin, info[i].relayState);
        pref.putBool(info[i].deviceName, info[i].relayState);
        my_switch[i].updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, info[i].relayState);
        delay(100);
        // Serial.println(results.value, HEX);
      }
    }
    if(irrecv.decodedIRData.command == IR_All_Off)
    {
      all_SwitchOff();
    }
    else if (irrecv.decodedIRData.command == IR_All_On)
    {
      all_SwitchOn();
    }
    irrecv.resume();
  }
}

void all_SwitchOff()
{
  for(byte i = 0; i < NUM_RELAYS; i++)
  {
    info[i].relayState = LOW;
    digitalWrite(info[i].relayPin, info[i].relayState);
    pref.putBool(info[i].deviceName, info[i].relayState);
    my_switch[i].updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, info[i].relayState);
  }
}

void all_SwitchOn()
{
  for(byte i = 0; i < NUM_RELAYS; i++)
  {
    info[i].relayState = HIGH;
    digitalWrite(info[i].relayPin, info[i].relayState);
    pref.putBool(info[i].deviceName, info[i].relayState);
    my_switch[i].updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, info[i].relayState);
  }
}

void getRelayState()
{
  for(byte i = 0; i < NUM_RELAYS; i++)
  {
    info[i].relayState = pref.getBool(info[i].deviceName, 0);
    digitalWrite(info[i].relayPin, info[i].relayState);
    my_switch[i].updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, info[i].relayState);
  }
  delay(200);
}

void setup()
{
  Serial.begin(115200);

  Node my_node;
  my_node = RMaker.initNode(nodeName);

  for(byte i = 0; i < NUM_RELAYS; i++)
  {
    pinMode(info[i].relayPin, OUTPUT);
    digitalWrite(info[i].relayPin, info[i].relayState);

    my_switch[i] = Switch(info[i].deviceName, &info[i].relayPin);
    my_switch[i].addCb(write_callback);
    my_node.addDevice(my_switch[i]);
  }

  // This is optional
  RMaker.enableOTA(OTA_USING_PARAMS);
  // If you want to enable scheduling, set time zone for your region using setTimeZone().
  // The list of available values are provided here https://rainmaker.espressif.com/docs/time-service.html
  // RMaker.setTimeZone("Asia/Shanghai");
  // Alternatively, enable the Timezone service and let the phone apps set the appropriate timezone
  //RMaker.setTimeZone("America/Sao_Paulo");
  RMaker.enableTZService();
  RMaker.enableSchedule();
  //RMaker.enableScenes();
  RMaker.start();

  WiFi.onEvent(sysProvEvent);
  #if CONFIG_IDF_TARGET_ESP32
    WiFiProv.beginProvision(WIFI_PROV_SCHEME_BLE, WIFI_PROV_SCHEME_HANDLER_FREE_BTDM, WIFI_PROV_SECURITY_1, pop, service_name);
  #else
    WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE, WIFI_PROV_SECURITY_1, pop, service_name);
  #endif

  pinMode(wifiLedPin, OUTPUT);
  digitalWrite(wifiLedPin, LOW);

  irrecv.enableIRIn();   // Enabling IR sensor
  
  // Service Name
  for(int i = 0; i < 17; i = i + 8)
  {
    espChipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
  }

  Serial.printf("\nChip ID:  %d Service Name: %s\n", espChipId, service_name);
  
  getRelayState();   // Get the last state of Relays
}

void loop()
{
  // Read GPIO0 (external button to reset device
  if(digitalRead(gpio_reset) == LOW)     // Push button pressed
  {
    Serial.printf("Reset Button Pressed!\n");
    // Key debounce handling
    delay(100);
    int startTime = millis();
    while(digitalRead(gpio_reset) == LOW)
    {
      delay(50);
    }
    int endTime = millis();

    if ((endTime - startTime) > 10000)
    {
      // If key pressed for more than 10secs, reset all
      Serial.printf("Reset to factory.\n");
      RMakerFactoryReset(2);
    }
    else if ((endTime - startTime) > 3000)
    {
      Serial.printf("Reset Wi-Fi.\n");
      // If key pressed for more than 3secs, but less than 10, reset Wi-Fi
      RMakerWiFiReset(2);
    }
  }
  delay(100);

  if (WiFi.status() != WL_CONNECTED)
  {
    // Serial.println("WiFi Not Connected");
    digitalWrite(wifiLedPin, false);
  }
  else
  {
    // Serial.println("WiFi Connected");
    digitalWrite(wifiLedPin, true);
  }

  ir_remote();   // IR remote Control
}