Управление розетками IP PDU NetPing через Telegram

Всё ближе пора отпусков. Как и многие другие сотрудники, системные администраторы тоже мечтают провести отпуск где-нибудь вдали от рабочего места. Для большинства системных администраторов, особенно в небольших организациях, отвлечься от работы даже на относительно короткое время не так-то просто. Многие из них единолично несут ответственность за состояние различных компонентов ИТ-инфраструктуры. Как же ИТ-специалисту уйти в отпуск с уверенностью в том, что в его отсутствие компания сможет работать не менее эффективно, чем обычно? Ранее в нашем блоге мы уже рассматривали процесс создания ботов для мессенджера «Telegram». В этой статье мы рассмотрим один из вариантов удалённого управления питанием ИТ-оборудования из любой точки земного шара (при наличии доступа к Интернет) с использованием интеграции мессенджера «Telegram» и устройства удалённого управления электропитанием (IP PDU) NetPing. При необходимости ИТ-специалист отправляет команду на розетку через «Telegram», после применения команды специалисту в «Telegram» приходит уведомление о том, что команда была успешно применена, и розетка изменила свое состояние.

Требуемое оборудование, программное обеспечение и подготовка к разработке:

Для реализации функционала удалённого управления розетками устройства NetPing через «Telegram» потребуется следующий комплект оборудования:

  • Устройство удалённого управления розетками (NetPing 8/PWR-220 v3/SMSNetPing 4/PWR-220 v3/SMSNetPing 2/PWR-220 v2/SMS или NetPing 2/PWR-220 v3/ETH) – 1 шт.;
  • Подключаемая нагрузка – количество в зависимости от количества встроенных розеток IP PDU NetPing;
  • ПК или сервер с предустановленной операционной системой Linux или Windows и доступом в Интернет – 1 шт.;
  • Локальная сеть для связи между устройством мониторинга и ПК, на котором выполняется скрипт бота – 1 шт.;
  • Мессенджер «Telegram» на ПК или смартфоне с доступом к Интернет – 1 шт.;

В нашем примере будем использовать устройство NetPing 4/PWR-220 v3/SMS. Считаем, что устройство настроено на работу в вашей локальной сети. Подробнее ознакомиться с настройками можно в документации. Также предполагается, что у вас настроен сервер с OS Ubuntu, и созданы боты в соответствии с рекомендациями этой статьи. В данном примере мы создали бота с именем @NetPing_4PWR_bot. 

Программирование функций управления электропитанием для бота @NetPing_4PWR_bot

Запрограммируем расширенный функционал для нашего бота @NetPing_4PWR_bot. Правим основной файл скрипта управляющего ботом – «bot.py»: 

import telebot
import requests
from telebot import types
import conf_bot

auth = conf_bot.auth
url = conf_bot.url
bot = telebot.TeleBot(conf_bot.TOKEN)

# Обработка команд "/start" и "/help"
@bot.message_handler(commands=['start', 'help'])
def start(message):
     markup = types.ReplyKeyboardMarkup()
     markup.row('/relay1', '/relay2')
     markup.row('/relay3', '/relay4')
     markup.row('/npstatus', '/help')
     bot.send_message(message.chat.id, '''
    ***Тестовый бот для управления розетками устройства NetPing 4/PWR-220 v3/SMS***
    Чтобы запросить актуальные данные о состоянии реле используйте команду /npstatus
    Чтобы управлять реле №1 используйте команду /relay1
    Чтобы управлять реле №2 используйте команду /relay2
    Чтобы управлять реле №3 используйте команду /relay3
    Чтобы управлять реле №4 используйте команду /relay4
    Для вызова этой справки используйте команду /help
         ''',
    reply_markup=markup)

# Обработка команды "/npstatus" получение данных о статусе реле
@bot.message_handler(commands=['npstatus'])
def status(m):
     i=1
     while i <=4:
         def relay ():
              r = requests.get(url+'relay.cgi?r'+str(i), auth=auth)
              io = r.text[22:23]               
              if io == '0':
                   io = ('Текущее состояние реле #'
                        + str(i) + ': ' + io + ' выключено')
                   return io
              else:
                   io= ('Текущее состояние реле #'
                        + str(i)  + ': ' + io + ' включено')
                   return io         
         io_stat = relay()           
         sent = bot.send_message(m.chat.id, io_stat )         
         i=i+1

