Skip to content

Commit bdde3b2

Browse files
committed
Adding support for device method
1 parent 7c9d971 commit bdde3b2

9 files changed

Lines changed: 180 additions & 9 deletions

File tree

.vscode/arduino.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"board": "esp32:esp32:esp32",
3-
"sketch": "sample/device.ino",
3+
"sketch": "examples\\ESP32_Device_OTA\\ESP32_Device_OTA.ino",
44
"output": "./.build",
55
"programmer": "AVR ISP",
66
"port": "COM3",

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
"deque": "cpp",
1313
"string": "cpp",
1414
"vector": "cpp",
15-
"unordered_map": "cpp"
15+
"unordered_map": "cpp",
16+
"*.tcc": "cpp"
1617
},
1718
"cmake.configureOnOpen": false
1819
}

examples/ESP32_Device_OTA/ESP32_Device_OTA.ino

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88

99
#define DEFAULT_TELEMETRY_FREQUENCY 5000
1010

11-
#define FIRMWARE_VERSION "0.0.1"
11+
#define FIRMWARE_VERSION "0.0.2"
1212

1313
DHTesp dht;
1414

15+
bool rebootRequired;
16+
1517
DynamicJsonDocument CheckPropertiesState()
1618
{
1719
bool hasChanged = false;
@@ -43,6 +45,18 @@ DynamicJsonDocument CheckPropertiesState()
4345
return propertiesState;
4446
}
4547

48+
int OnRebootInvoked(const unsigned char* payload, size_t size, unsigned char** response, size_t* response_size)
49+
{
50+
const char deviceMethodResponse[] = "{ \"acknowledged\": \"true\" }";
51+
*response_size = sizeof(deviceMethodResponse)-1;
52+
*response = (unsigned char *)malloc(*response_size);
53+
(void)memcpy(*response, deviceMethodResponse, *response_size);
54+
55+
rebootRequired = true;
56+
57+
return 200;
58+
}
59+
4660
void setup()
4761
{
4862
Serial.begin(115200);
@@ -52,12 +66,18 @@ void setup()
5266
// Wait for device connection
5367
while(!IoTDevice_IsConnected()) { }
5468

69+
IoTDevice_RegisterForMethodInvoke("reboot", OnRebootInvoked);
70+
5571
// début de la mesure
5672
dht.setup(15, DHTesp::DHT11);
5773
}
5874

5975
void loop()
6076
{
77+
if (rebootRequired) {
78+
ESP.restart();
79+
}
80+
6181
DynamicJsonDocument propertiesState = CheckPropertiesState();
6282
int waitTime = propertiesState["telemetry"]["frequency"] | DEFAULT_TELEMETRY_FREQUENCY;
6383

src/ESP32_AzureIoT_OTA.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ extern "C"
1717
#include "core/iot_device_connection.h"
1818
#include "core/iot_device_d2c.h"
1919
#include "core/iot_device_ota.h"
20+
#include "core/iot_device_method.h"
2021

2122
#ifdef __cplusplus
2223
} // extern "C"

src/core/iot_device_connection.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ static void IoTDevice_ConfigureOptions()
187187

188188
// Setting device twin callback
189189
(void)IoTHubDeviceClient_LL_SetDeviceTwinCallback(__hub_client_handle__, IoTDevice_DeviceTwinCallback, NULL);
190+
191+
IoTDevice_RegisterDeviceMethodCallback();
190192
}
191193

192194
static void IoTDevice_ConnectToHub(const char *connectionString)

src/core/iot_device_core.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ extern IOTHUB_CLIENT_LL_HANDLE __hub_client_handle__;
1717

1818
extern void IoTDevice_DeviceTwinCallback(DEVICE_TWIN_UPDATE_STATE update_state, const unsigned char *payLoad, size_t size, void *userContextCallback);
1919

20+
extern void IoTDevice_RegisterDeviceMethodCallback();
21+
2022
extern bool __twin_received__;
2123

2224
#ifdef __cplusplus

src/core/iot_device_d2c.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
#ifndef IOT_DEVICE_D2C_H
2-
#define IOT_DEVICE_D2C_H
3-
41
#include "logging.h"
52

63
#include "iot_device_d2c.h"
@@ -33,6 +30,4 @@ bool IoTDevice_Send(const char *message)
3330

3431
IoTHubDeviceClient_LL_DoWork(__hub_client_handle__);
3532
ThreadAPI_Sleep(3);
36-
}
37-
38-
#endif
33+
}

