- Jelina 개요
- EMS Builder
- 핵심 기능
표현식 엔진
표현식 엔진은 Edge-EMS Builder의 “계산” 기능의 핵심입니다. 집계 데이터 포인트의 값, 트리거 구성의 판단 조건 및 MQTT 메시지 조립은 모두 표현식 엔진이 스크립트를 실행한 결과입니다. 스크립트 문법은 Lua입니다.
1. 변수 참조 규칙
섹션 제목: “1. 변수 참조 규칙”표현식 스크립트를 실행하기 전에 Edge-EMS Builder는 ${...} 형태의 자리표시자를 실제 데이터 값으로 치환한 후 스크립트 본문을 실행합니다. 다음 표기 방식을 지원하며 조합하여 사용할 수 있습니다.
| 표기 | 설명 | 예 |
|---|---|---|
${dataKey} |
데이터 포인트의 현재 값 참조 | ${PCS1_有功功率} |
${dataKey[-NTimeUnit]} |
N개 시간 단위 이전의 이력 값 참조 | ${PCS1_有功功率[-5s]}은 5초 전의 값 |
${dataKey[#N]} |
최근 이력 샘플부터 역순으로 N번째 값 참조 | ${PCS1_有功功率[#3]}은 최근 값부터 세 번째 값 |
${dataKey[raw]} |
자동 형 변환 없이 원문 그대로 입력합니다. 숫자 1000와 이진수 1000처럼 구별하기 어려운 경우 raw로 원문 주입을 강제합니다. 반드시 마지막에만 배치해야 합니다. |
${设备状态[raw]} |
${[deviceCode]dataKey} |
공유 장치(Share) 데이터 포인트의 최신 값 참조 | ${[DeviceA]PCS1_有功功率} |
| 혼합 사용 | 위 규칙을 자유롭게 조합 가능 | ${[DeviceA]PCS1_有功功率[-1s][#3]} |
누락값: 대상 데이터 포인트에 값이 없으면 엔진은
__Null__문자열을 주입합니다. 명시적으로 비교하거나isNull/isNotNull를 사용할 수 있습니다. 수치 계산 전에tonumber을 사용하고, 이 문자열을or 0에 의존하여 판단하지 마세요.
시간 오프셋에서 지원하는 단위:
| 단위 | 사용 가능한 약칭 |
|---|---|
| 밀리초 | ms / millisecond |
| 초 | s / sec / second / seconds |
| 분 | m / min / minute / minutes |
| 시간 | h / hour / hours |
| 일 | d / day / days |
| 주 | w / week / weeks |
| 월 | M / month |
2. 스크립트 본문: 표준 Lua 문법
섹션 제목: “2. 스크립트 본문: 표준 Lua 문법”자리표시자를 치환한 후 남은 스크립트 본문은 표준 Lua 5.1 문법으로 실행되며, 마지막에 return으로 계산 결과를 반환합니다. 따라서 Lua의 기본 변수, 조건문, 반복문 및 함수 등을 사용할 수 있습니다.
-- 총 피상 전력을 계산합니다(단순화한 예제).local ua, ub, uc = tonumber(${Meter1_Ua}), tonumber(${Meter1_Ub}), tonumber(${Meter1_Uc})local ia, ib, ic = tonumber(${Meter1_Ia}), tonumber(${Meter1_Ib}), tonumber(${Meter1_Ic})if not (ua and ub and uc and ia and ib and ic) then return "__Null__" end
local s = ua * ia + ub * ib + uc * icreturn s3. 내장 함수 및 모듈
섹션 제목: “3. 내장 함수 및 모듈”Edge-EMS Builder는 표준 Lua 문법(기본 string/table/math 라이브러리 포함) 외에도 전역 함수와 require로 불러올 수 있는 모듈을 스크립트 환경에 제공합니다. 데이터 읽기, 쓰기 구조 생성, 문자열/시간/정규식 처리 등 일반적인 요구를 지원하므로 저수준 코드를 작성하지 않고도 복잡한 로직을 구현할 수 있습니다.
| 분류 | 설명 | 예 |
|---|---|---|
| 데이터 읽기(전역 함수) | getLatestDataValue, getHistoryData, getDeviceShareValue 및 접두사/접미사/유사 패턴으로 일괄 조회하는 함수군 |
동일 명명 규칙의 데이터 포인트를 동적으로 검색(트리거 구성의 동적 장치 검색 예제 참조) |
| 쓰기 구조 생성(전역 함수) | buildCommonWriteMap, buildCustomizationWriteMap, buildDailyRepeatWriteMap, buildCommonAlarmMap, buildMqttAlarmMap, buildAlarmObservationMap, buildSlaveWriteMap |
트리거/MQTT 동작에서 통합 실행할 대상 데이터 구조 생성 |
| 시간 변환 | cp56Time2aToOffsetDateTime, offsetDateTimeToCP56Time2a, AB/BA 지원 |
IEC 시간 레지스터 연계 |
| 시간 모듈 | require("OffsetDateTime"), require("LocalTime") |
현재 타임스탬프 가져오기(빈도 제한 판단), 시간 구간 비교 |
| 공통 유틸리티 모듈 | require("Logger"), require("JSON"), require("Regex"), require("String"), require("Math"), require("TableUtils") |
로그 출력, JSON 심층 조작, 정규식, 문자열/숫자/테이블 처리 |
| JSON 변환(전역 함수) | jsonToMap, jsonToList, toJsonString |
외부 시스템과 구조화된 데이터 교환(주로 MQTT 메시지에 사용) |
| HTTP | require("http") |
스크립트에서 HTTP 요청을 직접 보내 외부 인터페이스에 연결하며, 빈도와 제한 시간은 직접 제어해야 함 |
전체 함수 시그니처와 모듈 메서드 목록은 Lua 스크립트 전체 참조, 변수 참조의 상세 규칙은 데이터 변수 파싱 규칙을 참조하세요.
집계 데이터 포인트 표현식의 반환값 규칙:
return단일 값(숫자, 문자열 등)을 해당 집계 포인트의 최신 값으로 사용합니다.buildCommonWriteMap와 같은 쓰기 설명 배열은 여기에서 반환하지 마세요. 이는 트리거 동작, MQTT 동작 등의 반환 형식입니다. Lua 스크립트 전체 참조 · 반환값 규칙을 참조하세요.
4. 설정 예제: 남은 가용 용량 계산
섹션 제목: “4. 설정 예제: 남은 가용 용량 계산”부하 분산 시나리오에서 흔히 사용하는 “남은 가용 전력”을 예로 들겠습니다.
-- 정격 전류 × 전압 = 정격 전력 상한(kW)local rated_kw = tonumber(${Grid_current} or 0) * tonumber(${Grid_voltage} or 0) * 0.001
-- 사용 중인 전력(계통 측에서 실측한 총전력, kW)local used_kw = tonumber(${Grid_total_power} or 0)
-- 10%의 안전 여유를 확보합니다.local avail_kw = (rated_kw - used_kw) * 0.9
return avail_kw이 스크립트를 집계 데이터 포인트 avail_kw의 표현식으로 설정하면 모든 트리거 구성이나 다른 집계 포인트에서 ${avail_kw}로 계산 결과를 직접 참조할 수 있습니다. 계산 로직을 반복해서 작성할 필요가 없으며, 이것이 “로직 재사용”입니다.
5. 시험 계산 기능
섹션 제목: “5. 시험 계산 기능”집계 데이터 포인트 표현식을 추가하거나 변경한 후 저장 전에 시험 계산으로 문법과 계산 결과가 예상과 일치하는지 확인하여 운영 적용 후 스크립트 오류가 발견되는 일을 방지할 수 있습니다.
다음 단계
섹션 제목: “다음 단계”- 전체 내장 함수 시그니처, 모듈 목록 및 추가 예제: Lua 스크립트 전체 참조
- 트리거 구성으로 표현식 계산 결과를 실제 동작으로 전환하는 방법: 트리거 구성