Skip to content

RainMaker device callback issue #8231

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
1 task done
ndtfy opened this issue May 19, 2023 · 2 comments · Fixed by #8249
Closed
1 task done

RainMaker device callback issue #8231

ndtfy opened this issue May 19, 2023 · 2 comments · Fixed by #8249
Labels
Area: Rainmaker Issue is related to ESP Rainmaker. Status: To be implemented Selected for Development

Comments

@ndtfy
Copy link

ndtfy commented May 19, 2023

Board

LilyGo T-Display-S3

Device Description

LilyGo T-Display-S3

Hardware Configuration

Amended esp-rainmaker\examples\switch example
gpio_switch = PIN_21

Version

v2.0.9

IDE Name

Arduino IDE

Operating System

Windows 11

Flash frequency

No idea

PSRAM enabled

yes

Upload speed

115200

Description

I elaborate the esp-rainmaker\examples\switch example. Originally it works fine, but after adding a new device with his callback the switch callback become the same as new device callback.

Sketch

// This example demonstrates the ESP RainMaker with a standard Switch device.
#include "RMaker.h"
#include "WiFi.h"
#include "WiFiProv.h"
#include "AppInsights.h"

#define DEFAULT_POWER_MODE true
const char *service_name = "PROV_1234";
const char *pop = "abcd1234";

// GPIO for push button
static int gpio_0 = 0;
static int gpio_switch = PIN_21;

/* Variable for reading pin status*/
bool switch_state = true;

// The framework provides some standard device types like switch, lightbulb,
// fan, temperaturesensor.
static Switch *my_switch = NULL;


static Device *my_menu = NULL;


void sysProvEvent(arduino_event_t *sys_event)
{
    switch (sys_event->event_id) {
    case ARDUINO_EVENT_PROV_START:
        Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on SoftAP\n",
                      service_name, pop);
        printQR(service_name, pop, "softap");
        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:;
    }
}

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(param_name, "Power") == 0) {
        Serial.printf("Received value = %s for %s - %s\n",
                      val.val.b ? "true" : "false", device_name, param_name);
        switch_state = val.val.b;
        (switch_state == false) ? digitalWrite(gpio_switch, LOW)
        : digitalWrite(gpio_switch, HIGH);
        param->updateAndReport(val);
    }
}


/******* Added *******/
void write_debug_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();

  Serial.printf("[debug] %s/%s: address %08X\n", device_name, param_name, &val);
}
/**********************/


void setup()
{
    Serial.begin(115200);
    pinMode(gpio_0, INPUT);
    pinMode(gpio_switch, OUTPUT);
    digitalWrite(gpio_switch, DEFAULT_POWER_MODE);

    Node my_node;
    my_node = RMaker.initNode("ESP RainMaker Node");

    // Initialize switch device
    my_switch = new Switch("Switch", &gpio_switch);
    if (!my_switch) {
        return;
    }
    // Standard switch device
    my_switch->addCb(write_callback);

    // Add switch device to the node
    my_node.addDevice(*my_switch);









/******* Added *******/

    my_menu = new Device("Main menu", NULL, NULL);
    if (!my_menu) {
        return;
    }

    my_menu->addNameParam();
    my_menu->addPowerParam(true);
    my_menu->assignPrimaryParam(my_menu->getParamByName(ESP_RMAKER_DEF_POWER_NAME));

    Param mode_param("Mode", "custom.param.mode", esp_rmaker_str("Main"), PROP_FLAG_READ | PROP_FLAG_WRITE);
    static const char *mode_strs[] = {"Main", "Temp", "Internet", "About"};
    mode_param.addValidStrList(mode_strs, 4);
    mode_param.addUIType(ESP_RMAKER_UI_DROPDOWN);

    my_menu->addParam(mode_param);


    // !!!
    my_menu->addCb(write_debug_callback); // <- after this both my_switch and my_menu call the same callback-function (write_debug_callback)

    my_node.addDevice(*my_menu);


    // !!! However all variables differ
    Serial.printf("[write_callback]       Value: %08X\n", write_callback);
    Serial.printf("[my_switch]            Value: %08X\n", my_switch);
    Serial.printf("[getDeviceHandle]      Value: %08X\n", my_switch->getDeviceHandle());
    Serial.println("=======");
    Serial.printf("[write_debug_callback] Value: %08X\n", write_debug_callback);
    Serial.printf("[my_menu]              Value: %08X\n", my_menu);
    Serial.printf("[getDeviceHandle]      Value: %08X\n", my_menu->getDeviceHandle());

/**********************/










    // 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();
    // Enable ESP Insights. Insteads of using the default http transport, this function will
    // reuse the existing MQTT connection of Rainmaker, thereby saving memory space.
    initAppInsights();

    RMaker.enableSystemService(SYSTEM_SERV_FLAGS_ALL, 2, 2, 2);

    RMaker.start();

    WiFi.onEvent(sysProvEvent);

    WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE,
                            WIFI_PROV_SECURITY_1, pop, service_name);

}

