산업기술
PLCnext Common Classes가 XML 직렬화를 지원한다는 사실을 알고 계셨습니까? 이 문서에서는 IXmlSerializable
를 사용하는 방법을 보여줍니다. C++ 클래스의 데이터를 채우는 인터페이스.
PLCnext Common Classes의 API 문서에서 Interface 설명을 찾을 수 있습니다.
이 기사는 다음 설정으로 작성되었습니다.
PLCnext 펌웨어:2020.6 LTS Linux 64비트용 PLCnext C++ SDK 2020.6 LTS
다음 구성 파일로 클래스를 채우고자 합니다.
<?xml version="1.0" encoding="UTF-8"?> <MyConfigDocument schemaVersion="1.0"> <Server dnsName="server.domain.tld" /> <FileList> <File path="$ARP_DATA_DIR$/Services/MyComponent/file1.txt" /> <File path="$ARP_DATA_DIR$/Services/MyComponent/file2.txt" /> </FileList> </MyConfigDocument>
$ARP_DATA_DIR$
표기법은 환경 변수의 자리 표시자입니다(이 경우 ARP_DATA_DIR
). . 대상 /etc/plcnext/Device.acf.settings
의 장치 설정 파일에서 정의된 Arp 환경 변수를 찾을 수 있습니다. .
XML 파일에서 데이터를 읽을 수 있으려면 IXMLSerializable
을 구현해야 합니다. 우리 클래스의 인터페이스. 간단하게 하기 위해 우리 클래스에는 DNS 이름과 파일 경로 벡터라는 두 가지 데이터 요소만 있습니다.
#pragma once #include "Arp/System/Core/Arp.h" #include "Arp/System/Commons/Xml/IXmlSerializable.hpp" #include "vector" namespace MyComponent { class MyConfiguration : public Arp::System::Commons::Xml::IXmlSerializable { public: MyConfiguration() = default; ~MyConfiguration() = default; // IXMLSerializable interface public: void ReadXml(Arp::System::Commons::Xml::XmlReader& reader, Arp::System::Commons::Xml::XmlSerializationContext& context) override; void WriteXml(Arp::System::Commons::Xml::XmlWriter& writer, Arp::System::Commons::Xml::XmlSerializationContext& context) override; // The data public: Arp::String DnsName{""}; std::vector<Arp::String> FileList; // Some supporting methods private: void readFileList(Arp::System::Commons::Xml::XmlReader& reader, Arp::System::Commons::Xml::XmlSerializationContext& context); void readFile(Arp::System::Commons::Xml::XmlReader& reader, Arp::System::Commons::Xml::XmlSerializationContext& context); }; } // namespace MyComponent
ReadXml
를 구현해야 합니다. 및 WriteXml
방법.
WriteXml
방법은 간단합니다. 우리는 XML 파일에서 데이터를 읽고 싶은 것만 쓰고 싶지 않습니다. ReadXml
XML 파일에서 데이터를 읽으려면 메서드가 호출됩니다.
#include "MyConfiguration.hpp"
namespace MyComponent
{
void MyConfiguration::WriteXml(Arp::System::Commons::Xml::XmlWriter& writer, Arp::System::Commons::Xml::XmlSerializationContext& context)
{
// no operation.
return;
}
void MyConfiguration::ReadXml(Arp::System::Commons::Xml::XmlReader& reader, Arp::System::Commons::Xml::XmlSerializationContext& context)
{
Arp::String elementName;
while (reader.TryReadStartElement(elementName))
{
if (elementName == Arp::System::Commons::Xml::XmlSerializationContext::IncludesXmlName)
{
context.ReadIncludesElement(reader);
}
else if (elementName == "Server")
{
this->DnsName = reader.GetAttributeValue<Arp::String>("dnsName");
reader.ReadEndElement();
}
else if (elementName == "FileList")
{
this->readFileList(reader, context);
}
else
{
context.InvalidXmlElementOccurs(reader, elementName);
reader.ReadEndElement();
}
}
}
void MyConfiguration::readFileList(Arp::System::Commons::Xml::XmlReader& reader, Arp::System::Commons::Xml::XmlSerializationContext& context)
{
if (reader.IsEmptyElement()){
return;
}
if (reader.ReadToDescendant("File"))
{
this->readFile(reader, context);
while (reader.ReadToNextSibling("File"))
{
this->readFile(reader, context);
}
}
else
{
reader.ReadEndElement();
}
}
void MyConfiguration::readFile(Arp::System::Commons::Xml::XmlReader& reader, Arp::System::Commons::Xml::XmlSerializationContext& context)
{
// Use 'context.ResolvePath' to replace placeholders in the path.
auto file = Arp::String(context.ResolvePath(reader.GetAttributeValue<Arp::String>("path")));
this->FileList.push_back(file);
reader.ReadEndElement();
}
} // namespace MyComponent
이제 XMLConfigDocument
클래스를 사용할 수 있습니다. LoadConfig 메서드의 클래스를 사용하여 클래스의 데이터를 로드합니다.
void MyComponent::LoadConfig() { // load project config here using namespace Arp::System::Commons; this->log.Info("LoadConfig"); // Fist argument has to match the XML root element name. // Our MyConfiguration instance this->config will be populated. Xml::XmlConfigDocument configDoc("MyConfigDocument", this->config); if (!Io::File::Exists(this->settingsPath)) { this->log.Error("Configuration file '{}' does not exist.", this->settingsPath); return; } try { configDoc.Load(this->settingsPath); } catch (const Arp::Exception& e) { this->log.Error(e.GetMessage()); throw InvalidConfigException(e.GetMessage()); } }
산업기술
정원 조명과 가로등은 특히 밤에 켜져 있어야 합니다. 이러한 이유로 태양광 패널은 매우 중요한 역할을 합니다. 엔지니어들은 가정용 및 산업용 잔디 LED 조명용 QX5252 ASIC을 높이 평가합니다. 따라서 DIY LED 회로를 만드는 데 열성적이라면 QX5252가 편리할 것입니다. 여기에서는 이 IC, 작동 방식 및 프로젝트에서 IC를 활용하는 방법에 대한 모든 내용을 다룹니다. 1. Qx5252 핀 구성 핀 이름 패키지 유형 TO-94 / DIP-8 핀 유형 SBAT 1 / 6 입력 핀 LX 4 / 3 출력 핀
산업용 애플리케이션의 로깅 값은 많은 고객의 주요 특성이며 일부 애플리케이션에서는 변수의 수가 정말 많을 수 있으므로 이 데이터 로깅을 구성하는 기본적이고 쉬운 방법이 필요합니다. 아래에서 네이티브 데이터 로깅 서비스 구성 요소를 살펴보고 이 서비스에서 CSV 파일을 생성하는 방법을 알아보겠습니다. 다음 링크에서 데이터 로깅 서비스 구성 요소에 대한 추가 정보를 찾을 수 있습니다. 데이터 로거 구성 및 OPC UA 기록 액세스에서 사용 실시간 데이터 로거 – PLCnext 정보 센터 Datalogging 세션을 구성한 경