2
This commit is contained in:
@@ -1,38 +1,169 @@
|
||||
# esp32-ir
|
||||
|
||||
ИК приёмник/передатчик на ESP32-C6, управляемый локально через REPL или удалённо по HTTP API.
|
||||
|
||||
- **Приёмник** — GPIO20
|
||||
- **Передатчик** — GPIO19
|
||||
|
||||
### воспроизвести сигнал по имени
|
||||
```
|
||||
## Файлы
|
||||
|
||||
| Файл | Назначение |
|
||||
| ---------------- | ------------------------------------------------------------------- |
|
||||
| `capture.py` | захват ИК-сигнала с приёмника |
|
||||
| `transmit.py` | воспроизведение сохранённого сигнала через ИК-светодиод (PWM 38кГц) |
|
||||
| `wifi_server.py` | HTTP-сервер для удалённого управления |
|
||||
| `.env` | секреты (WiFi, API-ключ) — см. ниже |
|
||||
| `main.py` | автозапуск сервера при включении платы |
|
||||
| `dotenv.py` | самописный экземпляр для получения переменных окружения |
|
||||
|
||||
---
|
||||
|
||||
## Локальное использование (через REPL)
|
||||
|
||||
### Воспроизвести сигнал по имени
|
||||
```python
|
||||
from transmit import send_code
|
||||
send_code("power")
|
||||
```
|
||||
|
||||
### сделать новую запись
|
||||
```
|
||||
from capture import capture_raw
|
||||
### Сделать новую запись
|
||||
```python
|
||||
from capture import capture_raw, save_code
|
||||
data = capture_raw()
|
||||
save_code("name", data)
|
||||
```
|
||||
|
||||
### посмотреть записи
|
||||
```
|
||||
### Посмотреть записи
|
||||
```python
|
||||
from capture import list_codes
|
||||
list_codes()
|
||||
```
|
||||
|
||||
### Удалить старые файлы/коды
|
||||
```python
|
||||
import os
|
||||
os.remove("test.py") # удалить конкретный файл
|
||||
|
||||
### start server by hands
|
||||
import json
|
||||
with open("codes.json", "w") as f:
|
||||
json.dump({}, f) # очистить все коды
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## HTTP API
|
||||
|
||||
### Запуск сервера вручную
|
||||
```python
|
||||
import wifi_server
|
||||
wifi_server.main()
|
||||
```
|
||||
При старте сервер подключается к WiFi (данные из `.env`) и выводит в консоль свой IP:
|
||||
```
|
||||
WiFi подключен. IP адрес: 192.168.1.123
|
||||
Сервер запущен: http://192.168.1.123/
|
||||
```
|
||||
|
||||
### Автозапуск
|
||||
Сервер поднимается автоматически при каждом включении/перезагрузке платы через `main.py`:
|
||||
```python
|
||||
import wifi_server
|
||||
wifi_server.main()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Конфигурация (`.env`)
|
||||
|
||||
#### пример запущенного сервера
|
||||
Сервер запущен: `http://192.168.1.22/`
|
||||
```
|
||||
WIFI_SSID=ИмяСети
|
||||
WIFI_PASSWORD=Пароль
|
||||
API_KEY=длинный_секретный_ключ
|
||||
```
|
||||
|
||||
Записанные команды: `http://192.168.1.22/list`
|
||||
Если `API_KEY` не задан — сервер работает **без авторизации** (только для локальных тестов).
|
||||
|
||||
Исполнение команды: `http://192.168.1.22/send?code=power`
|
||||
---
|
||||
|
||||
### Авторизация
|
||||
|
||||
Все эндпоинты, кроме `/`, требуют ключ из `API_KEY`. Передавайте его любым из двух способов:
|
||||
|
||||
**Query-параметр:**
|
||||
```
|
||||
?key=длинный_секретный_ключ
|
||||
```
|
||||
|
||||
**Заголовок:**
|
||||
```
|
||||
X-API-Key: длинный_секретный_ключ
|
||||
```
|
||||
|
||||
Без ключа или с неверным — ответ `401 Unauthorized`.
|
||||
|
||||
---
|
||||
|
||||
### Эндпоинты
|
||||
|
||||
| Метод | Путь | Описание |
|
||||
| ----- | ---------------------------------- | --------------------------------------------------------------------------- |
|
||||
| `GET` | `/` | статус сервера, список эндпоинтов (без авторизации) |
|
||||
| `GET` | `/list` | список сохранённых кодов с количеством импульсов |
|
||||
| `GET` | `/send?code=ИМЯ` | воспроизвести сохранённый код |
|
||||
| `GET` | `/record?code=ИМЯ&timeout_ms=5000` | записать новый код (наведите пульт и нажмите кнопку в течение `timeout_ms`) |
|
||||
| `GET` | `/delete?code=ИМЯ` | удалить сохранённый код |
|
||||
|
||||
---
|
||||
|
||||
### Примеры использования
|
||||
|
||||
**Проверить, что сервер жив:**
|
||||
```bash
|
||||
curl http://192.168.1.123/
|
||||
```
|
||||
|
||||
**Посмотреть список записанных команд:**
|
||||
```bash
|
||||
curl "http://192.168.1.123/list?key=длинный_секретный_ключ"
|
||||
```
|
||||
```json
|
||||
{"codes": {"power": 67, "tv_power": 23, "light_toggle": 67}}
|
||||
```
|
||||
|
||||
**Воспроизвести команду:**
|
||||
```bash
|
||||
curl "http://192.168.1.123/send?code=power&key=длинный_секретный_ключ"
|
||||
```
|
||||
```json
|
||||
{"status": "ok", "sent": "power"}
|
||||
```
|
||||
|
||||
**Записать новую команду** (после запроса наведите пульт на приёмник и нажмите кнопку):
|
||||
```bash
|
||||
curl "http://192.168.1.123/record?code=fan_speed1&key=длинный_секретный_ключ"
|
||||
```
|
||||
```json
|
||||
{"status": "ok", "saved": "fan_speed1", "pulses": 67}
|
||||
```
|
||||
Если сигнал не поймали за отведённое время — `408 Request Timeout`.
|
||||
|
||||
**Удалить команду:**
|
||||
```bash
|
||||
curl "http://192.168.1.123/delete?code=fan_speed1&key=длинный_секретный_ключ"
|
||||
```
|
||||
```json
|
||||
{"status": "ok", "deleted": "fan_speed1"}
|
||||
```
|
||||
|
||||
**С заголовком вместо query-параметра:**
|
||||
```bash
|
||||
curl -H "X-API-Key: длинный_секретный_ключ" "http://192.168.1.123/send?code=power"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Заметки
|
||||
|
||||
- Сервер однопоточный: во время `/record` (ожидание сигнала с пульта) остальные запросы не обрабатываются.
|
||||
- Трафик идёт по обычному HTTP без шифрования — ключ защищает от случайных запросов в локальной сети, но не является криптостойкой защитой.
|
||||
- IP адрес платы может меняться при переподключении к роутеру — для стабильности рекомендуется закрепить IP за MAC-адресом в настройках роутера (DHCP reservation).
|
||||
Reference in New Issue
Block a user