본문으로 건너뛰기

Predictive Maintenance API

개요​

Predictive Maintenance API는 ML.NET 기반의 예측 정비 기능을 제공합니다. 고장 예측, RUL(잔여 수명) 예측, 이상 탐지, 모델 재학습 및 품질 메트릭 조회를 지원합니다.

기본 정보​

항목값
기본 경로/api/v1.0/predictive-maintenance
인증불필요
버전v1.0

엔드포인트 요약​

메서드경로설명
GET/api/v1.0/predictive-maintenance/failure-prediction/{equipmentId}/{tagId}고장 예측
GET/api/v1.0/predictive-maintenance/rul/{equipmentId}/{componentName}RUL 예측
GET/api/v1.0/predictive-maintenance/anomaly/{tagId}이상 탐지
POST/api/v1.0/predictive-maintenance/retrain/{modelType}모델 재학습
GET/api/v1.0/predictive-maintenance/metrics/{modelType}모델 메트릭 조회
GET/api/v1.0/predictive-maintenance/equipments설비 목록 조회
GET/api/v1.0/predictive-maintenance/equipments/{equipmentId}/tags설비별 태그 목록
GET/api/v1.0/predictive-maintenance/equipments/{equipmentId}/components설비별 부품 목록

상세 엔드포인트​

GET /api/v1.0/predictive-maintenance/failure-prediction/{equipmentId}/{tagId}​

설비의 고장 발생 확률을 예측합니다.

요청

파라미터타입필수설명
equipmentIdstringY설비 ID (경로 파라미터)
tagIdstringY태그 ID (경로 파라미터)

응답

{
"equipmentId": "Equipment-01",
"tagId": "Motor.Current",
"failureProbability": 0.75,
"prediction": "Failure",
"confidence": 0.85,
"predictedAt": "2026-02-09T12:00:00Z",
"features": {
"mean": 85.2,
"stdDev": 12.3,
"trend": "increasing"
}
}

응답 코드

코드설명
200예측 성공
400잘못된 파라미터 (equipmentId 또는 tagId 누락)
500서버 내부 오류 (모델 로드 실패)

GET /api/v1.0/predictive-maintenance/rul/{equipmentId}/{componentName}​

설비 부품의 RUL(Remaining Useful Life, 잔여 수명)을 예측합니다.

요청

파라미터타입필수설명
equipmentIdstringY설비 ID (경로 파라미터)
componentNamestringY부품 이름 (경로 파라미터)

응답

{
"equipmentId": "Equipment-01",
"componentName": "Motor",
"rulDays": 45,
"confidence": 0.78,
"predictedFailureDate": "2026-03-26T00:00:00Z",
"healthScore": 0.60,
"predictedAt": "2026-02-09T12:00:00Z",
"recommendation": "부품 교체 준비 권장"
}

응답 코드

코드설명
200예측 성공
400잘못된 파라미터
500서버 내부 오류

GET /api/v1.0/predictive-maintenance/anomaly/{tagId}​

태그의 이상 탐지를 수행합니다.

요청

파라미터타입필수설명
tagIdstringY태그 ID (경로 파라미터)

응답

{
"tagId": "Motor.Current",
"isAnomaly": true,
"anomalyScore": 0.92,
"threshold": 0.8,
"detectedAt": "2026-02-09T12:00:00Z",
"currentValue": 95.5,
"expectedRange": {
"min": 60.0,
"max": 80.0
},
"severity": "High"
}

응답 코드

코드설명
200탐지 성공
400잘못된 파라미터 (tagId 누락)
500서버 내부 오류

POST /api/v1.0/predictive-maintenance/retrain/{modelType}​

ML 모델을 재학습합니다.

요청

파라미터타입필수설명
modelTypestringY모델 타입 (FailurePrediction, RUL)

응답

{
"success": true,
"modelType": "FailurePrediction",
"version": "v2.1",
"trainedAt": "2026-02-09T12:00:00Z",
"trainingSamples": 5000,
"accuracy": 0.87,
"precision": 0.85,
"recall": 0.89,
"f1Score": 0.87,
"message": "Model trained successfully"
}

응답 코드

코드설명
200학습 성공
400지원하지 않는 모델 타입
500학습 실패 (데이터 부족, 메모리 부족 등)

GET /api/v1.0/predictive-maintenance/metrics/{modelType}​

모델의 품질 메트릭을 조회합니다.

요청

파라미터타입필수설명
modelTypestringY모델 타입 (FailurePrediction, RUL)
versionstringN모델 버전 (기본값: 최신)

응답

{
"modelType": "FailurePrediction",
"version": "v2.1",
"trainedAt": "2026-02-09T12:00:00Z",
"testSampleCount": 1000,
"accuracy": 0.87,
"precision": 0.85,
"recall": 0.89,
"f1Score": 0.87,
"confusionMatrix": {
"truePositive": 450,
"trueNegative": 420,
"falsePositive": 80,
"falseNegative": 50
}
}

응답 코드

