セクションの複数ページをまとめています。 印刷またはPDF形式で保存...

もとのページに戻る

2024-02-22 現在

スタートガイド

ここでは、最初に目を通していただきたい情報を掲載しています。

1 - TWELITE SPOT

TWELITE と Wi-Fi のネットワークを連携させる
無線LANゲートウェイ TWELITE SPOT は、低消費電力が特徴の無線マイコンモジュール TWELITE と 無線 LAN マイコンモジュール ESP32 を組み合わせた製品です。ESP32 のファームウェアを開発することで、TWELITE のネットワークと Wi-Fi ネットワークを連携させることができます。

TWELITE と ESP32 で広がる世界

TWELITE SPOT は、小型で省電力、さらにペアリングをしないため多くの端末を同時に使用できる TWELITE シリーズと無線 LAN マイコンモジュール ESP32 を組み合わせた製品です。

外観

外観

内部構成

内部構成

ESP32 のファームウェアを開発することで、例えば下記のようなシステムを実現できます。

ローカルサーバローカルゲートウェイIoT ゲートウェイ
TWELITE 子機のデータを LAN 内で共有TWELITE 子機のデータを LAN 内で利用TWELITE 子機のデータをクラウドに利用

ローカルサーバ

ESP32 をサーバとして使用します。例えば、TWELITE CUE が計測した加速度データをスマートフォンに表示したり、TWELITE DIP の出力ポートをスマートフォンで操作したりすることができます。

ローカルゲートウェイ

ESP32 を LAN に接続します。例えば、ビル全体に設置した TWELITE ARIA が送るデータを各フロアの TWELITE SPOT で受信し、LAN 上のサーバに全フロアの温湿度データを集約することができます。

IoT ゲートウェイ

ESP32 をインターネットに接続します。例えば、TWELITE CUE と磁石をドアに取り付け、取得したドアの開閉状態から、ドアが開いたままであることをクラウド上で検知できます。

Arduino IDE と専用ライブラリによる開発

TWELITE SPOT によるシステムを構築するには、ESP32 のファームウェアを開発する必要があります。

このとき、ESP32 のファームウェア開発には Arduino IDE が使用できます。

Arduino IDE を使った開発の様子

Arduino IDE を使った開発の様子

Arduino ライブラリマネージャで配布中の MWings ライブラリ により、TWELITE 子機からのパケット受信や TWELITE 子機へのコマンド送信を簡単に行うことができます。

スタートガイドの流れ

このスタートガイドでは、TWELITE SPOT の動作確認、ESP32 開発環境の構築、簡単なスケッチの作成および書き込みを行います。

1. TWELITE SPOT の動作を確認する

まずは使ってみる

内容

TWELITE SPOT にプリインストールされているアプリを使って、加速度センサー無線タグ TWELITE CUE のデータをスマートフォンで閲覧してみます。

必要なもの
TWELITE SPOTTWELITE CUE
TWELITE 親機TWELITE 子機

2. ESP32 の Hello World を行う

ESP32 を使ったファームウェア開発の基礎

内容

開発環境の構築、Hello World スケッチの作成・書き込み、動作確認を行ってみます。

必要なもの
TWELITE SPOTTWELITE R3
ファームウェアを書き込むための TWELITE SPOT 本体PC と TWELITE SPOT を接続するための USB アダプター

3. TWELITE CUE からデータを取得する

TWELITE との通信

内容

TWELITE CUE の加速度データを ESP32 から出力してみます。

必要なもの
TWELITE SPOTTWELITE CUETWELITE R3
ファームウェアを書き込むための TWELITE SPOT 本体TWELITE SPOT と通信するための TWELITE 子機PC と TWELITE SPOT を接続するための USB アダプター

1.1 - まずは使ってみる

TWELITE SPOT と TWELITE CUE を使って、スマホに加速度情報を表示してみる
TWELITE SPOT では、ESP32 上の Web サーバに動的なページをホストすることで、TWELITE 子機から受信したデータをネットワーク内に配信できます。
動作イメージ

動作イメージ

ここでは、TWELITE SPOT が無線 LAN のアクセスポイントとして機能します。