src/core/iot_device_method.cpp

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#include <ArduinoJson.h>
2+
3+
#include <AzureIoTHub.h>
4+
#include <SPIFFS.h>
5+
6+
#include "logging.h"
7+
#include "iot_device_core.h"
8+
#include "iot_device_method.h"
9+
10+
struct MethodCallback {
11+
const char* methodName;
12+
IOT_DEVICE_METHOD_CALLBACK callback;
13+
};
14+
15+
static MethodCallback methodCallbacks[IOT_DEVICE_MAX_METHOD_COUNT];
16+
static int registeredCount = 0;
17+
18+
static int IoTDevice_DeviceMethodCallback(const char* method_name, const unsigned char* payload, size_t size, unsigned char** response, size_t* response_size, void* userContextCallback)
19+
{
20+
(void)userContextCallback;
21+
(void)payload;
22+
(void)size;
23+
24+
bool methodFound = false;
25+
26+
int result;
27+
28+
Log_Debug("Direct method lookup: %s", method_name);
29+
30+
for(int i = 0; i < registeredCount; i++)
31+
{
32+
Log_Trace("Trying %s", methodCallbacks[i].methodName);
33+
34+
if (strcmp(methodCallbacks[i].methodName, method_name) == 0)
35+
{
36+
Log_Debug("Method callback for %s found. Executing", method_name);
37+
38+
methodFound = true;
39+
result = methodCallbacks[i].callback(payload, size, response, response_size);
40+
}
41+
}
42+
43+
if (!methodFound)
44+
{
45+
Log_Info("Method %s not registered!", method_name);
46+
const char deviceMethodResponse[] = "{ }";
47+
*response_size = sizeof(deviceMethodResponse)-1;
48+
*response = (unsigned char *)malloc(*response_size);
49+
(void)memcpy(*response, deviceMethodResponse, *response_size);
50+
result = -1;
51+
}
52+
53+
return result;
54+
}
55+
56+
int OnSystemInfoInvoked(const unsigned char* payload, size_t size, unsigned char** response, size_t* response_size)
57+
{
58+
String output;
59+
60+
DynamicJsonDocument doc(1024);
61+
62+
doc["chipRevision"] = ESP.getChipRevision();
63+
doc["cpuFreqMHz"] = ESP.getCpuFreqMHz();
64+
doc["cycleCount"] = ESP.getCycleCount();
65+
doc["sdkVersion"] = ESP.getSdkVersion();
66+
67+
doc["flashChip"]["size"] = ESP.getFlashChipSize();
68+
doc["flashChip"]["speed"] = ESP.getFlashChipSpeed();
69+
70+
doc["heap"]["size"] = ESP.getHeapSize(); //total heap size
71+
doc["heap"]["free"] = ESP.getFreeHeap(); //available heap
72+
doc["heap"]["minFree"] = ESP.getMinFreeHeap(); //lowest level of free heap since boot
73+
doc["heap"]["maxAlloc"] = ESP.getMaxAllocHeap(); //largest block of heap that can be allocated at once
74+
75+
doc["spi"]["size"] = ESP.getPsramSize();
76+
doc["spi"]["free"] = ESP.getFreePsram();
77+
doc["spi"]["minFree"] = ESP.getMinFreePsram();
78+
doc["spi"]["maxAlloc"] = ESP.getMaxAllocPsram();
79+
80+
doc["sketch"]["MD5"] = ESP.getSketchMD5();
81+
doc["sketch"]["size"] = ESP.getSketchSize();
82+
doc["sketch"]["space"] = ESP.getFreeSketchSpace();
83+
84+
doc["fs"]["usedBytes"] = SPIFFS.usedBytes();
85+
doc["fs"]["totalBytes"] = SPIFFS.totalBytes();
86+
87+
serializeJsonPretty(doc, output);
88+
89+
const char *deviceMethodResponse = output.c_str();
90+
*response_size = strlen(deviceMethodResponse);
91+
*response = (unsigned char *)malloc(*response_size);
92+
(void)memcpy(*response, deviceMethodResponse, *response_size);
93+
94+
return 200;
95+
}
96+
97+
void IoTDevice_RegisterDeviceMethodCallback(){
98+
(void)IoTHubClient_LL_SetDeviceMethodCallback(__hub_client_handle__, IoTDevice_DeviceMethodCallback, NULL);
99+
100+
IoTDevice_RegisterForMethodInvoke("systemInfo", OnSystemInfoInvoked);
101+
}
102+
103+
void IoTDevice_RegisterForMethodInvoke(const char *methodName, IOT_DEVICE_METHOD_CALLBACK callback) {
104+
Log_Debug("Registering method %s at index: %d", methodName, registeredCount);
105+
106+
if(registeredCount >= IOT_DEVICE_MAX_METHOD_COUNT)
107+
{
108+
Log_Error("Cannot regiter more than %d methods. Increase the IOT_DEVICE_MAX_METHOD_COUNT variable.", IOT_DEVICE_MAX_METHOD_COUNT);
109+
return;
110+
}
111+
112+
MethodCallback item = {
113+
.methodName = methodName,
114+
.callback = callback
115+
};
116+
117+
methodCallbacks[registeredCount] = item;
118+
registeredCount++;
119+
}

src/core/iot_device_method.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#ifndef __ESP32_AzureIoT_DEVICE_METHOD_H__
2+
#define __ESP32_AzureIoT_DEVICE_METHOD_H__
3+
4+
#include <stddef.h>
5+
6+
typedef int(*IOT_DEVICE_METHOD_CALLBACK)(const unsigned char* payload, size_t size, unsigned char** response, size_t* response_size);
7+
8+
9+
#ifndef IOT_DEVICE_MAX_METHOD_COUNT
10+
#define IOT_DEVICE_MAX_METHOD_COUNT 10
11+
#endif
12+
13+
#ifdef __cplusplus
14+
extern "C"
15+
{
16+
#endif
17+
18+
/**
19+
* @brief Register for Cloud To Device Method invoke.
20+
*
21+
* @param methodName Pointer to a character string containing the message to send.
22+
* @param callback Pointer to a method callback.
23+
*
24+
*/
25+
void IoTDevice_RegisterForMethodInvoke(const char *methodName, IOT_DEVICE_METHOD_CALLBACK callback);
26+
27+
#ifdef __cplusplus
28+
} // extern "C"
29+
#endif /* __cplusplus */
30+
31+
#endif

0 commit comments

Comments
 (0)