| OPC UA NodeId | 데이터 유형 | AAS 경로 | semanticId (IRDI) | 단위 |
|---|---|---|---|---|
| ns=2;s=AR-S513.AssemblyForce | Float | AR01/OperationalData/AssemblyForce | 0173-1#02-AAI648#001 | A |
| ns=2;s=AR-S513.AssemblyVoltage | Float | AR01/OperationalData/AssemblyVoltage | 0173-1#02-AAI649#001 | V |
| ns=2;s=AR-S513.ArcTime | Float | AR01/OperationalData/ArcTime | 0173-1#02-AAI651#001 | s |
| ns=2;s=AR-S513.MotorTemp | Float | AR01/OperationalData/MotorTemperature | 0173-1#02-AAI652#001 | °C |
| ns=2;s=AR-S513.CycleCount | Int32 | AR01/OperationalData/CycleCount | 0173-1#02-AAI655#001 | count |
| ns=2;s=AR-S513.Status | String | AR01/OperationalData/Status | 0173-1#02-AAI660#001 | enum |
import asyncio from asyncua import Client, ua import aiohttp OPCUA_URL = "opc.tcp://plc-142:4840/freeopcua/server/" AAS_URL = "http://localhost:8081" AAS_ID = "dXJuOmZhY3Rvcnk..." # base64(AAS id) SM_ID = "dXJuOmZhY3Rvcnk..." # base64(Submodel id) MAPPING = { "ns=2;s=AR-S513.AssemblyForce": "AssemblyForce", "ns=2;s=AR-S513.AssemblyVoltage": "AssemblyVoltage", "ns=2;s=AR-S513.MotorTemp": "MotorTemperature", } async def sync_to_aas(prop_name, value): url = (f"{AAS_URL}/shells/{AAS_ID}" f"/submodels/{SM_ID}" f"/submodel-elements/{prop_name}/$value") async with aiohttp.ClientSession as s: await s.patch(url, json=str(value)) async def main: async with Client(OPCUA_URL) as client: handles = [] sub = await client.create_subscription( 500, lambda node, val, data: asyncio.create_task( sync_to_aas(MAPPING[node.nodeid], val) ) ) for nodeid in MAPPING: node = client.get_node(nodeid) h = await sub.subscribe_data_change(node) handles.append(h) await asyncio.sleep(float("inf")) # 영구 실행 asyncio.run(main)
# BaSyx OPC UA Connector 설정 (YAML)
aas: id: "urn:factory142:aas:AR01"
opcua: serverUrl: "opc.tcp://plc-142:4840/"
mapping: - nodeId: "ns=2;s=AR-S513.AssemblyForce" submodelId: "urn:aas-edu:sm:OperationalData" idShortPath: "AssemblyForce" updateRate: 500ms - nodeId: "ns=2;s=AR-S513.AssemblyVoltage" submodelId: "urn:aas-edu:sm:OperationalData" idShortPath: "AssemblyVoltage" updateRate: 500msasyncua 라이브러리로 OPC UA 구독 → DemoServer REST API PUT 방식. 의존성 최소, 유연한 변환 로직 구현 가능.
DemoServer 대신 BaSyx로 교체 후 공식 Connector 사용. 안정성 높지만 설정 복잡도 증가.
node-red-contrib-opcua → node-red-contrib-aas 노드 체인. 비개발자도 GUI로 플로우 구성 가능.