Реализация протокола с настройками каналов в C++

<< Click to Display Table of Contents >>

Navigation:  API MasterSCADA 4D > Функции, ФБ, Протоколы на С++ > API для ФБ и протоколов > Разработка протоколов > Разработка протокола с настройками каналов >

Реализация протокола с настройками каналов в C++

Пример реализации подключен к Examples.sln как mplc_protocol_with_settings:

realiz_protocola_nastr_kanalov_v_C

Для разработки своих собственных протоколов нужно открыть пример и изменить те части проекта, которые отвечают за логику работы. Вспомогательные файлы, служащие для взаимодействия с исполнительной системой, редактировать не требуется.

Порядок разработки

protocol_with_settings.h

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

Для этого в примере был создан заголовочный файл protocol_with_settings.h:

realiz_protocola_nastr_kanalov_v_C_1

Содержимое файла:

Скриншот

Текст

realiz_protocola_nastr_kanalov_v_C_2

#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;

 

public:

  MPLC_OBJECT(ProtocolWithSettings);

   ProtocolWithSettings();

   ~ProtocolWithSettings();

  void Execute() override;

   mplc::api::ScadaChannel* Create(const mplc::vm::Channel* channel) override;

  void Init() override;

};

protocol_with_settings.cpp

Настройки самого протокола работают с параметрами, т. е. указываются как поля класса и регистрируются в макросе MPLC_DECLARE_PROPERTIES в качестве аргумента MPLC_In.

Настройки же каналов в свою очередь необходимо извлекать из них на этапе создания в методе Create из std::map settings и дальнейшей группировки их в зависимости от необходимости. В нашем случае группировка идёт по конечным точкам.

Для этого в примере был создан файл реализации для протокола с настройками: protocol_with_settings.cpp:

realiz_protocola_nastr_kanalov_v_C_3

Содержимое файла:

Скриншот

Текст

realiz_protocola_nastr_kanalov_v_C_4

#include "protocol_with_settings.h"

 

ProtocolWithSettings::ProtocolWithSettings() {

   emulator = new Emulator(Host, Port);

}

 

ProtocolWithSettings::~ProtocolWithSettings() {

   emulator->close();

  delete emulator;

}

 

void ProtocolWithSettings::Init() {

   emulator->init();

}

 

void ProtocolWithSettings::Execute() {

   std::string buff;

 

  for (auto ch : endpointChannels["main"]) {

      if (ch->InVar) {

           buff = emulator->read(MAIN);

           ch->Write(LuaProvider(), buff);

       }

         if (ch->OutVar) {

           ch->OutVar->Read(LuaProvider());

           ch->OutVar->Value.GetString(buff);

           emulator->write(buff);

       }

 

   }

  for (auto ch : endpointChannels["with_key"]) {

      if (ch->InVar) {

           buff = emulator->read(WITH_KEY);

           ch->Write(LuaProvider(), buff);

       }

         if (ch->OutVar) {

           ch->OutVar->Read(LuaProvider());

           ch->OutVar->Value.GetString(buff);

           emulator->writeWithKey(buff, key);

       }

   }

}

 

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);

  return ch;

}

 

MPLC_DECLARE_PROPERTIES(ProtocolWithSettings){

 MPLC_In(Port),

  MPLC_In(Host),

};

 

MPLC_PROTOCOL_TYPE(ProtocolWithSettings, ProtocolWithSettings);

 

Ввод и вывод данных из каналов модулей происходит методами Read и Write класса ScadaChannel. ch - это указатель на класс ScadaChannel.

Важно! Метод Read выдаёт ошибку и не возвращает значение, пока заменяется на комбинацию методов.

Далее можно компилировать проект.

Компиляция проекта

ОС Windows

Для компиляции проекта на ОС Windows нужно выполнить команду Build в контекстном меню проекта:

realiz_protocola_nastr_kanalov_v_C_5

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

ОС Linux

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

После сборки можно приступать к тестированию созданного ФБ.