用意するもの

TWELITE SPOT の動作を確認する

1. 本体を起動する ⚡

TWELITE SPOT の側面に USB-C ケーブルを接続し、USB AC アダプタから電源を供給してください。

USB 電源の接続

USB 電源の接続

2. TWELITE CUE を起動する ⚡

TWELITE CUE に CR2032 型コイン電池を挿入してください。ただちに動作を開始します。

コイン電池の挿入

コイン電池の挿入

3. スマートフォンを接続する 📱

スマートフォンの Wi-Fi 設定からネットワーク TWELITE SPOT (XXXX) に接続してください。

4. Webブラウザを開く 🌐

スマートフォンのWebブラウザを開き、spot.local へアクセスしてください。

以下のような画面が表示されます。

トップページ

トップページ

5. CUE ビューアを開く 📈

CUE Viewer をタップして、CUE ビューアの画面を開いてください。

以下のような画面が表示されます。

CUE Viewer

1.2 - ESP32 を使ったファームウェア開発の基礎

TWELITE SPOT のファームウェア開発に向けて、ESP32 の Hello World を試す

ESP32 は、単体でも無線 LAN によるシステムを構築することができます。例えば、ホストした Web ページにデータを表示したり、データを WebSocket で LAN 内のサーバに送信したり、クラウドサービスへ REST API を投げたりすることができます。

TWELITE SPOT は、この ESP32 に TWELITE を組み合わせることで、多数の小型で省電力な無線タグを利用できるようにした製品です。

用意するもの

環境を構築する

1. IDE を導入する 🚛

コンピュータに Arduino IDE 1.x を導入していない場合は、Arduino 公式ダウンロードページから Legacy IDE (1.8.X) をダウンロードのうえ、これをインストールしてください。

2. ツールチェインを導入する 🚚

Arduino IDE 1.x に Arduino core for the ESP32 を導入していない場合は、ボードマネージャの URL に下記を追加し、esp32 ボード定義をインストールしてください。

        
https://espressif.github.io/arduino-esp32/package_esp32_index.json

3. ボード設定を行う ⚙️

TWELITE SPOT に合わせて、Arduino core for the ESP32 の設定を行います。

ボード種別を選択する

ツールバーの ツール -> ボード -> ESP32 Arduino -> ESP32 Dev Module を選択してください。

ESP32 Dev Module の場所

ESP32 Dev Module の場所

ボード設定を行う

下図と同様に設定してください。

設定後の内容

設定後の内容

TWELITE SPOT を準備する

1. フタをはずす ⛏️

TWELITE SPOT のケース上面のフタをはずしてください。

スイッチやコネクタ類が露出します。

各部の名称

各部の名称

2. TWELITE R3 / R2 をつなぐ 🔌

ESP32用 7P インターフェイス(ESP32 と記載)に TWELITE R3 / R2 を接続してください。

接続例 (ESP32)

接続例 (ESP32)

3. USB-C 電源をつなぐ ⚡

側面の USB-C コネクタ に 5V 電源を供給してください。

スケッチを動かす

Arduino では、プログラムコード/プロジェクトのことをスケッチと呼びます。

1. スケッチを作成する 👨‍💻

ESP32 から文字列をシリアル出力し、Arduino IDE のシリアルモニタに出力する Hello World スケッチを作成します。

スケッチ作成画面

スケッチ作成画面

Arduino IDE を起動して、下記のコードを入力してください。

        
void setup() {
  Serial.begin(115200);
  Serial.println("Hello, World!");
}

void loop() {
}

setup() の内容は起動時に一度だけ実行されます。一方、loop() の内容は際限なく繰り返し実行されます。

2行目では、シリアルポートのボーレート(通信速度)を 115200bps に設定しています。

        
  Serial.begin(115200);

3行目では、"Hello, World!" という文字列をシリアルポートに出力しています。

        
  Serial.println("Hello, World!");

2. スケッチを書き込む ⚒️

シリアルポートを選択する

ツール -> シリアルポート メニューから、 接続したデバイス(TWELITE R シリーズ)のポートを選択してください。