코드설명
200조회 성공
400잘못된 파라미터 (modelType 누락)
404모델을 찾을 수 없음
500서버 내부 오류

GET /api/v1.0/predictive-maintenance/equipments​

예측 정비에 사용 가능한 설비 목록을 조회합니다.

요청

파라미터 없음

응답

[
"Equipment-01",
"Equipment-02",
"Equipment-03"
]

응답 코드

코드설명
200성공
500서버 내부 오류

GET /api/v1.0/predictive-maintenance/equipments/{equipmentId}/tags​

특정 설비의 태그 목록을 조회합니다.

요청

파라미터타입필수설명
equipmentIdstringY설비 ID (경로 파라미터)

응답

[
"Motor.Current",
"Motor.Voltage",
"Motor.Temperature",
"Pump.Pressure"
]

응답 코드

코드설명
200성공 (빈 배열도 200 반환)
400잘못된 파라미터 (equipmentId 누락)
500서버 내부 오류

GET /api/v1.0/predictive-maintenance/equipments/{equipmentId}/components​

특정 설비의 부품 목록을 조회합니다 (RUL 예측용).

요청

파라미터타입필수설명
equipmentIdstringY설비 ID (경로 파라미터)

응답

[
"Motor",
"Pump",
"Bearing",
"Valve",
"Sensor"
]

비고: 부품 교체 이력이 없으면 기본 부품 목록을 반환합니다.

응답 코드

코드설명
200성공
400잘못된 파라미터 (equipmentId 누락)
500서버 내부 오류

DTO 정의​

PredictionResult​

속성타입설명
equipmentIdstring설비 ID
tagIdstring태그 ID
failureProbabilitydouble고장 확률 (0.0 ~ 1.0)
predictionstring예측 결과 (Normal, Failure)
confidencedouble신뢰도 (0.0 ~ 1.0)
predictedAtDateTime예측 시각 (UTC)

RulPrediction​

속성타입설명
equipmentIdstring설비 ID
componentNamestring부품 이름
rulDaysint잔여 수명 (일)
confidencedouble신뢰도 (0.0 ~ 1.0)
predictedFailureDateDateTime예상 고장 날짜 (UTC)
healthScoredouble건강 점수 (0.0 ~ 1.0)
predictedAtDateTime예측 시각 (UTC)

AnomalyDetectionResult​

속성타입설명
tagIdstring태그 ID
isAnomalybool이상 여부
anomalyScoredouble이상 점수 (0.0 ~ 1.0)
thresholddouble임계값
detectedAtDateTime탐지 시각 (UTC)

ModelTrainingResult​

속성타입설명
successbool학습 성공 여부
modelTypestring모델 타입
versionstring모델 버전
trainedAtDateTime학습 시각 (UTC)
trainingSamplesint학습 샘플 개수
accuracydouble정확도
messagestring결과 메시지

ModelQualityMetrics​

속성타입설명
modelTypestring모델 타입
versionstring모델 버전
trainedAtDateTime학습 시각 (UTC)
testSampleCountint테스트 샘플 개수
accuracydouble정확도
precisiondouble정밀도
recalldouble재현율
f1ScoredoubleF1 점수

사용 예제​

C# (HttpClient)​

using System.Net.Http.Json;

var client = new HttpClient { BaseAddress = new Uri("https://localhost:5001") };

// 고장 예측
var prediction = await client.GetFromJsonAsync<PredictionResult>(
"/api/v1.0/predictive-maintenance/failure-prediction/Equipment-01/Motor.Current");

Console.WriteLine($"Failure Probability: {prediction.FailureProbability:P}");
Console.WriteLine($"Prediction: {prediction.Prediction}");

// RUL 예측
var rul = await client.GetFromJsonAsync<RulPrediction>(
"/api/v1.0/predictive-maintenance/rul/Equipment-01/Motor");

Console.WriteLine($"RUL: {rul.RulDays} days");
Console.WriteLine($"Predicted Failure Date: {rul.PredictedFailureDate:yyyy-MM-dd}");

// 이상 탐지
var anomaly = await client.GetFromJsonAsync<AnomalyDetectionResult>(
"/api/v1.0/predictive-maintenance/anomaly/Motor.Current");

if (anomaly.IsAnomaly)
{
Console.WriteLine($"Anomaly Detected! Score: {anomaly.AnomalyScore:F2}");
}

// 모델 재학습
var response = await client.PostAsync(
"/api/v1.0/predictive-maintenance/retrain/FailurePrediction", null);

if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadFromJsonAsync<ModelTrainingResult>();
Console.WriteLine($"Model trained: Accuracy = {result.Accuracy:P}");
}

// 모델 메트릭 조회
var metrics = await client.GetFromJsonAsync<ModelQualityMetrics>(
"/api/v1.0/predictive-maintenance/metrics/FailurePrediction?version=v2.1");

Console.WriteLine($"Model: {metrics.ModelType} {metrics.Version}");
Console.WriteLine($"Accuracy: {metrics.Accuracy:P}, F1 Score: {metrics.F1Score:F2}");

