Automatisez les calculs RF en Python avec rftools
Le paquet Python rftools donne un accès programmatique à 203 calculateurs RF et électroniques de rftools.io : API typée, CLI, mode lot et async.
Sommaire
Pourquoi automatiser les calculs RF ?
Écoutez, faire un calcul VSWR à la main n'est pas grave. Mais lorsque vous devez parcourir 50 longueurs de câble différentes, comparer les budgets de liaisons pour une douzaine d'options d'antennes ou créer un bloc-notes Jupyter pour votre prochaine révision de conception, cliquer sur des formulaires Web devient vite obsolète.
Le package Python rftools place l'intégralité du moteur de calcul rftools.io directement dans votre environnement Python. Pas de web scraping, pas de copie de numéros entre les fenêtres, juste des appels de fonction simples avec les types appropriés. J'ai vu trop de feuilles de calcul contenant des formules erronées et des erreurs de copier-coller. C'est plus propre.
Installation
pip install rftools-io
Vous aurez besoin d'une clé API gratuite provenant de rftools.io/pricing. Le niveau gratuit vous permet de passer 5 appels par mois, ce qui est suffisant pour démarrer. Si vous intégrez cela à un flux de travail réel ou si vous effectuez régulièrement des balayages, le niveau d'API vous fait passer à 10 000 appels par mois. C'est suffisant pour la plupart des vrais travaux.
Votre premier calcul
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
La fonction rftools.calculate() renvoie un objet CalculatorResult. Il se comporte comme un dictionnaire, vous pouvez donc extraire les résultats par clé. C'est assez simple : vous transmettez le slug de la calculatrice et un dict d'entrées, et vous obtenez vos réponses.
Stubs typés pour la saisie semi-automatique de l'IDE
Si vous souhaitez une meilleure visibilité et une saisie semi-automatique appropriée de l'IDE (et vous devriez le faire), utilisez les modules de catégorie typés au lieu de la fonction générique 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')
Les 13 catégories sont disponibles :rf , pcb , power , signal , antenna , general , motor , protocol , emc , thermal , sensor , unit_conversion et audio . Votre IDE vous montrera les signatures des fonctions, ce qui vaut mieux que de parcourir la documentation chaque fois que vous oubliez s'il s'agit du txPower ou du tx_power.
Mode batch (niveau API)
C'est là que les choses deviennent utiles pour un vrai travail. L'API batch vous permet d'exécuter jusqu'à 50 calculs en une seule requête HTTP. C'est parfait pour les balayages de paramètres dans le cadre desquels vous auriez autrement effectué des dizaines d'appels d'API individuels :
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')
Sortie :
10m → 60.0 dB
50m → 74.0 dB
100m → 80.0 dB
500m → 94.0 dB
1000m → 100.0 dB
C'est bien plus rapide que de passer des appels individuels en boucle, et cela ne perturbe pas l'API avec un flot de requêtes. Le point de terminaison du lot est conçu exactement pour ce genre de choses.
Support asynchrone
Si vous créez un service FastAPI ou si vous travaillez dans un noyau Jupyter asynchrone, il existe un AsyncClient qui fonctionne parfaitement avec le modèle async/wait de Python :
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())
Le client asynchrone utilise la même API en arrière-plan, mais avec des E/S non bloquantes. Si vous utilisez déjà une base de code asynchrone, tout reste cohérent.
CLIP
Parfois, vous avez juste besoin d'une réponse rapide dans le terminal. L'outil de ligne de commande rftools gère les points suivants :
# 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
Je l'utilise principalement pour les contrôles d'intégrité lorsque je suis déjà en ligne de commande et que je ne veux pas lancer Python. C'est également pratique dans les scripts shell si vous automatisez quelque chose de rapide et sale.
Gestion des erreurs
La bibliothèque déclenche des exceptions typées, ce qui vous permet de détecter des problèmes spécifiques plutôt que des erreurs génériques :
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}')
Le RateLimitError vous indique même combien de temps vous devez attendre avant de réessayer, ce qui est utile si vous intégrez une logique de nouvelle tentative dans un système de production. Le ValidationError vous indiquera exactement quelle entrée était erronée, afin que vous ne soyez pas obligé de deviner.
Parcourir le catalogue des calculatrices
203 calculatrices sont disponibles. Vous pouvez les répertorier par programmation si vous devez créer des outils en plus de cela :
# 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})')
Cela est particulièrement utile si vous créez une interface utilisateur ou une couche d'automatisation qui doit découvrir quelles calculatrices sont disponibles et quels paramètres elles acceptent. Les métadonnées incluent les unités, les valeurs par défaut et les descriptions de chaque champ.
Un exemple pratique : Link Budget Sweep
Voici un exemple concret : tracer la puissance reçue en fonction de la distance pour une liaison 915 MHz. C'est le genre de chose que vous feriez dans un bloc-notes Jupyter lorsque vous déterminez si un lien se fermera à votre portée maximale.
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()
Cela vous donne un joli graphique logarithmique indiquant où votre lien tombe en dessous de la sensibilité du récepteur. Vous pouvez ajuster la puissance d'émission, les gains d'antenne ou la fréquence et constater immédiatement l'impact. Bien plus rapide que de tout recalculer manuellement ou de cliquer 40 fois sur un formulaire Web.
Vous pouvez l'étendre pour inclure la marge de décoloration, comparer différentes configurations d'antennes ou superposer les données mesurées lors d'essais sur le terrain. Le fait est que vous disposez du moteur de calcul complet dans un environnement scriptable, ce qui vous permet de créer tous les outils d'analyse dont vous avez réellement besoin.
Pour commencer
Installez-le avec pip install rftools-io. Le code source et l'outil de suivi des problèmes se trouvent sur github.com/rftools/rftools-py. Rendez-vous sur rftools.io/pricing pour récupérer une clé API et voir les niveaux de tarification. Le niveau gratuit est idéal pour essayer des choses, mais si vous faites un travail sérieux, le niveau payant est suffisamment bon marché pour que vous n'y réfléchissiez pas à deux fois.
Foire Aux Questions
Articles connexes
rftools.io Adds MCP: 197 Calculators for AI
rftools.io now ships an MCP server that lets AI assistants like Claude Desktop, Cursor, and Claude Code run any of our 197 RF & electronics calculators.
3 mars 2026
RF EngineeringWhen Fresnel Zones Matter: Predicting LOS Issues
Learn when Fresnel zones kill your wireless link and how to calculate clearance for 900 MHz to 60 GHz. Real examples included.
29 sept. 2026
Signal ProcessingJohnson Noise: The Thermal Noise You Can't Escape
Johnson-Nyquist thermal noise explained for RF and electronics engineers. Formula, real-world values, design impact, and common mistakes.
28 sept. 2026