void loop()
{
    if (digitalRead(gpio_0) == LOW) {  // Push button pressed

        // Key debounce handling
        delay(100);
        int startTime = millis();
        while (digitalRead(gpio_0) == 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);
        } else {
            // Toggle device state
            switch_state = !switch_state;
            Serial.printf("Toggle State to %s.\n", switch_state ? "true" : "false");
            if (my_switch) {
                my_switch->updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME,
                                                switch_state);
            }
            (switch_state == false) ? digitalWrite(gpio_switch, LOW)
            : digitalWrite(gpio_switch, HIGH);
        }
    }
    delay(100);
}

Debug Message

[   348][D][WiFiGeneric.cpp:1035] _eventCallback(): Arduino Event: 0 - WIFI_READY
[   370][I][RMaker.cpp:17] event_handler(): RainMaker Initialised.
[write_callback]       Value: 42004264
[my_switch]            Value: 3FCAEAE4
[getDeviceHandle]      Value: 3FCAEB50
=======
[write_debug_callback] Value: 420042C4
[my_menu]              Value: 3FCAEC98
[getDeviceHandle]      Value: 3FCAECAC
[   381][D][WiFiGeneric.cpp:1035] _eventCallback(): Arduino Event: 33 - PROV_INIT
[   381][I][WiFiProv.cpp:149] beginProvision(): Already Provisioned
[   383][I][WiFiProv.cpp:153] beginProvision(): Attempting connect to AP: Galaxy Note10 Lite

[   424][D][WiFiGeneric.cpp:1035] _eventCallback(): Arduino Event: 2 - STA_START
[   425][D][WiFiGeneric.cpp:1035] _eventCallback(): Arduino Event: 34 - PROV_DEINIT
[ 10572][D][WiFiGeneric.cpp:1035] _eventCallback(): Arduino Event: 5 - STA_DISCONNECTED
[ 10572][W][WiFiGeneric.cpp:1057] _eventCallback(): Reason: 204 - HANDSHAKE_TIMEOUT
[ 10576][D][WiFiGeneric.cpp:1077] _eventCallback(): WiFi Reconnect Running
[ 10629][D][WiFiGeneric.cpp:1035] _eventCallback(): Arduino Event: 4 - STA_CONNECTED
[ 10642][D][WiFiGeneric.cpp:1035] _eventCallback(): Arduino Event: 7 - STA_GOT_IP
[ 10643][D][WiFiGeneric.cpp:1098] _eventCallback(): STA IP: 192.168.204.105, MASK: 255.255.255.0, GW: 192.168.204.141
[debug] Switch/Power: address 3FCB2DD8
[debug] Switch/Power: address 3FCB2DD8
[debug] Main menu/Power: address 3FCB2DD8
[debug] Main menu/Power: address 3FCB2DD8

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.
@ndtfy ndtfy added the Status: Awaiting triage Issue is waiting for triage label May 19, 2023
@mrengineer7777 mrengineer7777 added the Area: Rainmaker Issue is related to ESP Rainmaker. label May 21, 2023
@VojtechBartoska
Copy link
Contributor

@sanketwadekar Can you please take a look on this issue? Thanks

@sanketwadekar
Copy link
Contributor

@lishnih Thanks for reporting the issue. I'll provide a fix soon.

@VojtechBartoska VojtechBartoska added Status: To be implemented Selected for Development and removed Status: Awaiting triage Issue is waiting for triage labels May 24, 2023
@ndtfy ndtfy closed this as completed May 26, 2023
me-no-dev pushed a commit that referenced this issue May 31, 2023
This PR fixes an issue of multiple device callbacks (one callback per device) were not getting registered and invoked.
Consider an example where I create two devices, a switch and a fan; each of them having their own write callbacks. On controlling either switch/fan through Rainmaker app, the callback that got registered at last gets invoked. This is also seen in the issue reported in #8231
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: Rainmaker Issue is related to ESP Rainmaker. Status: To be implemented Selected for Development
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants