aws-iot-device-sdk-v2
Version:
NodeJS API for the AWS IoT service
224 lines (197 loc) • 6.84 kB
text/typescript
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
import { mqtt, mqtt5, iot, iotshadow } from 'aws-iot-device-sdk-v2';
import {once} from "events";
const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
type Args = { [index: string]: any };
const yargs = require('yargs');
yargs.command('*', false, (yargs: any) => {
yargs.option('endpoint', {
alias: 'e',
description: 'Your AWS IoT custom endpoint, not including a port.',
type: 'string',
required: true
})
.option('cert', {
alias: 'c',
description: '<path>: File path to a PEM encoded certificate to use with mTLS.',
type: 'string',
required: false
})
.option('key', {
alias: 'k',
description: '<path>: File path to a PEM encoded private key that matches cert.',
type: 'string',
required: false
})
.option('region', {
alias: 'r',
description: 'AWS region to establish a websocket connection to.',
type: 'string',
required: false
})
.option('client_id', {
alias: 'C',
description: 'Client ID for MQTT connection.',
type: 'string',
required: false
})
.option('shadow_property', {
alias: 'p',
description: 'Name of property in shadow to keep in sync',
type: 'string',
default: 'color'
})
.option('shadow_value', {
alias: 'u',
description: 'Value for shadow property',
type: 'string',
default: 'on'
})
.option('shadow_name', {
alias: 'N',
description: 'Use named shadow with specified name',
type: 'string'
})
.option('thing_name', {
alias: 'n',
description: 'The name assigned to your IoT Thing',
type: 'string',
default: 'name'
})
.option('mqtt_version', {
description: 'MQTT version to use (3 or 5). Default is 5.',
type: 'number',
required: false,
default: 5
})
}, main).parse();
function change_shadow_value(shadow: iotshadow.IotShadowClient, argv: Args, new_value?: object) {
return new Promise(async (resolve, reject) => {
try {
if (typeof new_value !== 'undefined') {
var updateShadow: iotshadow.model.UpdateShadowRequest = {
state: {
desired: new_value,
reported: new_value
},
thingName: argv.thing_name
};
await shadow.publishUpdateShadow(
updateShadow,
mqtt.QoS.AtLeastOnce)
console.log("Update request published.");
}
}
catch (error) {
console.log("Failed to publish update request.")
reject(error);
}
resolve(true)
});
}
function change_named_shadow_value(shadow: iotshadow.IotShadowClient, argv: Args, new_value?: object) {
return new Promise(async (resolve, reject) => {
try {
if (typeof new_value !== 'undefined') {
var updateNamedShadow: iotshadow.model.UpdateNamedShadowRequest = {
state: {
desired: new_value,
reported: new_value
},
thingName: argv.thing_name,
shadowName: argv.shadow_name
};
await shadow.publishUpdateNamedShadow(
updateNamedShadow,
mqtt.QoS.AtLeastOnce)
console.log("Update request published.");
}
}
catch (error) {
console.log("Failed to publish update request.")
reject(error);
}
resolve(true)
});
}
function createConnection(args: any): mqtt.MqttClientConnection {
let config_builder = iot.AwsIotMqttConnectionConfigBuilder.new_mtls_builder_from_path(
args.cert,
args.key
);
config_builder.with_clean_session(false);
config_builder.with_client_id(args.client_id || "test-" + Math.floor(Math.random() * 100000000));
config_builder.with_endpoint(args.endpoint);
const config = config_builder.build();
const client = new mqtt.MqttClient();
return client.new_connection(config);
}
function createMqtt5Client(args: any): mqtt5.Mqtt5Client {
let builder: iot.AwsIotMqtt5ClientConfigBuilder;
if (args.key && args.cert) {
builder = iot.AwsIotMqtt5ClientConfigBuilder.newDirectMqttBuilderWithMtlsFromPath(
args.endpoint,
args.cert,
args.key
);
} else {
builder = iot.AwsIotMqtt5ClientConfigBuilder.newWebsocketMqttBuilderWithSigv4Auth(
args.endpoint,
{ region: args.region || 'us-east-1' }
);
}
builder.withConnectProperties({
clientId: args.client_id || "test-" + Math.floor(Math.random() * 100000000),
keepAliveIntervalSeconds: 1200
});
return new mqtt5.Mqtt5Client(builder.build());
}
async function main(argv: Args) {
let connection: mqtt.MqttClientConnection | undefined;
let client5: mqtt5.Mqtt5Client | undefined;
let shadow: iotshadow.IotShadowClient;
console.log("Connecting...");
if (argv.mqtt_version == 5) {
client5 = createMqtt5Client(argv);
shadow = iotshadow.IotShadowClient.newFromMqtt5Client(client5);
const connectionSuccess = once(client5, "connectionSuccess");
client5.start();
await connectionSuccess;
console.log("Connected with Mqtt5 Client...");
} else {
connection = createConnection(argv);
shadow = new iotshadow.IotShadowClient(connection);
await connection.connect();
console.log("Connected with Mqtt3 Client...");
}
try {
let data_to_send: any = {}
data_to_send[argv.shadow_property] = argv.shadow_value
if (argv.shadow_name) {
console.log("Use named shadow")
await change_named_shadow_value(shadow, argv, data_to_send);
} else {
console.log("Use classic shadow")
await change_shadow_value(shadow, argv, data_to_send);
}
} catch (error) {
console.log(error);
}
console.log("Disconnecting..");
if (connection) {
await connection.disconnect();
} else if (client5) {
let stopped = once(client5, "stopped");
client5.stop();
await stopped;
client5.close();
}
// force node to wait a second before quitting to finish any promises
await sleep(1000);
console.log("Disconnected");
// Quit NodeJS
process.exit(0);
}