Skip to content
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

RainMaker library: Minor changes #5092

Merged
merged 2 commits into from
Apr 22, 2021
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
RainMaker library: Minor changes
- Use Serial.print instead of log_i for QR code helper information,
  so that it is always printed by default.
- Expose the RainMaker factory reset and wifi reset APIs.
- Simplify example to have only a Switch device. Create another example for custom device.
- Enable push button based Factory reset and Wi-Fi reset.
- Added support for the TimeZone service.
- Moved API doc to RainMaker library's top level README.
- Other minor doc changes.
shahpiyushv committed Apr 21, 2021
commit 43d695555ce4fa2d01204e64c7c8a33dd5a0990a
444 changes: 444 additions & 0 deletions libraries/RainMaker/README.md

Large diffs are not rendered by default.

438 changes: 7 additions & 431 deletions libraries/RainMaker/examples/README.md

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions libraries/RainMaker/examples/RMakerCustom/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# ESP RainMaker Switch

This example demonstrates how to build a switch device to be used with ESP RainMaker.

## What to expect in this example?

- This example sketch uses the on board Boot button and GPIO16 to demonstrate an ESP RainMaker switch device.
- After compiling and flashing the example, add your device using the [ESP RainMaker phone apps](https://rainmaker.espressif.com/docs/quick-links.html#phone-apps) by scanning the QR code.
- Toggling the state from the phone app will toggle the switch state (GPIO16).
- Pressing the Boot button will toggle the switch state (GPIO16) and the same will reflect on the phone app.

### Output

```
[ 63][I][RMaker.cpp:13] event_handler(): RainMaker Initialised.
[ 69][I][WiFiProv.cpp:158] beginProvision(): Already Provisioned
[ 69][I][WiFiProv.cpp:162] beginProvision(): Attempting connect to AP: Viking007_2GEXT
Toggle State to false.
[ 8182][I][RMakerDevice.cpp:162] updateAndReportParam(): Device : Switch, Param Name : Power, Val : false
Toggle State to true.
[ 9835][I][RMakerDevice.cpp:162] updateAndReportParam(): Device : Switch, Param Name : Power, Val : true
Received value = false for Switch - Power
Received value = true for Switch - Power
Toggle State to false.
[ 29937][I][RMakerDevice.cpp:162] updateAndReportParam(): Device : Switch, Param Name : Power, Val : false
```
126 changes: 126 additions & 0 deletions libraries/RainMaker/examples/RMakerCustom/RMakerCustom.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
//This example demonstrates the ESP RainMaker with a custom device
#include "RMaker.h"
#include "WiFi.h"
#include "WiFiProv.h"

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

//GPIO for push button
static int gpio_0 = 0;
//GPIO for virtual device
static int gpio_dimmer = 16;
/* Variable for reading pin status*/
bool dimmer_state = true;

// The framework provides some standard device types like switch, lightbulb, fan, temperature sensor.
// But, you can also define custom devices using the 'Device' base class object, as shown here
static Device my_device("Dimmer", "custom.device.dimmer", &gpio_dimmer);

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;
}
}

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);
dimmer_state = val.val.b;
(dimmer_state == false) ? digitalWrite(gpio_dimmer, LOW) : digitalWrite(gpio_dimmer, HIGH);
param->updateAndReport(val);
} else if (strcmp(param_name, "Level") == 0) {
Serial.printf("\nReceived value = %d for %s - %s\n", val.val.i, device_name, param_name);
param->updateAndReport(val);
}
}

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

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

//Create custom dimmer device
my_device.addNameParam();
my_device.addPowerParam(DEFAULT_POWER_MODE);
my_device.assignPrimaryParam(my_device.getParamByName(ESP_RMAKER_DEF_POWER_NAME));

//Create and add a custom level parameter
Param level_param("Level", "custom.param.level", value(DEFAULT_DIMMER_LEVEL), PROP_FLAG_READ | PROP_FLAG_WRITE);
level_param.addBounds(value(0), value(100), value(1));
level_param.addUIType(ESP_RMAKER_UI_SLIDER);
my_device.addParam(level_param);

my_device.addCb(write_callback);

//Add custom dimmer device to the node
my_node.addDevice(my_device);

//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();

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
}

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
dimmer_state = !dimmer_state;
Serial.printf("Toggle State to %s.\n", dimmer_state ? "true" : "false");
my_device.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, dimmer_state);
(dimmer_state == false) ? digitalWrite(gpio_dimmer, LOW) : digitalWrite(gpio_dimmer, HIGH);
}
}
delay(100);
}
34 changes: 0 additions & 34 deletions libraries/RainMaker/examples/RMakerDevice/README.md

This file was deleted.

Empty file.
Empty file.
27 changes: 27 additions & 0 deletions libraries/RainMaker/examples/RMakerSwitch/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# ESP RainMaker Switch

This example demonstrates how to build a switch device to be used with ESP RainMaker.

## What to expect in this example?

- This example sketch uses the on board Boot button and GPIO16 to demonstrate an ESP RainMaker switch device.
- After compiling and flashing the example, add your device using the [ESP RainMaker phone apps](https://rainmaker.espressif.com/docs/quick-links.html#phone-apps) by scanning the QR code.
- Toggling the state from the phone app will toggle the switch state (GPIO16).
- Pressing the Boot button will toggle the switch state (GPIO16) and the same will reflect on the phone app.

### Output

```
[ 63][I][RMaker.cpp:13] event_handler(): RainMaker Initialised.
[ 69][I][WiFiProv.cpp:158] beginProvision(): Already Provisioned
[ 69][I][WiFiProv.cpp:162] beginProvision(): Attempting connect to AP: Viking007_2GEXT
Toggle State to false.
[ 8182][I][RMakerDevice.cpp:162] updateAndReportParam(): Device : Switch, Param Name : Power, Val : false
Toggle State to true.
[ 9835][I][RMakerDevice.cpp:162] updateAndReportParam(): Device : Switch, Param Name : Power, Val : true
Received value = false for Switch - Power
Received value = true for Switch - Power
Toggle State to false.
[ 29937][I][RMakerDevice.cpp:162] updateAndReportParam(): Device : Switch, Param Name : Power, Val : false
```
Original file line number Diff line number Diff line change
@@ -1,34 +1,31 @@
//This example demonstrates the ESP RainMaker with the custom device and standard Switch device.
//This example demonstrates the ESP RainMaker with a standard Switch device.
#include "RMaker.h"
#include "WiFi.h"
#include "WiFiProv.h"

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

//GPIO for push button
static int gpio_0 = 0;
//GPIO for virtual device
static int gpio_switch = 16;
static int gpio_fan = 17;
/* Variable for reading pin status*/
bool switch_state = true;
bool fan_state = true;

//The framework provides some standard device types like switch, lightbulb, fan, temperaturesensor.
static Switch my_switch("Switch", &gpio_switch);
//You can also define custom devices using the 'Device' base class object, as shown here
static Device my_device("Fan", ESP_RMAKER_DEVICE_FAN, &gpio_fan);

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;
@@ -41,51 +38,37 @@ void write_callback(Device *device, Param *param, const param_val_t val, void *p
const char *param_name = param->getParamName();

if(strcmp(param_name, "Power") == 0) {
Serial.printf("\nReceived value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
if(strcmp(device_name, "Switch") == 0) {
switch_state = val.val.b;
(switch_state == false) ? digitalWrite(gpio_switch, LOW) : digitalWrite(gpio_switch, HIGH);
}
if(strcmp(device_name, "Fan") == 0) {
fan_state = val.val.b;
(fan_state == false) ? digitalWrite(gpio_fan, LOW) : digitalWrite(gpio_fan, HIGH);
}
}
else if(strcmp(param_name, "Speed") == 0) {
Serial.printf("\nReceived value = %d for %s - %s\n", val.val.i, device_name, param_name);
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);
}
param->updateAndReport(val);
}

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

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

//Standard switch device
my_switch.addCb(write_callback);

//Creating custom fan device
my_device.addNameParam();
my_device.addPowerParam(DEFAULT_POWER_MODE);
my_device.addSpeedParam(DEFAULT_FAN_SPEED);
my_device.assignPrimaryParam(my_device.getParamByName(ESP_RMAKER_DEF_POWER_NAME));
my_device.addCb(write_callback);

//Add switch and fan device to the node
//Add switch device to the node
my_node.addDevice(my_switch);
my_node.addDevice(my_device);

//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");
// RMaker.setTimeZone("Asia/Shanghai");
// Alternatively, enable the Timezone service and let the phone apps set the appropriate timezone
RMaker.enableTZService();

RMaker.enableSchedule();

RMaker.start();
@@ -96,18 +79,33 @@ void setup()
#else
WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE, WIFI_PROV_SECURITY_1, pop, service_name);
#endif

}

