n8n-nodes-hubitat
Version:
n8n nodes to integrate with Hubitat smart home platform
353 lines • 15.5 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Hubitat = void 0;
const axios_1 = __importDefault(require("axios"));
class Hubitat {
constructor() {
this.description = {
displayName: 'Hubitat',
name: 'hubitat',
icon: 'file:hubitat.svg',
group: ['transform'],
version: 1,
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
description: 'Interact with Hubitat devices',
defaults: {
name: 'Hubitat',
color: '#39ac8d',
},
usableAsTool: true,
inputs: [
{
type: "main",
displayName: 'Input',
},
],
outputs: [
{
type: "main",
displayName: 'Output',
},
],
credentials: [
{
name: 'hubitatApi',
required: true,
},
],
properties: [
{
displayName: 'Resource',
name: 'resource',
type: 'options',
noDataExpression: true,
options: [
{
name: 'Device',
value: 'device',
},
],
default: 'device',
},
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: [
'device',
],
},
},
options: [
{
name: 'Get All',
value: 'getAll',
description: 'Get all devices',
action: 'Get all devices',
},
{
name: 'Get',
value: 'get',
description: 'Get a device',
action: 'Get a device',
},
{
name: 'Get Attribute',
value: 'getAttribute',
description: 'Get a specific device attribute',
action: 'Get a device attribute',
},
{
name: 'Send Command',
value: 'sendCommand',
description: 'Send command to a device',
action: 'Send command to a device',
},
],
default: 'getAll',
},
{
displayName: 'Device',
name: 'deviceId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'loadDeviceOptions'
},
displayOptions: {
show: {
resource: [
'device',
],
operation: [
'get',
'sendCommand',
'getAttribute',
],
},
},
default: '',
required: true,
description: 'Select a device',
},
{
displayName: 'Attribute',
name: 'attribute',
type: 'options',
typeOptions: {
loadOptionsMethod: 'loadAttributeOptions',
loadOptionsDependsOn: ['deviceId'],
},
required: true,
default: '',
displayOptions: {
show: {
resource: [
'device',
],
operation: [
'getAttribute',
],
},
},
description: 'The attribute to retrieve from the device',
},
{
displayName: 'Command',
name: 'command',
type: 'options',
typeOptions: {
loadOptionsMethod: 'loadCommandOptions',
loadOptionsDependsOn: ['deviceId']
},
required: true,
default: '',
displayOptions: {
show: {
resource: [
'device',
],
operation: [
'sendCommand',
],
},
},
description: 'Select a command to send to the device',
},
{
displayName: 'Arguments',
name: 'arguments',
type: 'string',
default: '',
displayOptions: {
show: {
resource: [
'device',
],
operation: [
'sendCommand',
],
},
},
description: 'Command arguments separated by commas',
},
],
};
this.methods = {
loadOptions: {
async loadDeviceOptions() {
const credentials = await this.getCredentials('hubitatApi');
const authToken = credentials.accessToken;
const baseUrl = credentials.hubitatHost;
const appId = credentials.appId;
const query = this.getCurrentNodeParameter('query');
try {
const url = `${baseUrl}/apps/api/${appId}/devices/all?access_token=${authToken}`;
const response = await axios_1.default.get(url, { headers: { Accept: 'application/json' } });
const data = response.data;
let devices = data;
if (query) {
const lowerCaseQuery = query.toLowerCase();
devices = devices.filter((device) => device.name.toLowerCase().includes(lowerCaseQuery) ||
(device.label && device.label.toLowerCase().includes(lowerCaseQuery)));
}
return devices.map((device) => ({
name: device.label || device.name,
value: device.id.toString(),
description: `Type: ${device.type}`,
}));
}
catch (error) {
console.error('Error retrieving devices from Hubitat:', error);
throw new Error(`Unable to load devices: ${error instanceof Error ? error.message : String(error)}`);
}
},
async loadAttributeOptions() {
const credentials = await this.getCredentials('hubitatApi');
const authToken = credentials.accessToken;
const baseUrl = credentials.hubitatHost;
const appId = credentials.appId;
const deviceId = this.getCurrentNodeParameter('deviceId');
if (!deviceId) {
return [{ name: 'Please select a device first', value: '' }];
}
try {
const url = `${baseUrl}/apps/api/${appId}/devices/${deviceId}?access_token=${authToken}`;
const response = await axios_1.default.get(url, { headers: { Accept: 'application/json' } });
const data = response.data;
if (!data || !data.attributes) {
throw new Error('Device attributes not found in the response');
}
return data.attributes.map((attribute) => ({
name: attribute.name,
value: attribute.name,
description: `Current value: ${attribute.currentValue}${attribute.dataType ? ` (${attribute.dataType})` : ''}`,
}));
}
catch (error) {
console.error('Error retrieving attributes from Hubitat:', error);
throw new Error(`Unable to load attributes: ${error instanceof Error ? error.message : String(error)}`);
}
},
async loadCommandOptions() {
const credentials = await this.getCredentials('hubitatApi');
const authToken = credentials.accessToken;
const baseUrl = credentials.hubitatHost;
const appId = credentials.appId;
const deviceId = this.getCurrentNodeParameter('deviceId');
if (!deviceId) {
return [{ name: 'Please select a device first', value: '' }];
}
try {
const url = `${baseUrl}/apps/api/${appId}/devices/${deviceId}/commands?access_token=${authToken}`;
const response = await axios_1.default.get(url, { headers: { Accept: 'application/json' } });
const data = response.data;
if (!Array.isArray(data)) {
throw new Error('Invalid response format from Hubitat API');
}
return data.map((command) => ({
name: command.command,
value: command.command,
description: command.parameters && command.parameters.length > 0
? `Parameters: ${command.parameters.join(', ')}`
: 'No parameters'
}));
}
catch (error) {
console.error('Error retrieving commands from Hubitat:', error);
throw new Error(`Unable to load commands: ${error instanceof Error ? error.message : String(error)}`);
}
}
},
};
}
async execute() {
const items = this.getInputData();
const returnData = [];
const credentials = await this.getCredentials('hubitatApi');
const baseUrl = credentials.hubitatHost;
const appId = credentials.appId;
const token = credentials.accessToken;
const makerApiUrl = `${baseUrl}/apps/api/${appId}`;
for (let i = 0; i < items.length; i++) {
const resource = this.getNodeParameter('resource', i);
const operation = this.getNodeParameter('operation', i);
try {
if (resource === 'device') {
if (operation === 'getAll') {
const response = await axios_1.default.get(`${makerApiUrl}/devices/all?access_token=${token}`);
returnData.push({
json: response.data,
pairedItem: {
item: i,
},
});
}
else if (operation === 'get') {
const deviceId = this.getNodeParameter('deviceId', i);
const response = await axios_1.default.get(`${makerApiUrl}/devices/${deviceId}?access_token=${token}`);
returnData.push({
json: response.data,
pairedItem: {
item: i,
},
});
}
else if (operation === 'getAttribute') {
const deviceId = this.getNodeParameter('deviceId', i);
const attribute = this.getNodeParameter('attribute', i);
const url = `${makerApiUrl}/devices/${deviceId}/attribute/${attribute}?access_token=${token}`;
const response = await axios_1.default.get(url);
returnData.push({
json: response.data,
pairedItem: {
item: i,
},
});
}
else if (operation === 'sendCommand') {
const deviceId = this.getNodeParameter('deviceId', i);
const command = this.getNodeParameter('command', i);
const argString = this.getNodeParameter('arguments', i);
let url = `${makerApiUrl}/devices/${deviceId}/${command}?access_token=${token}`;
if (argString) {
const args = argString.split(',').map(arg => arg.trim());
args.forEach(arg => {
url += `&${arg}`;
});
}
const response = await axios_1.default.get(url);
returnData.push({
json: response.data,
pairedItem: {
item: i,
},
});
}
}
}
catch (error) {
if (this.continueOnFail()) {
returnData.push({
json: {
error: error.message,
},
pairedItem: {
item: i,
},
});
continue;
}
throw error;
}
}
return [returnData];
}
}
exports.Hubitat = Hubitat;
//# sourceMappingURL=Hubitat.node.js.map