10000
We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentat 8000 ion.
There was an error while loading. Please reload this page.
1 parent 1b1c36e commit c93bf11Copy full SHA for c93bf11
libraries/RainMaker/examples/RMakerCustomAirCooler/README.md
@@ -0,0 +1,34 @@
1
+# ESP RainMaker Custom Device
2
+
3
+This example demonstrates how to build a custom device to be used with ESP RainMaker using Mode, Range and Toggle Parameters.
4
5
+## What to expect in this example?
6
7
+- This example sketch uses the on board Boot button and GPIOs 16, 17, 18, 19, 21, 22 to demonstrate an ESP RainMaker AirCooler device.
8
+- 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.
9
+- Toggling the power state from the phone app will toggle GPIO 16.
10
+- Pressing the Boot button will toggle the power state (GPIO 16) and the same will reflect on the phone app.
11
+- Toggling the swing state from the phone app will toggle GPIO 17.
12
+- Changing the mode from the phone app will toggle the GPIOs 18 (auto), 19 (cool) and 21 (heat)
13
+- Changing the Speed slider from the phone app will dimming GPIO 22
14
+- You can also change the Level from the phone app and see it reflect on the device as a print message.
15
16
+### Output
17
18
+```
19
+Received value = true for Air Cooler - Power
20
+Received value = false for Air Cooler - Power
21
+Received value = true for Air Cooler - Swing
22
+Received value = false for Air Cooler - Swing
23
+Received value = 0 for Air Cooler - Speed
24
+Received value = 255 for Air Cooler - Speed
25
+Received value = Auto for Air Cooler - Mode
26
+Received value = Cool for Air Cooler - Mode
27
+Received value = Heat for Air Cooler - Mode
28
+Toggle power state to false.
29
30
31
32
+### Resetting the device
33
+- Press and Hold the Boot button for more than 3 seconds and then release to reset Wi-Fi configuration.
34
+- Press and Hold the Boot button for more than 10 seconds and then release to reset to factory defaults.
libraries/RainMaker/examples/RMakerCustomAirCooler/RMakerCustomAirCooler.ino
@@ -0,0 +1,192 @@
+//This example demonstrates the ESP RainMaker with a custom Air Cooler device
+#include "RMaker.h"
+#include "WiFi.h"
+#include "WiFiProv.h"
+#include "led_strip.h"
+#define DEFAULT_POWER_MODE true
+#define DEFAULT_SWING false
+#define DEFAULT_SPEED 0
+#define DEFAULT_MODE "Auto"
+const char *service_name = "PROV_1234";
+const char *pop = "abcd1234";
+#if CONFIG_IDF_TARGET_ESP32C3
+//GPIO for push button
+static int gpio_reset = 9;
+//GPIO for virtual device
+static int gpio_power = 7;
+static int gpio_swing = 3;
+static int gpio_mode_auto = 4;
+static int gpio_mode_cool = 5;
+static int gpio_mode_heat = 6;
+static int gpio_speed = 10;
+#else
+static int gpio_reset = 0;
+static int gpio_power = 16;
+static int gpio_swing = 17;
+static int gpio_mode_auto = 18;
+static int gpio_mode_cool = 19;
+static int gpio_mode_heat = 21;
35
+static int gpio_speed = 22;
36
+#endif
37
38
+bool power_state = true;
39
40
+// The framework provides some standard device types like switch, lightbulb, fan, temperature sensor.
41
+// But, you can also define custom devices using the 'Device' base class object, as shown here
42
+static Device my_device("Air Cooler", "my.device.air-cooler", NULL);
43
44
+void sysProvEvent(arduino_event_t *sys_event)
45
+{
46
+ switch (sys_event->event_id) {
47
+ case ARDUINO_EVENT_PROV_START:
48
+#if CONFIG_IDF_TARGET_ESP32S2
49
+ Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on SoftAP\n", service_name, pop);
50
+ printQR(service_name, pop, "softap");
51
52
+ Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on BLE\n", service_name, pop);
53
+ printQR(service_name, pop, "ble");
54
55
+ break;
56
+ default:;
57
+ }
58
+}
59
60
+void write_callback(Device *device, Param *param, const param_val_t val, void *priv_data, write_ctx_t *ctx)
61
62
+ const char *device_name = device->getDeviceName();
63
+ const char *param_name = param->getParamName();
64
65
+ if(strcmp(param_name, "Power") == 0) {
66
+ Serial.printf("Received value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
67
+ power_state = val.val.b;
68
+ (power_state == false) ? digitalWrite(gpio_power, LOW) : digitalWrite(gpio_power, HIGH);
69
+ param->updateAndReport(val);
70
+ } else if (strcmp(param_name, "Swing") == 0) {
71
+ Serial.printf("\nReceived value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
72
+ bool swing = val.val.b;
73
+ (swing == false) ? digitalWrite(gpio_swing, LOW) : digitalWrite(gpio_swing, HIGH);
74
75
+ } else if (strcmp(param_name, "Speed") == 0) {
76
+ Serial.printf("\nReceived value = %d for %s - %s\n", val.val.i, device_name, param_name);
77
+ int speed = val.val.i;
78
+ analogWrite(gpio_speed, speed);
79
80
+ } else if (strcmp(param_name, "Mode") == 0) {
81
+ const char* mode = val.val.s;
82
+ if (strcmp(mode, "Auto") == 0) {
83
+ digitalWrite(gpio_mode_auto, HIGH);
84
+ digitalWrite(gpio_mode_heat, LOW);
85
+ digitalWrite(gpio_mode_cool, LOW);
86
+ } else if (strcmp(mode, "Heat") == 0) {
87
+ digitalWrite(gpio_mode_auto, LOW);
88
+ digitalWrite(gpio_mode_heat, HIGH);
89
90
+ } else if (strcmp(mode, "Cool") == 0) {
91
92
93
+ digitalWrite(gpio_mode_cool, HIGH);
94
95
+ Serial.printf("\nReceived value = %s for %s - %s\n", val.val.s, device_name, param_name);
96
97
98
99
100
+void setup()
101
102
+ Serial.begin(115200);
103
+ pinMode(gpio_reset, INPUT_PULLUP);
104
+ pinMode(gpio_power, OUTPUT);
105
+ digitalWrite(gpio_power, DEFAULT_POWER_MODE);
106
+ pinMode(gpio_swing, OUTPUT);
107
+ digitalWrite(gpio_swing, DEFAULT_SWING);
108
+ pinMode(gpio_mode_auto, OUTPUT);
109
+ if (strcmp(DEFAULT_MODE, "Auto") == 0) digitalWrite(gpio_mode_auto, HIGH);
110
+ pinMode(gpio_mode_cool, OUTPUT);
111
+ if (strcmp(DEFAULT_MODE, "Cool") == 0) digitalWrite(gpio_mode_auto, HIGH);
112
+ pinMode(gpio_mode_heat, OUTPUT);
113
+ if (strcmp(DEFAULT_MODE, "Heat") == 0) digitalWrite(gpio_mode_auto, HIGH);
114
+ pinMode(gpio_speed, OUTPUT);
115
+ analogWrite(gpio_speed, DEFAULT_SPEED);
116
117
+ Node my_node;
118
+ my_node = RMaker.initNode("ESP RainMaker Node");
119
120
+ //Create custom air cooler device
121
+ my_device.addNameParam();
122
+ my_device.addPowerParam(DEFAULT_POWER_MODE);
123
+ my_device.assignPrimaryParam(my_device.getParamByName(ESP_RMAKER_DEF_POWER_NAME));
124
125
+ Param swing("Swing", ESP_RMAKER_PARAM_TOGGLE, value(DEFAULT_SWING), PROP_FLAG_READ | PROP_FLAG_WRITE);
126
+ swing.addUIType(ESP_RMAKER_UI_TOGGLE);
127
+ my_device.addParam(swing);
128
129
+ Param speed("Speed", ESP_RMAKER_PARAM_RANGE, value(DEFAULT_SPEED), PROP_FLAG_READ | PROP_FLAG_WRITE);
130
+ speed.addUIType(ESP_RMAKER_UI_SLIDER);
131
+ speed.addBounds(value(0), value(255), value(1));
132
+ my_device.addParam(speed);
133
134
+ static const char* modes[] = { "Auto", "Cool", "Heat" };
135
+ Param mode_param("Mode", ESP_RMAKER_PARAM_MODE, value("Auto"), PROP_FLAG_READ | PROP_FLAG_WRITE);
136
+ mode_param.addValidStrList(modes, 3);
137
+ mode_param.addUIType(ESP_RMAKER_UI_DROPDOWN);
138
+ my_device.addParam(mode_param);
139
140
+ my_device.addCb(write_callback);
141
142
+ //Add custom Air Cooler device to the node
143
+ my_node.addDevice(my_device);
144
145
+ //This is optional
146
+ // RMaker.enableOTA(OTA_USING_PARAMS);
147
+ //If you want to enable scheduling, set time zone for your region using setTimeZone().
148
+ //The list of available values are provided here https://rainmaker.espressif.com/docs/time-service.html
149
+ // RMaker.setTimeZone("Asia/Shanghai");
150
+ //Alternatively, enable the Timezone service and let the phone apps set the appropriate timezone
151
+ // RMaker.enableTZService();
152
153
+ RMaker.enableSchedule();
154
155
+ RMaker.start();
156
157
+ WiFi.onEvent(sysProvEvent);
158
159
+ WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE, WIFI_PROV_SECURITY_1, pop, service_name);
160
161
+ WiFiProv.beginProvision(WIFI_PROV_SCHEME_BLE, WIFI_PROV_SCHEME_HANDLER_FREE_BTDM, WIFI_PROV_SECURITY_1, pop, service_name);
162
163
164
165
+void loop()
166
167
+ if(digitalRead(gpio_reset) == LOW) { //Push button pressed
168
169
+ // Key debounce handling
170
+ delay(100);
171
+ int startTime = millis();
172
+ while(digitalRead(gpio_reset) == LOW) delay(50);
173
+ int press_duration = millis() - startTime;
174
175
+ if (press_duration > 10000) {
176
+ // If key pressed for more than 10secs, reset all
177
+ Serial.printf("Reset to factory.\n");
178
+ RMakerFactoryReset(2);
179
+ } else if (press_duration > 3000) {
180
+ Serial.printf("Reset Wi-Fi.\n");
181
+ // If key pressed for more than 3secs, but less than 10, reset Wi-Fi
182
+ RMakerWiFiReset(2);
183
+ } else {
184
+ // Toggle device state
185
+ power_state = !power_state;
186
+ Serial.printf("Toggle power state to %s.\n", power_state ? "true" : "false");
187
+ my_device.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, power_state);
188
189
190
191
192
libraries/RainMaker/src/RMakerParam.cpp
@@ -30,4 +30,12 @@ esp_err_t Param::updateAndReport(param_val_t val)
}
return err;
+esp_err_t Param::addValidStrList(const char **string_list, uint8_t count) {
+ esp_err_t err = esp_rmaker_param_add_valid_str_list(getParamHandle(), string_list, count);
+ if (err != ESP_OK) {
+ log_e("Add valid string list error");
+ return err;
#endif
libraries/RainMaker/src/RMakerParam.h
@@ -47,5 +47,6 @@ class Param
esp_err_t addUIType(const char *ui_type);
esp_err_t addBounds(param_val_t min, param_val_t max, param_val_t step);
esp_err_t updateAndReport(param_val_t val);
+ esp_err_t addValidStrList(const char **string_list, uint8_t count);
};
libraries/RainMaker/src/RMakerType.cpp
@@ -21,4 +21,9 @@ param_val_t value(float fval)
{
return esp_rmaker_float(fval);
+param_val_t value(const char* sval)
+ return esp_rmaker_str(sval);
libraries/RainMaker/src/RMakerType.h
@@ -33,4 +33,5 @@ param_val_t value(int);
param_val_t value(bool);
param_val_t value(char *);
param_val_t value(float);
+param_val_t value(const char*);