Unverified Commit e62ff6dc authored by Piyush Shah's avatar Piyush Shah Committed by GitHub

RainMaker library: Minor changes (#5092)

- 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.
parent 18249907
This diff is collapsed.
This diff is collapsed.
# 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
```
//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);
}
# Switch Example
## Compile n Flash firmware
### ESP32 Board
- Assisted Claiming + BLE Provisioning
## What to expect in this sketch ?
### It demonstartes the toggling of power of devices using phone app and BOOT button.
- Switch and Fan are the dummy device. Switch connected at gpio(16) and Fan connected at gpio(17).
- Toggling the power button for any device(switch/fan) on phone app will change the status(on/off) for the device connected at gpio(16/17) and also update the status to the ESP RainMaker cloud if `param.updateAndReport(val)` API is called.
- Pressing the BOOT button toggles the status(on/off) of both device(switch & fan) connected at gpio(16/17) and report values to the cloud.
### Output
```
[I][WiFiProv.cpp:179] beginProvision(): Already Provisioned
[I][WiFiProv.cpp:183] beginProvision(): Attempting connect to AP: Wce*****
Received value = false for Switch - Power
Received value = false for Fan - Power
Received value = true for Switch - Power
[I][RMakerDevice.cpp:161] updateAndReportParam(): Device : Switch, Param Name : Power, Val : false
[I][RMakerDevice.cpp:161] updateAndReportParam(): Device : Fan, Param Name : Power, Val : true
Received value = true for Switch - Power
Received value = false for Fan - Power
```
# 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
```
//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,20 +38,11 @@ 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()
......@@ -62,7 +50,7 @@ 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");
......@@ -70,22 +58,17 @@ void setup()
//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);
}
......@@ -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
\ No newline at end of file
#endif
......@@ -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,6 +19,7 @@ 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();
......@@ -25,4 +27,4 @@ class RMakerClass
extern RMakerClass RMaker;
#endif
\ No newline at end of file
#endif
......@@ -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
\ No newline at end of file
#endif
#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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment