node-red-contrib-smartthings
Version:
Querying/Controlling Smartthings Devices
933 lines (888 loc) • 51.5 kB
JavaScript
const https = require('https');
const Promise = require('promise');
const HttpSignature = require('http-signature');
const fs = require('fs');
const {SmartThingsClient,BearerTokenAuthenticator} = require('@smartthings/core-sdk');
const SmartApp = require('@smartthings/smartapp');
class NodeRedContextStore {
constructor(RED) {
this.userDir = RED.settings.userDir;
this.storeDir = this.userDir + "/smartthings/context/";
console.log("Creating directory: " + this.storeDir);
if (!fs.existsSync(this.storeDir)){
fs.mkdirSync(this.storeDir, { recursive: true });
}
}
readFile(installedAppId) {
console.log("readFile");
return new Promise((resolve, reject) => {
fs.readFile(this.storeDir + installedAppId + ".context", 'utf8', (err, data) => {
if (err) {
reject(err);
return;
}
resolve(JSON.parse(data));
});
});
}
writeFile(installedAppId, data) {
console.log("writeFile");
return new Promise((resolve, reject) => {
fs.writeFile(this.storeDir + installedAppId + ".context", JSON.stringify(data), err => {
if (err) {
reject(err);
return;
}
resolve(data);
});
});
}
deleteFile(installedAppId){
console.log("deleteFile");
return new Promise((resolve, reject) => {
fs.unlink(this.storeDir + installedAppId + ".context", err => {
if (err) {
reject(err);
return;
}
resolve();
});
});
}
get(installedAppId) {
console.log("NodeRedContextStore.get");
return new Promise((resolve, reject) => {
this.readFile(installedAppId).then( (data) => {
resolve(data);
}).catch( (err) => {
resolve({});
})
});
}
put(params) {
console.log("NodeRedContextStore.put");
return new Promise((resolve, reject) => {
this.writeFile(params.installedAppId, params).then( (data) => {
resolve(data);
}).catch( (err) => {
reject(err);
});
});
}
update(installedAppId, params) {
console.log("NodeRedContextStore.update");
return new Promise((resolve, reject) => {
this.writeFile(installedAppId, params).then( () => {
resolve(params);
}).catch( (err) => {
reject(err);
});
});
}
delete(installedAppId) {
console.log("NodeRedContextStore.delete");
return new Promise((resolve, reject) => {
this.deleteFile(installedAppId).then( () => {
resolve({});
}).catch( err => {
reject(err);
});
});
}
listAll(){
console.log("NodeRedContextStore.listAll");
return new Promise((resolve, reject) => {
fs.readdir(this.storeDir, function (err, files) {
if (err) {
reject(err);
}
let ret = [];
files.forEach(function (file) {
ret.push(file.replace(".context",""));
});
resolve(ret);
});
});
}
}
module.exports = function(RED) {
console.log("SmartthingsConfigNode");
const nodeContextStore = new NodeRedContextStore(RED);
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.name("NodeRed Smartthings Integration");
page.section('accelerationSensor', section => {
section
.deviceSetting('accelerationSensor')
.capabilities(['accelerationSensor'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('airQualitySensor', section => {
section
.deviceSetting('airQualitySensor')
.capabilities(['airQualitySensor'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('alarm', section => {
section
.deviceSetting('alarm')
.capabilities(['alarm'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('audioMute', section => {
section
.deviceSetting('audioMute')
.capabilities(['audioMute'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('audioNotification', section => {
section
.deviceSetting('audioNotification')
.capabilities(['audioNotification'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('audioStream', section => {
section
.deviceSetting('audioStream')
.capabilities(['audioStream'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('audioVolume', section => {
section
.deviceSetting('audioVolume')
.capabilities(['audioVolume'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('battery', section => {
section
.deviceSetting('battery')
.capabilities(['battery'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('button', section => {
section
.deviceSetting('button')
.capabilities(['button'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('bypassable', section => {
section
.deviceSetting('bypassable')
.capabilities(['bypassable'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('carbonDioxideMeasurement', section => {
section
.deviceSetting('carbonDioxideMeasurement')
.capabilities(['carbonDioxideMeasurement'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('carbonMonoxideDetector', section => {
section
.deviceSetting('carbonMonoxideDetector')
.capabilities(['carbonMonoxideDetector'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('colorControl', section => {
section
.deviceSetting('colorControl')
.capabilities(['colorControl'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('colorTemperature', section => {
section
.deviceSetting('colorTemperature')
.capabilities(['colorTemperature'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('contactSensor', section => {
section
.deviceSetting('contactSensor')
.capabilities(['contactSensor'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('dewPoint', section => {
section
.deviceSetting('dewPoint')
.capabilities(['dewPoint'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('doorControl', section => {
section
.deviceSetting('doorControl')
.capabilities(['doorControl'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('dustSensor', section => {
section
.deviceSetting('dustSensor')
.capabilities(['dustSensor'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('energyMeter', section => {
section
.deviceSetting('energyMeter')
.capabilities(['energyMeter'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('equivalentCarbonDioxideMeasurement', section => {
section
.deviceSetting('equivalentCarbonDioxideMeasurement')
.capabilities(['equivalentCarbonDioxideMeasurement'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('fanOscillationMode', section => {
section
.deviceSetting('fanOscillationMode')
.capabilities(['fanOscillationMode'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('fanSpeed', section => {
section
.deviceSetting('fanSpeed')
.capabilities(['fanSpeed'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('filterState', section => {
section
.deviceSetting('filterState')
.capabilities(['filterState'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('fineDustSensor', section => {
section
.deviceSetting('fineDustSensor')
.capabilities(['fineDustSensor'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('formaldehydeMeasurement', section => {
section
.deviceSetting('formaldehydeMeasurement')
.capabilities(['formaldehydeMeasurement'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('healthCheck', section => {
section
.deviceSetting('healthCheck')
.capabilities(['healthCheck'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('illuminanceMeasurement', section => {
section
.deviceSetting('illuminanceMeasurement')
.capabilities(['illuminanceMeasurement'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('imageCapture', section => {
section
.deviceSetting('imageCapture')
.capabilities(['imageCapture'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('infraredLevel', section => {
section
.deviceSetting('infraredLevel')
.capabilities(['infraredLevel'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('locationMode', section => {
section
.deviceSetting('locationMode')
.capabilities(['locationMode'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('lock', section => {
section
.deviceSetting('lock')
.capabilities(['lock'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('motionSensor', section => {
section
.deviceSetting('motionSensor')
.capabilities(['motionSensor'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('networkMeter', section => {
section
.deviceSetting('networkMeter')
.capabilities(['networkMeter'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('notification', section => {
section
.deviceSetting('notification')
.capabilities(['notification'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('objectDetection', section => {
section
.deviceSetting('objectDetection')
.capabilities(['objectDetection'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('panicAlarm', section => {
section
.deviceSetting('panicAlarm')
.capabilities(['panicAlarm'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('pHMeasurement', section => {
section
.deviceSetting('pHMeasurement')
.capabilities(['pHMeasurement'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('powerMeter', section => {
section
.deviceSetting('powerMeter')
.capabilities(['powerMeter'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('powerSource', section => {
section
.deviceSetting('powerSource')
.capabilities(['powerSource'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('presenceSensor', section => {
section
.deviceSetting('presenceSensor')
.capabilities(['presenceSensor'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('refrigeration', section => {
section
.deviceSetting('refrigeration')
.capabilities(['refrigeration'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('relativeHumidityMeasurement', section => {
section
.deviceSetting('relativeHumidityMeasurement')
.capabilities(['relativeHumidityMeasurement'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('remoteControlStatus', section => {
section
.deviceSetting('remoteControlStatus')
.capabilities(['remoteControlStatus'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('samsungTV', section => {
section
.deviceSetting('samsungTV')
.capabilities(['samsungTV'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('securitySystem', section => {
section
.deviceSetting('securitySystem')
.capabilities(['securitySystem'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('signalStrength', section => {
section
.deviceSetting('signalStrength')
.capabilities(['signalStrength'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('sleepSensor', section => {
section
.deviceSetting('sleepSensor')
.capabilities(['sleepSensor'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('smokeDetector', section => {
section
.deviceSetting('smokeDetector')
.capabilities(['smokeDetector'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('soundPressureLevel', section => {
section
.deviceSetting('soundPressureLevel')
.capabilities(['soundPressureLevel'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('soundSensor', section => {
section
.deviceSetting('soundSensor')
.capabilities(['soundSensor'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('switchLevel', section => {
section
.deviceSetting('switchLevel')
.capabilities(['switchLevel'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('switch', section => {
section
.deviceSetting('switch')
.capabilities(['switch'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('tamperAlert', section => {
section
.deviceSetting('tamperAlert')
.capabilities(['tamperAlert'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('temperatureAlarm', section => {
section
.deviceSetting('temperatureAlarm')
.capabilities(['temperatureAlarm'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('temperatureMeasurement', section => {
section
.deviceSetting('temperatureMeasurement')
.capabilities(['temperatureMeasurement'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('thermostatCoolingSetpoint', section => {
section
.deviceSetting('thermostatCoolingSetpoint')
.capabilities(['thermostatCoolingSetpoint'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('thermostatFanMode', section => {
section
.deviceSetting('thermostatFanMode')
.capabilities(['thermostatFanMode'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('thermostatHeatingSetpoint', section => {
section
.deviceSetting('thermostatHeatingSetpoint')
.capabilities(['thermostatHeatingSetpoint'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('thermostatMode', section => {
section
.deviceSetting('thermostatMode')
.capabilities(['thermostatMode'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('thermostatOperatingState', section => {
section
.deviceSetting('thermostatOperatingState')
.capabilities(['thermostatOperatingState'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('threeAxis', section => {
section
.deviceSetting('threeAxis')
.capabilities(['threeAxis'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('tone', section => {
section
.deviceSetting('tone')
.capabilities(['tone'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('tV', section => {
section
.deviceSetting('tV')
.capabilities(['tV'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('tvocMeasurement', section => {
section
.deviceSetting('tvocMeasurement')
.capabilities(['tvocMeasurement'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('ultravioletIndex', section => {
section
.deviceSetting('ultravioletIndex')
.capabilities(['ultravioletIndex'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('valve', section => {
section
.deviceSetting('valve')
.capabilities(['valve'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('veryFineDustSensor', section => {
section
.deviceSetting('veryFineDustSensor')
.capabilities(['veryFineDustSensor'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('videoCamera', section => {
section
.deviceSetting('videoCamera')
.capabilities(['videoCamera'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('videoCapture', section => {
section
.deviceSetting('videoCapture')
.capabilities(['videoCapture'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('videoStream', section => {
section
.deviceSetting('videoStream')
.capabilities(['videoStream'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('voltageMeasurement', section => {
section
.deviceSetting('voltageMeasurement')
.capabilities(['voltageMeasurement'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('waterSensor', section => {
section
.deviceSetting('waterSensor')
.capabilities(['waterSensor'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('windowShadePreset', section => {
section
.deviceSetting('windowShadePreset')
.capabilities(['windowShadePreset'])
.name("Devices").permissions('rwx').multiple(true);
});
page.section('windowShade', section => {
section
.deviceSetting('windowShade')
.capabilities(['windowShade'])
.name("Devices").permissions('rwx').multiple(true);
});
/*page.section('accelerationSensor', section => {
section
.deviceSetting('devices')
.capabilities(['accelerationSensor','airQualitySensor',
'alarm','audioMute','audioNotification','audioStream',
'audioVolume','battery', 'button', 'bypassable',
'carbonDioxideMeasurement','carbonMonoxideDetector',
'colorControl', 'colorTemperature', 'configuration',
'contactSensor', 'dewPoint', 'doorControl', 'dustSensor',
'energyMeter', 'equivalentCarbonDioxideMeasurement',
'execute', 'fanOscillationMode', 'fanSpeed', 'filterState',
'fineDustSensor', 'firmwareUpdate', 'formaldehydeMeasurement',
'healthCheck', 'illuminanceMeasurement', 'imageCapture',
'infraredLevel', 'locationMode', 'lock', 'moldHealthConcern',
'momentary', 'motionSensor', 'networkMeter', 'notification',
'objectDetection', 'panicAlarm', 'pHMeasurement', 'powerMeter',
'powerSource', 'presenceSensor', 'refresh', 'refrigeration',
'relativeHumidityMeasurement', 'remoteControlStatus',
'samsungTV', 'securitySystem', 'signalStrength',
'sleepSensor', 'smokeDetector', 'soundPressureLevel',
'soundSensor', 'switchLevel', 'switch', 'tamperAlert',
'temperatureAlarm', 'temperatureMeasurement', 'testCapability',
'thermostatCoolingSetpoint', 'thermostatFanMode', 'thermostatHeatingSetpoint',
'thermostatMode', 'thermostatOperatingState', 'threeAxis',
'tone', 'tV', 'tvocMeasurement', 'ultravioletIndex',
'valve', 'veryFineDustSensor', 'videoCamera', 'videoCapture',
'videoStream', 'voltageMeasurement', 'waterSensor', 'webrtc',
'windowShadePreset', 'windowShade', 'zwMultichannel'])
.multiple(true)
.required(true);
});*/
})
// Called for both INSTALLED and UPDATED lifecycle events if there is no separate installed() handler
.updated(async (context, updateData) => {
console.log("Smartthings WebApp Installed/Updated:");
console.log(updateData);
await context.api.subscriptions.delete() // clear any existing configuration
var i = 0;
await context.api.subscriptions.subscribeToDevices(context.config.accelerationSensor, 'accelerationSensor', 'acceleration', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.airQualitySensor, 'airQualitySensor', 'airQuality', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.alarm, 'alarm', 'alarm', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.audioMute, 'audioMute', 'mute', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.audioStream, 'audioStream', 'uri', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.audioVolume, 'audioVolume', 'volume', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.battery, 'battery', 'battery', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.button, 'button', 'button', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.bypassable, 'bypassable', 'bypassStatus', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.carbonDioxideMeasurement, 'carbonDioxideMeasurement', 'carbonDioxide', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.carbonMonoxideDetector, 'carbonMonoxideDetector', 'carbonMonoxide', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.colorControl, 'colorControl', 'color', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.colorControl, 'colorControl', 'hue', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.colorControl, 'colorControl', 'saturation', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.colorTemperature, 'colorTemperature', 'colorTemperature', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.contactSensor, 'contactSensor', 'contact', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.dewPoint, 'dewPoint', 'dewpoint', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.doorControl, 'doorControl', 'door', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.dustSensor, 'dustSensor', 'dustLevel', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.dustSensor, 'dustSensor', 'fineDustLevel', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.energyMeter, 'energyMeter', 'energy', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.equivalentCarbonDioxideMeasurement, 'equivalentCarbonDioxideMeasurement', 'equivalentCarbonDioxideMeasurement', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.fanOscillationMode, 'fanOscillationMode', 'fanOscillationMode', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.fanSpeed, 'fanSpeed', 'fanSpeed', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.filterState, 'filterState', 'filterLifeRemaining', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.fineDustSensor, 'fineDustSensor', 'fineDustLevel', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.formaldehydeMeasurement, 'formaldehydeMeasurement', 'formaldehydeLevel', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.healthCheck, 'healthCheck', 'healthStatus', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.illuminanceMeasurement, 'illuminanceMeasurement', 'illuminance', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.imageCapture, 'imageCapture', 'image', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.infraredLevel, 'infraredLevel', 'infraredLevel', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.locationMode, 'locationMode', 'mode', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.lock, 'lock', 'lock', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.moldHealthConcern, 'moldHealthConcern', 'moldHealthConcern', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.motionSensor, 'motionSensor', 'motion', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.networkMeter, 'networkMeter', 'downlinkSpeed', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.networkMeter, 'networkMeter', 'uplinkSpeed', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.objectDetection, 'objectDetection', 'detected', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.panicAlarm, 'panicAlarm', 'panicAlarm', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.pHMeasurement, 'pHMeasurement', 'pH', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.powerMeter, 'powerMeter', 'power', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.powerSource, 'powerSource', 'powerSource', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.presenceSensor, 'presenceSensor', 'presence', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.refrigeration, 'refrigeration', 'defrost', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.refrigeration, 'refrigeration', 'rapidCooling', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.refrigeration, 'refrigeration', 'rapidFreezing', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.relativeHumidityMeasurement, 'relativeHumidityMeasurement', 'humidity', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.remoteControlStatus, 'remoteControlStatus', 'remoteControlEnabled', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.samsungTV, 'samsungTV', 'messageButton', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.samsungTV, 'samsungTV', 'mute', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.samsungTV, 'samsungTV', 'pictureMode', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.samsungTV, 'samsungTV', 'soundMode', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.samsungTV, 'samsungTV', 'switch', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.samsungTV, 'samsungTV', 'volume', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.securitySystem, 'securitySystem', 'alarm', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.securitySystem, 'securitySystem', 'securitySystemStatus', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.signalStrength, 'signalStrength', 'lqi', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.signalStrength, 'signalStrength', 'rssi', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.sleepSensor, 'sleepSensor', 'sleeping', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.smokeDetector, 'smokeDetector', 'smoke', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.soundPressureLevel, 'soundPressureLevel', 'soundPressureLevel', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.soundSensor, 'soundSensor', 'sound', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.switchLevel, 'switchLevel', 'level', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.switch, 'switch', 'switch', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.tamperAlert, 'tamperAlert', 'tamper', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.temperatureAlarm, 'temperatureAlarm', 'temperatureAlarm', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.temperatureMeasurement, 'temperatureMeasurement', 'temperature', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.thermostatCoolingSetpoint, 'thermostatCoolingSetpoint', 'coolingSetpoint', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.thermostatFanMode, 'thermostatFanMode', 'thermostatFanMode', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.thermostatHeatingSetpoint, 'thermostatHeatingSetpoint', 'heatingSetpoint', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.thermostatMode, 'thermostatMode', 'thermostatMode', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.thermostatOperatingState, 'thermostatOperatingState', 'thermostatOperatingState', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.threeAxis, 'threeAxis', 'threeAxis', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.tone, 'tone', 'beep', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.tV, 'tV', 'channel', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.tV, 'tV', 'movieMode', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.tV, 'tV', 'picture', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.tV, 'tV', 'power', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.tV, 'tV', 'sound', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.tV, 'tV', 'volume', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.tvocMeasurement, 'tvocMeasurement', 'tvocLevel', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.ultravioletIndex, 'ultravioletIndex', 'ultravioletIndex', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.valve, 'valve', 'valve', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.veryFineDustSensor, 'veryFineDustSensor', 'veryFineDustLevel', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.videoCamera, 'videoCamera', 'camera', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.videoCamera, 'videoCamera', 'mute', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.videoCapture, 'videoCapture', 'clip', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.videoCapture, 'videoCapture', 'stream', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.videoStream, 'videoStream', 'stream', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.voltageMeasurement, 'voltageMeasurement', 'voltage', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.waterSensor, 'waterSensor', 'water', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.windowShadePreset, 'windowShadePreset', 'presetPosition', 'handler' + String(i++));
await context.api.subscriptions.subscribeToDevices(context.config.windowShade, 'windowShade', 'windowShade', 'handler' + String(i++));
})
.contextStore(nodeContextStore);
function SmartthingsConfigNode(config) {
RED.nodes.createNode(this, config);
console.log("SmartthingsConfigNode");
console.log(config);
var node = this;
node.callbacks = [];
node.callbackHooks = [];
for(var i = 0; i < 93; i++){
smartapp.subscribedEventHandler('handler' + String(i), async (context, event) => {
console.log("Smartthings WebApp Event Received:");
console.log(event);
if(event["stateChange"] === true){
node.callbackHooks.forEach( (c) => {
c.callback.call(c.parent, event);
});
const callback = node.callbacks[event["deviceId"]];
if(callback){
callback.forEach( (c) => {
c.callback.call(c.parent, event);
});
}
}
});
}
node.token = config.token;
if(node.token !== undefined){
node.stClient = new SmartThingsClient(new BearerTokenAuthenticator(node.token));
node.getDevice = function(deviceId) {
console.log("getDevice:token:"+ node.token);
return new Promise( (resolve, reject) => {
node.stClient.devices.get(deviceId).then(device => {
console.log("Device Info:");
console.log(device);
resolve(device);
}).catch( err => {
reject(err);
});
});
};
node.getDevices = function(type) {
console.log("getDevices:token:"+ node.token);
return new Promise( (resolve, reject) => {
if(type === "all"){
node.stClient.devices.list().then(deviceList => {
console.log("Device List:");
console.log(deviceList);
resolve(deviceList);
}).catch( err => {
reject(err);
});
} else {
node.stClient.devices.list({capability:type}).then(deviceList => {
console.log("Device List:");
console.log(deviceList);
resolve(deviceList);
}).catch( err => {
reject(err);
});
}
});
};
node.unregisterCallback = function(parent, deviceId, callback) {
if(node.callbacks[deviceId]){
node.callbacks[deviceId].filter( (c) => c !== callback);
}
};
node.registerCallback = function(parent, deviceId, callback) {
if(node.callbacks[deviceId] === undefined){
node.callbacks[deviceId] = [];
}
node.callbacks[deviceId].push({
parent: parent,
callback: callback
});
};
node.unregisterCallbackHook = function(parent, callback) {
node.callbackHooks.filter((c) => c.callback !== callback);
};
node.registerCallbackHook = function(parent, callback) {
node.callbackHooks.push({
parent: parent,
callback: callback
});
};
node.getDeviceStatus = function(deviceId, type){
console.log("getDeviceStatus:token:"+ node.token);
return new Promise( (resolve, reject) => {
if (typeof type === 'undefined') {
node.stClient.devices.getStatus(deviceId).then( deviceStatus => {
console.log("Device Status ("+deviceId+"):");
console.log(deviceStatus);
resolve(deviceStatus);
}).catch( err => {
reject(err);
});
} else {
node.stClient.devices.getComponentStatus(deviceId, type).then( deviceStatus => {
console.log("Device Status ("+deviceId+"):");
console.log(deviceStatus);
resolve(deviceStatus);
}).catch( err => {
reject(err);
});
}
});
};
node.executeDeviceCommand = function(deviceId, command){
console.log("executeDeviceCommand:token:"+ node.token);
return new Promise( (resolve, reject) => {
node.stClient.devices.executeCommands(deviceId, command).then(ret => {
console.log("Execute Command ("+deviceId+"):");
console.log(ret);
resolve(ret);
}).catch( err => {
reject(err);
});
});
};
node.getScenes = function() {
console.log("getScenes:token:"+ node.token);
return new Promise( (resolve, reject) => {
node.stClient.scenes.list().then(ret => {
resolve(ret);
}).catch( err => {
reject(err);
});
});
};
node.executeScene = function(sceneId){
console.log("executeScene:token:"+ node.token);
return new Promise( (resolve, reject) => {
node.stClient.scenes.execute(sceneId).then(ret => {
resolve(ret);
}).catch( err => {
reject(err);
});
});
};
node.getModes = function() {
console.log("getModes:token:"+ node.token);
return new Promise( (resolve, reject) => {
node.stClient.modes.list().then(ret => {
resolve(ret);
}).catch( err => {
reject(err);
});
});
};
RED.httpAdmin.get('/smartthings/' + node.token + '/devices/:type', function(req,res){
console.log("HTTP REQUEST: devices: " + node.token + " : " + req.params.type);
console.log("List Devices By Type: " + req.params.type);
node.getDevices(req.params.type).then(deviceList => {
console.log("Device List:");
console.log(deviceList);
let ret = [];
deviceList.forEach( (device, idx) => {
ret.push({
deviceId: device["deviceId"],
label: device["label"],
});
});
res.status(200).send(ret.sort( (a,b) => { return (a.label < b.label ? -1 : 1) } ));
}).catch( err => {
console.log("NODE ERROR");
console.log(err);
res.status(500).send("ERROR");
});
});
RED.httpAdmin.get('/smartthings/' + node.token+ '/scenes', function(req,res){
console.log("HTTP REQUEST: scenes: " + node.token);
console.log("List Scenes: ");
node.getScenes().then( scenes => {
console.log("scenes:");
console.log(scenes);
let ret = [];
scenes.forEach( (scene, idx) => {
ret.push({
sceneId: scene["sceneId"],
sceneName: scene["sceneName"],
});
});
res.status(200).send(ret.sort( (a,b) => { return (a.sceneName < b.sceneName ? -1 : 1) } ));
}).catch(err => {
console.log("NODE ERROR");
console.log(err);
res.status(500).send("ERROR");
});
});
RED.httpAdmin.get('/smartthings/' + node.token+ '/modes', function(req,res){
console.log("HTTP REQUEST: modes: " + node.token);
console.log("List Modes: ");
node.getModes().then( modes => {
console.log("modes:");
console.log(modes);
let ret = [];
modes.forEach( (mode, idx) => {
ret.push({