Skip to content

Commit 57e2fec

Browse files
committed
Added DPS and Device Twins support
1 parent 3f71b80 commit 57e2fec

File tree

3 files changed

+135
-47
lines changed

3 files changed

+135
-47
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.microsoft.samples.iot.sensorbox;
2+
3+
import com.microsoft.samples.iot.opensense.dto.SenseBoxValues;
4+
5+
import org.apache.commons.logging.Log;
6+
import org.apache.commons.logging.LogFactory;
7+
import org.springframework.beans.factory.annotation.Autowired;
8+
import org.springframework.beans.factory.annotation.Value;
9+
import org.springframework.boot.ApplicationArguments;
10+
import org.springframework.boot.ApplicationRunner;
11+
import org.springframework.stereotype.Component;
12+
13+
@Component
14+
public class AppStartupRunner implements ApplicationRunner {
15+
16+
private static final Log logger = LogFactory.getLog(SingleBoxSchedulerConfiguration.class);
17+
18+
@Autowired
19+
private IoTHubSender sender;
20+
21+
@Autowired
22+
private OpenSenseMapReader reader;
23+
24+
@Value("${opensensemap.publisher.boxid}")
25+
private String sensorBoxID;
26+
27+
@Override
28+
public void run(ApplicationArguments args) throws Exception {
29+
30+
logger.info("Your application started with option names : "+ args.getOptionNames());
31+
32+
SenseBoxValues values = reader.readLatestValues(this.sensorBoxID);
33+
this.sender.reportSettings(values);
34+
}
35+
36+
}

sensorbox-publisher/src/main/java/com/microsoft/samples/iot/sensorbox/IoTHubSender.java

