Generic serial and TCP

計量指示計やバーコードリーダーのように独自のテキストやバイトのプロトコルを話す装置を、シリアル回線、TCP、UDP で扱います。メッセージの終わり方と確かめ方、そして各タグがそこから値を取り出す方法です。

Markdown で表示

Generic serial and TCP ドライバーは、標準のプロトコルが当てはまらず、テキストや単純なバイトでできた独自のプロトコルを話す装置を読み書きします。計量指示計、バーコードや RFID のリーダー、古い計器、ラベルプリンターなどです。こうした装置には何者かを問い合わせられないので、何も検出しません。機器には、送ってくるメッセージがどう終わり、そのチェックサムをどう確かめるかを伝え、各タグには、値をどう得るか、どのメッセージが自分のものか、メッセージのどの文字が値かを伝えます。

機器は、作るときに選ぶ 3 つの方法のどれかで装置に届きます。

通信方式 機器への届き方 タグにできること
シリアル回線上 このドライバーのシリアル回線で、回線上のほかの機器と共有し、要求は 1 つずつです。 要求と応答、受信待ち、書き込み。
TCP クライアント 装置のホストとポートへの自分だけの接続です。 要求と応答、受信待ち、書き込み。
UDP 受信 装置がデータグラムを送ってくる、このステーションのポートです。ステーションからは何も送りません。 受信待ちだけ、読み取り専用。

シリアル回線上の機器は回線の下に入るので、ツリーのその部分は Modbus RTU と同じく ドライバー → 回線 → 機器 → タグ と読めます。ネットワークの機器はドライバーの下に置かれ、ほかのどのドライバーの機器とも同じようにフォルダーに整理でき、ドライバー → フォルダー → 機器 → タグ となります。機器は作られた側にとどまります。TCP と UDP は切り替えられますが、回線とネットワークのあいだを移ることはありません。

ドライバーのページ

見出しの下の行は「シリアル回線には 1 本のバスを共有する計器が並び、ネットワークの機器はドライバーの直下に置きます。回線か機器を追加してから開き、メッセージの形を設定してください。」と述べ、ページには上下に 2 つの表があります。

表 増やすもの 並ぶもの
シリアル回線 タイトルの右にある回線を追加。 ドライバーの回線です。回線、物理的な組(ポート · ボーレート · 形式。このドライバーの回線にはタイムアウトがないので含みません)、機器、状態、そして操作の開く、有効化、無効化、削除。空のときは「シリアル回線はまだありません。」と表示します。
機器 タイトルの右にある機器を追加。ネットワークの機器、つまり TCP クライアントを作ります。 回線上のものも含めたドライバーのすべての機器で、列はどのドライバーの機器の表とも同じです。空のときは「機器はまだありません。」と表示します。

見出しはかっこの中に機器の数を示し、ツリーのドライバーの行は回線が 1 本でもあれば両方の段を数えます(「回線 1 本 · 機器 2 台」)。ドライバーのバーに検出はありません。ドライバーの行を右クリックすると機器を追加、回線を追加、新しいフォルダー、再読み込みが出て、区切り線のあとにドライバーを削除が出ます。欄の新規…メニューでは、このドライバーの項目に新しい機器、新しいシリアル回線、新しいフォルダーがあり、そのあとに回線、フォルダー、機器が並びます。追加したドライバーは、回線や機器があってもなくても、ツリーのドライバーのフォルダーの下に並びます。

シリアル回線

このドライバーの回線は、シリアル回線で説明している回線から項目を減らしたものです。そのページは「1 つの物理的なシリアルバスです。つながる計器が共有するポートの設定で、要求は 1 つずつ送ります。」と述べ、「物理的な回線」のカードには次の項目があります。

項目 意味 既定値
名前 バスのわかりやすい名前で、ツリーと回線上のすべての機器に表示されます。 「新しい回線」
シリアルポート Windows の COM ポートで、物理、仮想、リダイレクトのどれでもかまいません。入力するか、Windows が報告するポートから選びます(再読み込みで読み直します)。1 つのポートは、回線のドライバーにかかわらず 1 本の回線に属します。 最初の空きポート
ボーレート バスの速度で、回線上のすべての機器が共有します。 9600
シリアルの形式 データビット、パリティ、ストップビットです。8N1、8N2、8E1、8E2、8O1、8O2、7N2、7E1、7E2、7O1 のどれかです。このドライバーは 8 データビットを必要としないので、10 個すべてを選べます。 8E1

ここで作った回線は無効の状態で始まるので、ポートが開く前にポートの設定を入力できます。ポート、ボーレート、形式は回線が無効のときだけ変えられ、名前はいつでも変えられます。このドライバーの回線には、伝送モード、応答のタイムアウト、通信の最小間隔、自動の無通信時間がありません。回線上の各機器が、メッセージの終わり方と応答を待つ時間を自分のパネルで決めます。回線の下の「機器」のカードもそう述べています:「この回線の機器はすべて、回線のポート設定を共有します。メッセージの終わり方と応答を待つ時間は、機器ごとに自分のパネルで決めます。」「ユニットを検出」のカードはなく、機器の表にユニット ID の列もありません。計器はアドレスではなく、要求の中身で見分けるからです。

回線の上、またはその右クリックメニューの機器を追加は、その回線にこのドライバーの機器を作ります。回線は、作られたときのドライバーにずっと属します。Modbus RTU の機器とこのドライバーの機器が 1 本の回線を共有することはなく、もう一方のドライバーの回線に機器を割り当てようとするエージェントは拒否されます。回線の状態(オフ、待機、接続中…、オンライン、ポート障害)はどのシリアル回線とも同じで、有効化と稼働状態にあります。

回線では、ドライバーは回線上のすべての機器のためにポートを 1 度だけ開き、要求を 1 つずつ送って、次を送る前にその応答を待ちます。要求のあいだに届いたものは回線上のすべての機器に渡され、各機器が自分の決まりでメッセージに切り分けます。ポートが故障すると、回線がすべての機器のためにポートを開き直し、故障が続くあいだは試行の間隔をしだいに長くします。

機器

接続

項目 意味 既定値
通信方式 ネットワークの機器だけです。TCP クライアント:「ステーションが機器のホストとポートに接続します。」UDP 受信:「機器が送るものをステーションがローカルのポートで受け取ります。ステーションからは何も送りません。」この 2 つは切り替えられます。回線上の機器は、代わりに回線を表示します。 TCP クライアント
ホスト TCP:装置のホスト名か IP アドレスです。先頭に tcp://、ホストの後ろにポートを付けたアドレス全体を貼り付けることもできます。 空欄
ポート TCP:装置が応答するポートで、1 から 65535 です。こうした装置に標準のポートはないので、新しい機器にはポートがありません。 空欄
受け入れる送信元 UDP でホストの代わりに表示されます:「このアドレスからのデータグラムだけを読みます。空欄なら送信元を問いません。」 空欄
ローカルポート UDP でポートの代わりに表示されます:「機器が送る先となる、このステーションのポートです。Windows のファイアウォールで通す必要があります。」 空欄
シリアル回線 · 固定 回線上の機器です。回線の名前と、その下にポート、ボーレート、形式を読み取り専用で示します。 追加した回線

新しい TCP の機器は「ホストがまだ入力されていません」と表示し、ホストとポートがそろうまで接続しません。ホストがあってポートがない機器と、ローカルポートのない UDP の機器は保存できません:「ポートを入れてください。TCP では機器のポート、UDP では受信するローカルポートです。」回線上の機器には、ホスト、ポート、フォルダー、ユニット ID がありません。