# Обработка команды "/relay1", создание меню.
@bot.message_handler(commands=['relay1'])
def status(m):
     keyboard = types.InlineKeyboardMarkup()
     keyboard.add(*[types.InlineKeyboardButton(text=name,
         callback_data=name) for name in ['Включить реле 1',
     'Выключить реле 1', 'Сбросить реле 1' ]])
     msg = bot.send_message(m.chat.id, '''
         Эта команда позволяет управлять реле 1.
         Выберите необходимое действие: ''',
         reply_markup=keyboard)

# Обработка команды "/relay2", создание меню.
@bot.message_handler(commands=['relay2'])
def status(m):
     keyboard = types.InlineKeyboardMarkup()
     keyboard.add(*[types.InlineKeyboardButton(text=name,
         callback_data=name) for name in ['Включить реле 2',
     'Выключить реле 2', 'Сбросить реле 2' ]])
     msg = bot.send_message(m.chat.id, '''
         Эта команда позволяет управлять реле 2.
         Выберите необходимое действие: ''',
         reply_markup=keyboard)

# Обработка команды "/relay3", создание меню.
@bot.message_handler(commands=['relay3'])
def status(m):
     keyboard = types.InlineKeyboardMarkup()
     keyboard.add(*[types.InlineKeyboardButton(text=name,
         callback_data=name) for name in ['Включить реле 3',
     'Выключить реле 3', 'Сбросить реле 3' ]])
     msg = bot.send_message(m.chat.id, '''
         Эта команда позволяет управлять реле 3.
         Выберите необходимое действие: ''',
         reply_markup=keyboard)

# Обработка команды "/relay4", создание меню.
@bot.message_handler(commands=['relay4'])
def status(m):
     keyboard = types.InlineKeyboardMarkup()
     keyboard.add(*[types.InlineKeyboardButton(text=name,
         callback_data=name) for name in ['Включить реле 4',
     'Выключить реле 4', 'Сбросить реле 4' ]])
     msg = bot.send_message(m.chat.id, '''
         Эта команда позволяет управлять реле 4.
         Выберите необходимое действие: ''',
         reply_markup=keyboard)
 
# Обработка нажатия кнопки меню "Включить реле 1"
@bot.callback_query_handler(func=lambda c: True)
def inline(c):
     if c.data =='Включить реле 1':
         bot.edit_message_text(
              chat_id=c.message.chat.id,
              message_id=c.message.message_id,
              text='Реле 1 включено',
              parse_mode='Markdown')
         r = requests.get(url+'relay.cgi?r1=1', auth=auth)

#Обработка нажатия кнопки меню "Выключить реле 1"
     elif c.data =='Выключить реле 1':
         bot.edit_message_text(
              chat_id=c.message.chat.id,
              message_id=c.message.message_id,
              text='Реле 1 выключено',
              parse_mode='Markdown')
         r = requests.get(url+'relay.cgi?r1=0', auth=auth)

#Обработка нажатия кнопки меню "Сбросить реле 1"
     elif c.data =='Сбросить реле 1':
         bot.edit_message_text(
              chat_id=c.message.chat.id,
              message_id=c.message.message_id,
              text='Реле 1 переключено в инверсное состояние на 10 сек.',
              parse_mode='Markdown')
         r = requests.get(url+'relay.cgi?r1=f,10', auth=auth)
    
# Обработка нажатия кнопки меню "Включить реле 2"
     elif c.data =='Включить реле 2':
         bot.edit_message_text(
              chat_id=c.message.chat.id,
              message_id=c.message.message_id,
              text='Реле 2 включено',
              parse_mode='Markdown')
         r = requests.get(url+'relay.cgi?r2=1', auth=auth)

#Обработка нажатия кнопки меню "Выключить реле 2"
     elif c.data =='Выключить реле 2':
         bot.edit_message_text(
              chat_id=c.message.chat.id,
              message_id=c.message.message_id,
              text='Реле 2 выключено',
              parse_mode='Markdown')
         r = requests.get(url+'relay.cgi?r2=0', auth=auth)

#Обработка нажатия кнопки меню "Сбросить реле 2"
     elif c.data =='Сбросить реле 2':
         bot.edit_message_text(
              chat_id=c.message.chat.id,
              message_id=c.message.message_id,
              text='Реле 2 переключено в инверсное состояние на 10 сек.',
              parse_mode='Markdown')
         r = requests.get(url+'relay.cgi?r2=f,10', auth=auth) 

