-
Notifications
You must be signed in to change notification settings - Fork 1
/
app.ts
144 lines (125 loc) · 5.73 KB
/
app.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import Homey from 'homey';
import { Yandex } from './library';
import { YandexIotSpeaker, YandexIotUpdater } from './library/client/iot';
module.exports = class YandexApp extends Homey.App {
yandex!: Yandex;
updater!: YandexIotUpdater;
#scenarioIcons!: string[];
#scenarioIcon!: string;
async onInit() {
this.yandex = new Yandex({
get: async () => JSON.parse(this.homey.settings.get('storage') ?? '{}'),
set: async content => this.homey.settings.set('storage', JSON.stringify(content))
});
this.updater = this.yandex.iot.updater;
await this.initFlows();
// Обновление куки
setInterval(async () => await this.yandex.request('https://ya.ru').catch(this.error), 2.16e+7);
}
async initFlows() {
// Flow-действие > Произнести текст
const mediaSayAction = this.homey.flow.getActionCard('media_say');
mediaSayAction.registerRunListener(async args => {
const speaker: YandexIotSpeaker = await args.device.getSpeaker();
await speaker.actionSay(args.text, args.volume);
});
// Flow-действие > Выполнить команду
const mediaRunAction = this.homey.flow.getActionCard('media_run');
mediaRunAction.registerRunListener(async args => {
const speaker: YandexIotSpeaker = await args.device.getSpeaker();
await speaker.actionRun(args.command, args.volume);
});
// Flow-триггер > Сценарий запущен
const scenarioTrigger = this.homey.flow.getTriggerCard('scenario_run');
scenarioTrigger.registerRunListener(async (args, state) => args.scenario.name === state.trigger);
scenarioTrigger.registerArgumentAutocompleteListener('scenario', async (query, args) => {
const scenarios = await this.updater.getScenarios();
const names = scenarios.map(scenario => scenario.trigger);
const items = [];
// Обновление иконки для нового сценария
if (query === '') this.#scenarioIcon = await this.#getScenarioIcon();
// Отображение нового сценария
if (query !== '' && !names.includes(query)) {
items.push({
name: query,
description: 'Нажмите для создания',
image: `https://avatars.mds.yandex.net/get-iot/icons-scenarios-${this.#scenarioIcon}.svg/svgorig`
});
}
// Отображение сценариев
scenarios.map(scenario => {
if (scenario.trigger.toLowerCase().includes(query.toLowerCase())) {
items.push({
name: scenario.trigger,
description: 'Нажмите для выбора',
image: scenario.icon
});
}
});
return items;
});
scenarioTrigger.on('update', async () => {
const flowArgs = await scenarioTrigger.getArgumentValues();
const promises = flowArgs.map(({ scenario }) => this.#createScenario(scenario.name, scenario.image));
await Promise.all(promises).catch(this.error);
});
this.updater.events.on('scenario_run', async scenario => {
await scenarioTrigger.trigger(undefined, scenario);
});
}
async #getScenarioIcon() {
if (this.#scenarioIcons === undefined) {
const scenarioIcons = await this.yandex.api.iot.getScenarioIcons();
this.#scenarioIcons = scenarioIcons.icons;
}
const index = Math.floor(Math.random() * this.#scenarioIcons.length);
return this.#scenarioIcons[index];
}
async #createScenario(trigger: string, iconUrl: string) {
const icon = iconUrl
.replace('https://avatars.mds.yandex.net/get-iot/icons-scenarios-', '')
.replace('.svg/svgorig', '');
const scenarios = await this.updater.getScenarios();
const scenario = await this.updater.getScenarioByTrigger(trigger);
if (scenario) return;
const scenarioActions = scenarios
.filter(scenario => scenario.action.value.startsWith('громче на 0!'))
.map(scenario => scenario.action.value.replace('громче на 0', '').length);
return await this.yandex.api.iot.createScenario({
name: trigger, icon,
triggers: [{
trigger: {
type: 'scenario.trigger.voice',
value: trigger
},
filters: []
}],
steps: [{
type: 'scenarios.steps.actions',
parameters: {
requested_speaker_capabilities: [{
retrievable: false,
type: 'devices.capabilities.quasar.server_action',
state: {
instance: 'text_action',
value: 'громче на 0' + '!'.repeat(this.#getNextNumber(scenarioActions))
},
parameters: {
instance: 'text_action'
}
}],
launch_devices: []
}
}],
settings: {
continue_execution_after_error: false
}
});
}
#getNextNumber(nums: number[]) {
nums = nums.sort();
for (let n = 1; n <= nums.length + 1; n++)
if (nums.indexOf(n) === -1) return n;
return 1;
};
}