シリアルポート選択

シリアルポート選択

ESP32 を起動する

ESP32 をプログラムモードで起動します。

ESP32 リセットスイッチ EN(RST) と ESP32 ブートスイッチ BOOT を押し、EN(RST) -> BOOT の順で離してください。

ボタンの位置

ボタンの位置

スケッチを書き込む

Arduino IDE 上部の マイコンボードに書き込む ボタンをクリックしてください。

書き込み完了画面

書き込み完了画面

3. シリアルモニタを開く 🖥️

画面を開く

Arduino IDE 右上の シリアルモニタ ボタンをクリックしてください。

右上にシリアルモニタボタンがある

右上にシリアルモニタボタンがある

設定する

シリアルモニタ画面の右下のボーレートを 115200 に設定してください。

ボーレート設定

ボーレート設定

4. スケッチを動かす 🚀

ESP32 を再起動する

書き込みが完了したら、TWELITE SPOT の ESP32 リセットスイッチ EN(RST) を押して離し、ESP32 をリセットしてください。

リセットスイッチの位置

リセットスイッチの位置

シリアルモニタを確認する

シリアルモニタに以下の文字列が表示されたら成功です。

        
Hello, World!
Hello World に成功した様子

Hello World に成功した様子

1.3 - TWELITE 子機からのデータ受信

TWELITE CUE から受信した加速度データをシリアルモニタに出力してみる
TWELITE SPOT は、ESP32 に TWELITE を組み合わせることで、多数の小型で省電力な無線タグを利用できるようにしています。

用意するもの

環境を構築する

1. 開発環境を導入する 🚛

ESP32 を使ったファームウェア開発の基礎 の環境構築を行っていない場合は、これを実施してください。

2. ボード設定を行う ⚙️

ボード種別を ESP32 Dev Module としたうえで、下記のように設定してください。

設定後の内容

設定後の内容

3. ライブラリを導入する 🚚

ESP32 から TWELITE を使うために必要となる MWings ライブラリをインストールします。

スケッチ -> ライブラリをインクルード -> ライブラリを管理… を開いてください。

ライブラリマネージャの場所

ライブラリマネージャの場所

検索ボックスに MWings と入力し、MWings をインストールしてください。

ライブラリマネージャ

ライブラリマネージャ

TWELITE SPOT を準備する

1. フタをはずす ⛏️

TWELITE SPOT のケース上面のフタをはずしてください。

2. ケーブルをつなぐ 🔌

ESP32用 7P インターフェイス(ESP32 と記載)に TWELITE R3 / R2 を接続したうえで、側面の USB-C コネクタ に 5V 電源を供給してください。

接続例 (ESP32)

接続例 (ESP32)

まずはスケッチを動かしてみる

1. サンプルを開く 📂

Arduino IDE を起動し、ファイル -> スケッチ例 -> MWings -> monitor_spot_app_cue を選択してください。

monitor_spot_app_cue

2. シリアルポートを選ぶ ⚙️

ツール -> シリアルポート メニューから、 接続したデバイス(TWELITE R シリーズ)のポートを選択してください。

シリアルポート選択

シリアルポート選択

3. ESP32 を起動する 👇

ESP32 をプログラムモードで起動します。

リセットスイッチ EN(RST) と ESP32 ブートスイッチ BOOT を押し、EN(RST) -> BOOT の順で離してください。

ボタンの位置

ボタンの位置

4. スケッチを書き込む ⚒️

Arduino IDE 上部の マイコンボードに書き込む ボタンをクリックしてください。

書き込み完了画面

書き込み完了画面

5. シリアルモニタを開く 🖥️

画面を開く

Arduino IDE 右上の シリアルモニタ ボタンをクリックしてください。

右上にシリアルモニタボタンがある

右上にシリアルモニタボタンがある

設定する

シリアルモニタのボーレートを 115200 に設定してください。

6. ESP32 を再起動する 🚀

書き込みが完了したら、TWELITE SPOT の ESP32 リセットスイッチ EN(RST) を押して離し、ESP32 をリセットしてください。

リセットスイッチの位置

