수식
변수와 경보 조건 뒤에 있는 하나의 수식 언어, 그것이 참조할 수 있는 것, 포인트마다의 읽기 표면, 평가기가 지키는 규칙, 검사가 내놓는 메시지, 그리고 스크립트 편집기와 찾아보기… 선택기가 동작하는 방식.
하나의 수식 언어가 Logic 페이지의 두 자리를 섬깁니다. 수식 변수가 계산하는 것과 경보가 감시하는 조건입니다. 둘 다 기계에 접근할 수 없는 모래상자 안에서 엄격 모드로 평가되는 JavaScript 수식 하나이고, 둘 다 같은 스크립트 편집기에서 편집합니다. 액션 스크립트는 같은 어휘를 쓰지만 실행문 묶음입니다. 그 차이는 액션에 있습니다.
수식이란 무엇인가
수식은 정확히 하나의 JavaScript 수식입니다. 리터럴, 산술, 비교, 논리 연산자, 조건 연산자 a ? b : c, 문자열 연산, 템플릿 문자열, 그리고 JavaScript 기본 내장인 Math와 Date와 JSON 호출입니다. 실행문(let, if, 반복문)은 액션에 속합니다. 두 번째 실행문은 "변수는 수식 하나를 담습니다. 실행문은 액션에 씁니다."로 거부됩니다. 수식 어디에서든 대입과 ++와 --는 "수식은 읽기 전용입니다. 쓰기는 액션에 씁니다."로 거부됩니다.
수식은 포인트를 뿌리에서 시작하는 주소로 참조합니다. 뿌리마다 수식에 건네주는 것은 이렇습니다.
| 뿌리 | 수식으로 넘어오는 것 |
|---|---|
Connector 태그, Variables, Alarms, Process 유닛의 Channels |
아래의 형식 있는 읽기 표면을 가진 실시간 객체입니다. 그대로 쓴 참조(Connector.Simulated.Pump.Flow 하나만)는 그 포인트의 값으로 평가되고, 그대로 쓴 경보는 자기 IsActive로 평가됩니다. |
System, Server, Assets, 그리고 Process 유닛의 실행 상태와 생산성과 명령과 준비 |
현재 값 그 자체입니다. 숫자이거나 글자이거나 부울이거나 한 시점입니다. 그대로 쓰십시오. 덧붙일 멤버가 없습니다. |
System.Now는 평가하는 그 시점입니다. 한 번의 평가 안에서 그것을 참조하면 모두 같은 시각을 읽습니다. 다른 모든 시각과 마찬가지로 JavaScript Date로 넘어오므로 시점끼리 자연스럽게 비교하고 뺄 수 있습니다. (System.Now - Connector.Simulated.Pump.Run.SourceTimeStamp()) / 1000은 초입니다.
수식 변수는 태그와 내부 값 변수와 경보와 Process 포인트와 Assets 포인트와 System 및 Server 진단을 참조할 수 있지만, 다른 수식 변수는 결코 참조할 수 없습니다. 편집기가 그것을 거부합니다("'Variables.X'은(는) 수식 변수입니다. 수식은 다른 수식 변수를 참조할 수 없습니다. 내부 값 변수나 바탕이 되는 포인트를 참조하십시오."). 그래서 결과가 평가 순서에 기대는 일이 결코 없습니다. 경보 조건은 Alarms.*만 빼고 무엇이든 참조할 수 있고("경보 조건은 다른 경보를 참조할 수 없습니다.") 부울을 내놓아야 합니다.
포인트의 읽기 표면
실시간 태그가 내놓는 것은 이렇습니다.
| 멤버 | 돌려주는 것 | 뜻 |
|---|---|---|
.Value |
형식 있는 값 | 태그의 변환 경로 전체를 지난 공학값 |
.ValueRaw |
형식 있는 값 | 스케일링 전에 태그가 선언한 형식으로 맞춘 원시값 |
.ValueObject |
무엇이든 | 드라이버가 만들어 낸 그대로의 값 |
.ValueScaled, .ValueCalibrated, .ValueLimited, .ValueRounded |
숫자 | 스케일링, 교정, 한계, 소수 자릿수 단계를 지난 값 |
.ValueToBool(), .ValueToInteger(), .ValueToReal(), .ValueToString(), .ValueToDateTime() |
변환된 값 | 그 범주로 변환한 공학값입니다. 값이 없으면 없는 채로 남습니다 |
.State() |
부울 | 품질입니다. 읽기가 정상인 동안 true입니다 |
.SourceTimeStamp() |
Date | 장치가 그 읽기를 만들어 낸 때 |
.ApplicationTimeStamp() |
Date | 내장 서버가 그것을 받은 때 |
.Name, .EngineeringUnit |
글자 | 태그의 이름과 단위 |
변수는 .Value와 다섯 가지 .ValueTo*() 변환과 .State()와 .ApplicationTimeStamp()와 .Name과 .EngineeringUnit을 내놓습니다. 경보는 .IsActive와 .IsAcked와 .CurrentState와 .State()(마지막 주기에서 그 조건을 평가할 수 있었는지)와 .ActiveSince()와 .LastTransitionAt()과 .Name을 내놓습니다. Process 채널은 태그에 묶여 있으면 태그의 표면을, 변수에 묶여 있으면 변수의 표면을 내놓습니다. 묶이지 않은 채널은 아무것도 내놓지 않습니다. 실시간 객체에서 그 밖의 것에는 닿을 수 없습니다. 이 표면 밖의 멤버는 undefined로 읽히고, 그것을 호출하면 검사에서 실패합니다. 찾아보기… 선택기는 포인트마다 바로 이 멤버들을 나열하므로, 어느 것도 외워서 입력할 필요가 없습니다.
평가기가 지키는 규칙
입력하는 동안 편집기에서도, 100 ms 주기마다 다시 한번도 지켜집니다.
- 품질 관문. 평가하기 전에 참조하는 모든 포인트를 풀어내고 새로 읽습니다. 하나라도 없거나 나쁘거나 값을 담고 있지 않으면, 수식을 돌리지 않고 결과가 품질이 나쁜 빈 값이 됩니다. 그래서 오프라인 태그가 표본을 지어내는 일이 결코 없고
null이 엔진에 닿아0이 되는 일도 없습니다. - 유한하지 않은 결과는 빈 값입니다. NaN이나 무한(0으로 나누기, 정의되지 않은 산술)은 결코 표본이 되지 않습니다.
- 폭주 보호. 평가는 250 ms, 실행문 5,000개, 스크립트 메모리 4 MB를 넘기면 중단되고 품질이 나쁜 빈 값으로 셉니다. 엔진은 수식 글자마다 하나씩 지키므로 다른 수식에서 무엇이 새어 나오지 않습니다.
- 형식 맞추기. 성공한 결과는 변수의 출력 형식으로 맞춰집니다. 경보 조건은 부울로 맞춰지고, 변환할 수 없는 결과는 경보의 상태를 그대로 둡니다.
- 오류는 예외가 아니라 빈 값입니다. 주기 중의 실행 오류는 빈 값과 진단 로그 항목을 낳습니다(첫 실패, 되풀이되는 동안의 요약, 회복될 때의 한 줄). 주기는 다음 변수로 이어집니다.
검사가 거부하는 것
편집기는 0.5초마다 초안을 검사하고 값이나 조건 아래에 첫 문제를 보여 줍니다.
| 메시지 | 원인 |
|---|---|
| 수식이 필요합니다. / 조건이 필요합니다. | 편집기가 비어 있습니다. |
| 수식 오류: … | 글자가 해석되지 않습니다. |
| 변수는 수식 하나를 담습니다. 실행문은 액션에 씁니다. | 실행문이 둘 이상이거나, 수식이 아닌 실행문입니다. |
| 수식은 읽기 전용입니다. 쓰기는 액션에 씁니다. | 대입이거나 ++나 --입니다. |
| 주소는 고정이어야 합니다. 'Root'을(를) 계산된 구획으로 접근했습니다. | Variables[name]이거나 리터럴이 아닌 마디입니다. |
| 주소 'Connector.Simulated'이(가) 완전하지 않습니다. | 자기 뿌리 아래에서 포인트를 부르기에 너무 짧은 사슬입니다. |
| 'X'을(를) 찾지 못했습니다. | 주소가 아무것도 가리키지 못합니다. |
| 'X'은(는) 수식 변수입니다. … | 다른 수식 변수를 참조합니다. |
| 경보 조건은 다른 경보를 참조할 수 없습니다. | 조건 안의 Alarms.* 참조입니다. |
| 조건은 Bool로 계산되어야 하는데 'x'이(가) 나왔습니다. | 조건을 시험 평가했더니 부울로 변환되지 않는 값이 나왔습니다. |
| 수식 오류: 실시간 포인트는 여기에서 그대로 쓸 수 없습니다. .Value 멤버로 읽으십시오(예: Connector.Driver.Device.Tag.Value). | 기본값이 필요한 자리에 실시간 객체를 썼습니다(Tag + 1). |
수식 오류: <engine message> |
시험 평가가 예외를 던졌습니다. 알 수 없는 식별자이거나, 막힌 멤버를 함수로 호출했습니다. |
시험 평가는 품질과 무관하게 현재 값으로 돌므로, 메시지는 나쁜 입력이 아니라 수식 자체를 비춥니다. 나쁜 입력은 대신 참조하는 포인트 카드에 나옵니다.
스크립트 편집기
이 페이지의 모든 수식과 조건과 스크립트는 같은 카드에서 편집합니다. 눈썹 문구(수식, 조건, 스크립트), 찾아보기… 단추, 편집기, 안내, 그리고 검사 메시지입니다. 편집기는 JavaScript 강조와 실행 취소 이력을 갖춘 CodeMirror이고, 주소 토큰을 자동으로 완성합니다. 토큰 하나만 있을 때는 뿌리 이름, 그다음에는 지금까지 입력한 경로의 자식, 그리고 토큰이 포인트를 가리키게 되면 멤버까지 내놓습니다(주소 넣기). 글자는 잠깐 모았다가 초안으로 밀어 넣고 자동으로 저장합니다. 수식 상자와 조건 상자의 높이는 최소 56 px이고 액션 스크립트 상자는 160 px입니다. 편집기 엔진이 시작하지 못하면 상자는 강조와 완성과 이력이 없는 평범한 텍스트 영역으로 물러서지만 읽고 쓰는 일은 그대로 됩니다. 그때 찾아보기…는 고른 주소를 커서 자리가 아니라 끝에 덧붙입니다.
찾아보기…는 주소 공간 전체를 멤버 단계까지 담은 트리와 함께 대화 상자를 엽니다("찾아보기: 수식에 삽입"). 행 하나를 고르고 삽입을 누르거나 그 행을 두 번 누르면 커서 자리에 그 주소가 놓입니다. 편집기마다 자기 대화 상자를 가지므로, 한 페이지의 편집기 둘이 선택을 함께 쓰는 일은 없습니다.
수식이 하지 않는 일
수식은 아무것도 쓰지 않고, Process 실행 명령을 부르지 않으며, 평가와 평가 사이에 상태를 남기지 않고, 여러 수식이 함께 쓰는 함수를 정의할 수 없으며, 요청할 때 평가되지도 않습니다. 주기가 100 ms마다 그것을 공개하고, 편집기는 1초에 두 번 초안을 미리 보여 줍니다.