Search code examples
androidnode.jsibm-cloudiot

IBM Bluemix IoT Topics/URL, different for Android vs Node.js, clarification required?


I am using an IoT service in Bluemix, and am connecting to it with a Node.js express server and an Android device.

The Android app is based on the ibmiot starter app(https://github.com/ibm-messaging/iot-starter-for-android). This connects with:
URL: <org>.messaging.internetofthings.ibmcloud.com:1883
Topic format: iot-2/cmd/+/fmt/json
Credentials: organization, deviceType, deviceId

The express server connects with the npm ibmiotf module, version 0.2.2. Connects with:
URL: <org>.messaging.internetofthings.ibmcloud.com:8883
Topic format: iot-2/type/<type>/id/<id>/cmd/<cmd>/fmt/json
Credentials: organization, id (Bluemix space name?), apiKey, apiToken

If I try to subscribe to a topic in the second format with the Android app, I am disconnected from the service due to the topic not being valid. However, the provided object (ApplicationClient) from the npm node contains functions such as publishDeviceCommand(deviceType, deviceId, commandType, format, data)
which publishes to a topic in the second format, which the app cannot subscribe to. Is this reformatting of the topic styles due to different versions?

So, how can I publish to a valid topic with the express server that the app can subscribe to? Does this require writing my own version of publishDeviceCommand? This is feasible, but does not seem ideal. It also is a function within the provided npm module, changes would only be local and not remote.

I can view events that the app publishes to topics in the first format through the service Dashboard, but I cannot see the same for the express ApplicationClient - perhaps because it is not a registered device?


Solution

  • The difference here is that you are using the ibmiotf node.js package to connect to the IoT service in Bluemix as an application, while the Android app is connecting as a device.

    When connecting as a device, you use a topic with the format

    iot-2/cmd/<command_id>/fmt/<format>
    

    or

    iot-2/evt/<event_id>/fmt/<format>
    

    When connecting as an application, you use a topic with the format

    iot-2/type/<deviceType>/id/<deviceId>/cmd/<command_id>/fmt/<format>
    

    or

    iot-2/type/<deviceType>/id/<deviceId>/evt/<event_id>/fmt/<format>
    

    What this means is that an application can publish and subscribe to any device in your organization, but a device can only publish and subscribe to topics specific to itself.

    If the android app connects with deviceType=Android, deviceID=myTestDevice and then subscribes to

    iot-2/cmd/updates/fmt/json
    

    and the node.js app publishes to

    iot-2/type/Android/id/myTestDevice/cmd/updates/fmt/json
    

    then the device will receive the message.

    https://docs.internetofthings.ibmcloud.com/messaging/devices.html

    https://docs.internetofthings.ibmcloud.com/messaging/applications.html