リセットスイッチの位置

7. 起動を確認する 💬

シリアルモニタに以下の文字列が表示されたら、起動に成功しています。

        
Monitor example for TWELITE SPOT: App_CUE (CUE Mode)
起動に成功した様子

起動に成功した様子

8. TWELITE CUE を起動する ⚡

TWELITE CUE に CR2032 型コイン電池を挿入してください。ただちに動作を開始します。

コイン電池の挿入

コイン電池の挿入

9. 受信を確認する 💬

シリアルモニタに以下のような文字列が表示されたら、TWELITE CUE からのデータ受信に成功しています。

        
Packet Number:     #3
Source Logical ID: 0x1
LQI:               147
Supply Voltage:    3310 mV
Accel Event:       Dice (1)
Accel X Axis [0]:  72 mG
Accel Y Axis [0]:  -64 mG
Accel Z Axis [0]:  1000 mG
Magnet State:      Leaving or Not found
受信に成功した様子

受信に成功した様子

スケッチの解説

サンプルスケッチ(monitor_spot_app_cue.ino)の内容を簡単に解説します。

ライブラリのインクルード

4行目では、さきほど導入した MWings ライブラリをインクルードしています。

        
#include "MWings.h"

ピン番号の定義

6-8行目では、ピン番号を定義しています。

        
const int RST_PIN = 5;
const int PRG_PIN = 4;
const int LED_PIN = 18;
名称内容
RST_PINTWELITE の RST ピンが接続されているピンの番号
PRG_PINTWELITE の PRG ピンが接続されているピンの番号
LED_PIN基板上の ESP32 用 LED が接続されているピンの番号

TWELITE 設定の定義

10-11行目では、TWELITE SPOT に搭載された TWELITE 親機に適用する設定を定義しています。

        
const uint8_t TWE_CHANNEL = 18;
const uint32_t TWE_APP_ID = 0x67720102;
名称内容
TWE_CHANNELTWELITE の 周波数チャネル
TWE_APP_IDTWELITE の アプリケーション ID

シリアルポートの設定

19-21行目では、使用するシリアルポートを初期化するとともに、シリアルモニタへ起動メッセージを出力しています。

        
  Serial.begin(115200);
  Serial.println("Monitor example for TWELITE SPOT: App_CUE (CUE Mode)");
  Serial2.begin(115200);

Serial は、Arduino IDE の シリアルモニタとの通信に使います。シリアルモニタの設定に合わせて、ボーレートを 115200 bps としています。

一方、Serial2 は、TWELITE SPOT に搭載された TWELITE 親機との通信に使います。こちらも TWELITE 親機の初期設定に合わせて、ボーレートを 115200 bps としています。

TWELITE の設定

24-26行目では、Twelite.begin() を呼び出し、TWELITE SPOT に搭載された TWELITE 親機の設定と起動を行っています。

        
    Twelite.begin(Serial2,
                      LED_PIN, RST_PIN, PRG_PIN,
                      TWE_CHANNEL, TWE_APP_ID);
引数内容
Serial2HardwareSerial&TWELITE との通信に使うシリアルポート
LED_PINintステータス LED を接続したピンの番号
RST_PINintTWELITE の RST ピンを接続したピンの番号
PRG_PINintTWELITE の PRG ピンを接続したピンの番号
TWE_CHANNELuint8_tTWELITE の 周波数チャネル
TWE_APP_IDuint32_tTWELITE の アプリケーション ID

パケット受信時のイベントの登録

29-49行目では、Twelite.on() を呼び出し、TWELITE CUE から送られたデータに対して行う処理を登録しています。