Lines changed: 97 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.text.ParseException;
77
import java.util.Date;
88
import java.util.HashMap;
9+
import java.util.HashSet;
910
import java.util.Locale;
1011
import java.util.Map;
1112
import java.util.function.BiConsumer;
@@ -17,6 +18,8 @@
1718
import com.microsoft.azure.sdk.iot.device.IotHubEventCallback;
1819
import com.microsoft.azure.sdk.iot.device.IotHubStatusCode;
1920
import com.microsoft.azure.sdk.iot.device.Message;
21+
import com.microsoft.azure.sdk.iot.device.DeviceTwin.Property;
22+
import com.microsoft.azure.sdk.iot.device.DeviceTwin.TwinPropertyCallBack;
2023
import com.microsoft.azure.sdk.iot.provisioning.device.ProvisioningDeviceClient;
2124
import com.microsoft.azure.sdk.iot.provisioning.device.ProvisioningDeviceClientRegistrationCallback;
2225
import com.microsoft.azure.sdk.iot.provisioning.device.ProvisioningDeviceClientRegistrationResult;
@@ -57,6 +60,17 @@ public class IoTHubSender {
5760

5861
private boolean sendOnlyNewer = true;
5962

63+
public void open() throws IOException {
64+
65+
this.deviceClient.open();
66+
this.deviceClient.startDeviceTwin(new DeviceTwinStatusCallBack(), null, new TwinPropertyCallBack(){
67+
@Override
68+
public void TwinPropertyCallBack(Property property, Object context) {
69+
logger.info("Desired property '" + property.getKey() + "' changed to '" + property.getValue() + "'. Ignoring");
70+
}
71+
}, null);
72+
}
73+
6074
/**
6175
*
6276
* @param latestValue
@@ -126,6 +140,7 @@ private boolean lastSentIsNotActual(final SenseBoxValues latestValue) {
126140
return this.lastSent.getLastMeasurementAt().before(latestValue.getLastMeasurementAt());
127141
}
128142

143+
@SuppressWarnings("unchecked")
129144
private static class EventCallback implements IotHubEventCallback {
130145
public void execute(IotHubStatusCode status, Object context) {
131146

@@ -143,6 +158,15 @@ public void execute(IotHubStatusCode status, Object context) {
143158
}
144159
}
145160

161+
// DeviceTwin status updates
162+
protected static class DeviceTwinStatusCallBack implements IotHubEventCallback {
163+
@Override
164+
public void execute(IotHubStatusCode status, Object context) {
165+
if (status != IotHubStatusCode.OK_EMPTY)
166+
logger.debug("IoT Hub responded to device twin operation with status " + status.name());
167+
}
168+
}
169+
146170
private SensorBoxValuesMessage createPayloadMessageFor(@NonNull final SenseBoxValues latestValue) {
147171

148172
NumberFormat format = NumberFormat.getInstance(Locale.US);
@@ -180,11 +204,15 @@ private SensorBoxValuesMessage createPayloadMessageFor(@NonNull final SenseBoxVa
180204

181205
private static final int MAX_TIME_TO_WAIT_FOR_REGISTRATION = 10000; // in milli seconds
182206

183-
public void setupWithDPS(String dpsScopeID, String deviceID, String deviceKey) throws IOException {
207+
/**
208+
*
209+
*/
210+
public void setupWithDPS(@NonNull final String dpsScopeID, @NonNull final String deviceID,
211+
@NonNull final String deviceKey) throws IOException {
184212

185213
DeviceClient iothubClient = null;
186-
SecurityProviderSymmetricKey securityClientSymmetricKey = new SecurityProviderSymmetricKey(
187-
deviceKey.getBytes(), deviceID);
214+
SecurityProviderSymmetricKey securityClientSymmetricKey = new SecurityProviderSymmetricKey(deviceKey.getBytes(),
215+
deviceID);
188216
ProvisioningDeviceClient provisioningDeviceClient = null;
189217

190218
try {
@@ -194,84 +222,108 @@ public void setupWithDPS(String dpsScopeID, String deviceID, String deviceKey) t
194222
dpsScopeID, ProvisioningDeviceClientTransportProtocol.HTTPS, securityClientSymmetricKey);
195223
provisioningDeviceClient.registerDevice(new ProvisioningDeviceClientRegistrationCallbackImpl(),
196224
provisioningStatus);
197-
while (provisioningStatus.provisioningDeviceClientRegistrationInfoClient
198-
.getProvisioningDeviceClientStatus() != ProvisioningDeviceClientStatus.PROVISIONING_DEVICE_STATUS_ASSIGNED) {
199-
if (provisioningStatus.provisioningDeviceClientRegistrationInfoClient
200-
.getProvisioningDeviceClientStatus() == ProvisioningDeviceClientStatus.PROVISIONING_DEVICE_STATUS_ERROR
201-
|| provisioningStatus.provisioningDeviceClientRegistrationInfoClient
202-
.getProvisioningDeviceClientStatus() == ProvisioningDeviceClientStatus.PROVISIONING_DEVICE_STATUS_DISABLED
203-
|| provisioningStatus.provisioningDeviceClientRegistrationInfoClient
204-
.getProvisioningDeviceClientStatus() == ProvisioningDeviceClientStatus.PROVISIONING_DEVICE_STATUS_FAILED) {
205-
provisioningStatus.exception.printStackTrace();
206-
System.out.println("Registration error, bailing out");
207-
break;
225+
226+
while (provisioningStatus.status() != ProvisioningDeviceClientStatus.PROVISIONING_DEVICE_STATUS_ASSIGNED) {
227+
if (provisioningStatus.status() == ProvisioningDeviceClientStatus.PROVISIONING_DEVICE_STATUS_ERROR
228+
|| provisioningStatus
229+
.status() == ProvisioningDeviceClientStatus.PROVISIONING_DEVICE_STATUS_DISABLED
230+
|| provisioningStatus
231+
.status() == ProvisioningDeviceClientStatus.PROVISIONING_DEVICE_STATUS_FAILED) {
232+
233+
logger.error("Device provisioning error", provisioningStatus.exception);
234+
throw new IOException("Device provisioning error", provisioningStatus.exception);
208235
}
209-
System.out.println("Waiting for Provisioning Service to register");
236+
210237
Thread.sleep(MAX_TIME_TO_WAIT_FOR_REGISTRATION);
211238
}
212239

213-
if (provisioningStatus.provisioningDeviceClientRegistrationInfoClient
214-
.getProvisioningDeviceClientStatus() == ProvisioningDeviceClientStatus.PROVISIONING_DEVICE_STATUS_ASSIGNED) {
215-
216-
System.out.println("IotHUb Uri : "
217-
+ provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getIothubUri());
218-
System.out.println("Device ID : "
219-
+ provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getDeviceId());
240+
if (provisioningStatus.status() == ProvisioningDeviceClientStatus.PROVISIONING_DEVICE_STATUS_ASSIGNED) {
241+
242+
logger.info("Device provisioned with ID '" + provisioningStatus.result.getDeviceId()
243+
+ "' and registered at IoT Hub '" + provisioningStatus.result.getIothubUri() + "'");
220244

221245
// connect to iothub
222-
String iotHubUri = provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getIothubUri();
223-
String deviceId = provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getDeviceId();
246+
String iotHubUri = provisioningStatus.result.getIothubUri();
247+
String deviceId = provisioningStatus.result.getDeviceId();
224248
try {
225249
iothubClient = DeviceClient.createFromSecurityProvider(iotHubUri, deviceId,
226250
securityClientSymmetricKey, IotHubClientProtocol.AMQPS);
227251
iothubClient.open();
228252
} catch (IOException | URISyntaxException e) {
229-
System.out.println("Device client threw an exception: " + e.getMessage());
253+
254+
logger.error("Open connection to IoT Hub threw an exception", e);
255+
230256
if (iothubClient != null) {
231257
iothubClient.closeNow();
232258
}
259+
if (e instanceof IOException)
260+
throw (IOException) e;
261+
else
262+
throw new IOException("Open connection to IoT Hub threw an exception", e);
233263
}
234264
this.deviceClient = iothubClient;
265+
} else {
266+
logger.error("Provisioning Device Client returned error ");
267+
throw new IOException("Provisioning Device Client returned error ");
235268
}
236269
} catch (ProvisioningDeviceClientException | InterruptedException e) {
237270

238-
System.out.println("Provisioning Device Client threw an exception" + e.getMessage());
271+
logger.error("Provisioning Device Client threw an exception", e);
272+
throw new IOException("Provisioning Device Client threw an exception", e);
273+
} finally {
274+
239275
if (provisioningDeviceClient != null) {
240276
provisioningDeviceClient.closeNow();
241277
}
242-
243-
throw new RuntimeException(e);
244-
}
245-
246-
if (provisioningDeviceClient != null) {
247-
provisioningDeviceClient.closeNow();
248278
}
249279
}
250280

251-
static class ProvisioningStatus
252-
{
253-
ProvisioningDeviceClientRegistrationResult provisioningDeviceClientRegistrationInfoClient = new ProvisioningDeviceClientRegistrationResult();
281+
static class ProvisioningStatus {
282+
ProvisioningDeviceClientRegistrationResult result = new ProvisioningDeviceClientRegistrationResult();
254283
Exception exception;
284+
285+
public ProvisioningDeviceClientStatus status() {
286+
return result.getProvisioningDeviceClientStatus();
287+
};
255288
}
256289

257-
static class ProvisioningDeviceClientRegistrationCallbackImpl implements ProvisioningDeviceClientRegistrationCallback
258-
{
290+
static class ProvisioningDeviceClientRegistrationCallbackImpl
291+
implements ProvisioningDeviceClientRegistrationCallback {
259292
@Override
260-
public void run(ProvisioningDeviceClientRegistrationResult provisioningDeviceClientRegistrationResult, Exception exception, Object context)
261-
{
262-
if (context instanceof ProvisioningStatus)
263-
{
293+
public void run(ProvisioningDeviceClientRegistrationResult provisioningDeviceClientRegistrationResult,
294+
Exception exception, Object context) {
295+
if (context instanceof ProvisioningStatus) {
264296
ProvisioningStatus status = (ProvisioningStatus) context;
265-
status.provisioningDeviceClientRegistrationInfoClient = provisioningDeviceClientRegistrationResult;
297+
status.result = provisioningDeviceClientRegistrationResult;
266298
status.exception = exception;
267-
}
268-
else
269-
{
299+
} else {
270300
System.out.println("Received unknown context");
271301
}
272302
}
273303
}
274304

305+
public void reportSettings(@NonNull final SenseBoxValues fromValues) throws IllegalArgumentException, IOException {
306+
307+
HashSet<Property> set = new HashSet<>();
308+
set.add(new Property("manufacturer", "SenseBox")); // (manufacturer)
309+
set.add(new Property("model", fromValues.getModel())); // (model)
310+
//set.add(new Property("swVersion", "text")); // (swVersion)
311+
//set.add(new Property("osName", "text")); // (osName)
312+
//set.add(new Property("processorArchitecture", "text")); // (processorArchitecture)
313+
//set.add(new Property("processorManufacturer", "text")); // (processorManufacturer)
314+
//set.add(new Property("totalStorage", 1)); // (totalStorage) <- try another value!
315+
//set.add(new Property("totalMemory", 2)); // (totalMemory) <- try another value!
316+
//set.add(new Property("currentlocation", 10)); // (currentlocation) <- try another value!
317+
set.add(new Property("name", fromValues.getName())); // (name)
318+
set.add(new Property("_id", fromValues.getId())); // (_id)
319+
set.add(new Property("grouptag", fromValues.getGrouptag())); // (grouptag)
320+
set.add(new Property("exposure", fromValues.getExposure())); // (exposure) <- try another value!
321+
set.add(new Property("createdAt", fromValues.getCreatedAt())); // (createdAt) <- try another value!
322+
set.add(new Property("updatedAt", fromValues.getUpdatedAt()));// (updatedAt) <- try another value!
323+
324+
this.deviceClient.sendReportedProperties(set);
325+
}
326+
275327
public DeviceClient getDeviceClient() {
276328
return deviceClient;
277329
}

sensorbox-publisher/src/main/java/com/microsoft/samples/iot/sensorbox/SensorboxPublisherApplication.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public IoTHubSender createSenderFromConnectionString() throws IllegalArgumentExc
3939

4040
IoTHubSender ioTHubSender = new IoTHubSender();
4141
ioTHubSender.setDeviceClient(new DeviceClient(this.iotHubConnectionString, IotHubClientProtocol.AMQPS));
42-
ioTHubSender.getDeviceClient().open();
42+
ioTHubSender.open();
4343

4444
return ioTHubSender;
4545
}
@@ -50,7 +50,7 @@ public IoTHubSender createSenderFromDPS() throws IOException {
5050

5151
IoTHubSender ioTHubSender = new IoTHubSender();
5252
ioTHubSender.setupWithDPS(this.dpsScopeID, this.deviceID, this.deviceKey);
53-
ioTHubSender.getDeviceClient().open();
53+
ioTHubSender.open();
5454

5555
return ioTHubSender;
5656
}

0 commit comments

Comments
 (0)