見出しに出る Base URI は実行時のアドレスです。generic://tcp/<host>:<port>、generic://udp/<local port>(受け入れる送信元が入っていれば from=<sender> 付き)、または generic://serial/<line id>/<port>/<baud>/<format> に続けて、メッセージの終わり方と確かめ方(end、start、terminator、length、gap、timeout、checksum など)が並びます。そこに入るのはバイトそのもので、機器の入力の表記ではありません。回線上の機器のコピーはその回線にとどまり、ネットワークの機器のコピーはドライバー直下に置かれます。

メッセージのカード

接続のカードの下にあるメッセージのカードは、バイトの入力のしかたとメッセージの終わり方を決めます。

項目 意味 既定値
入力の表記 開始マーカー、終端文字、そして各タグの要求、フィルター、区切り文字、書き込みメッセージ、期待する返答をどう書くかです。エスケープ付きのテキスト:印字できる文字はそのまま、ほかのバイトは \r、\n、\t、\\、\xNN で書きます。16 進数のバイト:1 バイトを 2 桁で書き、例えば 02 30 31 0D です。切り替えると、機器とそのタグのバイトの欄をすべて書き直し、どれも同じバイトを送り続けます。どれかが正しいバイトになっていないあいだは、切り替えは拒否されます:「表記は変わっていません。この機器かそのタグのバイトの欄に、今の表記で正しくないものがあります。先にそれを直してください。」 エスケープ付きのテキスト
メッセージの終わり方 終端文字、固定長、無通信の間 のどれかです。UDP では、ここで何を選んでもデータグラム 1 つが 1 つのメッセージです。 終端文字
終端文字 終端文字のとき:どのメッセージも閉じるバイトです。タグが読むものには含まれません。 \r\n
メッセージの長さ(バイト) 固定長のとき、1 から 1024:「どのメッセージもこのバイト数です。開始マーカーとチェックサムを含みます。」
無通信の間(ms) 無通信の間のとき、5 から 10000:「この時間なにも届かないと、メッセージの終わりとみなします。」 50
開始マーカー 任意です。どのメッセージも始まるバイトで、例えば \x02 です。その前のバイトは捨てるので、メッセージの途中から受け始めた流れもそろい直します。マーカーはメッセージの最初の文字として数えます。 空欄
応答のタイムアウト(ms) 50 から 60000:「要求が応答を、書き込みが期待する返答を待つ時間です。」 1000
メッセージがないまま許す最長時間(秒) 0 から 86400 で、0 は期限なしです:「この時間なにも届かないと、受信待ちのタグは読み取り値として扱われなくなります。0 は期限なしで、バーコードリーダーのようにときどきしか送らない機器向けです。はかりのように絶えず送る機器では値を入れてください。」 0

選んだ終わり方が使わない項目は表示されず、その終わり方に戻したときのために値を保ちます。機器が扱えない値は保存されず、操作ログ帯が理由を伝えます。例えば「メッセージの終わりの終端文字を入れてください。例:\r\n」や「メッセージの長さは 1 から 1024 バイトの間にしてください。」です。

チェックサムのカード

項目 意味 既定値
計算方法 どのメッセージにも付くチェックサムです。なし、合計(8 ビット)、合計の 2 の補数(LRC)、7 ビットの合計の 2 の補数(Toledo)、XOR(8 ビット)、CRC-16/MODBUS、CRC-16/CCITT のどれかです。「チェックサムが合わないメッセージは捨てて診断ログで数え、値として読むことはありません。」 なし
書き方 16 進数のテキストはチェックサムを 16 進数の数字で書いたもの、そのままのバイトはチェックサムのバイトそのものです。 16 進数のテキスト
位置 終わりの前:終端文字の前の最後のバイト、またはメッセージの最後のバイトです。終端文字の後:終端文字のすぐ後で、その場合は終端文字もチェックサムの対象になります。メッセージが終端文字で終わるときだけ選べます。 終わりの前
先頭で外すバイト数 0 から 255:「メッセージの先頭で、チェックサムの対象にならないバイトです。例えば STX や $ です。」 0
直前で外すバイト数 0 から 255:「チェックサムの直前にあって、その対象にならないバイトです。例えば NMEA の文の * です。タグもこれを読みません。」 0

