Skip to content

Add connection via device credentials #521

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jun 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
- name: Integration tests
uses: actions/setup-node@v1
with:
node-version: '12'
node-version: '16'
- run: npm install
- run: npm run lint
- run: npm run test
Expand Down
10 changes: 9 additions & 1 deletion .github/workflows/verify-version.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,15 @@ jobs:
name: Verify versions
shell: bash
run: |
if [[ ${{ needs.get-current-version.outputs.version }} > ${{ needs.get-master-version.outputs.version }} ]] ; then
verlte() {
[ "$1" = "`echo -e "$1\n$2" | sort -V | head -n1`" ]
}

verlt() {
[ "$1" = "$2" ] && return 1 || verlte $1 $2
}

if verlt ${{ needs.get-master-version.outputs.version }} ${{ needs.get-current-version.outputs.version }} ; then
echo 'Version is ok!'
else
echo 'Must bump app version' && exit 1
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v14.17.0
v16.15.0
4 changes: 2 additions & 2 deletions LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
This file includes licensing information for arduino-iot-js.

Copyright (c) 2018
Authors: Fabrizio Mirabito
Copyright (c) 2023
Authors: Fabrizio Mirabito, Francesco Pirrotta

The software is released under the GNU General Public License, which covers the main body
of the [insert app name] code. The terms of this license can be found at:
Expand Down
226 changes: 74 additions & 152 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,192 +1,114 @@