ここでは、受信したパケットの内容をシリアルモニタに出力しています。

        
    Twelite.on([](const ParsedAppCuePacket& packet) {
        Serial.println("");
        Serial.print("Packet Number:     #");
        Serial.println(packet.u16SequenceNumber, DEC);
        Serial.print("Source Logical ID: 0x");
        Serial.println(packet.u8SourceLogicalId, HEX);
        Serial.print("LQI:               ");
        Serial.println(packet.u8Lqi, DEC);
        Serial.print("Supply Voltage:    ");
        Serial.print(packet.u16SupplyVoltage, DEC); Serial.println(" mV");
        Serial.print("Accel Event:       ");
        printAccelEvent(packet.u8AccelEvent);
        Serial.print("Accel X Axis [0]:  ");
        Serial.print(packet.i16SamplesX[0], DEC); Serial.println(" mG");
        Serial.print("Accel Y Axis [0]:  ");
        Serial.print(packet.i16SamplesY[0], DEC); Serial.println(" mG");
        Serial.print("Accel Z Axis [0]:  ");
        Serial.print(packet.i16SamplesZ[0], DEC); Serial.println(" mG");
        Serial.print("Magnet State:      ");
        printMagnetState(packet.u8MagnetState, packet.bMagnetStateChanged);
    });

上記のイベントは、TWELITE CUEからのパケットを受信したときにだけ呼び出されます。

受信したパケットの内容は ParsedAppCuePacket 型の引数 packet に格納されます。

packet には、下記のデータが含まれています(太字 のデータを上記のコード中で使用しています)。

データ内容
packet.u32SourceSerialIduint32_t送信元のシリアルID
packet.u8SourceLogicalIduint8_t送信元の論理デバイスID
packet.u16SequenceNumberuint16_tシーケンス番号
packet.u8Lqiuint8_tLQI(電波通信品質の指標)
packet.u16SupplyVoltageuint16_t電源電圧 (mV)
packet.i16SamplesXint16_t[10]各サンプルの X 軸加速度 (mG)
packet.i16SamplesYint16_t[10]各サンプルの Y 軸加速度 (mG)
packet.i16SamplesZint16_t[10]各サンプルの Z 軸加速度 (mG)
packet.u8SampleCountuint8_tサンプル数
packet.bHasAccelEventbool加速度イベントがあるならtrue
packet.u8AccelEventuint8_t加速度イベントID
packet.u8MagnetStateuint8_t磁気イベントID
packet.bMagnetStateChangedbool磁気センサの状態が変化したならtrue

TWELITE のデータの更新

55行目では、Twelite.update() を呼び出しています。

        
    Twelite.update();

Twelite.update() は、TWELITE 親機から送信されるパケットデータ(ModBus ASCII 形式)を順次1バイトずつ読み出す関数です。

1.4 - 関連情報

ステップアップに向けて
TWELITE SPOT のファームウェア開発に役立つ資料をまとめました。

MWings ライブラリ

TWELITE 製品データシート

TWELITE SPOT マニュアル

スケッチ解説

その他

外部リンク

Arduino

ESP32

コミュニティ

ライブラリ
プラグイン

2 - TWELITE Wings API / MWings for Python

TWELITE が送信するデータを Python で受信する
Python を使って 超簡単!標準アプリ(App_Twelite) のデータを JSON 形式で出力してみます。

ライブラリの概要

TWELITE Wings API (以降 MWings) は、Python スクリプトから TWELITE を扱うためのライブラリです。

GitHub リポジトリ

機能

ホストへ接続された TWELITE の親機を通じて、TWELITE の子機と通信できます。

  • 受信データを解釈して、辞書や JSON のほか pandas データフレームへ変換
  • 辞書から生成したコマンドを親機へ送信

用途例

例えば、次のようなシステムを実現できます。

  • MONOSTICK で受信した温湿度データを JSON としてクラウドサーバへ送信
  • MONOSTICK で受信した加速度データを CSV または Excel ファイルへ記録
  • PC から MONOSTICK を通じて TWELITE DIP へ接続された LED を制御

特徴

モダン Python の モダン Python による モダン Python のためのモジュールです。

  • pip や poetry を使って導入できる
  • pydantic により、送受信データのバリデーションを実施している
  • PEP8 に準拠している※ ほか、型ヒント へ対応している

※ 例外あり。詳細は後述

インストール

PyPI から入手できます。

pip の場合


        
pip install mwings

poetry の場合


        
poetry add mwings

最も簡単なサンプルスクリプト

