forked from espressif/arduino-esp32
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcoap_lamp.ino
163 lines (153 loc) · 5.32 KB
/
coap_lamp.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
// Copyright 2024 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "OThreadCLI.h"
#include "OThreadCLI_Util.h"
#define OT_CHANNEL "24"
#define OT_NETWORK_KEY "00112233445566778899aabbccddeeff"
#define OT_MCAST_ADDR "ff05::abcd"
#define OT_COAP_RESOURCE_NAME "Lamp"
const char *otSetupLeader[] = {
// -- clear/disable all
// stop CoAP
"coap", "stop",
// stop Thread
"thread", "stop",
// stop the interface
"ifconfig", "down",
// clear the dataset
"dataset", "clear",
// -- set dataset
// create a new complete dataset with random data
"dataset", "init new",
// set the channel
"dataset channel", OT_CHANNEL,
// set the network key
"dataset networkkey", OT_NETWORK_KEY,
// commit the dataset
"dataset", "commit active",
// -- network start
// start the interface
"ifconfig", "up",
// start the Thread network
"thread", "start"
};
const char *otCoapLamp[] = {
// -- create a multicast IPv6 Address for this device
"ipmaddr add", OT_MCAST_ADDR,
// -- start and create a CoAP resource
// start CoAP as server
"coap", "start",
// create a CoAP resource
"coap resource", OT_COAP_RESOURCE_NAME,
// set the CoAP resource initial value
"coap set", "0"
};
bool otDeviceSetup(const char **otSetupCmds, uint8_t nCmds1, const char **otCoapCmds, uint8_t nCmds2, ot_device_role_t expectedRole) {
Serial.println("Starting OpenThread.");
Serial.println("Running as Lamp (RGB LED) - use the other C6/H2 as a Switch");
uint8_t i;
for (i = 0; i < nCmds1; i++) {
if (!otExecCommand(otSetupCmds[i * 2], otSetupCmds[i * 2 + 1])) {
break;
}
}
if (i != nCmds1) {
log_e("Sorry, OpenThread Network setup failed!");
rgbLedWrite(RGB_BUILTIN, 255, 0, 0); // RED ... failed!
return false;
}
Serial.println("OpenThread started.\r\nWaiting for activating correct Device Role.");
// wait for the expected Device Role to start
uint8_t tries = 24; // 24 x 2.5 sec = 1 min
while (tries && otGetDeviceRole() != expectedRole) {
Serial.print(".");
delay(2500);
tries--;
}
Serial.println();
if (!tries) {
log_e("Sorry, Device Role failed by timeout! Current Role: %s.", otGetStringDeviceRole());
rgbLedWrite(RGB_BUILTIN, 255, 0, 0); // RED ... failed!
return false;
}
Serial.printf("Device is %s.\r\n", otGetStringDeviceRole());
for (i = 0; i < nCmds2; i++) {
if (!otExecCommand(otCoapCmds[i * 2], otCoapCmds[i * 2 + 1])) {
break;
}
}
if (i != nCmds2) {
log_e("Sorry, OpenThread CoAP setup failed!");
rgbLedWrite(RGB_BUILTIN, 255, 0, 0); // RED ... failed!
return false;
}
Serial.println("OpenThread setup done. Node is ready.");
// all fine! LED goes Green
rgbLedWrite(RGB_BUILTIN, 0, 64, 8); // GREEN ... Lamp is ready!
return true;
}
void setupNode() {
// tries to set the Thread Network node and only returns when succeeded
bool startedCorrectly = false;
while (!startedCorrectly) {
startedCorrectly |=
otDeviceSetup(otSetupLeader, sizeof(otSetupLeader) / sizeof(char *) / 2, otCoapLamp, sizeof(otCoapLamp) / sizeof(char *) / 2, OT_ROLE_LEADER);
if (!startedCorrectly) {
Serial.println("Setup Failed...\r\nTrying again...");
}
}
}
// this function is used by the Lamp mode to listen for CoAP frames from the Switch Node
void otCOAPListen() {
// waits for the client to send a CoAP request
char cliResp[256] = {0};
size_t len = OThreadCLI.readBytesUntil('\n', cliResp, sizeof(cliResp));
cliResp[len - 1] = '\0';
if (strlen(cliResp)) {
String sResp(cliResp);
// cliResp shall be something like:
// "coap request from fd0c:94df:f1ae:b39a:ec47:ec6d:15e8:804a PUT with payload: 30"
// payload may be 30 or 31 (HEX) '0' or '1' (ASCII)
log_d("Msg[%s]", cliResp);
if (sResp.startsWith("coap request from") && sResp.indexOf("PUT") > 0) {
char payload = sResp.charAt(sResp.length() - 1); // last character in the payload
log_i("CoAP PUT [%s]\r\n", payload == '0' ? "OFF" : "ON");
if (payload == '0') {
for (int16_t c = 248; c > 16; c -= 8) {
rgbLedWrite(RGB_BUILTIN, c, c, c); // ramp down
delay(5);
}
rgbLedWrite(RGB_BUILTIN, 0, 0, 0); // Lamp Off
} else {
for (int16_t c = 16; c < 248; c += 8) {
rgbLedWrite(RGB_BUILTIN, c, c, c); // ramp up
delay(5);
}
rgbLedWrite(RGB_BUILTIN, 255, 255, 255); // Lamp On
}
}
}
}
void setup() {
Serial.begin(115200);
// LED starts RED, indicating not connected to Thread network.
rgbLedWrite(RGB_BUILTIN, 64, 0, 0);
OThreadCLI.begin(false); // No AutoStart is necessary
OThreadCLI.setTimeout(250); // waits 250ms for the OpenThread CLI response
setupNode();
// LED goes Green when all is ready and Red when failed.
}
void loop() {
otCOAPListen();
delay(10);
}