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;
},
};