Hands-on Lab: Simulation → AAS → 예측 알림
이 핸즈온 랩에서는 Caffeine V3의 핵심 기능을 단계별로 실습합니다.
개요
| 단계 | 주제 | 소요 시간 |
|---|---|---|
| 1 | 시뮬레이션 드라이버로 데이터 수집 | 15분 |
| 2 | AAS(Asset Administration Shell) 매핑 | 20분 |
| 3 | 예측 정비 알림 설정 | 15분 |
사전 요구 사항:
- .NET 10 SDK
- Docker Desktop
- IDE (Visual Studio, Rider, 또는 VS Code)
1단계: 환경 준비
Docker Compose 실행
# Caffeine CLI로 docker-compose.yml 생성
cafe docker generate --profile slim
# 인프라 서비스 시작
docker compose up -d
프로젝트 생성
# 튜토리얼용 프로젝트 클론 또는 생성
dotnet new console -n CaffeineLab
cd CaffeineLab
# Caffeine 패키지 추가
dotnet add package NEXCODE.Caffeine.Core --version 3.0.0
dotnet add package NEXCODE.Caffeine.AAS --version 3.0.0
dotnet add package NEXCODE.Caffeine.Infrastructure --version 3.0.0
2단계: 시뮬레이션 드라이버로 데이터 수집
드라이버 설정
using Caffeine.Core.Abstractions.Drivers;
using Caffeine.Core.Domain.Configuration;
// 시뮬레이션 드라이버 설정
var definition = new DriverDefinition
{
Identifier = "SIM-LAB-01",
DriverType = "Simulation",
Options = new Dictionary<string, string>
{
["PollingInterval"] = "1000",
["TagCount"] = "5"
}
};
태그 구독
using System.Reactive.Linq;
// 드라이버 연결
await driver.ConnectAsync();
// Rx 스트림으로 실시간 데이터 수신
driver.TagStream
.Where(t => t.TagName.Contains("Temperature"))
.Buffer(TimeSpan.FromSeconds(5))
.Subscribe(batch =>
{
var avg = batch.Average(t => (double)t.Value);
Console.WriteLine($"[5초 평균 온도] {avg:F1}°C ({batch.Count}개 샘플)");
});
Console.WriteLine("데이터 수집 중... (Ctrl+C로 종료)");
await Task.Delay(Timeout.Infinite);
실행 결과:
[5초 평균 온도] 72.3°C (5개 샘플)
[5초 평균 온도] 73.1°C (5개 샘플)
[5초 평균 온도] 71.8°C (5개 샘플)
3단계: AAS(Asset Administration Shell) 매핑
SemanticId 매핑
using Caffeine.AAS;
using Caffeine.AAS.Mapping;
// 기본 SemanticId 매퍼
var mapper = new DefaultSemanticIdMapper();
// Caffeine 타입 → ECLASS IRDI 변환
var temperatureIrdi = mapper.MapToSemanticId("Temperature");
Console.WriteLine($"Temperature → {temperatureIrdi}");
// 출력: Temperature → 0173-1#02-AAI835#001
// 역방향 변환
var caffeineType = mapper.MapFromSemanticId(IdtaSemanticIds.Pressure);
Console.WriteLine($"{IdtaSemanticIds.Pressure} → {caffeineType}");
// 출력: 0173-1#02-AAE912#007 → Pressure
서브모델 빌드
using Caffeine.AAS.Domain;
using Caffeine.AAS.Mapping;
using Caffeine.Core.Domain.Configuration;
// 태그를 AAS SubmodelElement로 변환
var tag = new TagDefinition("Temp-001")
{
LogicalName = "Temp-001",
DataType = "Float",
Unit = "Celsius",
SemanticType = "Temperature",
PhysicalMin = 0.0,
PhysicalMax = 150.0
};
var element = TagToAasConverter.ToSubmodelElement(tag, mapper);
Console.WriteLine($"IdShort: {element.IdShort}");
Console.WriteLine($"SemanticId: {element.SemanticId}");
Console.WriteLine($"Unit: {element.Unit}");
// IdShort: Temp-001
// SemanticId: 0173-1#02-AAI835#001
// Unit: Celsius
SemanticId 카탈로그 활용
using Caffeine.AAS.Catalog;
var catalog = new SemanticIdCatalog();
// 지원 장비 카테고리 확인
var categories = catalog.GetCategories();
Console.WriteLine($"지원 카테고리: {string.Join(", ", categories)}");
// 지원 카테고리: Pump, Motor, Compressor, HeatExchanger, Conveyor
// 펌프 센서 속성 매핑 조회
var pumpEntries = catalog.GetEntries("Pump");
foreach (var entry in pumpEntries)
{
Console.WriteLine($" {entry.PropertyName} → {entry.SemanticId}");
}
4단계: 예측 알림 파이프라인
이상 감지 + 알림
using System.Reactive.Linq;
// 온도 이상 감지 파이프라인
driver.TagStream
.Where(t => t.TagName.Contains("Temperature"))
.Select(t => (double)t.Value)
.Buffer(10, 1) // 슬라이딩 윈도우 10개
.Select(window => new
{
Avg = window.Average(),
StdDev = Math.Sqrt(window.Average(v => Math.Pow(v - window.Average(), 2))),
Latest = window.Last()
})
.Where(stats => Math.Abs(stats.Latest - stats.Avg) > 2 * stats.StdDev)
.Throttle(TimeSpan.FromSeconds(30)) // 30초 중복 억제
.Subscribe(anomaly =>
{
Console.WriteLine($"[ANOMALY] 온도 이상 감지!");
Console.WriteLine($" 현재: {anomaly.Latest:F1}°C");
Console.WriteLine($" 평균: {anomaly.Avg:F1}°C (표준편차: {anomaly.StdDev:F2})");
});
5단계: 전체 통합
DI 구성 (운영 환경)
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var builder = Host.CreateApplicationBuilder(args);
// Caffeine Core 등록
builder.Services.AddCaffeine();
// AAS 등록
builder.Services.AddCaffeineAas();
// Infrastructure 등록 (Redis, InfluxDB)
builder.Services.AddCaffeineInfrastructure(builder.Configuration);
var app = builder.Build();
await app.RunAsync();
정리
# Docker 서비스 중지
docker compose down
# 데이터 볼륨까지 삭제
docker compose down -v
다음 단계
- 드라이버 개발 가이드 — 커스텀 장비 드라이버 구현
- V3 마이그레이션 가이드 — V2에서 V3로 이전
- Caffeine.Core API — 핵심 API 레퍼런스
- Caffeine.Client API — 클라이언트 SDK
최종 업데이트: 2026-03-20