わずか6行で超簡単!標準アプリ(App_Twelite)の受信データを JSON 形式で出力できます。

        
import mwings as mw
twelite = mw.Twelite(mw.utils.ask_user_for_port())
@twelite.on(mw.common.PacketType.APP_TWELITE)
def on_app_twelite(packet):
    print(packet.to_json())
twelite.start()

使ってみる

用意するもの

  • PC
  • MONOSTICK(親機・中継機アプリ/デフォルト設定)
  • TWELITE DIP(超簡単!標準アプリ/デフォルト設定)
    • スイッチなどのペリフェラルを接続しておく(例:DI1 ポートと GND 間にタクトスイッチを接続)

環境整備

pyenv の導入

処理系のバージョンを管理するために、pyenv を導入します。

Linux

        
curl https://pyenv.run | bash
macOS

        
brew update
brew install pyenv
Windows

Windows 向けの pyenv はありません。代わりに pyenv-win を使用します。

        
Invoke-WebRequest -UseBasicParsing -Uri "https://raw.githubusercontent.com/pyenv-win/pyenv-win/master/pyenv-win/install-pyenv-win.ps1" -OutFile "./install-pyenv-win.ps1"; &"./install-pyenv-win.ps1"
pyenv / pyenv-win による Python の導入

MWings が対応する Python 3.12 以降の処理系を導入します。

導入できるバージョンの一覧を取得するには、下記を実行します。

        
pyenv install -l

ここでは例として、Python 3.12.1 を導入し、システム全体へ適用します。

        
pyenv install 3.12.1
pyenv global 3.12.1

導入済みバージョンの一覧を取得するには、下記を実行してください。

        
pyenv versions
pipx の導入

poetry のようなコマンドラインツールを隔離された環境で管理するために、pipx を導入します。

Linux

Debian系


        
sudo apt update
sudo apt install pipx
pipx ensurepath

Fedora系


        
sudo dnf install pipx
pipx ensurepath
macOS

        
brew install pipx
pipx ensurepath
Windows
        
scoop install pipx
pipx ensurepath
poetry の導入

プロジェクトに対する処理系のバージョンやモジュールの依存関係を Node.js のような形で管理するために、poetry を導入します。

        
pipx install poetry
プロジェクトの作成

ここでは、プロジェクト名を mwtest とします。

プロジェクトを作成するディレクトリへ移動し、下記を実行してください。

        
poetry new mwtest

mwtest ディレクトリを生成します。

プロジェクトの設定

プロジェクトへ移動し、先ほど pyenv で導入した 処理系のバージョンを紐付けます。

        
poetry env use 3.12.1

MWings を導入します。

        
poetry add mwings

最も簡単なサンプルスクリプトの作成

まずは、先ほど紹介したスクリプト を動かしてみましょう。

        
import mwings as mw
twelite = mw.Twelite(mw.utils.ask_user_for_port())
@twelite.on(mw.common.PacketType.APP_TWELITE)
def on_app_twelite(packet):
    print(packet.to_json())
twelite.start()

上記の内容で poetry が生成した __init__.py と同じ階層に simple.py を作成します。

        
📁 mwtest
└ 📁 mwtest
  ├ 📄 __init__.py
  └ 📄 simple.py

最も簡単なサンプルスクリプトの実行

MONOSTICK を接続し、実行します。

        
poetry run python simple.py

複数のシリアルポートが存在する場合は、シリアルポートを選択してください。

JSON 文字列の出力を得ることができたら成功です。実際の出力例を下記に示します。

        
{
  "time_parsed": "2024-02-20T03:16:50.150386+00:00",
  "packet_type": "APP_TWELITE",
  "sequence_number": 13699,
  "source_serial_id": "810E0E23",
  "source_logical_id": 120,
  "lqi": 84,
  "supply_voltage": 3249,
  "destination_logical_id": 0,
  "relay_count": 0,
  "periodic": true,
  "di_changed": [
    true,
    true,
    false,
    false
  ],
  "di_state": [
    false,
    false,
    false,
    false
  ],
  "ai_voltage": [
    8,
    272,
    1032,
    112
  ],
  "mwings_implementation": "python",
  "mwings_version": "1.0.0",
  "hostname": "silverstone.local",
  "system_type": "Darwin"
}

