espressif / esp-rainmaker

ESP RainMaker Agent for firmware development
Apache License 2.0
431 stars 145 forks source link

Many difficulties to use RainMaker with basic examples (MEGH-4382) #247

Closed FernandoGarcia closed 1 year ago

FernandoGarcia commented 1 year ago

Answers checklist.

General issue report

Hi!

I have found many difficulties to make RainMaker APP (V 2.10.1) connect to an ESP32-Wroover IE running the RMakerSwitch and RMakerSonoffDualR3 examples available in Arduino esp32 core 2.0.6.

Using a Galaxy J7 with Android 6.0.1 and switch example. Scan without reset immediately before recording and connection via BLE with reset in the middle:

https://user-images.githubusercontent.com/2778501/221967175-ac8aaec5-d370-4348-8736-c4371d15c180.mp4

I will add more information later.

Best regards

FernandoGarcia commented 1 year ago

Galaxy Tab A8 with android 13 and RainMaker App V2.10.1 and ESP332 with switch example and Arduino ESP32 core 2.0.6

https://user-images.githubusercontent.com/2778501/221997649-a1fffaf4-a74e-447b-b308-ae8fba146d8f.mp4

Here the QR code scan doesn't worked. The WiFi scan when connected through BLE neither.

Placing the SSD and password manually in this video doesn't worked and I was getting the error 201 on serial monitor.

After watch the video above I have noticed an extra space at the end of SSID name and after remove the extra space it worked.

JohnMacrae commented 1 year ago

Yup! The extra space makes all the difference. I discussed this in some early videos https://youtube.com/playlist?list=PL4Um4E3Og2S8It9Dyhdvf3ScvuTA_Tp-i

Hope they help reduce your frustration going forward 😊

On Tue, 28 Feb 2023 at 17:44, Fernando Garcia @.***> wrote:

Galaxy Tab A8 with android 13 and RainMaker App V2.10.1 and ESP332 with switch example and Arduino ESP32 core 2.0.6

https://user-images.githubusercontent.com/2778501/221997649-a1fffaf4-a74e-447b-b308-ae8fba146d8f.mp4

Here the QR code scan doesn't not worked. The WiFi scan when connected through BLE neither. Placing the SSD and password manually in this video doesn't worked and I was getting the error 204 on serial monitor.

After watch the video above I have noticed an extra space at the end of SSID name and after remove the extra space it worked.

— Reply to this email directly, view it on GitHub https://github.com/espressif/esp-rainmaker/issues/247#issuecomment-1449040424, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADHTIDPP5MJBA5A3UL67HYTWZZ5VPANCNFSM6AAAAAAVLFVS74 . You are receiving this because you are subscribed to this thread.Message ID: @.***>

-- Kind Regards John

FernandoGarcia commented 1 year ago

Hi @JohnMacrae !

This type of error is very common since the people is always using auto complete from keyboard.

The APP should make this type of filter to avoid users pull out some hair.

Best regards.

fenilGhoghari commented 1 year ago

Hi @FernandoGarcia , have you check your WiFi connection? and which ESP you are using? also which ESP-IDF version you are using?

FernandoGarcia commented 1 year ago

Yes, with WiFi scan example the board can find dozens of networks around.

I'm using Arduino esp32 core 2.0.6 with Esp32-wrover IE.

fenilGhoghari commented 1 year ago

yes make sure when you send credentials at a time ESP connect with your mobile and you are providing right credentials else this is not generated my our end.

FernandoGarcia commented 1 year ago

What I'm showing here's that the App or framework are not working properly at Android 6.0.1.

App almost always can't find network with scan even with dozens of networks around.

App doesn't make basic filter as remove extra space at the end of SSID before send data to ESP.

The connection with QR code never works, I have always to send manually.

fenilGhoghari commented 1 year ago

idf.py menuconfig -> Serial flasher config -> Enable Octal Flash ON this settings can help you to generate QR smoothly

FernandoGarcia commented 1 year ago

I'm using Arduino IDE.

FernandoGarcia commented 1 year ago

Another issue:

https://user-images.githubusercontent.com/2778501/222162449-4bbb1107-4cc0-4809-b1ce-b0461440af08.mov

What's the reason to a reset result in AUTH_FAIL using the code below?

After this error I have to make a factory reset and restart the configuration because I can't find any option on APP to fix it.

#include "RMaker.h"
#include "WiFi.h"
#include "WiFiProv.h"
#include <Bounce2.h>

