About AWS IoT Core

AWS IoT Core is a managed cloud platform that enables connected devices to easily and securely interact with cloud applications and other devices. It supports billions of devices and trillions of messages, processing and routing these messages to AWS endpoints and other devices reliably and securely. This functionality allows applications to continuously track and communicate with all your devices, even when they aren’t connected.

The service provides a secure and efficient connection between devices and the AWS cloud without the need to provision or manage servers. Devices connected to AWS IoT Core can automatically set up secure communications using mutual authentication and encryption at all points of connection, ensuring that data is never exchanged without proven identity.

Key features of AWS IoT Core include:

  1. Message Broker for MQTT: a low-latency, publish/subscribe messaging transport protocol ideal for connecting remote devices to each other and to applications.

  2. Rules Engine: transforms and routes the data to other AWS services such as AWS Lambda, Amazon Kinesis, Amazon S3, and more for processing, storage, or analytics.

  3. Device Shadow: provides a persistent virtual version, or “shadow”, of each device that includes the device’s latest state so that applications can read messages and interact with the device even when it is offline.

  4. Security and Identity Service: offers mutual authentication and encryption at all points of connection, ensuring that data is never exchanged between devices and AWS IoT Core without a proven identity.

  5. With AWS IoT Core, businesses and developers can build IoT applications that gather, process, analyze, and act on data generated by connected devices without managing any infrastructure. This robust integration not only simplifies the management of IoT devices but also enhances the capabilities to perform real-time analytics, create new applications, and improve decision-making processes.

In this learning path, you create an application that emulates the weather station and sends hypothesized sensor readings such as temperature and humidity to the AWS cloud.

Before you begin

Before you start, ensure you have installed and prepared the following tools:

  1. Download and install Node.js for ARM64 here .
  2. Download and configure AWS CLI here .

Create the project

You now create a Node.js project. Open the Command Prompt and type the following commands:


            mkdir AWS.WeatherStation && cd AWS.WeatherStation

Next, create a new Node.js application by typing:


            npm init -y

