값 변환 경로
모든 태그가 함께 쓰는 형식별 변환, 원시 읽기에서 공학값까지, 잘못된 읽기에 대한 두 정책, 범위를 벗어난 값에 대한 동작, 부울과 문자열 변환, 그리고 쓰기가 각 단계를 되돌리는 방식.
모든 태그는 원시 읽기를 공학값으로 바꾸는 하나의 형식별 변환 경로를 함께 씁니다. 이 경로는 태그 자신 안에 있습니다. 태그 페이지의 변환 카드와 장치 표는 같은 단계를 보여 주며, Logic과 대시보드와 기록기와 스테이션이 게시하는 곳에 닿는 값은 마지막 단계를 빠져나온 그 값입니다. 공개 OPC UA 노드는 원시값을 담습니다.
원시값이 먼저
변환 경로는 드라이버 자신의 객체가 아니라 태그의 데이터 형식으로 맞춘 원시값에서 시작합니다. Int32 태그에 3.7을 건네는 드라이버는 카드 맨 위에서 4로 읽히고, 모든 단계는 그 4에서 이어집니다. 선언한 형식이 아예 담을 수 없는 읽기(숫자를 선언한 자리에 온 텍스트)는 빈 읽기이며, 결코 0이라는 대체값이 되지 않습니다. 단계는 실수로 계산하며, 반대편 끝에서 공학값은 자신의 형식을 가집니다.
| 태그 | 공학값 |
|---|---|
| 정수 데이터 형식이고, 스케일링과 교정이 꺼져 있거나 기울기 1, 절편 0으로 켜져 있음(모든 태그가 만들어질 때의 상태) | 정수 그 자체이며, 태그의 데이터 형식 그대로입니다. |
| 정수 데이터 형식이고, 스케일링이나 교정이 값을 바꿈 | 실수(Double)이며, 소수 자릿수 단계가 반올림합니다. 온도에 10을 곱해 담는 Int16 태그는 장치에서 235로, 스케일링이 0.1이면 23.5로 읽힙니다. |
| Float 또는 Double | 태그의 데이터 형식이므로, Float 태그는 float가 나타낼 수 있는 값으로 반올림됩니다. |
데이터 형식은 장치와 공개 OPC UA 노드가 담는 형식 그대로입니다. 스케일링이나 교정을 켜거나 끄면 그 순간부터 공학값의 형식이 바뀝니다. 기록기가 이미 기록한 값은 기록된 그대로 남고, 채널은 자신이 선언한 형식을 유지하므로, 정수 채널은 가장 가까운 정수로 반올림한 값을 기록하고 실수 채널은 소수를 유지합니다. 변환 카드는 내보내는 값으로 끝나며, 스케일링과 교정이 값을 그대로 두는 정수 형식이 한계 단계가 값을 붙이는 경계의 소수를 반올림해 버릴 때 그렇다고 알려 줍니다.
단계
숫자 형식에서 변환 경로는 각자 확인란을 가진 단계의 사슬입니다. 꺼진 단계는 입력을 그대로 통과시키며, 카드는 매 단계 끝의 값을 보여 주므로 살아 있는 읽기가 계산을 따라가는 모습을 볼 수 있습니다.
| 단계 | 기본값 | 하는 일 |
|---|---|---|
| 스케일링 | 켜짐 | scaled = raw × Angular + Linear. 기울기의 기본값은 1, 절편의 기본값은 0입니다. 기울기 0은 입력하는 그 자리에서 거부됩니다("스케일링 계수를 0으로 두면 모든 읽은 값이 0이 됩니다. 곱할 계수를 입력하십시오(1은 값을 그대로 둡니다)."). 모든 읽기를 0으로 만들 뿐 아니라, 미리 보기와 저장되는 변환 경로가 서로 어긋나서는 안 되기 때문입니다. |
| 교정 | 꺼짐 | 스케일링을 거친 값에 적용하는 두 번째 선형 짝입니다. calibrated = scaled × Angular + Linear. 교정 전과 교정 후의 보정이 범위 계산을 흔들지 않도록 스케일링과 분리되어 있고, 자기 권한으로 지켜집니다. 교정을 보십시오. 기울기 0은 같은 방식으로 거부됩니다. |
| 올바르지 않은 읽기 | 언제나 나옵니다 | 쓸 수 있는 숫자를 담지 못한 읽기에 대한 두 정책입니다(아래 참조). 확인란이 아니며, 그 "끔"도 답 가운데 하나입니다. |
| 한계 | 꺼짐 | 값을 최소(기본값 0)와 최대(기본값 100)에 견주어 판단하고, 고른 범위 초과 동작을 적용합니다(아래 참조). 경계는 정규화되므로 최소가 최대보다 커도 결코 실패하지 않습니다. 둘 가운데 작은 쪽이 아래 경계가 됩니다. |
| 소수 자릿수 | 켜짐 | 소수 자릿수만큼 반올림합니다. 기본값은 2이고 0에서 15까지 받습니다. |
두 선형 단계에는 기준점 둘로 짝을 계산하는 2점 보정 도우미가 있습니다. 교정에서 단계별로 설명합니다.
장치가 숫자가 아닌 것으로 응답했습니다
열린 열전대, 센서가 없는 채널이 그런 경우입니다. 읽기는 도착했고 장비는 말을 하고 있지만 측정값이 NaN입니다. 숫자 태그에만 해당하며, 어느 쪽을 고르든 품질은 정상으로 남습니다.
| 정책 | 효과 |
|---|---|
| 그대로 통과(기본값) | NaN이 손대지 않은 채 그대로 지나가고, 그 단계가 어떤 동작을 지녔든 한계 단계를 통째로 건너뜁니다. 한계는 숫자를 판단하는데 여기에는 숫자가 없기 때문입니다. 무한대는 NaN이 아니므로 범위에서 여전히 포화됩니다. |
| 다른 값으로 대체 | 선언한 숫자가 이 단계부터 대신 서며, 다른 읽기와 마찬가지로 한계와 소수 자릿수와 마지막 형식 맞춤을 거칩니다. |
장치가 응답하지 않았습니다
시간 초과, 끊어진 케이블, 꺼진 장비, 드라이버 예외가 그런 경우입니다. 모든 형식에 해당하지만, 문자열이나 시각이나 식별자나 바이트 덩어리를 읽는 태그에는 앞의 두 정책만 제시됩니다. 선언한 대체값은 숫자이고, 그런 형식의 읽기는 숫자가 아니기 때문입니다.
| 정책 | 효과 |
|---|---|
| 오류 표시(기본값) | 태그가 비어 있는 값으로 읽히고 품질이 나빠지므로, 실패가 모든 곳에 한꺼번에 드러납니다. |
| 마지막 정상 값 유지 | 마지막으로 도착한 읽기가 만료 없이 화면에 남아, 장비가 다시 답할 때까지 유지됩니다. 시각은 그 읽기를 계속 가리키는데, 숫자가 측정된 때가 그때이기 때문입니다. 첫 읽기가 도착하기 전에는 아무것도 유지되지 않으며, 그때 태그는 비어 있는 값으로 읽힙니다. |
| 다른 값으로 대체 | 선언한 숫자가 선언한 그대로 제시됩니다. 단계를 거쳐 갈 읽기가 없으므로 스케일링도 교정도 반올림도 하지 않고, 공학값의 형식으로 맞추기만 합니다. 읽기가 숫자에서 나올 수 있는 숫자 형식과 부울에 제시되며, String, DateTime, Guid, ByteString에는 제시되지 않습니다. |
대체값은 결코 조용히 서 있지 않습니다. 실시간 값 카드가 이유를 적고("마지막 정상 값이며, 장치가 응답하지 않는 동안 유지됩니다."), 실시간 점이 호박색으로 바뀌며, 내장 OPC UA 서버는 그 값을 그냥 Good이 아니라 대체 상태와 함께 공개하고, tag_read로 태그를 읽는 에이전트는 그것이 어떤 대체값인지 듣습니다(substitution). 정책이 요구하는 동안에는 계속 그렇게 공개됩니다. 계속 답하지 않는 장치 때문에 외부 클라이언트가 대체값과 읽기 실패 사이를 오가는 일은 없으므로, 그 클라이언트가 읽는 것은 패널이 보여 주는 것과 같습니다. 장치가 답하는 순간 읽기 자신이 그 지점을 되찾으며, 대체값을 끌 때도 마찬가지입니다. 대체값을 고르는 것은 가용성을 고르는 것이므로, 경보와 수식은 그 지점에 값이 있는 것처럼 계속 판단합니다. 그 대가는 드러난 자리에서 치릅니다. 진단 로그는 실패한 읽기를 그대로 기록하고, 장치 상태 건전성은 그 장치를 여전히 오프라인으로 보고하기 때문입니다. 대체값은 "이 지점이 무엇을 보여야 하는가"에 답할 뿐, "장비가 거기 있는가"에는 결코 답하지 않습니다. 켜진 한계를 벗어난 대체값은 입력하는 그 자리에서 경고를 받습니다. "한계(0에서 100까지)를 벗어납니다: 읽기가 실패했을 때 대신 쓰는 값입니다."
끊긴 읽기는 실패한 읽기로 셉니다. 장치가 연결을 받아들인 뒤 응답을 멈춘 경우처럼 태그의 읽기 주기에 10초를 더한 시간 동안 새 읽기가 들어오지 않으면, 위의 정책이 읽기가 실패한 것과 똑같이 태그를 읽는 모든 곳에 적용됩니다. Logic 수식, 대시보드, 기록되는 값, 에이전트가 그렇습니다. 오류 표시에서는 태그가 비어 있는 값으로 읽히고 품질이 나빠지며, 내장 OPC UA 서버는 노드에 장치의 마지막 값을 Good 대신 UncertainLastUsableValue로 유지하므로, 외부 클라이언트는 가지고 있던 숫자와 그것을 더 이상 새로 고치는 것이 없다는 사실을 함께 봅니다. 대체값이 있으면 그 대체값이 위와 같이 제시되고 공개됩니다. 품질이 나쁜 동안 경보는 언제나처럼 상태를 유지합니다. 실시간 값 카드가 이유를 적고("애플리케이션 시각 뒤로 새 읽기가 들어오지 않았습니다. 태그는 이를 실패한 읽기로 봅니다."), 시각은 마지막으로 들어온 읽기를 계속 가리키며, 다음에 들어오는 읽기가 태그를 되돌립니다.
쓰기 전용 태그에는 이 정책 가운데 어느 것도 없습니다. 스테이션이 결코 읽지 않으므로 실패할 읽기가 없습니다. 스테이션이 쓰기 전까지 태그는 값이 없으며, 값이 없다는 것을 그대로 보여 줍니다. 대체값도, 호박색 점도 없고, 그 자리에 OPC UA로 공개되는 것도 없으며, 패널도 이 태그에는 이 줄을 그리지 않습니다. 태그를 읽던 동안 고른 정책은 저장된 채로 남아 태그가 쓰기 전용인 동안에는 무시되고, 접근이 읽기 전용이나 읽기와 쓰기로 돌아오면 곧바로 다시 적용됩니다.
범위를 벗어난 값
최소와 최대를 벗어난 값에 대한 한계 동작입니다.
| 동작 | 값이 되는 것 | 품질 |
|---|---|---|
| 널 | 빈칸(값 없음). | 정상 |
| 한계로 자름(기본값) | 가장 가까운 경계. | 정상 |
| 오류와 널 | 빈칸. | 나쁨(한계 결함) |
| 오류와 한계로 자름 | 가장 가까운 경계. | 나쁨(한계 결함) |
| NaN | NaN. | 정상. NaN을 나타낼 수 있는 형식인 Float과 Double 태그에만 제시되며, Process 채널이 그 잘못된 값을 분류할 수 있게 합니다. 에이전트의 쓰기나 복원한 백업이 정수 태그에 남긴 NaN 동작은 Null 빈칸으로 낮아집니다. |
한계 결함은 태그의 실질 품질에 섞여 들어가므로, 실시간 점과 속성 수식과 경보가 별도 연결 없이 모두 그 한계 초과 값을 나쁨으로 봅니다. 변환 카드에는 "값 130은(는) 한계(0에서 100까지)를 벗어납니다."가 적힙니다. 그래도 이것은 연결 문제가 아니라 공정의 상태이므로, 장치 상태 건전성은 이 때문에 장치를 오프라인으로 세지 않습니다.
부울, 문자열, 그 밖의 형식
숫자가 아닌 형식에는 같은 변환 카드 안에 자기 변환이 있습니다.
- 부울: 반전은 원시값의 논리적 부정을 보고합니다.
- 문자열: 부분 문자열 시작(0부터)과 길이 (비우면 끝까지)가 원시 문자열에서 한 구간을 잘라 냅니다. 길이를 비우면 끝까지 가고, 범위를 벗어난 경계는 실패하는 대신 경계로 붙습니다.
- 그 밖의 모든 형식(DateTime, Guid, ByteString)은 그대로 통과합니다. 그 변환 카드에는 올바르지 않은 읽기 단계만 있어, 장치가 응답하지 않았을 때의 정책을 고릅니다. 쓰기 전용 태그라면 카드가 나오지 않습니다.
오류 표시와 마지막 정상 값 유지는 모든 형식에 적용되고, 값으로 대체는 숫자 태그와 부울 태그에만 제시되므로 String, DateTime, Guid, ByteString 태그에는 나열되지 않습니다. 이런 형식의 태그에 예전 버전이 저장할 수 있었던 대로 대체가 이미 저장되어 있으면 오류 표시로 따르며, 다음에 그 태그를 저장할 때(패널에서든 에이전트에서든) 그 자리에 오류 표시가 저장됩니다. NaN 정책은 숫자 태그에만 적용됩니다.
쓰기는 변환 경로를 되돌립니다
실시간 값 카드의 쓰기 칸은 공학값을 받아, 켜져 있고 되돌릴 수 있는 단계를 순서대로 되돌립니다. 한계가 켜져 있으면 최소와 최대로 붙이고(한계 동작이 무엇이든 쓰기는 언제나 경계에 붙이지 결코 버리지 않습니다), 교정을 되돌리고((value − Linear) ÷ Angular), 같은 방식으로 스케일링을 되돌린 다음, 태그의 형식으로 맞춥니다. 스케일링이나 교정이 값을 바꾸는 정수 태그는 소수를 받습니다. 스케일링이 0.1인 Int16 태그에 123.4를 쓰면 1234가 쓰입니다. 스케일링도 교정도 없는 정수 태그에 소수를 쓰면 가장 가까운 정수로 반올림되며, 절반은 0에서 먼 쪽으로 갑니다(2.5는 3이 쓰입니다). 반올림은 잃는 연산이므로 되돌리지 않습니다. 부울 입력에는 반전이 다시 적용됩니다. 문자열 부분 추출은 표시만을 위한 것이므로, 문자열 쓰기는 값 전체를 그대로 보냅니다. DateTime, Guid, ByteString은 그대로 통과합니다. 외부 OPC UA 클라이언트가 공개 노드에 쓴 값은 이미 원시값이므로 이 가운데 어느 것도 거치지 않습니다.