IBM Watson IoT-无法使用ESP8266从带有参数的主题获得响应

问题描述 投票:0回答:1

从几天以来我一直在寻找这个问题:

我想使用Watson IoT Platform和ESP32(或类似产品)做一个连接的设备(IoT)。该设备带有一些继电器。

在Watson仪表板上,我创建了设备类型,物理/逻辑接口,并将ESP与平台相连。

我在仪表板上创建了一个自定义动作,该自定义动作具有用于标识要切换的继电器的参数(switch2)以及一个不带参数的简单自定义动作(switch)。

问题是,如果生成不带参数(开关)的动作,则会看到回调打印,如果生成带参数(开关2)的动作,则什么也不会发生。我还尝试使用内置的Watson操作“固件更新/下载”,如果我使用固件下载(想要某些参数,例如uri,版本等),则没有任何反应,如果我使用固件更新(不使用)需要参数),我看到订阅的回调。

在这里您可以看到类似ESP的代码arduino

// --------------- HEADERS -------------------
#include <Arduino_JSON.h>

#include <EEPROM.h>

#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>

#include <PubSubClient.h> //https://github.com/knolleary/pubsubclient/releases/tag/v2.3

WebServer server(80);

char wifi_ssid[100] = "xxxxxx";
char wifi_psw[200] = "xxxxxxx";

// ----- Watson IBM parameters
#define ORG "xxxx"
#define DEVICE_TYPE "Relay"
#define DEVICE_ID "xxxx"
#define TOKEN "xxxxxxxxxxxxxxxx"

char ibmServer[] = ORG ".messaging.internetofthings.ibmcloud.com";
char authMethod[] = "use-token-auth";
char token[] = TOKEN;
char clientId[] = "d:" ORG ":" DEVICE_TYPE ":" DEVICE_ID;

const char switchTopic[] = "iotdm-1/mgmt/custom/switch-actions-v1/switch2";
const char testTopic[] = "iotdm-1/mgmt/custom/switch-actions-v1/switch"; //"iot-2/cmd/+/fmt/+";
const char observeTopic[] = "iotdm-1/observe";
const char publishTopic[] = "iot-2/evt/status/fmt/json";
const char responseTopic[] = "iotdm-1/response";
const char deviceResponseTopic[] = "iotdevice-1/response";
const char manageTopic[] = "iotdevice-1/mgmt/manage";
const char updateTopic[] = "iotdm-1/mgmt/initiate/firmware/update";

void callback(char* topic, byte* payload, unsigned int payloadLength);

WiFiClient wifiClient;
PubSubClient client(ibmServer, 1883, callback, wifiClient);

bool outputEnable = false;
bool oldOutputEnable = false;

void setup() {
  // put your setup code here, to run once:
  //Init la porta seriale ed aspetta che si avii
  Serial.begin(115200);
  while(!Serial) {
    delay(1); 
  }

  setupWiFi();
}

void loop() {
  // put your main code here, to run repeatedly:
  if (!client.loop()) {
    mqttConnect();
    initManagedDevice();
  }

  delay(100);
}

// WiFi Settings