This will create the package.json with default values. Open this file and modify it as follows:


  "name": "aws.weatherstation",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "start": "node app.js"
  "dependencies": {
    "aws-iot-device-sdk": "^2.2.13"
  "keywords": [],
  "author": "",
  "license": "ISC"

Implement the weather station emulator

To continue, implement the weather station emulator. Within the AWS.WeatherStation folder, create a new file named emulator.js. Then, modify the file using the following code snippet:


            const getRandomValue = (min, max, digits) => {
    const randomNumber = Math.random() * (max - min) + min;
    return randomNumber.toFixed(digits);

const randomSensorReadings = (deviceId) => ({
    timestamp: new Date(),
    temperature: getRandomValue(20, 40, 2),
    humidity: getRandomValue(50, 60, 0),
    pressure: getRandomValue(1000, 1050, 1)

exports.randomSensorReadings = randomSensorReadings;

This code defines two functions, getRandomValue and randomSensorReadings, which are used for generating simulated sensor readings. Additionally, this code is designed to be part of a Node.js application, as indicated by the use of exports to make the randomSensorReadings function available to other parts of the application.

The getRandomValue(min, max, digits) function generates a random floating-point number within a specified range (min to max) and formats it to a specified number of decimal places. Conversely, the randomSensorReadings(deviceId) function creates an object representing sensor readings for a device, including a device identifier, a timestamp, and readings for temperature, humidity, and pressure.

MQTT and the common application settings

AWS IoT Core utilizes MQTT (Message Queuing Telemetry Transport), a lightweight messaging protocol designed for devices with limited network bandwidth and resources, making it highly suitable for many Internet of Things (IoT) applications. MQTT operates on a publish/subscribe model that facilitates efficient message exchange between devices without the need for complex network programming.

To prepare the application for using MQTT with AWS IoT Core, implement the common.js file in the same directory, AWS.WeatherStation:


            const rootCertDir = '<TYPE_YOUR_DIRECTORY_HERE>'; 

const awsConnectionInfo = {
    keyPath: `${rootCertDir}WeatherEmulator.private.key`,
    certPath: `${rootCertDir}WeatherEmulator.cert.pem`,
    caPath: `${rootCertDir}AmazonRootCA1.pem`,
    host: '', 
    clientId: 'WeatherStationEmulator'

const msDelayTime = 1000;
const topicSensorReadings = 'Emulators/Weather/SensorReadings';
const topicTelemetryControl = 'Emulators/Weather/Control';

exports.awsConnectionInfo = awsConnectionInfo;
exports.msDelayTime = msDelayTime;
exports.topicSensorReadings = topicSensorReadings;
exports.topicTelemetryControl = topicTelemetryControl;

This code snippet is a JavaScript module designed to set up and export configuration settings for a weather station emulator using AWS IoT Core services. Specifically, rootCertDir holds the directory path where the AWS IoT certificate files are stored. The placeholder <TYPE_YOUR_DIRECTORY_HERE> is meant to be replaced with the actual directory path on your system. You will obtain the certificates in the next “how-to” section.

awsConnectionInfo is an object that stores essential information required to connect to AWS IoT Core, including:

  • keyPath: Path to the private key file for the device, constructed by combining rootCertDir with the filename weather-emulator-private.key.
  • certPath: Path to the device’s certificate file, similarly constructed.
  • caPath: Path to the AWS root CA certificate, necessary for establishing a trusted connection.
  • host: The endpoint URL of the AWS IoT service, which needs to be provided by the user.
  • clientId: A unique identifier for the weather station emulator when it connects to AWS IoT.

We have three constants used to control messaging and timing:

  • msDelayTime: A constant set at 1000 milliseconds (1 second), likely used to define the frequency at which the device sends sensor readings or checks for commands.
  • topicSensorReadings: The MQTT topic on which the device will publish sensor readings.
  • topicTelemetryControl: The MQTT topic on which the device will subscribe to receive control messages or commands.

Finally, the module exports several settings and configurations using Node.js module exports, making awsConnectionInfo, msDelayTime, topicSensorReadings, and topicTelemetryControl accessible to other parts of the application. These details are crucial for connecting to, and interacting with, AWS IoT Core.

In an application, these settings enable a device or emulator to establish a connection to AWS IoT Core, allowing it to securely send and receive data. The defined MQTT topics are essential for the pub/sub mechanism, permitting the device to publish its sensor data and subscribe to commands that can alter its operation, such as turning on and off or adjusting parameters.

Implement the Application

You now implement the code to simulate a weather station that interacts with AWS IoT Core for device management and data transmission. This demonstrates a typical IoT application scenario where device states are remotely controlled and monitored. To begin, create a new file named app.js under the AWS.WeatherStation directory:


            'use strict';

// Dependencies
const common = require('./common.js');
const emulator = require('./emulator.js');
const awsIot = require('aws-iot-device-sdk');

// Connect to AWS
const device = awsIot.device(common.awsConnectionInfo);

// Variables
let telemetryIntervalHandle;
let isTelemetryActive = true;

// Device module event handlers
device.on('connect', () => {
    console.log('Connected to AWS IoT');


    telemetryIntervalHandle = setInterval(() => {
        if (isTelemetryActive) {
            // Synthesize telemetry data
            const telemetryEntry = JSON.stringify(emulator.randomSensorReadings('WeatherStationEmulator'));

            // Publish data to the cloud
            device.publish(common.topicSensorReadings, telemetryEntry);

            // Log current data to the console
        } else {
            console.log('Telemetry is inactive');
    }, common.msDelayTime);

device.on('close', (err) => {    
    console.log('Connection closed');

device.on('error', (err) => {
    console.log('Error', err);

device.on('message', (_topic, payload) => {
    const messageObject = JSON.parse(payload.toString());

    if (messageObject.isTelemetryActive !== undefined) {
        isTelemetryActive = messageObject.isTelemetryActive;
    } else {
        console.log('Unexpected structure of the control command');

This module integrates with AWS IoT using the AWS IoT Device SDK. It is designed to connect a device emulator, handle device communications, and manage telemetry data for a simulated weather station.

The code imports necessary modules: common.js, emulator.js, and aws-iot-device-sdk. The first two modules have been already described here. The latter, aws-iot-device-sdk, is a library that enables devices to interact with AWS IoT services.

The module creates the AWS IoT device connection, which establishes a connection to AWS IoT by creating a device instance with configuration settings provided by common.awsConnectionInfo.

The module has two variables:

  • telemetryIntervalHandle: a variable to store the reference to the interval timer that periodically sends telemetry data.
  • isTelemetryActive: a flag to control whether the device should currently send telemetry data.

The module includes four event handlers:

  • connect: activated when the device successfully connects to AWS IoT. It subscribes to a control topic to receive commands and starts an interval timer. During each interval, if telemetry is active, it generates telemetry data, converts it to a JSON string, and publishes it to a specified topic.
  • close: triggered when the connection to AWS IoT is closed, clearing the telemetry interval to stop sending data.
  • error: logs any errors that occur during the connection or data handling.
  • message: handles incoming messages on subscribed topics. It specifically looks for messages that toggle the isTelemetryActive status based on received commands.

Finally, the module manages telemetry data. It periodically generates and publishes telemetry data including weather conditions like temperature, humidity, and pressure, using the emulator module. This data is serialized to JSON format and logged in the console for monitoring.


You have successfully developed an application that can interact with AWS IoT Core, designed to simulate a weather station. This setup enables the application to manage device communications effectively and send telemetry data for remote monitoring. In the next steps, you register this application within AWS IoT Core to establish its credentials and connections settings formally. Once registered, you launch the application to begin streaming telemetry data to the cloud, allowing us to monitor and control the device states in real-time from AWS IoT Core’s platform. This will complete the setup for a fully functional IoT application that leverages AWS’s powerful cloud capabilities.