@yjay Have your referred to this document which provided information on Individual as well as Group enrollments with IoT Central.
Get connected to Azure IoT Central
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
We have successfully connected a device to IoT central but we are wondering how we can connect multiple devices automatically?
So far we have bulk imported our devices using a csv following Manage devices in your Azure IoT Central application
We are able to auto generate the SaS Token but we are still manually inputting the connection string.
private static String connString = "HostName=iotc-XXXXXX.azure-devices.net;DeviceId=testAll;SharedAccessKey=XXXXXXXXXX";
We are wondering if there is a way to auto generate the connection string or other ways to connect multiple devices without having to customize our app for every device(200+ devices)?
Thanks so much!
Here is the code that auto generates the SaS Token and sends data to IoT central:
public class MyConnection {
//Based on https://github.com/Azure/azure-iot-sdk-java/blob/master/device/iot-device-samples/send-receive-sample/src/main/java/samples/com/microsoft/azure/sdk/iot/SendReceive.java
private static String myData = null;
// The device connection string to authenticate the device with your IoT hub.
// Using the Azure CLI:
// az iot hub device-identity show-connection-string --hub-name {YourIoTHubName} --device-id MyJavaDevice --output table
private static String connString = "HostName=iotc-XXXXXX.azure-devices.net;DeviceId=testAll;SharedAccessKey=XXXXXXXXXX";
// Using the HTTPS protocol to connect to IoT Hub
private static IotHubClientProtocol protocol = IotHubClientProtocol.HTTPS;
private static DeviceClient client;
//Constructor
public MyConnection(String hrData) throws IOException, URISyntaxException {
this.myData = myData;
}
// Specify the telemetry to send to your IoT hub.
private static class TelemetryDataPoint {
public String Temp;
// Serialize object to JSON format.
public String serialize() {
Gson gson = new Gson();
return gson.toJson(this);
}
}
private static final int D2C_MESSAGE_TIMEOUT = 100; //miliseconds, to send data
private static final List<String> failedMessageListOnClose = new ArrayList<>(); // List of messages that failed on close
/** Used as a counter in the message callback. */
protected static class Counter
{
protected int num;
public Counter(int num)
{
this.num = num;
}
public int get()
{
return this.num;
}
public void increment()
{
this.num++;
}
@Override
public String toString()
{
return Integer.toString(this.num);
}
}
protected static class MessageCallback
implements com.microsoft.azure.sdk.iot.device.MessageCallback
{
public IotHubMessageResult execute(Message msg,
Object context)
{
Counter counter = (Counter) context;
System.out.println(
"Received message " + counter.toString()
+ " with content: " + new String(msg.getBytes(), Message.DEFAULT_IOTHUB_MESSAGE_CHARSET));
for (MessageProperty messageProperty : msg.getProperties())
{
System.out.println(messageProperty.getName() + " : " + messageProperty.getValue());
}
int switchVal = counter.get() % 3;
IotHubMessageResult res;
switch (switchVal)
{
case 0:
res = IotHubMessageResult.COMPLETE;
break;
case 1:
res = IotHubMessageResult.ABANDON;
break;
case 2:
res = IotHubMessageResult.REJECT;
break;
default:
// should never happen.
throw new IllegalStateException(
"Invalid message result specified.");
}
System.out.println(
"Responding to message " + counter.toString()
+ " with " + res.name());
counter.increment();
return res;
}
}
//comment
protected static class EventCallback implements IotHubEventCallback
{
public void execute(IotHubStatusCode status, Object context)
{
Message msg = (Message) context;
System.out.println("IoT Hub responded to message "+ msg.getMessageId() + " with status " + status.name());
if (status==IotHubStatusCode.MESSAGE_CANCELLED_ONCLOSE)
{
failedMessageListOnClose.add(msg.getMessageId());
}
}
}
//comment
protected static class IotHubConnectionStatusChangeCallbackLogger implements IotHubConnectionStatusChangeCallback
{
@Override
public void execute(IotHubConnectionStatus status, IotHubConnectionStatusChangeReason statusChangeReason, Throwable throwable, Object callbackContext)
{
System.out.println();
System.out.println("CONNECTION STATUS UPDATE: " + status);
System.out.println("CONNECTION STATUS REASON: " + statusChangeReason);
System.out.println("CONNECTION STATUS THROWABLE: " + (throwable == null ? "null" : throwable.getMessage()));
System.out.println();
if (throwable != null)
{
throwable.printStackTrace();
}
if (status == IotHubConnectionStatus.DISCONNECTED)
{
System.out.println("The connection was lost, and is not being re-established." +
" Look at provided exception for how to resolve this issue." +
" Cannot send messages until this issue is resolved, and you manually re-open the device client");
}
else if (status == IotHubConnectionStatus.DISCONNECTED_RETRYING)
{
System.out.println("The connection was lost, but is being re-established." +
" Can still send messages, but they won't be sent until the connection is re-established");
}
else if (status == IotHubConnectionStatus.CONNECTED)
{
System.out.println("The connection was successfully established. Can send messages.");
}
}
}
//main, call all methods
public void main() throws IOException, URISyntaxException {
// Connect to the IoT hub.
client = new DeviceClient(connString, protocol);
MessageCallback callback = new MessageCallback();
Counter counter = new Counter(0);
client.setMessageCallback(callback, counter);
System.out.println("Successfully set message callback.");
// Set your token expiry time limit here
long time = 60; //seconds or miliseconds?
client.setOption("SetSASTokenExpiryTime", time);
client.registerConnectionStatusChangeCallback(new IotHubConnectionStatusChangeCallbackLogger(), new Object());
client.open();
System.out.println("Opened connection to IoT Hub.");
System.out.println("Beginning to receive messages...");
System.out.println("Sending the following event messages: ");
System.out.println("Updated token expiry time to " + time);
//Create the telemetry data
TelemetryDataPoint telemetryDataPoint = new TelemetryDataPoint();
telemetryDataPoint.Temp = temp;
//Serialize the telemetry data
String msgStr = telemetryDataPoint.serialize();
try
{
//Create the payload
Message msg = new Message(msgStr); //create the message
msg.setContentTypeFinal("application/json"); //Content type
msg.setMessageId(java.util.UUID.randomUUID().toString()); //message id
msg.setExpiryTime(D2C_MESSAGE_TIMEOUT); //message expire in D2C_MESSAGE_TIMEOUT seconds
System.out.println(msgStr);
EventCallback eventCallback = new EventCallback();
client.sendEventAsync(msg, eventCallback, msg); //send message
}
catch (Exception e)
{
e.printStackTrace(); // Trace the exception
}
System.out.println("Wait for " + D2C_MESSAGE_TIMEOUT / 1000 + " second(s) for response from the IoT Hub...");
// Wait for IoT Hub to respond.
try
{
Thread.sleep(D2C_MESSAGE_TIMEOUT);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("In receive mode. Waiting for receiving C2D messages (only for MQTT and AMQP). Press ENTER to close. To recieve in Https, send message and then start the sample.");
// close the connection
System.out.println("Closing");
client.closeNow();
if (!failedMessageListOnClose.isEmpty())
{
System.out.println("List of messages that were cancelled on close:" + failedMessageListOnClose.toString());
}
System.out.println("Shutting down...");
}
}
@yjay Have your referred to this document which provided information on Individual as well as Group enrollments with IoT Central.
Get connected to Azure IoT Central
@QuantumCache thanks so much for all your help. I had the pleasure of working with some Microsoft team members to come up with a solution. In order to not have to expose the group SaS Token we are using the Devices - Create Attestation api. We are using individual enrolment which allows us to choose our own device key by calling the attestation api. We are hashing our key in our app which then gets used in the connection string to connect the devices dynamically.
If anybody has any additional question about how we worked out this solution please feel free to tag or message me