open62541 (http://open62541.org) เป็นการใช้งานโอเพ่นซอร์สของ OPC UA (OPC Unified Architecture / IEC 62541) ที่เขียนด้วยภาษา C ไลบรารีนี้สามารถใช้ได้กับคอมไพเลอร์หลักๆ ทั้งหมด และมอบเครื่องมือที่จำเป็นในการใช้งานไคลเอนต์และเซิร์ฟเวอร์ OPC UA โดยเฉพาะ หรือเพื่อรวมการสื่อสารที่ใช้ OPC UA เข้ากับแอปพลิเคชันที่มีอยู่ ไลบรารี open62541 เป็นอิสระจากแพลตฟอร์ม: ฟังก์ชันเฉพาะแพลตฟอร์มทั้งหมดถูกใช้งานผ่านปลั๊กอินที่แลกเปลี่ยนได้ เพื่อให้ง่ายต่อการย้ายไปยังเป้าหมาย (ฝัง) ที่แตกต่างกัน
open62541 ได้รับอนุญาตภายใต้ Mozilla Public License v2.0 (MPLv2) ซึ่งช่วยให้สามารถรวมและแจกจ่ายไลบรารี open62541 กับซอฟต์แวร์ที่เป็นกรรมสิทธิ์ใดๆ ได้ เฉพาะการเปลี่ยนแปลงไลบรารี open62541 เท่านั้นที่ต้องได้รับอนุญาตภายใต้ MPLv2 เมื่อคัดลอกและแจกจ่าย ปลั๊กอิน ตลอดจนตัวอย่างเซิร์ฟเวอร์และไคลเอนต์เป็นสาธารณสมบัติ (ใบอนุญาต CC0) สามารถนำมาใช้ซ้ำได้ภายใต้ใบอนุญาตใดๆ และไม่จำเป็นต้องเผยแพร่การเปลี่ยนแปลง
ห้องสมุดมีอยู่ในแหล่งมาตรฐานและรูปแบบไบนารี นอกจากนี้ การกระจายแหล่งที่มาของไฟล์เดียวจะรวมไลบรารีทั้งหมดเป็นไฟล์ .c และ .h ไฟล์เดียวที่สามารถเพิ่มลงในโปรเจ็กต์ที่มีอยู่ได้อย่างง่ายดาย ตัวอย่างการใช้งานเซิร์ฟเวอร์และไคลเอนต์สามารถพบได้ในไดเร็กทอรี /examples หรือเพิ่มเติมลงในหน้านี้
open62541 ใช้ OPC UA SDK พร้อมการรองรับเซิร์ฟเวอร์ ไคลเอนต์ และการสื่อสาร PubSub (สมัครสมาชิกเผยแพร่) ดูภาพรวมคุณสมบัติเพื่อดูรายละเอียดทั้งหมด
open62541 ได้รับอนุญาตภายใต้ MPLv2 นั่นคือ การเปลี่ยนแปลงไฟล์ภายใต้ MPLv2 จะอยู่ภายใต้ใบอนุญาตโอเพ่นซอร์สเดียวกัน แต่ไลบรารีสามารถใช้ร่วมกับการพัฒนาส่วนตัวจากไฟล์ที่แยกจากกันได้ เช่นกัน หากมีการสร้างไบนารีแบบคงที่ โดยไม่มีใบอนุญาตที่ส่งผลต่อไฟล์ส่วนตัว ดูเอกสารใบอนุญาตฉบับเต็มสำหรับรายละเอียด
Fraunhofer IOSB จ้างนักพัฒนา open62541 หลายคน และให้ การสนับสนุนเชิงพาณิชย์ ผู้ให้บริการเพิ่มเติมในระบบนิเวศ open62541 มีรายชื่ออยู่ใน open62541.org
เซิร์ฟเวอร์ตัวอย่าง (server_ctt) ที่สร้างโดยใช้ open62541 v1.0 สอดคล้องกับโปรไฟล์ 'Micro Embedded Device Server' ของ OPC Foundation ที่สนับสนุนการสื่อสารไคลเอ็นต์/เซิร์ฟเวอร์ OPC UA การสมัครสมาชิก การเรียกเมธอด และการรักษาความปลอดภัย (การเข้ารหัส) ด้วยนโยบายความปลอดภัย 'Basic128Rsa15 ', 'Basic256' และ 'Basic256Sha256' และแง่มุม 'เซิร์ฟเวอร์เมธอด' และ 'การจัดการโหนด' ดู https://open62541.org/certified-sdk สำหรับรายละเอียดเพิ่มเติม
PubSub (UADP) ถูกนำมาใช้ใน open62541 แต่คุณสมบัตินี้ไม่สามารถรับรองได้ในเวลานี้ (กันยายน 2019) เนื่องจากขาดกรณีทดสอบและเครื่องมือทดสอบอย่างเป็นทางการ
ในระหว่างการพัฒนา เครื่องมือทดสอบความสอดคล้อง (CTT) ของ OPC Foundation จะถูกนำไปใช้เป็นประจำ ติดตามการกำหนดค่า CTT และผลลัพธ์ได้ที่ https://github.com/open62541/open62541-ctt โปรไฟล์ OPC UA ที่อยู่ภายใต้การทดสอบปกติใน CTT ในปัจจุบันคือ:
ดูหน้าคุณสมบัติ open62541 เพื่อดูข้อมูลเชิงลึกเกี่ยวกับการสนับสนุนหน่วยความสอดคล้องที่ประกอบขึ้นเป็นโปรไฟล์ OPC UA
ข้อมูลเบื้องต้นทั่วไปเกี่ยวกับ OPC UA และเอกสาร open62541 มีอยู่ที่ http://open62541.org สามารถดาวน์โหลดไลบรารีรุ่นที่ผ่านมาได้ที่ https://github.com/open62541/open62541/releases
ชุมชน open62541 โดยรวมจัดการคำร้องขอการสนับสนุนสาธารณะบน Github และรายชื่อผู้รับจดหมาย สำหรับการสนทนาและการสนับสนุนรายบุคคล ให้ใช้ช่องทางต่อไปนี้:
เราต้องการส่งเสริมชุมชนที่เปิดกว้างและเป็นมิตร โปรดนำจรรยาบรรณของเรามาพิจารณาด้วย
สภาพแวดล้อมการสร้างของ open62541 ถูกสร้างขึ้นผ่าน CMake ดูเอกสารประกอบการสร้างสำหรับรายละเอียด เพื่อทำให้การรวมเข้ากับโปรเจ็กต์ซอฟต์แวร์ที่มีอยู่ง่ายขึ้น ซอร์ส open62541 สามารถบีบอัด (รวมกัน) ให้เป็นไฟล์เดียวซึ่งเป็นไฟล์ open62541.c/.h
คู่หนึ่ง ฟังก์ชันการทำงานที่รวมอยู่ในการแจกจ่ายไฟล์เดียวขึ้นอยู่กับการกำหนดค่า CMake ปัจจุบัน
ซอร์สโค้ดมีโครงสร้างดังนี้:
/include
): API สาธารณะถูกเปิดเผยต่อแอปพลิเคชันที่ใช้ open62541 ส่วนหัวสำหรับการใช้งานปลั๊กอินอยู่ใน /plugins/include
/src
): ไลบรารีหลักไม่มีการขึ้นต่อกันนอกเหนือจากส่วนหัวมาตรฐาน C99/arch
): การสนับสนุนสถาปัตยกรรมถูกนำมาใช้ผ่านปลั๊กอิน EventLoop
ซึ่งจะเก็บโค้ดเฉพาะสถาปัตยกรรม เช่น การใช้ POSIX API ออกจากไลบรารีหลัก มีพอร์ตสำหรับสถาปัตยกรรม (แบบฝัง) ที่แตกต่างกัน/plugins
): อินเทอร์เฟซปลั๊กอินช่วยให้สามารถทำงานร่วมกับระบบแบ็กเอนด์และไลบรารีต่างๆ ได้ ตัวอย่างเช่น เกี่ยวกับ crypto primitive การจัดเก็บข้อมูลโมเดลข้อมูล และอื่นๆ มีการจัดเตรียมการใช้งานเริ่มต้นไว้/deps
): ไลบรารีเพิ่มเติมบางตัวถูกใช้ผ่านโมดูลย่อย git หรือถูกทำให้อยู่ภายในโฟลเดอร์ deps/
ข้อมูลเพิ่มเติมเกี่ยวกับไลบรารีบุคคลที่สามและใบอนุญาตที่เกี่ยวข้องสามารถพบได้ใน deps/README.mdในระบบส่วนใหญ่ open62541 แบบเปลือยต้องใช้ไลบรารีมาตรฐาน C เท่านั้น ขึ้นอยู่กับการกำหนดค่าบิวด์ open62541 ขึ้นอยู่กับไลบรารีเพิ่มเติม เช่น mbedTLS หรือ OpenSSL สำหรับการเข้ารหัส
ในฐานะโครงการโอเพ่นซอร์ส ผู้มีส่วนร่วมรายใหม่ได้รับการสนับสนุนให้ช่วยปรับปรุง open62541 ไฟล์ CONTRIBUTING.md รวบรวมแนวปฏิบัติที่ดีที่เราคาดหวังสำหรับการมีส่วนร่วมในโค้ด ต่อไปนี้เป็นจุดเริ่มต้นที่ดีสำหรับผู้ร่วมให้ข้อมูลรายใหม่:
สำหรับการพัฒนาแบบกำหนดเองที่จะกลายมาเป็นส่วนหนึ่งของไลบรารี open62541 ในที่สุด โปรดเก็บหนึ่งในผู้ดูแลหลักไว้ในลูป
เราเน้นคุณภาพของโค้ด ตัววัดคุณภาพต่อไปนี้ได้รับการตรวจสอบอย่างต่อเนื่องและมั่นใจว่าจะคงไว้ก่อนที่จะมีการเปิดตัวอย่างเป็นทางการ:
โครงการได้กำหนดกระบวนการในการจัดการกับช่องโหว่ ดู SECURITY.md สำหรับรายละเอียดและวิธีการเปิดเผยสิ่งที่ค้นพบต่อผู้ดูแลอย่างมีความรับผิดชอบ
ตัวอย่างโค้ดสามารถพบได้ในไดเร็กทอรี /examples หากต้องการสร้างตัวอย่าง เราขอแนะนำให้ติดตั้ง open62541 ตามที่กล่าวไว้ในส่วนก่อนหน้า การใช้คอมไพเลอร์ GCC เพียงเรียกใช้ gcc -std=c99
(ภายใต้ Windows คุณอาจต้องเพิ่มลิงก์เพิ่มเติมกับไลบรารีซ็อกเก็ต ws2_32
)
#include
int main ( int argc , char * * argv )
{
/* Create a server listening on port 4840 (default) */
UA_Server * server = UA_Server_new ();
/* Add a variable node to the server */
/* 1) Define the variable attributes */
UA_VariableAttributes attr = UA_VariableAttributes_default ;
attr . displayName = UA_LOCALIZEDTEXT ( "en-US" , "the answer" );
UA_Int32 myInteger = 42 ;
UA_Variant_setScalar ( & attr . value , & myInteger , & UA_TYPES [ UA_TYPES_INT32 ]);
/* 2) Define where the node shall be added with which browsename */
UA_NodeId newNodeId = UA_NODEID_STRING ( 1 , "the.answer" );
UA_NodeId parentNodeId = UA_NS0ID ( OBJECTSFOLDER );
UA_NodeId parentReferenceNodeId = UA_NS0ID ( ORGANIZES );
UA_NodeId variableType = UA_NODEID_NULL ; /* take the default variable type */
UA_QualifiedName browseName = UA_QUALIFIEDNAME ( 1 , "the answer" );
/* 3) Add the node */
UA_Server_addVariableNode ( server , newNodeId , parentNodeId ,
parentReferenceNodeId , browseName ,
variableType , attr , NULL , NULL );
/* Run the server (until ctrl-c interrupt) */
UA_StatusCode status = UA_Server_runUntilInterrupt ( server );
/* Clean up */
UA_Server_delete ( server );
return status == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE ;
}
#include
#include
#include
int main ( int argc , char * argv [])
{
/* Create a client and connect */
UA_Client * client = UA_Client_new ();
UA_ClientConfig_setDefault ( UA_Client_getConfig ( client ));
UA_StatusCode status = UA_Client_connect ( client , "opc.tcp://localhost:4840" );
if ( status != UA_STATUSCODE_GOOD ) {
UA_Client_delete ( client );
return status ;
}
/* Read the value attribute of the node. UA_Client_readValueAttribute is a
* wrapper for the raw read service available as UA_Client_Service_read. */
UA_Variant value ; /* Variants can hold scalar values and arrays of any type */
UA_Variant_init ( & value );
status = UA_Client_readValueAttribute ( client , UA_NODEID_STRING ( 1 , "the.answer" ), & value );
if ( status == UA_STATUSCODE_GOOD &&
UA_Variant_hasScalarType ( & value , & UA_TYPES [ UA_TYPES_INT32 ])) {
printf ( "the value is: %in" , * ( UA_Int32 * ) value . data );
}
/* Clean up */
UA_Variant_clear ( & value );
UA_Client_delete ( client ); /* Disconnects the client internally */
return status == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE ;
}