void loop()
{
if(digitalRead(gpio_0) == LOW) { //Push button
switch_state = !switch_state;
fan_state = !fan_state;
my_switch.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, switch_state);
my_device.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, fan_state);
(switch_state == false) ? digitalWrite(gpio_switch, LOW) : digitalWrite(gpio_switch, HIGH);
(fan_state == false) ? digitalWrite(gpio_fan, LOW) : digitalWrite(gpio_fan, HIGH);
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");
my_switch.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, switch_state);
(switch_state == false) ? digitalWrite(gpio_switch, LOW) : digitalWrite(gpio_switch, HIGH);
}
}
delay(100);
}
11 changes: 10 additions & 1 deletion libraries/RainMaker/src/RMaker.cpp
Original file line number Diff line number Diff line change
@@ -92,6 +92,15 @@ esp_err_t RMakerClass::enableSchedule()
return err;
}

esp_err_t RMakerClass::enableTZService()
{
err = esp_rmaker_timezone_service_enable();
if(err != ESP_OK) {
log_e("Timezone service enable failed");
}
return err;
}

esp_err_t RMakerClass::enableOTA(ota_type_t type, const char *cert)
{
esp_rmaker_ota_config_t ota_config;
@@ -104,4 +113,4 @@ esp_err_t RMakerClass::enableOTA(ota_type_t type, const char *cert)
}

RMakerClass RMaker;
#endif
#endif
4 changes: 3 additions & 1 deletion libraries/RainMaker/src/RMaker.h
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@
#include "Arduino.h"
#include "RMakerNode.h"
#include "RMakerQR.h"
#include "RMakerUtils.h"
#include <esp_rmaker_standard_types.h>

class RMakerClass
@@ -18,11 +19,12 @@ class RMakerClass
esp_err_t deinitNode(Node node);
esp_err_t setTimeZone(const char *tz = "Asia/Shanghai");
esp_err_t enableSchedule();
esp_err_t enableTZService();
esp_err_t enableOTA(ota_type_t type, const char *cert = ESP_RMAKER_OTA_DEFAULT_SERVER_CERT);
esp_err_t start();
esp_err_t stop();
};

extern RMakerClass RMaker;

#endif
#endif
6 changes: 3 additions & 3 deletions libraries/RainMaker/src/RMakerQR.h
Original file line number Diff line number Diff line change
@@ -16,9 +16,9 @@ static void printQR(const char *name, const char *pop, const char *transport)
snprintf(payload, sizeof(payload), "{\"ver\":\"%s\",\"name\":\"%s\"" \
",\"pop\":\"%s\",\"transport\":\"%s\"}",
PROV_QR_VERSION, name, pop, transport);
log_i("Scan this QR code from the phone app for Provisioning.");
Serial.printf("Scan this QR code from the ESP RainMaker phone app.\n");
qrcode_display(payload);
log_i("If QR code is not visible, copy paste the below URL in a browser.\n%s?data=%s", QRCODE_BASE_URL, payload);
Serial.printf("If QR code is not visible, copy paste the below URL in a browser.\n%s?data=%s\n", QRCODE_BASE_URL, payload);
}

#endif
#endif
16 changes: 16 additions & 0 deletions libraries/RainMaker/src/RMakerUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include "esp_system.h"
#if ESP_IDF_VERSION_MAJOR >= 4 && CONFIG_IDF_TARGET_ESP32

#include <esp_rmaker_utils.h>

static void RMakerFactoryReset(int seconds)
{
esp_rmaker_factory_reset(seconds);
}

static void RMakerWiFiReset(int seconds)
{
esp_rmaker_wifi_reset(seconds);
}

#endif