open62541 (http://open62541.org) adalah implementasi open source dari OPC UA (OPC Unified Architecture / IEC 62541) yang ditulis dalam bahasa C. Pustaka ini dapat digunakan dengan semua kompiler utama dan menyediakan alat yang diperlukan untuk mengimplementasikan klien dan server OPC UA khusus, atau untuk mengintegrasikan komunikasi berbasis OPC UA ke dalam aplikasi yang sudah ada. Pustaka open62541 tidak bergantung pada platform: Semua fungsi khusus platform diimplementasikan melalui plugin yang dapat ditukar untuk memudahkan porting ke target yang berbeda (tertanam).
open62541 dilisensikan di bawah Mozilla Public License v2.0 (MPLv2). Hal ini memungkinkan perpustakaan open62541 untuk digabungkan dan didistribusikan dengan perangkat lunak berpemilik apa pun. Hanya perubahan pada perpustakaan open62541 itu sendiri yang perlu dilisensikan di bawah MPLv2 saat disalin dan didistribusikan. Plugin, serta contoh server dan klien berada dalam domain publik (lisensi CC0). Mereka dapat digunakan kembali di bawah lisensi apa pun dan perubahannya tidak harus dipublikasikan.
Perpustakaan tersedia dalam sumber standar dan bentuk biner. Selain itu, distribusi sumber file tunggal menggabungkan seluruh perpustakaan menjadi satu file .c dan .h yang dapat dengan mudah ditambahkan ke proyek yang ada. Contoh implementasi server dan klien dapat ditemukan di direktori /examples atau di bagian bawah halaman ini.
open62541 mengimplementasikan OPC UA SDK dengan dukungan untuk server, klien, dan komunikasi PubSub (terbitkan-berlangganan). Lihat ikhtisar fitur untuk detail selengkapnya.
open62541 dilisensikan di bawah MPLv2. Artinya, perubahan pada file di bawah MPLv2 berada di bawah lisensi sumber terbuka yang sama. Namun perpustakaan dapat digabungkan dengan pengembangan pribadi dari file terpisah, juga jika biner statis dihasilkan, tanpa lisensi mempengaruhi file pribadi. Lihat dokumen lisensi lengkap untuk detailnya.
Fraunhofer IOSB mempekerjakan beberapa pengembang open62541 dan menyediakan dukungan komersial . Penyedia layanan tambahan di ekosistem open62541 terdaftar di open62541.org.
Server sampel (server_ctt) yang dibangun menggunakan open62541 v1.0 sesuai dengan Profil 'Micro Embedded Device Server' dari OPC Foundation yang mendukung komunikasi klien/server OPC UA, langganan, panggilan metode dan keamanan (enkripsi) dengan kebijakan keamanan 'Basic128Rsa15 ', 'Basic256' dan 'Basic256Sha256' serta aspek 'server metode' dan 'node manajemen'. Lihat https://open62541.org/certified-sdk untuk detail lebih lanjut.
PubSub (UADP) diimplementasikan di open62541. Namun fitur tersebut tidak dapat disertifikasi pada saat ini (Sep-2019) karena kurangnya kasus pengujian dan alat pengujian resmi.
Selama pengembangan, Alat Pengujian Kesesuaian (CTT) dari OPC Foundation diterapkan secara berkala. Konfigurasi dan hasil CTT dilacak di https://github.com/open62541/open62541-ctt. Profil OPC UA yang diuji secara rutin di CTT saat ini adalah:
Lihat halaman di fitur open62541 untuk melihat secara mendalam dukungan unit kesesuaian yang membentuk profil OPC UA.
Pengenalan umum tentang OPC UA dan dokumentasi open62541 dapat ditemukan di http://open62541.org. Rilis perpustakaan sebelumnya dapat diunduh di https://github.com/open62541/open62541/releases.
Komunitas open62541 secara keseluruhan menangani permintaan dukungan publik di Github dan milis. Untuk diskusi dan dukungan individu, gunakan saluran berikut:
Kami ingin membina komunitas yang terbuka dan ramah. Harap perhatikan kode etik kami.
Lingkungan build open62541 dihasilkan melalui CMake. Lihat dokumentasi build untuk detailnya. Untuk menyederhanakan integrasi dengan proyek perangkat lunak yang ada, sumber open62541 dapat dikompresi (digabungkan) menjadi distribusi file tunggal, sepasang file open62541.c/.h
. Fungsionalitas yang disertakan dalam distribusi file tunggal bergantung pada konfigurasi CMake saat ini.
Kode sumber disusun sebagai berikut:
/include
): API publik diekspos ke aplikasi yang menggunakan open62541. Header untuk implementasi plugin ada di /plugins/include
./src
): Perpustakaan inti tidak memiliki ketergantungan selain header standar C99./arch
): Dukungan arsitektur diimplementasikan melalui plugin EventLoop
. Hal ini membuat kode khusus arsitektur - misalnya untuk menggunakan API POSIX - keluar dari perpustakaan inti. Port ke arsitektur yang berbeda (tertanam) disediakan./plugins
): Antarmuka plugin memungkinkan integrasi dengan sistem dan perpustakaan backend yang berbeda. Misalnya mengenai kripto primitif, penyimpanan model informasi, dan lain sebagainya. Implementasi default disediakan./deps
): Beberapa perpustakaan tambahan digunakan melalui submodul git atau telah diinternalisasi dalam folder deps/
. Informasi lebih lanjut tentang perpustakaan pihak ketiga dan lisensinya masing-masing dapat ditemukan di deps/README.mdPada sebagian besar sistem, open62541 sederhana hanya memerlukan pustaka standar C. Bergantung pada konfigurasi build, open62541 bergantung pada perpustakaan tambahan, seperti mbedTLS atau OpenSSL untuk enkripsi.
Sebagai proyek sumber terbuka, kontributor baru didorong untuk membantu meningkatkan open62541. File CONTRIBUTING.md mengumpulkan praktik baik yang kami harapkan untuk kontribusi kode. Berikut ini adalah titik awal yang baik bagi kontributor baru:
Untuk pengembangan khusus yang pada akhirnya akan menjadi bagian dari perpustakaan open62541, harap tetap ikuti perkembangan salah satu pengelola inti.
Kami menekankan kualitas kode. Metrik kualitas berikut terus diperiksa dan dipastikan berlaku sebelum rilis resmi dibuat:
Proyek ini telah menetapkan proses untuk menangani kerentanan. Lihat SECURITY.md untuk rincian dan cara mengungkapkan temuan secara bertanggung jawab kepada pengelola.
Contoh kode dapat ditemukan di direktori /examples. Untuk membuat contoh, kami menyarankan untuk menginstal open62541 seperti yang disebutkan di bagian sebelumnya. Dengan menggunakan kompiler GCC, jalankan saja gcc -std=c99
(di Windows Anda mungkin perlu menambahkan tautan tambahan ke perpustakaan soket 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 ;
}