AAS 시작하기
Caffeine Framework에서 IEC 63278 AAS 기능을 활성화하고 사용하는 단계별 가이드입니다.
학습 시간: 약 30분
사전 지식: Caffeine 기본 사용법, .NET 기초
사전 요구사항
| 항목 | 최소 버전 | 비고 |
|---|---|---|
| .NET SDK | 10.0 | dotnet --version으로 확인 |
| Caffeine Framework | v3.0.0+ | AAS 모듈 포함 버전 |
| Caffeine Engine | 실행 중 | AAS API 제공 |
Step 1: AAS 모듈 활성화
Caffeine Engine 또는 Admin의 서비스 등록에서 AAS 모듈을 활성화합니다.
// Program.cs
services.AddCaffeineAas()
.AddSubmodelProvider<NameplateSubmodelProvider>()
.AddSubmodelProvider<TechnicalDataSubmodelProvider>()
.AddSubmodelProvider<OperationalDataSubmodelProvider>()
.AddSemanticIdMapper<EclassSemanticIdMapper>()
.WithAasxPackageSupport();
AddCaffeineAas()는 AAS 핵심 서비스(Repository, Serializer, Converter 등)를 일괄 등록합니다. 이후 체이닝으로 서브모델 제공자, SemanticId 매퍼 등을 추가합니다.
AAS 모듈은 선택적(Opt-in)입니다. AddCaffeineAas()를 호출하지 않으면 기존 기능에 전혀 영향을 주지 않습니다.
Step 2: 장비 매니페스트 → AAS 변환
기존 Caffeine 장비 매니페스트(EquipmentManifest)를 AAS Shell로 변환합니다.
// 매니페스트에서 AAS Shell 생성
var converter = serviceProvider.GetRequiredService<IManifestToAasConverter>();
AssetAdministrationShell shell = await converter.ToAasShellAsync(
manifest,
cancellationToken);
// 결과 확인
Console.WriteLine($"AAS ID: {shell.Id}");
Console.WriteLine($"Asset ID: {shell.AssetInformation.GlobalAssetId}");
Console.WriteLine($"서브모델 수: {shell.Submodels.Count}");
IManifestToAasConverter는 매니페스트의 장비 정보(ID, 제조사, 모델명 등)를 AAS Shell의 AssetInformation으로 매핑하고, 태그 정의를 기반으로 서브모델 참조를 자동 생성합니다.
Step 3: 서브모델 빌드
ISubmodelProvider를 사용하여 장비의 특정 측면에 대한 서브모델을 빌드합니다.
// 서브모델 제공자 목록 조회
var providers = serviceProvider.GetRequiredService<IEnumerable<ISubmodelProvider>>();
foreach (var provider in providers)
{
if (provider.CanBuild(manifest))
{
Submodel submodel = await provider.BuildSubmodelAsync(
manifest,
cancellationToken);
Console.WriteLine($"서브모델: {submodel.IdShort}");
Console.WriteLine($" 요소 수: {submodel.SubmodelElements.Count}");
}
}
기본 제공 서브모델 제공자
| 제공자 | IdShort | 빌드 조건 |
|---|---|---|
NameplateSubmodelProvider | Nameplate | 항상 (장비 기본 정보) |
TechnicalDataSubmodelProvider | TechnicalData | 태그 정의에 물리량 정보가 있을 때 |
OperationalDataSubmodelProvider | OperationalData | 실시간 태그가 있을 때 |
Step 4: JSON 직렬화
AAS Shell과 서브모델을 IEC 63278-1 표준 JSON 포맷으로 직렬화합니다.
var serializer = serviceProvider.GetRequiredService<IAasSerializer>();
// AAS Shell → JSON
string shellJson = await serializer.SerializeShellAsync(shell, cancellationToken);
// Submodel → JSON
string submodelJson = await serializer.SerializeSubmodelAsync(submodel, cancellationToken);
// JSON → AAS Shell (역직렬화)
AssetAdministrationShell deserialized = await serializer.DeserializeShellAsync(
shellJson,
cancellationToken);
생성된 JSON은 AASX Server, Eclipse BaSyx, FA3ST 등 다른 AAS 구현체와 호환됩니다.
JSON 출력 예시
{
"idShort": "CVD_Equipment_001",
"id": "urn:caffeine:aas:cvd-001",
"assetInformation": {
"assetKind": "Instance",
"globalAssetId": "urn:caffeine:asset:cvd-001"
},
"submodels": [
{ "type": "ModelReference", "keys": [{ "type": "Submodel", "value": "urn:caffeine:sm:nameplate:cvd-001" }] },
{ "type": "ModelReference", "keys": [{ "type": "Submodel", "value": "urn:caffeine:sm:technical:cvd-001" }] }
]
}
Step 5: REST API로 조회
AAS 모듈이 활성화되면 Caffeine Engine에 AAS REST API가 자동으로 등록됩니다.
AAS 목록 조회
curl -X GET http://localhost:5000/api/v1/aas \
-H "Authorization: Bearer {token}"
응답 (200 OK):
{
"items": [
{
"id": "urn:caffeine:aas:cvd-001",
"idShort": "CVD_Equipment_001",
"assetInformation": {
"assetKind": "Instance",
"globalAssetId": "urn:caffeine:asset:cvd-001"
}
}
],
"totalCount": 1
}
AAS 상세 조회
curl -X GET http://localhost:5000/api/v1/aas/urn:caffeine:aas:cvd-001 \
-H "Authorization: Bearer {token}"
서브모델 조회
curl -X GET http://localhost:5000/api/v1/aas/urn:caffeine:aas:cvd-001/submodels \
-H "Authorization: Bearer {token}"
응답 (200 OK):
{
"items": [
{
"id": "urn:caffeine:sm:nameplate:cvd-001",
"idShort": "Nameplate",
"semanticId": {
"type": "ExternalReference",
"keys": [{ "type": "GlobalReference", "value": "urn:idta:submodel:nameplate:2.0" }]
},
"submodelElements": [
{ "idShort": "ManufacturerName", "valueType": "xs:string", "value": "NEXCODE" },
{ "idShort": "SerialNumber", "valueType": "xs:string", "value": "CVD-2024-001" }
]
}
]
}
Step 6: AASX 파일 Import/Export
AASX는 AAS의 패키지 포맷(OPC UA Part 12 기반)으로, Shell, Submodel, 첨부 파일을 하나의 ZIP 파일로 묶어 교환합니다.
Export (내보내기)
var packageHandler = serviceProvider.GetRequiredService<IAasxPackageHandler>();
await packageHandler.ExportAsync(
shell,
submodels,
outputPath: "/exports/cvd-001.aasx",
cancellationToken);
Import (가져오기)
var (importedShell, importedSubmodels) = await packageHandler.ImportAsync(
filePath: "/imports/external-equipment.aasx",
cancellationToken);
// 가져온 AAS를 Repository에 저장
var repository = serviceProvider.GetRequiredService<IAasRepository>();
await repository.CreateAsync(importedShell, cancellationToken);
AASX Import 시 외부 시스템의 SemanticId가 Caffeine 내부 태그 타입과 자동 매핑됩니다. 매핑할 수 없는 SemanticId는 원본 그대로 보존됩니다.
Step 7: 태그 ↔ AAS 양방향 변환
Caffeine의 태그(Tag) 시스템과 AAS SubmodelElement 간 양방향 변환을 지원합니다.
태그 → AAS 변환
var tagToAas = serviceProvider.GetRequiredService<ITagToAasConverter>();
// 단일 태그 변환
SubmodelElement element = tagToAas.Convert(tagDefinition);
Console.WriteLine($"IdShort: {element.IdShort}");
Console.WriteLine($"SemanticId: {element.SemanticId}");
// 복수 태그 일괄 변환
IReadOnlyList<SubmodelElement> elements = tagToAas.ConvertMany(tagDefinitions);
AAS → 태그 변환
var aasToTag = serviceProvider.GetRequiredService<IAasToTagConverter>();
// SubmodelElement → TagDefinition
TagDefinition tag = aasToTag.Convert(submodelElement);
Console.WriteLine($"태그명: {tag.Name}");
Console.WriteLine($"타입: {tag.DataType}");
이 양방향 변환을 통해 외부 AAS 시스템에서 가져온 장비 정의를 Caffeine 태그로 자동 등록하거나, Caffeine 태그를 AAS 표준으로 내보낼 수 있습니다.
Step 8: SemanticId 매핑
SemanticId는 AAS 데이터 항목에 국제 표준 의미를 부여하는 식별자입니다. Caffeine은 태그 타입에서 SemanticId를 자동 결정합니다.
기본 매퍼 사용
var mapper = serviceProvider.GetRequiredService<ISemanticIdMapper>();
// 태그 타입 → ECLASS IRDI
SemanticId? semanticId = mapper.Map("Temperature");
// 결과: 0173-1#02-AAI835#001
bool canMap = mapper.CanMap("Pressure");
// 결과: true
체이닝 매퍼
여러 매퍼를 체이닝하여 우선순위 기반으로 매핑할 수 있습니다. 첫 번째 매퍼가 매핑할 수 없으면 다음 매퍼로 폴백합니다.
services.AddCaffeineAas()
.AddSemanticIdMapper<CustomSemanticIdMapper>() // 우선순위 1: 프로젝트 전용
.AddSemanticIdMapper<EclassSemanticIdMapper>(); // 우선순위 2: ECLASS 기본
커스텀 매퍼를 구현하려면 ISemanticIdMapper 인터페이스를 구현합니다.
public class CustomSemanticIdMapper : ISemanticIdMapper
{
public SemanticId? Map(string tagType)
{
return tagType switch
{
"GasFlow_N2" => new SemanticId("0173-1#02-CUSTOM001#001"),
"GasFlow_SiH4" => new SemanticId("0173-1#02-CUSTOM002#001"),
_ => null // 매핑할 수 없으면 null → 다음 매퍼로 폴백
};
}
public bool CanMap(string tagType)
=> tagType is "GasFlow_N2" or "GasFlow_SiH4";
}
Step 9: RAG 파이프라인 활성화 (선택)
AAS 문서와 장비 매뉴얼을 AI 기반 RAG(Retrieval-Augmented Generation) 파이프라인으로 검색하고 분석할 수 있습니다.
// RAG 파이프라인 추가 등록
services.AddCaffeineAasRag()
.WithDocumentIngestion()
.WithVectorSearch()
.WithLlmIntegration();
RAG가 활성화되면 다음 기능을 사용할 수 있습니다.
- 문서 인제스트: AAS 서브모델의 Documentation에 첨부된 PDF, 매뉴얼을 벡터 DB에 인덱싱
- 자연어 검색: "CVD 장비의 최대 허용 온도는?"과 같은 자연어 질의
- 조치 가이드: 알람 발생 시 관련 매뉴얼에서 조치 방법 자동 추천
RAG 파이프라인은 별도의 벡터 DB 인프라가 필요합니다. 상세 설정은 RAG 가이드를 참조하세요.
전체 구성 예시
// Program.cs — AAS 전체 기능 활성화
var builder = WebApplication.CreateBuilder(args);
// Caffeine 핵심 서비스 (기존)
builder.Services.AddCaffeineEngine();
// AAS 모듈
builder.Services.AddCaffeineAas()
.AddSubmodelProvider<NameplateSubmodelProvider>()
.AddSubmodelProvider<TechnicalDataSubmodelProvider>()
.AddSubmodelProvider<OperationalDataSubmodelProvider>()
.AddSemanticIdMapper<EclassSemanticIdMapper>()
.WithAasxPackageSupport();
// RAG 파이프라인 (선택)
builder.Services.AddCaffeineAasRag()
.WithDocumentIngestion()
.WithVectorSearch()
.WithLlmIntegration();
var app = builder.Build();
app.MapCaffeineAasEndpoints(); // AAS REST API 엔드포인트 매핑
app.Run();
다음 단계
- AAS 핸즈온 랩 -- 반도체 CVD 장비를 AAS로 모델링하는 실전 튜토리얼
- AAS API 레퍼런스 -- REST/gRPC API 상세 문서
- AAS 개요 -- IEC 63278 표준 상세 설명