# TWELITE PAL Script

TWELITE PAL Script は、TWELITE SENSE PAL (センサーパル) のデータの解釈、ログ記録するためのサンプルスクリプトです。

{% hint style="success" %}
[資料の取り扱いについて](https://twelite.gitbook.io/general/about_documents)をご参照ください。  お気付きの点がありましたら、当サポート窓口にご連絡いただければ幸いです。
{% endhint %}

{% hint style="danger" %}
本アプリケーションは参考として提供されています。

* 本アプリケーションならびに本ドキュメントは無保証です。
* 予告無く仕様が変更されます。
* モノワイヤレス ソフトウェア使用許諾 (MW-SLA-1J/E) に基づきます。
  {% endhint %}


# Usage

使用方法を解説します。

### PCの準備

1. ダウンロードしたアーカイブをわかりやすいフォルダ(例えばC:) に解凍する。
2. 下記WebページよりPCの環境にあったAnacondaをダウンロードし、インストールする。\
   <https://www.anaconda.com/download/>\
   Anacondaをインストールしたくない場合は”Anacondaをインストールしない場合”を参照
3. Anaconda Promptを立ち上げ、下記コマンドを実行しpyserialをインストールする。 (Windowsの場合、Anaconda Promptは スタートメニュー → Anaconda3 内にあるのでそちらから立ち上げること。)

```
> pip install pyserial
```

#### Anacondaをインストールしない場合

下記のインストール手順はOSがWindowsの場合の一例です。 各種ライブラリのドキュメントをご覧の上、必要なソフトウェアおよびライブラリをインストールしてください。

1. &#x20;下記ページよりPythonの最新版をダウンロードしインストールする。\
   <https://www.python.org/downloads/>\
   \
   その時、下図の枠で囲まれている部分にチェックを入れること\
   もしくはPythonのインストール先にPathを通すこと。

   <img src="/files/-LfwpZMjJy4R8PeBKRDY" alt="" data-size="original">
2. コマンドプロンプトを立ち上げ、下記コマンドを入力しpyserialをインストールする。

```
> pip install pyserial
```

### TWELITE PAL の準備

1. BLUE PAL/RED PALにSENSE PALを接続する。
2. BLUE PAL/RED PALの電池ホルダーにコイン型電池(CR2032)を挿入する。

### MONOSTICK の準備

1. MONOSTICKのアプリ（App\_PAL-Parent-xxx-MONOSTICK.bin）を書き換える。
2. MONOSTICKをリセットもしくはUSBポートに差しなおす。

### スクリプトの実行方法

MONOSTICKのCOMポートがCOM6の場合、Anaconda Promptで下記コマンドを実行すると下記のようなデータが出力されます。（Teratermが接続された状態では起動できません。）

```
> cd C:\PAL_Script
> python PAL_Script.py -t COM6
*** MONOWIRELESS App_PAL_Viewer 1.1.0 ***
  *** Open COM6 ***
ArriveTime : 2021/03/05 09:43:28.880
LogicalID : 1
EndDeviceSID : 10B6465
RouterSID : No Relay
LQI : 180 (-35.50 [dBm])
…
```

スクリプトを終了させるにはAnaconda Promptで'Ctrl+C'を入力してください。

### スクリプトの引数

スクリプト実行時に以下の引数を使用できます。

#### 引数：-h

機能：コマンドライン引数の一覧を表示\
使用例：python PAL\_Script.py -h

#### 引数：-t

機能：MONOSTICKが使用するポート名を指定\
設定項目：MONOSTICKのポート名\
初期値：Windowsの場合：COM3、Linuxなどの場合：/dev/ttyUSB0\
使用例：python PAL\_Script.py -t COM6

#### 引数：-b

機能：MONOSTICKが使用するポートのボーレートを指定\
設定項目：MONOSTICKのボーレート\
初期値：115200\
使用例：python PAL\_Script.py -t COM6 -b 115200

#### 引数：-l

機能：CSV形式のログを出力\
使用例：python PAL\_Script.py -t COM6 -l\
備考：同一ディレクトリ内にCSVファイルが生成される。\
ファイル名はAppPAL\_シリアル番号\_PAL\_YYYYMMDD.csv

CSVファイルの読み方は下記表の通りです。

| 見出し                                                    | 値の説明         | 単位  |
| ------------------------------------------------------ | ------------ | --- |
| LogicalID                                              | 子機の論理デバイスID  | -   |
| EndDeviceSID                                           | 子機のシリアルナンバー  | -   |
| LQI                                                    | LQI          | -   |
| Power                                                  | 電源電圧         | mV  |
| ADC\*                                                  | 電圧           | mV  |
| HALLIC                                                 | マグネットセンサーの状態 | -   |
| Temperature                                            | 温度           | ℃   |
| Humidity                                               | 湿度           | %   |
| Illuminance                                            | 照度           | Lux |
| <p>AccelerationX<br>AccelerationY<br>AccelerationZ</p> | 加速度          | g   |


# Source Files

### 環境

以下の環境で動作確認を行いました。

* Windows10 Bulid 1809
  * python 3.6.4
  * pyserial  3.4


# Pal\_Script.py

メイン関数

本スクリプトを起動するためのコードで、主にMONOSTICKからのデータを読み込み、解釈されたデータの標準出力を行います。

### 読み出し方法

以下のコード例では、都度 MONOSTICK からデータを受信したかどうかを確認し、受信していれば標準出力とCSVファイルに書き出す処理を行っています。

```python
from apppal import AppPAL

...

if __name__ == '__main__':
...

	try:
		PAL = AppPAL(port=options.target, baud=options.baud, tout=0.05, sformat=options.format, err=bEnableErrMsg)
	except:
		print("Cannot open \"AppPAL\" class...")
		exit(1)

	while True:
		try:
			# データがあるかどうかの確認
			if PAL.ReadSensorData():
				# あったら辞書を取得する
				Data = PAL.GetDataDict()

				# なにか処理を記述する場合はこの下に書く
				PAL.ShowSensorData()	# データを出力する

				# ログを出力するオプションが有効だったらログを出力する。
				if bEnableLog == True:
					PAL.OutputCSV()	# CSVでログをとる

		# Ctrl+C でこのスクリプトを抜ける
		except KeyboardInterrupt:
			break

...

	del PAL
```

まず、AppPALオブジェクトを生成します。オブジェクト生成時にシリアルポートの設定も行うため、シリアルポートの設定パラメータを引数として渡します。

```python
PAL = AppPAL(port=options.target, baud=options.baud, tout=0.05, sformat=options.format, err=bEnableErrMsg)
```

次にシリアルデータが来ているかどうかを判断するために ReadSensorData() を呼び、返り値が True だったら、解釈したデータを受け取ります。

```
# データがあるかどうかの確認
if PAL.ReadSensorData():
	# あったら辞書を取得する
	Data = PAL.GetDataDict()
```

受け取る辞書に関しては[ここ](/1.1.0/source-files/mnlib/apppal.py#readsensordata)を参照してください。


# MNLib

本スクリプトでシリアルデータの読み込みやそれを解釈するコードが入ったフォルダです。


# apppal.py

読み込んだバイト列を解釈して辞書オブジェクトに登録するクラス

## `Class AppPAL`

AppBaseを継承し、得られたペイロードを解釈して、使いやすいデータに変換して、辞書オブジェクトに登録するクラスです。

### 定義するときのパラメータ

初期値が設定されているものは指定不要。

| 変数名     | 型       | 初期値    | 内容                                             |
| ------- | ------- | ------ | ---------------------------------------------- |
| port    | string  | None   | <p>開くシリアルポート名</p><p>例：COM3、/dev/ttyUSB0 など</p> |
| baud    | int     | 115200 | ボーレート                                          |
| tout    | float   | 0.1    | シリアル通信するときのタイムアウト時間(秒)                         |
| sformat | string  | Ascii  | 本設定値はAsciiで固定                                  |
| autolog | boolean | False  | ペイロードが解釈出来たときに自動でCSVファイルにログを出力する場合はTrue        |
| err     | boolean | False  | エラーメッセージを出力する場合はTrue                           |

### `ReadSensorData()`

本メソッドで読み込めたペイロードがあれば、 [TWELITE PAL 親機の書式フォーマット](https://mono-wireless.com/jp/products/TWE-APPS/App_pal/parent.html) に従ってそのペイロードの解釈を行います。

{% hint style="info" %}
[TWELITE PAL 親機の書式フォーマット](https://mono-wireless.com/jp/products/TWE-APPS/App_pal/parent.html) (ASCII形式のみ) を解釈しています。多くはその定義に従います。
{% endhint %}

#### パラメータ

なし

#### 戻り値

* データが読み込めた場合：`True`
* 読み込めなかった場合：`False`

辞書オブジェクトに格納されたデータのキーは下記の通りです。

{% hint style="info" %}
EventIDなどのデータの意味に関しては、[こちら](https://wings.twelite.info/how-to-use/parent-mode/receive-message/app_pal#chu-li-shu-shi)もご確認ください。
{% endhint %}

| キー                | 型          | 内容                                                              |
| ----------------- | ---------- | --------------------------------------------------------------- |
| ArriveTime        | datetime   | ペイロードを得たときの時間                                                   |
| LogicalID         | int        | 子機の論理デバイスID                                                     |
| EndDeviceSID      | int        | 子機のシリアル番号                                                       |
| RouterSID         | int        | <p>最初に受信した中継機のシリアル番号</p><p>(親機が直接子機のパケットを受信した場合は0x80000000)</p> |
| LQI               | int        | 受信電波品質                                                          |
| SequenceNumber    | int        | <p>パケットが送信されるごとにインクリメントされる続き番号</p><p>1からスタート、65535の次に0に戻る</p>   |
| Sensor            | int        | センサー種別（0x80で固定）                                                 |
| PALID             | int        | PAL基板ID                                                         |
| PALVersion        | int        | PAL基板バージョン                                                      |
| HALLIC            | int        | ホールICの状態                                                        |
| Temperature       | float      | 温度(degC)                                                        |
| Humidity          | float      | 湿度(%)                                                           |
| Illuminance       | int        | 照度(lux)                                                         |
| AccelerationX     | list,float | X軸の加速度(g)                                                       |
| AccelerationY     | list,float | Y軸の加速度(g)                                                       |
| AccelerationZ     | list,float | Z軸の加速度(g)                                                       |
| SamplingFrequency | int        | 加速度のサンプリング周波数                                                   |
| EventID           | list,int   | イベントの要因とイベントID                                                  |
| WakeupFactor      | list,int   | 起床した要因等のデータ                                                     |

### `OutputCSV()`

辞書オブジェクトをCSVファイルに出力します。

#### パラメータ

なし

#### 戻り値

なし


# appbase.py

シリアルデータ解釈のための基底クラス

## `class AppBase`

本コードでは、すべてのTWELITE APPS 共通で必要な機能が実装されており、シリアルデータの読み込みに必要なシリアルポートの開閉処理やシリアルデータの読み込み、ログファイルの出力などの処理が記述された基底クラスです。\
これを継承した [apppal.py](/1.1.0/source-files/mnlib/apppal.py) が得られたバイト列を解釈し、辞書オブジェクトにデータを入れてメイン関数に返します。

### `GetDataDict()`

ペイロードの解釈し、データを格納した辞書オブジェクトを返します。

#### パラメータ

なし

#### 戻り値

| 型    | 内容                         |
| ---- | -------------------------- |
| Dict | ペイロードを解釈したデータを格納した辞書オブジェクト |


# mwSerial.py

## `Class MWSerial`

本クラスはシリアルの読み書きなど、シリアルポートの管理を行うクラスです。

### 定義するときのパラメータ

初期値が設定されているものは指定不要。

| 変数名     | 型      | 初期値                 | 内容                                             |
| ------- | ------ | ------------------- | ---------------------------------------------- |
| port    | string | None                | <p>開くシリアルポート名</p><p>例：COM3、/dev/ttyUSB0 など</p> |
| baud    | int    | 115200              | ボーレート                                          |
| timeout | float  | 0.1                 | シリアル通信するときのタイムアウト時間(秒)                         |
| parity  | int    | serial.PARITY\_NONE | パリティを指定する                                      |
| stop    | int    | 1                   | ストップビット                                        |
| byte    | int    | 8                   | データビット長                                        |
| rtscts  | int    | 0                   | RTSとCTSを有効にする場合は1                              |
| dsrdtr  | int    | 0                   | DSRとDTRを有効にする場合は1                              |
| mode    | string | Ascii               | 本設定値はAsciiで固定                                  |

### `SerialSelect`

PCに接続されたシリアルポートを検索し、使用するシリアルポートをユーザー選択します。

シリアルポートが1ポートしかない場合は自動的にそのポート名を使用します。\
シリアルポートがない場合はNoneを指定します。\
シリアルポート名を引数に指定した場合はそのシリアルポートを使用します。

#### パラメータ

| 変数名      | 型      | 初期値  | 内容                                                                  |
| -------- | ------ | ---- | ------------------------------------------------------------------- |
| portname | string | None | <p>開くシリアルポート名 (例：COM3、/dev/ttyUSB0 など)</p><p>自動選択する場合は、指定しないこと。</p> |

#### 戻り値

なし


# parseFmt.py parseFmt\_\*.py

TWELITE シリアル書式パーサー

## `class FmtBase`

書式パーサーの基底クラスで共通手続きを定義する。これを継承した FmtAscii (アスキー形式 ASCII形式), FmtBinary (バイナリ形式 Binary形式) を利用する。

書式パーサーは、シリアル入力を想定し、アスキー形式の場合は１行単位でバイナリ形式の場合は１バイト単位で入力系列を解釈し、その系列が書式で定義されるヘッダ、フッタ、チェックサムを満足した時、解釈の完了とし、ヘッダ、フッタを除いた内容（ペイロード）を格納する。

### `process(c)`

入力文字列の解釈を行う。解釈後は  `is_complete()` が `true` を返した場合、解釈が成功し `get_payload()` によりペイロードを得ることができる。ペイロードは続く `process()` 処理などを実行すると内容を保証しないため、解釈終了後に速やかに利用します。

続けて別の系列を解釈したい場合は、そのまま `process()` を実行する。

#### パラメータ

| パラメータ | 内容                                                                                                                                                           |
| ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `c`   | 解釈したい入力系列。１バイト単位の解釈と系列単位の解釈の２種類に対応する。１バイト単位の入力では、int型のアスキーコード、str型、bytes型、list型の長さ1の系列。系列単位の入力では list 型、str型、bytes型の１系列を処理する。データに複数系列ある場合や途中で切れている場合は処理できない。 |
|       |                                                                                                                                                              |

#### 戻り値

なし

### `is_comp()`

`process()` 処理後に呼び出し、書式解釈の完了状況を知らせる。true を得た場合は `get_peyload()` または `get_payload_in_str()` メソッドにより、ペイロードを取得する。

{% hint style="info" %}
続く `process()` などの処理により、内部格納されるペイロードは初期化や破壊されるため、速やかにデータをコピーします。
{% endhint %}

#### パラメータ

なし

#### 戻り値

| 値       | 内容                    |
| ------- | --------------------- |
| `true`  | 解釈に成功した。ペイロードが利用できる。  |
| `false` | 解釈に失敗した、または、書式の途中である。 |

### `get_payload()`

ペイロードを返す。

#### パラメータ

なし

#### 戻り値

ヘッダやフッタが含まれないペイロード部を list型 バイト列として返します。

### `reinit()`

明示的に内部を初期状態にします。

#### パラメータ

なし

#### 戻り値

なし

### その他メソッド

内部で利用する目的でいくつかのメソッドが定義されています。詳細はソースコードを参照してください。

### コード例

### 系列単位の解釈

`str` 型の系列 `a` を解釈し、`pay` にペイロード情報保存します。`pay` には `[ 0x78, 0x80, 0x01, ... , 0x00 ]` が格納されます。

```python
import parseFmt_Ascii

fmta=parseFmt_Ascii.FmtAscii()
a = ':7880010F0F0380030002800200DF'
pay = []

fmta.process(a)

if fmta.is_comp():
    pay = fmta.get_payload()

```

１バイト単位の解釈

バイナリの系列 `b` について、１バイトごと `process()` メソッドにより系列の解釈を進めます。終端の `0x04` を投入した時点で、解釈が完了しペイロードが `pay` に保管されます。

```python
import parseFmt_Binary

fmtb=parseFmt_Binary.FmtBinary()
b = [0xA5, 0x5A, 0x80, 0x05, 0x78, 0x00, 0x11, 0x22, 0x33, 0x78, 0x04]
pay = []

for x in b:
  fmtb.process(x)
  
  if fmtb.is_comp():
    pay = fmtb.get_payload()
    break
    
```


# TWELITE PAL Script

TWELITE PAL Script は、TWELITE SENSE PAL (センサーパル) のデータの解釈、ログ記録するためのサンプルスクリプトです。

{% hint style="success" %}
[資料の取り扱いについて](https://twelite.gitbook.io/general/about_documents)をご参照ください。  お気付きの点がありましたら、当サポート窓口にご連絡いただければ幸いです。
{% endhint %}

{% hint style="danger" %}
本アプリケーションは参考として提供されています。

* 本アプリケーションならびに本ドキュメントは無保証です。
* 予告無く仕様が変更されます。
* モノワイヤレス ソフトウェア使用許諾 (MW-SLA-1J/E) に基づきます。
  {% endhint %}


# Usage

使用方法を解説します。

### PCの準備

1. ダウンロードしたアーカイブをわかりやすいフォルダ(例えばC:) に解凍する。
2. 下記WebページよりPCの環境にあったAnacondaをダウンロードし、インストールする。\
   <https://www.anaconda.com/download/>\
   Anacondaをインストールしたくない場合は”Anacondaをインストールしない場合”を参照
3. Anaconda Promptを立ち上げ、下記コマンドを実行しpyserialをインストールする。 (Windowsの場合、Anaconda Promptは スタートメニュー → Anaconda3 内にあるのでそちらから立ち上げること。)

```
> pip install pyserial
```

#### Anacondaをインストールしない場合

下記のインストール手順はOSがWindowsの場合の一例です。 各種ライブラリのドキュメントをご覧の上、必要なソフトウェアおよびライブラリをインストールしてください。

1. &#x20;下記ページよりPythonの最新版をダウンロードしインストールする。\
   <https://www.python.org/downloads/>\
   \
   その時、下図の枠で囲まれている部分にチェックを入れること\
   もしくはPythonのインストール先にPathを通すこと。

   <img src="/files/-LfwpZMjJy4R8PeBKRDY" alt="" data-size="original">
2. コマンドプロンプトを立ち上げ、下記コマンドを入力しpyserialをインストールする。

```
> pip install pyserial
```

### TWELITE PAL の準備

1. BLUE PAL/RED PALにSENSE PALを接続する。
2. BLUE PAL/RED PALの電池ホルダーにコイン型電池(CR2032)を挿入する。

### MONOSTICK の準備

1. MONOSTICKのアプリ（App\_PAL-Parent-xxx-MONOSTICK.bin）を書き換える。
2. MONOSTICKをリセットもしくはUSBポートに差しなおす。

### スクリプトの実行方法

MONOSTICKのCOMポートがCOM6の場合、Anaconda Promptで下記コマンドを実行すると下記のようなデータが出力されます。（Teratermが接続された状態では起動できません。）

```
> cd C:\PAL_Script
> python PAL_Script.py -t COM6
*** MONOWIRELESS App_PAL_Viewer 1.0.0 ***
{'ArriveTime': datetime.datetime(2018, 12, 25, 12, 16, 15, 148718), 'LogicalID': 6, 'EndDeviceSID': '82012395', 'RouterSID': '80000000', 'LQI': 114, 'SequenceNumber': 3185, 'Sensor': 128, 'PALID': 1, 'PALVersion': 1, 'Power': 2705, 'ADC1': 829, 'HALLIC': 129}
{'ArriveTime': datetime.datetime(2018, 12, 25, 12, 16, 19, 548512), 'LogicalID': 4, 'EndDeviceSID': '82012CD4', 'RouterSID': '80000000', 'LQI': 84, 'SequenceNumber': 10550, 'Sensor': 128, 'PALID': 2, 'PALVersion': 1, 'Power': 2600, 'ADC1': 791, 'Temperature': 27.2, 'Humidity': 20.9, 'Illuminance': 502}
…
```

スクリプトを終了させるにはAnaconda Promptで'Ctrl+C'を入力してください。

### スクリプトの引数

スクリプト実行時に以下の引数を使用できます。

#### 引数：-h

機能：コマンドライン引数の一覧を表示\
使用例：python PAL\_Script.py -h

#### 引数：-t

機能：MONOSTICKが使用するポート名を指定\
設定項目：MONOSTICKのポート名\
初期値：Windowsの場合：COM3、Linuxなどの場合：/dev/ttyUSB0\
使用例：python PAL\_Script.py -t COM6

#### 引数：-b

機能：MONOSTICKが使用するポートのボーレートを指定\
設定項目：MONOSTICKのボーレート\
初期値：115200\
使用例：python PAL\_Script.py -t COM6 -b 115200

#### 引数：-l

機能：CSV形式のログを出力\
使用例：python PAL\_Script.py -t COM6 -l\
備考：同一ディレクトリ内にCSVファイルが生成される。\
ファイル名はAppPAL\_シリアル番号\_PAL\_YYYYMMDD.csv

CSVファイルの読み方は下記表の通りです。

| 見出し                                                    | 値の説明         | 単位  |
| ------------------------------------------------------ | ------------ | --- |
| LogicalID                                              | 子機の論理デバイスID  | -   |
| EndDeviceSID                                           | 子機のシリアルナンバー  | -   |
| LQI                                                    | LQI          | -   |
| Power                                                  | 電源電圧         | mV  |
| ADC\*                                                  | 電圧           | mV  |
| HALLIC                                                 | マグネットセンサーの状態 | -   |
| Temperature                                            | 温度           | ℃   |
| Humidity                                               | 湿度           | %   |
| Illuminance                                            | 照度           | Lux |
| <p>AccelerationX<br>AccelerationY<br>AccelerationZ</p> | 加速度          | g   |


# Source Files

### 環境

以下の環境で動作確認を行いました。

* Windows10 Bulid 1809
  * python 3.6.4
  * pyserial  3.4


# Pal\_Script.py

メイン関数

本スクリプトを起動するためのコードで、主にMONOSTICKからのデータを読み込み、解釈されたデータの標準出力を行います。

### 読み出し方法

以下のコード例では、都度 MONOSTICK からデータを受信したかどうかを確認し、受信していれば標準出力とCSVファイルに書き出す処理を行っています。

```python
from apppal import AppPAL

if __name__ == '__main__':
	try:
		PAL = AppPAL(port=options.target, baud=options.baud, tout=0.05, sformat=options.format, err=bEnableErrMsg)
	except:
		print("Cannot open \"AppPAL\" class...")
		exit(1)

	while True:
		try:
			# データがあるかどうかの確認
			if PAL.ReadSensorData():
				# あったら辞書を取得する
				Data = PAL.GetDataDict()

				# なにか処理を記述する場合はこの下に書く
				print(Data)			# 受け取った辞書をそのまま標準出力する

				# ログを出力するオプションが有効だったらログを出力する。
				if bEnableLog == True:
					PAL.OutputCSV()	# CSVでログをとる

		# Ctrl+C でこのスクリプトを抜ける
		except KeyboardInterrupt:
			break

	del PAL

```

まず、AppPALオブジェクトを生成します。オブジェクト生成時にシリアルポートの設定も行うため、シリアルポートの設定パラメータを引数として渡します。

```python
PAL = AppPAL(port=options.target, baud=options.baud, tout=0.05, sformat=options.format, err=bEnableErrMsg)
```

次にシリアルデータが来ているかどうかを判断するために ReadSensorData() を呼び、返り値が True だったら、解釈したデータを受け取ります。

```
# データがあるかどうかの確認
if PAL.ReadSensorData():
	# あったら辞書を取得する
	Data = PAL.GetDataDict()
```

受け取る辞書に関しては[ここ](/master/source-files/mnlib/apppal.py#readsensordata)を参照してください。


# MNLib

本スクリプトでシリアルデータの読み込みやそれを解釈するコードが入ったフォルダです。


# apppal.py

読み込んだバイト列を解釈して辞書オブジェクトに登録するクラス

### `Class AppPAL`

AppBaseを継承し、得られたペイロードを解釈して、使いやすいデータに変換して、辞書オブジェクトに登録するクラスです。

#### 定義するときのパラメータ

初期値が設定されているものは指定不要。

| 変数名     | 型       | 初期値    | 内容                                             |
| ------- | ------- | ------ | ---------------------------------------------- |
| port    | string  | None   | <p>開くシリアルポート名</p><p>例：COM3、/dev/ttyUSB0 など</p> |
| baud    | int     | 115200 | ボーレート                                          |
| tout    | float   | 0.1    | シリアル通信するときのタイムアウト時間(秒)                         |
| sformat | string  | Ascii  | 本設定値はAsciiで固定                                  |
| autolog | boolean | False  | ペイロードが解釈出来たときに自動でCSVファイルにログを出力する場合はTrue        |
| err     | boolean | False  | エラーメッセージを出力する場合はTrue                           |

### `ReadSensorData()`

本メソッドで読み込めたペイロードがあれば、 [TWELITE PAL 親機の書式フォーマット](https://mono-wireless.com/jp/products/TWE-APPS/App_pal/parent.html) に従ってそのペイロードの解釈を行います。

{% hint style="info" %}
[TWELITE PAL 親機の書式フォーマット](https://mono-wireless.com/jp/products/TWE-APPS/App_pal/parent.html) (ASCII形式のみ) を解釈しています。多くはその定義に従います。
{% endhint %}

#### パラメータ

なし

#### 戻り値

* データが読み込めた場合：`True`
* 読み込めなかった場合：`False`

辞書オブジェクトに格納されたデータのキーは下記の通りです。

{% hint style="info" %}
EventIDなどのデータの意味に関しては、[こちら](https://wings.twelite.info/how-to-use/parent-mode/receive-message/app_pal#chu-li-shu-shi)もご確認ください。
{% endhint %}

| キー                | 型          | 内容                                                              |
| ----------------- | ---------- | --------------------------------------------------------------- |
| ArriveTime        | datetime   | ペイロードを得たときの時間                                                   |
| LogicalID         | int        | 子機の論理デバイスID                                                     |
| EndDeviceSID      | int        | 子機のシリアル番号                                                       |
| RouterSID         | int        | <p>最初に受信した中継機のシリアル番号</p><p>(親機が直接子機のパケットを受信した場合は0x80000000)</p> |
| LQI               | int        | 受信電波品質                                                          |
| SequenceNumber    | int        | <p>パケットが送信されるごとにインクリメントされる続き番号</p><p>1からスタート、65535の次に0に戻る</p>   |
| Sensor            | int        | センサー種別（0x80で固定）                                                 |
| PALID             | int        | PAL基板ID                                                         |
| PALVersion        | int        | PAL基板バージョン                                                      |
| HALLIC            | int        | ホールICの状態                                                        |
| Temperature       | float      | 温度(degC)                                                        |
| Humidity          | float      | 湿度(%)                                                           |
| Illuminance       | int        | 照度(lux)                                                         |
| AccelerationX     | list,float | X軸の加速度(g)                                                       |
| AccelerationY     | list,float | Y軸の加速度(g)                                                       |
| AccelerationZ     | list,float | Z軸の加速度(g)                                                       |
| SamplingFrequency | int        | 加速度のサンプリング周波数                                                   |
| EventID           | list,int   | イベントの要因とイベントID                                                  |
| WakeupFactor      | list,int   | 起床した要因等のデータ                                                     |

### `OutputCSV()`

辞書オブジェクトをCSVファイルに出力します。

#### パラメータ

なし

#### 戻り値

なし


# appbase.py

シリアルデータ解釈のための基底クラス

### `class AppBase`

本コードでは、すべてのTWELITE APPS 共通で必要な機能が実装されており、シリアルデータの読み込みに必要なシリアルポートの開閉処理やシリアルデータの読み込み、ログファイルの出力などの処理が記述された基底クラスです。\
これを継承した [apppal.py](/master/source-files/mnlib/apppal.py) が得られたバイト列を解釈し、辞書オブジェクトにデータを入れてメイン関数に返します。

#### `GetDataDict()`

ペイロードの解釈し、データを格納した辞書オブジェクトを返します。

#### パラメータ

なし

#### 戻り値

| 型    | 内容                         |
| ---- | -------------------------- |
| Dict | ペイロードを解釈したデータを格納した辞書オブジェクト |


# readSerial.py

### `Class ReadSerial`

本クラスはシリアルデータを読み込み、`FmtAscii` クラスや、`FmtBinary` クラスを制御して、シリアルデータのペイロードを渡すためのクラスです。

### `ReadSerialLine()`

シリアルデータを読み込み、それを書式パーサに渡してシリアルデータの解釈してペイロードだけの状態になったか判定を行います。

#### 引数

なし

#### 返り値

なし

### `IsDataArrived()`

ペイロードを受信したかどうかを返します。

#### 引数

なし

#### 戻り値

| 型       | 内容                           |
| ------- | ---------------------------- |
| boolean | ペイロードが受信できればTrue、できなければFalse |

### `GetPayload()`

ペイロードを取得します。

#### 引数

なし

#### 戻り値

| 型          | 内容    |
| ---------- | ----- |
| byte, list | ペイロード |


# parseFmt.py parseFmt\_\*.py

TWELITE シリアル書式パーサー

## `class FmtBase`

書式パーサーの基底クラスで共通手続きを定義する。これを継承した FmtAscii (アスキー形式 ASCII形式), FmtBinary (バイナリ形式 Binary形式) を利用する。

書式パーサーは、シリアル入力を想定し、アスキー形式の場合は１行単位でバイナリ形式の場合は１バイト単位で入力系列を解釈し、その系列が書式で定義されるヘッダ、フッタ、チェックサムを満足した時、解釈の完了とし、ヘッダ、フッタを除いた内容（ペイロード）を格納する。

### `process(c)`

入力文字列の解釈を行う。解釈後は  `is_complete()` が `true` を返した場合、解釈が成功し `get_payload()` によりペイロードを得ることができる。ペイロードは続く `process()` 処理などを実行すると内容を保証しないため、解釈終了後に速やかに利用します。

続けて別の系列を解釈したい場合は、そのまま `process()` を実行する。

#### パラメータ

| パラメータ | 内容                                                                                                                                                           |
| ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `c`   | 解釈したい入力系列。１バイト単位の解釈と系列単位の解釈の２種類に対応する。１バイト単位の入力では、int型のアスキーコード、str型、bytes型、list型の長さ1の系列。系列単位の入力では list 型、str型、bytes型の１系列を処理する。データに複数系列ある場合や途中で切れている場合は処理できない。 |
|       |                                                                                                                                                              |

#### 戻り値

なし

### `is_comp()`

`process()` 処理後に呼び出し、書式解釈の完了状況を知らせる。true を得た場合は `get_peyload()` または `get_payload_in_str()` メソッドにより、ペイロードを取得する。

{% hint style="info" %}
続く `process()` などの処理により、内部格納されるペイロードは初期化や破壊されるため、速やかにデータをコピーします。
{% endhint %}

#### パラメータ

なし

#### 戻り値

| 値       | 内容                    |
| ------- | --------------------- |
| `true`  | 解釈に成功した。ペイロードが利用できる。  |
| `false` | 解釈に失敗した、または、書式の途中である。 |

### `get_payload()`

ペイロードを返す。

#### パラメータ

なし

#### 戻り値

ヘッダやフッタが含まれないペイロード部を list型 バイト列として返します。

### `reinit()`

明示的に内部を初期状態にします。

#### パラメータ

なし

#### 戻り値

なし

### その他メソッド

内部で利用する目的でいくつかのメソッドが定義されています。詳細はソースコードを参照してください。

### コード例

### 系列単位の解釈

`str` 型の系列 `a` を解釈し、`pay` にペイロード情報保存します。`pay` には `[ 0x78, 0x80, 0x01, ... , 0x00 ]` が格納されます。

```python
import parseFmt_Ascii

fmta=parseFmt_Ascii.FmtAscii()
a = ':7880010F0F0380030002800200DF'
pay = []

fmta.process(a)

if fmta.is_comp():
    pay = fmta.get_payload()

```

１バイト単位の解釈

バイナリの系列 `b` について、１バイトごと `process()` メソッドにより系列の解釈を進めます。終端の `0x04` を投入した時点で、解釈が完了しペイロードが `pay` に保管されます。

```python
import parseFmt_Binary

fmtb=parseFmt_Binary.FmtBinary()
b = [0xA5, 0x5A, 0x80, 0x05, 0x78, 0x00, 0x11, 0x22, 0x33, 0x78, 0x04]
pay = []

for x in b:
  fmtb.process(x)
  
  if fmtb.is_comp():
    pay = fmtb.get_payload()
    break
    
```


# TWELITE PAL/CUE/ARIA Script

TWELITE PAL Script は、TWELITE SENSE PAL (センサーパル), TWELITE CUE (加速度センサー・磁気センサー), TWELITE ARIA (温湿度センサー・磁気センサー) のデータの解釈、ログ記録するためのサンプルスクリプトです。

{% hint style="success" %}
[資料の取り扱いについて](https://twelite.gitbook.io/general/about_documents)をご参照ください。  お気付きの点がありましたら、当サポート窓口にご連絡いただければ幸いです。
{% endhint %}

{% hint style="danger" %}
本アプリケーションは参考として提供されています。

* 本アプリケーションならびに本ドキュメントは無保証です。
* 予告無く仕様が変更されます。
* モノワイヤレス ソフトウェア使用許諾 (MW-SLA-1J/E) に基づきます。
  {% endhint %}


# Usage

使用方法を解説します。

### PCの準備

1. ダウンロードしたアーカイブをわかりやすいフォルダ(例えばC:) に解凍する。
2. 下記WebページよりPCの環境にあったAnacondaをダウンロードし、インストールする。\
   <https://www.anaconda.com/download/>\
   Anacondaをインストールしたくない場合は”Anacondaをインストールしない場合”を参照
3. Anaconda Promptを立ち上げ、下記コマンドを実行しpyserialをインストールする。 (Windowsの場合、Anaconda Promptは スタートメニュー → Anaconda3 内にあるのでそちらから立ち上げること。)

```
> pip install pyserial
```

#### Anacondaをインストールしない場合

下記のインストール手順はOSがWindowsの場合の一例です。 各種ライブラリのドキュメントをご覧の上、必要なソフトウェアおよびライブラリをインストールしてください。

1. &#x20;下記ページよりPythonの最新版をダウンロードしインストールする。\
   <https://www.python.org/downloads/>\
   \
   その時、下図の枠で囲まれている部分にチェックを入れること\
   もしくはPythonのインストール先にPathを通すこと。

   <img src="/files/-LfwpZMjJy4R8PeBKRDY" alt="" data-size="original">
2. コマンドプロンプトを立ち上げ、下記コマンドを入力しpyserialをインストールする。

```
> pip install pyserial
```

### TWELITE PAL の準備

1. BLUE PAL/RED PALにSENSE PALを接続する。
2. BLUE PAL/RED PALの電池ホルダーにコイン型電池(CR2032)を挿入する。

### MONOSTICK の準備

1. MONOSTICKのアプリ（App\_PAL-Parent-xxx-MONOSTICK.bin）を書き換える。
2. MONOSTICKをリセットもしくはUSBポートに差しなおす。

### スクリプトの実行方法

MONOSTICKのCOMポートがCOM6の場合、Anaconda Promptで下記コマンドを実行すると下記のようなデータが出力されます。（Teratermが接続された状態では起動できません。）

```
> cd C:\PAL_Script
> python PAL_Script.py -t COM6
*** MONOWIRELESS App_PAL_Viewer 1.1.0 ***
  *** Open COM6 ***
ArriveTime : 2021/03/05 09:43:28.880
LogicalID : 1
EndDeviceSID : 10B6465
RouterSID : No Relay
LQI : 180 (-35.50 [dBm])
…
```

スクリプトを終了させるにはAnaconda Promptで'Ctrl+C'を入力してください。

### スクリプトの引数

スクリプト実行時に以下の引数を使用できます。

#### 引数：-h

機能：コマンドライン引数の一覧を表示\
使用例：python PAL\_Script.py -h

#### 引数：-t

機能：MONOSTICKが使用するポート名を指定\
設定項目：MONOSTICKのポート名\
初期値：Windowsの場合：COM3、Linuxなどの場合：/dev/ttyUSB0\
使用例：python PAL\_Script.py -t COM6

#### 引数：-b

機能：MONOSTICKが使用するポートのボーレートを指定\
設定項目：MONOSTICKのボーレート\
初期値：115200\
使用例：python PAL\_Script.py -t COM6 -b 115200

#### 引数：-l

機能：CSV形式のログを出力\
使用例：python PAL\_Script.py -t COM6 -l\
備考：同一ディレクトリ内にCSVファイルが生成される。\
ファイル名はAppPAL\_シリアル番号\_PAL\_YYYYMMDD.csv

CSVファイルの読み方は下記表の通りです。

| 見出し                                                    | 値の説明         | 単位  |
| ------------------------------------------------------ | ------------ | --- |
| LogicalID                                              | 子機の論理デバイスID  | -   |
| EndDeviceSID                                           | 子機のシリアルナンバー  | -   |
| LQI                                                    | LQI          | -   |
| Power                                                  | 電源電圧         | mV  |
| ADC\*                                                  | 電圧           | mV  |
| HALLIC                                                 | マグネットセンサーの状態 | -   |
| Temperature                                            | 温度           | ℃   |
| Humidity                                               | 湿度           | %   |
| Illuminance                                            | 照度           | Lux |
| <p>AccelerationX<br>AccelerationY<br>AccelerationZ</p> | 加速度          | g   |


# Source Files

### 環境

以下の環境で動作確認を行いました。

* Windows10 Bulid 1809
  * python 3.6.4
  * pyserial  3.4


# Pal\_Script.py

実行用スクリプト

本スクリプトを起動するためのコードで、主にMONOSTICKからのデータを読み込み、ユーザーが記述するMain()に読み込んだデータを渡します。

### 読み出し方法

以下のコード例では、都度 MONOSTICK からデータを受信したかどうかを確認し、受信していればMain()に渡す処理を行っています。

```python
from apppal import AppPAL

...

def mainloop(PAL):
	global end_flag

	try:
		from Main_user import Main
	except:
		mainflag = False
	else:
		mainflag = True

	if PAL.ReadSensorData():
		if mainflag:
			Main(PAL)
		else:
			PAL.ShowSensorData()

...

if __name__ == '__main__':
...

	try:
		PAL = AppPAL(port=options.target, baud=options.baud, tout=0.05, sformat=options.format, autolog=bEnableLog, err=bEnableErrMsg, stdinput=options.stdinp, Logfilename=options.file)
	except:
		print("Cannot open \"AppPAL\" class...")
		exit(1)

	while True:
		try:
			mainloop(PAL)
		except KeyboardInterrupt:
			break

	del PAL
```

まず、AppPALオブジェクトを生成します。オブジェクト生成時にシリアルポートの設定も行うため、シリアルポートの設定パラメータを引数として渡します。

```python
PPAL = AppPAL(port=options.target, baud=options.baud, tout=0.05, sformat=options.format, autolog=bEnableLog, err=bEnableErrMsg, stdinput=options.stdinp, Logfilename=options.file)
```

次にmainloop()でシリアルデータが来ているかどうかを判断するために ReadSensorData() を呼びます。返り値が True だったら、解釈したをMain()に渡します。

```python
def mainloop(PAL):
	# ユーザが処理を記述するMain関数がインポートできるか確認する。
	try:
		from Main_user import Main
	except:
		mainflag = False
	else:
		mainflag = True

	# データがあるかどうかの確認
	if PAL.ReadSensorData():
		if mainflag:
			# Main関数が読めたらPALオブジェクトをMain()に渡す
			Main(PAL)
		else:
			# Main関数が読めなかったらコンソールにデータを表示する。
			PAL.ShowSensorData()
```

受け取る辞書に関しては[ここ](/source-files/mnlib/apppal.py#readsensordata)を参照してください。


# Main\_user.py

メイン関数

本コードにはデータが読み込めた後のメインの処理を記述します。

ここではデータを受け取ったらコンソールに解釈したデータを出力するコードが記述されています。

```python
# この関数に処理したい内容を書く
def Main(PAL=None):
	# 渡された変数がAppPALクラスか確認する。
	if isinstance(PAL, AppPAL):
		sns_data = PAL.GetDataDict()

		# 受信時間
		print('Receive Time: ', end='')
		if isinstance(sns_data['ArriveTime'], datetime.datetime):
			print(sns_data['ArriveTime'].strftime('%Y/%m/%d %H:%M:%S') + '.%03d'%(sns_data['ArriveTime'].microsecond/1000))
		else:
			print(sns_data['ArriveTime'])

		# 論理デバイスID
		print('Logical ID: 0x%02X'%sns_data['LogicalID'])
		# シリアル番号
		print('Serial ID: 0x' + sns_data['EndDeviceSID'])
		# 電源電圧
		print('Power: %d mV' % sns_data['Power'])

		# センサーの名前を調べる
		sname  = PAL.GetSensorName()

		# センサー名がPALだったらPAL/ARIA/CUE、モデル名を出力する。
		if sname == 'PAL':
			pid = PAL.GetPALName()
			print('Sensor: ' + pid )
		else:
			print('Sensor: ' + sname )

		# アナログセンサーモード(App_Tag)
		if sname == 'Analog':
			print('ADC1: %d mV'%sns_data['ADC1'])
			print('ADC2: %d mV'%sns_data['ADC2'])
		else:
			# ホールIC
			if 'HALLIC' in sns_data.keys():
				print('HALLIC: %d'%sns_data['HALLIC'])

			# 温度
			if 'Temperature' in sns_data.keys():
				print('Temperature: %.02f degC'%sns_data['Temperature'])

			# 湿度
			if 'Humidity' in sns_data.keys():
				print('Humidity: %.02f %%'%sns_data['Humidity'])

			# 照度
			if 'Illuminance' in sns_data.keys():
				print('Illuminance: %f lux'%sns_data['Illuminance'])

			# 気圧
			if 'Pressure' in sns_data.keys():
				print('Pressure: %f hPa'%sns_data['Pressure'])

			# 加速度
			if 'AccelerationX' in sns_data.keys():
				print('X: ', end='')
				print(sns_data['AccelerationX'])
				print('Y: ', end='')
				print(sns_data['AccelerationY'])
				print('Z: ', end='')
				print(sns_data['AccelerationZ'])

			# ジャイロ
			if 'Roll' in sns_data.keys():
				print('Roll: ', end='')
				print(sns_data['Roll'])
				print('Pitch: ', end='')
				print(sns_data['Pitch'])
				print('Yaw: ', end='')
				print(sns_data['Yaw'])

			# カラーセンサー
			if 'Red' in sns_data.keys():
				print('Red: ', end='')
				print(sns_data['Red'])
				print('Green: ', end='')
				print(sns_data['Green'])
				print('Blue: ', end='')
				print(sns_data['Blue'])
				print('IR: ', end='')
				print(sns_data['IR'])


		print()
```


# MNLib

本スクリプトでシリアルデータの読み込みやそれを解釈するコードが入ったフォルダです。


# apppal.py

読み込んだバイト列を解釈して辞書オブジェクトに登録するクラス

## `Class AppPAL`

AppBaseを継承し、得られたペイロードを解釈して、使いやすいデータに変換して、辞書オブジェクトに登録するクラスです。

### 定義するときのパラメータ

初期値が設定されているものは指定不要。

| 変数名     | 型       | 初期値    | 内容                                             |
| ------- | ------- | ------ | ---------------------------------------------- |
| port    | string  | None   | <p>開くシリアルポート名</p><p>例：COM3、/dev/ttyUSB0 など</p> |
| baud    | int     | 115200 | ボーレート                                          |
| tout    | float   | 0.1    | シリアル通信するときのタイムアウト時間(秒)                         |
| sformat | string  | Ascii  | 本設定値はAsciiで固定                                  |
| autolog | boolean | False  | ペイロードが解釈出来たときに自動でCSVファイルにログを出力する場合はTrue        |
| err     | boolean | False  | エラーメッセージを出力する場合はTrue                           |

### `ReadSensorData()`

本メソッドで読み込めたペイロードがあれば、 [TWELITE PAL 親機の書式フォーマット](https://mono-wireless.com/jp/products/TWE-APPS/App_pal/parent.html) に従ってそのペイロードの解釈を行います。

{% hint style="info" %}
[TWELITE PAL 親機の書式フォーマット](https://mono-wireless.com/jp/products/TWE-APPS/App_pal/parent.html) (ASCII形式のみ) を解釈しています。多くはその定義に従います。
{% endhint %}

#### パラメータ

なし

#### 戻り値

* データが読み込めた場合：`True`
* 読み込めなかった場合：`False`

辞書オブジェクトに格納されたデータのキーは下記の通りです。

{% hint style="info" %}
EventIDなどのデータの意味に関しては、[こちら](https://wings.twelite.info/how-to-use/parent-mode/receive-message/app_pal#chu-li-shu-shi)もご確認ください。
{% endhint %}

| キー                | 型          | 内容                                                              |
| ----------------- | ---------- | --------------------------------------------------------------- |
| ArriveTime        | datetime   | ペイロードを得たときの時間                                                   |
| LogicalID         | int        | 子機の論理デバイスID                                                     |
| EndDeviceSID      | int        | 子機のシリアル番号                                                       |
| RouterSID         | int        | <p>最初に受信した中継機のシリアル番号</p><p>(親機が直接子機のパケットを受信した場合は0x80000000)</p> |
| LQI               | int        | 受信電波品質                                                          |
| SequenceNumber    | int        | <p>パケットが送信されるごとにインクリメントされる続き番号</p><p>1からスタート、65535の次に0に戻る</p>   |
| Sensor            | int        | センサー種別（0x80で固定）                                                 |
| PALID             | int        | PAL基板ID                                                         |
| PALVersion        | int        | PAL基板バージョン                                                      |
| HALLIC            | int        | ホールICの状態                                                        |
| Temperature       | float      | 温度(degC)                                                        |
| Humidity          | float      | 湿度(%)                                                           |
| Illuminance       | int        | 照度(lux)                                                         |
| AccelerationX     | list,float | X軸の加速度(g)                                                       |
| AccelerationY     | list,float | Y軸の加速度(g)                                                       |
| AccelerationZ     | list,float | Z軸の加速度(g)                                                       |
| SamplingFrequency | int        | 加速度のサンプリング周波数                                                   |
| EventID           | list,int   | イベントの要因とイベントID                                                  |
| WakeupFactor      | list,int   | 起床した要因等のデータ                                                     |

### `OutputCSV()`

辞書オブジェクトをCSVファイルに出力します。

#### パラメータ

なし

#### 戻り値

なし


# appbase.py

シリアルデータ解釈のための基底クラス

## `class AppBase`

本コードでは、すべてのTWELITE APPS 共通で必要な機能が実装されており、シリアルデータの読み込みに必要なシリアルポートの開閉処理やシリアルデータの読み込み、ログファイルの出力などの処理が記述された基底クラスです。\
これを継承した [apppal.py](/source-files/mnlib/apppal.py) が得られたバイト列を解釈し、辞書オブジェクトにデータを入れてメイン関数に返します。

### `GetDataDict()`

ペイロードの解釈し、データを格納した辞書オブジェクトを返します。

#### パラメータ

なし

#### 戻り値

| 型    | 内容                         |
| ---- | -------------------------- |
| Dict | ペイロードを解釈したデータを格納した辞書オブジェクト |


# mwSerial.py

## `Class MWSerial`

本クラスはシリアルの読み書きなど、シリアルポートの管理を行うクラスです。

### 定義するときのパラメータ

初期値が設定されているものは指定不要。

| 変数名     | 型      | 初期値                 | 内容                                             |
| ------- | ------ | ------------------- | ---------------------------------------------- |
| port    | string | None                | <p>開くシリアルポート名</p><p>例：COM3、/dev/ttyUSB0 など</p> |
| baud    | int    | 115200              | ボーレート                                          |
| timeout | float  | 0.1                 | シリアル通信するときのタイムアウト時間(秒)                         |
| parity  | int    | serial.PARITY\_NONE | パリティを指定する                                      |
| stop    | int    | 1                   | ストップビット                                        |
| byte    | int    | 8                   | データビット長                                        |
| rtscts  | int    | 0                   | RTSとCTSを有効にする場合は1                              |
| dsrdtr  | int    | 0                   | DSRとDTRを有効にする場合は1                              |
| mode    | string | Ascii               | 本設定値はAsciiで固定                                  |

### `SerialSelect`

PCに接続されたシリアルポートを検索し、使用するシリアルポートをユーザー選択します。

シリアルポートが1ポートしかない場合は自動的にそのポート名を使用します。\
シリアルポートがない場合はNoneを指定します。\
シリアルポート名を引数に指定した場合はそのシリアルポートを使用します。

#### パラメータ

| 変数名      | 型      | 初期値  | 内容                                                                  |
| -------- | ------ | ---- | ------------------------------------------------------------------- |
| portname | string | None | <p>開くシリアルポート名 (例：COM3、/dev/ttyUSB0 など)</p><p>自動選択する場合は、指定しないこと。</p> |

#### 戻り値

なし


# parseFmt.py parseFmt\_\*.py

TWELITE シリアル書式パーサー

## `class FmtBase`

書式パーサーの基底クラスで共通手続きを定義する。これを継承した FmtAscii (アスキー形式 ASCII形式), FmtBinary (バイナリ形式 Binary形式) を利用する。

書式パーサーは、シリアル入力を想定し、アスキー形式の場合は１行単位でバイナリ形式の場合は１バイト単位で入力系列を解釈し、その系列が書式で定義されるヘッダ、フッタ、チェックサムを満足した時、解釈の完了とし、ヘッダ、フッタを除いた内容（ペイロード）を格納する。

### `process(c)`

入力文字列の解釈を行う。解釈後は  `is_complete()` が `true` を返した場合、解釈が成功し `get_payload()` によりペイロードを得ることができる。ペイロードは続く `process()` 処理などを実行すると内容を保証しないため、解釈終了後に速やかに利用します。

続けて別の系列を解釈したい場合は、そのまま `process()` を実行する。

#### パラメータ

| パラメータ | 内容                                                                                                                                                           |
| ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `c`   | 解釈したい入力系列。１バイト単位の解釈と系列単位の解釈の２種類に対応する。１バイト単位の入力では、int型のアスキーコード、str型、bytes型、list型の長さ1の系列。系列単位の入力では list 型、str型、bytes型の１系列を処理する。データに複数系列ある場合や途中で切れている場合は処理できない。 |
|       |                                                                                                                                                              |

#### 戻り値

なし

### `is_comp()`

`process()` 処理後に呼び出し、書式解釈の完了状況を知らせる。true を得た場合は `get_peyload()` または `get_payload_in_str()` メソッドにより、ペイロードを取得する。

{% hint style="info" %}
続く `process()` などの処理により、内部格納されるペイロードは初期化や破壊されるため、速やかにデータをコピーします。
{% endhint %}

#### パラメータ

なし

#### 戻り値

| 値       | 内容                    |
| ------- | --------------------- |
| `true`  | 解釈に成功した。ペイロードが利用できる。  |
| `false` | 解釈に失敗した、または、書式の途中である。 |

### `get_payload()`

ペイロードを返す。

#### パラメータ

なし

#### 戻り値

ヘッダやフッタが含まれないペイロード部を list型 バイト列として返します。

### `reinit()`

明示的に内部を初期状態にします。

#### パラメータ

なし

#### 戻り値

なし

### その他メソッド

内部で利用する目的でいくつかのメソッドが定義されています。詳細はソースコードを参照してください。

### コード例

### 系列単位の解釈

`str` 型の系列 `a` を解釈し、`pay` にペイロード情報保存します。`pay` には `[ 0x78, 0x80, 0x01, ... , 0x00 ]` が格納されます。

```python
import parseFmt_Ascii

fmta=parseFmt_Ascii.FmtAscii()
a = ':7880010F0F0380030002800200DF'
pay = []

fmta.process(a)

if fmta.is_comp():
    pay = fmta.get_payload()

```

１バイト単位の解釈

バイナリの系列 `b` について、１バイトごと `process()` メソッドにより系列の解釈を進めます。終端の `0x04` を投入した時点で、解釈が完了しペイロードが `pay` に保管されます。

```python
import parseFmt_Binary

fmtb=parseFmt_Binary.FmtBinary()
b = [0xA5, 0x5A, 0x80, 0x05, 0x78, 0x00, 0x11, 0x22, 0x33, 0x78, 0x04]
pay = []

for x in b:
  fmtb.process(x)
  
  if fmtb.is_comp():
    pay = fmtb.get_payload()
    break
    
```


