
Возможно ли в промышленной панеле оператора (HMI) создать своего Телеграм бота?
В HMI от Weintek это реализуемо! В данном туториале мы научим нашу панельку работать с Telegram Bot API, напишем Echo-бот и реализуем отправку сообщений по событию.
Когда появляется необходимость удаленного контроля за работой автоматизированной системы, например опрос показаний с каких-либо внешних датчиков по запросу или в случае аварии получение уведомлений — в таких ситуациях, возможно, пригодится дружба Telegram c HMI от Weintek.
Создание проектов для оборудования от Weintek осуществляется в среде разработки EasyBuilder Pro (далее EB Pro). Начиная с версии EB Pro V6.05.01 появилась возможность писать скрипты на JavaScript по стандарту ECMAScript 2017, правда данная опция присутствует пока в стандартных и расширенных моделях cMT серии X. Скачать самую свежую версию EB Pro можно тут.
Для начала нам необходимо создать проект в EB Pro, выбрать вашу модель HMI, в моем случае это cMT2078X.


документация про «JS Object» . В одном из примеров можно найти библиотеку для отправки POST или GET запросов, она нам понадобится для работы с Telegram Bot API. Скачиваем ее и подключаем через модуль “JS Ресурс”.

const request = require('./request-0.0.2.js'); export class TelegramBot { constructor(token) { this.token = token; this.url = `https://api.telegram.org/bot${this.token}`; this.keyboard = Array(); this.resultUpdates = {}; }
В request мы предварительно подключаем скачанную ранее из документации библиотеку, а в конструкторе класса TelegramBot присваиваем первоначальные значения свойствам.
● token — токен, полученный от BotFather, передаваемый при создании экземпляра класса в качестве аргумента
● url — будет хранить ссылку API Telegram
● keyboard — массив для функциональных кнопок, которые будут передаваться вместе с сообщением пользователю
● resultUpdates — ассоциативный массив для хранения последнего сообщения
Получение токена с BotFather я описывать не буду, на Хабре и так полно статей на тему чат-ботов в Telegram (вот к примеру отличная подробная статья).
Далее описываем методы созданного нами класса:
makeButton(button){ this.keyboard.push(button) }
makeButton принимает на вход в качестве аргументов массив из названий кнопок и добавляет их в один ряд. Например код:
makeButton(['Температура','Давление']);
При передаче сообщения добавит нам такие кнопочки:

Чтобы добавить кнопки рядом ниже необходимо снова использовать метод makeButton и передать ему названия кнопки.
makeButton(['Скорость']);
Результат будет таким:

Далее опишем метод отправки сообщения:
sendMessage(message, chatid){ var final_url = `${this.url}/sendmessage?`; var json = { "chat_id": chatid, "text": message }; if (this.keyboard != 0) { json['reply_markup'] = { "resize_keyboard": true, "keyboard": this.keyboard } }; var jsonData = JSON.stringify(json); request.post({ url: final_url, header: { "content-type": "application/json; charset=utf-8", }, data: jsonData }, (error, response, body) => { if (error == "No error") { console.log("body:", body); } else { console.log("error:", error); console.log("response:", response); console.log("body:", body); } } ); }
sendMessage отправляет сообщение пользователю методом запроса POST, в качестве аргументов принимает message (текст сообщения) и chatid (id пользователя). Свой id можно например узнать через данного бота. Если данные успешно доставлены — выводим в консоль тело ответа от сервера, в случае ошибки совместно с телом в консоль дополнительно производится вывод информация о ошибке.
getUpdates(){ var final_url = `${this.url}/getUpdates?offset=-1`; request.get({ url: final_url }, (error, response, body) => { if (error == "No error") { var body_json = JSON.parse(body); this.resultUpdates = body_json.result[0]; } else { console.log("error:", error); console.log("response:", response); console.log("body:", body); } } ); return this.resultUpdates } }
С помощью метода getUpdates получаем все обновления от сервера Telegram и возвращаем последнее сообщение.
Минимальный необходимый функционал реализован, сохраняем данный класс в отдельный файл и подключаем его в EBPro через инструмент “JS ресурс”, как делали это ранее с библиотекой для отправки POST и GET запросов.


Заполняем содержимое.
const telegramBot = await import('/weintek_telebot.js'); var bot = new telegramBot.TelegramBot('TOKEN') var chats = {} var mouseArea = new MouseArea(); this.widget.add(mouseArea);
В telegramBot импортируем файл с ранее написанным классом.
bot — экземпляр класса telegramBot с переданным в качестве аргумента токеном от BotFather.
chats — именованный массив, понадобиться для хранения ID пользователей написавших нашему боту и ID последнего сообщения
mouseArea — экземпляр, входящего в стандартную библиотеку класса MouseArea, подробнее о нем можно почитать в документации, с помощью него мы будем обрабатывать событие “нажатия по области” и осуществлять рассылку сообщений.
Добавляем кнопки:
bot.makeButton(['Температура','Давление']); bot.makeButton(['Скорость']);
Теперь, по традиции всех примеров Телеграм ботов, реализуем функцию ECHO бота (при получении сообщения бот будет отправлять его копию в ответ). Для этого будем использовать функцию setInterval, которая вызывает callback функцию с определенным интервалом времени, в нашем случае 500 мс.
setInterval(() => { var message = bot.getUpdates(); var chatId = message.message.from.id var messageId = message.message.message_id var text = message.message.text if (!(chatId in chats)){ chats[chatId]=[messageId, text]; bot.sendMessage(text, chatId); } else { if (chats[chatId][0] != messageId){ chats[chatId][0] = messageId; bot.sendMessage(text, chatId); } } } , 500);
В message мы сохраняем объект последнего сообщения, а дальше уже из него вытягиваем необходимые в дальнейшем данные
● chatId — хранит ID пользователя.
● messageId — ID сообщения, по которому мы будем определять произошло ли его обновление
● text — текст сообщения
Далее мы проверяем есть ли в нашем списке такой пользователь, если его нет, то запоминаем его в chats для использования его в будущей рассылке 🙂 также не забываем отправить ему копию его же сообщения.
Ну что? Осталось только написать код для рассылки сообщений?
Для этого к mouseArea подключаем обработчик события ‘click’ и описываем для него callback функцию, которая перебирает значения с массива chats, но если он еще пустой просто ругаемся в консоль. ¯\_(ツ)_/¯
mouseArea.on('click', (mouseEvent) => { if (!(Object.keys(chats).length == 0)){ for (var key in chats) { var mes = bot.sendMessage('Привет! Я Weintek', key); } } else { console.log('Боту еще никто не отписал!!'); } });
Кстати, для проверки нашего проекта не обязательно иметь панель физически, его можно запустить прямо в среде разработки EBPro с помощью инструмента “Оффлайн симуляция”.


Все работает! Бот нам отвечает и отправляет сообщение, когда происходит нажатие по объекту JS.
Для просмотра диагностической информации или то что мы отправляем в консоль с помощью функции console.log() — в режиме оффлайн симуляции запускаем инструмент “Диагностировать”:

Остается только протестировать проект на реальном устройстве. =)
Весь код и пример проекта для EBPro лежит на гитхабе.
ссылка на оригинал статьи https://habr.com/ru/post/709010/
Добавить комментарий