BeatCraft BC-11AH-A (Raspberry Pi 802.11ah(HaLow) HAT) で Duty cycle を設定する

# この記事について
[BeatCraft BC-11AH-A (Raspberry Pi 802.11ah HAT)](https://www.beatcraft.com/labs/2024/11/raspberry-pi-80211ah-hat-askey.html) で、Duty比10%規制に適用するための設定をまとめたものです。

# BeatCraft BC-11AH-A (Raspberry Pi 802.11ah HAT) とは？
BeatCraft社製の Raspberry Pi 3/4 で使用できる HaLow HAT です。BeatCraftは日本のメーカーさんなのでもちろん技適も問題なしです。Amazonから1万円ちょっとのお手軽価格で買えます（[ここ](https://www.amazon.co.jp/dp/B0DKNYK3VT)）。

# Duty比10%規制 とは？
920MHz帯を使用する無線には、ざっくり言うと「1時間(=3600秒)あたり360秒しか電波を出してはいけない」というルールがあります。これを破ると電波法違反になります。電波を出せるのが「単位時間の10%まで」ということから、一般的に「Duty比10%規制」などと呼ばれています。  
この規制は920MHz帯を使用する無線全般に適用されるので、 Wi-Fi HaLow だけでなく LoRaWAN や Wi-SUN なども対象になるのですが、一般的にごく少量の通信しかしない LoRa/Wi-SUN などと違い、大量に通信しがちな Wi-Fi HaLow はこのルールに引っかかりやすくなります。

# BC-11AH-A の設定手順

## 初期インストール

[公式のインストール手順](https://www.beatcraft.com/labs/2024/11/raspberry-pi-80211ah-hat-askey.html) どおりにインストール作業を行います。
なお、手順に「[nrc7394_sw_pkg-1.2.1.tar.gz](https://github.com/newracom/nrc7394_sw_pkg/releases/tag/v1.2.1) をダウンロードし展開しておきます」 と書かれている部分については、v1.2系では Duty の設定ができないため、現時点の最新（2025/01時点）である v1.3系 [nrc7394_sw_pkg-1.3.tar.gz](https://github.com/newracom/nrc7394_sw_pkg/releases/tag/v1.3) をダウンロードしてインストールを進めます。
なお、v1.3系のインストーラーでは、手順の 3.3 （NRC7394 host driver と cli_app の更新） は自動で行われますので、この手順は省略してOKです。

ちなみに、公式には [v1.3系は不具合があるので使うな](https://www.beatcraft.com/labs/2025/01/bc-11ah-a.html) と書かれていますが、v1.3系でないと Duty の設定ができないので、仕方ありません。

## Duty cycle の設定

セットアップ後、vi や nano などのエディタで `~/nrc_pkg/script/start.py` を開きます。
165行目あたりに以下のような記述があります。この部分を修正します。
``` start.py (変更前)
#--------------------------------------------------------------------------------#
# Duty cycle configuration
duty_cycle_enable = 0      # 0 (disable) or 1 (enable)
duty_cycle_window = 0
duty_cycle_duration = 0
#--------------------------------------------------------------------------------#
```

- `duty_cycle_enable` を `1` とすることで、Duty制御を有効化します。
- `duty_cycle_window` は、Dutyの単位時間をマイクロ秒単位で記述します。
  - 例えば単位時間を10秒とすると「10秒間のうちの10%(=1秒)だけ電波を出す」という設定になります。 
  - 設定値はマイクロ秒単位なので10秒と設定したい場合は `10000000` (= 10 * 1000 * 1000) を設定します。
  - 最小値は1,000,000 （1秒）です。
- `duty_cycle_duration` は、上記の単位時間の中で最大何秒間電波を出すかをマイクロ秒単位で記述します。
  - 現在の日本の法律では10%ですので、`duty_cycle_window`の1/10の値を記述することになります。
  - `duty_cycle_window`に10秒 `10000000`(10 * 1000 * 1000) を設定した場合は、`duty_cycle_duration` には1秒 `1000000`(1 * 1000 * 1000)を設定します。
  - 最小値は100,000 （0.1秒）です。


ということで、Duty cycle の間隔を10秒とする場合は以下のような記述に変更します。
``` start.py (変更後)
#--------------------------------------------------------------------------------#
# Duty cycle configuration
duty_cycle_enable   = 1      # 0 (disable) or 1 (enable)
duty_cycle_window   = 10000000
duty_cycle_duration = 1000000
#--------------------------------------------------------------------------------#
```

数字の羅列だとわかりにくいので、ちょっとわかりやすく書いたほうが無難かもしれません（しょせんpythonスクリプトですし）。
``` start.py (さらに変更後)
#--------------------------------------------------------------------------------#
# Duty cycle configuration
duty_cycle_enable   = 1      # 0 (disable) or 1 (enable)
duty_cycle_window   = 10 * 1000 * 1000
duty_cycle_duration = duty_cycle_window // 10
#--------------------------------------------------------------------------------#
```

# Duty cycle を有効化したときの挙動

### 例：`duty_cycle_window` を10秒に設定した場合
「10秒間のうち1秒間だけ通信できる」というのは「10秒間のうち**トータルで**1秒間通信できる」ということです。つまり、1秒\*1回でも 0.1秒\*10回でも 0.01秒\*100回でもOK、という意味です。
というのを踏まえて。
- 回線が許容出来る最大速度で通信を行うと、最初の1秒だけ通信を行った後、残りの9秒間は通信が止まります。
- 回線が許容出来る最大速度の半分の速度で通信を継続すると、最初の5秒だけ通信を行った後、残りの5秒間は通信が止まります。
- 回線が許容出来る最大速度の1/10の速度で通信を行うと、概ね10秒間ずっと通信を継続できます。

なお、電波の状況は一定ではなく常にブレがありますので、この例のような杓子定規な通信が出来ることはまず不可能で、大なり小なりの通信速度のブレが発生します。

### なるべく通信を止めたくない場合
`duty_cycle_window` を1秒で設定すると、概ね「回線が許容出来る最大速度の1/10の速度」でずっと通信を継続させることができます。

### なるべく速度を制限させたくない場合
Duty cycle を無効にしてしまうと、電波法違反となってしまうような大量通信もできてしまいますので、日本で使う場合は最低でも Duty cycle は有効化しておきましょう。
その上で `duty_cycle_window` の値を少し大きめ（1分とか10分とか）にすれば、法律違反しないレベルで比較的高速な通信ができるようになります。もちろん通信量は単位時間の10%を超えることはできませんので、通信量が規制を超えないように自前で制御してあげる必要があります