Skip to content
RFrftools.io
Tools11 de março de 20266 min de leitura

Automatize cálculos de RF em Python com rftools

O pacote rftools Python oferece acesso programático a 203 calculadoras de RF e eletrônicas do rftools.io — com uma API digitada, CLI, modo em lote e assíncrona.

Conteúdo

Por que automatizar os cálculos de RF?

Olha, fazer um cálculo de VSWR manualmente não é grande coisa. Mas quando você está varrendo 50 comprimentos de cabo diferentes, comparando orçamentos de links para uma dúzia de opções de antenas ou montando um notebook Jupyter para sua próxima análise de design, clicar em formulários da web envelhece rapidamente.

O pacote Python rftools coloca todo o mecanismo de calculadora rftools.io diretamente no seu ambiente Python. Sem captura de dados na web, sem cópia de números entre janelas — apenas chamadas de funções simples com os tipos adequados. Já vi muitas planilhas com fórmulas quebradas e erros de copiar e colar. Isso é mais limpo.

Instalação
pip install rftools-io
Você precisará de uma chave de API gratuita do rftools.io/pricing — o nível gratuito oferece 5 chamadas por mês, o que é bom para se livrar dos pneus. Se você estiver incorporando isso em um fluxo de trabalho real ou executando varreduras regularmente, o nível da API aumenta para 10.000 chamadas/mês. Isso é suficiente para a maioria dos trabalhos reais.

Seu primeiro 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
A funçãorftools.calculate()retorna um objetoCalculatorResult. Ele se comporta como um dicionário, então você pode extrair os resultados por chave. Simples: você insere o slug da calculadora e um ditado de entradas e recebe suas respostas de volta.

Stubs digitados para preenchimento automático do IDE

Se você quiser uma melhor capacidade de descoberta e um preenchimento automático adequado do IDE (e deveria), use os módulos de categoria digitados em vez da função 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')
Todas as 13 categorias estão disponíveis:rf,pcb,power,signal,antenna,general,motor,protocol,emc,thermal,sensor,unit_conversioneaudio. Seu IDE mostrará as assinaturas da função, o que é melhor do que vasculhar a documentação toda vez que você esquece se étxPoweroutx_power.

Modo em lote (nível de API)

É aqui que as coisas se tornam úteis para um trabalho real. A API em lote permite que você execute até 50 cálculos em uma única solicitação HTTP. Isso é perfeito para varreduras de parâmetros em que, de outra forma, você estaria fazendo dezenas de chamadas de API individuais:

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')
Saída:
    10m  →  60.0 dB
    50m  →  74.0 dB
   100m  →  80.0 dB
   500m  →  94.0 dB
  1000m  →  100.0 dB
Isso é muito mais rápido do que percorrer chamadas individuais e não sobrecarrega a API com uma enxurrada de solicitações. O endpoint do lote foi projetado exatamente para esse tipo de coisa.

Suporte assíncrono

Se você estiver criando um serviço FastAPI ou trabalhando em um kernel Jupyter assíncrono, há um § 28§ que funciona bem com o padrão async/await do 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())
O cliente assíncrono usa a mesma API nos bastidores, apenas com E/S sem bloqueio. Se você já estiver em uma base de código assíncrona, isso mantém tudo consistente.

CLI

Às vezes, você só precisa de uma resposta rápida no terminal. A ferramenta de linha de comandorftoolslida com isso:

# 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
Eu uso isso principalmente para verificações de integridade quando já estou na linha de comando e não quero iniciar o Python. Também é útil em scripts de shell se você estiver automatizando algo rápido e sujo.

Tratamento de erros

A biblioteca gera exceções digitadas, para que você possa detectar problemas específicos em vez de erros 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}')
ORateLimitErroraté informa quanto tempo esperar antes de tentar novamente, o que é útil se você estiver criando uma lógica de repetição em um sistema de produção. OValidationErrordirá exatamente qual entrada estava errada, para que você não fique preso em adivinhar.

Existem 203 calculadoras disponíveis. Você pode listá-los programaticamente se precisar criar ferramentas além disso:

# 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})')
Isso é particularmente útil se você estiver criando uma interface de usuário ou camada de automação que precisa descobrir quais calculadoras estão disponíveis e quais parâmetros elas aceitam. Os metadados incluem unidades, valores padrão e descrições para cada campo.

Aqui está um exemplo real: traçar a potência recebida versus a distância para um link de 915 MHz. Esse é o tipo de coisa que você faria em um notebook Jupyter ao avaliar se um link fechará no seu 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()
Isso fornece um bom gráfico logarítmico mostrando onde seu link fica abaixo da sensibilidade do receptor. Você pode ajustar a potência de transmissão, os ganhos da antena ou a frequência e ver imediatamente o impacto. Muito mais rápido do que recalcular tudo manualmente ou clicar em um formulário da web 40 vezes.

Você pode estender isso para incluir margem de esmaecimento, comparar diferentes configurações de antena ou sobrepor dados medidos de testes de campo. A questão é que você tem o mecanismo de calculadora completo disponível em um ambiente programável, para que possa criar quaisquer ferramentas de análise de que realmente precise.

Começando

Instale-o com opip install rftools-io. O código-fonte e o rastreador de problemas estão em github.com/rftools/rftools-py. Acesse rftools.io/pricing para obter uma chave de API e ver os níveis de preços. O nível gratuito é bom para experimentar coisas, mas se você está fazendo um trabalho sério, o nível pago é barato o suficiente para que você não pense duas vezes sobre isso.

Artigos Relacionados