콘텐츠로 이동
무료 평가 시작

이력 접근

OPC UA 서버는 변수 값과 이벤트의 이력을 저장하고, 클라이언트가 지난 기간의 값을 읽게 할 수 있습니다. HistoryRead 서비스는 Part 4 5.10.3절, 이력 읽기의 세부 규칙은 Part 11(Historical Access)에서 정의합니다.

변수가 이력을 제공하는지는 두 속성으로 확인합니다.

  • Historizing(속성 20): 서버가 지금 이 변수의 이력을 저장하는지 여부입니다.
  • AccessLevel(속성 17)의 HistoryRead 비트(0x04): 이력을 읽을 수 있는지 여부입니다.

PDComm 시뮬레이터는 Simulator.Double과 Simulator.Counter의 이력을 저장합니다. Simulator.Double은 값을 쓸 때마다, Simulator.Counter는 시뮬레이션 주기(기본 500 ms)마다 기록합니다. 서버를 시작할 때의 초기값도 한 번 기록합니다.

HistoryRead 요청에는 읽는 방식을 정하는 세부 정보(HistoryReadDetails)와 노드 목록이 들어갑니다.

세부 정보 용도
ReadRawModifiedDetails 저장된 원래 값(raw)을 기간으로 읽습니다.
ReadProcessedDetails 집계(aggregate) 함수로 계산한 값을 읽습니다. 집계는 Part 13에서 정의합니다.
ReadAtTimeDetails 지정한 시각의 값을 읽습니다.
ReadEventDetails 이벤트 이력을 읽습니다.

가장 많이 쓰는 ReadRawModifiedDetails의 필드는 다음과 같습니다.

필드 의미
startTime, endTime 읽을 기간
numValuesPerNode 응답 하나에 담을 노드당 최대 값 개수. 0이면 제한이 없습니다.
returnBounds 기간 경계의 값을 함께 돌려줄지 여부
isReadModified 원래 값 대신 수정 이력을 읽을지 여부

요청의 timestampsToReturn은 결과 DataValue에 어떤 시각을 넣을지 정합니다(Source, Server, Both, Neither).

기간 안의 값이 numValuesPerNode보다 많으면 서버는 값 일부와 연속 지점(continuation point)을 돌려줍니다. 나머지는 연속 지점을 넣어 HistoryRead를 다시 호출해 받습니다.

HistoryRead(start, end, numValuesPerNode=2) -> values 1..2, continuation point A
HistoryRead(same details, continuation point A) -> values 3..4, no continuation point
HistoryRead(same details, point B, releaseContinuationPoints) -> point B released, no values
  • 연속 지점은 처음 요청과 같은 세부 정보로 이어 받아야 합니다. PDComm 서버는 세부 정보가 다르면 BadContinuationPointInvalid를 돌려줍니다.
  • 나머지 값이 필요 없으면 releaseContinuationPoints를 참으로 설정해 연속 지점을 해제합니다. 연속 지점은 서버 자원입니다.
  • 한 번 쓴 연속 지점은 다시 쓸 수 없습니다.
상태 의미
Good(0x00000000) 값을 읽었습니다.
GoodNoData(0x00A50000) 기간 안에 값이 없습니다.
BadContinuationPointInvalid(0x804A0000) 연속 지점을 모르거나 세부 정보가 처음과 다릅니다.
BadHistoryOperationUnsupported(0x80720000) 서버가 요청한 이력 작업을 지원하지 않습니다.

이력 값의 StatusCode 하위 비트에는 이력 정보 비트(historian bits)가 있습니다. 예를 들어 0x00000408은 Good이면서 같은 시각에 값이 더 있음(HistorianExtraData)을 뜻합니다. 시뮬레이터에서 서버 시작 직후 같은 밀리초에 두 값이 기록된 Simulator.Counter의 첫 값이 이렇게 표시됩니다.

PDComm 서버는 있는 노드라도 이력을 저장하지 않으면(AccessLevel에 HistoryRead 비트가 없으면) BadHistoryOperationUnsupported를, 없는 노드에는 BadNodeIdUnknown을 돌려줍니다. 이력을 저장하는 노드라도 기간 안에 값이 없으면 GoodNoData입니다.

SDK. 클라이언트는 HistoryReadRequest(i=664)를 UA Binary로 만들어 pdcomm_opcua_client_begin으로 보냅니다. SDK 메모리 서버는 이력을 저장하지 않습니다.

시뮬레이터. history_read 동작이 ReadRawModifiedDetails로 Source 시각을 요청합니다.

인자 기본값
node ns=2;s=Simulator.Double
start, end 지금부터 1시간 전, 1분 뒤(Unix 밀리초)
max 100(numValuesPerNode, 1~1000)
continuation 연속 지점(16진수). 지정하면 앞 요청의 start, end, max를 다시 씁니다.
release true면 연속 지점을 해제합니다.

이력 튜토리얼에서 실행합니다.

PubSub에서 연결 없이 데이터를 전달하는 모델을 살펴봅니다.