# Simulated

> 하드웨어 없이 시험하고 교육하고 대시보드를 만들기 위한, 애플리케이션 안에서 만들어 내는 신호.

Simulated 드라이버는 장비도 네트워크도 없이 애플리케이션 안에서 신호를 만들어 냅니다. 이것은 임시 방편이 아니라 제 몫을 하는 드라이버입니다. 그 장치는 실제 하드웨어와 정확히 같은 런타임 경로로 등록되고 주기적으로 읽히고 캐시되므로, 그래프와 데이터 형식과 품질 표시와 쓰기 동작이 모두 현장에서와 같이 동작합니다. [Connector](connector) 모델을 시험해 보거나, 장비가 도착하기 전에 대시보드를 만들거나, 시연을 준비할 때 쓰십시오.

## 장치 {#device}

시뮬레이션 장치에는 연결 칸이 없습니다. 이름과 기본 **읽기 주기 (ms)**(기본값 1000)뿐입니다. 기본 URI는 `simulated://<device>`이며, 장치 마디는 알려 주는 뜻만 있습니다. 모든 동작이 태그에 있기 때문입니다.

## 장치 검색 {#discovery}

**장치 검색**은 대상이 필요 없으며 내장 카탈로그를 나열합니다. 원형마다 바로 추가할 수 있는 인스턴스 하나가 태그와 함께 나옵니다. 추가하기 전에 원하지 않는 채널의 체크를 지우십시오.

| 모델 | 인스턴스 | 채널 |
| --- | --- | --- |
| Universal Controller | UC-01 | ProcessValue(사인파), SetPoint(쓸 수 있는 설정값, 기본 50), Output(램프), RunStatus(Run/Stop/Pause/Fault) |
| Electrical Power Meter | PM-01 | Voltage, Current, ActivePower, Frequency(각각 230, 10, 2300, 60 언저리의 랜덤 워크이며 250 ms마다 읽습니다), PowerFactor(사인파) |
| Production Counter | CNT-01 | Count(Int32 카운터), Rate(100 언저리의 랜덤 워크), Running(뒤집히는 부울) |
| Status Panel | STS-01 | State(Run/Stop/Pause/Fault), Alarm(뒤집히는 부울), Uptime(Int64 카운터) |
| Type Showcase | SHOW-01 | OPC UA 기본 형식마다 채널 하나씩 모두 열다섯 개이며, 값 표시를 하나하나 확인할 때 쓸모가 있습니다 |

