Skip to content
RFrftools.io
Tools11 de marzo de 20266 min de lectura

Automatice los cálculos de RF en Python con rftools

El paquete python rftools le brinda acceso programático a 203 calculadoras de RF y electrónica de rftools.io, con una API escrita, una CLI, modo por lotes y asincrónico.

Contenido

¿Por qué automatizar los cálculos de RF?

Mira, hacer un cálculo del VSWR a mano no es gran cosa. Pero cuando estás barriendo 50 longitudes de cable diferentes, comparando los presupuestos de enlaces para una docena de opciones de antena o armando un portátil Jupyter para tu próxima revisión de diseño, el hecho de hacer clic en los formularios web pasa de moda rápidamente.

El paquete Python rftools coloca todo el motor de la calculadora rftools.io en su entorno Python. Sin necesidad de extraer datos web ni copiar números de una ventana a otra, solo llamadas a funciones sencillas con los tipos adecuados. He visto demasiadas hojas de cálculo con fórmulas rotas y errores de copiar y pegar. Esto está más limpio.

Instalación
pip install rftools-io
Necesitarás una clave API gratuita de rftools.io/pricing. La capa gratuita te ofrece 5 llamadas al mes, lo que está bien para estirar los neumáticos. Si estás integrando esto en un flujo de trabajo real o si realizas barridos con regularidad, el nivel de API te lleva a 10 000 llamadas al mes. Eso es suficiente para la mayoría de los trabajos reales.

Tu primer cálculo
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 funciónrftools.calculate()devuelve un objetoCalculatorResult. Se comporta como un diccionario, por lo que puede extraer los resultados por clave. Bastante simple: pasas el slug de la calculadora y un dictado de entradas, y obtienes tus respuestas.

Stubs mecanografiados para IDE Autocomplete

Si quieres una mejor visibilidad y una función correcta de autocompletado del IDE (y deberías hacerlo), usa los módulos de categorías escritos en lugar de la función genéricacalculate():

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')
Están disponibles las 13 categorías:rf,pcb,power,signal,antenna,general,motor,protocol,emc,thermal,sensor,unit_conversionyaudio. Su IDE le mostrará las firmas de las funciones, lo que es mejor que buscar en la documentación cada vez que olvide si estxPowerotx_power.

Modo por lotes (nivel de API)

Aquí es donde las cosas se vuelven útiles para el trabajo real. La API por lotes le permite ejecutar hasta 50 cálculos en una sola solicitud HTTP. Esto es perfecto para realizar barridos de parámetros en los que, de lo contrario, tendrías que realizar docenas de llamadas individuales a la 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')
Salida:
    10m  →  60.0 dB
    50m  →  74.0 dB
   100m  →  80.0 dB
   500m  →  94.0 dB
  1000m  →  100.0 dB
Esto es mucho más rápido que recorrer llamadas individuales en bucle, y no afecta a la API con una avalancha de solicitudes. El punto final del lote está diseñado exactamente para este tipo de cosas.

Soporte asincrónico

Si estás creando un servicio FastAPI o trabajando en un núcleo asíncrono de Jupyter, hay unAsyncClientque funciona muy bien con el patrón async/await 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())
El cliente asíncrono utiliza la misma API de forma clandestina, solo que no bloquea la E/S. Si ya tienes una base de código asíncrona, esto mantiene la coherencia de todo.

CLI

A veces solo necesitas una respuesta rápida en la terminal. La herramienta de línea de comandosrftoolsse encarga de eso:

# 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
Lo uso principalmente para comprobar la cordura cuando ya estoy en la línea de comandos y no quiero iniciar Python. También es útil en los scripts de shell si estás automatizando algo rápido y sucio.

Manejo de errores

La biblioteca genera excepciones mecanografiadas, por lo que puede detectar problemas específicos en lugar de errores genéricos:

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}')
El artículo 30§ incluso te indica cuánto tiempo debes esperar antes de volver a intentarlo, lo que resulta útil si estás incorporando la lógica de reintentos en un sistema de producción. ElValidationErrorte dirá exactamente qué entrada es incorrecta, para que no tengas que hacer conjeturas.

Hay 203 calculadoras disponibles. Puedes enumerarlas mediante programación si necesitas crear herramientas además de esto:

# 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})')
Esto es especialmente útil si estás creando una interfaz de usuario o una capa de automatización que necesita descubrir qué calculadoras están disponibles y qué parámetros aceptan. Los metadatos incluyen las unidades, los valores predeterminados y las descripciones de cada campo.

He aquí un ejemplo real: trazar la potencia recibida en función de la distancia para un enlace de 915 MHz. Esto es lo que harías en un ordenador portátil de Jupyter cuando estás evaluando si un enlace se cerrará a tu alcance máximo.

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()
Esto te proporciona un bonito gráfico logarítmico que muestra dónde tu enlace cae por debajo de la sensibilidad del receptor. Puedes ajustar la potencia de transmisión, las ganancias de la antena o la frecuencia e inmediatamente ver el impacto. Es mucho más rápido que volver a calcularlo todo a mano o hacer clic en un formulario web 40 veces.

Puede ampliarlo para incluir el margen de atenuación, comparar diferentes configuraciones de antena o superponer los datos medidos de las pruebas de campo. El punto es que tienes todo el motor de la calculadora disponible en un entorno programable, por lo que puedes crear cualquier herramienta de análisis que realmente necesites.

Cómo empezar

Instálelo conpip install rftools-io. El código fuente y el rastreador de problemas se encuentran en github.com/rftools/rftools-py. Visita rftools.io/pricing para obtener una clave de API y ver los niveles de precios. El nivel gratuito está bien para probar cosas, pero si te dedicas a un trabajo serio, el nivel de pago es lo suficientemente económico como para que no te lo pienses dos veces.

Artículos Relacionados