CLI で Zigbee その2

「CLI で Zigbee その1」
https://qiita.com/nanbuwks/items/709421e1ccb52604ec2c
の続きです。今回は、light_bulb に対してCLIで操作をしてみます。

# 環境

- SDK nRF5_SDK_for_Thread_and_Zigbee_v4.0.0_dc7186b
- Nordic nRF52840 (アオノドン2019)を使用


# プログラム

examplesのzigbeeディレクトリ中の以下構成

├── app_utils
│ └── ws2812
├── experimental
│ ├── cli
│ ├── light_control
│ ├── multi_sensor
│ └── multi_sensor_freertos
├── light_control
│ ├── light_bulb
│ ├── light_coordinator
│ └── light_switch
└── ota
├── bootloader
├── client
└── experimental_server


のうち、

├── experimental
│ ├── cli ← アオノドン2019で実行
│ ├── light_control
│ ├── multi_sensor
│ └── multi_sensor_freertos
├── light_control
│ ├── light_bulb ← アオノドン2019で実行
│ ├── light_coordinator
│ └── light_switch

を実行します。

# 元ネタ
前回に引き続き、以下の解説ページに沿って動かしていきます。

「Zigbee CLI Agent example」
https://infocenter.nordicsemi.com/topic/sdk_tz_v4.0.0/zigbee_example_cli_agent.html

また、以下にCLIのライブラリ、およびリファレンスの解説があります。

「Command Line Interface library」
https://infocenter.nordicsemi.com/topic/sdk_nrf5_v16.0.0/lib_cli.html
「Zigbee CLI Reference」
https://infocenter.nordicsemi.com/topic/sdk_tz_v4.0.0/zigbee_example_cli_reference.html


# UART 接続方法


- light_bulb は 100000bps 8N1
- cli は 115200 bps 8N1 ハードウェアフロー制御

UARTの接続パラメータは元々上記のようになってますが、以下に変更しています。

- light_bulb は 40800bps
- cliは ハードウェアフロー制御を解除


設定方法は以下を参照
「Nordic nRF52840 で Zigbee 照明とスイッチ」
https://qiita.com/nanbuwks/items/92a76bc68ebb75a58dfd
「Nordic Zigbee CLI Example の UART設定」
https://qiita.com/nanbuwks/items/cf66d56979ad9a2a7a96


# 起動

実行したら light_bulb では

```

<info> app: Set level value: 255
<info> app: Production configuration is not present or invalid (status: -1)
<info> app: Zigbee stack initialized
<info> app: Device started for the first time
<info> app: Start network steering

```
と出てきます。

また、cliではタブを押すと

```

  balloc   bdb      log      queue    radio    reset    version  zcl
  zdo
```
ヘルプが出てきます。これが出てくることでファームが起動しており、なおかつシリアルで問題なく通信ができていることがわかります。

```

> reset
```

念の為一旦リセットしておきます。

```

> bdb role zc
Coordinator set
Done
> bdb start
Started coordinator
Done

```
コーディネーターとしてスタートします。この時点で light_bulb では


```
<info> app: Restart network steering after 1 second (status: -1)
<info> app: Restart network steering after 1 second (status: -1)
<info> app: Restart network steering after 1 second (status: -1)
<info> app: Joined network successfully (Extended PAN ID: f4ce365035f26ad5, PAN ID: 0x34CD)

```

接続した旨表示されます。

CLIで引き続き操作します。

```

> bdb legacy
off
Done
> zdo match_desc  0xffff 0xffff 0x0104 2 0x0006 0x0008 0
Sending broadcast request.
> 
src_addr=4D0A ep=10

```

プロファイルを指定してブロードキャストした結果、light_bulb が検出されました。この4D0Aは短縮アドレスですが、コーディネータから割り当てられたもので、接続の都度異なります。


https://infocenter.nordicsemi.com/index.jsp?topic=%2Fsdk_tz_v4.0.0%2Fzigbee_example_cli_reference.html&anchor=match_desc

によると、match_desc の書式は以下のとおりです。

```

zdo match_desc <h:16-bit destination address>
               <h:requested address/type> <h:profile ID>
               <d:number of input clusters> [<h:input cluster IDs> ...]
               <d:number of output clusters> [<h:output cluster IDs> ...]

```


- 相手先短縮アドレスを16進で表示 
- 要求アドレス／タイプ16進で表示
- プロファイルID
- インプットクラスター数を10進で表示
 - インプットクラスター数が0でない場合、インプットクラスターのIDを16進で羅列
- アウトプットクラスター数を10進で表示
 - アウトプットクラスター数が0でない場合、インプットクラスターのIDを16進で羅列

ということなので、ZigBee デバイスオブジェクトのシンプル・ディスクリプタの内容を書いていけばいい感じですね。

ここで、相手先短縮アドレスや、要求アドレスの指定を 0xFFFF にした場合は 全てのアドレス、 0xFFFD にした場合はスリープしていない全てのアドレスになります。

また、プロファイルIDは  ZigBee HA の場合は 0x0104 になります。

```

 zdo match_desc  0xffff 0xffff 0x0104 2 0x0006 0x0008 0
```

