66import java .text .ParseException ;
77import java .util .Date ;
88import java .util .HashMap ;
9+ import java .util .HashSet ;
910import java .util .Locale ;
1011import java .util .Map ;
1112import java .util .function .BiConsumer ;
1718import com .microsoft .azure .sdk .iot .device .IotHubEventCallback ;
1819import com .microsoft .azure .sdk .iot .device .IotHubStatusCode ;
1920import 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 ;
2023import com .microsoft .azure .sdk .iot .provisioning .device .ProvisioningDeviceClient ;
2124import com .microsoft .azure .sdk .iot .provisioning .device .ProvisioningDeviceClientRegistrationCallback ;
2225import 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 }
0 commit comments