Formula(計算式、fomula)使用ガイド
タグ登録時に fomula フィールドへ算術式を入力すると、ドライバが PLC から読み取った生値(raw value)を後処理し、変換後の値をキャッシュ / Sparkplug / REST レスポンスに使用します。
| 項目 | 値 |
|---|---|
| 実装クラス | plantpulse.app.edge.component.collector.plc.PLCValueFomula |
| 呼び出し位置 | PLCValueReader.read() の 3 段階目(raw → format → fomula → キャッシュ更新) |
| ライブラリ | plantpulse-edge-fomula.jar (plantpulse.edge.fomula.FormulaEngine) |
| 変数置換 | ${VALUE}(現在のタグ値) / ${tag_id}(他タグの最終値、LastValueMap キャッシュ) |
適用対象 data_type | Float / Double / Integer / Long のみ適用。その他の型(String、Boolean、…)はそのまま通過 |
| 結果 | Formula.evaluate(...) の BigDecimal → 型ごとのレンダリング(整数系は整数、Float/Double は小数) |
動作フロー
-
ドライバから raw 文字列値を受け取る(例:
"16384")。 -
PLCValueFomula.fomulaValue(address, value)を呼び出し。 -
address.getFomula()が空であればそのまま返却。 -
data_typeが Float / Double / Integer / Long でなければ そのまま返却。 -
計算式が参照する名前を確認 —
VALUEは今読み取った値、それ以外はLastValueMapにある他タグの最終値。 -
参照タグが一度も収集されていない場合は例外:
Variable value referenced by the formula is not yet in cache : formula=[`<fomula>`], variable=[`<name>`] -
計算式が参照する名前のみを値にバインドして評価 →
BigDecimal→ 型ごとの文字列を返却。
変数の種類
| 表記 | 意味 | 出典 |
|---|---|---|
${VALUE} | 現在のタグの raw 値 | ドライバが読み取った直後の値 |
${TAG_ID_X} | 他タグの最終値 | LastValueMap(全タグ共用キャッシュ) |
LastValueMap は全タグの最終 raw / 後処理値を保持します。同一 OPC 内の他タグだけでなく、別の OPC のタグも参照できます(ただし、そのタグが一度でも収集されキャッシュに存在している必要があります)。
${TAG_ZERO} を参照したが TAG_ZERO が一度も収集されていない場合、値をバインドできず例外が発生します。参照タグの timecycle をより短くするか、参照タグが先に収集されるよう auto_collect=true で登録してください。(保存時の構文チェックはこのケースを通過させます — 収集順序の問題であり、式の誤りではありません。)
式の文法
Excel と同じ書き方をします。 関数名と意味が Excel と同一なので、Excel で使っていた式をほぼ
そのまま移せます。大文字・小文字は区別しません(IF = if)。
| カテゴリ | トークン | 備考 |
|---|---|---|
| 算術 | +, -, *, /, ^ | ^ はべき乗 |
| 比較 | >, <, >=, <=, =, <> | = は等しい、<> は等しくない(Excel と同一) |
| グループ | (, ) | 括弧が優先 |
| 定数 | PI, E | 円周率、自然対数の底 |
| 条件 | IF, SWITCH, AND, OR, NOT | IF(조건, 참일때, 거짓일때) |
| 丸め | ROUND, ROUNDUP, ROUNDDOWN, CEILING, FLOOR, INT, TRUNC | ROUND(값, 자리수) |
| 数値 | ABS, SIGN, MOD, POWER, SQRT, CBRT, EXP, FACT | MOD の剰余の符号は除数に従う |
| 集計 | MIN, MAX, SUM, AVERAGE, COALESCE | 引数は複数可 |
| 対数 | LOG, LOG10, LN | LOG = 常用対数(底10)、LN = 自然対数 |
| 三角 | SIN, COS, TAN, ASIN, ACOS, ATAN, ATAN2 | ラジアン基準(Excel と同一) |
| 双曲線 | SINH, COSH, TANH, ASINH, ACOSH, ATANH | |
| 角度変換 | DEGREES, RADIANS | ラジアン ↔ 度 |
- ビット演算(
&,|) - ユーザー定義関数
- 文字列演算 / 日付演算 これらが必要な場合は、後続の段階(外部関数 / 後処理ノード)で扱ってください。
文法が正しくない計算式は保存時に拒否されます(UI 保存 / CSV アップロード / バックアップ復元すべて)。 タグ設定モーダルでサンプル値を入力して結果を事前確認できます。
計算中の失敗(0 除算、参照値が数値でない等)は収集エラーとして記録され、該当タグの 品質が低下します。もっともらしい数値を代わりに保存することはありません。
変数表記
${VALUE} と素の名前 VALUE の両方が使えます。他タグも同様です —
${TAG_ZERO} = TAG_ZERO。既存に保存された ${...} の計算式はそのまま動作します。
${VALUE}*0.1 기존 표기
VALUE*0.1 같은 뜻
IF(VALUE>100, 100, VALUE*0.1) 엑셀식
豊富な例集
1. 単純スケール(×0.1)
| 項目 | 値 |
|---|---|
data_type | Float |
fomula | ${VALUE}*0.1 |
| 入力 → 出力 | 16384 → 1638.4 |
用途:整数 raw → 小数点 1 桁の実数。温度 / 圧力 / 流量センサが整数で値を送る場合。
2. 単位変換(mV → V)
| 項目 | 値 |
|---|---|
data_type | Float |
fomula | ${VALUE}/1000 |
| 入力 → 出力 | 3300 → 3.3 |
3. オフセット補正(摂氏 → ケルビン)
| 項目 | 値 |
|---|---|
data_type | Float |
fomula | ${VALUE}+273.15 |
| 入力 → 出力 | 25 → 298.15 |
4. 他タグの参照(ゼロ点補正)
| 項目 | 値 |
|---|---|
data_type | Float |
fomula | ${VALUE}-${TAG_ZERO} |
| 入力 → 出力 | VALUE=1024, TAG_ZERO=24 → 1000 |
TAG_ZERO は他タグの ID。ゼロ点 / Tare 補正に使用します。
5. 多項式(二乗)
| 項目 | 値 |
|---|---|
data_type | Float |
fomula | ${VALUE}*${VALUE}*0.001 |
| 入力 → 出力 | 100 → 10.0 |
6. 関数 — 平方根
| 項目 | 値 |
|---|---|
data_type | Float |
fomula | sqrt(${VALUE}) |
| 入力 → 出力 | 144 → 12.0 |
7. 関数 — 三角(sin, radian)
| 項目 | 値 |
|---|---|
data_type | Float |
fomula | sin(${VALUE}) |
| 入力 → 出力 | 1.5708(≈π/2) → 1.0 |
角度(degree)入力の場合は sin(${VALUE}*pi/180)。
8. 複数タグ — キャリブレーション(gain × x + offset)
| 項目 | 値 |
|---|---|
data_type | Float |
fomula | ${VALUE}*${TAG_GAIN}+${TAG_OFFSET} |
| 入力 → 出力 | VALUE=100, GAIN=0.05, OFFSET=2 → 7.0 |
装置ごとの補正係数を別タグ(または HTTP-bind タグ)で管理するパターン。
9. 型変換 / 強制的な実数化
| 項目 | 値 |
|---|---|
data_type | Float |
fomula | ${VALUE}*1.0 |
| 入力 → 出力 | 123 → 123.0 |
Integer で入ってきた値を Float にキャストするだけにしたい場合。
10. べき乗 / 指数
| 項目 | 値 |
|---|---|
data_type | Float |
fomula | ${VALUE}^2 |
| 入力 → 出力 | 5 → 25.0 |
11. 対数
| 項目 | 値 |
|---|---|
data_type | Float |
fomula | log(${VALUE}) |
| 入力 → 出力 | 100 → 2.0 |
ln(...) も使用可能(自然対数)。
12. 複合 — RMS の dB 変換
| 項目 | 値 |
|---|---|
data_type | Float |
fomula | 20*log(${VALUE}) |
| 入力 → 出力 | 1000 → 60.0 |
REST 登録例(curl)
タグ単体の登録:
curl -X POST http://<edge-host>/api/v1/opc/OPC_LS_XBM_0001/tag \
-H "Content-Type: application/json" \
-d '{
"tag_id": "OPC_LS_XBM_0001_TAG_PRESS",
"tag_name": "Pressure (kPa)",
"plc_address": "D00100",
"data_type": "Float",
"format": "REAL",
"fomula": "${VALUE}*0.1",
"description": "스케일 ×0.1 적용"
}'
OPC + タグを一括登録する場合は、tag_list[] の中に fomula を入れてください。
値の read(後処理された値が返されます):
curl -s http://<edge-host>/api/v1/tag/OPC_LS_XBM_0001_TAG_PRESS/value | jq
# {
# "result": "OK",
# "data": {
# "tag_id": "OPC_LS_XBM_0001_TAG_PRESS",
# "value": "1638.4",
# ...
# }
# }
よくあるエラーと解決
| メッセージ / 症状 | 原因 | 解決 |
|---|---|---|
계산식에 해당하는 변수값이 아직 캐시에 없습니다 : 계산식=[${VALUE}-${TAG_ZERO}] | 参照タグ(TAG_ZERO)が一度も収集されていない | 参照タグを先に登録し、auto_collect=true で 1 サイクル回しておく |
계산식이 참조하는 값이 숫자가 아닙니다 | 参照タグの値が数値でない(例:data_type=String のタグを参照) | 数値型タグを参照するよう修正 |
Closing brace not found / Missing second operand | 括弧の対応が取れていない、または演算子の後に被演算子が欠落 | 保存時に拒否されるため、モーダルのエラーメッセージが位置まで示します |
| 後処理が適用されない(raw がそのまま返る) | data_type が String/Boolean | Float/Double/Integer/Long に変更する、または後処理が必要なら別の加工段階を使用 |
結果が常に 0 | raw 値が実際に 0 | raw read 値をまず GET /api/v1/tag/.../value で確認。(旧パーサは ${VALUE}* のような不完全な式を黙って 0 として計算していましたが、現在はそのような式は保存段階で拒否されます。) |
収集エラー FORMAT_FAILED + 品質低下 | 0 による除算や sqrt が負数などで計算失敗 | Infinity/NaN を保存せずエラーとして表出させます。式にガードを入れてください — 例:IF(TAG_ZERO=0, 0, VALUE/TAG_ZERO) |
動作メモ
LastValueMapはシングルトン(in-memory)。ゲートウェイ再起動時に初期化される → 最初のサイクルでは他タグ参照が失敗する場合があります。- 計算は全区間
BigDecimalのため、Long/QWordの大きな整数も最終桁まで保存されます(旧double評価で発生していた損失はありません)。 - 結果は
Double.toString()→ 文字列キャッシュ。画面 / Sparkplug 発行時に再びdata_typeにキャストされます(SparkplugDataTypeMapper参照)。 - 同一 OPC 内で複数タグの fomula が互いを参照すると、収集順序によって最初のサイクルが部分的に失敗することがあります。運用上大きな問題ではありませんが(次のサイクルからは正常)、きれいに動かすには参照対象タグをより短い
timecycleの別 OPC に配置してください。