aws / aws-iot-device-sdk-js-v2

Next generation AWS IoT Client SDK for Node.js using the AWS Common Runtime
Apache License 2.0
215 stars 97 forks source link

Where is the documentation? #284

Closed runemadsen closed 1 month ago

runemadsen commented 2 years ago

Describe the issue

This upgraded version of the SDK is now three years old, and there still isn't any documentation on how to use this package. The old package had a README detailing the installation and usage with AWS IoT Core, but there is nothing in this package like that. I've tried to go through the samples but they are honestly terribly confusing. Wouldn't it be a priority to give users a way to actually consume this package?

Links

https://github.com/aws/aws-iot-device-sdk-js-v2/blob/main/README.md https://stackoverflow.com/questions/67451677/getting-started-with-aws-iot-publication-from-device https://stackoverflow.com/questions/71388320/mirgration-aws-iot-device-sdk-js-to-aws-iot-device-sdk-js-v2

jmklix commented 2 years ago

I'm sorry that you are still having problems using this sdk. We have made some improvements, but documentation is something that we are still working on and welcome any feedback for.

Here is our API documentation Here is FAQ which is meant to explain things not covered by the API docs Here is the developer guide which will help explain different parts and how to use IoT with AWS

Could you please elaborate about problems that you are having with the samples? Any suggestions are welcome.

runemadsen commented 2 years ago

Thanks for the quick response. The problems I'm having is that the package went from a simple and understandable README with lovely small examples that have nice textual descriptions to explain what they do to a set of cryptic samples written in Typescript that are nested inside a yargs api that few people understand. Here are the kind of questions that this setup affords:

  1. Do I need yargs?
  2. What is the main function?
  3. Do I need to run a setInterval timer to use the library?
  4. Do I need to write it in Typescript?

I would suggest rewriting the README that already exists for the old package to fit the new API. There are dozens of questions about this in these issues and many more on StackOverflow, so I don't think it's just me who is confused about this.

jmklix commented 2 years ago
  1. No, you don't need yargs. They are used to command line input when running the samples. These allow you to run the samples without having to change any of the code, but can safely removed.
  2. Here

    async function main(argv: Args) {
    /// parse the common command line arguments
    common_args.apply_sample_arguments(argv);
    
    /// build the mqtt connection
    const connection = common_args.build_connection_from_cli_args(argv);
    
    /// does what below comment says
    // force node to wait 60 seconds before killing itself, promises do not keep node alive
    // ToDo: we can get rid of this but it requires a refactor of the native connection binding that includes
    //    pinning the libuv event loop while the connection is active or potentially active.
    const timer = setInterval(() => { }, 60 * 1000);
    
    /// wait for connection to connect
    await connection.connect()
    /// publish and subscribe to messages
    await execute_session(connection, argv)
    /// call disconnect
    await connection.disconnect()
    
    // Allow node to die if the promise above resolved
    clearTimeout(timer);
    }
  3. Most likely not. Your program will likely be running longer that just a few publishes so you don't need to worry about node killing itself to early.
  4. No, we even have the pub_sub sample in javascript. I would recommend you use typescript and most of our examples are typescript, but it is ultimately your choice.
sborsay commented 2 years ago

You can find a PubSub sample in JavaScript here, no need to code typeScript: https://github.com/aws/aws-iot-device-sdk-js-v2/blob/main/samples/node/pub_sub_js/index.js

Go to: https://github.com/aws/aws-iot-device-sdk-js-v2#Installation

Build the JavaScript V2 SDK from source, do not use the NPM method to install it

Make sure you have active AWS security certificates and have attached an IoT policy to them.

in your RPi prompt: cd ~ mkdir certs (add your security certificates here)

Goto the following directory on your RPi:

/samples/node/pub_sub_js/index.js

and build the program with dependencies: npm install

Finally execute your index.js pubsub program with:

node index.js --endpoint --ca_file ~/certs/Amazon-root-CA-1.pem --cert ~/certs/certificate.pem.crt --key ~/certs/private.pem.key

If you don't want to use yargs for your certificates from the command line then you can hardocde them into the cli_args.js file which is a dependency in your index.js program:

https://github.com/aws/aws-iot-device-sdk-js-v2/blob/main/samples/util/cli_args.js

On Tue, Sep 13, 2022 at 4:33 PM Joseph Klix @.***> wrote:

  1. No, you don't need yargs. They are used to command line input when running the samples. These allow you to run the samples without having to change any of the code, but can safely removed.
  2. Here https://github.com/aws/aws-iot-device-sdk-js-v2/blob/336420386a8829fb5d6ddd010af2cef4ceec7b5a/samples/node/pub_sub/index.ts#L69-L85

async function main(argv: Args) { /// parse the common command line arguments common_args.apply_sample_arguments(argv);

/// build the mqtt connection
const connection = common_args.build_connection_from_cli_args(argv);

/// does what below comment says
// force node to wait 60 seconds before killing itself, promises do not keep node alive
// ToDo: we can get rid of this but it requires a refactor of the native connection binding that includes
//    pinning the libuv event loop while the connection is active or potentially active.
const timer = setInterval(() => { }, 60 * 1000);

/// wait for connection to connect
await connection.connect()
/// publish and subscribe to messages
await execute_session(connection, argv)
/// call disconnect
await connection.disconnect()

// Allow node to die if the promise above resolved
clearTimeout(timer);}
  1. Most likely not. Your program will likely be running longer that just a few publishes so you don't need to worry about node killing itself to early.
  2. No, we even have the pub_sub sample in javascript https://github.com/aws/aws-iot-device-sdk-js-v2/blob/main/samples/node/pub_sub_js/index.js. I would recommend you use typescript and most of our examples are typescript, but it is ultimately your choice.