#define NUM_RELAYS 16

#if CONFIG_IDF_TARGET_ESP32C3
const byte resetPin = 9;
#else
const byte resetPin = 0;
#endif

const char nodeName[] = "ESP32_Relay_16";
const char *service_name = "PROV_1234";
const char *pop = "abcd1234";

Bounce2::Button resetButton = Bounce2::Button();

static Switch my_switch[NUM_RELAYS];

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

INFOS info[NUM_RELAYS] = {
  { "Relay1", 4, LOW },  // Initial state = HIGH to active LOW relay model.
  { "Relay2", 5, LOW },
  { "Relay3", 18, LOW },
  { "Relay4", 19, LOW },
  { "Relay5", 21, LOW },
  { "Relay6", 22, LOW },
  { "Relay7", 23, LOW },
  { "Relay8", 25, LOW },
  { "Relay9", 26, LOW },
  { "Relay10", 27, LOW },
  { "Relay11", 32, LOW },
  { "Relay12", 33, LOW },
  { "Relay13", 13, LOW },
  { "Relay14", 12, LOW },
  { "Relay15", 14, LOW },
  { "Relay16", 15, LOW }
};

void sysProvEvent(arduino_event_t *sys_event) {
  switch (sys_event->event_id) {
    case ARDUINO_EVENT_PROV_START:
#if CONFIG_IDF_TARGET_ESP32S2
      Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on SoftAP\n", service_name, pop);
      printQR(service_name, pop, "softap");
#else
      Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on BLE\n", service_name, pop);
      printQR(service_name, pop, "ble");
#endif
      break;
    case ARDUINO_EVENT_PROV_INIT:
      wifi_prov_mgr_disable_auto_stop(10000);
      break;
    case ARDUINO_EVENT_PROV_CRED_SUCCESS:
      wifi_prov_mgr_stop_provisioning();
      break;
    default:
      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) {
      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);
      }
    }
  }
}
void read_callback(Device *device, Param *param, void *priv_data, read_ctx_t *ctx) {
  const char *device_name = device->getDeviceName();
  const char *param_name = param->getParamName();
  Serial.printf("Received for %s - %s\n", device_name, param_name);
}

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

  resetButton.attach(resetPin, INPUT);
  resetButton.interval(5);
  resetButton.setPressedState(LOW);

  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, read_callback);
    my_node.addDevice(my_switch[i]);
  }

  //This is optional
  RMaker.enableOTA(OTA_USING_TOPICS);
  //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();

  RMaker.enableScenes();

  RMaker.start();

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

void loop() {
  resetButton.update();

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

The result after try update the code:

[    88][I][RMaker.cpp:17] event_handler(): RainMaker Initialised.
[   115][I][WiFiProv.cpp:149] beginProvision(): Already Provisioned
[   115][I][WiFiProv.cpp:153] beginProvision(): Attempting connect to AP: Nossarede

[   231][W][WiFiGeneric.cpp:955] _eventCallback(): Reason: 202 - AUTH_FAIL
sanketwadekar commented 1 year ago

Another issue:

What's the reason to a reset result in AUTH_FAIL using the code below?

After this error I have to make a factory reset and restart the configuration because I can't find any option on APP to fix it.

#include "RMaker.h"
#include "WiFi.h"
#include "WiFiProv.h"
#include <Bounce2.h>

#define NUM_RELAYS 16

#if CONFIG_IDF_TARGET_ESP32C3
const byte resetPin = 9;
#else
const byte resetPin = 0;
#endif

const char nodeName[] = "ESP32_Relay_16";
const char *service_name = "PROV_1234";
const char *pop = "abcd1234";

Bounce2::Button resetButton = Bounce2::Button();

static Switch my_switch[NUM_RELAYS];

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

INFOS info[NUM_RELAYS] = {
  { "Relay1", 4, LOW },  // Initial state = HIGH to active LOW relay model.
  { "Relay2", 5, LOW },
  { "Relay3", 18, LOW },
  { "Relay4", 19, LOW },
  { "Relay5", 21, LOW },
  { "Relay6", 22, LOW },
  { "Relay7", 23, LOW },
  { "Relay8", 25, LOW },
  { "Relay9", 26, LOW },
  { "Relay10", 27, LOW },
  { "Relay11", 32, LOW },
  { "Relay12", 33, LOW },
  { "Relay13", 13, LOW },
  { "Relay14", 12, LOW },
  { "Relay15", 14, LOW },
  { "Relay16", 15, LOW }
};

void sysProvEvent(arduino_event_t *sys_event) {
  switch (sys_event->event_id) {
    case ARDUINO_EVENT_PROV_START:
#if CONFIG_IDF_TARGET_ESP32S2
      Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on SoftAP\n", service_name, pop);
      printQR(service_name, pop, "softap");
#else
      Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on BLE\n", service_name, pop);
      printQR(service_name, pop, "ble");
#endif
      break;
    case ARDUINO_EVENT_PROV_INIT:
      wifi_prov_mgr_disable_auto_stop(10000);
      break;
    case ARDUINO_EVENT_PROV_CRED_SUCCESS:
      wifi_prov_mgr_stop_provisioning();
      break;
    default:
      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) {
      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);
      }
    }
  }
}
void read_callback(Device *device, Param *param, void *priv_data, read_ctx_t *ctx) {
  const char *device_name = device->getDeviceName();
  const char *param_name = param->getParamName();
  Serial.printf("Received for %s - %s\n", device_name, param_name);
}

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

  resetButton.attach(resetPin, INPUT);
  resetButton.interval(5);
  resetButton.setPressedState(LOW);

  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, read_callback);
    my_node.addDevice(my_switch[i]);
  }

  //This is optional
  RMaker.enableOTA(OTA_USING_TOPICS);
  //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();

  RMaker.enableScenes();

  RMaker.start();

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

