Синтаксис формул, интерпретация null значений и функций

Содержание:



Читайте дополнительно:

За полным списком применяемых операторов обращайтесь службу поддержки help@1sim.ru


В системе АТМ формула вычисляемого параметра или возникновения события/аварии является математическим выражением в привычном понимании этого слова. В формуле допускаются арифметические и булевы операторы, скобки произвольной вложенности и функции. Допускается любое количество пробелов вокруг операторов, скобок и запятых. Исключения — не допускаются пробелы после имени функции и перед ее открывающей скобкой, например, в выражении abs(dM). Так же не допускаются пробелы внутри описания параметров, например, в выражении plc123.n2.integ(M1) пробелы не допускаются нигде.

Операндами являются вещественные константы и другие параметры с соблюдением формата написания. Так же для удобства введены константы «true» (равняется 1), «false» (равняется 0), «null» (равняется null). При задании числовых констант допускается шестнадцатеричная запись (удобно при работе с побитовыми операциями), например «0xFF«.

Следует отличать null от 0 (число ноль). Число 0 является чётким конкретным нулевым значением. В то время как null отражает неизвестность значения. Как правило, null при вычислений формул возникает вследствие ссылки на устаревший параметр, но может возникнуть и по причине отсутствия данных в самом устройстве, о чём устройство явно сообщает во время сеанса связи.

Смысл null значений — их неизвестность. Если к неизвестности прибавить 1, то мы снова получим неизвестность. Т.е. null плюс что угодно тоже будет null. Все базовые арифметические операции (+, -, *, /) возвращают null, если хотя бы один из их операндов равняется null. Таким образом, параметр dt = t1 — t2 будет принимать значение null, пока t1 или t2 равны null (то есть устарели). Только когда и t1, и t2 примут какое-то конкретное значение (с учетом их 2х-часового устаревания), параметр dt примет значение их разности.


Описание операторов «Редактора формул»


Арифметические операторы

+, -, *, /

Если любой из операндов null, результат будет null. Деление на ноль так же вернет null. Плюс и минус могут быть как бинарными (к примеру, t1+t2), так и унарными (к примеру, +Q или -M1).

Операторы сравнения

<, <=, >, >=,
=, ==, <>, !=

= и == означают проверку на равенство.
<> и != означают проверку на неравенство.
Если любой из операндов null, результат будет null. В частности, code = null или code <> null всегда вернут null, чему бы ни равнялся code.
Операторы сравнения делают поправку на приближенность арифметики с плавающей точкой, используемой в приборах и на сервере. Поправка заключается в том, что значения, находящиеся в пределах 10-8 друг от друга, считаются равными.

Логические операторы

AND, OR, XOR, NOT, !, &&, ||, ^^

AND, && - логическое И. Возвращает 1, когда оба операнда не равны 0 и не являются null. Если один из операндов равен 0, возвращает 0, даже если другой операнд является null.
OR, || - логическое ИЛИ. Возвращает 1, когда хотя бы один из операндов (или оба) не равны 0 и не являются null. Если один из операндов равен 1, возвращает 1 даже если другой операнд является null.
XOR, ^^ - логическое исключающее ИЛИ. Возвращает 1, когда один операнд равен 0, а другой не равен 0. Возвращает null, когда хотя бы один операнд является null.
NOT, ! - логическое отрицание. Возвращает 1, когда операнд равен 0 и возвращает 0, когда операнд не равен 0. Если операнд является null, возвращает null.
Неравенство/равенство операндов нулю так же проверяется с учетом возможных люфтов на ±10-8. То есть величина -3*10-9 во всех логических операциях будет считаться равной нулю.

Побитовые операторы

&, |, ^, <<, >>, ~
Все побитовые операции округляют свои аргументы до 64-битного целого. 
При этом если хотя бы один из операндов равен null, то и результат будет равен null.

& - побитовое "И". 
| - побитовое "ИЛИ".
^ - побитовое исключающее "ИЛИ".
>> - побитовый сдвиг вправо. При этом старшие биты числа заполняются нулями.
<< - побитовый сдвиг влево. Младшие биты заполняются нулями.
~ - инвертация всех битов числа. Стоит учитывать, что числа хранятся в дополнительном коде,
таким образом ~1 = -2.

Например, проверка на то, что в третьем бите параметра status находится 
единица, может выглядеть так:
((status >> 2) & 1) != 0

Условные операторы

a ? b : c