[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
[![npm version](https://badge.fury.io/js/arduino-iot-js.svg)](https://badge.fury.io/js/arduino-iot-js)

# arduino-iot-js

## Introduction
This NPM module provides interaction with the Arduino IoT Cloud MQTT broker. It can be used both from the browser and node.js

The main features of this module are:
- Connection/disconnection to Arduino IoT Cloud Broker using WebSocket
- Send IoT Cloud *property* updates
- Listen for IoT Cloud *property* updates made by other clients and/or devices
This library provides interaction with the **Arduino IoT Cloud MQTT broker** and It can be used both from the browser and Node.js

It allows to connect in two different modes:

If you are looking for a way to create, read, update, delete resources like
- Devices
- Things
- Properties
- Data Timeseries
- via **[User credentials](examples/1.user-credentials/README.md)**, to send or listen every properties of a user
- via **[Device credentials](examples/2.device-credentials/README.md)**, to behave as a single device

please check the official [Javascript Rest API client](https://www.npmjs.com/package/@arduino/arduino-iot-client).
The main features of this module are:

If you want to learn more about Arduino IoT Cloud architecture, check the official [getting started documentation](https://www.arduino.cc/en/IoT/HomePage).
- Connection/disconnection to Arduino IoT Cloud Broker using WebSocket
- Behave as a device via MQTT
- Send IoT Cloud _property_ updates
- Listen for IoT Cloud _property_ updates made by other clients and/or devices

If you are looking for a way to create, read, update, delete resources (like Devices , Things, Properties, Data Timeseries, ecc...) please check the official [Javascript Rest API client](https://www.npmjs.com/package/@arduino/arduino-iot-client).

If you want to learn more about Arduino IoT Cloud architecture, check the official [getting started documentation](https://www.arduino.cc/en/IoT/HomePage).

## Installation

Via NPM

```bash
$ npm install arduino-iot-js
```

## How to use
The MQTT connection over Websocket relies on Username / Password authentication. Under the hood, this module uses your user ID (plus a timestamp) as *Username* and needs a valid JWT Token as *Password*. You can use either a valid JWT token or just your API Credentials (*clientId* and *clientSecret*).
Via Yarn

### How to import arduino-iot-js in your project
Using a web application in the browser
```javascript
import { ArduinoIoTCloud } from 'arduino-iot-js'
```
Using nodejs
```javascript
const { ArduinoIoTCloud } = require('arduino-iot-js');
```bash
$ yarn add arduino-iot-js
```

### How to connect to Arduino IoT Cloud broker using API Credentials
```javascript
const { ArduinoIoTCloud } = require('arduino-iot-js');
## How to use

The MQTT connection relies on Username / Password authentication.

const options = {
clientId: "YOUR_CLIENT_ID",
clientSecret: "YOUR_CLIENT_SECRET",
onDisconnect: message => {
console.error(message);
}
}
Under the hood, this module could uses your user ID (plus a timestamp) as _Username_ and a valid JWT Token as _Password_ when needs to connect to every properties (You can use either a valid JWT token or just your API Credentials) or some device credentials.

ArduinoIoTCloud.connect(options)
.then(() => console.log("Connected to Arduino IoT Cloud broker"))
.catch(error => console.error(error));
```
### How to connect via **User Credentials**

### How to listen for property value updates
After a successful connection, you can listen for property updates.
To do this you need:
- The ID of the *Thing* the *property* belongs to. You can list all your things and properties using the [Javascript Rest API client](https://www.npmjs.com/package/@arduino/arduino-iot-client), calling the [GET Things endpoint](https://www.arduino.cc/reference/en/iot/api/index.html#api-ThingsV2-thingsV2List)
- The *variable name* of the property you want to listen

```javascript
const { ArduinoIoTCloud } = require('arduino-iot-js');
const thingId = "THING_ID"
const variableName = "PROPERTY_NAME"

const options = {
clientId: "YOUR_CLIENT_ID",
clientSecret: "YOUR_CLIENT_SECRET",
onDisconnect: message => {
console.error(message);
}
}
- via **API Credentials**

ArduinoIoTCloud.connect(options)
.then(() => {
console.log("Connected to Arduino IoT Cloud broker");
return ArduinoIoTCloud.onPropertyValue(thingId, variableName, showUpdates = value => console.log(value));
})
.then(() => console.log("Callback registered"))
.catch(error => console.log(error));
```
Each time a new value is sent from the Device, the `counterUpdates` callback will be called.
```typescript
import { ArduinoIoTCloud } from 'arduino-iot-js';

### How to disconnect from Arduino IoT Cloud Broker
```javascript
ArduinoCloud.disconnect()
.then(() => console.log("Successfully disconnected"));
```
### How to send property values to the device
To do this you need:
- The ID of the *Thing* the *property* belongs to. You can list all your things and properties using the [Javascript Rest API client](https://www.npmjs.com/package/@arduino/arduino-iot-client), calling the [GET Things endpoint](https://www.arduino.cc/reference/en/iot/api/index.html#api-ThingsV2-thingsV2List)
- The *variable name* of the property you want to set
- Value can be either a string, a boolean or a number
```javascript
const { ArduinoIoTCloud } = require('arduino-iot-js');
const thingId = "THING_ID"
const variableName = "PROPERTY_NAME"

const options = {
clientId: "YOUR_CLIENT_ID",
clientSecret: "YOUR_CLIENT_SECRET",
onDisconnect: message => {
console.error(message);
}
}
(async () => {
const client = await ArduinoIoTCloud.connect({
clientId: 'YOUR_CLIENT_ID',
clientSecret: 'YOUR_CLIENT_SECRET',
onDisconnect: (message) => console.error(message),
});

ArduinoIoTCloud.connect(options).then(() => {
console.log("Connected to Arduino IoT Cloud broker");
ArduinoCloud.sendProperty(thingId, variableName, value).then(() => {
console.log("Property value correctly sent");
});
});
// Send a value to a thing property
const value = 'some value';
client.sendProperty('YOUR_THING_ID', 'YOUR_VARIABLE_NAME', value);

// Listen to a thing property's changes
client.onPropertyValue('YOUR_THING_ID', 'ANOTHER_VARIABLE_NAME', (value) => console.log(value));
})();
```
### How to listen to every user properties updates
```javascript
const { ArduinoIoTCloud } = require('arduino-iot-js');
const ArduinoIoTApi = require('@arduino/arduino-iot-client');

const options = {
clientId: "YOUR_CLIENT_ID",
clientSecret: "YOUR_CLIENT_SECRET",
onDisconnect: message => {
console.error(message);
}

- via **User JWT Token**

```typescript
import { ArduinoIoTCloud } from 'arduino-iot-js';

async function retrieveUserToken() {
// Retrieve JWT Token here
}

// Connect to Arduino IoT Cloud MQTT Broker
ArduinoIoTCloud.connect(options)
.then(() => {
console.log("Connected to Arduino IoT Cloud MQTT broker");

// Init Arduino API Client
const ArduinoIoTClient = ArduinoIoTApi.ApiClient.instance;
ArduinoIoTClient.authentications['oauth2'].accessToken = ArduinoIoTCloud.getToken();

const thingsApi = new ArduinoIoTAPI.ThingsV2Api(ArduinoIoTClient);
const propertiesAPI = new ArduinoIoTApi.PropertiesV2Api(ArduinoIoTClient);

return thingsApi.thingsV2List()
.then(things => {
things.forEach(thing => {
propertiesAPI.propertiesV2List(thing.id)
.then(properties => {
properties.forEach(property => {
ArduinoIoTCloud.onPropertyValue(thing.id, property.variable_name,
showUpdates = value => console.log(property.variable_name + ": " + value))
.then(() => console.log("Callback registered for " + property.variable_name))
.catch(error => console.error(error));
});
})
.catch(error => console.error(error));
});
});
})
.catch(error => console.error(error));
```
(async () => {
const token = await retrieveUserToken();

## Development
const client = await ArduinoIoTCloud.connect({
token,
onDisconnect: (message) => console.error(message),
});

### Testing
In order to test the library you have to export a couple of environment variables and then
launch a specific `npm` script as follows:
// Send a value to a thing property
const value = 'some value';
client.sendProperty('YOUR_THING_ID', 'YOUR_VARIABLE_NAME', value);

```sh
$ export CLIENT_ID=<YOUR_CLIENT_ID>
$ export CLIENT_SECRET=<YOUR_CLIENT_SECRET>
$ npm run test
// Listen to a thing property's changes
client.onPropertyValue('YOUR_THING_ID', 'ANOTHER_VARIABLE_NAME', (value) => console.log(value));
})();
```

## Changelog
### [0.9.0] - 2023-01-16
### How to connect via **Device Credentials**

#### Changed
A few development settings have been updated, this should not affect how the library works.
- 'mqtt' is imported differently if the library is used in the browser or in node.
In browser we're using 'mqtt/dist/mqtt' because of some issues with React with some bundlers (namely, Parcel 2)

See:
```typescript
import { ArduinoIoTCloud } from 'arduino-iot-js';

[https://github.com/mqttjs/MQTT.js/issues/1412#issuecomment-1193363330](https://github.com/mqttjs/MQTT.js/issues/1412#issuecomment-1193363330)
(async () => {
const client = await ArduinoIoTCloud.connect({
deviceId: 'YOUR_DEVICE_ID',
secretKey: 'YOUR_SECRET_KEY',
onDisconnect: (message) => console.error(message),
});

[https://github.com/mqttjs/MQTT.js/issues/1233](https://github.com/mqttjs/MQTT.js/issues/1233)
// Send property's values as a device
const value = 'some value';
client.sendProperty('YOUR_VARIABLE_NAME', value);

- updated README file with this changelog and some instructions about testing
// Listen property's updates
client.onPropertyValue('ANOTHER_VARIABLE_NAME', (value) => console.log(value));
})();
```
41 changes: 0 additions & 41 deletions examples/listenProperties/index.js

This file was deleted.

Loading