• Stars
    star
    142
  • Rank 258,495 (Top 6 %)
  • Language
    JavaScript
  • License
    Apache License 2.0
  • Created almost 6 years ago
  • Updated 7 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Javascript/NodeJS SDK to create SmartThings SmartApps

SmartThings SmartApp Node.js SDK

Language grade: JavaScript Total alerts Known Vulnerabilities

Reference Documentation

For a detailed look at the API, check out the reference documentation.

Getting Started

Version 2.0 Release

This major release is not fully backwards compatible with version 1.X, though for most SmartApps the changes required should be relatively minor. The major non-backwards compatible changes include:

  • Methods that return lists now return arrays instead of objects with the properties items and _links.
  • Axios is now used rather than request-promise-native for making HTTP calls, resulting in changes to the error objects thrown when exceptions occur.

See the Version 2.0.0 release notes for more information.

This SDK includes a set of Node.js libraries for building Webhook and AWS Lambda SmartApps, and interacting with the public SmartThings API.

Highlights include:

  • ✅ Javascript API hides details of REST calls and authentication.
  • ✅ Event handler framework dispatches lifecycle events to named event handlers.
  • ✅ Configuration page API simplifies page definition.
  • ✅ Integrated i18n framework provides configuration page localization.
  • ✅ Winston framework manges log messages.
  • ✅ Context Store plugins – easily scale access token management (and more) to support many users.

What is a SmartApp?

SmartApps are custom applications that execute outside of the SmartThings Platform. All of the SmartApp execution will happen on the server or Lambda that you control. The complexity of execution and the number of expected users will need to be examined to understand the hardware or execution requirements your app needs to handle. Your application will respond to lifecycle events sent from SmartThings to perform actions on behalf of your users and will execute any scheduled tasks that you have created in the SmartApp. Creating a SmartApp allows you to control and get status notifications from SmartThings devices using the SmartThings API.

Hosting Your SmartApp

There are two distinct options for hosting your SmartApp: AWS Lambda and Webhook.

  • AWS Lambda SmartApps are hosted in the Amazon Web Services cloud and are invoked by ARN instead of a public-DNS address.

  • Webhook SmartApps are any publicly-accessible web server that will receive a POST request payload.

To learn more about SmartApps, including choosing the best hosting solution for your SmartApp, visit the SmartApp developer documentation.

Installation

npm i @smartthings/smartapp --save

Importing

Node.js:

const SmartApp = require('@smartthings/smartapp')

Or ES2015+:

import SmartApp from '@smartthings/smartapp'

Examples

The example SmartApp below is the equivalent of a simple Rule (if contact sensor opens/closes, turn lights on/off) which is easily achieved via our Rules API. It is given here as a brief showcase of the SDK, and is not meant to be a good candidate for a SmartApp.

Before hosting your own Automation, be sure to check out Rules. When all services and Device features involved in a Rule are local, Rules execute locally on a Hub, allowing you to benefit from greater speed, stability, and security than cloud-reliant solutions.

Running as a Web Service

To run your SmartApp with an HTTP server, such as Express.js:

const SmartApp = require('@smartthings/smartapp');
const express = require('express');
const server = express();
const PORT = 8080;


/* Define the SmartApp */
const smartapp = new SmartApp()
    .enableEventLogging(2) // logs all lifecycle event requests and responses as pretty-printed JSON. Omit in production
    .page('mainPage', (context, page, configData) => {
        page.section('sensors', section => {
            section
                .deviceSetting('contactSensor')
                .capabilities(['contactSensor'])
        });
        page.section('lights', section => {
            section
                .deviceSetting('lights')
                .capabilities(['switch'])
                .permissions('rx')
                .multiple(true);
        });
    })
    // Called for both INSTALLED and UPDATED lifecycle events if there is no separate installed() handler
    .updated(async (context, updateData) => {
        await context.api.subscriptions.delete() // clear any existing configuration
        await context.api.subscriptions.subscribeToDevices(context.config.contactSensor, 'contactSensor', 'contact', 'myDeviceEventHandler');
    })
    .subscribedEventHandler('myDeviceEventHandler', async (context, event) => {
        const value = event.value === 'open' ? 'on' : 'off';
        await context.api.devices.sendCommands(context.config.lights, 'switch', value);
    });

