Update README token guide and refine WB rule behavior
This commit is contained in:
58
README.md
58
README.md
@@ -11,6 +11,7 @@
|
|||||||
- [Быстрый старт](#быстрый-старт)
|
- [Быстрый старт](#быстрый-старт)
|
||||||
- [Полная установка](#полная-установка)
|
- [Полная установка](#полная-установка)
|
||||||
- [Токен](#токен)
|
- [Токен](#токен)
|
||||||
|
- [Как получить токен](#как-получить-токен)
|
||||||
- [CLI](#cli)
|
- [CLI](#cli)
|
||||||
- [Примеры wb-rules](#примеры-wb-rules)
|
- [Примеры wb-rules](#примеры-wb-rules)
|
||||||
- [Прямые Python-команды](#прямые-python-команды)
|
- [Прямые Python-команды](#прямые-python-команды)
|
||||||
@@ -89,9 +90,15 @@ alice/
|
|||||||
## Быстрый старт
|
## Быстрый старт
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /путь/к/распакованному/репозиторию
|
apt update
|
||||||
|
apt install -y git python3 python3-venv python3-pip
|
||||||
|
|
||||||
|
mkdir -p /opt/shd/plugins
|
||||||
|
cd /opt/shd/plugins
|
||||||
|
git clone https://git.xyz.su/shd/local_yandex_station.git alice
|
||||||
|
cd alice
|
||||||
chmod +x *.sh
|
chmod +x *.sh
|
||||||
./install.sh
|
./install.sh --in-place
|
||||||
|
|
||||||
printf %s 'YANDEX_OAUTH_TOKEN' > /opt/shd/plugins/alice/token.txt
|
printf %s 'YANDEX_OAUTH_TOKEN' > /opt/shd/plugins/alice/token.txt
|
||||||
chmod 600 /opt/shd/plugins/alice/token.txt
|
chmod 600 /opt/shd/plugins/alice/token.txt
|
||||||
@@ -100,7 +107,10 @@ cd /opt/shd/plugins/alice
|
|||||||
./cli.sh columns
|
./cli.sh columns
|
||||||
./cli.sh loxone
|
./cli.sh loxone
|
||||||
./cli.sh wb-rules
|
./cli.sh wb-rules
|
||||||
./cli.sh web
|
systemctl enable --now shd-alice.service shd-alice-plugin.service
|
||||||
|
|
||||||
|
curl -sS http://127.0.0.1:9124/health
|
||||||
|
curl -sS http://127.0.0.1:9140/api/status
|
||||||
```
|
```
|
||||||
|
|
||||||
После этого web UI обычно доступен по адресу:
|
После этого web UI обычно доступен по адресу:
|
||||||
@@ -120,17 +130,20 @@ sudo apt install -y python3 python3-venv python3-pip
|
|||||||
|
|
||||||
Для более удобной синхронизации в `/opt` желателен `rsync`, но без него установка тоже работает.
|
Для более удобной синхронизации в `/opt` желателен `rsync`, но без него установка тоже работает.
|
||||||
|
|
||||||
### 2. Распаковать проект и запустить установку
|
### 2. Клонировать проект в рабочий путь и запустить установку
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /путь/к/распакованному/репозиторию
|
mkdir -p /opt/shd/plugins
|
||||||
|
cd /opt/shd/plugins
|
||||||
|
git clone https://git.xyz.su/shd/local_yandex_station.git alice
|
||||||
|
cd alice
|
||||||
chmod +x *.sh
|
chmod +x *.sh
|
||||||
./install.sh
|
./install.sh --in-place
|
||||||
```
|
```
|
||||||
|
|
||||||
Что делает `install.sh`:
|
Что делает `install.sh`:
|
||||||
|
|
||||||
- копирует проект в `/opt/shd/plugins/alice`;
|
- при запуске с `--in-place` работает прямо из `/opt/shd/plugins/alice`;
|
||||||
- создаёт `.venv`, если его нет;
|
- создаёт `.venv`, если его нет;
|
||||||
- ставит зависимости из `requirements.txt`;
|
- ставит зависимости из `requirements.txt`;
|
||||||
- создаёт каталоги `data/`, `configs/loxone/`, `configs/wb-rules/`;
|
- создаёт каталоги `data/`, `configs/loxone/`, `configs/wb-rules/`;
|
||||||
@@ -146,11 +159,12 @@ printf %s 'YANDEX_OAUTH_TOKEN' > /opt/shd/plugins/alice/token.txt
|
|||||||
chmod 600 /opt/shd/plugins/alice/token.txt
|
chmod 600 /opt/shd/plugins/alice/token.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
Или через CLI/web-команду:
|
Разовый запуск через переменную окружения (не для постоянного хранения):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /opt/shd/plugins/alice
|
export YANDEX_TOKEN='YANDEX_OAUTH_TOKEN'
|
||||||
./cli.sh web --token 'YANDEX_OAUTH_TOKEN'
|
./cli.sh columns
|
||||||
|
unset YANDEX_TOKEN
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. Обновить список станций
|
### 4. Обновить список станций
|
||||||
@@ -188,12 +202,32 @@ sudo systemctl enable --now shd-alice.service shd-alice-plugin.service
|
|||||||
/opt/shd/plugins/alice/token.txt
|
/opt/shd/plugins/alice/token.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Рекомендация по безопасности:
|
||||||
|
|
||||||
|
- для постоянной работы храни токен только в `token.txt` с правами `600`;
|
||||||
|
- `YANDEX_TOKEN` используй только временно для разовых команд, затем делай `unset YANDEX_TOKEN`.
|
||||||
|
|
||||||
Если токен неверный, при обновлении списка станций будет ошибка:
|
Если токен неверный, при обновлении списка станций будет ошибка:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
YANDEX_OAUTH_TOKEN invalid: update token and retry
|
YANDEX_OAUTH_TOKEN invalid: update token and retry
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Как получить токен
|
||||||
|
|
||||||
|
Создать собственное OAuth-приложение для этого сценария нельзя. Обычно используют токен,
|
||||||
|
полученный через официальные клиенты Яндекс.Музыки.
|
||||||
|
|
||||||
|
Рабочие варианты:
|
||||||
|
|
||||||
|
- Веб-сервис (может работать не для всех аккаунтов): [music-yandex-bot.ru](https://music-yandex-bot.ru/)
|
||||||
|
- Android-приложение (APK): [MarshalX/yandex-music-token releases](https://github.com/MarshalX/yandex-music-token/releases)
|
||||||
|
- Расширение для Google Chrome: [Yandex Music Token (Chrome Web Store)](https://chrome.google.com/webstore/detail/yandex-music-token/lcbjeookjibfhjjopieifgjnhlegmkib)
|
||||||
|
- Расширение для Mozilla Firefox: [Yandex Music Token (Firefox Add-ons)](https://addons.mozilla.org/en-US/firefox/addon/yandex-music-token/)
|
||||||
|
|
||||||
|
Во всех вариантах выше итог один: получить и скопировать OAuth-токен.
|
||||||
|
Исходный код инструментов открыт: [github.com/MarshalX/yandex-music-token](https://github.com/MarshalX/yandex-music-token).
|
||||||
|
|
||||||
## CLI
|
## CLI
|
||||||
|
|
||||||
Основной интерфейс из терминала — `cli.sh`.
|
Основной интерфейс из терминала — `cli.sh`.
|
||||||
@@ -322,11 +356,11 @@ configs/wb-rules/wb-rules-examples.js
|
|||||||
|
|
||||||
Как привязать к конкретной колонке:
|
Как привязать к конкретной колонке:
|
||||||
|
|
||||||
1. возьми `id` нужной станции из `data/stations.json`;
|
1. возьми IP нужной станции (или `id` из `data/stations.json`);
|
||||||
2. подставь его в строку:
|
2. подставь его в строку:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
var STATION = "PUT_EXACT_STATION_ID_HERE";
|
var STATION = "PUT_STATION_IP_HERE";
|
||||||
```
|
```
|
||||||
|
|
||||||
3. скопируй файл в `/etc/wb-rules/` и перезапусти `wb-rules`.
|
3. скопируй файл в `/etc/wb-rules/` и перезапусти `wb-rules`.
|
||||||
|
|||||||
@@ -479,6 +479,25 @@ function _enc(v) {{
|
|||||||
return encodeURIComponent(String(v === undefined || v === null ? "" : v));
|
return encodeURIComponent(String(v === undefined || v === null ? "" : v));
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
function _clampVolume(v, defVal) {{
|
||||||
|
var n = parseInt(v, 10);
|
||||||
|
if (isNaN(n)) n = defVal;
|
||||||
|
if (isNaN(n)) n = 35;
|
||||||
|
if (n < 0) n = 0;
|
||||||
|
if (n > 100) n = 100;
|
||||||
|
return n;
|
||||||
|
}}
|
||||||
|
|
||||||
|
function _ttsRestoreDelayMs(text) {{
|
||||||
|
var clean = String(text || "").trim();
|
||||||
|
if (!clean) return 3500;
|
||||||
|
var chars = clean.length;
|
||||||
|
var words = clean.split(/\\s+/).filter(Boolean).length;
|
||||||
|
var speechSec = Math.max(words / 2.4, chars / 14.0);
|
||||||
|
var delaySec = Math.max(3.5, Math.min(20.0, speechSec + 1.5));
|
||||||
|
return Math.round(delaySec * 1000);
|
||||||
|
}}
|
||||||
|
|
||||||
defineVirtualDevice(DEVICE_ID, {{
|
defineVirtualDevice(DEVICE_ID, {{
|
||||||
title: DEVICE_TITLE,
|
title: DEVICE_TITLE,
|
||||||
cells: {{
|
cells: {{
|
||||||
@@ -507,7 +526,18 @@ defineRule(DEVICE_ID + "_tts_send", {{
|
|||||||
if (!newValue) return;
|
if (!newValue) return;
|
||||||
var txt = String(dev[DEVICE_ID + "/tts_text"] || "").trim();
|
var txt = String(dev[DEVICE_ID + "/tts_text"] || "").trim();
|
||||||
if (!txt) return;
|
if (!txt) return;
|
||||||
_apiGet("/api/exec?action=tts&station=" + _enc(STATION_SELECTOR) + "&text=" + _enc(txt) + "&volume=35", function(){{}});
|
var targetVolume = _clampVolume(dev[DEVICE_ID + "/volume"], 35);
|
||||||
|
var prevVolumeRaw = dev[DEVICE_ID + "/current_volume"];
|
||||||
|
var prevVolume = _clampVolume(prevVolumeRaw, targetVolume);
|
||||||
|
_apiGet(
|
||||||
|
"/api/exec?action=tts&station=" + _enc(STATION_SELECTOR) + "&text=" + _enc(txt) + "&volume=" + _enc(targetVolume),
|
||||||
|
function(){{}}
|
||||||
|
);
|
||||||
|
if (prevVolume !== targetVolume) {{
|
||||||
|
setTimeout(function() {{
|
||||||
|
_apiGet("/api/exec?action=volume&station=" + _enc(STATION_SELECTOR) + "&level=" + _enc(prevVolume), function(){{}});
|
||||||
|
}}, _ttsRestoreDelayMs(txt));
|
||||||
|
}}
|
||||||
}}
|
}}
|
||||||
}});
|
}});
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
// Примеры wb-rules для ОДНОЙ выбранной станции.
|
// Примеры wb-rules для ОДНОЙ выбранной станции.
|
||||||
//
|
//
|
||||||
// Как использовать:
|
// Как использовать:
|
||||||
// 1) подставь id станции из data/stations.json в переменную STATION;
|
// 1) подставь IP станции (или station_id) в переменную STATION;
|
||||||
// 2) скопируй файл в /etc/wb-rules/;
|
// 2) скопируй файл в /etc/wb-rules/;
|
||||||
// 3) перезапусти сервис wb-rules.
|
// 3) перезапусти сервис wb-rules.
|
||||||
|
|
||||||
var API_BASE = "http://127.0.0.1:9124";
|
var API_BASE = "http://127.0.0.1:9124";
|
||||||
var STATION = "PUT_EXACT_STATION_ID_HERE";
|
var STATION = "PUT_STATION_IP_HERE";
|
||||||
|
|
||||||
function enc(v) {
|
function enc(v) {
|
||||||
return encodeURIComponent(String(v === undefined || v === null ? "" : v));
|
return encodeURIComponent(String(v === undefined || v === null ? "" : v));
|
||||||
|
|||||||
Reference in New Issue
Block a user