Till now we were mostly sending data from ESP32 like devices to IBM Watson IoT. Opposite direction of commands often a practical need, such as to control a LED connected to device. In this context, knowledge of cURL commands (here is cURL for Windows, other way is using Windows 10 bash) for testing required. IBM has “HTTP Messaging APIs for devices” and ”
Extending device management”. We already know about HTTP POST and sent HTTP POST request from ESP32. Current use-case is reverse – we will use command line from some computer or server towards IBM Watson IoT to trigger event on device. The required two authentication parameters are the authentication token (which works as password) and API key (which works as username). API key can be collected from the web UI of IBM Watson IoT.
How To Send Commands to IBM Watson IoT to Trigger Event on Device
Documentation on this topic exists on official website (s) :
1 2 3 4 5 | https://console.bluemix.net/docs/services/IoT/applications/api.html https://console.bluemix.net/docs/services/IoT/GA_information_management/ga_im_index_scenario.html https://console.bluemix.net/docs/services/IoT/devices/device_cmd_api.html https://console.bluemix.net/docs/services/IoT/devices/device_mgmt/custom_actions.html https://docs.internetofthings.ibmcloud.com/apis/swagger/v0002/http-messaging.html |
Obviously, if we can use HTTP POST request from command line interface, we can create simple web applications for versatile control. Here is a sample code for ESP32 Arduino :
---
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 | #include <WiFi.h> #include <WiFiMulti.h> #include <PubSubClient.h> #include <HTTPClient.h> #include <base64.h> #define USE_SERIAL Serial #include <Ticker.h> // <------- CHANGE PARAMETERS BELOW THIS LINE ------------> const char* ssid = "change-it"; const char* password = "change-it"; #define ORG "change-it" #define DEVICE_TYPE "your-custom-name" #define DEVICE_ID "custom-name-change" #define TOKEN "your-token" #define DEVICE_BUTTON 0 // ESP32 onboard boot push button #define DEVICE_RELAY 2 // Onboard LED. Pin to control with command #define DEVICE_GREEN_LED 12 // optional #define DEVICE_RED_LED 14 // optional // <------- CHANGE PARAMETERS ABOVE THIS LINE ------------> // <------- STOP EDITING ------------> Ticker ledBlinker; char server[] = ORG ".messaging.internetofthings.ibmcloud.com"; char authMethod[] = "use-token-auth"; char token[] = TOKEN; char clientId[] = "d:" ORG ":" DEVICE_TYPE ":" DEVICE_ID; #define CMD_STATE "/gpio/" // use the '+' wildcard so it subscribes to any command with any message format const char commandTopic[] = "iot-2/cmd/+/fmt/+"; void gotMsg(char* topic, byte* payload, unsigned int payloadLength); WiFiClient wifiClient; PubSubClient client(server, 1883, gotMsg, wifiClient); int buttonPressDuration; void setup() { Serial.begin(115200); Serial.println(); pinMode(DEVICE_RELAY, OUTPUT); pinMode(DEVICE_GREEN_LED, OUTPUT); pinMode(DEVICE_RED_LED, OUTPUT); ledBlinker.attach(0.1, ledBlink); // fast blink indicates Wifi connecting wifiConnect(); ledBlinker.attach(0.4, ledBlink); // slower blink indicates MQTT connecting mqttConnect(); ledBlinker.detach(); digitalWrite(DEVICE_GREEN_LED, LOW); // low is led on to show connected pinMode(DEVICE_BUTTON, INPUT); attachInterrupt(DEVICE_BUTTON, buttonPress, CHANGE); } int lastHeartBeat; void loop() { if (buttonPressDuration > 0) { doCommand(digitalRead(DEVICE_RELAY) ? "off" : "on"); buttonPressDuration = 0; } if (!client.loop()) { mqttConnect(); } if (millis()-lastHeartBeat > 10000) { Serial.print("loop: gpio "); Serial.print(DEVICE_RELAY); Serial.print(" current state "); Serial.println(digitalRead(DEVICE_RELAY) ? "On" : "Off"); digitalWrite(DEVICE_GREEN_LED, HIGH); // flicker LED to show its active delay(200); digitalWrite(DEVICE_GREEN_LED, LOW); lastHeartBeat = millis(); } } void gotMsg(char* topic, byte* payload, unsigned int payloadLength) { Serial.print("gotMsg: invoked for topic: "); Serial.println(topic); if (String(topic).indexOf(CMD_STATE) > 0) { String cmd = ""; for (int i=0; i<payloadLength; i++) { cmd += (char)payload[i]; } doCommand(cmd); } else { Serial.print("gotMsg: unexpected topic: "); Serial.println(topic); } } void doCommand(String cmd) { int currentState = digitalRead(DEVICE_RELAY); int newState = (cmd == "on"); digitalWrite(DEVICE_RELAY, newState); Serial.print("Relay switched from "); Serial.print(currentState ? "On" : "Off");Serial.print(" to "); Serial.println(newState ? "On" : "Off"); } unsigned long startPress = 0; void buttonPress() { int currentState = digitalRead(DEVICE_BUTTON); if (currentState == 0) { // 0 is pressed, 1 is released startPress = millis(); } else { int diff = millis() - startPress; if (diff > 100) { // debounce buttonPressDuration = diff; } } Serial.print("Button "); Serial.print(currentState ? "released" : "pressed"); Serial.print(" duration="); Serial.println(buttonPressDuration); } void ledBlink() { digitalWrite(DEVICE_GREEN_LED, ! digitalRead(DEVICE_GREEN_LED)); } void wifiConnect() { Serial.print("Connecting to "); Serial.print(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.print("\nWiFi connected, IP address: "); Serial.println(WiFi.localIP()); } void mqttConnect() { if (!!!client.connected()) { Serial.print("Reconnecting MQTT client to "); Serial.println(server); while (!!!client.connect(clientId, authMethod, token)) { Serial.print("."); delay(500); } Serial.println(); } subscribeTo(commandTopic); } void subscribeTo(const char* topic) { Serial.print("subscribe to "); Serial.print(topic); if (client.subscribe(topic)) { Serial.println(" OK"); } else { Serial.println(" FAILED"); } } |
The above code is adapted for ESP32 from this recipe :
1 | https://developer.ibm.com/recipes/tutorials/build-your-own-watson-controlled-kettle/ |
Here, if we press the on-board button of ESP32, the on-board LED on ESP32 will glow. The above is reference diagram of attaching external push button for need more than basic.
We can remotely control it using cURL in this format :
1 2 3 4 5 6 7 8 | # switch ON curl -u <yourApiKey>:<yourApiPassword> -H "Content-Type: text/plain" -v -X POST http://<yourOrg>.messaging.internetofthings.ibmcloud.com:1883/api/v0002/ application/types/<yourDeviceType>/devices/<yourDeviceId>/commands/gpio -d "on" # switch OFF curl -u <yourApiKey>:<yourApiPassword> -H "Content-Type: text/plain" -v -X POST http://<yourOrg>.messaging.internetofthings.ibmcloud.com:1883/api/v0002/ application/types/<yourDeviceType>/devices/<yourDeviceId>/commands/gpio -d "off" |
That is it. You need some work with command line by sending data to get used.
Tagged With http curl iot devices , ibm iot get latest event from device , ibm watson iot device command cache , iot watson api send command