void setupWiFi() {
  bool state = false;
  Serial.println("---- Setup WiFi ----");
  Serial.println(wifi_ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(wifi_ssid, wifi_psw);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  mqttConnect();
  initManagedDevice();
  publishStatus();

  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(wifi_ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}

// IBM IoT
void mqttConnect() {
 if (!!!client.connected()) {
   Serial.print("Reconnecting MQTT client to "); Serial.println(ibmServer);
   while (!!!client.connect(clientId, authMethod, token)) {
     Serial.print(".");
     delay(500);
   }
   Serial.println();
 }
}

void initManagedDevice() {
 if (client.subscribe("iotdm-1/response")) {
   Serial.println("subscribe to responses OK");
 } else {
   Serial.println("subscribe to responses FAILED");
 }

 if (client.subscribe("iotdm-1/device/update")) {
   Serial.println("subscribe to update OK");
 } else {
   Serial.println("subscribe to update FAILED");
 }

 if (client.subscribe(observeTopic)) {
   Serial.println("subscribe to observe OK");
 } else {
   Serial.println("subscribe to observe FAILED");
 }

 if (client.subscribe(switchTopic)) {
   Serial.println("subscribe to switch OK");
 } else {
   Serial.println("subscribe to switch FAILED");
 }

 if (client.subscribe(testTopic)) {
   Serial.println("subscribe to Test OK");
 } else {
   Serial.println("subscribe to Test FAILED");
 }

 JSONVar root;
 JSONVar d;
 JSONVar supports;
 supports["deviceActions"] = true;
 supports["firmwareActions"] = true;
 supports["switch-actions-v1"] = true;
 d["supports"] = supports;
 root["d"] = d;

 char buff[300] = "";
 JSON.stringify(root).toCharArray(buff, 300);

 Serial.println("publishing device metadata:"); Serial.println(buff);
 if (client.publish(manageTopic, buff)) {
   Serial.println("device Publish ok");
 } else {
   Serial.print("device Publish failed:");
 }
}

void callback(char* topic, byte* payload, unsigned int payloadLength) {
 Serial.print("callback invoked for topic: "); Serial.println(topic);

 if (strcmp (responseTopic, topic) == 0) {
   return; // just print of response for now
 }

 if (strcmp (updateTopic, topic) == 0) {
   handleUpdate(payload);
 }

 if (strcmp(switchTopic, topic) == 0) {
  handleRemoteSwitch(payload);
 }

 if(strcmp(observeTopic, topic) == 0) {
  handleObserve(payload);
 }
}

void sendSuccessResponse(const char* reqId) {
  JSONVar payload;
  payload["rc"] = 200;
  payload["reqId"] = reqId;

  char buff[300] = "";
  JSON.stringify(payload).toCharArray(buff, 300);

  if (client.publish(deviceResponseTopic, buff)) {
    Serial.println("Success sended");
  } else {
    Serial.print("Success failed:");
  }
}

void publishStatus() {
 String payload = "{\"relayStatus\":";
 payload += outputEnable;
 payload += "}";

 Serial.print("Sending payload: "); Serial.println(payload);

 if (client.publish(publishTopic, (char*) payload.c_str())) {
   Serial.println("Publish OK");
 } else {
   Serial.println("Publish FAILED");
 }
}

void handleUpdate(byte* payload) {
  Serial.println("handle Update");
}

void handleObserve(byte* payload) {
  JSONVar request = JSON.parse((char*)payload);
  JSONVar d = request["d"];
  JSONVar fields = d["fields"];
  const char* field = fields[0]["field"];

  if(strcmp(field, "mgmt.firmware") == 0) {
    Serial.println("Upadete the firmware");
    sendSuccessResponse(request["reqId"]);

  } else {
    Serial.println("Unmanaged observe");
    Serial.println(request);
  }
}

void handleRemoteSwitch(byte* payload) {
  Serial.println("handle remote switching");
  //invertedSwitch = !invertedSwitch;
  outputEnable = !outputEnable;

  JSONVar request = JSON.parse((char*)payload);
  const char* id = request["reqId"];
  sendSuccessResponse(id);
}

感谢所有想帮助我的人。

ibm-watson esp8266 esp32 watson-iot
1个回答
0
投票

几天后,我解决了这个问题,我在这里发布了针对同样问题的人的回复:

问题是PubSubClient库,该库仅接受128字节的响应消息(包括标头)。 Watson IBM产生的响应消息比128字节长。

要更改响应消息的缓冲区大小,您需要在行上修改PubSubClient.h文件

#define MQTT_MAX_PACKET_SIZE 128

并使用更大的数字(例如1024)更改128字节。

© www.soinside.com 2019 - 2024. All rights reserved.