|
<< Click to Display Table of Contents >> Navigation: API MasterSCADA 4D > Функции, ФБ, Протоколы на С++ > API для ФБ и протоколов > Разработка протоколов > Разработка протокола с настройками каналов > Реализация протокола с настройками каналов в C++ |
Пример реализации подключен к Examples.sln как mplc_protocol_with_settings:

Для разработки своих собственных протоколов нужно открыть пример и изменить те части проекта, которые отвечают за логику работы. Вспомогательные файлы, служащие для взаимодействия с исполнительной системой, редактировать не требуется.
Для начала по аналогии с простым протоколом создается класс, унаследованный от ScadaProtocol, реализующий требуемый функционал. Необходимы макросы регистрации класса MPLC_OBJECT(ProtocolWithSettings) в секции public. Также переопределению подлежат чисто виртуальные методы Execute() и Creatе(), которые отвечают за создание каналов и логику их хранения в самом классе протокола.
Для этого в примере был создан заголовочный файл protocol_with_settings.h:

Содержимое файла:
Скриншот |
Текст |
|
#pragma once #include <mplc/api.h>
#include "emulator.h"
class ProtocolWithSettings final : public mplc::api::ScadaProtocol { private: std::unordered_map<std::string, std::vector<mplc::api::ScadaChannel*>> endpointChannels; Emulator *emulator; INT Port; STRING Host; std::string key; bool connected{false}; bool Connect();
public: MPLC_OBJECT(ProtocolWithSettings); ProtocolWithSettings(); ~ProtocolWithSettings(); void Execute() override; mplc::api::ScadaChannel* Create(const mplc::vm::Channel* channel) override; void Init() override; }; |
Настройки самого протокола работают с параметрами, т. е. указываются как поля класса и регистрируются в макросе MPLC_DECLARE_PROPERTIES в качестве аргумента MPLC_In.
Настройки же каналов в свою очередь необходимо извлекать из них на этапе создания в методе Create из std::map settings и дальнейшей группировки их в зависимости от необходимости. В нашем случае группировка идёт по конечным точкам.
Для этого в примере был создан файл реализации для протокола с настройками: protocol_with_settings.cpp:

Содержимое файла:
Скриншот |
Текст |
|
#include "protocol_with_settings.h"
ProtocolWithSettings::ProtocolWithSettings() { emulator = new Emulator(Host, Port); }
ProtocolWithSettings::~ProtocolWithSettings() { emulator->close(); delete emulator; }
void ProtocolWithSettings::Init() { emulator->init(); }
bool ProtocolWithSettings::Connect() { if (connected) { return true; } if (!Connect()) { return false; } connected = true; SetFaultState(false, ""); return true; }
void ProtocolWithSettings::Execute() { if (!isConnect()) { return; } if (!Connect()) { SetFaultState(true, "Failed to connect"); return; } if (!isExecute()) { return; } std::string buff; for (auto ch : endpointChannels["main"]) { if (ch->InVar) { buff = emulator->read(MAIN); ch->InVar.Update(buff); } if (ch->OutVar) { buff = ch->OutVar.Get<std::string>(""); emulator->write(buff); }
} for (auto ch : endpointChannels["with_key"]) { if (ch->InVar) { buff = emulator->read(WITH_KEY); ch->InVar.Update(buff); } if (ch->OutVar) { buff = ch->OutVar.Get<std::string>(""); emulator->writeWithKey(buff, key); } } AcknowledgeAllChanges(); }
mplc::api::ScadaChannel* ProtocolWithSettings::Create(const mplc::vm::Channel* channel) { auto ch = new mplc::api::ScadaChannel(); if (channel->settings.find("Endpoint") != channel->settings.end()) { std::string endpoint; channel->settings.at("Endpoint").GetString(endpoint); endpointChannels[endpoint].push_back(ch); } if (channel->settings.find("Key") != channel->settings.end()) channel->settings.at("Key").GetString(key); ch->BaseInit(channel); Register(ch); return ch; }
MPLC_DECLARE_PROPERTIES(ProtocolWithSettings){ MPLC_In(Port), MPLC_In(Host), };
MPLC_PROTOCOL_TYPE(ProtocolWithSettings, ProtocolWithSettings);
|
Ввод и вывод данных из каналов модулей происходит методами Read и Write класса ScadaChannel. ch - это указатель на класс ScadaChannel.
Важно! Метод Read выдаёт ошибку и не возвращает значение, пока заменяется на комбинацию методов.
Далее можно компилировать проект.
Для компиляции проекта на ОС Windows нужно выполнить команду Build в контекстном меню проекта:

Скомпилированные файлы появятся в папке проекта: C:\mplc\api\platform\x64\bin\Release (адрес действителен, если название папок, которые делал разработчик, совпадают с названиями, которые давались в этой инструкции).
Чтобы произвести сборку под Linux платформы, нужно сохранить проект и перенести все файлы из папки C:\mplc\api (адрес действителен, если название папок, которые делал разработчик, совпадают с названиями, которые давались в этой инструкции) в созданный каталог на компьютере с ОС Linux. Подробнее смотрите в разделе Сборка под Linux платформы.
После сборки можно приступать к тестированию созданного ФБ.