Skip to content

Commit b4d86c6

Browse files
committed
new components
1 parent 759d1f6 commit b4d86c6

File tree

6 files changed

+345
-7
lines changed

6 files changed

+345
-7
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import tuya from "../../tuya.app.mjs";
2+
3+
export default {
4+
key: "tuya-list-devices",
5+
name: "List Devices",
6+
description: "Get a list of devices associated with a home. [See the documentation](https://developer.tuya.com/en/docs/cloud/d7ee73aadb?id=Kawfjer0wkt2a)",
7+
version: "0.0.1",
8+
type: "action",
9+
props: {
10+
tuya,
11+
userId: {
12+
propDefinition: [
13+
tuya,
14+
"userId",
15+
],
16+
},
17+
homeId: {
18+
propDefinition: [
19+
tuya,
20+
"homeId",
21+
(c) => ({
22+
userId: c.userId,
23+
}),
24+
],
25+
optional: true,
26+
},
27+
},
28+
async run({ $ }) {
29+
const response = this.homeId
30+
? await this.tuya.listHomeDevices({
31+
homeId: this.homeId,
32+
})
33+
: await this.tuya.listUserDevices({
34+
userId: this.userId,
35+
});
36+
if (response?.result?.length) {
37+
$.export("$summary", `Found ${response.result.length} device${response.result.length === 1
38+
? ""
39+
: "s"}`);
40+
}
41+
return response;
42+
},
43+
};
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import tuya from "../../tuya.app.mjs";
2+
3+
export default {
4+
key: "tuya-list-homes",
5+
name: "List Homes",
6+
description: "Based on the user ID, query the list of homes where the specified user belongs. [See the documentation](https://developer.tuya.com/en/docs/cloud/f5dd40ed14?id=Kawfjh9hpov1n)",
7+
version: "0.0.1",
8+
type: "action",
9+
props: {
10+
tuya,
11+
userId: {
12+
propDefinition: [
13+
tuya,
14+
"userId",
15+
],
16+
},
17+
},
18+
async run({ $ }) {
19+
const response = await this.tuya.listHomes({
20+
userId: this.userId,
21+
});
22+
if (response?.result?.length) {
23+
$.export("$summary", `Found ${response.result.length} home${response.result.length === 1
24+
? ""
25+
: "s"}`);
26+
}
27+
return response;
28+
},
29+
};
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import tuya from "../../tuya.app.mjs";
2+
3+
export default {
4+
key: "tuya-send-instructions-to-device",
5+
name: "Send Instructions to Device",
6+
description: "Send an instruction to the specified device. [See the documentation](https://developer.tuya.com/en/docs/cloud/device-control?id=K95zu01ksols7#title-35-Send%20instructions%20to%20the%20device)",
7+
version: "0.0.1",
8+
type: "action",
9+
props: {
10+
tuya,
11+
userId: {
12+
propDefinition: [
13+
tuya,
14+
"userId",
15+
],
16+
},
17+
homeId: {
18+
propDefinition: [
19+
tuya,
20+
"homeId",
21+
(c) => ({
22+
userId: c.userId,
23+
}),
24+
],
25+
optional: true,
26+
},
27+
deviceId: {
28+
propDefinition: [
29+
tuya,
30+
"deviceId",
31+
(c) => ({
32+
userId: c.userId,
33+
homeId: c.homeId,
34+
}),
35+
],
36+
},
37+
instructionCode: {
38+
propDefinition: [
39+
tuya,
40+
"instructionCode",
41+
(c) => ({
42+
deviceId: c.deviceId,
43+
}),
44+
],
45+
},
46+
value: {
47+
type: "string",
48+
label: "Value",
49+
description: "The value to set",
50+
},
51+
},
52+
async run({ $ }) {
53+
const response = await this.tuya.sendInstructionsToDevice({
54+
deviceId: this.deviceId,
55+
data: {
56+
commands: [
57+
{
58+
code: this.instructionCode,
59+
value: this.value,
60+
},
61+
],
62+
},
63+
});
64+
if (response.success) {
65+
$.export("$summary", "Successfully sent instructions to device");
66+
}
67+
return response;
68+
},
69+
};