— Reply to this email directly, view it on GitHub https://github.com/aws/aws-iot-device-sdk-js-v2/issues/284#issuecomment-1246054403, or unsubscribe https://github.com/notifications/unsubscribe-auth/AD4KXRHC6WVLHONQG3HFSTTV6EFNLANCNFSM6AAAAAAQLGBUTA . You are receiving this because you are subscribed to this thread.Message ID: @.***>

runemadsen commented 2 years ago

Thanks for the quick replies. I do know the answers to these questions, and I'm simply answering your question about what people are having a hard time understanding with the current documentation. The old README worked really well and the new samples are wrapped in a yargs script, so people need to deconstruct the examples from these. I think it's excellent that you do provide runnable samples, but these should not be the same as a getting started guide to using the package.

I would normally not be so specific about this if it was an open source project, but since this is the only way for me to interact with an entire fleet of AWS services, I do expect the documentation to at least be on par with the package that I used when starting to use this service.

PanMan commented 1 year ago

Also, properties like keep alive and timeouts are no where documented? I can find what options there are, but not how they work, or what would be good values in different scenario's...

canegru commented 1 year ago

I ran into the same issue as everyone mentioned above.

For those looking for a quick sample:

import { mqtt } from "aws-iot-device-sdk-v2";
import { iot } from "aws-iot-device-sdk-v2";
import { resolve } from "path";

const configs = {
  topic: "test",
  certPath: resolve("./secrets/certificate.pem.crt"),
  privateKeyPath: resolve("./secrets/private.pem.key"),
  caCertPath: resolve("./secrets/AmazonRootCA1.pem"),
  clientId: "TestingClient",
  endpointUrl: "xxxxx.iot.us-east-1.amazonaws.com",
};

const sendMessage = async (connection: mqtt.MqttClientConnection) => {
  const msg = {
    message: "This is my message",
    dateTime: new Date().toISOString(),
  };

  const json = JSON.stringify(msg);
  await connection.publish(configs.topic, json, mqtt.QoS.AtLeastOnce);
};

const createConnection = () => {
  let config_builder =
    iot.AwsIotMqttConnectionConfigBuilder.new_mtls_builder_from_path(
      configs.certPath,
      configs.privateKeyPath
    );

  config_builder.with_certificate_authority_from_path(
    undefined,
    resolve(configs.caCertPath)
  );
  config_builder.with_clean_session(false);
  config_builder.with_client_id(
    `${configs.clientId}-${Math.floor(Math.random() * 100000000)}`
  );
  config_builder.with_endpoint(configs.endpointUrl);
  const config = config_builder.build();

  const client = new mqtt.MqttClient();
  return client.new_connection(config);
};

const start = async () => {
  const connection = createConnection();
  const timer = setInterval(() => {}, 20 * 1000);

  console.log("Connecting...");
  await connection.connect();
  console.log("Connection completed.");
  await sendMessage(connection);
  console.log("Disconnecting...");
  await connection.disconnect();
  console.log("Disconnect completed.");

  // Allow node to die if the promise above resolved
  clearTimeout(timer);
};

start();
tunm1228 commented 8 months ago
certPath: resolve("./secrets/certificate.pem.crt"),
  privateKeyPath: resolve("./secrets/private.pem.key"),
  caCertPath: resolve("./secrets/AmazonRootCA1.pem"),

Can you guide me to create the other 3 files?

bretambrose commented 8 months ago

https://docs.aws.amazon.com/iot/latest/developerguide/device-certs-create.html is a good starting point

tunm1228 commented 8 months ago

I'm getting to the connect() step, but haven't caught the connection.on event yet Log from CloudWatch: _MqttClientConnection { _events: [Object: null prototype] { error: [Function (anonymous)] }, _eventsCount: 1, _maxListeners: undefined, corked: false, _handle: [External: 55bbb39619c0], client: MqttClient { handle: [External: 55bbb3b0ee00], bootstrap: undefined }, config: { client_id: 'mqtt-client-47131-64584868', host_name: 'a2yz9f5ypnqf3i-ats.iot.ap-southeast-1.amazonaws.com', socket_options: SocketOptions { handle: [External: 55bbb36d43c0] }, port: 8883, use_websocket: false, clean_session: false, keep_alive: undefined, will: undefined, username: '?SDK=NodeJSv2&Version=1.20.1', password: undefined, tls_ctx: ClientTlsContext { handle: [External: 55bbb38a1cf0] }, reconnect_min_sec: 1, reconnect_max_sec: 128 }, tls_ctx: ClientTlsContext { handle: [External: 55bbb38a1cf0] },

}_

jmklix commented 1 month ago
github-actions[bot] commented 1 month ago

This issue is now closed. Comments on closed issues are hard for our team to see. If you need more assistance, please open a new issue that references this one.