実用的なスクリプトの作成

simple.py はあくまでも説明用のサンプルです。実用的なスクリプトではありません。

なぜなら、twelite.start() がデータを受信するためのスレッドを作成するものの、これを終了する手段を用意していないからです。非常に読みづらいスクリプトでもあります。

次はより実用的なスクリプトを作成しましょう。それを実行したのち、内容を解説します。

今回は、下記の3点を条件とします。

  • Ctrl+C により、スレッドを正常終了できるようにすること
  • PEP8 へ準拠すること(一部例外あり、詳細は後述
  • 型ヒント を導入すること

これらを適用した例を下記に示します。

        
# -*- coding:utf-8 -*-
# Written for Python 3.12
# Formatted with Black

# MWings example: Receive data, print JSON, typed

from zoneinfo import ZoneInfo

import mwings as mw


# Main function
def main() -> None:
    # Create a twelite object
    twelite = mw.Twelite(mw.utils.ask_user_for_port())

    # Use JST for received data
    twelite.set_timezone(ZoneInfo("Asia/Tokyo"))

    # Register an event handler
    @twelite.on(mw.common.PacketType.APP_TWELITE)
    def on_app_twelite(packet: mw.parsers.app_twelite.ParsedPacket) -> None:
        print(packet.to_json(verbose=True, spread=False))

    # Start receiving
    try:
        # Set as daemon thread
        twelite.daemon = True
        # Start the thread, Join to the main thread
        twelite.start()
        print("Started receiving")
        while True:
            twelite.join(0.5)
    except KeyboardInterrupt:
        # Stop the thread
        print("Flushing...")
        twelite.stop()
        print("Completed")


if __name__ == "__main__":
    # Call the main function
    main()

上記を practical.py として保存してください。

        
📁 mwtest
└ 📁 mwtest
  ├ 📄 __init__.py
  ├ 📄 simple.py
  └ 📄 practical.py

実用的なスクリプトの実行

下記のコマンドを実行すると、simple.py と同じようにして JSON 形式の出力を得ることができます。

        
poetry run python practical.py

ただし、今回はエラーを発生させずに Ctrl+C で終了できるほか、time_parsed は日本標準時になっているものと思います。

実用的なスクリプトの解説

コードの解説

practical.py を解説します。

import

practical.py では、2つのモジュールを import しています。

        
from zoneinfo import ZoneInfo

import mwings as mw
  • zoneinfo.ZoneInfo 受信時刻のタイムゾーンを指定するために使用します。
  • mwings MWings ライブラリです。mw に短縮して呼び出せるようにしています。
オブジェクトの作成

mw.Twelite オブジェクトは、ホストへ接続された TWELITE の親機へアクセスするためのインタフェースとなります。

        
    # Create a twelite object
    twelite = mw.Twelite(mw.utils.ask_user_for_port())

mw.utils.ask_user_for_port() 関数は、ホストで利用できるシリアルポートの一覧を取得し、ユーザが選択したポートのファイルディスクリプタのパスや COM ポート名を返します。

タイムゾーンの設定

デフォルトでは、データの受信時刻を UTC として扱います。

practical.py では、これを JST としています。

        
    # Use JST for received data
    twelite.set_timezone(ZoneInfo("Asia/Tokyo"))

ZoneInfo には IANA のタイムゾーン識別子を渡してください。

受信ハンドラの登録

TWELITE の子機から送られるデータを処理するには、受信ハンドラを登録します。ここでは、超簡単!標準アプリ向けの受信ハンドラ内で受信したデータを JSON 形式に変換し、それを出力しています。

        
    # Register an event handler
    @twelite.on(mw.common.PacketType.APP_TWELITE)
    def on_app_twelite(packet: mw.parsers.app_twelite.ParsedPacket) -> None:
        print(packet.to_json(verbose=True, spread=False))

受信ハンドラは、任意の関数へ twelite.on() デコレータ ? を適用することで登録できます。

受信ハンドラが受け取るデータクラス ParsedPacket は、JSON 形式の文字列へ変換する to_json()、辞書へ変換する to_dict()pandas データフレームへ変換する to_df() といったメソッドを備えています。

ここでは、to_json() メソッドを使って JSON 形式の文字列へと変換しています。

        
        print(packet.to_json(verbose=True, spread=False))
受信の開始と終了

mw.Twelite は、threading.Thread を継承しています 。practical.py では、twelite.start() が別のスレッドで受信処理を開始し、twelite.stop() がそれを停止しています。

        
    # Start receiving
    try:
        # Set as daemon thread
        twelite.daemon = True
        # Start the thread, Join to the main thread
        twelite.start()
        print("Started receiving")
        while True:
            twelite.join(0.5)
    except KeyboardInterrupt:
        # Stop the thread
        print("Flushing...")
        twelite.stop()
        print("Completed")

twelite.daemonTrue へ設定すると、受信処理を担うサブスレッドは デーモン化 されます。デーモンでない生存中のスレッドがすべて終了すると、 Python プログラム全体も終了します。ここではメインスレッド内で twelite.join() を繰り返し呼ぶことで、メインスレッドを待機させています。

メインスレッドは Ctrl+C の入力を検知すると except 節で twelite.stop() を呼び出し、受信処理を停止させます。twelite.stop() はサブスレッドが受信ハンドラの呼び出しを終えるまで待機します。

補足説明
PEP8 への対応

practical.py や MWings のソースコードは、PEP8 に対応したコードフォーマッタ Black を使ってフォーマットされています。

Black は一行の最大長を除き、いかなる設定も受け付けない頑固なフォーマッタですが、コーディング規約を策定・共有する手間を省くことができます。コーディングルールはしばしば物議を醸す議題ですが、そうした取るに足らない作業へ費やすリソースを有益な作業へ割り当てることこそが Python らしさの本質でしょう。

プロジェクトへ Black を追加するには、下記を実行します。

        
poetry add --group dev black

対象のファイルやディレクトリを指定して実行できます。

        
poetry run black mwtest

フォーマットせずに確認だけ行うこともできます。

        
poetry run black --check mwtest
型ヒントへの対応

practical.py や MWings のソースコードは、型ヒント へ対応しています。

MWings ライブラリは、Python 公式の静的型チェッカである mypy を使用しています。

プロジェクトへ mypy を追加するには、下記を実行します。

        
poetry add --group dev mypy

こちらも Black と同様に、対象のファイルやディレクトリを指定して実行できます。

        
poetry run mypy mwtest

関連情報

実用的なスクリプトの応用

practical.py をさらに発展させたスクリプトを公開しています。

mwings_python/examples at main

log_export.py

親機の出力を保存したテキストファイルを読み込み、解釈した結果を pandas データフレームへ保存し、最終的に CSV または Excel ファイルを出力します。

rx_export.py

接続された親機の出力を受け取り、解釈した結果を pandas データフレームへ保存し、最終的に CSV または Excel ファイルを出力します。

  • CSV ファイルを選択した場合、すべての結果を一つのファイルへ保存します。
  • 代わりに Excel ファイルを選択した場合、パケットの種別ごとに別のシートへ保存します。
rx_export_csv_durable.py

接続された親機の出力を受け取り、解釈した結果を送信元のシリアルIDごとに CSV ファイルへ追記していきます。

rx_print_df.py

接続された親機の出力を受け取り、単に解釈した結果を pandas データフレームへ変換し、文字列として出力します。

rx_print_dict.py

接続された親機の出力を受け取り、単に解釈した結果を辞書へ変換して出力します。

rx_print_json.py

接続された親機の出力を受け取り、単に解釈した結果を JSON 文字列へ変換して出力します。

tx_binary_uart.py

接続されたシリアル通信アプリの親機を介して、TWELITE UART へバイナリデータ [0xBE, 0xEF] を送ります。

接続された親機・中継機アプリの親機を介して、TWELITE DIP の DO1 ポートに接続された LED を点滅させます。

接続された親機・中継機アプリの親機を介して、通知パルの LED を各色で点灯させます。

API リファレンス