Тернарный оператор со смыслом аналогичным функции if(a, b, c). 
Каскадные серии оператора ?: вычисляются слева направо, что позволяет использовать в аварийных критериях конструкции вида
dt < 10 ? true : dt > 20 ? false : null, что идентично записи
dt < 10 ? true : (dt > 20 : false : null), что в свою очередь идентично записи
if(dt < 10, true, if(dt > 20, false, null))
подобные записи бывают удобны в борьбе с "дребезгом" аварий.

Приоритет операторов

not, !, +, - (унарные)
*, /
+, - (бинарные)
<, <=, >, >=, >,
=, ==, <>, !=
and, &, &&, xor, ^, ^^
or, |, ||
?:

Чем выше, тем раньше вычисляется. Операторы на одной строке вычисляются слева направо в порядке их следования в выражении.

Таблица №2

Описание функций, используемых в «Редакторе формул»


abs(x)
Возвращает x, если x >= 0. Возвращает -x, если x < 0. Возвращает null, если x - null.

if(a, b, c)
Если a отлично от 0, возвращает b. Если a равняется 0, возвращает c. Если a является null, возвращает null.

zn(x)
Если x является null, возвращает 0. Иначе возвращает x.

isn(x)
Возвращает 1, если x является null, иначе возвращает 0.

zn_sum(x1, x2, ...., xn)

Возвращает сумму x1, x2, ... xn. 
От x1 + x2 + ... + xn отличается тем, что null значения аргументов рассматриваются как 0 (обычная сумма вернет null, если хотя бы одно из слагаемых является null).
От zn(x1) + zn(x2) + ... + zn(xn) отличается тем, что если все аргументы являются null, функция вернёт null (сумма zn значений вернет 0 даже когда все параметры являются null)
Данную функцию удобно использовать для универсальных формул суммарных тепловых мощностей и энергий, когда лишь некоторые из них могут выдаваться теплосчетчиком, к примеру: W = zn_sum(Wh, Whw). В этом случае W будет принимать значение Wh или Whw или Wh + Whw, смотря какие из этих значений доступны. Когда оба значения станут неизвестны, W тоже впадет в неизвестность (станет null).

zn_avg(x1, x2, ..., xn)
Возвращает среднее арифметическое не-null значений среди x1, x2, ..., xn. Если все аргументы равны null, функция вернет null.

round(a, b)
Возвращает значение a, округлённое до точности в b знаков после десятичной точки.Параметр b можно опустить, в таком случае округление будет вестись до целого числа.

date_part(ts, part)
Интерпретируя число ts как Unix Timestamp возвращает часть даты, определяемую параметром part. Поддерживаются стандартные символьные обозначения частей даты, например Y-год, m -месяц итп. Полный список обозначений можно увидеть в документации на функцию date в PHP: http://php.net/manual/ru/function.date.php

pow(a, b)
Возвращает a возведённое в степень b. Возвращает null если любой из аргументов будет null.

min(x1, x2, ..., xn)
Возвращает минимальное из значений x1, x2, ... xn. Если хоть одно из значений равно null, результат также будет null.

max(x1, x2, ..., xn)
Возвращает максимальное из значений x1, x2, ... xn. Если хоть одно из значений равно null, результат также будет null.

int(x, bytes)
Приводит значение x к знаковому целому числу длины bytes байт. При этом значение приводится к целому, у него отбрасываются все старшие байты и анализируется старший бит среди младших bytes байт. Функция удобна при чтении из modbus-устройств, например когда в регистре хранится 2 знаковых байта.

uint(x, bytes)
Аналогична функции int, но число предполагается беззнаковым.

select(a, x1, y1, x2, y2, ..., xn, yn)
Функция выбирает одно из значений y1, ... yn в зависимости от a. Более точно, если a=x1, функция вернет y1, если a=x2, функция вернет y2 итд. Может использоваться например для выбора правильного значения тепловой энергии в зависимости от схемы измерения на приборе.

lerp(x, x1, y1, x2, y2, ..., xn, yn)
Рассчитывает значение кусочно-линейной функции, заданной точками (x1, y1), (x2, y2), ... (xn, yn) в точке x (т.е. по сути выдает результат линейной интерполяции функции, для которой известны точки (x1, y1), (x2, y2), ... (xn, yn) в точке x). При этом предполагается, что x1 < x2 < ... < xn. Также предполагается, что левее x1 функция продолжается лучом (x2, y2) - (x1, y1) и аналогично правее xn функция продолжена лучом (xn-1, yn-1) - (xn, yn).

Эта функция удобна например при расчете требуемых значений по температурному графику, где в качестве (xi, yi) берутся точки графика, а в качестве x - температура окружающей среды. В таком варианте функция выдаст требуемое значение температуры подачи.
Данный пункт необходимо читать совместно с разделом Составные параметры