Skip to content

Commit 7861d70

Browse files
committed
Updates
1 parent ccef4ad commit 7861d70

File tree

4 files changed

+143
-95
lines changed

4 files changed

+143
-95
lines changed

articles/iot-hub/how-to-module-twins.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,16 @@ ms.custom: mqtt, devx-track-csharp, devx-track-dotnet
2222
This article shows you how to develop two types of applications:
2323

2424
* Device apps that view and update reported properties and handle requests to update module desired properties.
25-
* Service apps that can add modules and read and set new desired properties.
25+
* Service apps that can add modules, and read and set desired properties.
2626

2727
> [!NOTE]
2828
> This article is meant to complement [Azure IoT SDKs](iot-hub-devguide-sdks.md) samples that are referenced from within this article. You can use SDK tools to build both device and back-end applications.
2929
3030
## Prerequisites
3131

32-
* **An IoT hub**. Some SDK calls require the IoT Hub primary connection string, so make a note of the connection string.
33-
34-
* **A registered device**. Some SDK calls require the device primary connection string, so make a note of the connection string.
32+
* An IoT hub
33+
* An IoT hub device
34+
* An IoT hub device module identity
3535

3636
* If your application uses the MQTT protocol, make sure that **port 8883** is open in your firewall. The MQTT protocol communicates over port 8883. This port may be blocked in some corporate and educational network environments. For more information and ways to work around this issue, see [Connecting to IoT Hub (MQTT)](../iot/iot-mqtt-connect-to-iot-hub.md#connecting-to-iot-hub).
3737

includes/iot-hub-howto-module-twins-dotnet.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,13 @@ using Microsoft.Azure.Devices.Shared;
4242

4343
The [ModuleClient](/dotnet/api/microsoft.azure.devices.client.moduleclient) class exposes all the methods required to interact with module identity twins from the device.
4444

45-
Connect to the device using the [CreateFromConnectionString](/dotnet/api/microsoft.azure.devices.client.moduleclient.createfromconnectionstring) method with the module connection string. `CreateFromConnectionString` connects using the default AMQP transport.
45+
Connect to the device using the [CreateFromConnectionString](/dotnet/api/microsoft.azure.devices.client.moduleclient.createfromconnectionstring) method with the module connection string.
46+
For example:
47+
48+
Calling `CreateFromConnectionString` without a transport parameter connects using the default AMQP transport.
4649

4750
```csharp
48-
static string ModuleConnectionString = "{Device module connection string}";
51+
static string ModuleConnectionString = "{Device module identity connection string}";
4952
private static ModuleClient _moduleClient = null;
5053

5154
_moduleClient = ModuleClient.CreateFromConnectionString(ModuleConnectionString,
@@ -128,7 +131,10 @@ private async Task OnDesiredPropertyChangedAsync(TwinCollection desiredPropertie
128131

129132
### SDK module sample
130133

131-
The Azure IoT SDK for .NET provides a working sample of a device app that handles module identity twin tasks. For more information, see [TwinSample](https://github.com/Azure/azure-iot-sdk-csharp/tree/main/iothub/device/samples/getting%20started/TwinSample).
134+
The Azure IoT SDK for .NET provides working samples of device apps that handle module identity twin tasks. For more information, see:
135+
136+
* [TwinSample](https://github.com/Azure/azure-iot-sdk-csharp/tree/main/iothub/device/samples/getting%20started/TwinSample)
137+
* [Device Client Tests](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/iothub/device/tests/DeviceClientTests.cs)
132138

133139
## Create a backend application
134140

@@ -163,6 +169,8 @@ The SDK methods in this section require these shared access policy permissions:
163169

164170
As a parameter to `CreateFromConnectionString`, supply a shared access policy connection string that includes these permissions. For more information about shared access policies, see [Control access to IoT Hub with shared access signatures](/azure/iot-hub/authenticate-authorize-sas).
165171

172+
For example:
173+
166174
```csharp
167175
static RegistryManager registryManager;
168176
static string connectionString = "{IoT hub shared access policy connection string}";
@@ -199,7 +207,7 @@ Console.WriteLine("Generated module key: {0}", module.Authentication.SymmetricKe
199207

200208
Call [GetModuleAsync](/dotnet/api/microsoft.azure.devices.registrymanager.getmoduleasync) to retrieve current module identity twin fields into a [Module](/dotnet/api/microsoft.azure.devices.module) object.
201209

202-
The `Module` class includes [properties](/dotnet/api/microsoft.azure.devices.shared.twin?&#properties) that correspond to sections of an identity module twin. Use the `Module` class properties to view and update module identity twin fields. You can use the `Module` object properties to update multiple fields before writing the updates to the device using `UpdateModuleAsync`.
210+
The `Module` class includes `properties` that correspond to sections of an identity module twin. Use the Module class properties to view and update module identity twin fields. You can use the `Module` object properties to update multiple fields before writing the updates to the device using `UpdateModuleAsync`.
203211

204212
After making module identity twin field updates, call [UpdateModuleAsync](/dotnet/api/microsoft.azure.devices.registrymanager.updatemoduleasync) to write `Module` object field updates back to a device. Use `try` and `catch` logic coupled with an error handler to catch incorrectly formatted patch errors from `UpdateModuleAsync`.
205213

includes/iot-hub-howto-module-twins-node.md

Lines changed: 113 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ ms.author: kgremban
77
ms.service: iot-hub
88
ms.devlang: nodejs
99
ms.topic: include
10-
ms.date: 09/03/2024
10+
ms.date: 10/02/2024
1111
ms.custom: mqtt, devx-track-js
1212
---
1313

@@ -22,8 +22,8 @@ Device applications can read and write module identity twin reported properties,
2222
This section describes how to use the [azure-iot-device](/javascript/api/azure-iot-device) package in the Azure IoT SDK for Node.js to create a device application to:
2323

2424
* Retrieve a module identity twin and examine reported properties
25-
* Update reported module identity twin properties
26-
* Receive notice of module desired property changes
25+
* Update module identity reported twin properties
26+
* Receive notice of module identity twin desired property changes
2727

2828
### Install SDK packages
2929

@@ -55,19 +55,19 @@ npm install azure-iot-device-amqp --save
5555

5656
For more information about the differences between MQTT, AMQP, and HTTPS support, see [Cloud-to-device communications guidance](../articles/iot-hub/iot-hub-devguide-c2d-guidance.md) and [Choose a communication protocol](../articles/iot-hub/iot-hub-devguide-protocols.md).
5757

58-
### Create a client module
58+
### Create a client object
5959

60-
Create a `Client` module using the installed package.
60+
Create a `Client` object using the installed package.
6161

6262
For example:
6363

6464
```javascript
6565
const Client = require('azure-iot-device').Client;
6666
```
6767

68-
### Create a protocol module
68+
### Create a protocol object
6969

70-
Create a `Protocol` module using an installed transport package.
70+
Create a `Protocol` object using an installed transport package.
7171

7272
This example assigns the AMQP protocol:
7373

@@ -86,29 +86,32 @@ Call [fromConnectionString](/javascript/api/azure-iot-device/client?#azure-iot-d
8686
This example uses the `Amqp` transport protocol:
8787

8888
```javascript
89-
const deviceConnectionString = "{IoT hub module connection string}"
89+
const deviceConnectionString = "{IoT hub identity module connection string}"
9090
const Protocol = require('azure-iot-device-mqtt').Amqp;
9191
let client = Client.fromConnectionString(deviceConnectionString, Protocol);
9292
```
9393

9494
### Open the connection to IoT Hub
9595

96-
Use the [open](/javascript/api/azure-iot-device/client?#azure-iot-device-client-open) method to open a connection between an IoT device and IoT Hub.
97-
Use `.catch(err)` to catch an error and execute handler code.
96+
Use the [open](/javascript/api/azure-iot-device/client?#azure-iot-device-client-open) method to open connection between an IoT device and IoT Hub.
9897

9998
For example:
10099

101100
```javascript
102-
client.open() //open the connection
103-
.catch((err) => {
104-
console.error('Could not connect: ' + err.message);
105-
});
101+
client.open(function(err) {
102+
if (err) {
103+
console.error('error connecting to hub: ' + err);
104+
process.exit(1);
105+
}
106+
})
106107
```
107108

108109
### Retrieve a module identity twin and examine reported properties
109110

110111
Call [getTwin](/javascript/api/azure-iot-device/client?#azure-iot-device-client-gettwin-1) to retrieve current module identity twin information into a [Twin](/javascript/api/azure-iot-device/twin) object.
111112

113+
Device code can then access the twin properties.
114+
112115
For example:
113116

114117
```javascript
@@ -122,7 +125,7 @@ console.log('twin contents:');
122125
console.log(twin.properties);
123126
```
124127

125-
### Update reported module identity twin properties
128+
### Update module identity twin reported properties
126129

127130
Use [update](/javascript/api/azure-iothub/twin?#azure-iothub-twin-update) to update device reported properties. Include a JSON-formatted patch as the first parameter and function execution status callback method as the second parameter to the method.
128131

@@ -154,11 +157,11 @@ twin.properties.reported.update(patch, function(err)
154157
});
155158
```
156159
157-
### Receive notice of desired property changes
160+
### Receive notice of module identity twin desired property changes
158161
159-
Create a desired property update event listener that executes when a desired property is changed in the device by passing the callback handler method name to [twin.on](/javascript/api/azure-iot-device/twin?#azure-iot-device-twin-on).
162+
Create a module identity twin desired property update event listener that executes when a desired property is changed by passing the callback handler method name to [twin.on](/javascript/api/azure-iot-device/twin?#azure-iot-device-twin-on).
160163
161-
The desired property event listener can take one of the following forms:
164+
The desired property event listener can take the following forms:
162165
163166
* Receive all patches with a single event handler
164167
* Receive an event if anything changes under a properties grouping
@@ -237,22 +240,71 @@ You can set up a listener for a single property change. In this example, the cod
237240
});
238241
```
239242
243+
#### Complete example
244+
245+
This example encapsulates the principles of this section, including callback funcation nesting.
246+
247+
```javascript
248+
var Client = require('azure-iot-device').Client;
249+
var Protocol = require('azure-iot-device-amqp').Amqp;
250+
// Copy/paste your module connection string here.
251+
var connectionString = 'HostName=xxx.azure-devices.net;DeviceId=myFirstDevice2;ModuleId=myFirstModule2;SharedAccessKey=xxxxxxxxxxxxxxxxxx';
252+
// Create a client using the Amqp protocol.
253+
var client = Client.fromConnectionString(connectionString, Protocol);
254+
client.on('error', function (err) {
255+
console.error(err.message);
256+
});
257+
// connect to the hub
258+
client.open(function(err) {
259+
if (err) {
260+
console.error('error connecting to hub: ' + err);
261+
process.exit(1);
262+
}
263+
console.log('client opened');
264+
// Create device Twin
265+
client.getTwin(function(err, twin) {
266+
if (err) {
267+
console.error('error getting twin: ' + err);
268+
process.exit(1);
269+
}
270+
// Output the current properties
271+
console.log('twin contents:');
272+
console.log(twin.properties);
273+
// Add a handler for desired property changes
274+
twin.on('properties.desired', function(delta) {
275+
console.log('new desired properties received:');
276+
console.log(JSON.stringify(delta));
277+
});
278+
// create a patch to send to the hub
279+
var patch = {
280+
updateTime: new Date().toString(),
281+
firmwareVersion:'1.2.1',
282+
weather:{
283+
temperature: 75,
284+
humidity: 20
285+
}
286+
};
287+
// send the patch
288+
twin.properties.reported.update(patch, function(err) {
289+
if (err) throw err;
290+
console.log('twin state reported');
291+
});
292+
293+
});
294+
});
295+
```
296+
240297
### Device SDK samples
241298
242-
The Azure IoT SDK for Node.js provides working samples of a service app that handles module identity twin tasks. For more information, see:
299+
The Azure IoT SDK for Node.js provides working samples of a device apps that handle module identity twin tasks. For more information, see:
243300
244301
* [Module Identity Twin](https://github.com/Azure/azure-iot-sdk-node/blob/main/e2etests/test/module_twin.js)
245302
* [Module Test Helper](https://github.com/Azure/azure-iot-sdk-node/blob/main/e2etests/test/module_test_helper.js)
246303
* [Twin e2e tests](https://github.com/Azure/azure-iot-sdk-node/blob/main/e2etests/test/twin_e2e_tests.js)
247304
248305
## Create a backend application
249306
250-
A backend application connects to a device through IoT Hub and can read and write device desired properties.
251-
252-
This section describes how to create a backend application that:
253-
254-
* Creates a module
255-
* Retrieve a module identity twin and update desired properties
307+
This section describes how to create a backend application that retrieves a module identity twin and update desired properties.
256308
257309
### Install service SDK packages
258310
@@ -262,6 +314,8 @@ Run this command to install **azure-iothub** on your development machine:
262314
npm install azure-iothub --save
263315
```
264316
317+
### Create a Registry object
318+
265319
The [Registry](/javascript/api/azure-iothub/registry) class exposes all methods required to interact with module identity twins from a backend application.
266320
267321
### Connect to IoT hub
@@ -276,70 +330,60 @@ The SDK methods in this section require these shared access policy permissions:
276330
As a parameter to `CreateFromConnectionString`, supply a shared access policy connection string that includes these permissions. For more information about shared access policies, see [Control access to IoT Hub with shared access signatures](/azure/iot-hub/authenticate-authorize-sas).
277331
278332
```javascript
279-
var iothub = require('azure-iothub');
280-
var connectionString = '{IoT hub shared access policy connection string}';
281-
var registry = iothub.Registry.fromConnectionString(connectionString);
282-
```
283-
284-
### Create a module
285-
286-
Call [addModule](/javascript/api/azure-iothub/registry?#azure-iothub-registry-addmodule-1) to add a module to a device.
287-
288-
For example:
289-
290-
```javascript
291-
// Add a module to a device
292-
var deviceId = 'myFirstDevice';
293-
var moduleId = 'myFirstModule';
294-
registry.addModule({ deviceId: deviceId, moduleId: moduleId }, function(err) {
295-
if (err) {
296-
console.log('Error creating module identity: ' + err);
297-
process.exit(1);
298-
}
333+
let Registry = require('azure-iothub').Registry;
334+
let connectionString = '{IoT hub shared access policy connection string}';
335+
let registry = Registry.fromConnectionString(serviceConnectionString);
299336
```
300337
301338
### Retrieve a module identity twin and update desired properties
302339
303-
You can create a patch that contains tag and desired property updates for a module identity twin.
340+
You can create a patch that contains desired property updates for a module identity twin.
304341
305342
To update a module identity twin:
306343
307344
1. Call [getModuleTwin](/javascript/api/azure-iothub/registry?#azure-iothub-registry-getmoduletwin-1) to retrieve the device [Twin](/javascript/api/azure-iothub/twin) object.
308345
309-
1. Format a patch that contains the module identity twin update. The patch is formatted in JSON as described in [Twin class](/javascript/api/azure-iothub/twin). A backend service patch can contain tag and desired property updates. For more patch format information, see [Tags and properties format](/azure/iot-hub/iot-hub-devguide-device-twins#tags-and-properties-format).
346+
1. Format a patch that contains the module identity twin update. The patch is formatted in JSON as described in [Twin class](/javascript/api/azure-iothub/twin). A backend service patch contains desired property updates. For more patch format information, see [Tags and properties format](/azure/iot-hub/iot-hub-devguide-device-twins#tags-and-properties-format).
310347
311348
1. Call [updateModuleTwin](/javascript/api/azure-iothub/registry?&#azure-iothub-registry-updatemoduletwin-1) to update the module identity twin with the patch.
312349
313350
In this example, the module identity twin is retrieved for `myDeviceId` and `myModuleId`. Then a patch is applied to the twins that contains `updateTime`, `firmwareVersion`, and `weather` information.
314351
315352
```javascript
316-
registry.getModuleTwin('myDeviceId', 'myModuleId', function(err, twin){
317-
if (err) {
318-
console.error(err.constructor.name + ': ' + err.message);
319-
} else {
320-
var patch = {
321-
updateTime: new Date().toString(),
322-
firmwareVersion:'1.2.0',
323-
weather:{
324-
temperature: 75,
325-
humidity: 23
326-
}
327-
};
328-
329-
twin.updateModuleTwin('myDeviceId', 'myModuleId', patch, twin.etag,function(err) {
330-
if (err) {
331-
console.error('Could not update twin: ' + err.constructor.name + ': ' + err.message);
332-
} else {
333-
console.log(twin.deviceId + ' twin updated successfully');
334-
}
335-
});
336-
}
353+
// Insert your device ID and moduleId here.
354+
var deviceId = 'myFirstDevice2';
355+
var moduleId = 'myFirstModule2';
356+
357+
// Retrieve the current module identity twin
358+
registry.getModuleTwin(deviceId, moduleId, function (err, twin) {
359+
console.log('getModuleTwin returned ' + (err ? err : 'success'));
360+
if (err) {
361+
console.log(err);
362+
} else {
363+
console.log('success');
364+
console.log('Current twin:' + JSON.stringify(twin))
365+
366+
// Format a desired property patch
367+
const twinPatch1 = {
368+
properties: {
369+
desired: {
370+
climate: { minTemperature: 69, maxTemperature: 77, },
371+
},
372+
},
373+
};
374+
375+
// Send the desired property patch to IoT Hub
376+
twin.update(twinPatch1, function(err) {
377+
if (err) throw err;
378+
console.log('twin state reported');
379+
});
380+
}
337381
});
338382
```
339383
340384
### Service SDK samples
341385
342-
The Azure IoT SDK for Node.js provides working samples of a service app that handles module identity twin tasks. For more information, see:
386+
The Azure IoT SDK for Node.js provides working samples of service apps that handle module identity twin tasks. For more information, see:
343387
344388
* [Module Identity Twin](https://github.com/Azure/azure-iot-sdk-node/blob/main/e2etests/test/module_twin.js)
345389
* [Module Test Helper](https://github.com/Azure/azure-iot-sdk-node/blob/main/e2etests/test/module_test_helper.js)

0 commit comments

Comments
 (0)