Реализация протокола с настройками каналов в 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;

    bool connected{false};

    bool Connect();

 

public:

    MPLC_OBJECT(ProtocolWithSettings);

    ProtocolWithSettings();

    ~ProtocolWithSettings();

    void Execute() override;

    mplc::api::ScadaChannel* Create(const mplc::vm::Channelchanneloverride;

    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_4realiz_protocola_nastr_kanalov_v_C_40

#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::ScadaChannelProtocolWithSettings::Create(const mplc::vm::Channelchannel) {

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

 

Ввод и вывод данных из каналов модулей происходит методами 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 платформы.

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