計算方法以外の項目は、チェックサムを選んだときだけ表示されます。チェックサムの対象は、外すバイトを除いた、メッセージの最初のバイトからチェックサムの直前のバイトまでです。チェックサムが合わないメッセージは値として読まれず、捨てられます。診断ログには機器の下に、多くても 1 分に 1 回記録されます。チェックサムは確かめるだけです。要求と書き込みは入力したとおりに送るので、チェックサムが必要な要求は、自分のバイトの中にそれを含めます。

計算方法 よくある用途
合計(8 ビット) 指示計。
合計の 2 の補数(LRC) 指示計、Modbus ASCII 風のフレーム。
7 ビットの合計の 2 の補数(Toledo) Toledo の指示計の連続出力で、CR の後のそのままのバイトです。
XOR(8 ビット) NMEA 0183 の文($…*hh)、指示計、RFID リーダー。
CRC-16/MODBUS バイナリのフレームです。そのままのバイトでは下位バイトが先です。
CRC-16/CCITT バイナリのフレーム(CCITT-FALSE の変種)です。そのままのバイトでは上位バイトが先です。

タグのアドレス

このドライバーのタグには入力するアドレスがありません。信号源のカードが、次の項目で値の得方を尋ねます。バイトは機器の表記で入力します。

項目 意味 既定値
取得方法 要求と応答:「タグの読み出し周期ごとにステーションが要求を送り、応答から値を読みます。」受信待ち:「機器が自分から送り、タグはフィルターが受け入れた最後のメッセージを保ちます。」UDP の機器では受信待ちだけです:「この機器は UDP で受信するだけで何も送りません。タグは受信待ちだけで、読み取り専用です。」 要求と応答
要求 要求と応答のときだけ:「タグの読み出し周期ごとにステーションが送るもので、機器の表記で入れます。応答のタイムアウト内にフィルターが受け入れた最初のメッセージが応答です。」 必須
メッセージのフィルター タグのものになるメッセージです。すべてのメッセージ、先頭が一致(先頭のバイトを指定)、正規表現に一致(正規表現で指定)のどれかです。要求では「要求への応答になるメッセージです。それ以外は受信待ちのタグに渡ります。」 すべてのメッセージ
値の取り出し方 メッセージから値を切り出す方法です。メッセージ全体、固定位置(最初の文字と文字数)、区切り文字の間の項目(区切り文字と項目の番号)、パターンのキャプチャグループ(パターン)のどれかです。「位置と項目は 1 から数えます。パターンには値になるキャプチャグループがちょうど 1 つ必要です。数値は小数点をピリオドとして読みます。」 メッセージ全体
機器は小数点にカンマを使う Float と Double のタグだけです。読み取りでも書き込みでも、カンマを小数点として扱います。 オフ
書き込みメッセージ 書き込むタグで、UDP では使えません:「書き込みで送るものです。値を入れる位置に を置きます。例:SP \r。書式を付けるときは とします。Boolean のタグでは、 のない書き込みメッセージはコマンドで、true を書き込むと送られます。」 空欄
期待する返答 「任意です。書き込みへの機器の返答の先頭です。応答のタイムアウト内にその返答が届いたときだけ、書き込みは成功します。」 空欄

文字はメッセージの先頭から、開始マーカーも含めて数えます。終端文字、チェックサム、チェックサムが直前で外すバイトは、タグが読むものに含まれません。パターンは .NET の正規表現で、読むのに 250 ms を超えるメッセージは読みません。書き込み専用のタグには要求、フィルター、値の項目がなく、書き込みメッセージのないタグは読み取り専用です。

