[Yandex Cloud documentation](../../index.md) > [Tutorials](../index.md) > Application solutions > Internet of Things (IoT) > Monitoring the status of geographically distributed devices

# Monitoring the status of geographically distributed devices

{% note warning %}

Yandex IoT Core is no longer available to new users. 

Current users can create resources until November 1, 2026. Afterwards, the service will go read-only and cease to operate on December 1, 2026. For more information on the timing and procedure, see [Service shutdown](../../iot-core/sunset.md).

{% endnote %}


In this tutorial, you will configure status monitoring for devices, e.g., vending machines, connected to [Yandex IoT Core](../../iot-core/index.md) scattered around the city. You can monitor the status of vending machines on the [Yandex DataLens](../../datalens/index.md) map and charts. To emulate sensors, we will use [Yandex Cloud Functions](../../functions/index.md). If you have any connected sensors, use them. [Yandex Managed Service for PostgreSQL](../../managed-postgresql/index.md) will be used to store data.

The source code for the tutorial is available in a [GitHub repository](https://github.com/yandex-cloud-examples/yc-geo-dist-devices-iot-monitoring).

To configure monitoring of sensor readings:
1. [Get your cloud ready](#configure-cloud).
1. [Create a Managed Service for PostgreSQL cluster](#postgresql-step).
1. [Create the required Yandex IoT Core resources](#resources-step).
1. [Create a device emulator in Cloud Functions](#emulator-step).
1. [Create a function for processing data in Cloud Functions](#processing-function-step).
1. [Configure monitoring in DataLens](#configure-datalens).

If you no longer need the resources you created, [delete them](#cleanup).

## Getting started {#before-you-begin}

Sign up for Yandex Cloud and create a [billing account](../../billing/concepts/billing-account.md):
1. Navigate to the [management console](https://console.yandex.cloud) and log in to Yandex Cloud or create a new account.
1. On the **[Yandex Cloud Billing](https://center.yandex.cloud/billing/accounts)** page, make sure you have a billing account linked and it has the `ACTIVE` or `TRIAL_ACTIVE` [status](../../billing/concepts/billing-account-statuses.md). If you do not have a billing account, [create one](../../billing/quickstart/index.md) and [link](../../billing/operations/pin-cloud.md) a cloud to it.

If you have an active billing account, you can create or select a [folder](../../resource-manager/concepts/resources-hierarchy.md#folder) for your infrastructure on the [cloud page](https://console.yandex.cloud/cloud).

[Learn more about clouds and folders here](../../resource-manager/concepts/resources-hierarchy.md).


### Required paid resources {#paid-resources}

* Managed Service for PostgreSQL cluster: computing resources allocated to hosts, storage and backup size (see [Managed Service for PostgreSQL pricing](../../managed-postgresql/pricing.md)).
* Public IP addresses if public access is enabled for cluster hosts (see [Virtual Private Cloud pricing](../../vpc/pricing.md)).
* Yandex IoT Core registry: number of sent messages (see [Yandex IoT Core pricing](../../iot-core/pricing.md)).
* Yandex Cloud Functions functions: number of function calls, idle time of provisioned instances, and computing resources allocated for the function (see [Yandex Cloud Functions pricing](../../functions/pricing.md)).


## Get your cloud ready {#configure-cloud}

* [Create](../../iam/operations/sa/create.md) a service account named `my-emulator-function-service-account` for data sending. [Assign](../../iam/operations/sa/assign-role-for-sa.md) the `functions.functionInvoker`, `iot.devices.writer`, and `viewer` [roles](../../iam/concepts/access-control/roles.md) to it.
* Create a service account named `my-db-function-service-account` for data processing. Assign the `functions.functionInvoker` and `editor` roles to it.
* [Create](../../vpc/operations/network-create.md) a cloud network and at least one [subnet](../../vpc/operations/subnet-create.md) in the `ru-central1-a`, `ru-central1-b`, or `ru-central1-d` availability zone.
* [Create](../../vpc/operations/security-group-create.md) a security group named `my-pg-sg` and [add](../../vpc/operations/security-group-add-rule.md) a rule for incoming traffic:

    * **Port range**: `6432`.
    * **Protocol**: `TCP`.
    * **Source**: `CIDR`.
    * **CIDR blocks**: `0.0.0.0/0`.

## Create a cluster in Managed Service for PostgreSQL {#postgresql-step}

The example is based on the minimum values of [host](../../managed-postgresql/concepts/instance-types.md) parameters. For real tasks, it is better to choose hosts with a guaranteed 100% vCPU share.

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), select the folder you are using to complete this tutorial.
  1. Navigate to **Managed Service for&nbsp;PostgreSQL**.
  1. Click **Create cluster**.
  1. Specify a name for the cluster, e.g., `my-pg-database`.
  1. From the **Environment** list, select `PRODUCTION`.
  1. From the **Version** list, select `17`.
  1. Under **Host class**, specify:

      * **Platform**: `Intel Ice Lake`.
      * **Type**: `standard`.
      * Class: `s3-c2-m8 (2 vCPU, 8 GB)`.

  1. Under **Storage size**:

      * Select `network-hdd`.
      * Specify the size of `10 GB`.

  1. Under **Database**, specify:

      * **DB name**: `db1`.
      * **Username**: `user1`.
      * **Password**: Set a password to access the database.

          {% note info %}
          
          Save the password as you will need it for [authentication](../../iot-core/concepts/authorization.md).
          
          {% endnote %}

      * **Locale for sorting (LC_COLLATE)**: `C`.
      * **Charset locale (LC_CTYPE)**: `C`.

  1. Under **Network settings**:

      1. Select the cloud network where you created the `my-pg-sg` security group.
      1. Select the `my-pg-sg` security group.

  1. Under **Hosts**:

      1. Leave a single host.
      1. Click ![image](../../_assets/console-icons/pencil.svg).
      1. In the window that opens, enable **Public access** and click **Save**.

  1. Under **Advanced settings**, enable **DataLens access** and **Access from the management console**.
  1. Click **Create cluster**.

  It may take a few minutes to create a cluster.

{% endlist %}

## Create the required Yandex IoT Core resources {#resources-step}

[Registry](../../iot-core/concepts/index.md#registry) and [device](../../iot-core/concepts/index.md#device) are the main Yandex IoT Core components for exchanging data and commands. Devices can only exchange data if created in the same registry.

### Create a registry and set up username and password authentication {#registry-step}

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), select the [folder](../../resource-manager/concepts/resources-hierarchy.md#folder) you are using to complete this tutorial.
  1. Navigate to **IoT Core**.
  1. Click **Create registry**.
  1. In the **Name** field, enter a name for the registry, e.g., `my-registry`.
  1. In the **Password** field, set a password for registry access. The password must be at least 14 characters long and contain lowercase letters, capital letters, and numbers. To create a password, you can use [this password generator](https://passwordsgenerator.net/).

      {% note info %}
      
      Save the password as you will need it for [authentication](../../iot-core/concepts/authorization.md).
      
      {% endnote %}

  1. Click **Create**.

{% endlist %}

You can also complete authorization using certificates. Learn more [about authorization in Yandex IoT Core](../../iot-core/concepts/authorization.md).

### Create devices and configure authorization with your login and password {#device-step}

Create three devices: `my-device-1`, `my-device-2`, and `my-device-3`.

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), select the folder you are using to complete this tutorial.
  1. Navigate to **IoT Core**.
  1. Select the registry you created in the previous step.
  1. In the left-hand menu, select **Devices**.
  1. Click **Add device**.
  1. In the **Name** field, enter the device name: `my-device-1`.
  1. In the **Password** field, set a password for device access. The password must be at least 14 characters long and contain lowercase letters, capital letters, and numbers. To create a password, you can use [this password generator](https://passwordsgenerator.net/).

      {% note info %}
      
      Save the password as you will need it for [authentication](../../iot-core/concepts/authorization.md).
      
      {% endnote %}

  1. Optionally, add an alias:

      1. Click **Add alias**.
      1. Fill out the fields: enter an alias, e.g., `events`, and the [topic](../../iot-core/concepts/topic/index.md) type after `$devices/{id}`, e.g., `events`.

          As a result, you will be able to use the `events` alias instead of the `$devices/<device_ID>/events` topic.

      1. Repeat these steps for each alias you add.

  1. Click **Create**.
  1. Similarly, create `my-device-2` and `my-device-3`.

{% endlist %}

You can also complete authorization using certificates. Learn more [about authorization in Yandex IoT Core](../../iot-core/concepts/authorization.md).

## Create a device emulator in Cloud Functions {#emulator-step}

The emulator will send data from the devices to the Managed Service for PostgreSQL cluster.

To run the emulator, create a [function](../../functions/concepts/function.md) to emulate sending data from device sensors and a [trigger](../../functions/concepts/trigger/index.md) to call this function once per minute.

### Create a function to emulate sending data from the device {#emulation_function}

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), select the folder you are using to complete this tutorial.
  1. Navigate to **Cloud Functions**.
  1. Create a function:

      1. Click **Create function**.
      1. In the **Name** field, enter a name for the function, e.g., `my-device-emulator-function`.
      1. Click **Create**.

  1. Create a function version:

      1. In the **Editor** window that opens, select `Node.js 18`.
      1. Disable **Add files with code examples**.
      1. Click **Continue**.
      1. In the **Code source** field, select `Code editor`.
      1. Click **Create file**:

          * File name: `device-emulator.js`.
          * File contents: Function code from [GitHub](https://github.com/yandex-cloud-examples/yc-geo-dist-devices-iot-monitoring/blob/main/device-emulator.js).

      1. Similarly, create a file named `package.json` with the following contents:

          ```json
          {
            "name": "my-app",
            "version": "1.0.0",
            "dependencies": {
              "yandex-cloud": "*"
            }
          }
          ```

      1. In the **Entry point** field, specify `device-emulator.handler`.

      1. Under **Parameters**, specify:

          * **Timeout**: `10`.
          * **Memory**: `128 MB`.
          * **Service account**: `my-emulator-function-service-account`.
          * **Environment variables**:

              Key | Description | Value
              :--- | :--- | :---
              `CASH_DRAWER_SENSOR_VALUE`  | Percentage of used cash box space          | `67.89`
              `TEMPERATURE_SENSOR_VALUE`  | Baseline temperature in the pickup box | `10.34`
              `POWER_SENSOR_VALUE`        | Baseline mains voltage            | `24.12`
              `SERVICE_DOOR_SENSOR_VALUE` | State of the open service door sensor | `False`
              `ITEM1_SENSOR_VALUE`        | Stock of product 1                       | `50.65`
              `ITEM2_SENSOR_VALUE`        | Stock of product 2                       | `80.97`
              `ITEM3_SENSOR_VALUE`        | Stock of product 3                       | `30.33`
              `ITEM4_SENSOR_VALUE`        | Stock of product 4                       | `15.15`
              `REGISTRY_ID`               | ID of the registry you created   | To look up the ID, use the [management console](https://console.yandex.cloud)<br>in Yandex IoT Core

      1. Click **Save changes**.

{% endlist %}

### Test the emulation function {#test-emulation-function}

1. (Optional) To get detailed information from the sensors, [subscribe](../../iot-core/operations/subscribe.md#one-device) your registry to the Yandex IoT Core device [topic](../../iot-core/concepts/topic/index.md).

    {% list tabs group=instructions %}

    - CLI {#cli}

      If you do not have the Yandex Cloud CLI yet, [install and initialize it](../../cli/quickstart.md#install).

      The folder used by default is the one specified when [creating](../../cli/operations/profile/profile-create.md) the CLI profile. To change the default folder, use the `yc config set folder-id <folder_ID>` command. You can also specify a different folder for any command using `--folder-name` or `--folder-id`. If you access a resource by its name, the search will be limited to the default folder. If you access a resource by its ID, the search will be global, i.e., through all folders based on access permissions.

      Run this command:

      ```bash
      yc iot mqtt subscribe \
        --username <registry_ID> \
        --password <registry_password> \
        --topic '$devices/<device_ID>/events/#' \
        --qos 1
      ```

      Where:
      * `--username` and `--password`: Credentials for authentication with a username and password.
      * `--topic`: Device topic for sending data or topic alias.
      * `--qos`: Quality of service (QoS).

      The command should run without interruption until you finish testing the function.

      For more information about the `yc iot mqtt subscribe` command, see the [CLI reference](../../cli/cli-ref/iot/cli-ref/mqtt/subscribe.md).

    {% endlist %}

1. Test the emulation function:

    {% list tabs group=instructions %}

    - Management console {#console}

      1. In the [management console](https://console.yandex.cloud), select the folder you are using to complete this tutorial.
      1. Navigate to **Cloud Functions**.
      1. Select the `my-device-emulator-function` function.
      1. In the left-hand menu, select **Testing**.
      1. In the **Version tag** list, select `$latest`, the most recent version of the function.
      1. Click **Run test**.

          If the function runs successfully, the **Function status** field will show **Done** and the **Function output** field, the following result:

          ```json
          {
            "statusCode" : 200
          }
          ```

          If you subscribed to the Yandex IoT Core device topic before running the test, you will get the following JSON object in the terminal:

          ```json
          {
            "DeviceId":"areulpu7dnou********",
            "TimeStamp":"2024-06-19T08:29:14Z",
            "Values":[
                {"Type":"Bool","Name":"Service door sensor","Value":"False"},
                {"Type":"Float","Name":"Power Voltage","Value":"24.91"},
                {"Type":"Float","Name":"Temperature","Value":"10.51"},
                {"Type":"Float","Name":"Cash drawer fullness","Value":"67.89"},
                {"Items":[
                    {"Type":"Float", "Id":"1","Name":"Item 1","Fullness":"50.65"},
                    {"Type":"Float", "Id":"2","Name":"Item 2","Fullness":"80.97"},
                    {"Type":"Float", "Id":"3","Name":"Item 3","Fullness":"30.33"},
                    {"Type":"Float", "Id":"4","Name":"Item 4","Fullness":"15.15"}
                ]}
                ]
            }
          ```

    {% endlist %}

### Create a trigger to invoke the function once per minute {#minute-trigger}

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), select the folder you are using to complete this tutorial.
  1. Navigate to **Cloud Functions**.
  1. In the left-hand panel, select **Triggers**.
  1. Click **Create trigger**.
  1. In the **Name** field, enter a name for the trigger, e.g., `my-emulator-function-trigger`.
  1. In the **Type** field, select `Timer`.
  1. In the **Cron expression** field, select `Every minute`.
  1. Under **Function settings**, specify the function parameters:

      * **Function**: `my-device-emulator-function`.
      * **Function version tag**: `$latest`.
      * **Service account**: `my-emulator-function-service-account`.

  1. (Optional) In the **Repeat request settings** and **Dead Letter Queue settings** sections, set parameters to prevent data loss in case of failure:

      * **Repeat request settings** enable automatic retries if the current function invocation fails.
      * **Dead Letter Queue settings** allow you to redirect messages that the trigger sends to the function.

          You can use a [standard message queue](../../message-queue/concepts/queue.md#standard-queues) as a [dead-letter queue](../../message-queue/concepts/dlq.md). If you do not have a message queue, [create one in Yandex Message Queue](../../message-queue/operations/message-queue-new-queue.md).

  1. Click **Create trigger**.

{% endlist %}

## Create a function for processing data in Cloud Functions {#processing-function-step}.

Create a data processing function, test it, and review the result of data processing. Then create a trigger to call the function and see the result it returns.

### Create a function to process incoming data {#processing-function}

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), select the folder you are using to complete this tutorial.
  1. Navigate to **Cloud Functions**.
  1. In the left-hand panel, select **Functions**.
  1. Create a function:

      1. Click **Create function**.
      1. In the **Name** field, enter a name for the function, e.g., `my-db-function`.
      1. Click **Create**.

  1. Create a function version:

      1. In the **Editor** window that opens, select `Python 3.12`.
      1. Disable **Add files with code examples**.
      1. Click **Continue**.
      1. In the **Code source** field, select `Code editor`.
      1. Click **Create file**:

          * File name: `myfunction.py`.
          * File contents: Function code from [GitHub](https://github.com/yandex-cloud-examples/yc-geo-dist-devices-iot-monitoring/blob/main/myfunction.py).

      1. In the **Entry point** field, specify `myfunction.msgHandler`.
      1. Under **Parameters**, specify:

          * **Timeout**: `10`.
          * **Memory**: `128 MB`.
          * **Service account**: `my-db-function-service-account`.
          * **Environment variables**:

              Key | Description | Value
              :--- | :--- | :---
              `VERBOSE_LOG` | Enables and disables writing data | `True`
              `DB_HOSTNAME` | Host FQDN in Managed Service for PostgreSQL | To look up the FQDN, use the [management console](https://console.yandex.cloud)<br>in Managed Service for PostgreSQL
              `DB_PORT`     | Port for connection to the cluster in Managed Service for PostgreSQL | `6432`
              `DB_NAME`     | Cluster name in Managed Service for PostgreSQL | `db1`
              `DB_USER`     | Username to connect to the cluster in Managed Service for PostgreSQL | `user1`
              `DB_PASSWORD` | Password to connect to the DB in Managed Service for PostgreSQL | Password you set in Managed Service for PostgreSQL

      1. Click **Save changes**.

{% endlist %}

### Test the data processing function {#test-processing-function}

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), select the folder you are using to complete this tutorial.
  1. Navigate to **Cloud Functions**.
  1. Select the `my-db-function` function.
  1. In the left-hand menu, select **Testing**.
  1. In the **Version tag** list, select `$latest`, the most recent version of the function.
  1. In the **Payload** field, paste the following data:

      ```json
      {
        "messages": [
        {
          "event_metadata": {
            "event_id": "160d239876d9714800",
            "event_type": "yandex.cloud.events.iot.IoTMessage",
            "created_at": "2020-05-08T19:16:21.267616072Z",
            "folder_id": "b112345678910"
          },
          "details": {
            "registry_id": "are1234567890",
            "device_id": "are0987654321",
            "mqtt_topic": "$devices/are0987654321/events",
            "payload": "ewogICAgICAgICAgICAiRGV2aWNlSWQiOiJhcmU1NzBrZTA1N29pcjg1bDlmciIsCiAgICAgICAgICAgICJUaW1lU3RhbXAiOiIyMDIwLTA2LTExVDExOjA3OjIwWiIsCiAgICAgICAgICAgICJWYWx1ZXMiOlsKICAgICAgICAgICAgICAgIHsiVHlwZSI6IkJvb2wiLCJOYW1lIjoiU2VydmljZSBkb29yIHNlbnNvciIsIlZhbHVlIjoiRmFsc2UifSwKICAgICAgICAgICAgICAgIHsiVHlwZSI6IkZsb2F0IiwiTmFtZSI6IlBvd2VyIFZvbHRhZ2UiLCJWYWx1ZSI6IjI1LjA2In0sCiAgICAgICAgICAgICAgICB7IlR5cGUiOiJGbG9hdCIsIk5hbWUiOiJUZW1wZXJhdHVyZSIsIlZhbHVlIjoiMTEuMjEifSwKICAgICAgICAgICAgICAgIHsiVHlwZSI6IkZsb2F0IiwiTmFtZSI6IkNhc2ggZHJhd2VyIGZ1bGxuZXNzIiwiVmFsdWUiOiI2Ny44OSJ9LAogICAgICAgICAgICAgICAgeyJJdGVtcyI6WwogICAgICAgICAgICAgICAgICAgIHsiVHlwZSI6IkZsb2F0IiwgIklkIjoiMSIsIk5hbWUiOiJJdGVtIDEiLCJGdWxsbmVzcyI6IjUwLjY1In0sCiAgICAgICAgICAgICAgICAgICAgeyJUeXBlIjoiRmxvYXQiLCAiSWQiOiIyIiwiTmFtZSI6Ikl0ZW0gMiIsIkZ1bGxuZXNzIjoiODAuOTcifSwKICAgICAgICAgICAgICAgICAgICB7IlR5cGUiOiJGbG9hdCIsICJJZCI6IjMiLCJOYW1lIjoiSXRlbSAzIiwiRnVsbG5lc3MiOiIzMC4zMyJ9LAogICAgICAgICAgICAgICAgICAgIHsiVHlwZSI6IkZsb2F0IiwgIklkIjoiNCIsIk5hbWUiOiJJdGVtIDQiLCJGdWxsbmVzcyI6IjE1LjE1In0KICAgICAgICAgICAgICAgIF19CiAgICAgICAgICAgICAgICBdCiAgICAgICAgICAgIH0="
          }
        }]
      }
      ```

  1. Click **Run test**.

      If the function runs successfully, the **Function status** field will show **Done** and the **Function output** field, the following result:

      ```json
      {
        "statusCode" : 200 ,
        "headers" : {
          "Content-Type" : "text/plain"
        },
      "isBase64Encoded" : false
      }
      ```

{% endlist %}

### View the data processing result in Managed Service for PostgreSQL {#processing-function-results}

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), select the folder you are using to complete this tutorial.
  1. Navigate to **Managed Service for&nbsp;PostgreSQL**.
  1. Select the `my-pg-database` cluster.
  1. In the left-hand menu, select **SQL**.
  1. In the **Password** field, enter the password you set to access the database and click **Connect**.
  1. Select the `public` folder.
  1. View the data processing result in the `iot_events` and `iot_position` tables.

{% endlist %}

### Create a trigger to call the data processing function {#processing-function-trigger}

The trigger will invoke the function when messages appear in the [device topic](../../iot-core/concepts/topic/devices-topic.md).

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), select the folder you are using to complete this tutorial.
  1. Navigate to **Cloud Functions**.
  1. In the left-hand panel, select **Triggers**.
  1. Click **Create trigger**.
  1. In the **Name** field, enter a name for the trigger, e.g., `my-db-func-trigger`.
  1. In the **Type** field, select `IoT Core (device)`.
  1. Under **IoT Core message settings**, specify the registry and device parameters:

      * **Registry**: `my-registry`.
      * **Device**: `Any device`.
      * **MQTT topic**: `$devices/#`.

  1. Under **Function settings**, specify the function parameters:

      * **Function**: `my-db-function`.
      * **Function version tag**: `$latest`.
      * **Service account**: `my-db-function-service-account`.

  1. (Optional) In the **Repeat request settings** and **Dead Letter Queue settings** sections, set parameters to prevent data loss in case of failure:

      * **Repeat request settings** enable automatic retries if the current function invocation fails.
      * **Dead Letter Queue settings** allow you to redirect messages that the trigger sends to the function.

          You can use a standard message queue as a dead-letter queue. If you do not have a message queue, [create one in Yandex Message Queue](../../message-queue/operations/message-queue-new-queue.md).

  1. Click **Create trigger**.

{% endlist %}

### View the trigger result in Managed Service for PostgreSQL {#processing-function-trigger-results}

Shortly after creating the trigger, you can check how it works.

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), select the folder you are using to complete this tutorial.
  1. Navigate to **Managed Service for&nbsp;PostgreSQL**.
  1. Select the `my-pg-database` cluster.
  1. In the left-hand menu, select **SQL**.
  1. In the **Password** field, specify the password you set to access the database and click **Connect**.
  1. Select the `public` folder.
  1. View the changes in the `iot_events` table.

{% endlist %}

## Configure monitoring in DataLens {#configure-datalens}

To monitor the state of your devices, configure a [connection](../../datalens/concepts/connection/index.md), create a [dataset](../../datalens/dataset/index.md), [charts](../../datalens/concepts/chart/index.md), and a [dashboard](../../datalens/concepts/dashboard.md).

### Set up a connection to Managed Service for PostgreSQL {#connect-mpg}

{% list tabs group=instructions %}

- DataLens UI {#console}

  1. In the [management console](https://console.yandex.cloud), select the folder you are using to complete this tutorial.
  1. Navigate to **DataLens**.
  1. Click **Create connection**.
  1. Select the **PostgreSQL** connector.

      When connecting to an external data source (which is not a Yandex Cloud resource), grant access to the source [for the DataLens IP address ranges](../../datalens/concepts/connection/index.md#changing-connection-ranges).

  1. Select a cloud and folder.
  1. Select the `my-pg-database` cluster and a host.
  1. In the **Port** field, specify `6432`.
  1. Select `db1` as the database and `user1` as the user.
  1. In the **Password** field, specify the password you set to access the database in Managed Service for PostgreSQL.
  1. Click **Create connection**.
  1. In the window that opens, specify the `MyPGConnection` name for the connection and click **Create**.

{% endlist %}

### Create a dataset {#create-dataset}

{% list tabs group=instructions %}

- DataLens UI {#console}

  1. In the [management console](https://console.yandex.cloud), select the folder you are using to complete this tutorial.
  1. Navigate to **DataLens**.
  1. Click **Create dataset**.
  1. In the left-hand panel, click ![image](../../_assets/console-icons/plus.svg) **Add**.
  1. Select the `MyPGConnection` connection.
  1. In the left-hand menu, select the `public.iot_events` and `public.iot_position` tables and drag them to the right.
  1. Click **Save**.
  1. In the window that opens, specify `My-pg-dataset` as the dataset name and click **Create**.

      The dataset will appear in the list.

{% endlist %}

### Create a chart for temperature and mains voltage {#create-chart}

{% list tabs group=instructions %}

- DataLens UI {#console}

  1. In the [management console](https://console.yandex.cloud), select the folder you are using to complete this tutorial.
  1. Navigate to **DataLens**.
  1. Click **Create chart**.
  1. In the left-hand panel, click ![image](../../_assets/console-icons/circles-intersection.svg) **Select dataset** and select `My-pg-dataset`, which you created previously.
  1. Select **Line chart** as your [chart type](../../datalens/visualization-ref/line-chart.md).
  1. From the **Dimensions** section in the left-hand menu, drag the dimensions to the **Line chart** section as follows:
      * `event_datetime`, to the **X** section.

          A timeline will appear in the lower part of the chart on the X-axis.
      * `temperature` and `power_voltage`, to the **Y** section.

      The temperature and mains voltage values will appear on the Y-axis of the chart.
  1. Click **Save**.
  1. In the window that opens, specify the chart name or use the generated `My-pg-dataset — Line chart` name and click **Save**.

{% endlist %}

### Create a chart with a map {#create-chart-map}

{% list tabs group=instructions %}

- DataLens UI {#console}

  1. In the [management console](https://console.yandex.cloud), select the folder you are using to complete this tutorial.
  1. Navigate to **DataLens**.
  1. Create a field to define device coordinates:
      1. In the left-hand menu, select **Datasets**.
      1. Select `My-pg-dataset` from the list of datasets.
      1. Go to the **Fields** tab.
      1. In the right part of the window, click ![image](../../_assets/console-icons/plus.svg) **Add field**.
      1. In the window that opens, in the **Field name** field, enter `Position`.
      1. In the **Formula** field, insert `GEOPOINT([latitude],[longitude])`.
      1. Click **Create**.
      1. Click **Save**.
  1. Create a chart:
      1. At the top right, click **Create chart**.
      1. Select `Map` as the [chart type](../../datalens/visualization-ref/map-chart.md).
      1. From the **Dimensions** section in the left-hand menu, drag the dimensions to the **Map** section as follows:
          * `Position`, to the **Geopoints** section.
          * `item1_fullness`, `item2_fullness`, `item3_fullness`, `item4_fullness`, and `cash_drawer`, to the **Tooltips** section.

              On the right side of the window, you will see a scalable map with vending machines displayed as dots on the map and tooltips displayed as legend lines when you hover over the dots.
      1. Click **Save**.
      1. In the window that opens, specify the chart name or use the generated `My-pg-dataset — Map` name and click **Save**.

{% endlist %}

### Create a dashboard {#create-dashboard}

{% list tabs group=instructions %}

- DataLens UI {#console}

  1. In the [management console](https://console.yandex.cloud), select the folder you are using to complete this tutorial.
  1. Navigate to **DataLens**.
  1. Click **Create dashboard**.
  1. Add the `My-pg-dataset — Map` and `My-pg-dataset — Line chart` charts, which you created at the previous steps, to the dashboard:
      1. In the bottom panel, click **Chart**.
      1. In the **Chart** field of the window that opens, click **Select** and select `My-pg-dataset — Map`.
      1. Click **Add**.
      1. Repeat the steps to add `My-pg-dataset — Line chart`.
  1. Configure the selector:
      1. In the bottom panel, click **Selector**.
      1. In the **Dataset** field, click **Select** and select `My-pg-dataset`.
      1. In the **Field** list, select `device_id`.
      1. In the **Default value** list, select the ID of any one device you created in Yandex IoT Core.
      1. In the **Header** field, enter `Device`.
      1. Click **Add**.
  1. Configure links:
      1. At the top right, click **Links**.
      1. In the window that opens, select the `My-pg-dataset — Map` chart from the list.
      1. In the **In.link** drop-down list, select `Ignore`.

          Maps do not support the **Links** parameter.

      1. In the list, select `My-pg-dataset — Line chart`.
      1. In the **In.link** drop-down list, select `In.link`.
      1. Click **Save**.

  1. Click **Save**.
  1. In the window that opens, enter `MyDash` as the dashboard name.
  1. Click **Create**.

{% endlist %}

After completing the tutorial, you will be able to monitor sensor readings on a map and chart.

## How to delete the resources you created {#cleanup}

To stop paying for the resources you created:

1. [Delete](../../iot-core/operations/device/device-delete.md) the devices in Yandex IoT Core.
1. [Delete](../../iot-core/operations/registry/registry-delete.md) the registry in Yandex IoT Core.
1. [Delete](../../functions/operations/trigger/trigger-delete.md) the triggers for function calls in Cloud Functions.
1. [Delete](../../functions/operations/function/function-delete.md) the functions in Cloud Functions.
1. [Delete](../../managed-postgresql/operations/cluster-delete.md) the cluster in Managed Service for PostgreSQL.
1. [Delete](../../vpc/operations/address-delete.md) the static public IP address if you reserved one.