# 値の変換経路

> すべてのタグが共有する型の決まった変換、生の読み取りから工業値まで、無効な読み値の 2 つの方針、範囲外のときの動作、ブール値と文字列の変換、そして書き込みが段階をどう逆にたどるか。

すべてのタグは、生の読み取りを工業値に変える、型の決まった 1 つの変換経路を共有します。この経路はタグ自身の中にあります。[タグ](connector-tags#the-conversion-card)のページの「値の変換」のカードと機器のグリッドは、どちらも同じ段階を見せ、Logic、ダッシュボード、記録、ステーションが公開するものに届く値は、最後の段階を出た値です。公開される OPC UA のノードは生値を運びます。

## まず生値 {#raw-first}

経路は、ドライバー自身の値そのものではなく、タグのデータ型に合わせた**生値**から始まります。Int32 のタグに 3.7 を渡すドライバーがあれば、カードの一番上には 4 が出て、以降のどの段階もその 4 から続きます。宣言した型がまったく保持できない読み取り（数値を宣言したところに文字が来た場合）は空の読み取りであり、代わりの 0 になることは決してありません。段階は実数で計算し、反対の端で工業値はその型を取ります。

| タグ | 工業値 |
| --- | --- |
| 整数のデータ型で、スケールと校正がオフ、または傾き 1、切片 0 でオン（どのタグも作成時はこの状態です） | 整数そのもので、タグのデータ型のままです。 |
| 整数のデータ型で、スケールか校正が値を変える | 実数（Double）で、小数桁の段階で丸められます。温度を 10 倍して保持する Int16 のタグは、機器では 235、スケールが 0.1 なら 23.5 と読めます。 |
| Float または Double | タグのデータ型なので、Float のタグは float が表せる値に丸められます。 |

データ型は、機器と公開される OPC UA のノードが運ぶ型のままです。スケールや校正をオンまたはオフにすると、その時点から工業値の型が変わります。記録がすでに記録した値は記録したとおりに残り、チャネルは自分が宣言する型を保つので、整数のチャネルは最も近い整数に丸めた値を記録し、小数のチャネルは小数を残します。「値の変換」のカードは渡される値で終わり、スケールと校正が値をそのままにする整数の型が、上下限の段階が値を収める境界の小数を丸めて落とすときは、そう知らせます。

## 段階 {#the-stages}

数値の型では、経路はそれぞれ自分のチェックボックスを持つ段階の連なりです。オフの段階は入力をそのまま通し、カードは各段階の終わりでその時点の値を見せるので、実時間の読み取りが計算をどう進むかを追えます。

| 段階 | 既定 | 何をするか |
| --- | --- | --- |
| **スケール** | オン | `scaled = raw × Angular + Linear`。傾きの既定は 1、切片の既定は 0 です。傾きが 0 なら入力したその場で拒否されます（「スケールの係数が 0 だと、すべての読み値が 0 になります。掛ける係数を入力してください（1 なら値は変わりません）。」）。すべての読み取りを 0 にしてしまううえ、予告と保存される経路が食い違ってはならないからです。 |
| **校正** | オフ | スケーリング後の値に当てる 2 つ目の線形の組です：`calibrated = scaled × Angular + Linear`。基準器に対して測った値と直した値の差が範囲の計算を乱さないよう、スケーリングとは分けてあり、専用の権限で守られています。[校正](connector-calibration)を参照してください。傾きが 0 なら同じように拒否されます。 |
| **無効な読み取り** | 常に表示 | 使える数値を持たない読み取りに対する 2 つの方針です（下記）。チェックボックスではありません。その「オフ」もまた、答えのひとつだからです。 |
| **上下限** | オフ | 値を**最小**（既定は 0）と**最大**（既定は 100）と比べ、選んだ越限したときの動作を当てます（下記）。境界は整えられるので、下限が上限より大きくても失敗にはなりません。小さいほうが下限になります。 |
| **小数桁** | オン | **小数桁**で指定した桁に丸めます。既定は 2 で、0 から 15 まで受け付けます。 |

線形の 2 つの段階には、どちらも 2 つの基準点から組を計算する **2 点法**の補助が付きます。手順は[校正](connector-calibration#the-two-point-assistant)で 1 段階ずつ説明します。

## 機器が数値以外を返したとき {#the-device-answered-without-a-number}

熱電対の断線、センサーのないチャネル。読み取りは届き、設備は話しているのに、測定値が NaN である場合です。数値のタグだけの話で、どちらの方針でも品質は良いままです。

| 方針 | 効果 |
| --- | --- |
| **そのまま通す**（既定） | NaN はそのまま進み、上下限の段階を丸ごと飛ばします。その段階がどの動作を持っていても同じです。上下限は数値を判断するものであり、ここには数値がないからです。無限大は NaN ではないので、これまでどおり範囲で頭打ちになります。 |
| **値で置き換える** | 宣言した数値がこの段階から先に立ち、ほかの読み取りと同じように上下限、小数桁、最後の型合わせに入ります。 |

## 機器が応答しなかったとき {#the-device-did-not-answer}

タイムアウト、切れたケーブル、電源の入っていない設備、ドライバーの例外。どの型でも起こりますが、文字列、日時、識別子、バイト列を読むタグには最初の 2 つの方針しか出ません。宣言する代替値は数値であり、それらの型の読み取りは数値ではないからです。

| 方針 | 効果 |
| --- | --- |
| **エラーを表示する**（既定） | タグは空になり、品質が悪くなるので、失敗があらゆる場所に一度に現れます。 |
| **最後の良い値を保持する** | 最後に届いた読み取りが、期限なしで、設備がふたたび答えるまで表示に残ります。時刻はその読み取りを指したままです。数値が測られたのはそのときだからです。最初の読み取りが届く前は何も保たれず、そのあいだタグは空です。 |
| **値で置き換える** | 宣言した数値が、宣言したとおりに出ます。段階を通す読み取りがそもそもないので、スケーリングも校正も丸めもされず、工業値の型に合わせられるだけです。数値の型とブールで出ます。読み取りが数値から作れる型だからです。String、DateTime、Guid、ByteString では出ません。 |

代替値が黙って立つことはありません。「現在の値」のカードが理由を書き（「最後の良い値です。機器が応答しない間、これを保持します。」）、実時間のドットは黄色になり、内蔵の OPC UA サーバーはその値を、単なる Good ではなく代替を表す状態とともに公開し、`tag_read` でタグを読むエージェントには、それがどの代替値かが伝えられます（`substitution`）。方針が求めるあいだ、それは公開され続けます。答えないままの機器が、外部のクライアントに代替値と読み取り失敗を交互に見せることはないので、そのクライアントが読むものはパネルが見せるものと同じです。機器が答えた瞬間、読み取り自身がその点を取り戻します。代替値をオフにしたときも同じです。代替値を選ぶことは可用性を選ぶことなので、警報も式も、その点に値があるものとして判断し続けます。その代償は隠されずに支払われます。診断ログは失敗した読み取りを記録し続け、機器の稼働状態はその機器をオフラインとして報告し続けるからです。代替値は「この点は何を見せるべきか」に答えるものであって、「設備はそこにいるか」には決して答えません。有効な上下限の外にある代替値は、入力したその場で警告されます：「上下限（0 から 100）の外です：読み取りに失敗したときに置き換える値です。」

途絶えた読み取りは、失敗した読み取りとして扱われます。機器が接続を受け入れたあとで応答をやめた場合のように、タグの読み出し周期に 10 秒を足した時間のうちに新しい読み取りが届かないと、上の方針が、読み取りが失敗したときと同じように、タグを読むすべてのものに当てはまります。Logic の式、ダッシュボード、記録される値、エージェントです。**エラーを表示する** では、タグは空になり品質が悪くなります。一方で内蔵の OPC UA サーバーは、ノードに機器の最後の値を Good ではなく `UncertainLastUsableValue` で保つので、外部のクライアントには、持っていた数値と、それがもう更新されていないことの両方がわかります。代替値があるときは、その代替値が上と同じように示され、公開されます。品質が悪いあいだ、警報はいつもどおり状態を保ちます。「現在の値」のカードが理由を書き（「アプリケーションの時刻より後、新しい読み取りは届いていません。タグはこれを失敗した読み取りとして扱います。」）、時刻は最後に届いた読み取りを示し続け、次に届いた読み取りがタグを元に戻します。

書き込みのみのタグには、これらの方針のどれもありません。ステーションはそのタグを読まないので、失敗する読み取りがないのです。ステーションが書き込むまでタグは値を持たず、値がないことをそのまま示します。代替値も黄色のドットもなく、その代わりに OPC UA へ公開されるものもなく、パネルもこのタグにはこの行を描きません。タグが読まれていたあいだに選んだ方針は保存されたまま残り、タグが書き込みのみであるあいだは無視されます。アクセスが読み取りのみか読み書きに戻れば、すぐにまた効きます。

## 範囲外の値 {#out-of-range-values}

下限と上限の外にある値に対する**上下限**の動作です。

| 動作 | 値はこうなる | 品質 |
| --- | --- | --- |
| **値なし** | 空欄（値なし）。 | 良い |
| **上下限で丸める**（既定） | 近いほうの境界。 | 良い |
| **エラーにして値なし** | 空欄。 | 悪い（上下限の異常） |
| **エラーにして丸める** | 近いほうの境界。 | 悪い（上下限の異常） |
| **NaN** | NaN。 | 良い。NaN を表せる Float と Double のタグにだけ出ます。これにより Process のチャネルが無効な値を分類できます。エージェントの書き込みや復元したバックアップによって整数のタグに残った NaN の動作は、Null の空欄に落ちます。 |

上下限の異常はタグの実効的な品質に折り込まれるので、実時間のドット、プロパティの式、警報のすべてが、追加の配線なしにその越限した値を悪いものとして見ます。「値の変換」のカードには「値 130 は、上下限（0 から 100）の外です。」と出ます。それでもこれは接続の問題ではなくプロセスの状態なので、[機器の稼働状態](connector-health)がそのために機器をオフラインと数えることはありません。

## ブール値、文字列、その他の型 {#boolean-string-and-other-types}

数値でない型には、同じ「値の変換」のカードに自分の変換があります。

- **ブール**：**反転**は、生値の論理的な否定を報告します。
- **文字列**：**部分文字列の開始**（0 から数えます）と**長さ（空欄なら末尾まで）**が、生の文字列から範囲を切り出します。長さが空なら末尾までで、範囲外の境界は失敗ではなく頭打ちになります。
- ほかのすべての型（DateTime、Guid、ByteString）はそのまま通ります。その「値の変換」のカードには無効な読み取りの段階だけがあり、機器が応答しなかったときの方針を選べます。書き込みのみのタグなら、カードは出ません。

エラーを見せることと最後の正常値を保つことは、どの型にも当てはまります。値で置き換えることは数値とブールのタグだけに出るので、String、DateTime、Guid、ByteString のタグには並びません。これらの型のタグに、以前の版が保存できたように置き換えがすでに保存されていても、それは **エラーを表示する** として扱われ、次にそのタグを保存するとき（パネルからでもエージェントからでも）、代わりにエラーの表示が保存されます。NaN の方針は数値のタグだけのものです。

## 書き込みは経路を逆にたどる {#writes-reverse-the-pipeline}

「現在の値」のカードの書き込みの入力欄は工業値を取り、有効で逆にたどれる段階を順に戻します。上下限が有効なら下限と上限に丸め（動作が何であれ、書き込みは常に丸められ、捨てられることはありません）、校正を戻し（`(value − Linear) ÷ Angular`）、同じようにスケーリングを戻し、最後にタグの型に合わせます。スケールか校正が値を変える整数のタグは小数を受け付けます。スケールが 0.1 の Int16 のタグに 123.4 を書くと 1234 が書かれます。スケールも校正もない整数のタグに小数を書き込むと、いちばん近い整数に丸められ、半分はゼロから遠い側へ向かいます（2.5 は 3 が書かれます）。丸めは情報を失う操作なので、戻されません。ブール値の入力は反転をもう一度当てます。文字列の部分取り出しは表示だけのものなので、文字列の書き込みは値の全体をそのまま送ります。DateTime、Guid、ByteString はそのまま通ります。外部の OPC UA クライアントが公開ノードに書いた値はすでに生値なので、ここを一切通りません。