curl​

# 고장 예측
curl -X GET "https://localhost:5001/api/v1.0/predictive-maintenance/failure-prediction/Equipment-01/Motor.Current"

# RUL 예측
curl -X GET "https://localhost:5001/api/v1.0/predictive-maintenance/rul/Equipment-01/Motor"

# 이상 탐지
curl -X GET "https://localhost:5001/api/v1.0/predictive-maintenance/anomaly/Motor.Current"

# 모델 재학습
curl -X POST "https://localhost:5001/api/v1.0/predictive-maintenance/retrain/FailurePrediction"

# 모델 메트릭 조회
curl -X GET "https://localhost:5001/api/v1.0/predictive-maintenance/metrics/FailurePrediction"

# 설비 목록
curl -X GET "https://localhost:5001/api/v1.0/predictive-maintenance/equipments"

# 설비별 태그 목록
curl -X GET "https://localhost:5001/api/v1.0/predictive-maintenance/equipments/Equipment-01/tags"

# 설비별 부품 목록
curl -X GET "https://localhost:5001/api/v1.0/predictive-maintenance/equipments/Equipment-01/components"

JavaScript (Fetch)​

// 고장 예측
const prediction = await fetch(
'https://localhost:5001/api/v1.0/predictive-maintenance/failure-prediction/Equipment-01/Motor.Current'
).then(res => res.json());

if (prediction.prediction === 'Failure') {
console.warn(`High failure risk: ${(prediction.failureProbability * 100).toFixed(1)}%`);
}

// RUL 예측
const rul = await fetch(
'https://localhost:5001/api/v1.0/predictive-maintenance/rul/Equipment-01/Motor'
).then(res => res.json());

console.log(`Remaining Life: ${rul.rulDays} days`);
console.log(`Health Score: ${(rul.healthScore * 100).toFixed(1)}%`);

// 모델 재학습
const training = await fetch(
'https://localhost:5001/api/v1.0/predictive-maintenance/retrain/FailurePrediction',
{ method: 'POST' }
).then(res => res.json());

console.log(`Training Result: ${training.message}`);
console.log(`Accuracy: ${(training.accuracy * 100).toFixed(1)}%`);

ML 모델 타입​

모델 타입설명알고리즘
FailurePrediction고장 예측 모델FastTree Binary Classification
RUL잔여 수명 예측 모델FastTree Regression

예측 정비 워크플로우​

주의사항​

  • 모델 재학습은 CPU/메모리 집약적이므로, 피크 시간대를 피해 실행하세요.
  • RUL 예측은 부품 교체 이력 데이터가 충분해야 정확도가 높습니다.
  • 이상 탐지는 정상 패턴 학습이 필요하므로, 최소 7일 이상의 데이터를 권장합니다.
  • 모델 버전은 자동으로 증가하며 (v2.0, v2.1, ...), 최신 버전이 기본값으로 사용됩니다.

모델 저장 경로​

ML 모델은 다음 위치에 저장됩니다:

  • 기본값: {AppDomain.CurrentDomain.BaseDirectory}/models/
  • 파일명 예시: FailurePrediction_v2.1.zip, RUL_v1.5.zip

🆕 v2.1.3 업데이트: 다변량 이상 탐지 (FIR-023)​

IAnomalyDetectionService.DetectMultivariateAnomalyAsync()​

여러 태그의 연관 패턴을 동시에 분석하여 복합 이상을 탐지합니다.

네임스페이스: Caffeine.Core.Abstractions.AI

public interface IAnomalyDetectionService
{
// 기존: 단변량 이상 탐지
Task<AnomalyDetectionResult> DetectAnomalyAsync(string tagId, CancellationToken ct = default);

// v2.1.3 추가: 다변량 이상 탐지
Task<MultivariateAnomalyResult> DetectMultivariateAnomalyAsync(
IReadOnlyList<string> tagIds,
CancellationToken ct = default);
}

MultivariateAnomalyResult DTO​

속성타입설명
IsAnomalybool복합 이상 여부
AnomalyScoredouble복합 이상 점수 (0.0 ~ 1.0)
ContributingTagsIReadOnlyList<string>이상에 기여한 태그 목록
TagScoresIReadOnlyDictionary<string, double>태그별 개별 이상 점수
DetectedAtDateTimeOffset탐지 시각 (UTC)
Severitystring심각도 (Low / Medium / High / Critical)

C# 사용 예제​

// 다변량 이상 탐지: 전류, 전압, 온도 연관 분석
var result = await _anomalyService.DetectMultivariateAnomalyAsync(
new[] { "Motor.Current", "Motor.Voltage", "Motor.Temperature" });

if (result.IsAnomaly)
{
_logger.LogWarning(
"다변량 이상 탐지: Score={Score}, ContributingTags={Tags}",
result.AnomalyScore,
string.Join(", ", result.ContributingTags));

foreach (var (tagId, score) in result.TagScores)
{
_logger.LogDebug(" {TagId}: {Score:F3}", tagId, score);
}
}

관련 API​