components/tuya/package.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pipedream/tuya",
3-
"version": "0.0.1",
3+
"version": "0.1.0",
44
"description": "Pipedream Tuya Components",
55
"main": "tuya.app.mjs",
66
"keywords": [
@@ -11,5 +11,9 @@
1111
"author": "Pipedream <support@pipedream.com> (https://pipedream.com/)",
1212
"publishConfig": {
1313
"access": "public"
14+
},
15+
"dependencies": {
16+
"@pipedream/platform": "^3.0.3",
17+
"@tuya/tuya-connector-nodejs": "^2.1.2"
1418
}
15-
}
19+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import tuya from "../../tuya.app.mjs";
2+
import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform";
3+
4+
export default {
5+
key: "tuya-new-device-activated",
6+
name: "New Device Activated",
7+
description: "Emit new event when a device is activated. [See the documentation](https://developer.tuya.com/en/docs/cloud/device-management?id=K9g6rfntdz78a#title-10-Get%20a%20list%20of%20devices%20under%20a%20specified%20user)",
8+
version: "0.0.1",
9+
type: "source",
10+
dedupe: "unique",
11+
props: {
12+
tuya,
13+
db: "$.service.db",
14+
timer: {
15+
type: "$.interface.timer",
16+
default: {
17+
intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL,
18+
},
19+
},
20+
userId: {
21+
propDefinition: [
22+
tuya,
23+
"userId",
24+
],
25+
},
26+
homeId: {
27+
propDefinition: [
28+
tuya,
29+
"homeId",
30+
(c) => ({
31+
userId: c.userId,
32+
}),
33+
],
34+
optional: true,
35+
},
36+
},
37+
methods: {
38+
_getLastTs() {
39+
return this.db.get("lastTs") || 0;
40+
},
41+
_setLastTs(lastTs) {
42+
this.db.set("lastTs", lastTs);
43+
},
44+
generateMeta(item) {
45+
return {
46+
id: `${item.id}${item.active_time}`,
47+
summary: `Device Activated with ID: ${item.id}`,
48+
ts: item.active_time,
49+
};
50+
},
51+
},
52+
async run() {
53+
const lastTs = this._getLastTs();
54+
let maxTs = lastTs;
55+
56+
const { result: devices } = this.homeId
57+
? await this.tuya.listHomeDevices({
58+
homeId: this.homeId,
59+
})
60+
: await this.tuya.listUserDevices({
61+
userId: this.userId,
62+
});
63+
64+
for (const device of devices) {
65+
if (device.active_time >= lastTs) {
66+
const meta = this.generateMeta(device);
67+
this.$emit(device, meta);
68+
maxTs = Math.max(device.active_time, maxTs);
69+
}
70+
}
71+
72+
this._setLastTs(maxTs);
73+
},
74+
};

components/tuya/tuya.app.mjs

Lines changed: 124 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,130 @@
1+
import { TuyaContext } from "@tuya/tuya-connector-nodejs";
2+
import { ConfigurationError } from "@pipedream/platform";
3+
14
export default {
25
type: "app",
36
app: "tuya",
4-
propDefinitions: {},
7+
propDefinitions: {
8+
userId: {
9+
type: "string",
10+
label: "User ID",
11+
description: "The identifier of a user",
12+
async options() {
13+
const { result: { list } } = await this.listUsers();
14+
return list?.map(({
15+
user_id: value, user_name: label,
16+
}) => ({
17+
label,
18+
value,
19+
})) || [];
20+
},
21+
},
22+
homeId: {
23+
type: "string",
24+
label: "Home ID",
25+
description: "The identifier of a home",
26+
async options({ userId }) {
27+
const { result } = await this.listHomes({
28+
userId,
29+
});
30+
return result?.map(({
31+
home_id: value, name: label,
32+
}) => ({
33+
label,
34+
value,
35+
})) || [];
36+
},
37+
},
38+
deviceId: {
39+
type: "string",
40+
label: "Device ID",
41+
description: "The identifier of a device",
42+
async options({
43+
userId, homeId,
44+
}) {
45+
const { result } = homeId
46+
? await this.listHomeDevices({
47+
homeId,
48+
})
49+
: await this.listUserDevices({
50+
userId,
51+
});
52+
return result?.map(({
53+
id: value, name: label,
54+
}) => ({
55+
label,
56+
value,
57+
})) || [];
58+
},
59+
},
60+
instructionCode: {
61+
type: "string",
62+
label: "Instruction Code",
63+
description: "The code of the command to use",
64+
async options({ deviceId }) {
65+
const { result } = await this.listDeviceFunctions({
66+
deviceId,
67+
});
68+
return result?.functions?.map(({
69+
code: value, name: label,
70+
}) => ({
71+
label,
72+
value,
73+
})) || [];
74+
},
75+
},
76+
},
577
methods: {
6-
// this.$auth contains connected account data
7-
authKeys() {
8-
console.log(Object.keys(this.$auth));
78+
_getClient() {
79+
return new TuyaContext({
80+
baseUrl: this.$auth.base_url,
81+
accessKey: this.$auth.client_id,
82+
secretKey: this.$auth.client_secret,
83+
});
84+
},
85+
async _makeRequest({
86+
method = "GET",
87+
path,
88+
data = {},
89+
}) {
90+
const response = await this._getClient().request({
91+
method,
92+
path,
93+
body: data,
94+
});
95+
if (!response.success) {
96+
console.log(response);
97+
throw new ConfigurationError(`${response.msg}`);
98+
}
99+
},
100+
listUsers() {
101+
return this._getClient().user.users({});
102+
},
103+
listHomes({ userId }) {
104+
return this._makeRequest({
105+
path: `/v1.0/users/${userId}/homes`,
106+
});
107+
},
108+
listUserDevices({ userId }) {
109+
return this._makeRequest({
110+
path: `/v1.0/users/${userId}/devices`,
111+
});
112+
},
113+
listHomeDevices({ homeId }) {
114+
return this._makeRequest({
115+
path: `/v1.0/homes/${homeId}/devices`,
116+
});
117+
},
118+
listDeviceFunctions({ deviceId }) {
119+
return this._makeRequest({
120+
path: `/v1.0/devices/${deviceId}/functions`,
121+
});
122+
},
123+
sendInstructionsToDevice({ deviceId }) {
124+
return this._makeRequest({
125+
method: "POST",
126+
path: `/v1.0/devices/${deviceId}/commands`,
127+
});
9128
},
10129
},
11-
};
130+
};

0 commit comments

Comments
 (0)