Python での RF 計算をRFツールを使って自動化する
rftools Pythonパッケージを使用すると、型付きAPI、CLI、バッチモード、および非同期を使用して、rftools.ioの203個のRFおよび電子計算機にプログラム的にアクセスできます。
目次
- RF 計算を自動化する理由
- インストール```bash
- 初めての計算```python
- IDE オートコンプリート用の型付きスタブ
- バッチモード (API 層)
- 非同期サポート
- CLI
- エラーハンドリング
- 電卓カタログの閲覧
- 実践例:リンク・バジェット・スイープ
- はじめに`pip install rftools-io`でインストールしてください。ソースコードとイシュートラッカーは github.com/rftools/rftools-py にあります。rftools.io/pricingにアクセスしてAPIキーを入手し、価格帯を確認してください。試しには無料利用枠で十分ですが、真剣に取り組んでいるのであれば、有料利用枠の方が安いので迷うことはありません。
RF 計算を自動化する理由
ほら、VSWR 計算を 1 回手作業で行うのは大したことではありません。しかし、50 種類のケーブル長を調べたり、12 種類のアンテナオプションのリンクバジェットを比較したり、次のデザインレビューのために Jupyter ノートブックを作成したりする場合、Web フォームをクリックする作業はすぐに古くなります。
rftools Python パッケージを使うと、rftools.io の電卓エンジン全体があなたの Python 環境に正しく組み込まれます。Web スクレイピングやウィンドウ間での数値のコピーは不要です。適切な型を使った単純な関数呼び出しだけです。数式が壊れていてコピー&ペーストのエラーがあるスプレッドシートをたくさん見てきました。この方がすっきりしています。インストールpip install rftools-io
rftools.io/pricing から無料の API キーが必要です。無料利用枠では、1 か月あたり 5 回の呼び出しが可能で、疲れを癒すには十分です。これを実際のワークフローに組み込んだり、定期的にスイープを実行したりする場合、API 層では 1 か月あたり 10,000 回の呼び出しに制限されます。ほとんどの実際の作業にはこれで十分です。
pip install rftools-io初めての計算import rftools
result = rftools.calculate('vswr-return-loss', {'vswr': 2.5})
print(f'Return Loss: {result["returnLoss"]:.2f} dB') # 9.54 dB
print(f'Reflection Coeff: {result["reflectionCoeff"]:.3f}') # 0.333
rftools.calculate()関数はCalculatorResultオブジェクトを返します。辞書のように振る舞うので、キーごとに結果を引き出すことができます。簡単に言うと、電卓のスラッグと入力の辞書を渡すだけで、答えが返ってきます。
import rftools
result = rftools.calculate('vswr-return-loss', {'vswr': 2.5})
print(f'Return Loss: {result["returnLoss"]:.2f} dB') # 9.54 dB
print(f'Reflection Coeff: {result["reflectionCoeff"]:.3f}') # 0.333IDE オートコンプリート用の型付きスタブ
もっと見つけやすく、適切な IDE オートコンプリートが欲しい (そしてそうすべきだ) なら、汎用calculate()関数の代わりに型付きカテゴリモジュールを使ってください。
from rftools.calculators import rf, antenna, pcb
# Parameter names and defaults match what you see on the rftools.io web UI
fspl = rf.free_space_path_loss(frequency=2400.0, distance=100.0)
print(f'FSPL: {fspl["pathLoss"]:.1f} dB') # 80.0 dB
dipole = antenna.dipole_antenna(frequency=433.0)
print(f'Dipole length: {dipole["length"]:.0f} mm')rf、pcb、power、signal、antenna、general、motor、protocol、emc、thermal、sensor、unit_conversion、audioの13のカテゴリすべてが利用可能です。IDE が関数シグネチャを表示するので、txPowerかtx_powerかを忘れるたびにドキュメントを掘り下げて調べるよりも便利です。
バッチモード (API 層)
これが実際の作業に役立つところです。バッチ API では、1 回の HTTP リクエストで最大 50 件の計算を実行できます。これは、そうでなければ何十回も個別に API 呼び出しを行うことになるようなパラメータースイープに最適です。
import rftools
client = rftools.Client(api_key='rfc_live_xxx')
# or just: export RFTOOLS_API_KEY=rfc_live_xxx
distances = [10, 50, 100, 500, 1000]
results = client.batch([
('free-space-path-loss', {'frequency': 2400, 'distance': d})
for d in distances
])
for d, r in zip(distances, results):
if r.ok:
print(f'{d:>6}m → {r.values["pathLoss"]:.1f} dB')出力: 10m → 60.0 dB
50m → 74.0 dB
100m → 80.0 dB
500m → 94.0 dB
1000m → 100.0 dBこれは、個々の呼び出しをループ処理するよりもずっと速く、大量のリクエストで API に打撃を与えることもありません。バッチエンドポイントはまさにこのようなことを想定して設計されています。
非同期サポート
FastAPI サービスを構築している場合や、非同期 Jupyter カーネルで作業している場合、Python の非同期/待機パターンとうまく連携するAsyncClientがあります。
import asyncio
import rftools
async def main():
async with rftools.AsyncClient(api_key='rfc_live_xxx') as client:
result = await client.calculate('rf-link-budget', {
'txPower': 20,
'txGain': 6,
'rxGain': 3,
'frequency': 2400,
'distance': 500,
})
print(f'Received power: {result["rxPower"]:.1f} dBm')
asyncio.run(main())非同期クライアントは内部で同じ API を使用し、ノンブロッキング I/O を使用するだけで、すでに非同期コードベースを使用している場合は、これによってすべての一貫性が保たれます。
CLI
ターミナルでクイックアンサーが必要な場合もあります。rftoolsコマンドラインツールがそれを処理します。
# Single calculation
rftools calc vswr-return-loss --vswr 2.5
# JSON output — pipe to jq or whatever
rftools calc vswr-return-loss --vswr 2.5 --json | jq '.values.returnLoss'
# List available calculators in a category
rftools list --category rf
# Show what inputs and outputs a calculator expects
rftools info free-space-path-loss私は主に、すでにコマンドラインを使っていて、Python を起動したくないときに、これを健全性チェックに使っています。また、シェルスクリプトの中で、手っ取り早く汚いものを自動化したい場合にも便利です。
エラーハンドリング
ライブラリは型付き例外を発生させるので、一般的なエラーではなく特定の問題を検出できます。
from rftools.exceptions import AuthError, RateLimitError, ValidationError
try:
result = client.calculate('vswr-return-loss', {'vswr': 2.5})
except RateLimitError as e:
print(f'Quota exceeded. Retry after {e.retry_after}s')
except AuthError:
print('Invalid API key')
except ValidationError as e:
print(f'Bad inputs: {e.detail}')RateLimitErrorには、再試行までの待機時間も記載されています。これは、再試行ロジックを本番システムに組み込む場合に便利です。ValidationErrorはどの入力が間違っていたかを正確に教えてくれるので、推測で行き詰まることはありません。
電卓カタログの閲覧
203 種類のカリキュレータが用意されています。これを基にツールを構築する必要がある場合は、プログラムでリストアップできます。
# All calculators
calcs = rftools.list_calculators()
print(f'{len(calcs)} calculators available')
# Filter by category
rf_calcs = rftools.list_calculators(category='rf')
for c in rf_calcs:
print(f'{c.slug}: {c.title}')
# Inspect a specific calculator's inputs and outputs
info = rftools.get_calculator('noise-figure-cascade')
for field in info.inputs:
print(f' in: {field.id} ({field.unit})')
for field in info.outputs:
print(f' out: {field.id} ({field.unit})')これは、UI またはオートメーションレイヤーを構築していて、どの電卓が使用可能で、どのパラメーターが受け付けられるかを調べる必要がある場合に特に役立ちます。メタデータには、各フィールドの単位、デフォルト値、説明が含まれます。
実践例:リンク・バジェット・スイープ
実際の例として、915 MHz リンクの受信電力と距離の関係をプロットしてみます。これは、リンクが最大範囲で閉じるかどうかをサイズアップするときに、Jupyter ノートブックで行うようなものです。
import numpy as np
import matplotlib.pyplot as plt
from rftools.calculators import rf
distances = np.logspace(1, 4, 40) # 10m to 10km
rx_powers = []
for d in distances:
r = rf.rf_link_budget(
txPower=30, # dBm
txGain=6, # dBi
rxGain=6, # dBi
frequency=915, # MHz
distance=float(d),
)
rx_powers.append(r['rxPower'])
plt.semilogx(distances, rx_powers)
plt.axhline(-100, color='r', linestyle='--', label='Sensitivity (-100 dBm)')
plt.xlabel('Distance (m)')
plt.ylabel('Received Power (dBm)')
plt.title('915 MHz Link Budget')
plt.legend()
plt.grid(True)
plt.show()これにより、リンクがレシーバーの感度を下回る箇所を示すわかりやすい対数プロットが得られます。送信電力、アンテナゲイン、または周波数を微調整すれば、その影響をすぐに確認できます。すべてを手作業で再計算したり、Web フォームを 40 回クリックしたりするよりもはるかに高速です。
これを拡張して、フェードマージンを含めたり、さまざまなアンテナ構成を比較したり、フィールドテストの測定データを重ね合わせたりすることができます。重要なのは、完全な計算エンジンがスクリプト可能な環境で利用できるため、実際に必要な分析ツールをすべて構築できるということです。
はじめにpip install rftools-ioでインストールしてください。ソースコードとイシュートラッカーは github.com/rftools/rftools-py にあります。rftools.io/pricingにアクセスしてAPIキーを入手し、価格帯を確認してください。試しには無料利用枠で十分ですが、真剣に取り組んでいるのであれば、有料利用枠の方が安いので迷うことはありません。
関連記事
Annular Ring: Why the Pad Is Bigger Than You Drew It
A 0.3 mm drill does not give you a 0.3 mm hole, and the pad around it has to absorb drill wander, registration error, and plating build-up. Here is where each of those numbers comes from and why IPC-6012 Class 3 costs more.
2026年8月18日
Unit ConversionThe 180° Error: Why arctan(b/a) Flips Your Impedance
arctan of a ratio cannot tell 3 + j4 from −3 − j4. That single-argument shortcut turns inductive loads capacitive and sends matching networks in the wrong direction. Here is why atan2 exists.
2026年8月18日
PCB DesignBGA Escape Routing Starts at the Land Pad
How many traces fit between two BGA balls is decided the moment you pick the pad diameter. Here is the arithmetic from pitch to channel width to trace count, and why NSMD and via-in-pad change the answer.
2026年8月18日