> For the complete documentation index, see [llms.txt](https://palviewer.twelite.info/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://palviewer.twelite.info/source-code/format-parser.md).

# Format Parser

{% hint style="info" %}
[TWELITE PAL 親機の書式フォーマット ](https://wings.twelite.info/how-to-use/parent-mode/receive-message/app_pal)(ASCII形式のみ) を解釈しています。多くはその定義に従います。
{% endhint %}

{% hint style="warning" %}
Version 1.0 では書式フォーマットの解釈を VB.NET にて実装していましたが、v1.2 では C# による実装となりました。

当アプリのビルドでは PAL\_PARSER プロジェクト（ターゲットフレームワーク .NET Framework 4, クラスライブラリ）が該当し、VB.NET 側の PAL\_VIEWER プロジェクトから参照関係になっています。

本書では VB からの呼び出し例として記載します。
{% endhint %}

TWELITE PAL / ARIA / CUE の無線パケットは [App\_Wings ](https://wings.twelite.info/)を書き込んだ MONOSTICK などで受信します。この受信データは `:80000...<CR><LF>` といった電文で、データ量も多く複数の形式になるためデータの取り出しが容易では有りません。ここでは .NET 開発環境家で、この解釈処理を行うためのライブラリについて解説します。

PAL の書式フォーマットの構造は、大まかには、共通データ部とセンサーデータ部に分別されます。センサーデータ部は\[センサーデータ]のブロックが並んでいる構造で、PALの種別などによって数と種類は変わります。

```
[共通ヘッダ]{[センサーデータ1][センサーデータ2]...[センサーデータn]}
```

以下に挙げた関数とクラスを受信データ解釈に用います。

<table><thead><tr><th>関数とクラス</th><th>解説</th><th data-hidden></th></tr></thead><tbody><tr><td><code>PAL_Utils.genDataPresentation()</code></td><td>データ列の解釈を行う</td><td></td></tr><tr><td><code>ClsDataFormatPalApp</code></td><td>共通ヘッダ部の解釈データ</td><td></td></tr><tr><td><code>ClsDataPayloadPalSensors</code></td><td>センサーデータ部</td><td></td></tr></tbody></table>

### 関連ソースファイル

以下のソースコードにより PAL 親機より出力されるデータを解釈します。

※ ソースコードは[パルアプリビューアのサイト](https://mono-wireless.com/jp/products/TWE-APPS/App_pal/palviewer.html)より入手ください。

| ファイル名                       | 内容                                                                                       |
| --------------------------- | ---------------------------------------------------------------------------------------- |
| ITweDataPresentation.cs     | UART 電文のエンコード(ASCII 書式)を解釈する。解釈ができれば、ITweDataFormat による解釈も行う。                            |
| ClsDataPresentationAscii.cs | ASCII書式 `:800...<CR><LF>` の解釈。                                                           |
| ITweDataFormat.cs           | 上記 ASCII 書式で解釈されたデータ書式を表現する（アドレス情報など共通情報や、データ書式内のデータ構造など）。また書式を解釈後、ITweDataPayloadを生成する。 |
| ClsDataFormatPAL.cs         | PAL のデータ書式を解釈する。                                                                         |
| ITweDataPayload.cs          | センサー情報など各データを表現する。                                                                       |
| ClsDataPayloadPalSensors.cs | SENSE PAL の個別センサーの集約データ型。                                                                |
| ClsDataPalSenseElement.cs   | SENSE PAL の単独センサーのデータ型。                                                                  |
| MUtils.cs                   | ITWE??? 抽象型より、適切なクラスの生成を行うジェネレータや、諸ユーティリティ。                                              |

### プロジェクトへの組み込み方法

上記は Visual Studio (2019を想定) で、プロジェクト定義されたライブラリなどを参照する手順です。詳細はマニュアルや一般の情報を参照ください。

1. PAL\_PARSER ディレクトリを開発プロジェクト配下の適当な場所にコピーします。
2. Visual Studio の\[ソリューション]にPAL\_PARSER プロジェクトを追加します。
3. 開発プロジェクト中のプロジェクト\[プロパティ]>\[参照設定]にPARL\_PARSERを追加します。
4. 利用するソースコードの先頭部で Imports MONOW\_PAL\_PARSER を追加します。

上記参照設定を行えば、ソースコード中で PAL\_PARSER ライブラリのクラスなどが参照可能になります。

### 読み出し方法

TWELITE PAL Viewer では、`SerialPort1` の `.DataRecieved`イベントを起点として、書式の解釈が行われます。

以下のコード例(VB.NET)は、シリアルポートからのデータを String型の文字列 ( `:80000000CF0002` ) として受け取り、内容を解釈した後、解釈文字列として戻す関数です。（一例で、すべてのデータ要素やセンサーに対応したコードではありません）

* [VB.NET](/source-code/format-parser/sample-vb.net.md)
* [C#](/source-code/format-parser/sample-c.md)

以下は、VB.NET のコードを例に解説しています。

エラー処理は、*Try Catch* 構文で、まとめて例外処理しています。内部からのエラー時には `throw new Exception();` といった例外が発生します。

まず、解釈のために文字列をバイト列に変換して、`genDataPresentation()` により、データ解釈を行います。実行後、解釈済みの`ClsDataPresentationAscii`オブジェクトが生成されます。（末尾の改行コードが省略された場合を想定して`dataText & vbCr` と CR コードを追記した上、念の為末尾をCRの連続と変換しています。PAL\_PARSERは末尾 CR (\&H0D) を終端と処理しています）

```
' String -> Byte()
Dim b() As Byte = System.Text.Encoding.ASCII.GetBytes(dataText & vbCr)
' 末尾のコントロール文字を CR(&H0D) に書き換え
For i = b.Length - 1 To 0 Step -1 
    If b(i) < &H20 Then b(i) = &HD Else Exit For
Next
' :8000... を解釈しバイナリ列に[80 00 ...]に変換し、書式の解釈まで行う
Dim dataArrival = PAL_Utils.genDataPresentation(b)
```

続いて、データ書式、センサー情報を取り出します。`dataFmt` はデータ書式で、アドレス情報などを得ることができます。`dataPay`はセンサー情報で複数のセンサーの情報をひとまとめにしています。

```
Dim dataFmt As ClsDataFormatPalApp = dataArrival.objFormat 'データ形式、無線ノードの情報
Dim dataPay As ClsDataPayloadPalSensors = dataFmt.objPayload '各種センサー情報
```

データ書式(`ClsDataFormatPalApp`)で得られる情報を列挙します。

| 名前           |            | 内容                                                                                                           |
| ------------ | ---------- | ------------------------------------------------------------------------------------------------------------ |
| `BLQI`       | *Byte*     | LQI（受信感度相当）情報                                                                                                |
| `UsDataSer`  | *UShort*   | 続き番号                                                                                                         |
| `BBalPCB`    | *Byte*     | SENSE PAL 種別識別子                                                                                              |
| `BSrcAddr`   | *Byte*     | SENSE PAL の論理ID                                                                                              |
| `UiSrcAddr`  | *UInteger* | SENSE PAL のアドレス                                                                                              |
| `UiRepeater` | *UInteger* | <p>配送経路（<code>\&H80000000UI</code> なら直接、それ以外の場は最後に配送した中継器のアドレス）</p><p>※ PAL アプリの設定によって中継器のアドレスの定義は変化します。</p> |

次にセンサーの情報を得ます。`dataPay.SensoerCode()` により、センサーの種別を指定して情報を得ることができます。戻り型は`List(Of ClsDataPalSenseElement)`で、０個以上の要素が格納されます（Nothingにはならない）。ここでは電圧関連(`ClsDataPalSenseElement.E_SNSCD.VOLT`)のリストを探索します。

```
Dim l = dataPay.SensorCode(ClsDataPalSenseElement.E_SNSCD.VOLT)
```

ここでは、電源電圧(`ClsDataPalSenseElement.E_EXCD_VOLT.POWER`)の情報が欲しいので、リストの中にあるか探索します。見つかったらローカル変数 `iVolt`に値を格納します。

```
For Each m In l
    If m.Ex = ClsDataPalSenseElement.E_EXCD_VOLT.POWER Then
        iVolt = m.Data(0)
    End If
Next
```

#### ClsDataPalSenseElement クラス

このクラスは、各センサーの単一のデータを表現します。以下にデータの取り出しのためのプロパテを列挙します。

| 名前           | 型                      | 内容                                                                                                                                                                        |
| ------------ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `IsError`    | *Boolean*              | データエラーの場合は *True* となる。                                                                                                                                                    |
| `ErrorCode`  | *Byte*                 | エラーコードが入ります。                                                                                                                                                              |
| `Data`       | *Object(Byte,Shortなど)* | <p>センサーのデータを格納します。エラーなどで <em>Nothing</em> になる場合があります。データについては要素数が１つであっても配列型となります。<br>例えば <em>Byte</em>型のデータが一つだけ含まれる場合であっても <code>Byte(0)</code> で宣言された配列オブジェクトとなります。</p> |
| `SensorCode` | *Byte*                 | センサー種別が入ります。                                                                                                                                                              |
| `Ex`         | *Object(Byte)*         | 拡張データが入ります。主に電圧情報など、センサー種別が同じでも、複数ある場合に使われます。                                                                                                                             |
|              |                        |                                                                                                                                                                           |

センサーの種別を調べるための列挙型`ClsDataPalSenseElement.E_SNDCD`の定義は以下です。

| 名前     | 内容       |
| ------ | -------- |
| `HALL` | 開閉磁気センサー |
| `TEMP` | 温度センサー   |
| `HUMD` | 湿度センサー   |
| `LUMI` | 照度センサー   |
| `VOLT` | 電圧       |

電圧センサーの種別を特定するための列挙型`ClsDataPalSenseElement.E_EXCD_VOLT`は以下です。

| 名前      | 内容   |
| ------- | ---- |
| `POWER` | 電源電圧 |
| `ADC1`  | ADC1 |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://palviewer.twelite.info/source-code/format-parser.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