とリクエストしている 2 0x0006 0x0008 0 の意味は、

- インプットクラスターとして 
- ON/OFF (0x0006)
- レベルコントロール (0x0008) を持つ
- Zigbee HA デバイスを全てのアドレスから検索

することになります。

ここで、 ZigBee HA の定義は external/zboss/include/zboss_api_af.h で ZB_AF_HA_PROFILE_ID として定義されています。


また、クラスターは
external/zboss/include/zcl/zb_zcl_common.h 内で以下のように定義されています。

```

/** @brief ZCL cluster identifiers
  * @see ZCL spec, subclause 2.2.2.
  */
typedef enum zb_zcl_cluster_id_e
{
  ZB_ZCL_CLUSTER_ID_BASIC = 0x0000,                 /**< Basic cluster identifier. */
  ZB_ZCL_CLUSTER_ID_POWER_CONFIG = 0x0001,          /**< Power configuration cluster identifier. */
  ZB_ZCL_CLUSTER_ID_DEVICE_TEMP_CONFIG = 0x0002,    /**< Device temperature configuration cluster
                                                      identifier. */
  ZB_ZCL_CLUSTER_ID_IDENTIFY = 0x0003,              /**< Identify cluster identifier. */
  ZB_ZCL_CLUSTER_ID_GROUPS = 0x0004,                /**< Groups cluster identifier. */
  ZB_ZCL_CLUSTER_ID_SCENES = 0x0005,                /**< Scenes cluster identifier. */
  ZB_ZCL_CLUSTER_ID_ON_OFF = 0x0006,                /**< On/Off cluster identifier. */
  ZB_ZCL_CLUSTER_ID_ON_OFF_SWITCH_CONFIG = 0x0007,  /**< On/Off switch configuration cluster
                                                      identifier. */
  ZB_ZCL_CLUSTER_ID_LEVEL_CONTROL = 0x0008,         /**< Level control cluster identifier. */
  ZB_ZCL_CLUSTER_ID_ALARMS = 0x0009,                /**< Alarms cluster identifier. */
  ZB_ZCL_CLUSTER_ID_TIME = 0x000a,                  /**< Time cluster identifier. */
  ZB_ZCL_CLUSTER_ID_RSSI_LOCATION = 0x000b,         /**< RSSI location cluster identifier. */
  ZB_ZCL_CLUSTER_ID_ANALOG_INPUT = 0x000c,          /**< Analog input (basic) cluster identifier. */
  ZB_ZCL_CLUSTER_ID_ANALOG_OUTPUT = 0x000d,         /**< Analog output (basic) cluster identifier.
                                                      */
  ZB_ZCL_CLUSTER_ID_ANALOG_VALUE = 0x000e,          /**< Analog value (basic) cluster identifier. */
  ZB_ZCL_CLUSTER_ID_BINARY_INPUT = 0x000f,          /**< Binary input (basic) cluster identifier. */
  ZB_ZCL_CLUSTER_ID_BINARY_OUTPUT = 0x0010,         /**< Binary output (basic) cluster identifier.
                                                      */
  ZB_ZCL_CLUSTER_ID_BINARY_VALUE = 0x0011,          /**< Binary value (basic) cluster identifier. */

・
・
・

```


短縮アドレスから IEEEアドレスを引いてみます。


```

zdo ieee_addr 0x4D0A
> f4ce36743de1e525
Done
```

エンドデバイスの内容を確認します。

```

zdo simple_desc_req 0x4D0A 0
> 
src_addr=0x4D0A ep=0 profile_id=0x0000 app_dev_id=0x0 app_dev_ver=0x0 in_clusters=out_clusters=
Done
```

アドレス 0x4D0A に、エンドポイント 0 の ZigBee デバイスオブジェクトのシンプルディスクリプタを要求します。

結果、以下が得られました。

- エンド・ポイント番号 0
- このエンド・ポイントがサポートするプロファイルのID 0x0000
- アサインされた16ビットデバイスID 0x0 
- デバイスバージョン 0x0
- 入力クラスタ なし
- 出力クラスタ なし

あれれ？ 全然情報が取れていないですね。

Nordic Dev Zone で聞いてみたら、
https://devzone.nordicsemi.com/f/nordic-q-a/60244/zigbee-cli-example-and-light_bulb-example

```

zdo simple_desc_req 0x4D0A 10

```

とするのが正しいらしいです。

この10 は、先に

```

> zdo match_desc  0xffff 0xffff 0x0104 2 0x0006 0x0008 0
Sending broadcast request.
> 
src_addr=4D0A ep=10
```

で得られた ep の値ということでした。

```

> zdo simple_desc_req 0x35F1 10
> 
src_addr=0x35F1 ep=10 profile_id=0x0104 app_dev_id=0x101 app_dev_ver=0x1 in_clusters=0x0000,0x0003,0x0005,0x0004,0x0006,0x0008 out_clusters=
Done
```

日を改めて実験したので src_addr は 4D0A ではなく、35F1になっています。