server.use(express.json());

/* Handle POST requests */
server.post('/', function (req, res, next) {
    smartapp.handleHttpCallback(req, res);
});

/* Start listening at your defined PORT */
server.listen(PORT, () => console.log(`Server is up and running on port ${PORT}`));

Running as an AWS Lambda Function

To run your SmartApp as a Lambda function instead of an HTTP server, ensure that your main entry file exports smartapp.handleLambdaCallback(...).

Note that this snippet is heavily truncated for brevity:

const SmartApp = require('@smartthings/smartapp');

const smartapp = new SmartApp()
    .enableEventLogging() // logs all lifecycle event requests and responses. Omit in production
    .page( ... )
    .updated(() => { ... })
    .subscribedEventHandler( ... );

exports.handler = (event, context, callback) => {
    smartapp.handleLambdaCallback(event, context, callback);
};

Additional Examples

You can find additional examples in Glitch:

More detailed examples to use as a starting point can be found in our smartthings-smartapp-example Github Topic.

Localization

Configuration page strings are specified in a separate locales/en.json file, which can be automatically created the first time you run the app. Here's a completed English localization file for the previous simple SmartApp example:

{
  "pages.mainPage.name": "Let There Be Light",
  "pages.mainPage.sections.sensors.name": "When this door or window opens or closes",
  "pages.mainPage.settings.contactSensor.name": "Select open/close sensor",
  "pages.mainPage.sections.lights.name": "Turn on and off these lights and switches",
  "pages.mainPage.settings.lights.name": "Select lights and switches",
  "Tap to set": "Tap to set"
}

Unhandled Promise Rejection Handling

By default, instantiation of the SmartApp object registers an unhandledReject handler that logs unhandled promise rejections. You can disable this behavior by passing an option to the SmartApp instantiation (e.g. new SmartApp({logUnhandledRejections: false})).

If desired, you can replace the handler by calling unhandledRejectionHandler(promise => {...}) on the SmartApp object.

Making API Calls Outside of an EVENT Handler

By default, the SmartApp SDK will facilitate API calls on behalf of a user within the EVENT lifecycle. These user tokens are ephemeral and last 5 minutes. These access tokens are not able to be refreshed and should not be stored.

If you are making out-of-band API calls on behalf of a user's installed app, you will need to use the 24-hour access token that is supplied after the INSTALL and UPDATE lifecycles. This token includes a refresh_token, and will automatically be refreshed by the SDK when necessary.

Note that there is no in-memory context store; you must use a context store plugin. If you'd like to add a custom context store plugin, please consider contributing.

To get started with our context store example below, we will add a compatible ContextStore plugin that will persist these tokens (among other things) to a database.

Amazon AWS DynamoDB

Available as a node package on NPM or fork on GitHub.

If you are hosting your SmartApp as an AWS Lambda, this DynamoDB context store makes perfect sense. This assumes you've already configured the aws-sdk package to interact with your Lambda, so extending your context store to DynamoDB is a drop-in solution.

If you are self-hosted and still want to use DynamoDB, you can do that, too:

  1. Import the package to your project: npm i --save @smartthings/dynamodb-context-store
    • Note: when adding this package, you also have aws-sdk available at the global scope, so you can configure the AWS SDK: AWS.config.loadFromPath(creds)
  2. Get an AWS Access Key and Secret
  3. Set your credentials for your app, any of the following ways are fine.
  4. Register your Context Store plugin as described on the project repository's readme.

For complete directions on usage, please see this project's GitHub repository. (SmartThingsCommunity/dynamodb-context-store-nodejs)

Firebase Cloud Firestore

Available as a node package on NPM or fork on GitHub.

Usage is generally the same as DynamoDB:

  1. Generate a Firebase service account. You will receive a JSON file with the credentials.
  2. Load your Google Services JSON
  3. Create the context store

See the full usage guide on the project's GitHub repository.


More about SmartThings

Check out our complete developer documentation here.