データ型は Boolean、Int32、Int64、Float、Double、String です。切り出したテキストは、どのドライバーとも同じく、タグ自身の段階で変換される前にタグの型として読まれます(値の変換経路を参照)。Boolean は 1、true、on、yes と 0、false、off、no を読み、整数は整数を読み(12.0 は 12 と読み、12.5 は拒否します)、Float と Double は小数を読み、String は文字をそのまま受け取ります。指示計は数値を空白で埋めるので、数値の前後の空白と、符号と数字のあいだの空白は無視します。項目が成り立たないタグは保存されず、タグのページが足りないものを示します。例えば「このタグが送る要求を入れてください。」や「パターンには、値を囲むキャプチャグループがちょうど 1 つ必要です。」です。

読み取り専用のワイヤアドレスのプレビューは、ask か listen に当てはまるものを続けて示します。例えば listen?extract=position&start=5&length=6、また 01RD と CR を送り、応答のカンマ区切りの 3 番目の項目を読むタグなら ask?send=01RD%0D&extract=field&separator=,&field=3 です。

読み取り

状況 要求と応答のタグ 受信待ちのタグ
値 要求の後、応答のタイムアウト内にフィルターが受け入れた、確かめ済みの最初のメッセージから取ります。 フィルターが受け入れた、確かめ済みの最後のメッセージから取り、届いた時刻を付けます。
読む時点 タグの読み出し周期ごと。 装置が送るたびです。タグは読み出し周期ごとに最後のメッセージを示します。
最初のメッセージの前 該当しません。 タグは待ちます。どのタグも最初の応答の前と同じく、値もエラーもありません。
応答がない、装置が黙っている 応答のタイムアウト内に応答がなければ読み取りの失敗で、応答しなかった機器についてのタグの方針が表示を決めます。 機器のメッセージがないまま許す最長時間(秒)を過ぎると、受信待ちのタグはすべて読み取りに失敗し、それぞれの方針が表示を決めます。TCP の接続が切れたときは、その時間に関係なく失敗します。
タグが読めないメッセージ 理由付きの読み取りの失敗です。項目が足りない、値がメッセージの終わりを越える、型に収まらないテキストなどです。 同じです。

どの要求の応答にもならないメッセージは同じ機器の受信待ちのタグに渡るので、1 台の機器が両方の種類のタグを持てます。フィルターが同じ受信待ちのタグは受け取ったものを共有し、同じメッセージから別々の項目を取り出せます。

書き込み

書き込みは、ほかのどのドライバーとも同じ経路を通ります。書き込み欄は工学値を受け取り、変換の段階を逆にたどってから生の値を送ります(Connectorを参照)。

書き込みメッセージ 送るもの 書き込みの結果
{value} あり 入力したバイトで、{value} の位置に値が入ります。数値はインバリアントカルチャで(タグがそう指定すれば小数点はカンマ)、または {value:FORMAT} で .NET の数値書式に従って書きます(W{value:000.0}\r は 12.5 を W012.5 と CR として送ります)。Boolean は 1 か 0、テキストはそのままです。 送った時点で完了です。期待する返答があれば、それで始まる返答が応答のタイムアウト内に届いたときだけ完了します。別の返答なら、その返答を理由に書き込みは拒否され、何も届かなければ応答なしです。
{value} なし、Boolean のタグ 風袋引きや印刷のようなコマンドです。true を書き込むと送り、false の書き込みは拒否します。 同じです。
なし 何も送りません。タグは読み取り専用です。

書き込みは、どのドライバーとも同じく機器のキューで順番を待ちます。回線では回線の 1 つずつの要求を分け合い、TCP では機器自身の接続を使います。UDP の機器は何も送らないので、そのタグには書き込めません。

例:RS-232 の計量指示計

