wol proxy & wol emulator added.
This commit is contained in:
@@ -12,9 +12,11 @@ SYNOLOGY_VERIFY_SSL=False # Проверка SSL-сертификата
|
|||||||
SYNOLOGY_TIMEOUT=10 # Таймаут для API запросов в секундах
|
SYNOLOGY_TIMEOUT=10 # Таймаут для API запросов в секундах
|
||||||
SYNOLOGY_API_VERSION=1 # Версия API
|
SYNOLOGY_API_VERSION=1 # Версия API
|
||||||
SYNOLOGY_POWER_API=SYNO.Core.System # API для управления питанием
|
SYNOLOGY_POWER_API=SYNO.Core.System # API для управления питанием
|
||||||
|
SYNOLOGY_INFO_API=SYNO.DSM.Info # API для получения информации о DSM
|
||||||
|
MAC_ADDRESS=00:11:22:33:44:55 # MAC-адрес Synology NAS
|
||||||
|
SYNOLOGY_MAC=00:11:22:33:44:55 # Альтернативное имя для MAC-адреса (для обратной совместимости)
|
||||||
|
|
||||||
# WOL (Wake-on-LAN)
|
# WOL (Wake-on-LAN)
|
||||||
MAC_ADDRESS=00:11:22:33:44:55 # MAC-адрес Synology NAS
|
|
||||||
WOL_BROADCAST=255.255.255.255 # Broadcast-адрес для WOL
|
WOL_BROADCAST=255.255.255.255 # Broadcast-адрес для WOL
|
||||||
WOL_PORT=9 # Порт для WOL (обычно 7 или 9)
|
WOL_PORT=9 # Порт для WOL (обычно 7 или 9)
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,6 @@
|
|||||||
FROM python:3.11-slim
|
FROM python:3.11-slim
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY src/wol_proxy.py ./
|
COPY src/wol_proxy.py ./
|
||||||
RUN pip install flask
|
RUN pip install flask python-dotenv
|
||||||
EXPOSE 5000
|
EXPOSE 5002
|
||||||
CMD ["python", "wol_proxy.py"]
|
CMD ["python", "wol_proxy.py"]
|
||||||
|
|||||||
14
deploy.sh
Normal file → Executable file
14
deploy.sh
Normal file → Executable file
@@ -16,8 +16,8 @@ if ! [ -x "$(command -v docker)" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo -e "${YELLOW}Проверка наличия Docker Compose...${NC}"
|
echo -e "${YELLOW}Проверка наличия Docker Compose...${NC}"
|
||||||
if ! [ -x "$(command -v docker-compose)" ] && ! [ -x "$(command -v docker compose)" ]; then
|
if ! docker compose version > /dev/null 2>&1; then
|
||||||
echo -e "${RED}Ошибка: Docker Compose не установлен.${NC}" >&2
|
echo -e "${RED}Ошибка: Docker Compose не установлен или не работает.${NC}" >&2
|
||||||
echo -e "Установите Docker Compose, следуя инструкциям: https://docs.docker.com/compose/install/"
|
echo -e "Установите Docker Compose, следуя инструкциям: https://docs.docker.com/compose/install/"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
@@ -37,13 +37,13 @@ chmod 777 logs
|
|||||||
|
|
||||||
# Сборка и запуск Docker контейнеров
|
# Сборка и запуск Docker контейнеров
|
||||||
echo -e "${YELLOW}Сборка и запуск Docker контейнеров...${NC}"
|
echo -e "${YELLOW}Сборка и запуск Docker контейнеров...${NC}"
|
||||||
docker-compose down
|
docker compose down
|
||||||
docker-compose up -d --build
|
docker compose up -d --build
|
||||||
|
|
||||||
# Проверка статуса контейнеров
|
# Проверка статуса контейнеров
|
||||||
echo -e "${YELLOW}Проверка статуса контейнеров...${NC}"
|
echo -e "${YELLOW}Проверка статуса контейнеров...${NC}"
|
||||||
docker-compose ps
|
docker compose ps
|
||||||
|
|
||||||
echo -e "${GREEN}Развертывание завершено успешно!${NC}"
|
echo -e "${GREEN}Развертывание завершено успешно!${NC}"
|
||||||
echo -e "Для просмотра логов: ${YELLOW}docker-compose logs -f${NC}"
|
echo -e "Для просмотра логов: ${YELLOW}docker compose logs -f${NC}"
|
||||||
echo -e "Для остановки: ${YELLOW}docker-compose down${NC}"
|
echo -e "Для остановки: ${YELLOW}docker compose down${NC}"
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
container_name: synology-power-control-bot
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
@@ -26,7 +25,6 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile.wol
|
dockerfile: Dockerfile.wol
|
||||||
container_name: wol-proxy
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
network_mode: host
|
network_mode: host
|
||||||
|
|
||||||
@@ -34,7 +32,6 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile.nas
|
dockerfile: Dockerfile.nas
|
||||||
container_name: nas-emulator
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
network_mode: host
|
network_mode: host
|
||||||
networks:
|
networks:
|
||||||
|
|||||||
@@ -2,11 +2,25 @@ from flask import Flask, request, jsonify
|
|||||||
import socket
|
import socket
|
||||||
import struct
|
import struct
|
||||||
import os
|
import os
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
|
# Загружаем переменные окружения из файла .env
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
# Получаем параметры из переменных окружения
|
||||||
|
MAC_ADDRESS = os.getenv('MAC_ADDRESS', '00:11:22:33:44:55')
|
||||||
|
WOL_BROADCAST = os.getenv('WOL_BROADCAST', '255.255.255.255')
|
||||||
|
WOL_PORT = int(os.getenv('WOL_PORT', '9'))
|
||||||
|
SYNOLOGY_HOST = os.getenv('SYNOLOGY_HOST', '192.168.1.100')
|
||||||
|
|
||||||
# Функция отправки WOL-пакета
|
# Функция отправки WOL-пакета
|
||||||
def send_wol(mac_address):
|
def send_wol(mac_address=None):
|
||||||
|
# Если MAC-адрес не предоставлен, используем из .env
|
||||||
|
if not mac_address:
|
||||||
|
mac_address = MAC_ADDRESS
|
||||||
|
|
||||||
# Проверка формата MAC
|
# Проверка формата MAC
|
||||||
mac_address = mac_address.replace(':', '').replace('-', '')
|
mac_address = mac_address.replace(':', '').replace('-', '')
|
||||||
if len(mac_address) != 12:
|
if len(mac_address) != 12:
|
||||||
@@ -19,30 +33,47 @@ def send_wol(mac_address):
|
|||||||
# Отправка пакета
|
# Отправка пакета
|
||||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
|
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
|
||||||
sock.sendto(send_data, ('<broadcast>', 9))
|
sock.sendto(send_data, (WOL_BROADCAST, WOL_PORT))
|
||||||
sock.close()
|
sock.close()
|
||||||
|
|
||||||
@app.route('/wol', methods=['POST'])
|
@app.route('/wol', methods=['POST'])
|
||||||
def wol():
|
def wol():
|
||||||
data = request.get_json()
|
data = request.get_json() if request.is_json else {}
|
||||||
mac = data.get('mac')
|
mac = data.get('mac')
|
||||||
if not mac:
|
|
||||||
return jsonify({'error': 'MAC-адрес обязателен'}), 400
|
|
||||||
try:
|
try:
|
||||||
send_wol(mac)
|
# Если MAC не указан, используем MAC из .env
|
||||||
return jsonify({'status': 'WOL sent', 'mac': mac})
|
if not mac:
|
||||||
|
send_wol()
|
||||||
|
return jsonify({'status': 'WOL sent', 'mac': MAC_ADDRESS})
|
||||||
|
else:
|
||||||
|
send_wol(mac)
|
||||||
|
return jsonify({'status': 'WOL sent', 'mac': mac})
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({'error': str(e)}), 500
|
||||||
|
|
||||||
|
@app.route('/wol', methods=['GET'])
|
||||||
|
def wol_get():
|
||||||
|
try:
|
||||||
|
# Используем MAC из .env по умолчанию
|
||||||
|
send_wol()
|
||||||
|
return jsonify({'status': 'WOL sent', 'mac': MAC_ADDRESS})
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return jsonify({'error': str(e)}), 500
|
return jsonify({'error': str(e)}), 500
|
||||||
|
|
||||||
# Пример получения IP по MAC через парсинг DHCP lease-файла
|
# Получение IP адреса NAS
|
||||||
@app.route('/ip', methods=['GET'])
|
@app.route('/ip', methods=['GET'])
|
||||||
def get_ip():
|
def get_ip():
|
||||||
mac = request.args.get('mac')
|
mac = request.args.get('mac', MAC_ADDRESS)
|
||||||
|
|
||||||
|
# Пробуем получить IP из переменной окружения
|
||||||
|
if not mac or mac == MAC_ADDRESS:
|
||||||
|
return jsonify({'ip': SYNOLOGY_HOST, 'mac': MAC_ADDRESS, 'source': 'env'})
|
||||||
|
|
||||||
|
# Если запрашивается другой MAC - пробуем найти его в lease-файле
|
||||||
lease_file = '/var/lib/dhcp/dhcpd.leases' # путь к lease-файлу
|
lease_file = '/var/lib/dhcp/dhcpd.leases' # путь к lease-файлу
|
||||||
if not mac:
|
|
||||||
return jsonify({'error': 'MAC-адрес обязателен'}), 400
|
|
||||||
if not os.path.exists(lease_file):
|
if not os.path.exists(lease_file):
|
||||||
return jsonify({'error': 'Lease-файл не найден'}), 500
|
return jsonify({'error': 'Lease-файл не найден'}), 500
|
||||||
|
|
||||||
ip = None
|
ip = None
|
||||||
with open(lease_file, 'r') as f:
|
with open(lease_file, 'r') as f:
|
||||||
for line in f:
|
for line in f:
|
||||||
@@ -50,10 +81,29 @@ def get_ip():
|
|||||||
# Пример: lease 192.168.1.100 { ... hardware ethernet 00:11:22:33:44:55; ... }
|
# Пример: lease 192.168.1.100 { ... hardware ethernet 00:11:22:33:44:55; ... }
|
||||||
if 'lease' in line:
|
if 'lease' in line:
|
||||||
ip = line.split()[1]
|
ip = line.split()[1]
|
||||||
|
|
||||||
if ip:
|
if ip:
|
||||||
return jsonify({'ip': ip, 'mac': mac})
|
return jsonify({'ip': ip, 'mac': mac, 'source': 'lease'})
|
||||||
else:
|
else:
|
||||||
return jsonify({'error': 'IP не найден для MAC'}), 404
|
return jsonify({'error': 'IP не найден для MAC'}), 404
|
||||||
|
|
||||||
|
# Маршрут для отображения информации о конфигурации
|
||||||
|
@app.route('/', methods=['GET'])
|
||||||
|
def index():
|
||||||
|
return jsonify({
|
||||||
|
'status': 'running',
|
||||||
|
'config': {
|
||||||
|
'mac_address': MAC_ADDRESS,
|
||||||
|
'wol_broadcast': WOL_BROADCAST,
|
||||||
|
'wol_port': WOL_PORT,
|
||||||
|
'synology_host': SYNOLOGY_HOST
|
||||||
|
},
|
||||||
|
'endpoints': {
|
||||||
|
'wol_get': 'GET /wol - отправка WOL пакета на MAC из .env',
|
||||||
|
'wol_post': 'POST /wol - отправка WOL пакета с указанным MAC',
|
||||||
|
'ip': 'GET /ip - получение IP по MAC из .env или указанному в параметре'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.run(host='0.0.0.0', port=5000)
|
app.run(host='0.0.0.0', port=5002)
|
||||||
|
|||||||
Reference in New Issue
Block a user