pamoja for TypeScript - v0.1.17
    Preparing search index...

    Module @pamoja/lora

    Ergonomic facade over the generated LoRa binding.

    LoRa buys kilometres of range on license-free bands at tiny power, and the price is time: a transmission occupies the channel for a duration the radio settings fix, and the regional rules cap how much of the time a node may transmit. This is the arithmetic that keeps a node inside that budget, with no radio and no floating point in the answer.

    @pamoja/lora

    Time-on-air, duty-cycle off-time, and the regional channel plans a LoRa node must keep to. One capability of pamoja, one memory-safe Rust core with bindings for TypeScript, Python, and C#.

    API reference read the guide documentation

    npm install @pamoja/lora
    

    This pulls in @pamoja/native, the compiled engine. npm install pamoja is the whole framework in one package.

    The test that runs in CI, spliced here as it ran.

    From bindings/node/guides/lora.ts:

    import { LoraRegion, airtimeUs, messagesPerHour, minOffTimeUs, planFor } from '@pamoja/lora'

    // EU863-870 numbers its data rates from the slowest. DR0 is SF12 at 125 kHz, the setting
    // that reaches furthest and holds the channel longest.
    const plan = planFor(LoraRegion.Eu868)
    const link = plan.linkSettings(0)!
    console.log(`${plan.name} DR0 is SF${link.spreadingFactor} at 125 kHz`)

    // The time on air for that setting, coding rate 4/5, an eight-symbol preamble, an explicit
    // header and CRC on, carrying a ten-byte reading.
    const airtime = airtimeUs(link, 10)
    console.log(`airtime ${(airtime / 1e6).toFixed(2)} s for ten bytes`)

    // 868.1 MHz falls in a sub-band capped at 1% of the time and 16 dBm, so every transmission
    // buys ninety-nine times its own length in silence.
    const channel = 868_100_000
    const permille = plan.dutyCyclePermille(channel)!
    console.log(`channel ${permille} per mille duty cycle, ${plan.maxEirpDbm(channel)} dBm`)

    const offTime = minOffTimeUs(link, 10, permille)!
    console.log(`silence ${(offTime / 1e6).toFixed(1)} s owed after each reading`)

    // The airtime plus that silence is what one reading really costs, which is the budget a
    // deployment plans against.
    console.log(`budget ${messagesPerHour(link, 10, permille)} readings an hour`)

    // A frequency in no sub-band the plan describes has no duty cycle to budget against. That
    // is a limit published elsewhere, not permission to transmit.
    const outside = plan.dutyCyclePermille(700_000_000)
    console.log(`700 MHz is outside this plan, so it budgets nothing: ${outside === null}`)
    Language Package Reference
    Rust pamoja-lora reference, docs.rs, install
    TypeScript @pamoja/lora reference, install
    Python pamoja-lora reference, install
    C# Pamoja.Lora reference, install

    MIT

    LoraChannelPlan
    LoraPlanBuilder
    LoraBeacon
    LoraChannelBlock
    LoraDataRate
    LoraMaxPayload
    LoraPlanInfo
    LoraRx2
    LoraSubBand
    LoraChannelSet
    LoraDirection
    LoraModulation
    LoraPayloadTable
    LoraRegion
    LoraChannelSet
    LoraDirection
    LoraModulation
    LoraPayloadTable
    LoraRegion
    airtimeUs
    messagesPerHour
    messagesPerHourAt
    minOffTimeUs
    planFor
    symbolTimeUs