void loop() {
  resetButton.update();

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

The result after try update the code:

[    88][I][RMaker.cpp:17] event_handler(): RainMaker Initialised.
[   115][I][WiFiProv.cpp:149] beginProvision(): Already Provisioned
[   115][I][WiFiProv.cpp:153] beginProvision(): Attempting connect to AP: Nossarede

[   231][W][WiFiGeneric.cpp:955] _eventCallback(): Reason: 202 - AUTH_FAIL

@FernandoGarcia Can you try the WiFiProv example and see if the same issue exists there?

FernandoGarcia commented 1 year ago

Yes, but it was connected at a second attempt.

Connected IP address : 192.168.1.144

Provisioning Successful

Provisioning Ends
ets Jul 29 2019 12:21:46

rst:0x1 (POWERON_RESET),boot:0x12 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1344
load:0x40078000,len:13836
load:0x40080400,len:3608
entry 0x400805f0
[    84][I][WiFiProv.cpp:149] beginProvision(): Already Provisioned
[    84][I][WiFiProv.cpp:153] beginProvision(): Attempting connect to AP: Nossarede

[   202][W][WiFiGeneric.cpp:955] _eventCallback(): Reason: 202 - AUTH_FAIL

Disconnected. Connecting to the AP again... 

Connected IP address : 192.168.1.144

With the code above there's no connection at all after reset.

sanketwadekar commented 1 year ago

As mentioned here, the Arduino WiFi library will try to reconnect only once if the connection failure reason is WIFI_REASON_AUTH_FAIL. You can manually check the WiFi connection status in loop() and reconnect to WiFi if status==WL_CONNECT_FAILED

FernandoGarcia commented 1 year ago

This issue was supposed to be fixed at #7343

Moreover the code above has different behaviour from WiFiProv example.

Look for this:

Captura de tela de 2023-03-02 17 47 34

if (WiFi.status() == WL_CONNECT_FAILED) never become true.

FernandoGarcia commented 1 year ago

As told before after this error the board never will come on again and only a factory reset will solve.

https://user-images.githubusercontent.com/2778501/222556424-819b7e29-f4ab-44db-a334-e1f4e81437b4.mov

sanketwadekar commented 1 year ago

Can you attach the WiFi event callback from the WiFiProv example in your sketch, so that you can see the logs of which events are generated by the underlying WiFi layer?

FernandoGarcia commented 1 year ago

Using the SysProvEvent function from WiFiProv example the connection at second attempt is done.

[    89][I][RMaker.cpp:17] event_handler(): RainMaker Initialised.
[   117][I][WiFiProv.cpp:149] beginProvision(): Already Provisioned
[   117][I][WiFiProv.cpp:153] beginProvision(): Attempting connect to AP: Nossarede

[   304][W][WiFiGeneric.cpp:955] _eventCallback(): Reason: 202 - AUTH_FAIL

Disconnected. Connecting to the AP again... 

Connected IP address : 192.168.1.144
Received value = false for Relay2 - Power
Received value = true for Relay2 - Power

So the SysProvEvent function in switch example is incomplete.