카탈로그에서 추가한 장치는 뺀 채널을 자기 페이지에서 되찾습니다. 태그 카드 머리의 **태그 검색**은 모델의 채널 중 아직 태그가 없는 것을 나열합니다. 직접 만든 장치는 모델이 없으므로 태그 검색이 없습니다([장치의 태그 검색](connector-discovery#discovering-a-devices-tags) 참고).

## 태그 {#tags}

시뮬레이션 태그에는 입력할 주소가 없습니다. 태그 이름이 곧 그 지점입니다. OPC UA 기본 데이터 형식을 모두 쓸 수 있고 세 가지 접근 방식도 모두 쓸 수 있습니다. 태그가 무엇을 내놓는지는 신호원 카드의 **신호 종류**로 고릅니다. 선택 목록은 태그의 데이터 형식과 맞는 모양만 내놓고, 데이터 형식을 바꾸면 맞지 않게 된 모양이 알맞은 기본값으로 붙습니다. 접근 방식이 쓰기를 허용하는 태그에는 쓰기를 받아들이는 모양, 곧 설정값 유지와 펄스만 나옵니다. 접근 방식을 바꿀 때도 모양이 같은 방식으로 붙습니다.

| 신호 종류 | 내놓는 것 | 맞는 형식 | 쓰기 |
| --- | --- | --- | --- |
| **사인파** | 잔물결이 살짝 있는 매끄러운 파형이며, 태그 이름에서 씨앗을 얻으므로 이름이 다른 태그는 다르게 움직이고 다시 시작해도 같은 곡선이 나옵니다 | 숫자 | 없음 |
| **램프** | 삼각파(올라갔다가 내려옵니다). 주기는 10에서 59 s이며 태그 이름에서 씨앗을 얻습니다 | 숫자 | 없음 |
| **랜덤 워크** | 실제 계기의 잡음처럼 마지막 값에서 한 걸음씩 움직이며 기본값(정하지 않으면 50)으로 되돌아옵니다. 걸음 크기는 중심값의 1%(최소 0.5)입니다 | 숫자 | 없음 |
| **카운터** | 단조롭게 커지는 정수입니다. 기본값(정하지 않으면 0)에서 시작해 읽을 때마다 1을 더하므로, 증가 속도는 읽기 주기를 따릅니다 | 숫자 | 없음 |
| **부울 토글** | 1초마다 번갈아 바뀌는 부울 | 부울 | 없음 |
| **열거 텍스트** | 정해진 상태 목록을 3 s에 한 단계씩 도는 문자열 | 문자열 | 없음 |
| **시계** | 읽을 때마다 샘플로 뜨는 현재 시각 | DateTime | 없음 |
| **임의 GUID** | 읽을 때마다 새로 만드는 무작위 Guid | Guid | 없음 |
| **임의 바이트** | 읽을 때마다 만드는 8바이트 무작위 페이로드 | ByteString | 없음 |
| **설정값 유지** | 쓰기가 들어오기 전까지 기본값을 유지하며, 쓰기가 들어오면 그 뒤의 모든 읽기가 답하는 값이 바뀝니다 | 모든 형식 | 있음 |
| **펄스** | 잠깐 서는 지점입니다. 평소에는 기준값에 머물고, 쓰기가 들어오면 정해 둔 초 동안 쓴 값을 유지한 다음 스스로 돌아옵니다 | 모든 형식 | 있음 |

종류를 밝히지 않고 만든 태그는 살아 있는 기본값을 받습니다. 쓸 수 있는 태그는 **설정값 유지**가 되어 쓰기가 남고, 읽기 전용 태그는 형식에 맞는 생성기를 받습니다(숫자는 사인파, 부울은 부울 토글, 문자열은 열거 텍스트, DateTime은 시계, Guid는 임의 GUID, ByteString은 임의 바이트). **펄스**는 결코 기본값이 되지 않습니다. 쓴 값을 되돌려 주었다가 놓아 버리는 지점은 일부러 고르는 것이기 때문입니다. 예외는 주소에 `default` 값을 밝힌 읽기 전용 태그입니다(예를 들어 `?default=true`). 이 태그도 **설정값 유지**가 되어 그 값을 답합니다. 생성기라면 그 값을 무시하기 때문입니다.

### 패널에 있는 매개변수 {#parameters-in-the-panel}

신호원 카드에서 바로 편집하는 매개변수는 둘입니다.

| 칸 | 나오는 종류 | 뜻 |
| --- | --- | --- |
| **기본값** | 랜덤 워크, 카운터, 설정값 유지 | 걸음의 중심, 카운터의 시작값, 또는 무엇인가 쓰이기 전까지 설정값이 답하는 값입니다. 입력 방식은 태그 형식에 맞춥니다(부울은 확인란, DateTime은 날짜 선택기, 그 밖에는 텍스트). |
| **상태 (세미콜론으로 구분)** | 열거 텍스트 | 돌아가며 쓸 목록을 세미콜론으로 나눠 적습니다. 예를 들어 `Run;Stop;Pause`입니다. 비어 있거나 항목이 없는 목록은 `Run;Stop;Pause`로 되돌아갑니다. |

### 고급 신호 매개변수 {#advanced-signal-parameters}

나머지 모양 매개변수는 태그에 저장된 주소의 질의 인수로 함께 다닙니다(예를 들어 `ProcessValue?min=20&max=80&period=30`). 패널은 이 인수를 편집하지 않지만 어떤 편집에서도 그대로 지키며, 함께 실린 예제가 이것을 쓰고, 에이전트는 [에이전트](agent) 표면의 태그 도구로 이 값을 정할 수 있습니다.

| 인수 | 해당하는 종류 | 뜻 | 없을 때 |
| --- | --- | --- | --- |
| `min`, `max` | 사인파 | 파형이 도는 폭이며, 출력은 이 폭으로 붙습니다 | 태그 이름에서 씨앗을 얻은 폭(20에서 49 사이의 기준선 둘레에 진폭 10에서 49), 경계로 붙이지 않습니다 |
| `period` | 사인파 | 초 단위 파형 주기 | 태그 이름에서 씨앗을 얻은 주파수(0.05에서 0.24 Hz) |
| `phase` | 사인파 | 도 단위 위상차 | 태그 이름에서 씨앗을 얻습니다 |
| `default` | 랜덤 워크, 카운터, 설정값 유지 | 패널의 기본값 칸이 편집하는 그 값 | 50 / 0 / 형식의 기본값 |
| `values` | 열거 텍스트 | 패널의 상태 칸이 편집하는 그 목록 | `Run;Stop;Pause` |
| `baseline` | 펄스 | 두 번의 유지 사이에 지점이 머무는 값이며, 태그의 형식으로 읽습니다 | 형식의 0에 해당하는 값(DateTime은 현재 시각, 문자열은 빈 문자열) |
| `hold` | 펄스 | 쓰기 한 번이 만드는 유지가 몇 초 동안 이어지는지 | 10 s |
| `warmup` | 모든 종류 | 접속한 뒤 첫 읽기가 답하기까지 기다리는 초이며, 안정될 시간이 필요한 계측기와 같습니다. 이 기다림은 주기적 읽기 고리가 흡수합니다 | 없음 |
| `outage` | 모든 종류 | 각 주기의 끝에서 점이 읽기에 실패하는 초이며, 응답을 멈춘 장치와 같습니다. 그 장치의 다른 태그는 계속 답하며, 쓰기도 계속 도착합니다 | 없음 |
| `outageEvery` | 모든 종류 | 중단 주기 하나가 몇 초 동안 이어지는지이며, 접속부터 셉니다. 점은 각 주기의 처음에 답하고 마지막 `outage` 초 동안 실패합니다. 주기만큼 긴 중단은 계속 실패하게 합니다 | 60 s |

`outage`를 쓰면 장비 없이도, 장치가 응답하지 않을 때 태그가 무엇을 하는지 볼 수 있습니다. `?outage=5&outageEvery=30`은 25초 동안 답하고, 5초 동안 읽기에 실패한 뒤, 처음부터 다시 시작합니다. 태그는 [장치가 응답하지 않았습니다](connector-value-pipeline#the-device-did-not-answer)에 설명된 대로 자신이 고른 정책을 적용하고, 실패한 읽기는 선언된 중단을 원인으로 밝힙니다.

## 쓰기 {#writes}

- **설정값 유지**는 쓰기를 받아들이고 그때부터 쓴 값으로 답합니다. 유지하는 값은 장치가 접속해 있는 동안 메모리에 있고 구성에 저장되지 않으므로, 장치를 끄거나 애플리케이션을 다시 시작하면 지점은 기본값으로 돌아갑니다.
- **펄스**는 쓰기를 하나의 유지 구간으로 받아들입니다. 유지 시간이 다할 때까지 쓴 값으로 답한 다음 자기 기준값으로 돌아갑니다. 유지 중에 다시 쓰면 그 구간이 통째로 새로 시작되므로, 단추를 누르고 있어도 두 구간이 쌓이지 않고 유지가 다시 시작됩니다.
- 그 밖의 모든 종류는 쓰기를 거부합니다. 시도한 쓰기는 읽을 때마다 진단 로그를 채우는 대신 태그마다 한 번만 기록됩니다.

다른 드라이버에서와 마찬가지로 쓰기 칸은 공학값을 받으며, 원시값이 신호에 닿기 전에 [값 변환 경로](connector-value-pipeline)가 거꾸로 적용됩니다.

## 알아 둘 만한 한계 {#limits-worth-knowing}

- 값은 실행할 때마다 새로 만들어집니다. 결정적인 모양(사인파, 램프, 시계)은 다시 시작한 뒤에도 같은 곡선을 내놓지만, 상태를 가지는 모양(카운터, 랜덤 워크, 설정값 유지, 펄스)은 처음부터 다시 시작합니다.
- 신호 종류를 맞지 않는 데이터 형식과 짝지으면(패널이 선택 목록을 제한하므로 프로그램으로 구성할 때에만 생길 수 있습니다) 그 태그는 모든 읽기에 실패하고, 경고가 한 번 기록됩니다.
