Skip to content
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
174 changes: 174 additions & 0 deletions components/govee/actions/control-device/control-device.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
import { v4 as uuid } from "uuid";
import app from "../../govee.app.mjs";

export default {
key: "govee-control-device",
name: "Control Device",
description: "Send a command to control a Govee device, such as turning it on/off, changing its brightness, or adjusting its color. [See the documentation](https://developer.govee.com/reference/control-you-devices).",
version: "0.0.1",
type: "action",
props: {
app,
deviceId: {
propDefinition: [
app,
"deviceId",
],
},
commandType: {
reloadProps: true,
propDefinition: [
app,
"commandType",
({ deviceId }) => ({
deviceId,
}),
],
},
},
async additionalProps() {
const {
deviceId,
commandType,
} = this;

const { data: devices } = await this.app.listDevices();
const device = devices.find(({ device }) => device === deviceId);
const capability = device?.capabilities?.find(({ type }) => type === commandType);
const { parameters } = capability ?? {};

if (parameters.dataType === "ENUM") {
return {
value: {
type: "string",
label: "Value",
description: "The value of the command.",
options: parameters?.options.map(({
name: label,
value,
}) => ({
label,
value: String(value),
})),
},
};
}

if (parameters.dataType === "INTEGER") {
return {
value: {
type: "integer",
label: "Value",
description: `The value of the command. Min value: \`${parameters.range.min}\`, Max value: \`${parameters.range.max}\`.`,
min: parameters.range.min,
max: parameters.range.max,
},
};
}

if (parameters.dataType === "STRUCT") {
return parameters.fields.reduce((acc, {
fieldName,
dataType,
range,
required,
options,
}) => {
if (dataType === "INTEGER") {
acc[fieldName] = {
type: "integer",
label: fieldName,
description: `The value of the ${fieldName} field. Min value: \`${range.min}\`, Max value: \`${range.max}\`.`,
min: range.min,
max: range.max,
optional: !required,
};
} else if (dataType === "ENUM") {
acc[fieldName] = {
type: "string",
label: fieldName,
description: `The value of the ${fieldName} field.`,
optional: !required,
options: options.reduce((acc, {
name: label,
value,
defaultValue,
options: nestedOptions,
}) => {
if (nestedOptions) {
return acc.concat(nestedOptions.map(({
name: label,
value,
}) => ({
label,
value: String(value),
})));
}
return acc.concat({
label,
value: value !== undefined && String(value) || String(defaultValue),
});
}, []),
};
} else if (dataType === "Array") {
acc[fieldName] = {
type: "string[]",
label: fieldName,
description: `The value of the ${fieldName} field.`,
optional: !required,
options: options.map(({ value }) => String(value)),
};
} else {
acc[fieldName] = {
type: "string",
label: fieldName,
description: `The value of the ${fieldName} field.`,
optional: !required,
};
}
return acc;
}, {});
}
},
methods: {
controlDevice(args = {}) {
return this.app.post({
path: "/device/control",
...args,
});
},
},
async run({ $ }) {
const {
app,
controlDevice,
deviceId,
commandType,
value,
...fields
} = this;

const { data: devices } = await app.listDevices();
const device = devices.find(({ device }) => device === deviceId);

const response = await controlDevice({
$,
data: {
requestId: uuid(),
payload: {
sku: device.sku,
device: deviceId,
capability: {
type: commandType,
parameters: {
value: value ?? fields,
},
},
},
},
});

$.export("$summary", "Successfully sent command to device.");
return response;
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { v4 as uuid } from "uuid";
import app from "../../govee.app.mjs";

export default {
key: "govee-retrieve-device-info",
name: "Retrieve Device Info",
description: "Retrieve the current status and metadata of a specific Govee device, such as its power state, color, mode, and health. [See the documentation](https://developer.govee.com/reference/get-devices-status).",
version: "0.0.1",
type: "action",
props: {
app,
deviceId: {
propDefinition: [
app,
"deviceId",
],
},
},
methods: {
getDeviceStatus(args = {}) {
return this.app.post({
path: "/device/state",
...args,
});
},
},
async run({ $ }) {
const {
app,
getDeviceStatus,
deviceId,
} = this;

const { data: devices } = await app.listDevices();
const device = devices.find(({ device }) => device === deviceId);

const response = await getDeviceStatus({
$,
data: {
requestId: uuid(),
payload: {
sku: device.sku,
device: deviceId,
},
},
});
$.export("$summary", "Successfully retrieved device info");
return response;
},
};
7 changes: 7 additions & 0 deletions components/govee/common/constants.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const BASE_URL = "https://openapi.api.govee.com";
const VERSION_PATH = "/router/api/v1";

export default {
BASE_URL,
VERSION_PATH,
};
71 changes: 66 additions & 5 deletions components/govee/govee.app.mjs
Original file line number Diff line number Diff line change
@@ -1,11 +1,72 @@
import { axios } from "@pipedream/platform";
import constants from "./common/constants.mjs";

export default {
type: "app",
app: "govee",
propDefinitions: {},
propDefinitions: {
deviceId: {
type: "string",
label: "Device ID",
description: "The device ID",
async options() {
const { data: devices } = await this.listDevices();
return devices.map(({
device: value,
sku: label,
}) => ({
label,
value,
}));
},
},
commandType: {
type: "string",
label: "Command Type",
description: "The type of command, e.g., power, brightness change, color change.",
async options({ deviceId }) {
const { data: devices } = await this.listDevices();
const device = devices.find(({ device }) => device === deviceId);
return device?.capabilities?.map(({
type: value,
instance: label,
}) => ({
label,
value,
}));
},
},
},
methods: {
// this.$auth contains connected account data
authKeys() {
console.log(Object.keys(this.$auth));
getUrl(path) {
return `${constants.BASE_URL}${constants.VERSION_PATH}${path}`;
},
getHeaders(headers) {
return {
"Content-Type": "application/json",
"Govee-API-Key": this.$auth.api_key,
...headers,
};
},
_makeRequest({
$ = this, path, headers, ...args
} = {}) {
return axios($, {
...args,
url: this.getUrl(path),
headers: this.getHeaders(headers),
});
},
post(args = {}) {
return this._makeRequest({
method: "POST",
...args,
});
},
listDevices() {
return this._makeRequest({
path: "/user/devices",
});
},
},
};
};
6 changes: 5 additions & 1 deletion components/govee/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@pipedream/govee",
"version": "0.0.1",
"version": "0.1.0",
"description": "Pipedream Govee Components",
"main": "govee.app.mjs",
"keywords": [
Expand All @@ -11,5 +11,9 @@
"author": "Pipedream <[email protected]> (https://pipedream.com/)",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@pipedream/platform": "^3.0.3",
"uuid": "^11.1.0"
}
}
15 changes: 10 additions & 5 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading