@JaumeMas следующий Python3 скрипт позволит вам включать или выключать состояние порта PoE. Протестирован на UDMB с версией 4.1.13+9.0.108. Синтаксис:
`command.py -s SwitchName -p PortNum -m auto|off|toggle`
Аргумент `-m` необязателен. Если он отсутствует, состояние PoE порта будет переключено. Имя переключателя должно быть заключено в кавычки, если оно содержит пробелы или другие специальные символы. Например:
`command.py -s 'My Switch' -p 2 -m auto`
Несколько важных моментов:
* Замените `CONTROLLER`, `USER` и `PASS` на соответствующие значения для вашей системы. Обратите внимание, что комбинация `USER/PASS` должна быть для учетной записи администратора (так как скрипт вносит изменения в контроллер).
* На системе должна быть установлена библиотека Python Requests (вероятно, установлена по умолчанию).
Если вы используете автономный контроллер, а не шлюз Dream, то нужно изменить глобальные переменные `URI_`.
```python
import requests
import json
import sys
import argparse
from urllib3.exceptions import InsecureRequestWarning
CONTROLLER = 'udm.home.arpa' # FQDN или IP адрес
USER = 'username' # Должен иметь доступ для чтения/записи
PASS = 'password'
URI_LOGIN = f'https://{CONTROLLER}/api/auth/login'
URI_LOGOUT = f'https://{CONTROLLER}/logout'
URI_REQUEST_PREFIX = f'https://{CONTROLLER}/proxy/network/api/s/default/'
def updatePoe(switchName, port, action):
if not action in ['auto', 'off', 'toggle']:
print(f'Неверное действие PoE запрошено: \'{action}\'')
return 1
authDict = {'username':USER, 'password':PASS}
headers = {'Content-Type': 'application/json'}
r = requests.post(URI_LOGIN, data=json.dumps(authDict), headers=headers, verify=False)
cookies = r.cookies
headerPut = { 'Accept': 'application/json',
'Content-Type': 'application/json; charset=utf-8',
'x-csrf-token': r.headers['X-CSRF-Token'] }
r = requests.get(f'{URI_REQUEST_PREFIX}stat/device', cookies=cookies, verify=False)
respDict = json.loads(r.text)
for sDict in respDict['data']:
if 'sw' in sDict['stat'].keys() and sDict['name'] == switchName:
switchId = sDict['_id']
overrides = sDict['port_overrides']
portIdx = [x for x in range(len(overrides)) if overrides[x]['port_idx'] == port]
break
if not 'switchId' in locals():
print(f'Переключатель \'{switchName}\' не найден')
return 1
if not 'portIdx' in locals() or len(portIdx) == 0:
print(f'Порт {port} на \'{switchName}\' не существует')
return 1
portIdx = portIdx[0]
if not 'poe_mode' in overrides[portIdx].keys():
print(f'PoE не поддерживается на \'{switchName}\', порт {port}')
return 1
if action == 'toggle':
action = 'auto' if overrides[portIdx]['poe_mode'] == 'off' else 'off'
overrides[portIdx]['poe_mode'] = action
r = requests.put(f'{URI_REQUEST_PREFIX}rest/device/{switchId}',
data = json.dumps({'port_overrides': overrides}),
headers=headerPut,
cookies=cookies,
verify=False)
r= requests.get(URI_LOGOUT, cookies=cookies, verify=False)
return
def main():
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
parser = argparse.ArgumentParser(description='Обновить состояние PoE на порту переключателя')
parser.add_argument('-s', required=True, type=str, dest='switchName',
help='Имя переключателя, заключенное в кавычки, если оно содержит специальные символы')
parser.add_argument('-p', required=True, type=int, dest='port',
help='Номер целевого порта')
parser.add_argument('-m', required=False, type=str, dest='mode', default='toggle',
help='Необязательный режим PoE, один из (auto, off, toggle). По умолчанию \'toggle\'.')
if updatePoe(parser.parse_args().switchName,
parser.parse_args().port,
parser.parse_args().mode) == 1:
print('Обнаружены ошибки')
sys.exit(1)
if __name__ == '__main__':
main()
```