# Обработка нажатия кнопки меню "Включить реле 3"
     elif c.data =='Включить реле 3':
         bot.edit_message_text(
              chat_id=c.message.chat.id,
              message_id=c.message.message_id,
              text='Реле 3 включено',
              parse_mode='Markdown')
         r = requests.get(url+'relay.cgi?r3=1', auth=auth)

#Обработка нажатия кнопки меню "Выключить реле 3"
     elif c.data =='Выключить реле 3':
         bot.edit_message_text(
              chat_id=c.message.chat.id,
              message_id=c.message.message_id,
              text='Реле 3 выключено',
              parse_mode='Markdown')
         r = requests.get(url+'relay.cgi?r3=0', auth=auth)

#Обработка нажатия кнопки меню "Сбросить реле 3"
     elif c.data =='Сбросить реле 3':
         bot.edit_message_text(
              chat_id=c.message.chat.id,
              message_id=c.message.message_id,
              text='Реле 3 переключено в инверсное состояние на 10 сек.',
              parse_mode='Markdown')
         r = requests.get(url+'relay.cgi?r3=f,10', auth=auth)

# Обработка нажатия кнопки меню "Включить реле 4"
     elif c.data =='Включить реле 4':
         bot.edit_message_text(
              chat_id=c.message.chat.id,
              message_id=c.message.message_id,
              text='Реле 4 включено',
              parse_mode='Markdown')
         r = requests.get(url+'relay.cgi?r4=1', auth=auth)

#Обработка нажатия кнопки меню "Выключить реле 4"
     elif c.data =='Выключить реле 4':
          bot.edit_message_text(
              chat_id=c.message.chat.id,
              message_id=c.message.message_id,
              text='Реле 4 выключено',
              parse_mode='Markdown')
         r = requests.get(url+'relay.cgi?r4=0', auth=auth)

#Обработка нажатия кнопки меню "Сбросить реле 4"
     elif c.data =='Сбросить реле 4':
         bot.edit_message_text(
              chat_id=c.message.chat.id,
              message_id=c.message.message_id,
              text='Реле 4 переключено в инверсное состояние на 10 сек.',
              parse_mode='Markdown')
         r = requests.get(url+'relay.cgi?r4=f,10', auth=auth) 
bot.polling()

Исходные файлы бота можно скачать здесь.

Работа с ботом удалённого управления электропитанием

Активируем диалог с ботом @NetPing_4PWR_bot, в скрипт для управления которым мы добавили новый функционал. После того, как мы отправим боту команду «/start» (1) в окно диалога будет выведена памятка (2), и ниже поля для ввода сообщения появятся кнопки (3), дублирующие команды для управления ботом:

Telegram начало диалога с ботом для управления устройством NetPing 4PWR-220 v3 SMS

Команды «/relay1» — «/relay4» служат для управления розетками устройства NetPing 4/PWR-220 v3/SMS. При выборе команды в окне диалога отображается уведомление о выбранной команде (1) и кнопки для выбора возможных действий (2). На скриншоте ниже последовательно выбраны все четыре команды для управления розетками:

Telegram вывод команд для управления розетками устройства NetPing 4PWR-220 v3 SMS

Рассмотрим подробнее команды управления розетками. Бот управляет розетками устройства NetPing 4/PWR-220 v3/SMS при помощи URL-encoded команд, которые прописаны в коде скрипта бота и назначены кнопкам. Для управления реле доступны команды «Включить», «Выключить» и «Сбросить». Команда «Сбросить» выполняет кратковременное (10 секунд) переключение реле в инверсное состояние (выдача импульса сброса), таким образом выполняется перезагрузка подключённого к розетке оборудования. При выполнении команды в окне диалога выводится уведомление о текущем состоянии реле. На скриншоте ниже результаты последовательного нажатия на кнопки управления реле 1:

Telegram вывод сообщений о статусе реле устройства NetPing 4PWR-220 v3 SMS

Команда «/npstatus» позволяет запросить текущее состояние всех розеток устройства NetPing 4/PWR-220 v3/SMS. В этом примере команда «/npstatus» не имеет кнопок действий, и запрос состояния розеток происходит сразу после выбора команды:

Telegram Вывод текущего состояния всех розеток устройства NetPing 4PWR-220 v3 SMS

Таким образом, мы получили удобный инструмент для удалённого управления питанием различных ИТ-устройств (серверов, коммутаторов, маршрутизаторов, Wi-Fi точек доступа, модемов и прочего оборудования) из любого уголка мира, где есть подключение к Интернет, благодаря которому системный администратор может спокойно ехать в отпуск.