To create and manage your services and devices on SmartThings, create an account in the developer workspace.

The SmartThings Community is a good place share and ask questions.

There is also a SmartThings reddit community where you can read and share information.

License and Copyright

Licensed under the Apache License, Version 2.0

Copyright 2023 Samsung Electronics Co., LTD.

More Repositories

1

SmartThingsPublic

SmartThings open-source DeviceType Handlers and SmartApps code
Groovy
2,556
star
2

SmartThingsEdgeDrivers

Lua
256
star
3

smartthings-cli

Command-line Interface for the SmartThings APIs.
TypeScript
233
star
4

st-device-sdk-c-ref

SmartThings SDK Reference for Direct Connected Devices for C
C
124
star
5

st-device-sdk-c

SmartThings SDK for Direct Connected Devices for C
C
122
star
6

smartthings-core-sdk

SDK for calling the SmartThings API from JavaScript and TypeScript applications
TypeScript
113
star
7

Code

DEPRECATED A collection of code examples from the SmartThings team, and the community
Groovy
81
star
8

weather-color-light-smartapp-nodejs

This SmartApp sets the color of a light based on the weather forecast.
JavaScript
56
star
9

smartapp-sdk-java

A collection of consumer-oriented Java (JVM) libraries for creating SmartApps and using the public API
Java
50
star
10

cli-example-nodejs

An example CLI to interact with SmartThings-connected devices, written in Node.js
JavaScript
37
star
11

st-schema-nodejs

ST Schema helper library for NodeJS
JavaScript
36
star
12

app-examples

JavaScript
12
star
13

example-lifx-nodejs-web-connector

LIFX C2C connector implementation as NodeJS web service
JavaScript
12
star
14

st-schema-connectors

Example connectors written for ST Schema
JavaScript
10
star
15

api-app-subscription-example-js

Example API Access SmartApp that shows the state and allows control of devices
JavaScript
9
star
16

api-app-minimal-example-js

Simple API Access integration that allows scenes to be executed
JavaScript
8
star
17

st-schema-oauth-example

Compete ST Schema connector example including OAuth server and virtual device web app
JavaScript
8
star
18

dynamodb-context-store-nodejs

Stores SmartApp configuration and auth tokens for use in app-initiated calls
JavaScript
7
star
19

acme-control-panel-example

Example SmartApp that creates C2C devices as well as providing scene and device control
JavaScript
7
star
20

generator-smartthings

Yeoman generator to bootstrap a SmartThings Cloud SDK-based app
JavaScript
6
star
21

MyCloudToCloudSchemaConnection

JavaScript
5
star
22

homebrew-smartthings

Ruby
4
star
23

smartapp-example-no-devices-nodejs-lambda

Give Lambda SmartApps a try without any physical devices.
JavaScript
4
star
24

smartapp-example-open-close-nodets

The Typescript version of the Open/Close example SmartApp.
TypeScript
3
star
25

example-lifx-lambda-connector

Imports LIFX devices into SmartThings
JavaScript
3
star
26

edge-cli-plugin

TypeScript
3
star
27

st-schema-simple-example-js

Very simple ST-Schema connector that creates one device
JavaScript
2
star
28

smartapp-example-every-setting-nodejs

This SmartApp has multiple configuration pages that contain examples of all setting types.
JavaScript
2
star
29

firestore-context-store-nodejs

Stores SmartApp configuration and auth tokens for use in app-initiated calls
JavaScript
2
star
30

github-actions

A library of reusable workflows
2
star
31

st-schema-callback-example-js

ST Schema virtual device example with proactive state updates
JavaScript
2
star
32

file-context-store-nodejs

File-based context store for SmartApps
JavaScript
1
star
33

device-scene-example-nodejs

Example SmartApp that stores installed app context makes callback to the SmartThings platform
JavaScript
1
star
34

slack-nodejs-workshop

JavaScript
1
star
35

smartapp-example-open-close-nodejs

This SmartApp turns on and off a light when something opens and closes.
JavaScript
1
star
36

drlc-prototype

JavaScript
1
star
37

dummy-oauth-server

OAuth2 server intended for testing clients, especially ST Schema connectors
1
star