- エンド・ポイント番号 10
- このエンド・ポイントがサポートするプロファイルのID 0x0104
- アサインされた16ビットデバイスID 0x101 
- デバイスバージョン 0x1
- 入力クラスタ 0x0000,0x0003,0x0005,0x0004,0x0006,0x0008
- 出力クラスタ なし



この入力クラスタについて、

- 0x0000 Basic cluster identifier.
- 0x0003 Identify cluster identifier.
- 0x0005 Scenes cluster identifier.
- 0x0004 Groups cluster identifier.
- 0x0006 On/Off cluster identifier.
- 0x0008 Level control cluster identifier.

ということで、レベル変更をしてみます。

```

zcl cmd f4ce36a90365d8fb 10 0x0008 -p 0x0104  0x00 -l 0xff10
```
書式は

zcl cmd [-d] <h:dst_addr> <d:ep> <h:cluster> [-p h:profile] <h:cmd_ID> [-l h:payload]

です。

送信コマンドの意味は以下の通りです。

- デバイス  f4ce36a90365d8fb
- エンドポイント 10
- レベルコントロール 0x0008
- コマンドID 0x00
- ペイロード 0xff10

これを送るとレベル255に3秒ほどで遷移します。

```

<info> app: zcl_device_cb id 7
<info> appデバイス: Level control setting to 2
<info> app: Set level value: 2
<info> app: zcl_device_cb status: 0
<info> app: zcl_device_cb id 7
<info> app: Level control setting to 4
<info> app: Set level value: 4
<info> app: zcl_device_cb status: 0
<info> app: zcl_device_cb id 7
<info> app: Level control setting to 6
.
.
.
<info> app: zcl_device_cb id 7
<info> app: Level control setting to 252
<info> app: Set level value: 252
<info> app: zcl_device_cb status: 0
<info> app: zcl_device_cb id 7
<info> app: Level control setting to 255
<info> app: Set level value: 255
<info> app: zcl_device_cb status: 0
```


ZigBee Cluster Library Specification Revision 6 Draft Version 1.0
https://zigbeealliance.org/wp-content/uploads/2019/12/07-5123-06-zigbee-cluster-library-specification.pdf
の
3.10.2.4 Commands Received
Table 3-53. Command IDs for the Level Control Cluster

によると、

|Command Identifier |Field Value Description |M/O|
|:---:|:---:|:---:|
|0x00| Move to Level| M|
|0x01 |Move| M|
|0x02 |Step |M|
|0x03 |Stop |M|
|0x04 |Move to Level (with On/Off) |M|
|0x05 |Move (with On/Off) |M|
|0x06 |Step (with On/Off) |M|
|0x07 |Stop |M|

となっています。

3.10.2.4.1 Move to Level Command
3.10.2.4.1.1 Payload Format
Figure 3-39. Format of the Move to Level Command Payload

によると、

|Octets| 1| 2|
|:---:|:---:|:---:|
|Data Type |uint8 |uint16|
|Field Name |Level |Transition time|


ということで Transition time は 16bitのはずですがおかしいなーと思ったら、リトルエンディアンらしいです。
Transition Time は 0.1秒単位ということで、例えば60秒にしたいとすれば600の16進数0x0258を 5802と表記し、
1分で消灯するとすると 0x005802 とすればいいのですね。

さて、

```

zcl cmd f4ce36a90365d8fb 10 0x0008 -p 0x0104  0x00 -l 0x00FF
```
とすると25.6秒の調光時間で消灯することになりますが、

調光中に、

```

zcl cmd f4ce36a90365d8fb 10 0x0008 -p 0x0104  0x03
```
とすると調光が停止します。


現在の光量値を読むには以下のようにします。

```

zcl attr read f4ce36a90365d8fb 10 0x0008 0x0104 0x0000
> 
ID: 0 Type: 20 Value: 51
Done
```

書式は以下の通りです。
zcl attr read <h:dst_addr> <d:ep> <h:cluster> [-c] <h:profile> <h:attr_id>


別のクラスターを試してみます。
ON/OFFクラスターは 0x0006となります。

```

zcl cmd f4ce36a90365d8fb 10 0x0006 -p 0x0104  0x02
```
とすると以下のようにライトのトグル操作が行われます。

```

<info> app: zcl_device_cb id 0
<info> app: on/off attribute setting to 0
<info> app: Set ON/OFF value: 0
<info> app: zcl_device_cb status: 0
<info> app: zcl_device_cb id 0
<info> app: on/off attribute setting to 1
<info> app: Set ON/OFF value: 1
<info> app: Set level value: 255
<info> app: zcl_device_cb status: 0
```




# 参考文献

「Zigbee CLI example and light_bulb example」
https://devzone.nordicsemi.com/f/nordic-q-a/60244/zigbee-cli-example-and-light_bulb-example

「ZigBee開発ハンドブック」
鄭立著 （実践入門ネットワーク） リックテレコム, 2006.2


「ZigBee Cluster Library Specification」 Revision 6 Draft Version 1.0
https://zigbeealliance.org/wp-content/uploads/2019/12/07-5123-06-zigbee-cluster-library-specification.pdf

「ZigBee Reference」
http://docs.smartthings.com/en/latest/ref-docs/zigbee-ref.html