mirror of
https://github.com/n8n-io/n8n.git
synced 2024-11-11 07:04:06 -08:00
1c615b615f
* Hue Node: Add Room/Group Name to Light Name To easier identify lights in the dropdown it is useful to know to which group (room) they belong. While lights can be added to multiple zones, they can only ever belong to one room. * ⚡ Small improvemenets to (#1299) Co-authored-by: Robert Kaelin <robertkaelin@users.noreply.github.com>
199 lines
4.8 KiB
TypeScript
199 lines
4.8 KiB
TypeScript
import {
|
|
IExecuteFunctions,
|
|
} from 'n8n-core';
|
|
|
|
import {
|
|
IDataObject,
|
|
ILoadOptionsFunctions,
|
|
INodeExecutionData,
|
|
INodePropertyOptions,
|
|
INodeType,
|
|
INodeTypeDescription,
|
|
} from 'n8n-workflow';
|
|
|
|
import {
|
|
getUser,
|
|
philipsHueApiRequest,
|
|
} from './GenericFunctions';
|
|
|
|
import {
|
|
lightFields,
|
|
lightOperations,
|
|
} from './LightDescription';
|
|
|
|
export class PhilipsHue implements INodeType {
|
|
description: INodeTypeDescription = {
|
|
displayName: 'Philips Hue',
|
|
name: 'philipsHue',
|
|
icon: 'file:philipshue.png',
|
|
group: ['input'],
|
|
version: 1,
|
|
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
|
description: 'Consume Philips Hue API.',
|
|
defaults: {
|
|
name: 'Philips Hue',
|
|
color: '#063c9a',
|
|
},
|
|
inputs: ['main'],
|
|
outputs: ['main'],
|
|
credentials: [
|
|
{
|
|
name: 'philipsHueOAuth2Api',
|
|
required: true,
|
|
},
|
|
],
|
|
properties: [
|
|
{
|
|
displayName: 'Resource',
|
|
name: 'resource',
|
|
type: 'options',
|
|
options: [
|
|
{
|
|
name: 'Light',
|
|
value: 'light',
|
|
},
|
|
],
|
|
default: 'light',
|
|
description: 'The resource to operate on.',
|
|
},
|
|
...lightOperations,
|
|
...lightFields,
|
|
],
|
|
};
|
|
|
|
methods = {
|
|
loadOptions: {
|
|
// Get all the lights to display them to user so that he can
|
|
// select them easily
|
|
async getLights(
|
|
this: ILoadOptionsFunctions,
|
|
): Promise<INodePropertyOptions[]> {
|
|
const returnData: INodePropertyOptions[] = [];
|
|
|
|
const user = await getUser.call(this);
|
|
|
|
const lights = await philipsHueApiRequest.call(
|
|
this,
|
|
'GET',
|
|
`/bridge/${user}/lights`,
|
|
);
|
|
|
|
const groups = await philipsHueApiRequest.call(
|
|
this,
|
|
'GET',
|
|
`/bridge/${user}/groups`,
|
|
);
|
|
|
|
for (const light of Object.keys(lights)) {
|
|
let lightName = lights[light].name;
|
|
const lightId = light;
|
|
|
|
for (const groupId of Object.keys(groups)) {
|
|
if(groups[groupId].type === 'Room' && groups[groupId].lights.includes(lightId)) {
|
|
lightName = `${groups[groupId].name}: ${lightName}`;
|
|
}
|
|
}
|
|
|
|
returnData.push({
|
|
name: lightName,
|
|
value: lightId,
|
|
});
|
|
}
|
|
return returnData;
|
|
},
|
|
},
|
|
};
|
|
|
|
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
|
const items = this.getInputData();
|
|
const returnData: IDataObject[] = [];
|
|
const length = (items.length as unknown) as number;
|
|
const qs: IDataObject = {};
|
|
let responseData;
|
|
const resource = this.getNodeParameter('resource', 0) as string;
|
|
const operation = this.getNodeParameter('operation', 0) as string;
|
|
for (let i = 0; i < length; i++) {
|
|
if (resource === 'light') {
|
|
if (operation === 'update') {
|
|
|
|
const lightId = this.getNodeParameter('lightId', i) as string;
|
|
|
|
const on = this.getNodeParameter('on', i) as boolean;
|
|
|
|
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
|
|
|
|
const body = {
|
|
on,
|
|
};
|
|
|
|
if (additionalFields.transitiontime) {
|
|
additionalFields.transitiontime = (additionalFields.transitiontime as number * 100);
|
|
}
|
|
|
|
if (additionalFields.xy) {
|
|
additionalFields.xy = (additionalFields.xy as string).split(',').map((e: string) => parseFloat(e));
|
|
}
|
|
|
|
if (additionalFields.xy_inc) {
|
|
additionalFields.xy_inc = (additionalFields.xy_inc as string).split(',').map((e: string) => parseFloat(e));
|
|
}
|
|
|
|
Object.assign(body, additionalFields);
|
|
|
|
const user = await getUser.call(this);
|
|
|
|
const data = await philipsHueApiRequest.call(
|
|
this,
|
|
'PUT',
|
|
`/bridge/${user}/lights/${lightId}/state`,
|
|
body,
|
|
);
|
|
|
|
responseData = {};
|
|
|
|
for (const response of data) {
|
|
Object.assign(responseData, response.success);
|
|
}
|
|
|
|
}
|
|
if (operation === 'delete') {
|
|
|
|
const lightId = this.getNodeParameter('lightId', i) as string;
|
|
|
|
const user = await getUser.call(this);
|
|
|
|
responseData = await philipsHueApiRequest.call(this, 'DELETE', `/bridge/${user}/lights/${lightId}`);
|
|
|
|
}
|
|
if (operation === 'getAll') {
|
|
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
|
|
|
|
const user = await getUser.call(this);
|
|
|
|
const lights = await philipsHueApiRequest.call(this, 'GET', `/bridge/${user}/lights`);
|
|
|
|
responseData = Object.values(lights);
|
|
|
|
if (!returnAll) {
|
|
const limit = this.getNodeParameter('limit', i) as number;
|
|
responseData = responseData.splice(0, limit);
|
|
}
|
|
}
|
|
if (operation === 'get') {
|
|
const lightId = this.getNodeParameter('lightId', i) as string;
|
|
|
|
const user = await getUser.call(this);
|
|
|
|
responseData = await philipsHueApiRequest.call(this, 'GET', `/bridge/${user}/lights/${lightId}`);
|
|
}
|
|
}
|
|
}
|
|
if (Array.isArray(responseData)) {
|
|
returnData.push.apply(returnData, responseData as IDataObject[]);
|
|
} else if (responseData !== undefined) {
|
|
returnData.push(responseData as IDataObject);
|
|
}
|
|
return [this.helpers.returnJsonArray(returnData)];
|
|
}
|
|
}
|