Toledo の連続出力の形式で送る指示計は、1 秒に何度も、STX、状態バイト 3 つ、重量の数字 6 桁、風袋の数字 6 桁、CR、チェックサムのバイトを送ります。ステーションでは次のようにします。

  1. ドライバーのページで回線を追加し、名前を Scale line にして COM3 を選び、ボーレートは 9600 のまま、シリアルの形式に 7E1 を選んでから、回線を有効化します。
  2. 回線で機器を追加し、名前を Scale にします。メッセージのカードではエスケープ付きのテキストと終端文字のまま、終端文字を \r、開始マーカーを \x02、メッセージがないまま許す最長時間(秒)を 10 にします。ケーブルが抜けたときに通信切れとして見えるようにするためです。
  3. チェックサムのカードで7 ビットの合計の 2 の補数(Toledo)、そのままのバイト、終端文字の後を選び、外すバイト数はどちらも 0 にします。
  4. タグを追加し、名前を Weight、Double、読み取り専用にします。信号源のカードで受信待ち、すべてのメッセージ、固定位置を選び、最初の文字を 5、文字数を 6 にします。STX が 1 文字目、状態バイト 3 つが 2 から 4、重量が 5 から 10 です。
  5. 数字には小数点が入っていないので、タグのスケールの段階で小数点を置きます。例えば小数 2 桁に設定した指示計なら係数 0.01 です。

エージェントは、ツールを 3 回呼んで同じことをします。

serial_line_upsert driver=GenericSerialTcp name="Scale line" serialPort=COM3 baudRate=9600 serialFormat=7E1
device_upsert driver=GenericSerialTcp name=Scale transport=SerialLine serialLineId=<id> messageEnd=Terminator terminator=\r startMarker=\x02 checksum=SumTwosComplement7Bit checksumFormat=Raw checksumPlacement=AfterEnd silenceTimeoutSeconds=10
tag_upsert device=Scale name=Weight opcUaType=Double tagMode=Listen valueExtraction=FixedPosition valueStart=5 valueLength=6

例:TCP のバーコードリーダー

Ethernet ポートのあるバーコードリーダーは、コードを読んだときだけ、1 行に 1 つのコードを送ります。

  1. ドライバーのページで機器を追加し、名前を Reader にして TCP クライアントのまま、ホストに 192.168.0.40、ポートに 2001 を入れます。
  2. メッセージのカードではエスケープ付きのテキスト、終端文字 \r\n、メッセージがないまま許す最長時間(秒) 0 のままにします。1 時間なにも送らないリーダーは故障ではないからです。チェックサムのカードはなしのままにします。
  3. タグを追加し、名前を Code、String、読み取り専用にします。信号源のカードで受信待ち、すべてのメッセージ、メッセージ全体を選びます。

エージェントのツールでは次のとおりです。

device_upsert driver=GenericSerialTcp name=Reader transport=TcpClient host=192.168.0.40 port=2001 messageEnd=Terminator terminator=\r\n
tag_upsert device=Reader name=Code opcUaType=String tagMode=Listen valueExtraction=WholeMessage

driver_capabilities はこのドライバーを genericSerialTcp の下に、この 2 つの例とともに説明し、serial_line_upsert は driver=GenericSerialTcp でこのドライバーの回線を作ります。ほかのツールはツールを範囲ごとににあります。

知っておきたい制限

  • 何も検出しません。こうした装置に、何者か、何を持っているかを尋ねるプロトコルがないからです。
  • 見出しの中で自分の長さを告げるバイナリのフレームは読みません。メッセージは終端文字、固定長、無通信の間、データグラムのどれかで終わります。
  • チェックサムは確かめるだけで、ステーションが送るものにチェックサムを付け足すことはありません。
  • タグはメッセージから 1 つの値を、型として読むテキストとして取り出します。メッセージの中にバイナリの整数や浮動小数点として詰められた数値は解読しません。
  • UDP の機器は受信するだけで、要求を送らず、書き込みも受け付けません。
  • 機器をシリアル回線とネットワークのあいだで、また別の回線へ移すことはできません。あるべき場所に作り直して、古いほうを削除してください。