pamoja.raw

Low-level generated contract for the pamoja core (the escape hatch).

This module re-exports the native pamoja._native extension verbatim. It is the Python analog of @pamoja/core/raw in the Node binding: anything the ergonomic facade does not surface is still reachable here without leaving the SDK.

 1"""Low-level generated contract for the pamoja core (the escape hatch).
 2
 3This module re-exports the native :mod:`pamoja._native` extension verbatim. It is
 4the Python analog of ``@pamoja/core/raw`` in the Node binding: anything the
 5ergonomic facade does not surface is still reachable here without leaving the SDK.
 6"""
 7
 8from pamoja import _native
 9from pamoja._native import *  # noqa: F401,F403
10
11__all__ = [name for name in dir(_native) if not name.startswith("_")]
class AckOutcome:

What an incoming acknowledgment means for the command in flight.

kind

"unrelated" if the ack was for another command, "in_progress" if the command is still running, or "final" if it finished.

value

The progress percent when in progress (255 when the autopilot does not report one), or the MAV_RESULT when final.

class Ackermann:

Car-like steering: one steered axle and a driven axle a wheelbase apart.

def steering_angle(self, /, linear, angular):

Returns the steering angle, in radians, for a forward speed and a yaw rate, or 0 while stopped.

def yaw_rate(self, /, linear, steering):

Returns the yaw rate a forward speed and a steering angle, in radians, produce.

def turn_radius(self, /, steering):

Returns the turn radius of a steering angle, in meters, or inf with the wheels straight.

def curvature(self, /, steering):

Returns the path curvature of a steering angle, the reciprocal of the turn radius.

class Ads1115:

A Texas Instruments ADS1115 driven over an I2C bus, converting one input on demand.

def init(self, /):

Writes the input, range, and data rate, and reads the configuration back. Raises PamojaError when nothing answers or the configuration reads back differently.

def sample(self, /):

Runs one conversion of the configured input and returns it, initializing the part first if init has not run.

def sample_input(self, /, mux):

Converts another input once, by its multiplexer code, leaving the configured input as it was.

config

The configuration the driver writes.

class Ads1115Config:

An ADS1115 configuration register, field by field.

comparator_queue

The comparator queue code, 0..=3, where 3 disables the comparator.

start_conversion

Whether writing this starts a single conversion.

data_rate

The data rate code, 0..=7.

mux

The input multiplexer code, 0..=7.

window_comparator

Whether to use the window comparator rather than the traditional one.

comparator_active_high

Whether the ALERT/RDY pin is active high.

comparator_latching

Whether the comparator latches until the conversion is read.

single_shot

Whether to convert once per request and power down, rather than continuously.

pga

The gain code, 0..=7, which sets the full-scale range.

class Ads1115Sample:

One ADS1115 conversion.

nanovolts

The voltage in nanovolts, exact in integer arithmetic.

volts

The voltage in volts.

clipped

Whether the conversion sits at an end code, where the output clips for a signal past the range, so the voltage is a bound rather than the reading.

raw

The conversion register, two's complement.

pga

The gain code the conversion ran at.

class AgreementKey:

A key-agreement secret, and the public key to hand to a peer.

public_key

The public key to hand to a peer.

class AlertReport:

An alert a reading raised.

Only the attribute belonging to kind is set; the rest are None.

rate

The change since the previous sample, for a changing-fast alert.

value

The measurement behind the condition, for a custom alert.

samples

The estimated samples until empty, for a running-out alert.

kind

Which threshold the reading crossed: OutOfRange, RunningOut, ChangingFast, InvalidReading for a reading that is not a finite number, or Custom for a condition the program's own policy raised.

code

The condition's name, for a custom alert.

reading

The offending reading, for an out-of-range or invalid-reading alert.

class Anomaly:

Flags a reading that stands out from the ones before it.

def check(self, /, reading):

Folds a reading in and reports whether it stands out.

Nothing is flagged before two readings are held; from the third on, a reading can be, and one that is not a finite number always is.

capacity

How many readings the baseline keeps.

class AuditEntry:

One signed record, chained onto the one before it.

def from_bytes(data):

Reads an entry back from the bytes it was written as.

def to_bytes(self, /):

Encodes this entry for storage or transmission.

previous

The hash of the entry before this one, all zeroes for the first.

index

The position of this entry in its chain.

digest

The hash of this entry, which the next one chains onto.

payload

The record this entry carries.

signature

The signature over this entry.

class AuditLog:

A log that signs what it is given and chains it onto what came before.

def resume(identity, last):

Creates a log that carries on from the last entry an earlier one wrote.

This is what a device does after a restart: the chain continues at the next index and hashes onto the entry it left off at, so a reboot leaves no gap for a record to be removed through.

def append(self, /, payload):

Appends a payload, signing it and chaining it onto the last entry.

class AuditVerifier:

Checks a chain one entry at a time, in the order the entries were written.

def check(self, /, entry):

Checks the next entry, returning whether it belongs where it was offered.

Feeding entries out of order, skipping one, or repeating one is refused just as an altered payload is.

class Bme280:

A Bosch BME280 driven over an I2C bus, measuring on demand in forced mode.

def init(self, /):

Resets the part, checks it is a BME280, reads its calibration, and writes the settings, leaving the part asleep. Raises PamojaError when nothing answers or another part does.

def measure(self, /):

Runs one forced measurement and returns the compensated reading, initializing the part first if init has not run.

class Bme280Calibration:

A BME280's factory calibration, read once and reused for every measurement.

def compensate(self, /, measurement):

Turns an eight-byte burst read into a compensated reading.

class Bme280Config:

A BME280 config register, field by field.

standby

The normal-mode standby code, 0..=7.

filter

The IIR filter code, 0..=4, where 0 is off.

spi_3wire

Whether the 3-wire SPI interface is enabled.

class Bme280CtrlMeas:

A BME280 ctrl_meas register, field by field.

mode

The power mode code: 0 sleep, 1 forced, 3 normal.

temperature

The temperature oversampling code, 0..=5, where 0 skips the measurement.

pressure

The pressure oversampling code, 0..=5, where 0 skips the measurement.

class Bme280Measurement:

A compensated BME280 reading.

celsius

The temperature in degrees Celsius.

relative_humidity_percent

The relative humidity as a percentage.

hectopascals

The pressure in hectopascals, the unit a barometer is usually quoted in.

pascals

The pressure in pascals.

class Bmp280:

A Bosch BMP280 driven over an I2C bus, measuring on demand in forced mode.

def init(self, /):

Resets the part, checks it is a BMP280, reads its trimming, and writes the settings, leaving the part asleep. Raises PamojaError when nothing answers or another part does.

def measure(self, /):

Runs one forced measurement and returns the compensated reading, initializing the part first if init has not run.

coefficients

The trimming coefficients read at initialization, or None before it.

class Bmp280Calibration:

A BMP280's factory calibration, read once and reused for every measurement.

def compensate(self, /, measurement):

Turns a six-byte burst read into a compensated reading.

def to_bytes(self, /):

Rebuilds the 24 calibration bytes a device holding these coefficients returns.

coefficients

The trimming coefficients the calibration bytes carried.

class Bmp280Coefficients:

A BMP280's per-chip trimming coefficients, as they sit in its registers.

dig_p2

The dig_P2 coefficient.

dig_t2

The dig_T2 coefficient.

dig_p3

The dig_P3 coefficient.

dig_p4

The dig_P4 coefficient.

dig_t3

The dig_T3 coefficient.

dig_p6

The dig_P6 coefficient.

dig_p7

The dig_P7 coefficient.

dig_p9

The dig_P9 coefficient.

dig_t1

The dig_T1 coefficient.

dig_p1

The dig_P1 coefficient.

dig_p5

The dig_P5 coefficient.

dig_p8

The dig_P8 coefficient.

class Bmp280Config:

A BMP280 config register, field by field.

standby

The normal-mode standby code, 0..=7.

filter

The IIR filter code, 0..=7.

spi_3wire

Whether the 3-wire SPI interface is enabled.

class Bmp280CtrlMeas:

A BMP280 ctrl_meas register, field by field.

pressure

The pressure oversampling code, 0..=5, where 0 skips the measurement.

mode

The power mode code: 0 sleep, 1 forced, 3 normal.

temperature

The temperature oversampling code, 0..=5, where 0 skips the measurement.

class Bmp280RawMeasurement:

The uncompensated codes a BMP280 burst read carries.

pressure_skipped

Whether pressure oversampling was off, so the code carries no reading.

temperature

The 20-bit temperature code.

temperature_skipped

Whether temperature oversampling was off, so the code carries no reading.

pressure

The 20-bit pressure code.

class Bmp280Reading:

A compensated BMP280 reading.

hectopascals

The pressure in hectopascals, the unit a barometer is usually quoted in.

celsius

The temperature in degrees Celsius.

pascals

The pressure in pascals.

class BootDecision:

The decision a device made at boot, already recorded before it was returned.

fallback

The slot to run. It is the same as slot for anything but Reverted.

action

What the bootloader should do: Confirmed, Trying, or Reverted.

slot

The image the decision is about, which for Reverted is the one that failed.

class Calibration:

Turns a raw sensor count into the units the reading is actually in.

def linear(scale, offset):

Creates a calibration applying raw * scale + offset.

def two_point(raw_low, value_low, raw_high, value_high):

Creates a calibration fitted through two known reference points.

def apply(self, /, raw):

Converts a raw reading into calibrated units.

class CanBus:

One node's place on a CAN bus: a kernel interface through SocketCAN on a Linux board, or a bus inside the program.

A node hears every frame the others send and none of its own, and keeps only the frames its filters pass. A send and a receive release the interpreter while the bus is busy; a receive on a simulated bus with nothing waiting returns None at once and counts its timeout in waited_micros.

def open(interface):

Opens a kernel CAN interface, such as can0, through SocketCAN. Raises PamojaError anywhere but Linux, and when the interface does not exist or cannot be bound.

def simulated():

A new bus inside the program, with this node the first on it.

def join(self, /):

Puts another node on the same bus.

def send(self, /, frame):

Sends a frame to every other node on the bus.

def receive(self, /, timeout_micros):

Takes the next frame the node keeps, waiting up to timeout_micros for one, or returns None when the timeout passed with nothing.

def set_filters(self, /, filters):

Keeps only the frames that pass at least one of the filters, from now on; an empty list keeps nothing.

def clear_filters(self, /):

Keeps every frame again, as a node does when it joins.

received

How many frames the node has received.

kind

What the bus is: "Device" or "Simulated".

interface

The kernel interface the node is on, or None on a simulated bus.

sent

How many frames the node has sent.

waited_micros

How long receives on the node have waited without a frame, in microseconds, whether or not the process slept through it.

class CanFilter:

A frame a node keeps: one whose identifier, masked, equals id, masked, and whose format is the filter's.

def exact(id, extended=False):

A filter that passes one identifier and nothing else.

def pgn(pgn):

A filter that passes one J1939 parameter group at any priority, from any source, and for an addressed group, to any destination.

def matches(self, /, id, extended=False):

Whether a frame with an identifier passes the filter.

id

The identifier to match.

extended

Whether the identifier is a 29-bit extended one.

mask

The identifier bits that have to match.

class CanFrame:

A CAN frame: an identifier, its flags, and its payload.

extended

Whether the identifier is a 29-bit extended one.

fd

Whether this is a CAN-FD frame rather than classic CAN 2.0.

id

The arbitration identifier, already masked to 11 or 29 bits.

remote

Whether this is a remote transmission request, which carries no payload.

len

The data length: the payload length, or the length a remote frame requests.

dlc

The data length code as it appears on the wire.

data

The payload, empty for a remote frame.

class CdrReader:

A CDR decoder, which reads primitives back in the order they were written.

Reading past the end returns None rather than raising, because a short buffer is a wire condition rather than a programming error.

def read_i32(self, /):

Reads the next 32-bit signed integer, or None once exhausted.

def read_u32(self, /):

Reads the next 32-bit unsigned integer, or None once exhausted.

def read_f32(self, /):

Reads the next 32-bit float, or None once exhausted.

def read_f64(self, /):

Reads the next 64-bit float, or None once exhausted.

class CdrWriter:

A CDR encoder, which writes primitives with the alignment the wire format requires.

def write_i32(self, /, value):

Appends a 32-bit signed integer.

def write_u32(self, /, value):

Appends a 32-bit unsigned integer.

def write_f32(self, /, value):

Appends a 32-bit float.

def write_f64(self, /, value):

Appends a 64-bit float.

bytes

The bytes written so far.

class ChannelPlan:

A regional channel plan, published or private.

def for_region(region):

Returns the published plan for a region.

Raises ValueError if no published region goes by that name.

def for_cn470(plan):

Returns one of the CN470-510 channel plans.

RP002-1.0.5 divides the band into four plans, for 20 MHz and 26 MHz antennas, each with a type A and B; channels_96 is the plan of the LoRaWAN 1.0.3 Regional Parameters revision A. Raises ValueError for any other name.

def cn470_plans():

Returns the name of every CN470-510 plan, as for_cn470 takes.

def regions():

Returns the short code of every published region, as for_region takes.

These are the codes a deployment is configured with. The band name the specification uses, such as EU863-870, is the plan's name.

def info(self, /):

Returns the scalar facts of the plan.

def data_rate(self, /, data_rate, direction='uplink'):

Returns the data rate a number selects, or None past the end of the plan's table.

A number the region reserves is a data rate of kind reserved, which is different from a number the plan never defines.

def max_payload(self, /, data_rate, table='uplink_direct'):

Returns what a data rate may carry in one frame, or None where the plan publishes no limit for it.

def duty_cycle_permille(self, /, frequency_hz):

Returns the share of time a transmitter may hold a frequency, in parts per thousand, or None if the frequency falls in no sub-band this plan describes.

This reports the limit; it does not impose it. Pair it with min_off_time_us to turn the limit into the silence a frame costs.

def max_eirp_dbm(self, /, frequency_hz):

Returns the power ceiling that applies at a frequency, in dBm EIRP, falling back to the plan's default where no sub-band says otherwise.

def tx_power_dbm(self, /, index, max_eirp_dbm):

Returns the radiated power a transmit-power index selects, in dBm, or None if the index is past the highest the plan defines.

def rx1_data_rate(self, /, uplink_data_rate, offset, dwell_limited=False):

Returns the downlink data rate the first receive window listens at, or None if the uplink data rate or offset is outside what the plan defines.

def rx2(self, /):

Returns where the second receive window listens, as a frequency in hertz and a data rate.

def next_backoff_data_rate(self, /, data_rate):

Returns the next lower data rate to fall back to during adaptive back-off, or None at the slowest rate the plan has.

A device that has lost the network steps down this chain, trading airtime for range until it is heard again.

def channel_frequency_hz(self, /, channel):

Returns the center frequency of one of the plan's default channels, or None past the last one the plan starts a device with.

def channel_blocks(self, /, which='default'):

Returns the plan's channel blocks: the join set, the default set, or the numbered downlink channels a fixed plan answers the first receive window on.

def rules(self, /):

Returns how the plan defines and uses its channels.

def mask_control(self, /, value):

Returns what a ChMaskCntl value does, or None past 7.

def rx1_frequency_hz(self, /, uplink_channel, uplink_hz):

Returns where the first receive window listens after an uplink on a channel.

On a plan with no numbered downlink channels that is the uplink's own frequency; otherwise it is the downlink channel the uplink channel maps to.

def join_plans(self, /):

Returns the runs of join channels that select a plan, which only the published CN470-510 plans carry.

def join_plan_for_channel(self, /, join_channel):

Returns the run of join channels a join channel belongs to, and where the accept and the second receive window fall for it, or None if no run holds it.

def relay_channels(self, /):

Returns the plan's default relay channels, by the index a relay configuration names: RP002-1.0.5 sections 3.4.9 to 3.13.9, and none where a region defines none.

def sub_bands(self, /):

Returns the plan's sub-bands and the transmit limits inside each.

name

The specification's name for the band.

class ChannelPlanBuilder:

A channel plan under construction.

Tables are indexed by position, so entries are added in data-rate order and a number the plan does not use is added as a reserved data rate. What a region would share between directions is filled in by build.

def data_rate(self, /, rate, direction='uplink'):

Adds the next data rate in a direction.

A plan that never adds a downlink rate uses its uplink table in both directions, which is what every region but the 900 MHz plans does.

def max_payload(self, /, payload=None, table='uplink_direct'):

Adds the next entry of one payload table.

Pass no payload for a data rate that carries nothing. A downlink table left empty mirrors the matching uplink one.

def channel_block(self, /, block, which='default'):

Adds a run of evenly spaced channels to the join, default, or downlink set.

def kind(self, /, kind, channel_list=None):

Sets whether the network creates channels (dynamic) or only switches numbered ones (fixed), and for a dynamic plan the numbering a type 1 channel list is read against, mhz800 or mhz900.

def tx_param_setup(self, /, answered):

Sets whether devices on the plan answer TXParamSetupReq.

def mask_controls(self, /, controls):

Sets what each ChMaskCntl value does, all eight in value order.

def join_sequence(self, /, sequence):

Sets the order a device tries the join channels in, random or octet_passes.

def power_reference(self, /, reference, gain_allowance_db=0):

Sets what the transmit power indexes count down from, eirp or conducted, and for a conducted ceiling the antenna gain it allows for.

def sub_band(self, /, band):

Adds a sub-band and the transmit limits inside it.

A deployment on licensed spectrum gives its sub-band a duty cycle of 1000, which reports as unrestricted.

def relay_channel(self, /, channel):

Adds the next default relay channel, whose position is the index a relay configuration names. A data rate that is not one of the plan's LoRa downlink rates is refused when the plan is built.

def rx1_row(self, /, offsets, dwell_limited=False):

Adds the RX1 downlink data rates for the next uplink data rate.

Every row must be as wide as the plan's highest RX1 offset allows.

def backoff(self, /, lower=None):

Adds the next entry of the adaptive back-off chain.

Pass no data rate at the slowest, which has nothing below it. A chain left empty steps down one data rate at a time.

def power(self, /, default_max_eirp_dbm, step_db=2, max_index=7):

Sets the transmit-power ladder.

def rx(self, /, rx2_frequency_hz, rx2_data_rate=0, max_rx1_offset=0):

Sets the receive windows.

max_rx1_offset fixes how wide every RX1 row must be.

def beacon(self, /, beacon, has_dwell_time_limit=False):

Sets the Class B beacon and whether the plan limits dwell time.

def build(self, /):

Finishes the plan.

Raises PamojaError if the plan would answer a question wrongly, for example because an RX1 row is narrower than the plan's offsets allow, or because the second receive window listens at a data rate the plan does not define.

class ChirpstackReception:

One gateway that heard an uplink.

gateway

The gateway's EUI, as lowercase hex.

rssi_dbm

The received signal strength, in dBm.

snr_db

The signal-to-noise ratio, in dB.

class ChirpstackUplinkEvent:

An uplink as ChirpStack reports it.

def from_json(text):

Reads an uplink event from the JSON ChirpStack published.

Fields protobuf's JSON mapping leaves out when they hold their default read as that default: a frame counter of zero, ADR off, unconfirmed. Raises PamojaError for text that is not a JSON object, an event with no device EUI, or a field that does not read as what it should.

def best_reception(self, /):

The gateway that heard it with the highest signal-to-noise ratio, or None when none did.

fport

The application port, or None for a frame that carried none.

data

The application payload, decoded from base64.

fcnt

The uplink frame counter.

device_name

The name the device was given in ChirpStack.

dev_eui

The device EUI, as lowercase hex.

application_id

The application the device belongs to.

frequency_hz

The carrier it was heard on, in hertz, or None.

adr

Whether the device had adaptive data rate on.

data_rate

The data rate, as the region numbers them.

dev_addr

The device's address, or None when the event names none.

time

When the uplink was received, as ChirpStack wrote it, or None.

confirmed

Whether the uplink was confirmed.

deduplication_id

The identifier ChirpStack gave the uplink once it deduplicated the gateways' copies.

receptions

Every gateway that heard it.

class CoapClient:

A CoAP endpoint.

def connect(self, /):

Binds the local socket so the endpoint can carry traffic.

def send(self, /, topic, payload):

Sends a payload to a resource path.

def subscribe(self, /, topic):

Observes a resource path, so messages published to it reach recv.

def recv(self, /):

Waits for the next message on an observed path, or None once closed.

def is_connected(self, /):

Whether the local socket is bound.

def disconnect(self, /):

Releases the socket the endpoint holds.

class CoapServer:

A CoAP server: the end that nodes send their readings to and observe their commands on.

A PUT or POST to a path matching one of its subscribe filters is answered 2.04 Changed and delivered to recv, and one to any other path 4.04 Not Found. send sets a resource's state, which a GET reads and every observer is notified of. send does not wait for a recv that is waiting, so a gateway sends commands while it listens for readings.

def connect(self, /):

Binds the socket and starts answering requests.

def subscribe(self, /, filter):

Takes the readings sent to the paths a filter matches, with + for one level and # for the rest.

def send(self, /, path, payload):

Sets a resource's state and notifies every observer of it.

def recv(self, /):

Waits for the next reading sent to a path the server takes.

def observers(self, /, path):

Counts the clients observing a resource.

def disconnect(self, /):

Closes the socket, keeping the resources and filters.

local_port

The port the server listens on, which names the one the system chose for port 0, or None while it is not connected.

is_connected

Whether the server holds a bound socket.

class CobsDecoder:

Reassembles whole COBS frames from the chunks a serial port delivers.

def feed(self, /, chunk):

Feeds a chunk of the stream and returns every frame it completed.

def reset(self, /):

Discards any partly assembled frame.

discarded

How many corrupt frames this decoder has discarded.

class CommandPart:

A part that is not there, answering commands with the replies it was given.

A write sends a command and any arguments after it; a read takes the reply that command left, once, padded with 0xFF. A read with no reply waiting is not acknowledged.

def answer(self, /, command, reply):

Answers one command with a reply from now on, in place of any reply given before.

address

The address the part answers to.

received

Every write the part has received, oldest first: a command and any arguments after it.

transfers

How many transfers the part has served.

class CommandProtocol:

Tracks one command awaiting its acknowledgment.

def on_frame(self, /, frame):

Classifies an incoming frame against the command in flight.

Returns the outcome, or None if the frame is not a COMMAND_ACK.

def on_timeout(self, /):

Records a timeout and reports whether the command may be resent.

Returns the new confirmation count to stamp on the resend, or None once the retry budget is exhausted.

command

The command id being tracked.

confirmation

The confirmation count to stamp on the command being sent: zero for the first transmission, incremented on each retransmission.

class Complementary:

Fuses a drifting rate, such as a gyroscope's, with a noisy absolute reading, such as an accelerometer's tilt, into one steady estimate.

def update(self, /, rate, absolute, dt):

Fuses a rate and an absolute reading over dt and returns the estimate. If any of the three is not a finite number, the update is ignored.

estimate

The current estimate.

class ControlPolicy:

A profile's control policy.

Only the attributes belonging to kind are set; the rest are None. A Custom kind is one the library does not ship: the manifest names it in custom_kind, and every field beside the kind is in params, for the program's own code to decide.

warn_within

How many samples ahead to warn, for a level policy.

safe_band

How far the reading may stray before an alert, for a setpoint policy.

hysteresis

Half the deadband width, for a setpoint policy.

kind

Which policy this describes: Setpoint, Level, Surge, Monitor, or Custom.

empty

The level treated as empty, for a level policy.

limit

The largest safe change per sample, for a surge policy.

custom_kind

The kind as the manifest names it, for a custom policy.

params

Every field the manifest carried beside a custom kind, as numbers, flags, and text by name, or None for a built-in kind.

rising

Whether a rise rather than a fall is watched, for a surge policy.

setpoint

The target reading, for a setpoint policy.

cooling

Whether the output cools rather than heats, for a setpoint policy.

class Controller:

The decision logic a profile assembles.

A controller carries state between readings, because a level estimate and a rate of change both need the previous sample, so evaluate readings through one controller in the order they were taken.

def setpoint(setpoint, hysteresis, cooling, safe_band):

Holds a reading near a setpoint by switching an output on and off.

def level(empty, warn_within):

Warns before a falling level reaches empty.

def surge(rising, limit):

Warns when a reading changes faster than a limit.

def monitor():

Reports readings without judging them.

def evaluate(self, /, reading):

Decides what one reading calls for.

class Debounce:

Stops a flickering input from acting until it has settled.

def update(self, /, raw):

Feeds a raw reading in and returns the settled state.

state

The settled state.

class Delegation:

A statement, signed by the anchor, that a second key may sign releases.

release_key

The public key that may sign manifests while this delegation stands.

expires

When the delegation stops being honored, in seconds since the Unix epoch, or 0 to never expire.

epoch

Rises with every rotation, so a retired key cannot be reinstated by replaying the statement that once authorized it.

class Depletion:

Warns before a falling level runs out, by projecting its rate of fall.

def update(self, /, level):

Records a level and returns the samples left before the threshold.

Returns 0 once the level is at or below the threshold, the first reading included, and None while the level is steady or rising, or on a first reading above it, when no rate of fall is known yet.

class DeviceIdentity:

A device's private signing identity.

def sign(self, /, payload):

Signs a payload, returning the 64-byte detached signature.

def sign_message(self, /, payload):

Signs a payload and returns the signature followed by the payload, as one message.

fingerprint

The short hex fingerprint of this identity, for logs and displays.

public_key

The public key matching this identity, which is safe to share.

class DhParameters:

One joint of a serial arm in the Denavit-Hartenberg convention.

def transform(self, /):

Returns the homogeneous transform this joint makes.

a

The link length along the common normal, in meters.

d

The link offset along the previous z axis, in meters.

theta

The joint angle about the previous z axis, in radians.

alpha

The link twist about the common normal, in radians.

class Dialect:

The CRC_EXTRA seeds of a dialect beyond the common one.

Entries added here are consulted before the built-in common-dialect registry, so a private dialect may also override an id the common one defines.

def add(self, /, msgid, crc_extra):

Adds or replaces the seed for a message id.

def add_message(self, /, msgid, name, fields):

Adds a message by its definition, deriving the seed, and returns it.

This is the whole path for a vendor dialect: describe the message once, and every frame carrying it checks from then on.

def crc_extra(self, /, msgid):

Returns the seed this dialect resolves a message id to, or None if neither it nor the common dialect knows the id.

class DiffDrive:

Wheel speeds for a desired body motion, and the body motion measured wheel speeds make, for a robot that steers by spinning two wheels at different speeds.

def wheel_speeds(self, /, linear, angular):

Returns the (left, right) wheel speeds for a forward speed and a turn rate.

def body_motion(self, /, left, right):

Returns the (linear, angular) body motion measured wheel speeds make.

class Ds18b20Reading:

A decoded DS18B20 scratchpad.

alarm_low

The low alarm threshold in whole degrees Celsius.

raw_temperature

The raw temperature register, 1/16 degree Celsius per count.

alarm_high

The high alarm threshold in whole degrees Celsius.

micro_celsius

The temperature in micro-degrees Celsius, exact in integer arithmetic.

resolution_bits

The configured resolution, as a number of bits: 9, 10, 11, or 12.

celsius

The temperature in degrees Celsius.

class Ds18b20Thermometer:

A DS18B20 the Linux kernel serves as a w1_slave file under /sys/bus/w1/devices.

def for_serial(serial):

A thermometer named by the serial in its directory name, the twelve hex digits after 28-.

def at(path):

A thermometer named by the path of its w1_slave file.

def discover(devices=None):

Every DS18B20 the kernel has found, one per 28- directory under devices, which is /sys/bus/w1/devices unless given. Raises PamojaError when the directory cannot be listed, which usually means the 1-Wire overlay is off.

def read(self, /):

Reads the file, which makes the kernel run a conversion, and returns the decoded reading. Raises PamojaError when the file cannot be read or the kernel or this decoder rejects the checksum.

serial

The serial the kernel named the thermometer's directory after: the twelve hex digits after 28-, which tell one probe from another and stay with the part for life. None when the file does not sit in a DS18B20's directory, as one named by at may not.

path

The path of the file the thermometer reads.

class DutyCycle:

The split between the time a node works and the time it sleeps.

def from_fraction(period_us, fraction):

Creates a duty cycle that spends fraction of period_us awake.

The fraction is clamped to 0 through 1, and one that is not a number keeps the node asleep for the whole period. The time awake is rounded down to a whole microsecond and the rest of the period is spent asleep, so the two always add up to the period.

active_us

How long the node stays awake each period, in microseconds.

period_us

The whole period, awake plus asleep, in microseconds.

sleep_us

How long it sleeps each period, in microseconds.

fraction

The share of the period spent awake, from 0 through 1.

class EStop:

An emergency stop that latches until a person resets it.

def engage(self, /):

Engages the stop; it holds until reset.

def reset(self, /):

Clears the stop.

def gate(self, /, desired):

Returns desired while clear, or a zero twist while engaged.

is_engaged

Whether the stop is engaged.

class ElementSpec:

A custom sensor or node stat a profile contributes to the dashboard.

The graphic is named as a manifest names it (droplet, gauge, ...); the Viz enum in the facade lists the choices. A band is (low, high) in the element's unit, and scope names the link kinds whose groups the element is offered on, or None for every group.

scope

The link kinds whose groups this element is offered on; None means every group.

labels

Per-locale labels, keyed by locale tag (en, sw, ...).

span

Whether the element's tile spans two columns.

label

A human-readable fallback label, shown when no localized label applies.

key

The stable, language-neutral element key, such as water_turbidity.

viz

The graphic this element is drawn with, by its manifest name.

stat

Whether this is a node or network stat rather than a measurement of the world.

value

A starting numeric value for the add-sensor dialog.

unit

The canonical unit name, such as ntu, ph, or count.

band

The safe band (low, high) in the element's unit.

state

A starting discrete state code, such as state.closed, for a non-numeric element.

class Esc:

An electronic speed controller's pulse widths from full reverse to full forward.

def bidirectional():

The common reversible controller: 1000, 1500, and 2000 microseconds.

def pulse(self, /, throttle):

Returns the pulse width for a throttle from -1 to 1, held to that range, or the neutral one for a throttle that is not a number.

neutral_us

The pulse width at rest, in microseconds.

min_us

The pulse width at full reverse, in microseconds.

max_us

The pulse width at full forward, in microseconds.

class EventBus:

One endpoint on an event bus.

An endpoint both publishes and receives, and it receives what it publishes itself. Each subscriber needs its own, taken with subscribe, because an endpoint only sees events published after it existed. Only next_event and next_text wait: publishing and subscribing return at once, even while a wait on the same endpoint is open.

def subscribe(self, /):

Takes another endpoint on the same bus.

The new endpoint sees events published from now on, not those already sent, so subscribe before publishing anything it needs to see.

def publisher(self, /):

Takes a publish-only handle on the same bus, for a part that announces and never reads.

def publish(self, /, event):

Publishes an event to every subscriber, this endpoint included: bytes, or text such as an event name.

It never waits: a subscriber that has fallen behind loses its oldest event rather than holding up the publisher.

def next_event(self, /):

Waits for the next event on this endpoint.

The wait lasts until an event arrives. asyncio.wait_for gives up sooner, and the wait it cancels takes no event.

def next_text(self, /):

Waits for the next event as text.

Raises ValueError if the event is not UTF-8 text.

missed

How many events this endpoint lost by falling behind, as of its last completed wait.

class EventPublisher:

A publish-only handle to an event bus.

It has no queue of its own, so a part that only announces never fills a buffer it does not read. Publishing never waits, so a callback on another thread can call it without an event loop.

def publish(self, /, event):

Hands an event to every current subscriber: bytes, or text such as an event name.

Returns how many subscribers the event was handed to. An event published while no one is subscribed is dropped, and the count is 0.

def subscribe(self, /):

Subscribes to the bus, returning an endpoint that sees events published from now on.

def publisher(self, /):

Takes another publisher on the same bus, for another part that announces.

class ForwardDecision:

A routing decision, and the neighbor it names when there is one.

next_hop

The neighbor to unicast to, or None unless the action is Relay.

action

What to do with the packet: Deliver, Relay, or Flood.

class GatewayNetwork:

The network side of one site: what a server does with what a gateway forwarded.

def register(self, /, dev_eui, app_eui, app_key, version=None):

Admits a device, so a join request signed with its key is accepted.

version is the link layer revision the device follows, "1.0.3" or "1.0.4", and 1.0.4 unless given. A 1.0.3 device's frames are refused once their counter runs MAX_FCNT_GAP ahead of the last one accepted, which TS001-1.0.4 no longer asks.

def answer(self, /, dev_addr, slot, fport, payload):

Builds a downlink for a device, encrypted with its session.

def notices(self, /):

Takes the devices relays have reported hearing and could not verify, TS011-1.0.1 section 10.7.

A relay carries these in the MAC commands of its own uplinks, alongside whatever else that uplink was for, so they wait here until they are read.

def command(self, /, dev_addr, slot, commands):

Builds a downlink carrying MAC commands, which is how a network configures a relay.

The commands ride in the frame options where they fit, and in a frame of their own on port 0 where they do not.

def trust_command(self, /, dev_addr, index, reload_rate=63, bucket_size=0):

Builds the command that tells a relay to trust a device, with the key that lets it verify the device's wake-on-radio frames, TS011-1.0.1 section 10.4.

index is the entry in the relay's list, reload_rate how many of the device's uplinks it forwards an hour, 63 for no limit, and bucket_size the coded multiplier of table 55.

class GatewayNetworkEvent:

What a forwarded packet turned out to be, and where its answer goes.

dev_eui

The device that joined, as sixteen hexadecimal digits.

relay

What a relay added to an uplink it carried, and None for one a gateway heard directly.

fcnt

The counter the frame carried, reconstructed to its full width.

slot

Where an answer goes, for a join or for data.

fport

The port the frame was sent on, absent for a frame carrying only options.

outcome

joined, data, or foreign.

payload

What the device sent, decrypted.

accept

The packet carrying the accept, for a join.

confirmed

Whether the device asked to be acknowledged.

dev_addr

The address granted, or the address a frame claimed.

class GatewayNotice:

A device a relay heard and could not verify, TS011-1.0.1 section 10.7.

dev_addr

The address the wake-on-radio frame named.

rssi_dbm

The frame's signal strength in dBm.

snr_db

Its signal-to-noise ratio in dB.

relay

The relay that heard it.

class GatewayPacket:

One datagram of the protocol, with the fields its kind carries.

kind

Which kind of datagram: "PushData", "PushAck", "PullData", "PullResp", "PullAck", or "TxAck".

packets

The packets a PUSH_DATA forwards.

gateway

The gateway's identifier, as sixteen hexadecimal digits, for the kinds that carry one.

status

The report a PUSH_DATA carries.

token

The token that pairs a datagram with its answer.

transmit

What a PULL_RESP asks the gateway to transmit.

tx_status

What a TX_ACK reports, such as "NONE" or "COLLISION_PACKET".

class GatewayRelayed:

What a relay added to an uplink it forwarded, TS011-1.0.1 section 9.1.

snr_db

Its signal-to-noise ratio, in dB.

wor_channel

The wake-on-radio channel the device woke the relay on: default or second.

relay

The relay's own address.

data_rate

The data rate it arrived at.

rssi_dbm

What it heard of the uplink, in dBm.

frequency_hz

The frequency it arrived on, in hertz.

class GatewayRxpk:

A packet the gateway heard, with the metadata the protocol carries beside it.

channel

The concentrator channel it arrived on.

crc

What the CRC said: "Ok", "Failed", or "Absent".

bitrate_bps

The bitrate in bits per second, for an FSK packet.

timestamp_us

The concentrator's own timestamp of the reception, in microseconds.

rssi_dbm

The received signal strength in dBm.

rf_chain

The radio chain it arrived on.

frequency_hz

The carrier it arrived on, in hertz.

received_at_us

When it arrived, in microseconds since 1970-01-01 UTC.

gps_millis

When it arrived on the GPS clock, in milliseconds since 6 January 1980.

snr_db

The signal-to-noise ratio in dB, for a LoRa packet.

payload

The packet itself.

class GatewaySlot:

Where and when a downlink answers an uplink, in the concentrator's own terms.

timestamp_us

The concentrator timestamp to transmit at, in microseconds.

frequency_hz

The frequency to transmit on, in hertz.

class GatewayStat:

A gateway's own status report.

received

How many packets its radio received.

forwarded

How many it forwarded.

acknowledged_percent

What share of its datagrams were acknowledged, as a percentage.

time_s

The gateway's clock, in seconds since 1970-01-01 UTC.

received_ok

How many of those had a good CRC.

transmitted

How many packets it transmitted.

altitude_m

Its altitude in meters.

latitude_deg

Its latitude in degrees, north positive.

longitude_deg

Its longitude in degrees, east positive.

class GatewayStationBroadcast:

One frame of a schedule, transmitted to a group rather than a device.

data_rate

The data rate to transmit at.

priority

How urgent it is.

frequency_hz

The frequency to transmit on, in hertz.

pdu

The frame to transmit.

gpstime

The GPS time to transmit at.

rctx

The radio to transmit on.

class GatewayStationDataRate:

One number of a configuration's data-rate table.

bandwidth_hz

The bandwidth in hertz.

spreading_factor

The spreading factor, 0 for FSK.

class GatewayStationJoinRange:

A range of join identifiers whose join requests a station forwards, both ends included.

first

The first identifier, as sixteen hexadecimal digits.

last

The last identifier, as sixteen hexadecimal digits.

class GatewayStationLevels:

How a station heard a packet, as it reports it.

snr

The signal-to-noise ratio, in dB.

xtime

The station clock, in microseconds.

rctx

The radio the packet arrived on, which an answer goes back out on.

gpstime

The GPS time, when the station has one.

rssi

The received signal strength, in dBm.

class GatewayStationMessage:

A message either side of a session sends.

Every message names its kind in msgtype, and carries the fields that kind uses. The rest read as None. Build one with the keyword arguments of its kind and write it with station_encode().

data_rate

The data rate a frame arrived at.

mhdr

The MAC header byte, for a join request or a data frame.

protocol

The protocol version it speaks, for a version.

freq_max

The highest frequency the station may use, in hertz.

priority

How urgent a downlink is.

firmware

Its firmware, for a version.

payload

The payload a frame carries, still encrypted, the whole of a proprietary frame, or the frame a downlink transmits.

freq_min

The lowest frequency the station may use, in hertz.

station

The station software, for a version.

data_rates

A configuration's data rates, indexed by data-rate number, with None for a number the table leaves undefined.

dev_nonce

The nonce a join request used.

dev_addr

The address a data frame came from.

class_

Which class of downlink this is: 0 for A, 1 for B, 2 for C.

net_id

The networks whose data frames a configuration forwards, None to forward every network's. A station matches each against the top seven bits of a device address, so an empty list forwards no data frame at all.

frequency_hz

The frequency in hertz.

region

The region name, for a configuration.

rx_delay

The delay before the first receive window, in seconds.

rx2

The second receive window a downlink names.

dev_eui

The device, as sixteen hexadecimal digits.

rx1

The first receive window a downlink names.

xtime

The station clock in microseconds: the uplink a downlink answers, the moment a reported frame went out, or the one a time sync carries.

schedule

What to transmit to a group, for a schedule.

fopts

The frame options a data frame carries.

fcnt

The frame counter, as the sixteen bits on the air.

max_eirp

The highest radiated power the region allows, in dBm.

levels

How it was heard, for the kinds a station sends up.

model

The hardware model, for a version.

features

What it can do, for a version.

hwspec

The concentrator the configuration is written for.

fport

The port, None for a frame carrying only options.

msgtype

The kind as the protocol writes it, such as jreq or updf.

mic

The message integrity code.

package

The package it came from, for a version.

join_eui_ranges

The join identifier ranges a configuration forwards; empty forwards every join.

rctx

The radio, for a downlink or a report.

txtime

When a frame went out, in seconds, or the station time a time sync carries, in microseconds.

diid

The identifier a downlink and its transmission report share.

join_eui

The application being joined, as sixteen hexadecimal digits.

gpstime

The GPS time in microseconds since the GPS epoch.

ping_slot

The ping slot a class B downlink goes out in.

fctrl

The frame control byte.

class GatewayStationRouter:

The answer a discovery endpoint gives.

error

Why the station was refused, when it was.

router

The station, as the server read it.

muxs

The server endpoint carrying the session.

uri

The websocket to open, absolute.

class GatewayStationWindow:

A receive window, or the ping slot a class B frame goes out in.

data_rate

The data rate, as the network's table numbers it.

frequency_hz

The frequency in hertz.

class GatewayStationXtime:

A station clock value taken apart.

unit

The radio unit the time was read on, 0 to 127.

session

The run of the station the time belongs to.

micros

The microseconds the run had counted, below 2^48.

class GatewayTxpk:

A packet the server asks the gateway to transmit.

frequency_hz

The carrier to transmit on, in hertz.

bitrate_bps

The bitrate in bits per second, for an FSK packet.

timestamp_us

The concentrator timestamp to transmit at, in microseconds.

invert_polarity

Whether to invert the LoRa polarity, as a LoRaWAN downlink is sent.

gps_millis

The GPS time to transmit at, in milliseconds since 6 January 1980.

frequency_deviation_hz

The FSK frequency deviation in hertz.

preamble_symbols

How long a preamble to send, in symbols.

payload

The packet itself.

without_crc

Whether to leave the physical CRC off, as LoRaWAN downlinks are.

rf_chain

The radio chain to transmit from.

immediate

Whether to transmit at once, which ignores the timestamps.

power_dbm

The power to transmit at, in dBm.

class Geofence:

Keeps a tracked point inside an area, and notices when it leaves.

def update(self, /, latitude, longitude):

Feeds a fix in and names where it sits, including a single crossing.

Returns one of "Inside", "Outside", "Exited", or "Entered".

def contains(self, /, latitude, longitude):

Reports whether a fix lies inside, without recording a crossing.

class GpioLine:

A GPIO line opened on a Linux board, through the kernel's GPIO character device.

Levels cross as "Low" and "High"; the facade's GpioLine speaks the Level enum.

def open_output(chip, line, initial):

Opens a line as an output, driving initial from the moment it is taken.

Raises PamojaError when the platform is not Linux, or the chip or the line cannot be opened, and ValueError for a level other than "Low" or "High".

def open_input(chip, line):

Opens a line as an input.

Raises PamojaError when the platform is not Linux, or the chip or the line cannot be opened.

def drive(self, /, level):

Drives the line to "Low" or "High". Raises PamojaError when the kernel refuses the write, which an input line does, or the line is closed.

def read(self, /):

Reads the level on the line now, as "Low" or "High". Raises PamojaError when the kernel refuses the read, or the line is closed.

def close(self, /):

Hands the line back to the kernel. Calls after this raise PamojaError.

offset

The line's number on its chip.

chip

The GPIO chip's device file.

class Guidance:

The command toward a waypoint, with the geometry behind it.

twist

The body motion to drive.

heading_error_deg

The heading error to the target, in degrees, in (-180, 180].

distance_m

The distance left to the target, in meters.

arrived

Whether the target is within the arrival radius.

class Hdc1080:

A Texas Instruments HDC1080 driven over an I2C bus, measuring temperature then humidity from one trigger.

def init(self, /):

Checks the part is an HDC1080 and writes the configuration. Raises PamojaError when nothing answers or another part does.

def measure(self, /):

Triggers one acquisition of both channels and returns them, initializing the part first if init has not run. Raises PamojaError when the part does not acknowledge the read, which it refuses until its results are ready.

def heater(self, /, on):

Switches the on-die heater, which runs only during acquisitions, on or off.

configuration

The configuration the driver writes.

class Hdc1080Config:

An HDC1080 configuration register, field by field.

battery_low

Whether the supply has dropped below 2.8 V, which the part reports back.

sequential

Whether one trigger acquires temperature and humidity in sequence.

software_reset

Whether writing this resets the part.

humidity_resolution_bits

The humidity resolution in bits: 14, 11, or 8.

heater

Whether the on-die heater runs during measurements.

temperature_resolution_bits

The temperature resolution in bits: 14 or 11.

class Hdc1080Measurement:

A decoded HDC1080 temperature and humidity pair.

milli_celsius

The temperature in milli-degrees Celsius, exact in integer arithmetic.

celsius

The temperature in degrees Celsius.

milli_percent

The relative humidity in milli-percent.

relative_humidity

The relative humidity as a percentage.

humidity_raw

The raw humidity register.

temperature_raw

The raw temperature register.

I2C_RESERVED_BELOW = 8
I2C_RESERVED_FROM = 120
class I2cBus:

One I2C bus, shared by the program and every driver built on it.

A failed transfer raises PamojaError with the reason: nothing answered at the address, the script expected something else, or the kernel's own words.

def open(path):

Opens the kernel's I2C adapter, such as /dev/i2c-1 on a Raspberry Pi.

Raises PamojaError anywhere but Linux, and when the file cannot be opened as an adapter: the interface is not turned on, or the process may not use it.

def simulated(parts=None):

A bus of simulated parts of any kind, each answering at its own address. A later part at an address an earlier one holds takes its place.

def scripted(steps):

A bus that plays the steps in order and refuses any transfer that is not the next one.

def attach(self, /, part):

Puts a copy of a part of any kind on a simulated bus, in place of any part at its address. Raises PamojaError for a bus that is not simulated.

def write(self, /, address, data):

Writes bytes to a part in one transaction: usually a register address and its value.

def read(self, /, address, length):

Reads length bytes from a part in one transaction.

def write_read(self, /, address, data, length):

Writes bytes and then reads length bytes in one transaction, with a repeated start between them, which is how a register is read.

def part(self, /, address):

A copy of what a simulated part holds now, with whatever drivers have written to it, as the class of part it is, or None when the bus is not simulated or no part holds the address.

remaining

How many steps a script has left, or None when the bus is not scripted.

waited_micros

How long the drivers on the bus have asked to wait, in microseconds, whether or not the process slept through it.

kind

What answers on the bus: "Adapter", "Simulated", or "Scripted".

transfers

How many transfers have been made on the bus, by the program and every driver on it, including any that failed.

class I2cPart:

A part that is not there, answering from 256 registers.

A write names a register and fills it and the ones after it; a read takes them back from wherever the last write left off. What a driver writes stays written.

def load(self, /, first, data):

Puts bytes in the part from a register on. Past the last register they wrap to the first.

def register(self, /, register):

What one register holds now.

def read(self, /, first, length):

What consecutive registers hold, from one register on.

transfers

How many transfers the part has served.

address

The address the part answers to.

class I2cStep:

One transfer a script expects, and what the part answers.

def write(address, data):

The driver writes exactly data to the address.

def read(address, reply):

The driver reads from the address and receives reply, whose length is the length it must ask for.

def write_read(address, data, reply):

The driver writes data and then reads reply in one transaction, the shape of a register read.

def fault(address, fault):

The next transfer to the address fails, the way a missing or busy part does. The fault is "NoAcknowledgeAddress", "NoAcknowledgeData", "NoAcknowledge", "Bus", "ArbitrationLoss", "Overrun", or "Other".

class ImageVerifier:

Hashes an image as it arrives and settles it against its manifest.

def update(self, /, chunk):

Takes the next piece of the image, in order.

def finish(self, /):

Settles the image, returning its digest, and spends this verifier.

Raises if the image is not the one the manifest described.

class Ina219:

A Texas Instruments INA219 driven over an I2C bus, measuring shunt and bus voltage, current, and power on demand.

def init(self, /):

Resets the part, writes the configuration and the calibration, and reads the calibration back. Raises PamojaError when nothing answers or it does not hold.

def measure(self, /):

Triggers one shunt and bus conversion and returns every result, initializing the part first if init has not run.

current_lsb_microamps

The current step the driver programs, in microamps per count.

calibration_word

The calibration word the driver programs.

class Ina219Config:

An INA219 configuration register, field by field, each setting as the code the datasheet prints.

reset

Whether writing this resets the part.

bus_range

The bus-voltage range code: 0 for 16 V, 1 for 32 V.

shunt_adc

The shunt converter code, as bus_adc.

gain

The shunt gain code, 0..=3, for ranges of 40, 80, 160, and 320 mV.

bus_adc

The bus converter code, 0..=15: a resolution below 8, a sample count averaged at 12 bits from 9 up.

mode

The operating-mode code, 0..=7.

class Ina219Reading:

One INA219 conversion: the four result registers as read, and what they mean.

power_microwatts

The power in microwatts.

current

The current register.

shunt_microvolts

The shunt voltage in microvolts.

current_microamps

The current in microamps; negative flows the other way through the shunt.

math_overflow

Whether the part's arithmetic overflowed, leaving current and power meaningless.

current_lsb_microamps

The current step the calibration programmed, in microamps per count.

bus

The bus-voltage register, flags included.

power

The power register.

bus_millivolts

The bus voltage in millivolts.

shunt

The shunt-voltage register.

class Ina226:

A Texas Instruments INA226 driven over an I2C bus, measuring shunt and bus voltage, current, and power on demand.

def init(self, /):

Resets the part, checks it is an INA226, writes the configuration and the calibration, and reads the calibration back. Raises PamojaError when nothing answers or another part does.

def measure(self, /):

Triggers one shunt and bus conversion and returns every result, initializing the part first if init has not run.

def set_alert(self, /, mask, limit):

Programs the alert pin: which limit it watches, one function at a time, and the limit, in the units of the register the function watches.

current_lsb_microamps

The current step the driver programs, in microamps per count.

calibration_word

The calibration word the driver programs.

identity

The die id read at initialization, or None before it.

class Ina226Config:

An INA226 configuration register, field by field.

shunt_conversion_time

The shunt-voltage conversion-time code, 0..=7.

mode

The operating-mode code, 0..=7.

averaging

The averaging code, 0..=7, from 1 to 1024 samples.

reset

Whether writing this resets the part.

bus_conversion_time

The bus-voltage conversion-time code, 0..=7.

class Ina226DieId:

A decoded INA226 die-ID register.

device

The 12-bit device identifier.

revision

The 4-bit die revision.

class Ina226MaskEnable:

An INA226 Mask/Enable register, field by field.

bus_over_limit

Alert when the bus voltage exceeds the limit.

power_over_limit

Alert when the power exceeds the limit.

alert_function_flag

Whether the selected limit function caused the last alert.

shunt_under_limit

Alert when the shunt voltage drops below the limit.

bus_under_limit

Alert when the bus voltage drops below the limit.

math_overflow

Whether an arithmetic overflow left current and power invalid.

alert_active_high

Whether the alert pin is active high.

alert_latch

Whether the alert pin latches until this register is read.

conversion_ready

Also alert when a conversion completes.

conversion_ready_flag

Whether every conversion and multiplication has completed.

shunt_over_limit

Alert when the shunt voltage exceeds the limit.

class Ina226Reading:

One INA226 conversion: the four result registers as read, and what they mean.

bus

The bus-voltage register.

bus_microvolts

The bus voltage in microvolts.

shunt

The shunt-voltage register.

power

The power register.

bus_volts

The bus voltage in volts.

current_microamps

The current in microamps; negative flows the other way through the shunt.

current_lsb_microamps

The current step the calibration programmed, in microamps per count.

shunt_nanovolts

The shunt voltage in nanovolts.

current

The current register.

power_microwatts

The power in microwatts.

power_watts

The power in watts.

shunt_millivolts

The shunt voltage in millivolts.

current_amps

The current in amps.

math_overflow

Whether the part's arithmetic overflowed, leaving current and power meaningless.

class J1939Message:

The fields J1939 packs into an extended CAN identifier.

pgn

The parameter group number, which names what the message carries.

destination

The destination address for an addressed (PDU1) message, or None for a broadcast (PDU2) one.

source

The source address: the node that sent the message.

broadcast

Whether the message is a broadcast.

pdu_format

The PDU format byte of the parameter group.

priority

The message priority, 0 (highest) to 7.

class Kalman:

Estimates a true value from noisy readings, trusting the model and the sensor in proportion to how noisy each is.

def update(self, /, reading):

Folds a reading in and returns the new estimate.

estimate

The current estimate.

LORAWAN_ADR_ACK_DELAY = 32
LORAWAN_ADR_ACK_LIMIT = 64
LORAWAN_CLOCK_PORT = 202
LORAWAN_FIRMWARE_PORT = 203
LORAWAN_FORWARD_OVERHEAD = 6
LORAWAN_FRAGMENT_PORT = 201
LORAWAN_JOIN_ACCEPT_DELAY1_US = 5000000
LORAWAN_JOIN_ACCEPT_DELAY2_US = 6000000
LORAWAN_LA_FPORT_RELAY = 226
LORAWAN_MAX_FCNT_GAP = 16384
LORAWAN_MAX_FRAGMENTS = 16383
LORAWAN_MIN_WOR_PREAMBLE_SYMBOLS = 8
LORAWAN_MULTICAST_PORT = 200
LORAWAN_RECEIVE_DELAY1_US = 1000000
LORAWAN_RECEIVE_DELAY2_US = 2000000
LORAWAN_RECEIVE_WINDOW_TOLERANCE_US = 20
LORAWAN_RELAY_FWD_DELAY_US = 50000
LORAWAN_RETRANSMIT_TIMEOUT_MAX_US = 3000000
LORAWAN_RETRANSMIT_TIMEOUT_MIN_US = 1000000
LORAWAN_RXR_DELAY_US = 18000000
LORAWAN_SAVED_LEN = 1678
LORAWAN_TRUSTED_ED_NUMBER = 16
LORAWAN_WOR_ACK_DELAY_US = 50000
LORAWAN_WOR_ATTEMPTS_WO_ACK = 8
LORAWAN_WOR_DATA_DELAY_US = 50000
class Ladder:

An ordered set of transports backed by an offline buffer.

def rung(self, /, transport):

Adds a rung, which is tried after the rungs already added.

Add the cheapest, most-preferred link first and the costliest fallback last, because a send takes the first rung that accepts it. The transport is consumed. A transport that delivers is subscribed and listened on; a host transport without recv is an uplink the ladder never listens on.

def connect(self, /):

Connects every rung, so a send can be tried against each in turn.

A rung that will not connect is left in the ladder: it may come back, and a send simply falls through it until it does.

def send(self, /, topic, payload):

Sends a payload, falling through the rungs and buffering if none take it.

Returns "Sent" or "Buffered". Buffering is a success, not a failure: it is what the ladder exists to do.

def flush(self, /):

Replays the buffer over the rungs, oldest message first, and reports how many went out.

def buffered(self, /):

How many messages are waiting in the buffer.

def subscribe(self, /, topic):

Subscribes every rung that listens to a topic.

The filter is kept for the life of the ladder: a rung that is down when it is placed receives it when it next connects, so subscribing before connect is fine and never fails for want of a link.

def recv(self, /):

Waits for the next message from any rung that listens, whichever delivers first.

Raises if no connected rung listens: none was added, the ladder is not connected, or every listening link has ended. The ladder does one thing at a time, so a send waits behind a receive in progress; a node that listens and reports waits with asyncio.wait_for and sends between waits.

class Limits:

Speed and acceleration limits, with the motion they last allowed.

def apply(self, /, desired, dt):

Returns desired held to the speed limits and eased toward within the acceleration limits over dt.

def reset(self, /):

Forgets the motion last allowed, so the next command eases up from rest.

class LinkBudget:

The gains and losses of a LoRa link, from the transmitting radio to the receiving one.

Every value is in decibels, resolved to the hundredth of a decibel the Rust crate holds.

def eirp_dbm(self, /):

The equivalent isotropically radiated power, in dBm.

The transmit power plus the transmitting antenna gain, less the transmitting cable loss. This is the figure regional power ceilings limit.

def received_dbm(self, /, path_loss_db):

The power that reaches the receiving radio across a path, in dBm.

def sensitivity_dbm(self, /, link):

The weakest signal the receiver can demodulate on a link, in dBm.

def max_path_loss_db(self, /, link):

The most path loss the link survives, in dB.

def margin_db(self, /, link, path_loss_db):

How far above the sensitivity a signal arrives across a path, in dB.

Negative where the path loses more than the link survives.

def max_transmit_power_dbm(self, /, eirp_ceiling_dbm):

The most transmit power that keeps the EIRP at or under a ceiling, in dBm.

A higher-gain antenna leaves less power for the radio.

receive_cable_loss_db

The loss in the cable and connectors between the receiving antenna and its radio, in dB.

noise_figure_db

The noise figure of the receiver, in dB.

receive_antenna_gain_dbi

The gain of the receiving antenna over an isotropic antenna, in dBi.

transmit_antenna_gain_dbi

The gain of the transmitting antenna over an isotropic antenna, in dBi.

transmit_power_dbm

The power the transmitting radio delivers at its antenna port, in dBm.

transmit_cable_loss_db

The loss in the cable and connectors between the transmitting radio and its antenna, in dB.

class LoopbackBroker:

An in-process broker.

Every transport built from one broker shares its traffic, so a message one publishes reaches the others that subscribed to the topic.

def rung(self, /):

Creates a link to this broker as a transport, for composing into a ladder or a wrapper.

reachable

Whether the broker is in reach. Set it to False to put every link on it out of range at once, links a ladder owns included: they fail to connect, send, or subscribe until it is True again, keeping their connections and filters through the outage.

class LoopbackTransport:

One in-process link to a broker.

def connect(self, /):

Marks this link connected so it will carry traffic.

def send(self, /, topic, payload):

Publishes a payload to a topic on the broker.

def subscribe(self, /, topic):

Subscribes this link to a topic.

def recv(self, /):

Waits for the next message on a subscribed topic, or None once closed.

def is_connected(self, /):

Whether this link is connected.

def disconnect(self, /):

Marks this link disconnected, so sends over it fail.

class LoraBeacon:

The Class B beacon settings of a plan.

ping_slot_frequency_hz

The default ping-slot frequency, in hertz.

frequency_hz

The frequency the beacon is broadcast on, in hertz.

data_rate

The data rate the beacon is broadcast at.

class LoraChannelBlock:

A run of evenly spaced channels.

count

How many channels the block holds.

min_data_rate

The slowest data rate the block allows.

max_data_rate

The fastest data rate the block allows.

step_hz

The spacing between channels in hertz.

start_hz

The first channel's center frequency in hertz.

class LoraDataRate:

One data rate: what a number on the wire means for the radio.

Only the attributes belonging to kind are set; the rest are None.

def lora(spreading_factor, bandwidth_hz, bitrate_bps):

Describes a rate carried by LoRa modulation.

def fsk(bitrate_bps):

Describes a rate carried by frequency-shift keying.

def lr_fhss( coding_rate_numerator, coding_rate_denominator, bandwidth_hz, bitrate_bps):

Describes a rate carried by long-range frequency-hopping spread spectrum.

def reserved():

Describes a data-rate number the region reserves, which carries nothing.

coding_rate_numerator

The coding-rate numerator, for an LR-FHSS rate.

bandwidth_hz

The channel bandwidth in hertz, for a LoRa or LR-FHSS rate.

bitrate_bps

The payload bitrate in bits per second.

kind

How this rate is carried: lora, fsk, lr_fhss, or reserved.

spreading_factor

The spreading factor, for a LoRa rate.

coding_rate_denominator

The coding-rate denominator, for an LR-FHSS rate.

class LoraJoinPlan:

A run of join channels that puts a device on a plan.

accept_step_hz

How far the accept frequency moves for each next channel, in hertz.

channels

The join channels and the data rates a request may use on them.

accept_start_hz

Where the accept answering the first channel arrives, in hertz.

rx2_start_hz

The second receive window's frequency after joining on the first channel, in hertz.

rx2_step_hz

How far that frequency moves for each next channel, in hertz.

plan

The CN470-510 plan a join on these channels selects, as ChannelPlan.for_cn470 takes it.

class LoraJoinPlanPlace:

The run of join channels one join channel belongs to.

rx2_hz

Where the second receive window listens once joined on it, in hertz.

accept_hz

Where the join accept for that channel arrives, in hertz.

offset

The channel's place within the run.

index

The run's position in join_plans().

class LoraMaskControl:

What one ChMaskCntl value of a LinkADRReq does.

Only the attributes belonging to kind are set; the rest are None.

def one_group(group):

The mask sets one group of sixteen channels.

def banks():

The ten low bits of the mask switch banks of eight channels.

def paired_banks():

The eight low bits switch banks of eight with their 500 kHz channel, and the ninth the 500 kHz channels past them.

def all_channels(on, then_group=None):

Every channel turns on or off, then the mask sets a group if one is given.

def reserved():

The value is reserved.

kind

What the value does: group, banks, paired_banks, all, or reserved.

group

For group, the group of sixteen channels the mask sets.

on

For all, whether every channel turns on.

then_group

For all, the group the mask then sets, if any.

class LoraMaxPayload:

What one data rate may carry in a single frame.

application

The largest application payload, in bytes.

mac_payload

The largest MAC payload, frame options included, in bytes.

class LoraPlanInfo:

The scalar facts of a plan, read in one call.

sub_band_count

How many sub-bands the plan defines.

join_channel_block_count

How many join channel blocks the plan defines.

has_dwell_limited_rx1

Whether the plan publishes a second RX1 mapping for a dwell-limited downlink.

default_channel_block_count

How many default channel blocks the plan defines.

max_tx_power_index

The highest transmit-power index the plan defines.

default_max_eirp_dbm

The power ceiling assumed when no sub-band says otherwise, in dBm.

rx2_frequency_hz

The frequency the second receive window listens on, in hertz.

default_channel_count

How many channels the plan starts a device with.

has_dwell_time_limit

Whether the plan limits how long one transmission may hold a channel.

has_dwell_limited_payloads

Whether the plan publishes a payload table for a dwell-limited device.

max_rx1_data_rate_offset

The highest RX1 data-rate offset the plan allows.

rx2_data_rate

The data rate the second receive window listens at.

beacon

The Class B beacon settings.

name

The specification's name for the band, such as EU863-870.

tx_power_step_db

The step between transmit-power settings, in dB.

class LoraPlanRules:

How a plan defines and uses its channels.

power_reference

What the transmit power indexes count down from: eirp or conducted.

channel_list

For a dynamic plan, the numbering a type 1 channel list is read against: mhz800, mhz900, or None.

tx_param_setup

Whether devices on the plan answer TXParamSetupReq.

join_plan_count

How many runs of join channels select a plan, which only the published CN470-510 plans carry.

kind

dynamic if the network creates channels, fixed if it only switches numbered ones.

join_sequence

The order a device tries the join channels in: random or octet_passes.

gain_allowance_db

For a conducted ceiling, the antenna gain it already allows for, in dB.

class LoraRadio:

A LoRa radio opened on a Linux board or wired to a simulated chip.

def open_sx126x( spi, gpio_chip, busy_line, reset_line, amplifier, *, spi_hz=None, tcxo_volts=None, tcxo_settle_us=None, dio2_rf_switch=False, dc_dc=False, llcc68=False):

Opens an SX1261, SX1262, SX1268, or LLCC68 module and resets it, which takes a few tens of milliseconds.

Raises PamojaError when the platform is not Linux, a device cannot be opened, or no chip answers, and ValueError for an amplifier name or a TCXO voltage the chip has no setting for.

def open_sx127x(spi, gpio_chip, reset_line, output, *, spi_hz=None, tcxo=False):

Opens an SX1276, SX1277, SX1278, or SX1279 module, such as an RFM95W, and resets it into LoRa mode.

Raises PamojaError when the platform is not Linux, a device cannot be opened, or no chip answers, and ValueError for an amplifier output name the chip has no setting for.

def configure( self, /, frequency_hz, link, output_dbm, *, sync_word=None, band_low_hz=None, band_high_hz=None, invert_iq_transmit=False, invert_iq_receive=False):

Tunes the radio to a carrier, a link, and an output power.

The sync word is one byte, 0x34 for a public network such as LoRaWAN and 0x12, the default, for a private one. An SX126x calibrates its receiver for the carrier alone unless a band is given.

def transmit(self, /, payload):

Sends one frame and returns its airtime in microseconds once it has left.

def receive(self, /, timeout_us):

Listens for one frame for up to a timeout in microseconds.

def listen(self, /):

Starts listening, frame after frame, until another call changes the mode.

def take_frame(self, /):

Takes the frame a listening radio has received, or None when nothing has arrived.

def detect(self, /, symbols):

Listens a few symbols for a LoRa preamble and returns whether one is there, as a relay's scan does, leaving the chip in standby. An SX126x listens over 1, 2, 4, 8, or 16 symbols, rounded down to one of them, and an SX127x over one.

def standby(self, /):

Puts the radio in standby, which stops a transmission or a reception.

def sleep(self, /):

Puts the radio to sleep until the next call wakes it. An SX126x is configured again before its next frame; an SX127x keeps its registers.

def random(self, /):

Draws a random number from the noise the receiver hears, leaving the chip in standby.

Semtech's own drivers draw it the same way, and LoRaWAN 1.0.3 suggests this source for a join nonce on a device that has no other.

def read_register(self, /, address):

Reads one register: a 16-bit address on the SX126x, 0x00 to 0x7F on the SX127x.

def write_register(self, /, address, value):

Writes one register: a 16-bit address on the SX126x, 0x00 to 0x7F on the SX127x.

def close(self, /):

Closes the radio's device files, after any call in progress finishes. Calls after this raise PamojaError.

family

The family of the radio's chip: "Sx126x" or "Sx127x".

class LoraReception:

How a reception ended, with the frame and its signal levels when one arrived.

payload

The frame's payload, or None without a frame.

outcome

How it ended: "Frame", "Timeout", or "Corrupt".

snr_db

The estimated signal-to-noise ratio, in dB, or None without a frame.

signal_rssi_dbm

The estimated strength of the LoRa signal itself, in dBm, or None without a frame.

rssi_dbm

The received signal strength averaged over the frame, in dBm, or None without a frame.

class LoraRelayChannel:

A default channel of a LoRaWAN relay, TS011-1.0.1.

data_rate

The data rate of both, numbered as the plan's downlink data rates.

wor_frequency_hz

Where an end device sends its wake-on-radio frame, in hertz.

ack_frequency_hz

Where the relay acknowledges it, in hertz.

class LoraSentFrame:

A frame a simulated chip put on the air.

tuning

What the chip was tuned to when the frame went out.

payload

The frame's payload.

class LoraSubBand:

A slice of a band with its own transmit limits.

max_eirp_dbm

The power ceiling in dBm EIRP.

start_hz

The first frequency in the sub-band, in hertz.

duty_cycle_permille

The share of time a transmitter may hold the channel, in parts per thousand, so 10 is one percent and 1000 is unrestricted.

end_hz

The last frequency in the sub-band, in hertz.

class LoraTuning:

What a simulated chip is tuned to.

frequency_hz

The carrier frequency in hertz, as the chip's synthesizer steps it: within a hertz of the one asked for on an SX126x, and within 61 Hz on an SX127x.

output_dbm

The output power the amplifier was asked for, in dBm.

sync_word

The sync word byte.

class LorawanAckWindow:

When and where a relay's acknowledgment would arrive.

airtime_us

How long it lasts, in microseconds.

start_us

When it starts, in microseconds.

carrier

Where it arrives, and how fast.

class LorawanAcknowledgment:

The acknowledgment a relay answers a wake-on-radio frame with.

frame

The frame, seven bytes.

airtime_us

How long it holds the air, in microseconds.

start_us

When to start sending it, in microseconds.

carrier

Where it goes, and how fast.

output_dbm

The power to ask of the radio, conducted, in dBm.

class LorawanBackoff:

A device's count of how long the network has been silent.

A network running adaptive data rate moves a device to the fastest rate and lowest power that still reach it. Once uplinks go unanswered, this says when to ask the network to answer and which of those settings to give back, a step at a time, as LoRaWAN 1.0.3 or TS001-1.0.4 describes.

counter

How many uplinks have gone unanswered.

version

The revision whose steps this count follows, 1.0.3 or 1.0.4.

class LorawanBackoffStep:

What a back-off says to do with one uplink.

request_ack

Set the ADRACKReq bit, asking the network to answer.

restore_channels

Re-enable the default channels and set the repetition count back to one before sending. Only TS001-1.0.4 takes this step.

lower_data_rate

Step the data rate down by the region's back-off table before sending.

restore_power

Go back to the default transmit power before sending. Only TS001-1.0.4 takes this step.

class LorawanBlockMic:

The code taken over a data block as it arrives, TS004-2.0.0 section 3.3.

def update(self, /, data):

Adds a piece of the block, in order, without any padding.

def finish(self, /):

Finishes the code, returning the four bytes a session setup carries.

class LorawanCarrier:

Where a frame goes and how fast.

frequency_hz

The frequency in hertz.

data_rate

The data rate.

class LorawanCfList:

The optional channel list at the end of a join accept.

A network that wants a device on more channels than its region's defaults says so in sixteen bytes: five frequencies for a dynamic plan such as EU868, or six groups of channel mask bits for a fixed plan such as US915. The list keeps the bytes as they arrived and reads either form out of them.

def from_frequencies(frequencies_hz):

Builds a type 0 list from five frequencies in hertz, with 0 for a slot left unused.

Raises PamojaError if there are not five, or a frequency is not a whole number of hundreds of hertz from 100 MHz to just under 1.678 GHz.

def from_channel_masks(masks):

Builds a type 1 list from six mask groups, where bit n of group g enables channel g * 16 + n.

def from_bytes(data):

Keeps a channel list exactly as it arrived, whatever its type byte says.

def frequencies_hz(self, /):

The five frequencies of a type 0 list in hertz, 0 for an unused slot, or None for a list of any other type.

def channel_mask_groups(self, /):

The six mask groups of a type 1 list, or None for a list of any other type.

def enables(self, /, channel):

Whether a type 1 list enables a channel, or None for a list of any other type or a channel past the 96 the groups cover.

def enabled_channels(self, /):

The channels a type 1 list enables, lowest first, which is empty for a list of any other type.

kind

Which form the list takes: frequencies, channel_masks or reserved.

bytes

The sixteen bytes, as a join accept carries them.

type_byte

The CFListType byte the list ends with.

class LorawanChannel:

A channel a device may send on.

index

The channel's index in the device's table.

min_data_rate

The slowest data rate the channel carries.

max_data_rate

The fastest.

class LorawanClockHeard:

What a device made of a downlink on the clock port.

correction

The seconds to add to the device's clock, where an answer carried one.

resync

How many requests a resynchronization command asked for.

more_correction

Whether the correction was the largest the field carries, so another follows.

answer_due

Whether the device now owes an answer.

class LorawanClockSync:

The clock synchronization package running on a device, TS003-2.0.0.

def request(self, /, device_time, ans_required=False):

Builds the request that asks a server for a correction, section 3.2.

def heard(self, /, payload):

Reads a downlink on the clock port and acts on it.

def answer(self, /, device_time):

Writes the answer the device owes, or an empty value when it owes none.

period_s

The seconds between requests, as the server last set them.

token

The token the next request will carry.

answer_due

Whether the device owes its server an answer.

class LorawanDefragmenter:

A fragmentation session being put back together, TS004-2.0.0 appendix A.2.

The uncoded fragments go straight into the block. A coded fragment is reduced against everything already known and kept only if it says something new, so the working memory is sized by the losses rather than by the block.

def fragment(self, /, n, data):

Takes one fragment of the session, counting from one.

Returns True once the block is whole.

missing

How many uncoded fragments are still missing.

done

Whether the whole block is there.

block

The block, as far as it has been put back together, padding and all.

received

How many fragments arrived, coded, uncoded and repeated.

class LorawanDelivery:

A downlink, read and acted on.

device_time

The answer to a time request the device asked for, as whole seconds since the GPS epoch and 256ths of a second, or None.

acknowledged

Whether the network acknowledged the confirmed uplink this answered.

port

The application port the payload arrived on, or None for a frame that carried only MAC commands or nothing.

payload

The application payload, decrypted.

confirmed

Whether the network asked for this downlink to be acknowledged, which the next uplink does by itself.

more_pending

Whether the network has more waiting.

class LorawanDevice:

The root credentials over-the-air activation is built on.

def join_request(self, /, dev_nonce):

Builds the join request this device broadcasts to activate.

dev_nonce must never repeat for a device, since the network rejects a replayed one.

def accept_join(self, /, bytes, dev_nonce):

Turns the join accept a network sent into the settings it grants.

dev_nonce is the nonce the matching join request carried.

dev_eui

The 8-byte device EUI, most-significant byte first.

class LorawanDeviceError(pamoja.raw.PamojaError):

Raised when an end device cannot do what it was asked. kind names why: too_many_channels, no_credentials, not_joined, busy, nothing_pending, wait, no_channel, data_rate, payload_too_long, counter_exhausted, frame, foreign, replayed, counter_gap, refused or state. until_us, max, data_rate, state and format carry what goes with it, and are None otherwise.

class LorawanDeviceSettings:

What a device's radio can do, and how it takes part.

seed

The seed for the random choices of channel and retry delay.

max_output_dbm

The highest, conducted, in dBm.

adr

Whether the network manages the data rate and power.

version

The link layer revision, 1.0.3 or 1.0.4.

lowest_hz

The lowest frequency the radio and its front end can use, in hertz.

antenna_gain_db

The antenna gain less the cable and connector losses, in dB.

behind_repeater

Whether payloads are sized for a path through a relay.

highest_hz

The highest, in hertz.

min_output_dbm

The lowest power the radio puts out, conducted, in dBm.

regional_duty_cycle

Whether the device is held to the region's sub-band duty cycles.

class LorawanEndDevice:

A LoRaWAN Class A end device.

One exchange runs like this: join or send returns a transmission to put on the air and two receive windows timed from its end. A frame heard in either window goes to heard. If neither window held one, nothing_heard says whether to send the same frame again with repeat, or move on.

def over_the_air(plan, credentials, settings, fcnt_up=0, fcnt_down=None):

Makes a device that joins over the air.

fcnt_up and fcnt_down carry frame counters over a restart; a join starts them over. Raises PamojaError if the plan was built rather than published.

def personalized(plan, session, settings, fcnt_up=0, fcnt_down=None):

Makes a device activated by personalization, with its session provisioned.

Such a device never resets its frame counters, TS001-1.0.4 section 4.3.1.5, so one that lost power passes the counters it kept.

def join(self, /, dev_nonce, now_us):

Builds a join request, with a nonce this device has never used with its join identifier.

def send(self, /, port, payload, now_us, confirmed=False):

Builds an uplink carrying a payload on an application port, 1 to 223, or 224 for the certification test port.

def send_empty(self, /, now_us):

Builds an uplink with no payload, carrying the answers the device owes, an acknowledgment, or an ADR acknowledgment request.

def repeat(self, /, now_us):

Sends the last uplink again, the same frame on a channel chosen afresh.

def heard(self, /, frame, snr_db, window=None):

Reads a frame heard in one of the receive windows of the last transmission.

A frame that is not for this device, does not verify, or is longer than the window's data rate carries raises and leaves the transmission waiting, so the second window still opens. window is "rx1" or "rx2"; without it, a frame may be as long as the faster window allows.

def nothing_heard(self, /, now_us):

Says what comes next once both receive windows closed with nothing for the device.

def use_relay(self, /, on):

Turns relay mode on or off, TS011-1.0.1 section 10.2 and appendix 5.

From here on the decision is the caller's rather than the device's own policy, until its network takes it over with an EndDeviceConfReq or hands it back. Returns False when the network holds the decision, leaving the mode as it was.

def heard_wor_ack(self, /, frame):

Reads the acknowledgment a relay answered the last wake-on-radio frame with.

The device is now synchronized: it knows when the relay scans, so its next frames carry only as much preamble as the two clocks could have drifted apart.

def no_wor_ack(self, /, now_us):

Says what to do once the acknowledgment window closed with nothing in it: send the uplink anyway, or wake the relay again first, as the network's BackOff asks.

def set_battery(self, /, level=None, external=False):

Sets what the device reports its battery as when a network asks: a level from 1, empty, to 254, full, or None when it cannot tell. external marks a device on external power, whatever the level.

def request_device_time(self, /):

Asks the network, with the next uplink, for the time.

def channels(self, /):

The channels the device may send on.

def save(self, /, now_us):

Saves a joined device's state, to keep across a loss of power.

The bytes hold the session keys, so keep them wherever the keys would be safe.

def resume(self, /, saved, now_us):

Puts a saved state back on a device made the same way, on the clock it woke to.

transmissions

How many times each uplink goes out, as the network last set it.

rx2

Where the second receive window listens, as a frequency in hertz and a data rate.

receive_delay_us

The delay from the end of an uplink to the first receive window, in microseconds.

frequency_span

The lowest and highest frequency the device transmits or listens on, in hertz.

relaying

Whether the next uplink goes through a relay.

fcnt_down

The last downlink frame counter accepted, or None before any downlink.

fcnt_up

The next uplink frame counter.

relay_status

What the relay's last acknowledgment said about itself, or None before one arrived.

dev_addr

The address the device is on the network by, or None before joining.

relay_sync

What the device knows of when its relay listens: initialized, unsynchronized or synchronized, TS011-1.0.1 section 3.9.

relay_activation

How the device decides whether to use a relay: disabled, enabled, dynamic or device_controlled.

wor_counter

The wake-on-radio frame counter the next frame will use, TS011-1.0.1 section 5.3.2.

is_joined

Whether the device is on a network: once joined, or from the start for a personalized device.

data_rate

The data rate the next uplink goes out at, before any back-off step.

class LorawanFirmware:

The firmware management package running on a device, TS006-1.0.0.

def set_image(self, /, status, version=None):

Says what firmware upgrade image the device is holding.

def heard(self, /, payload, now_s=None):

Reads a downlink on the firmware port and writes the answers it calls for.

now_s is what the device believes the time is, in seconds since the GPS epoch; a device that does not know refuses a reboot set for a moment in time.

def rebooted(self, /):

Forgets the programmed reboot, for a device that has carried it out.

reboot_in_s

How long until it reboots, where one was set as a countdown.

image_status

What the device makes of the image it holds.

reboot_now

Whether the device was told to reboot at once.

next_version

What the device would boot into, for an image it can install.

reboot_at_s

The moment the device is to reboot, where one was set as a time.

class LorawanFragSession:

How a block is cut into fragments.

nb_frag

How many uncoded fragments the block takes.

padding

How many bytes of padding the last one carries.

class LorawanGrant:

What a network grants a device that joined.

def accept(self, /, app_key, dev_nonce):

Builds the signed join-accept to transmit.

def session(self, /, app_key, dev_nonce):

Derives the session this grant activates, the same one the device computes.

dev_addr

The address this grant assigns.

net_id

The network identifier this grant carries.

class LorawanHeader:

What a frame says about itself before any key is involved.

Nothing here is authenticated, since checking the MIC needs the session key. Treat it as a routing hint until decode has verified the frame.

dev_addr

The device address, or None for a join frame.

adr_ack_req

Whether an uplink asks the network to answer.

class_b

Whether an uplink comes from a device running Class B.

payload_len

The length of the still-encrypted payload.

fport

The port, or None for a join frame or one carrying only options.

is_data

Whether this is a data frame rather than part of a join exchange.

confirmed

Whether the frame asks to be acknowledged.

adr

Whether the frame takes part in adaptive data rate.

ack

Whether the frame acknowledges the last confirmed one.

fcnt

The low 16 bits of the frame counter, or None for a join frame.

fpending

Whether the network has more downlink data waiting.

fopts_len

How many bytes of frame options the header carries.

message_type

What kind of message the frame is.

class LorawanHeard:

What a frame heard in a receive window turned out to be.

dev_addr

The address the device is on the network by.

delivery

For a data frame, what it carried, and None for a join.

kind

joined for a join accept, data for a data frame.

class LorawanJoinAccept:

An accepted join: the network settings, and the session it grants.

def session(self, /):

The activated session this join grants, with its keys already derived.

dl_settings

The downlink settings byte, carrying the second receive window data rate and the first window offset.

rx_delay

The delay byte before the first receive window, as it arrived.

rx2_data_rate

The data rate the second receive window listens at.

rx1_dr_offset

How far below the uplink's data rate the first receive window listens, the RX1DROffset of the downlink settings.

net_id

The identifier of the network that accepted the join.

cflist

The channel list the accept carried, or None when it carried none.

dev_addr

The device address the network assigned.

receive_delay_us

The delay from the end of an uplink to the first receive window, in microseconds, where a delay byte of zero means one second.

class LorawanJoinRequest:

A join-request a device broadcast, with its integrity already verified.

app_eui

The application identifier, most-significant byte first.

dev_eui

The device identifier, most-significant byte first.

dev_nonce

The nonce the request carried, which a network must not accept twice.

class LorawanListen:

When and where a relay listens for the uplink a wake-on-radio frame announced.

max_len

The longest frame the relay forwards; stop receiving anything longer.

carrier

Where it arrives, and how fast.

start_us

When the uplink starts, in microseconds.

class LorawanMacCommand:

One of the commands a network and a device configure each other with.

kind names the command and cid is the identifier it travels under. Only the fields that command carries are set; the rest are None. The same identifier means a different command in each direction, so direction decides which one this is.

def encode(self, /):

Writes this command out.

Returns

The bytes it goes out as.

Errors

When the identifier and the direction name no command, or a field will not fit what carries it.

data_rate_range_ok

Whether the device can run that range of rates.

rssi_dbm

The signal strength of a WOR frame a relay could not verify, in dBm.

second_channel_index

Whether a relay configuration sets a second channel, 1 for yes.

cad_periodicity_ack

Whether the scan period was valid.

margin

How far above the floor a link check arrived, in dB.

gateways

How many gateways heard it.

rx1_offset_ack

Whether the window offset was in range.

channel_ack

Whether the frequency was usable.

battery

A device battery level: 0 on external power, 255 when it cannot tell.

default_channel_index

Which of the region's relay channels is a relay's default one.

direction

Which way it travels: Uplink or Downlink.

rx2_data_rate

The rate of the second receive window.

power_ack

Whether the power was set.

default_channel_index_ack

Whether the default channel was valid.

bucket_size

Its bucket size multiplier, as TS011-1.0.1 table 55 codes it.

kind

Which command this is, as a name.

eui_len_ack

Whether its length was valid.

join_request_reload_rate

Join requests a relay forwards an hour, 127 for no limit.

overall_reload_rate

Every message a relay sends an hour.

max_duty_cycle

The share of the air a device is held to, as one over two to this.

max_eirp

The coded transmit power ceiling a region imposes.

data_rate_ack

Whether the data rate was set.

mask_control

Which block of sixteen channels that mask applies to.

frequency_ok

Whether its radio can reach that frequency.

second_channel_data_rate

The second channel's data rate; its frequency is the frequency field.

root_wor_s_key

An end device's root relay session key.

action_ack

Whether its action was valid.

index

Which channel a channel command names.

notify_bucket_size

The notification bucket size multiplier.

rx2_data_rate_ack

Whether the window rate was known.

fraction

The fraction of that second, in steps of one part in 256.

cad_periodicity

How often a relay scans, as TS011-1.0.1 table 18 codes it.

cid

The identifier it travels under.

max_data_rate

The fastest rate allowed on it.

index_ack

Whether a trusted list entry was in use.

reset_limit_counters

What a forwarding limit command does to a relay's token counters, as table 63 codes it.

combined_rules_ack

Whether a join filter rule was one to create, change or remove.

transmissions

How many times to send an unconfirmed uplink.

dev_addr

An end device address a relay command names.

data_rate

The data rate a network asks a device to use.

second_channel_ack_offset_ack

Whether its acknowledgment offset was valid.

second_channel_data_rate_ack

Whether the second channel's data rate was valid.

back_off

How many WOR frames without an acknowledgment before an uplink goes anyway.

reload_rate

Tokens a trusted end device earns an hour, 63 for no limit.

frequency_hz

A frequency in hertz, for the receive window and the channel commands.

eui_len

How many leading bytes of JoinEUI and DevEUI a join filter rule matches.

delay

How long a device waits before its first receive window, as the command codes it.

second_channel_ack_offset

How far above its frequency the second channel is acknowledged, as table 35 codes it.

overall_bucket_size

The overall bucket size multiplier.

rx1_offset

How far the first receive window sits below the uplink rate.

snr_db

Its signal-to-noise ratio, in dB.

second_channel_frequency_ack

Whether its frequency was valid.

eui

Those bytes, most significant first, with the rest zero.

notify_reload_rate

New end device notifications a relay sends an hour.

tx_power

The transmit power it may use, as a ceiling.

channel_mask_ack

Whether the channel mask was usable.

seconds

Seconds since the GPS epoch.

snr_margin

The signal-to-noise ratio of the last request, in dB.

channel_mask

Which channels may carry an uplink.

action

What a join filter rule does, or whether a trusted end device is read or removed.

second_channel_index_ack

Whether the second channel index was valid.

enabled

Whether a relay runs.

min_data_rate

The slowest rate allowed on it.

relay_mode

How an end device uses a relay, as TS011-1.0.1 table 40 codes it.

wfcnt

A wake-on-radio frame counter.

join_request_bucket_size

The join request bucket size multiplier.

smart_enable_level

How many unanswered uplinks turn relaying on, as table 41 codes it.

class LorawanNext:

What to do once both receive windows closed with nothing for the device.

kind

repeat, done, unacknowledged or join_again.

not_before_us

For a repeat or another join, the earliest time to send, in microseconds.

class LorawanPackageCommand:

One command of an application layer package, whichever package it belongs to.

port says which package and kind names the command within it; together they decide which of the other fields carry anything. The rest are None.

def encode(self, /):

Writes this command out, which is what lorawan_package_encode() does.

no_valid_image

Whether a device holds no valid image.

missing

How many uncoded fragments are still missing.

version

The package version it implements.

time_to_start

How many seconds until a window opens.

reboot

The moment or the delay a reboot is set for.

kind

Which command this is, as a name.

freq_error

Whether the frequency named is not one it can use.

time_out

How long it lasts at most, coded.

mc_group_bit_mask

Which multicast groups may feed it, a bit for each.

hardware

The hardware it runs on.

period

The coded period between clock requests.

nb_total_groups

How many groups a device holds in all.

received

How many fragments arrived, coded, uncoded and repeated.

fragment_n

Which fragment of a session a data fragment carries, counting from one.

mc_group_id

Which multicast group, 0 to 3.

no_session

Whether the session or group named does not exist on the device.

mc_addr

The address a group answers to.

mic_error

Whether the block's code did not check out.

id_error

Whether a device holds no group by the identifier named.

time_correction

The seconds to add to a device's clock.

not_supported

Whether a device manages its own clock periodicity.

ack_reception

Whether a device reports the block once it has it.

group_mask

Which groups a status request or answer covers, a bit for each.

image_status

What a device makes of the upgrade image it holds.

port

Which package this command belongs to, as its port.

device_time

A device's own clock, in seconds since the GPS epoch.

unsupported_algorithm

Whether the setup named an algorithm the device does not run.

token

The token that pairs a clock answer with its request.

all_participants

Whether every device answers a status request.

session_time

When a multicast window opens, in seconds since the GPS epoch.

ans_required

Whether a clock request must be answered.

firmware

The firmware a device reports running.

data_rate

The data rate it listens at.

mic

The code over the block a device checks once it has it all.

session_cnt

The session counter, which must rise for each new block.

unsupported_index

Whether the setup named an index the device does not keep.

package

The package identifier a version answer carries.

wrong_descriptor

Whether the descriptor is not one the device accepts.

min_mc_fcnt

The first frame counter a device accepts from a group.

invalid_version

Whether the version named is not the one held.

mc_key_encrypted

A group's key, wrapped under the device's key encryption key.

periodicity

How often a device opens a ping slot inside a Class B window.

memory_error

Whether a session ran out of memory to defragment with.

frag_algo

Which fragmentation algorithm to run.

block_ack_delay

The coded spread of the delay before a device answers.

delete_version

The version a delete command names.

next_version

The version it would run once that image is installed.

frag_index

Which fragmentation session, 0 to 3.

session_replay

Whether the session counter repeats one already used.

dl_frequency_hz

Where a group listens, in hertz.

dr_error

Whether the data rate named is not one the device has.

data

The bytes a data fragment carries.

nb_frag

How many uncoded fragments a block was cut into.

max_mc_fcnt

The last one, which ends the group's life.

start_missed

Whether the window was to start at a time already past.

frag_size

How many bytes each fragment carries.

transmissions

How many requests a resynchronization command asks for.

padding

How many bytes of padding the last fragment carries.

descriptor

The four bytes a server describes a block with.

class LorawanRelay:

A LoRaWAN relay: an end device that also listens for the devices around it.

One turn runs like this: next_scan says when and where to listen, a wake-on-radio frame heard there goes to heard_wor, the uplink it announced to heard_uplink, and forward wraps that in one of the relay's own uplinks on port 226. What the relay's own receive windows hear goes to heard_in, which turns a downlink meant for an end device into one to send in that device's relay window.

A call that cannot be done raises LorawanRelayError, or LorawanDeviceError when it is the relay's own device that refused.

def personalized(plan, session, settings, xtal_accuracy='ppm40', cad_to_rx='symbols8'):

Makes a relay whose own device is activated by personalization.

xtal_accuracy and cad_to_rx describe the relay's own hardware, and travel in every acknowledgment it sends, so the devices around it know how much preamble to send.

def over_the_air( plan, credentials, settings, xtal_accuracy='ppm40', cad_to_rx='symbols8'):

Makes a relay whose own device joins over the air.

def start( self, /, cad_periodicity='ms1000', default_channel_index=0, second_channel=None):

Starts scanning, or changes what a running relay scans from its next scan on.

default_channel_index picks one of the region's wake-on-radio channels, and second_channel is one a network configured.

def stop(self, /):

Stops scanning. A forwarded uplink already waiting still goes out.

def trust( self, /, index, dev_addr, root_wor_s_key, next_wfcnt=0, reload_rate=63, bucket_size=0):

Trusts an end device, as an UpdateUplinkListReq with the same fields does.

index is the entry, 0 to 15. reload_rate is how many of the device's uplinks are forwarded an hour, 63 for no limit, and bucket_size the coded multiplier of TS011-1.0.1 table 55.

def next_scan(self, /, now_us):

Says when and where to scan next, or None while the relay is stopped.

def heard_wor(self, /, scan, frame, rssi_dbm, snr_db, ended_us):

Reads a wake-on-radio frame a scan heard, ended_us being when the frame ended.

def forward(self, /, now_us):

Sends the uplink the relay is holding, in one of its own on port 226.

def heard_in(self, /, window, frame, snr_db):

Reads a frame the relay's own device heard, acting on the relay commands in it.

window is "rx1", "rx2" or "rxr".

def nothing_heard(self, /, now_us):

Says what comes next once the relay's own windows closed with nothing in them.

def join(self, /, dev_nonce, now_us):

Makes the relay's own join request.

def send(self, /, port, payload, now_us, confirmed=False):

Sends one of the relay's own uplinks, which also carries what it owes its network.

def send_empty(self, /, now_us):

Sends an uplink with no payload, carrying whatever the relay owes its network.

running

Whether the relay is scanning.

dev_addr

The address the relay's own device is on the network by, or None before joining.

joined

Whether the relay's own device is on a network.

data_rate

The data rate the relay forwards at, which its acknowledgments report.

forward_due

When the forwarded uplink waiting to go out is due, or None with nothing waiting.

class LorawanRelayError(pamoja.raw.PamojaError):

Raised when a relay cannot do what it was asked. kind names why: stopped, busy, not_listening, nothing_held, nothing_awaited, frame, carrier, limited, filtered, foreign or configuration. What the relay's own device refused raises LorawanDeviceError instead.

class LorawanRelayExchange:

The wake-on-radio exchange an uplink under a relay goes out behind, TS011-1.0.1 section 5.

ack

Where the relay's acknowledgment would arrive, or None ahead of a join request, which no relay acknowledges.

wake_up

The frame that wakes the relay.

rxr

The relay window, timed from the end of the uplink like the other two.

class LorawanRelayHeard:

What a frame a relay's own device heard turned out to be.

heard

What the relay's own device made of the frame.

reason

Why a downlink could not be passed on, for undeliverable.

kind

device, downlink or undeliverable.

class LorawanRelayStatus:

What a relay's acknowledgment said about itself, TS011-1.0.1 table 14.

relay_data_rate

The data rate it forwards at, which bounds what the device may send.

forward

Whether it will forward: available, retry_in_30_minutes, retry_in_60_minutes or disabled.

cad_periodicity

How often it scans.

xtal_accuracy

How accurate its crystal is.

cad_to_rx

How long it takes to start receiving.

class LorawanRxData:

A decoded data frame, with its payload decrypted.

fcnt

The low 16 bits of the frame counter.

confirmed

Whether the frame asks to be acknowledged.

fpending

Whether the network has more downlink data waiting.

class_b

Whether an uplink comes from a device running Class B.

fport

The port the frame was sent on, or None when it carries only options.

adr

Whether the frame takes part in adaptive data rate.

payload

The decrypted application payload.

fopts

The MAC commands the header carried.

dev_addr

The device address the frame carries.

direction

The direction the frame traveled: Uplink or Downlink.

ack

Whether the frame acknowledges the last confirmed one.

adr_ack_req

Whether an uplink asks the network to answer.

class LorawanScan:

A scan for wake-on-radio frames, due next.

carrier

Where to listen, and how fast.

start_us

When to start detecting, in microseconds.

preamble_symbols

The longest preamble an end device sends on the channel, in symbols.

channel

Which channel: default or second.

class LorawanSession:

An activated LoRaWAN session: a device address and its two session keys.

def root_wor_s_key(self, /):

The root relay session key a network sends a relay for this device, TS011-1.0.1 section 4.4.

def wor_keys(self, /):

The keys this device's wake-on-radio frames are protected with, section 4.5.

def decode(self, /, bytes, fcnt):

Verifies a received frame, then decrypts it.

fcnt is the full 32-bit counter expected for this frame; its low 16 bits must match the counter the frame carries.

dev_addr

The device address this session is bound to.

class LorawanStateSync:

What a relay tells an end device about itself in a WOR ACK, TS011-1.0.1 table 14.

cad_to_rx

How long the relay takes to start receiving: symbols2 to symbols8.

xtal_accuracy

How accurate its crystal is: ppm10 to ppm40.

cad_periodicity

How often it scans: ms1000, ms500, ms250, ms100, ms50 or ms20.

t_offset_ms

Milliseconds from the start of the scan to the end of the WOR preamble.

relay_data_rate

The data rate it forwards at.

forward

Whether it forwards: available, retry_in_30_minutes, retry_in_60_minutes or disabled.

class LorawanSynchronization:

What an end device knows of a relay's scans once a WOR ACK has arrived.

cad_to_rx

How long it takes to start receiving.

cad_periodicity

How often it scans.

reference_us

When the relay scanned, in the device's microseconds.

relay_xtal

How accurate its crystal is.

class LorawanTransmission:

A frame to put on the air, and where to listen afterward.

rx2

The second receive window, which opens only if nothing for this device arrived in the first.

carries_payload

Whether the application payload went out in this frame. When the answers the device owed left no room, it did not, and has to be sent again.

relay

The wake-on-radio exchange this frame goes out behind, and None for a frame that goes straight to a gateway.

airtime_us

How long the frame holds the air, in microseconds.

rx1

The first receive window.

frequency_hz

The carrier, in hertz.

frame

The frame.

data_rate

The data rate, as the region numbers them.

output_dbm

The power to ask of the radio, conducted, in dBm.

class LorawanUplinkMetadata:

What a relay heard of an uplink it forwards.

snr_db

Its signal-to-noise ratio in dB, carried from -20 to 11.

wor_channel

The channel the WOR frame came in on: default or second.

data_rate

The data rate it arrived at.

rssi_dbm

The uplink's signal strength in dBm, carried from -142 to -15.

class LorawanWake:

What a wake-on-radio frame led a relay to do.

acknowledgment

The acknowledgment to send, where there is one.

forward

Whether the relay forwards the uplink, which the acknowledgment reports.

kind

join_request, uplink or notified.

dev_addr

The device, for an uplink or a notification, and None for a join request.

listen

Where and when to listen for the uplink, where the relay will.

wfcnt

The wake-on-radio frame counter it carried, for an uplink.

class LorawanWakeUp:

The frame that wakes a relay, and where it goes.

carrier

Where it goes, and how fast.

start_us

When to start sending it, in microseconds.

output_dbm

The power to ask of the radio, conducted, in dBm.

frame

The frame: five bytes ahead of a join request, fifteen ahead of an uplink.

airtime_us

How long it holds the air, in microseconds.

class LorawanWindow:

When and where to listen for a downlink.

frequency_hz

The carrier, in hertz.

delay_us

How long after the end of the transmission the window opens, in microseconds.

data_rate

The downlink data rate, as the region numbers them.

class LorawanWor:

A wake-on-radio frame, as a relay reads it.

kind

join_request or uplink.

dev_addr

The address an uplink WOR names.

wfcnt

The low sixteen bits of its frame counter.

class LorawanWorKeys:

The integrity and encryption keys of one end device's wake-on-radio frames, TS011-1.0.1.

integrity

WorSIntKey, 16 bytes.

encryption

WorSEncKey, 16 bytes.

class LorawanWorNext:

What an end device does once its wake-on-radio frame went unanswered.

wake_up

The next exchange, when the relay is woken again first, and None otherwise.

class LorawanWorSlot:

When a synchronized end device's next WOR frame goes out.

start_us

When to start sending, in microseconds.

preamble_symbols

The preamble length in symbols.

class Manifest:

What a release says about itself, and what a device checks it against.

size

The payload length in bytes, known before a single byte is accepted.

format

How the payload is encoded, currently only the raw format.

structure_version

Which iteration of the manifest format this is.

sequence

Rises with every release, which is what stops an older image being replayed at a device.

vendor_id

Who built the image, as 16 bytes.

digest

The SHA-256 of the payload, which every other guarantee rests on.

class_id

Which kind of device it is for, as 16 bytes.

expires

When this release stops being offered, in seconds since the Unix epoch, or 0 to never expire.

storage

Which slot the payload belongs in.

class MavlinkFieldInfo:

One field of a message shape.

array_len

The element count for an array field, or 0 for a scalar.

field_type

The field's type, one of the FieldType values.

name

The field name as the dialect writes it, such as custom_mode.

offset

The field's byte offset within the payload.

extension

Whether this is a MAVLink 2 extension field.

type_name

The field's type name as the dialect writes it, such as uint32_t.

class MavlinkFrame:

One MAVLink frame, assembled or received.

def encode_v2(header, msgid, payload, crc_extra):

Assembles a v2 frame carrying a message.

This is the current wire format and what a modern autopilot expects.

def encode_v1(header, msgid, payload, crc_extra):

Assembles a v1 frame, for a peer that predates MAVLink 2.

A v1 frame only carries message ids below 256.

def parse(data, crc_extra):

Parses one frame, checking it against a known CRC_EXTRA.

Raises PamojaError if the bytes are not a whole frame or the checksum does not match, which is what rejects a frame mangled in transit.

def parse_known(data, dialect=None):

Parses one frame, looking its CRC_EXTRA up as it goes.

This is what a receiver holding many message types uses: the id comes out of the frame, and the seed comes from the dialect or the common registry.

def raw(header, msgid, crc_extra, payload):

Assembles a v2 frame carrying a message this build does not type.

The escape hatch a private dialect needs: supply the id, the payload, and the seed, and the frame is built and checked like any other.

incompat_flags

The incompatibility flags a v2 frame declares.

signature

The signature block, or None when the frame is not signed.

signed

Whether the frame carries a signature.

This says only that the frame was signed, not that the signature is good; a MavlinkVerifier decides that.

header

The addressing fields the frame carries.

version

Which wire format this frame uses: 1 or 2.

message_id

The id of the message the frame carries.

payload

The message payload.

A v2 frame drops trailing zero bytes, so a payload can arrive shorter than the message's full length; a decoder zero-extends it.

bytes

The whole frame, ready to put on the wire.

class MavlinkHeader:

The addressing fields a sender stamps on every frame.

sequence

The sender's sequence number, which wraps at 256.

system_id

The sending system's id.

component_id

The sending component's id.

class MavlinkMessage:

A message read and written by field name against a schema.

def empty(schema):

Creates a message with every field zero.

Raises PamojaError if the shape does not fit a MAVLink payload.

def decode(schema, payload):

Reads a message out of a frame payload.

A payload shorter than the shape is zero-extended, as MAVLink 2 truncation requires, so a frame from a peer that trimmed trailing zeros or predates an extension field still decodes. Raises PamojaError if the payload is longer than the shape describes.

def to_frame(self, /, header):

Builds a v2 frame carrying this message.

Raises PamojaError if the message does not fit a frame.

def get(self, /, field, index=0):

Reads a field as a number.

Every field reads this way. An integer field wider than 53 bits can exceed what a float holds exactly; read those with get_int where the exact value matters.

def get_int(self, /, field, index=0):

Reads an integer field exactly, whatever its width or sign.

def set(self, /, field, value, index=0):

Writes a number into a field, converting it to the field's type.

A value bound for an integer field must be a whole number within that field's range, so a fractional or oversized value is refused rather than silently truncated.

def set_int(self, /, field, value, index=0):

Writes an integer into a field exactly, whatever its width or sign.

def get_bytes(self, /, field):

Copies the raw bytes of a byte-wide array field out, padding included.

def set_bytes(self, /, field, data):

Writes the raw bytes of a byte-wide array field, zero-padding the rest.

def get_text(self, /, field):

Reads a char array as text, stopping at the padding.

def set_text(self, /, field, text):

Writes text into a char array, padding the rest with zeros.

name

The name of the message this carries.

message_id

The id of the message this carries.

payload

The message's bytes as they go on the wire.

class MavlinkParser:

A streaming frame parser, and the frames it has completed.

def push(self, /, data, dialect=None):

Feeds bytes off a link and returns the frames that completed.

Whatever a serial port or socket delivers can be pushed as it arrives, however it is split. Noise between frames is skipped rather than reported, which is what lets a parser join a stream already in progress.

def feed(self, /, data, dialect=None):

Feeds bytes and queues what completed, for a caller that drains later.

def next_frame(self, /):

Takes the next queued frame, or None when the parser needs more bytes.

pending

How many completed frames are waiting to be taken.

class MavlinkSigner:

A signing key and the monotonic timestamp that goes with it.

def sign(self, /, header, msgid, payload, crc_extra):

Signs a message into a v2 frame.

Each call advances the timestamp, which is what makes a replayed frame detectable.

class MavlinkVerifier:

A signing key and the timestamps it has already accepted.

def set_window(self, /, window):

Sets how far a timestamp may run ahead of the last one accepted.

A wider window tolerates a noisier link; a narrower one narrows the chance of a replay landing inside it.

def verify(self, /, frame):

Checks a frame's signature and its place in the timestamp sequence.

Raises PamojaError when the frame is unsigned, the signature does not match the key, or the timestamp has been seen before.

class Mecanum:

A four-wheel mecanum base, which drives, strafes, and turns at once.

def wheel_speeds(self, /, twist):

Returns the four wheel speeds for a body twist.

def body_motion(self, /, wheels):

Returns the body twist measured wheel speeds make.

class Median:

Rejects a single wild reading, where an average would let it pull the answer.

def update(self, /, reading):

Folds a reading in and returns the median of the window.

value

The current median, or None before the first reading.

capacity

How many readings the filter keeps.

class MeshFrame:

A mesh packet: its addressing, its payload, and the bytes to transmit.

id

The sequence number identifying this packet from this source.

payload

The payload the frame carries.

version

The protocol version the frame declares.

src

The address of the node the frame came from.

dst

The address the frame is addressed to.

bytes

The whole frame as it goes on the air.

broadcast

Whether the frame is addressed to every node.

hop_limit

How many further relays the frame may take.

class Message:

A message that arrived on a subscribed topic.

CoAP and the loopback broker both hand back a topic and a payload, so one class serves them rather than a near-identical type per transport.

topic

The topic it was published to.

payload

The raw payload bytes.

text

The payload as text: words, or a number written out.

Raises ValueError if the payload is not UTF-8 text.

number

The payload as a number written out as text, such as 21.5.

Raises ValueError if the payload is not text or the text is not a number.

class MessageSchema:

The shape of one message: its id, name, seed, and fields.

def for_id(msgid):

Returns the shape of a message the engine types, by id.

Raises ValueError if this build does not type that id, which is what a builder is for.

def for_name(name):

Returns the shape of a message the engine types, by name.

Raises ValueError if this build does not type that name.

name

The name of the message this schema describes.

crc_extra

The CRC_EXTRA seed a frame carrying this message folds into its checksum.

fields

The fields in wire order: the base fields largest first, then extensions.

id

The id of the message this schema describes.

wire_len

The length of the message on the wire, in bytes, extensions included.

class MessageSchemaBuilder:

Describes a message this build does not type, one field at a time.

Fields are added in the order the message definition lists them; building puts them in wire order and derives the CRC_EXTRA seed from the result.

def field(self, /, name, field_type, array_len=0):

Adds a base field, in the order the definition declares it.

The type is either a FieldType value or the name a dialect writes, such as "uint32_t". Raises ValueError if it is neither, or if the shape has already been built.

def extension(self, /, name, field_type, array_len=0):

Adds a MAVLink 2 extension field, in the order the definition declares it.

Extensions keep their declared order, stay out of the CRC_EXTRA seed, and read as zero from a frame sent by a peer that predates them.

def build(self, /):

Puts the declared fields in wire order and finishes the shape.

Raises PamojaError if two fields share a name or the fields do not fit a MAVLink payload, and ValueError if the shape has already been built.

class MissionReceiver:

Requests a plan's items in order and collects them, ending with an acknowledgment.

def request_list(self, /, header):

Builds the MISSION_REQUEST_LIST frame that starts a download.

def on_frame(self, /, frame, header):

Handles an incoming frame, if it is one this transfer is waiting for.

A MISSION_COUNT opens the transfer and a MISSION_ITEM_INT advances it. Returns the step taken, or None if the frame carries a message this transfer does not handle.

complete

Whether every item has been received and the acknowledgment produced.

expected

The next sequence number the receiver expects.

class MissionSender:

Holds a plan and answers a receiver's requests for its items.

def add_item(self, /, item):

Appends an item to the plan, from a MISSION_ITEM_INT payload.

The sender stamps the sequence number, target ids, and mission type onto each item as it is handed out, so the item need only carry its content: command, frame, position, and parameters. Build one by field name with the MISSION_ITEM_INT schema and pass its payload.

def count(self, /, header):

Builds the MISSION_COUNT frame that opens an upload.

def on_frame(self, /, frame, header):

Handles an incoming frame, if it is one this transfer answers.

A MISSION_REQUEST_LIST is answered with the count, a MISSION_REQUEST_INT (or the older MISSION_REQUEST) with the item asked for, and a request past the end of the plan with a MISSION_ACK reporting an invalid sequence. A MISSION_ACK from the receiver ends the transfer. Returns None for a message this transfer does not handle.

class ModbusClient:

A Modbus RTU client on a serial line: the gateway that sends each request and waits for its reply, holding each transaction to the Modbus over Serial Line specification.

Each call releases the interpreter while the line is busy, and a failure raises ModbusClientError.

def frame_gap_nanos(baud, parity, stop_bits):

The silence that separates two frames, in nanoseconds, for a speed, a parity name, and a stop bit count: 3.5 characters, and a fixed 1750 microseconds above 19200 baud.

def set_response_timeout_micros(self, /, micros):

Sets how long the client waits for a whole reply, in microseconds.

def set_turnaround_micros(self, /, micros):

Sets how long the client leaves the line quiet after a broadcast, in microseconds.

def read_coils(self, /, unit, start, quantity):

Reads coils, function 0x01.

def read_discrete_inputs(self, /, unit, start, quantity):

Reads discrete inputs, function 0x02.

def read_holding_registers(self, /, unit, start, quantity):

Reads holding registers, function 0x03.

def read_input_registers(self, /, unit, start, quantity):

Reads input registers, function 0x04.

def write_single_coil(self, /, unit, address, on):

Writes one coil, function 0x05; unit 0 broadcasts it to every device.

def write_single_register(self, /, unit, address, value):

Writes one holding register, function 0x06; unit 0 broadcasts it to every device.

def write_multiple_coils(self, /, unit, start, values):

Writes a run of coils, function 0x0F; unit 0 broadcasts them to every device.

def write_multiple_registers(self, /, unit, start, values):

Writes a run of holding registers, function 0x10; unit 0 broadcasts them to every device.

turnaround_micros

How long the client leaves the line quiet after a broadcast, in microseconds.

response_timeout_micros

How long the client waits for a whole reply, in microseconds.

class ModbusClientError(pamoja.raw.PamojaError):

Raised when a Modbus transaction fails. kind names why: request, broadcast_read, port, timeout, frame, wrong_unit, wrong_function, mismatch, or exception. unit is the unit asked, and function_code, found, exception, and received carry what goes with the kind, and are None otherwise.

class ModbusFrame:

A received Modbus RTU frame whose CRC has been verified.

def registers(self, /):

Reads the 16-bit registers out of a read-registers reply.

def coils(self, /, count):

Reads count coils or discrete inputs out of a read-bits reply.

address

The unit (slave) address the frame is addressed to or came from.

exception

The exception code a device reported, or None when the frame is not an exception response.

function_code

The function code. An exception response carries the request's code with its high bit set, as it appeared on the wire.

pdu

The protocol data unit: the function code and its data, without the address or the CRC.

class ModbusLine:

Several devices on one simulated line, as devices share an RS485 pair: every frame reaches all of them, the one it is addressed to answers, and each carries out a broadcast write.

def attach(self, /, server):

Puts a device on the line, which shares it.

def port(self, /, baud, parity, stop_bits):

A serial port with the line on its far end, at a speed, a parity name, and a stop bit count. Devices put on the line later are on the port too.

class ModbusServer:

A Modbus device: a unit address and the four tables it serves, coils, discrete inputs, holding registers, and input registers, each holding only the addresses it was given.

answer takes one RTU frame and returns the frame the device sends back, or None when it stays silent: the frame failed its CRC, is for another unit, or is a broadcast, whose write the device still carries out.

def set_coils(self, /, start, values):

Sets coils from an address on, adding any the device did not have.

def set_discrete_inputs(self, /, start, values):

Sets discrete inputs from an address on, adding any the device did not have.

def set_holding_registers(self, /, start, values):

Sets holding registers from an address on, adding any the device did not have.

def set_input_registers(self, /, start, values):

Sets input registers from an address on, adding any the device did not have.

def coil(self, /, address):

A coil's state, or None when the device has no coil there.

def discrete_input(self, /, address):

A discrete input's state, or None when the device has no input there.

def holding_register(self, /, address):

A holding register's value, or None when the device has no register there.

def input_register(self, /, address):

An input register's value, or None when the device has no register there.

def answer(self, /, frame):

Answers one RTU frame, as the device on the line does, or returns None when it stays silent.

served

How many requests the device has carried out, broadcasts included and refusals not.

unit

The device's unit address.

class MqttClient:

An MQTT client transport backed by the native pamoja core.

def connect(self, /):

Connects to the broker and starts the background event loop.

def publish(self, /, topic, payload, *, qos=None, retain=False):

Publishes a payload to a topic, returning once it is queued for the broker. qos is the client's unless given, and retain has the broker keep the message for clients that subscribe later; an empty retained message clears the one it holds.

def publish_confirmed(self, /, topic, payload, *, qos=None, retain=False):

Publishes a payload to a topic and returns once the broker acknowledges it: its PUBACK at "AtLeastOnce", its PUBCOMP at "ExactlyOnce", and once the connection has taken it at "AtMostOnce", where MQTT acknowledges nothing. Raises PamojaError if the connection ends first, when the message may or may not have arrived.

def subscribe(self, /, topic):

Subscribes to a topic filter.

def recv(self, /):

Awaits the next message from any subscribed topic, or None once the connection has ended. A connection that ends on its own raises PamojaError once, saying why.

def is_connected(self, /):

Reports whether the client currently holds an active connection.

def disconnect(self, /):

Closes the connection and stops the background event loop.

class MqttMessage:

A message received from a subscribed topic.

topic

The topic the message was published to.

number

The payload as a number written out as text, such as 21.5.

Raises ValueError if the payload is not text or the text is not a number.

payload

The raw payload bytes.

text

The payload as text: words, or a number written out.

Raises ValueError if the payload is not UTF-8 text.

class MqttTls:

How a connection is secured with TLS, conventionally on port 8883.

class MqttWill:

A message the broker publishes on the client's behalf if its connection ends without a disconnect: the network dropped, the power failed, or the keep-alive ran out. A client that disconnects leaves no will behind.

payload

What the will publishes.

retain

Whether the broker retains it for clients that subscribe later.

topic

The topic the broker publishes it to.

qos

The quality of service it is published at, by name.

class Odometry:

Tracks a robot's pose by adding up its motion.

def reset(self, /, pose):

Sets the estimate to a known pose.

def integrate(self, /, linear, angular, dt):

Adds a forward speed and yaw rate held for dt, and returns the new pose.

def integrate_wheels(self, /, left, right, drive):

Adds the distances two wheels rolled, through a differential drive, and returns the new pose.

def fuse_heading(self, /, measured, weight):

Nudges the heading toward an absolute measurement by weight, from 0 to 1.

pose

The pose so far.

class Opt3001:

A Texas Instruments OPT3001 driven over an I2C bus, measuring on demand in single-shot mode.

def init(self, /):

Checks the part is an OPT3001 and writes the settings with the part in shutdown. Raises PamojaError when nothing answers or another part does.

def measure(self, /):

Runs one conversion and returns the illuminance, initializing the part first if init has not run.

def set_limits(self, /, low_milli_lux, high_milli_lux):

Writes the low and high limits the part's interrupt pin compares each result against, in millilux.

configuration

The configuration the driver writes, with the part in shutdown.

class Opt3001Config:

An OPT3001 configuration register, field by field.

overflow

Whether the last result overflowed its range.

latched_window

Whether the INT pin latches until the configuration register is read.

mask_exponent

Whether the limit registers carry a mantissa alone, without an exponent.

active_high

Whether the INT pin is active high.

long_conversion

Whether a conversion takes 800 ms rather than 100 ms.

fault_count

The fault-count code, 0..=3, for one, two, four, or eight faults.

conversion_ready

Whether a conversion has completed since the register was last read.

range_number

The full-scale range number, 0..=11, or 12 to set the range automatically.

mode

The mode code: 0 shutdown, 1 single shot, 2 continuous.

flag_high

Whether the result went above the high limit.

flag_low

Whether the result went below the low limit.

class Opt3001Reading:

An OPT3001 illuminance result.

lux

The illuminance in lux.

raw

The result register: a four-bit exponent over a twelve-bit mantissa.

milli_lux

The illuminance in millilux, exact in integer arithmetic.

class PamojaError(builtins.Exception):

Raised when a pamoja operation fails.

class Pca9685:

An NXP PCA9685 on an I2C bus, driving sixteen PWM outputs.

def init(self, /):

Programs the prescale and the output wiring with the oscillator asleep, wakes it, waits the 500 us it needs, and restarts the channels.

def set_channel(self, /, channel, pwm):

Loads one channel with the four register bytes the pwm builders make, initializing the part first if init has not run. Raises for a channel past 15.

def channel(self, /, channel):

Reads one channel's four register bytes back from the part, one register a transfer, so the read works whatever MODE1 holds and changes nothing on the part.

def set_all(self, /, pwm):

Loads every channel with the same four bytes in one transfer.

def sleep(self, /):

Stops the oscillator; the channels keep their settings.

def wake(self, /):

Wakes the oscillator, waits the 500 us it needs, and restarts the channels that were running before the sleep.

def software_reset(self, /):

Sends the general-call software reset, which returns every PCA9685 on the bus to its power-on state. It goes to address 0x00, which nothing on a simulated bus answers.

prescale

The prescale value the driver writes for its frequency.

frequency

The frequency the part runs at once the prescaler has rounded the one asked for, in hertz.

class Pid:

Holds a value at a setpoint by trading off present, past, and predicted error.

def update(self, /, setpoint, measurement, dt):

Advances the controller by one step and returns the control output.

def reset(self, /):

Clears the accumulated integral, the last error, and the last output.

class Pose:

Where a robot is and which way it faces.

y

Position along the world y axis, in meters.

theta

Heading from the world x axis, in radians, in (-pi, pi], positive counter-clockwise.

x

Position along the world x axis, in meters.

class PowerPlan:

The work intervals a node uses in each mode, and where the modes change.

def with_thresholds(self, /, saver_below, critical_below):

Returns a copy of this plan with the state-of-charge thresholds moved.

def with_hysteresis(self, /, margin):

Returns a copy of this plan with the hysteresis margin moved: how far above a threshold the charge must climb before the plan leaves the lower mode. 0 switches at the thresholds themselves; a margin below zero or not a number is taken as 0.

def mode(self, /, soc):

Returns the mode this plan calls for at a state of charge, by name.

A charge that is not a number, such as a fuel gauge that failed to answer, is taken as critical.

def mode_while_charging(self, /, soc, charging):

Returns the mode, eased one step toward full duty while charging.

def next_mode(self, /, current, soc):

Returns the mode a node in current moves to at a new charge, by name. It drops to a lower mode as soon as the charge falls below that mode's threshold, and climbs back only once the charge reaches the threshold plus the hysteresis margin, so a charge wandering around a threshold keeps the node where it is.

def next_mode_while_charging(self, /, current, soc, charging):

Returns the mode a node in current moves to, eased one step toward full duty while charging. current is the mode this returned last time.

def interval_for_us(self, /, mode):

Returns the work interval for a named mode, in microseconds.

def interval_us(self, /, soc):

Returns the work interval at a state of charge, in microseconds.

hysteresis

How far above a threshold the charge must climb before the plan leaves the lower mode.

saver_below

The charge below which the plan enters saver mode.

critical_below

The charge below which the plan enters critical mode.

class PowerScheduleSpec:

How often a node samples as its battery drains, in whole seconds.

hysteresis

How far above a threshold the charge must climb to leave the lower cadence.

active_secs

Seconds between samples at a healthy charge.

saver_below

Enter the saver cadence below this state of charge.

saver_secs

Seconds between samples while conserving.

critical_secs

Seconds between samples when critically low.

critical_below

Enter the critical cadence below this state of charge.

class Presentation:

How a profile presents itself on the dashboard: its custom elements, an optional theme, and the words for any state or event code it introduces.

elements

The custom sensors and node stats this profile contributes.

theme

An optional theme that tints the dashboard.

messages

The text for each code this profile introduces, keyed by the page's message key (state.flushing, event.filter_clog): a str for every locale, or a dict from locale tag to text.

class Profile:

A named, ready-to-run node assembled from pamoja capabilities.

def vaccine_fridge_monitor():

A cold-chain fridge monitor, which holds 5 C and flags an excursion.

def irrigation_node():

An irrigation node, which opens a valve as soil moisture falls.

def well_level():

A well-level monitor, which warns before a tank runs dry.

def flood_sensor():

A flood sensor, which warns when a level rises too fast.

def from_json(manifest):

Loads a profile from its JSON manifest.

Raises PamojaError if the manifest is malformed, or describes a profile no node could run.

def to_json(self, /):

Serializes this profile to its JSON manifest.

def with_reads(self, /, quantity, unit):

A copy of this profile that says what it reads.

Raises PamojaError when the quantity or unit is not lowercase words joined by underscores.

def with_description(self, /, description):

A copy of this profile carrying a description of what it is for.

def with_presentation(self, /, presentation):

A copy of this profile carrying a dashboard presentation.

Raises ValueError if an element names a graphic the dashboard does not draw, and PamojaError if the presentation holds something else the dashboard could not draw, such as a band whose low end comes second.

def power_plan(self, /):

The schedule assembled into the power governor, which says what mode a charge puts the node in and how long it waits between samples there.

def controller(self, /):

Builds the decision logic this profile describes.

Each call builds a new controller, so keep the one it returns for the life of the node: one built again for each reading forgets whether its output was on and what the reading before was.

Raises PamojaError when the profile names a custom control kind, which no built-in controller decides.

description

What the profile is for, in the words its manifest carries, or None.

presentation

How the profile presents itself on the dashboard, or None when it declares nothing beyond the built-in set.

reads

What the profile reads, the quantity and the unit its numbers are in, or None when the manifest does not say.

topic

The topic each reading is published to.

control

The control policy applied to each reading.

power

The sampling schedule kept as the battery drains.

name

The profile's stable, human-readable name.

class Progress:

How much of an image has arrived.

total

The total the manifest declares.

written

The bytes stored so far.

class PyTransport:

One transport: a link to drive with connect, subscribe, send, and recv, or to compose into a ladder or a wrapper.

Build one with the module constructors, then drive it or hand it to whatever should own it. A transport handed on is spent: using it afterwards raises.

def mqtt( *, client_id, host, port, keep_alive_secs=None, capacity=None, qos=None, max_packet_size=None, username=None, password=None, will=None, tls=None):

Creates an MQTT transport from broker settings.

def coap( *, host, port, bind=None, reliability=None, ack_timeout_ms=None, max_retransmits=None):

Creates a CoAP transport from endpoint settings.

def faulty(inner, failures):

Wraps a transport so its next failures sends fail.

This is how a caller checks that a ladder falls through to its next rung, or that a buffer fills, without unplugging anything. The wrapped transport is consumed.

def degraded(inner, drop_every=0, up=0, down=0):

Wraps a transport in a link that loses packets and goes down.

The wrapped transport is consumed.

def from_handlers(handlers):

Wraps an object whose methods are the link.

handlers needs connect(), send(topic, payload), and subscribe(topic), each a coroutine function or a plain one. A recv() that returns a Message, a (topic, payload) pair with the payload as text or bytes, or None once the link has ended makes it a link that delivers: it is called again as soon as it returns, from the moment the transport connects. A recv that raises ends the link until the next connect, and the next receive raises what it raised. Without recv the transport only sends, and a ladder never listens on it.

def connect(self, /):

Establishes the link.

Raises PamojaError when the link cannot be established, or when the transport was handed on.

def send(self, /, topic, payload):

Publishes a payload to a topic: bytes, or text such as a reading written out.

Raises PamojaError when the link refuses it, or when the transport was handed on.

def subscribe(self, /, topic):

Subscribes to a topic, with the + and # wildcards.

Raises PamojaError when the link refuses it, or when the transport was handed on.

def recv(self, /):

Waits for the next message on a subscribed topic, or None once the link has ended.

Raises PamojaError when the link fails, or when the transport was handed on.

is_available

Whether this transport is still holdable, or has been handed on.

class Quadrature:

Counts a quadrature encoder's steps from its A and B channels.

def update(self, /, a, b):

Feeds the channel levels read now, and returns 1 or -1 for a step in either direction, or 0 for no change or a jump past a step.

def reset(self, /):

Sets the count back to 0, keeping the channel state last read.

count

The signed count of steps so far.

class QuadratureScale:

Turns encoder steps into the distance and speed of the wheel they turn with.

def distance(self, /, count):

Returns the distance, in meters, a wheel rolled for a step count.

def velocity(self, /, delta_count, dt):

Returns the speed, in meters per second, from the steps counted over dt, or 0 when dt is 0.

class Quantizer:

Packs float readings to a fixed precision for a metered link.

def encode(self, /, readings):

Quantizes and delta-encodes a batch of readings.

A reading that is not a number, is infinite, or is too large for the scale is refused, since the format has no way to carry a missing reading.

def decode(self, /, bytes):

Decodes a batch back into readings, to within the quantizer's precision.

class RadioDutyCycle:

The silence a radio owes after its transmissions under a duty-cycle limit.

def wait_us(self, /, now_us):

How long the radio must still stay silent, in microseconds, or None when the limit forbids transmitting.

def ready(self, /, now_us):

Whether a transmission may start at a time in microseconds on the caller's clock.

def transmitted(self, /, started_us, link, payload_len):

Records a transmission and the silence it owes, returning its airtime in microseconds.

earliest_us

The earliest time the next transmission may start, in microseconds on the caller's clock, or None when the limit forbids transmitting.

permille

The limit the guard enforces, in parts per thousand.

class Ramp:

Limits how fast a value may change, so a load is never slammed.

def update(self, /, target):

Moves one step toward target and returns the new value.

def set(self, /, value):

Forces the value without rate limiting.

value

The current value.

class Reaction:

What a controller decided about one reading.

actuator

The setting the output should take, or None when the profile observes rather than controls.

alert

The alert the reading raised, or None if it crossed nothing.

class Reads:

What a profile reads: the quantity its control decides on, and the unit its numbers are in, both lowercase words joined by underscores.

unit

The unit the profile's numbers are in, such as celsius or percent.

quantity

The quantity, such as temperature or relative_humidity.

class ReceiverStep:

What one incoming frame produced for a mission receiver.

accepted

The MISSION_ITEM_INT the frame carried, if it was the one expected next, as a message read by field name.

reply

The frame to send back.

kind

What the receiver answered with: "request" for the next item, or "ack" to end the transfer.

class RecordingActuatorHandle:

An actuator that records every command instead of acting on one.

def apply(self, /, command):

Applies a command, which is recorded rather than acted on.

def commands(self, /):

The commands recorded so far, oldest first.

class Replay:

A sensor that reads back a recorded series.

This is how a caller replays a real capture, so a test asks what the code does with readings that actually happened rather than ones it invented.

def read(self, /):

Takes the next reading.

Raises PamojaError (resource is closed) once a replay that does not repeat has run out.

class Reporter:

Records telemetry events, ships the ones worth their bytes, and counts them all.

def adapt_to(self, /, cost):

Moves the threshold to match what the link now costs.

def record(self, /, level):

Records an event at a level and reports whether it should be shipped.

The event is counted either way, so the aggregate picture survives even when the link is too costly to carry the detail.

def count(self, /, level):

Returns how many events have been seen at a level, shipped or not.

def snapshot(self, /):

Takes a snapshot of the counters to ship in place of the event stream.

emitted

How many events passed the threshold and were shipped.

threshold

The level this reporter is currently shipping from.

total

How many events have been seen across every level.

dropped

How many events the threshold dropped.

class Route:

A learned way to reach one node.

next_hop

The neighbor to send a packet to on the way there.

cost

What the route costs, usually in hops.

dst

The node this route reaches.

class Router:

One node routing table, learned from the traffic the node hears.

def observe(self, /, origin, via, cost):

Learns a route from a packet that arrived, reporting whether it changed the table.

def next_hop(self, /, dst):

The neighbor to send a packet to on the way to dst, or None.

def cost(self, /, dst):

What the known route to dst costs, or None when none is known.

def route(self, /, dst):

The whole route to dst, or None when none is known.

def routes(self, /):

The routes the table holds, each once, in the order the table holds them rather than sorted by destination or cost.

def forward(self, /, dst):

Decides what to do with a packet bound for dst.

def forget(self, /, dst):

Forgets the route to dst, for example after it stops answering.

address

The address this router answers for.

capacity

How many routes the table can hold.

class RuleAction:

One thing a rule calls for, as the rule file writes it.

Only the attributes belonging to kind are set; the rest are None.

on

The setting to switch it to, for a drive.

topic

The topic to publish to, for a publish.

payload

The text to publish, for a publish.

kind

drive to switch an output, or publish to send a message.

actuator

The output to switch, for a drive.

class RuleEvaluator:

The decisions a rule file makes, reading by reading, with no link and no outputs of its own.

def from_json(text):

Loads a rule file and arms its rules, every condition starting cleared.

Raises PamojaError if the text is not a rule file, or holds a rule no engine could run, such as one that watches a filter or has nothing to do.

def to_json(self, /):

Writes the rules back out as the file a fleet shares.

def evaluate(self, /, topic, reading):

Judges one reading from one topic against every rule that watches it, and returns what fired in the order the rules are listed: empty when no rule watches the topic or the reading changed nothing.

Raises PamojaError if a rule watches the topic and the reading is not a finite number.

def watches(self, /, topic):

Whether any rule watches a topic, so the program knows whether to decode a message.

def is_set(self, /, rule):

Whether a rule's condition currently holds, or None for a name no rule has.

topics

The topics the rules watch, each once, in name order: the topics to subscribe to.

actuators

The actuators the rules drive, each once, in name order: the outputs the program has to have.

class RuleFired:

What one rule did with one reading.

edge

set when the rule's condition became true, cleared when it stopped holding.

reading

The reading that did it.

rule

The rule's name.

actions

What the rule calls for on this edge: its then actions when it set and its otherwise actions when it cleared, in the order the file gives them.

class SafetyGate:

The gate every motion command passes through: an e-stop, a watchdog, and limits.

def feed(self, /):

Feeds the watchdog; call it whenever a fresh command arrives.

def engage_estop(self, /):

Engages the latching e-stop.

def reset_estop(self, /):

Clears the e-stop.

def command(self, /, desired, dt):

Returns the command that is safe to drive: a zero twist while stopped, otherwise desired bounded by the limits.

is_stopped

Whether the gate is forcing a stop: its e-stop is engaged or its watchdog expired.

class Scd4x:

A Sensirion SCD40 or SCD41 driven over an I2C bus in periodic measurement, a result every five seconds.

def init(self, /):

Stops any running measurement, reads the serial number, and starts periodic measurement. Raises PamojaError when nothing answers or the serial number fails its checksum.

def measure(self, /):

Waits for the next periodic result and returns it, initializing the part first if init has not run.

def measure_single_shot(self, /):

Runs one on-demand measurement on an SCD41, which takes five seconds. The part must not be measuring periodically: call stop first, or use this in place of init.

def data_ready(self, /):

Asks the part whether a periodic result is waiting, so measure would read at once.

def stop(self, /):

Stops periodic measurement, after which the part takes its settings commands.

def start(self, /):

Starts periodic measurement.

def set_temperature_offset(self, /, milli_celsius):

Sets the temperature offset that compensates the part's own warmth, in millidegrees, until power is lost.

def set_sensor_altitude(self, /, meters):

Sets the altitude the part corrects its carbon dioxide reading for, in meters.

serial

The 48-bit serial number read at initialization, or None before it.

class Scd4xMeasurement:

A decoded SCD4x measurement frame.

relative_humidity_percent

The relative humidity as a percentage.

celsius

The temperature in degrees Celsius.

temperature_raw

The raw temperature word.

co2_ppm

The carbon dioxide concentration in parts per million.

milli_celsius

The temperature in milli-degrees Celsius, exact in integer arithmetic.

humidity_raw

The raw humidity word.

humidity_milli_percent

The relative humidity in milli-percent.

class SealedMessage:

A message that has been sealed, with the header that travels beside it.

ciphertext

The encrypted message.

tag

The tag over the ciphertext and its associated data.

counter

The counter naming this message within the session.

class SeenPackets:

A memory of recently seen packets, so a node relays each one only once.

def contains(self, /, src, id):

Reports whether a packet is currently remembered, without recording it.

def record(self, /, src, id):

Records a packet and reports whether it was new.

A true answer is when a node should act on the packet and relay it; a false one means another copy already arrived by a different path.

capacity

How many packets this cache remembers.

class SenderStep:

What one incoming frame produced for a mission sender.

kind

What happened: "reply" when there is a frame to send, or "finished" when the receiver acknowledged the transfer.

result

The receiver's MAV_MISSION_RESULT, when the transfer finished.

reply

The frame to send back, when there is one.

class SerialPort:

One serial port, shared by the program and every driver built on it.

A failed write or read raises PamojaError with the reason: the script expected another write, or the kernel's own words.

def open(path, baud, parity, stop_bits):

Opens the kernel's serial device raw: /dev/serial0 for a Raspberry Pi's own UART, /dev/ttyUSB0 or /dev/ttyACM0 for a USB adapter.

Raises PamojaError anywhere but Linux, for a speed that is not a standard rate from 1200 to 921600, and when the device cannot be opened.

def looped(baud, parity, stop_bits):

A line looped back on itself: every byte written is waiting to be read.

def pair(baud, parity, stop_bits):

The two ends of a null-modem pair: what one end writes, the other reads.

def scripted(baud, parity, stop_bits, steps):

A port that checks each write against the next step of a script, and makes the bytes the far end sends readable as the script reaches them.

def write(self, /, data):

Writes bytes, returning once they have left the UART.

def read(self, /, size, timeout_micros):

Reads up to size bytes, waiting up to timeout_micros for the first one when nothing has arrived, and returns what arrived, empty when the timeout passed with nothing.

def discard_input(self, /):

Drops whatever has arrived and not been read.

def wait(self, /, micros):

Waits, really on the kernel's device and anywhere else only counted.

settings

The speed, the parity name, and the stop bit count the port runs at.

waited_micros

How long reads have waited without an answer, and waits have waited, in microseconds, whether or not the process slept through it.

received

How many bytes have been read through the port.

written

How many bytes have been written through the port.

kind

What is on the other end: "Device", "Looped", "Paired", "Simulated", or "Scripted".

remaining

How many steps a script has left, or None when the port is not scripted.

class SerialStep:

One step of a scripted port: a write the program is expected to make, or bytes the far end sends.

def write(data):

A write the program is expected to make, in one call.

def read(data):

Bytes the far end sends, readable once every step before them has happened.

class ServoMap:

A hobby servo's pulse widths across its travel.

def standard():

The standard hobby servo: 1000 to 2000 microseconds over 180 degrees.

def pulse(self, /, angle_deg):

Returns the pulse width for an angle, held to the travel, or 0, no pulse, for an angle that is not a number.

def angle(self, /, pulse_us):

Returns the angle a pulse width sets, held to the pulse range.

min_us

The pulse width at zero degrees, in microseconds.

max_us

The pulse width at full travel, in microseconds.

range_deg

The full travel, in degrees.

class Session:

A confidential, tamper-evident, replay-protected channel with one peer.

def seal(self, /, plaintext, aad=Ellipsis):

Seals a message for the peer.

The associated data is authenticated but not encrypted, so it stays readable on the wire yet cannot be altered: a device identifier or a routing header belongs there.

def open(self, /, sealed, aad=Ellipsis):

Opens a message from the peer, returning the plaintext.

Raises if the counter repeats or is older than the replay window still tracks, and if the tag does not authenticate. Nothing readable is ever returned from a message that failed either check.

class Sht3x:

A Sensirion SHT3x driven over an I2C bus, measuring on demand in single-shot mode.

def init(self, /):

Soft-resets the part and reads its status; a status word whose checksum holds is what confirms an SHT3x answers. Raises PamojaError when nothing answers or the word fails.

def measure(self, /):

Runs one single-shot measurement and returns it, initializing the part first if init has not run. Raises PamojaError when a data word fails its checksum.

def read_status(self, /):

Reads the status register, which last_status keeps as well.

def heater_on(self, /):

Switches the plausibility-check heater on, initializing the part first if needed.

def heater_off(self, /):

Switches the heater off, which is its state after any reset.

last_status

The status register as it was last read, or None before it has been.

class Sht3xMeasurement:

A decoded SHT3x temperature and humidity pair.

milli_celsius

The temperature in milli-degrees Celsius, exact in integer arithmetic.

celsius

The temperature in degrees Celsius.

fahrenheit

The temperature in degrees Fahrenheit.

relative_humidity

The relative humidity as a percentage.

humidity_raw

The raw humidity word.

milli_fahrenheit

The temperature in milli-degrees Fahrenheit.

milli_percent

The relative humidity in milli-percent.

temperature_raw

The raw temperature word.

class Sht3xStatus:

A decoded SHT3x status register.

humidity_tracking_alert

Whether a humidity tracking alert is set.

alert_pending

Whether at least one alert condition is pending.

command_failed

Whether the last command could not be processed.

bits

The 16-bit status word the flags were read from.

write_checksum_failed

Whether the last write failed its checksum.

heater_on

Whether the on-die heater is running.

temperature_tracking_alert

Whether a temperature tracking alert is set.

reset_detected

Whether the part has reset since the flag was last cleared.

class Signals:

The eight data bytes of a J1939 frame, addressed by the signals inside them.

A parameter group places each signal at a fixed byte offset, little-endian. A payload starts with every signal marked not available, so a controller writes only the signals it actually reports.

def from_bytes(bytes):

Reads the eight data bytes of a frame that arrived off the bus.

def set_u8(self, /, at, value):

Writes a one-byte signal at the offset its parameter group defines.

def set_u16(self, /, at, value):

Writes a two-byte little-endian signal at the offset its group defines.

def u8(self, /, at):

Reads a one-byte signal, or None if the offset is past the payload.

def u16(self, /, at):

Reads a two-byte little-endian signal, or None if it would run past the payload.

bytes

The eight data bytes, ready to put in a frame.

class SimulatedLoraChip:

A simulated SX126x or SX127x, which a LoraRadio drives with no radio attached.

The program says what arrives on the air with hear, and reads back what the chip was tuned to and what it sent with tuning and sent. Nothing is timed: a transmission is done as soon as it starts, and a reception with a timeout ends at once when nothing is waiting.

def sx126x( amplifier, *, tcxo_volts=None, tcxo_settle_us=None, dio2_rf_switch=False, dc_dc=False, llcc68=False):

A simulated SX1261, SX1262, SX1268, or LLCC68, out of reset.

Raises ValueError for an amplifier name or a TCXO voltage the chip has no setting for.

def sx127x(output, *, tcxo=False):

A simulated SX1276, SX1277, SX1278, or SX1279, out of reset.

Raises ValueError for an amplifier output name the chip has no setting for.

def radio(self, /):

Returns a radio wired to the chip, reset as opening a module resets it.

def hear(self, /, payload, rssi_dbm, snr_db):

Puts a frame on the air for the chip to receive the next time it listens, heard at a strength in dBm and a signal-to-noise ratio in dB. A payload past 255 bytes is cut to 255.

Raises ValueError for a level that is not a finite number.

def hear_corrupt(self, /, rssi_dbm, snr_db):

Puts a frame on the air whose CRC fails, which the chip reports and drops.

Raises ValueError for a level that is not a finite number.

def tuning(self, /):

Returns what the chip is tuned to now.

def sent(self, /):

Returns every frame the chip has put on the air, oldest first.

family

The family of the chip: "Sx126x" or "Sx127x".

waiting

How many frames wait on the air for the chip to receive.

class SimulatedRobot:

A robot that moves only in arithmetic.

def apply(self, /, *, vx=0.0, vy=0.0, omega=0.0):

Drives the robot for one time step.

def pose(self, /):

Where the robot has got to.

class SimulatedSensor:

A sensor that invents plausible readings.

def read(self, /):

Takes the next reading.

class SkidSteer:

A tracked or four-wheel drive that turns by skidding, with its track widened by a slip factor.

def wheel_speeds(self, /, linear, angular):

Returns the (left, right) speeds for a forward speed and a yaw rate.

def body_motion(self, /, left, right):

Returns the (linear, angular) body motion measured side speeds make.

class SlipDecoder:

Reassembles whole SLIP frames from the chunks a serial port delivers.

def feed(self, /, chunk):

Feeds a chunk of the stream and returns every frame it completed.

def reset(self, /):

Discards any partly assembled frame.

discarded

How many corrupt frames this decoder has discarded.

class SlotRecord:

The record a device keeps about one slot, durable across a reboot.

sequence

The sequence number of the image in the slot.

state

The state of the slot, by name.

digest

The digest of the image.

written

How many bytes have been stored, which is where a resumed transfer picks up.

size

The length of the image in bytes.

class Smoother:

Smooths a noisy reading by weighting each new sample against the running value.

def update(self, /, sample):

Folds a sample in and returns the smoothed value.

def reset(self, /):

Clears the smoother back to its initial state.

value

The current value, or None before the first sample.

class Snapshot:

A count of everything a reporter has seen, cheap enough to ship anywhere.

error

How many events were seen at error level.

emitted

How many events passed the filter and were shipped.

info

How many events were seen at info level.

trace

How many events were seen at trace level.

dropped

How many events the filter dropped.

warn

How many events were seen at warn level.

debug

How many events were seen at debug level.

class SpiClock:

The clock polarity and phase pair an SPI mode number names.

cpha

Whether data is sampled on the trailing edge (CPHA = 1), which is modes 1 and 3.

cpol

Whether the clock idles high (CPOL = 1), which is modes 2 and 3.

class Stepper:

A stepper motor's place in its drive sequence, and how far it has turned.

def step(self, /, direction):

Advances one step and returns the four-bit coil pattern to apply.

The most significant of the four bits is the first coil.

steps

How many steps have been taken, signed by direction.

coils

The coil pattern currently held, without advancing.

class Store:

A store-and-forward buffer.

Handing a store to a ladder consumes it, because the ladder owns it from then on. A consumed store is emptied rather than left aliasing what now belongs to the ladder, so using one twice raises.

def memory(capacity=0):

Creates a buffer held in memory.

A full store refuses the next append rather than dropping anything, so a record is never lost without the caller being told.

def file(dir, capacity=0):

Opens a buffer backed by a directory, so it survives a restart.

A record a power cut interrupted mid-write is never seen, and one written before the cut is found again when the directory is reopened. capacity is the most records to hold, or 0 for no bound; a full store refuses the next append, which keeps a long outage from filling the disk.

def drain_to(self, /, transport, topic):

Drains the buffer onto a transport, publishing each record to topic, oldest first, and returns how many went out.

Each record leaves the buffer only once the transport has taken it, so a send that fails raises the transport's error and leaves that record and every one after it buffered, in order, for the next drain. The transport is driven, not consumed.

def append(self, /, record):

Adds a record to the end of the buffer.

def peek(self, /):

Reads the oldest record without removing it, or None when empty.

def pop(self, /):

Removes and returns the oldest record, or None when empty.

def peek_text(self, /):

Reads the oldest record as text without removing it, or None when empty.

Raises ValueError if the record is not UTF-8 text.

def pop_text(self, /):

Removes and returns the oldest record as text, or None when empty.

Raises ValueError if the record is not UTF-8 text.

def len(self, /):

How many records the buffer holds.

is_available

Whether this store is still holdable, or has been given to a ladder.

class Surge:

Notices a step change between successive readings, such as a burst pipe.

def rising(limit):

Creates a detector for rises of more than limit between readings.

def falling(limit):

Creates a detector for falls of more than limit between readings.

def update(self, /, value):

Feeds a value in and returns the size of a step past the limit, or None.

class Sx126xPacketStatus:

The signal levels of the last LoRa packet received.

rssi_dbm

The RSSI averaged over the packet, in dBm.

signal_rssi_dbm

The estimated RSSI of the LoRa signal after despreading, in dBm.

snr_db

The estimated signal-to-noise ratio, in dB.

class Sx126xQuery:

A command the chip answers in the same SPI transaction.

answer_len

How many bytes of answer to read after the query's bytes.

bytes

The bytes to send, ending with the NOP during which the status byte comes back.

class Sx126xRxBufferStatus:

Where a received payload sits in the data buffer.

start

The buffer offset of its first byte.

payload_len

The length of the payload in bytes.

class Sx126xStatus:

A decoded SX126x status byte.

chip_mode

The mode the chip is in: StandbyRc, StandbyXosc, Fs, Rx, Tx, or Other.

error

Whether the last command timed out, could not be processed, or failed.

command_status

How the last command went: DataAvailable, Timeout, ProcessingError, ExecutionFailure, TxDone, or Other.

class Sx126xTxPower:

The amplifier configuration and power setting that produce an output power.

setting_dbm

The power byte of SetTxParams, in dBm.

pa_lut

paLut, reserved and always 1.

pa_duty_cycle

paDutyCycle, the conduction angle of the amplifier.

hp_max

hpMax, the size of the SX1262 amplifier; no effect on the SX1261.

device_sel

deviceSel: 0 for the SX1262 and the LLCC68, 1 for the SX1261.

class Sx127xHighBwOptimize:

The writes of the SX127x 500 kHz sensitivity erratum.

optimize_1

The RegHighBwOptimize1 value.

optimize_2

The RegHighBwOptimize2 value, or None when it is not written.

class Sx127xModem:

The LoRa modem registers of an SX127x for a link.

detection_threshold

RegDetectionThreshold.

detection_optimize

The DetectionOptimize bits for the low three bits of RegDetectOptimize.

modem_config_3

RegModemConfig3: low data rate optimization and the AGC.

modem_config_1

RegModemConfig1: bandwidth, coding rate, and header mode.

modem_config_2

RegModemConfig2: spreading factor, CRC, and the top bits of the symbol timeout.

class Sx127xModemStatus:

The live state of an SX127x LoRa modem.

coding_rate_denominator

The coding rate denominator the last header announced, or None for a reserved value.

signal_synchronized

The modem has synchronized on the end of the preamble.

signal_detected

A LoRa preamble has been detected.

clear

The modem is clear.

header_valid

The header of the packet under way is valid.

rx_ongoing

A reception is under way.

class Sx127xPacketStatus:

The signal levels of a packet an SX127x received.

signal_rssi_dbm

The strength of the packet itself, in dBm.

snr_db

The estimated signal-to-noise ratio, in dB.

rssi_dbm

The RSSI averaged over the packet, in dBm.

class Sx127xSpuriousReception:

The receive settings of the SX127x spurious reception erratum.

offset_hz

How far above the carrier to receive, in hertz.

if_freq_2

The RegIfFreq2 value, with RegIfFreq1 cleared, or None when the IF stays automatic.

automatic_if

Whether AutomaticIFOn stays on.

class Sx127xTxPower:

The amplifier settings of an SX127x.

ocp

RegOcp: the current limit.

pa_config

RegPaConfig: PaSelect, MaxPower, and OutputPower.

pa_dac

RegPaDac: the +20 dBm setting above +17 dBm on PA_BOOST, else its reset value.

output_dbm

The output power the settings produce, in dBm.

class Theme:

The theme tokens a profile sets on the dashboard; each is any CSS color.

alarm

The alarm status color.

accent

The brand and interaction accent.

warn

The warning status color.

track

The unfilled track color behind gauges and bars.

ok

The healthy status color, which also tints an in-band gauge.

class Thermostat:

Switches a load on and off around a setpoint, with hysteresis to stop chatter.

def cooling(setpoint, hysteresis):

Creates a cooling thermostat, which switches on when the reading rises.

def heating(setpoint, hysteresis):

Creates a heating thermostat, which switches on when the reading falls.

def update(self, /, reading):

Feeds a reading in and returns whether the load should be on.

is_on

Whether the load is on, as the last reading left it.

class Tilt:

Roll and pitch, in degrees.

pitch

Rotation about the right axis, in degrees, from -90 to 90.

roll

Rotation about the forward axis, in degrees, from -180 to 180.

class Tmp117:

A Texas Instruments TMP117 driven over an I2C bus, converting on demand in one-shot mode.

def init(self, /):

Checks the part is a TMP117, waits for its EEPROM to finish loading, and writes the settings with the part in shutdown. Raises PamojaError when nothing answers or another part does.

def measure(self, /):

Runs one conversion and returns the temperature, initializing the part first if init has not run.

def set_alert_limits(self, /, high_celsius, low_celsius):

Writes the high and low limits the part compares each result against; the factory limits are 192 C and -256 C.

def alerts(self, /):

Reads the alert flags: whether a result since the last call was above the high limit or below the low limit, including results the driver's own reads saw.

silicon_revision

The silicon revision read at initialization, or None before it.

class Tmp117Alerts:

The TMP117's alert flags: whether a result since they were last read crossed a limit.

high

A result was above the high limit.

low

A result was below the low limit.

class Tmp117Config:

A TMP117 configuration register, field by field.

cycle

The conversion-cycle code, 0..=7.

therm_mode

Whether the limits act as a therm hysteresis band rather than as alerts.

high_alert

Whether a result went above the high limit.

data_ready

Whether a conversion has completed since the register was last read.

eeprom_busy

Whether an EEPROM write is still in progress.

mode

The conversion-mode code: 0 continuous, 1 shutdown, 3 one-shot.

averaging

The averaging code, 0..=3.

alert_pin_data_ready

Whether the ALERT pin reflects data ready rather than the alert flags.

soft_reset

Whether writing this triggers a software reset.

alert_active_high

Whether the ALERT pin is active high.

low_alert

Whether a result went below the low limit.

class Tmp117Reading:

A TMP117 temperature result.

micro_celsius

The temperature in micro-degrees Celsius, exact in integer arithmetic.

celsius

The temperature in degrees Celsius.

raw

The temperature register, 7.8125 millidegrees Celsius per count.

class Transform:

A 4x4 homogeneous transform: a rotation and a translation.

def identity():

The identity: no rotation and no translation.

def multiply(self, /, other):

Returns self * other, the transform that applies other and then this one.

position

Where this transform places the origin, its translation, as (x, y, z).

elements

The sixteen elements, row-major.

class Trend:

Fits a line through recent readings, so a slow drift is visible before it matters.

def push(self, /, reading):

Adds a reading.

slope

The fitted slope in units per reading, or None without two readings.

A positive slope is a rising signal.

capacity

How many readings the estimator keeps.

class Trigger:

Fires once when a reading crosses a line, and not again until it has come back past the release band.

update answers "set" the moment the reading crosses the line, "cleared" the moment it comes back past the band, and None while nothing changed; the facade wraps the two in its Edge enum.

def above(threshold, hysteresis):

Creates a trigger that fires when a reading rises above the line and clears once it has fallen below the line by the hysteresis.

def below(threshold, hysteresis):

Creates a trigger that fires when a reading falls below the line and clears once it has risen above the line by the hysteresis.

def update(self, /, reading):

Feeds a reading in and returns the edge it caused, or None while nothing changed.

threshold

The line the trigger watches.

is_set

Whether the condition currently holds.

hysteresis

The release band on the far side of the line.

watches_above

Whether the trigger watches a rising reading, as above makes it.

class Twist:

How fast a robot is asked to move.

omega

Yaw rate about the z axis, positive counter-clockwise.

vx

Forward speed along the x axis.

vy

Leftward speed along the y axis; zero for drives that cannot strafe.

class TwoLinkArm:

A planar arm of two links, with a closed-form inverse.

def tip(self, /, shoulder, elbow):

Returns the hand's (x, y) for a shoulder and an elbow angle, in radians.

def joints_for(self, /, x, y, elbow='up'):

Returns the (shoulder, elbow) angles that put the hand at a point, or None for a point out of reach, an arm with a link of no length, or a coordinate that is not a finite number. elbow is "up" or "down".

reach

The (min, max) the hand reaches from the shoulder.

class Updater:

A device's slots, and the rules applied to what is offered for them.

def slot_record(self, /, slot):

Reads what the device believes about one slot.

def provision(self, /, slot, sequence):

Records that a slot already holds a confirmed image at a sequence number.

This is how a device that shipped with firmware says what it is running, so the rollback rule has something to compare against.

def adopt(self, /, envelope, now=None):

Adopts a delegation, so releases signed by the key it names are accepted.

def stage(self, /, envelope, image, now=None):

Checks a manifest and stages an image that is already held whole, returning the slot it went into.

def begin(self, /, envelope, now=None):

Checks a manifest and opens the slot it names for a transfer in pieces.

Every check that can be made without the image runs here, so a release that is not for this device, would roll it back, or does not fit is refused before a byte of it is accepted. The envelope is remembered until finish, and every call after this one checks it again, so a release overtaken or expired while it arrives stops arriving. The hash of what has arrived is carried from one call to the next, so an image taken in many small pieces costs no more than one taken whole.

def write(self, /, chunk):

Takes the next piece of an image opened with begin.

def progress(self, /):

Reports how much of an opened image has arrived.

def finish(self, /):

Finishes an opened image and marks the slot bootable if it matched, returning the slot now holding it.

def on_boot(self, /):

Decides what to run, and records that decision before returning it.

Call this once per boot, before jumping to an image. A staged image becomes pending here, so a device that resets before confirming reverts on the next call rather than trying a broken image forever.

def confirm(self, /):

Confirms the pending image, so it will be run from now on.

def revert(self, /):

Fails the pending image and goes back to the confirmed one.

slot_count

How many slots this device has.

installed_sequence

The highest sequence number the device already holds.

delegation

The delegation this updater currently honors, or None when releases must be signed by the anchor itself.

class Watchdog:

A deadman timer that expires unless fed often enough.

def feed(self, /):

Feeds the watchdog, restarting its silence timer.

def update(self, /, dt):

Advances the timer by dt and returns whether it has expired; a dt that is not a finite number expires it until it is fed.

is_expired

Whether the watchdog has expired.

class WaypointFollower:

Steers toward a waypoint: pivot toward it, then drive, slowing as the heading error grows.

def guide(self, /, here, heading_deg, target):

Returns the command from a (latitude, longitude) position and a compass heading, in degrees clockwise from north, toward a target.

class WheelSpeeds:

The four wheel speeds of a mecanum base.

front_left

The front-left wheel's speed.

rear_left

The rear-left wheel's speed.

front_right

The front-right wheel's speed.

rear_right

The rear-right wheel's speed.

class Window:

A rolling window of the most recent readings, with the stats over them.

def push(self, /, reading):

Adds a reading, dropping the oldest once the window is full.

def latest(self, /):

The most recent reading, or None while the window is empty.

def oldest(self, /):

The oldest reading still held, or None while the window is empty.

def mean(self, /):

The mean of the readings, or None while the window is empty.

def min(self, /):

The smallest reading, or None while the window is empty.

def max(self, /):

The largest reading, or None while the window is empty.

def range(self, /):

The spread between the smallest and largest readings, or None while empty.

def variance(self, /):

The population variance of the readings, 0 for one reading, or None while empty.

capacity

How many readings the window holds before it starts dropping.

is_full

Whether the window holds as many readings as it keeps.

class WordPart:

A part that is not there, answering from 256 registers sixteen bits wide.

A pointer byte names a register and a register travels most significant byte first. Bits the part sets for itself, such as a conversion-ready flag, are marked with read_only and keep the part's value whatever a driver writes.

def set(self, /, register, value):

Puts a value in one register, read-only bits included, the way the part itself would.

def read_only(self, /, register, mask):

Marks bits of one register as the part's to set: a driver's write leaves them as the part holds them.

def word(self, /, register):

What one register holds now, which is what a driver wrote there apart from the read-only bits.

address

The address the part answers to.

transfers

How many transfers the part has served.

def ads1115_config_bits(config):

Assembles the 16-bit ADS1115 configuration register value.

def ads1115_config_from_bits(bits):

Parses a 16-bit ADS1115 configuration register value.

def ads1115_conversion_micros(data_rate):

Returns how long an ADS1115 conversion takes at a data-rate code, in microseconds: one period of the rate plus the datasheet's ten percent rate variation.

def ads1115_full_scale_microvolts(pga):

Returns the full-scale range an ADS1115 gain code selects, in microvolts.

def ads1115_samples_per_second(data_rate):

Returns the sample rate an ADS1115 data-rate code selects.

def ads1115_sim_part(address):

A simulated ADS1115 reading 1.65 V, half a 3.3 V supply, at the range a driver starts with.

def ads1115_sim_reporting(address, pga, volts):

A simulated ADS1115 that reads what it is asked to at the gain code a driver converts at.

def ads1115_to_nanovolts(pga, raw):

Converts a raw ADS1115 conversion result to nanovolts.

def ads1115_to_volts(pga, raw):

Converts a raw ADS1115 conversion result to volts.

def bearing_between(from_latitude, from_longitude, to_latitude, to_longitude):

Returns the initial bearing from one coordinate to another, in degrees.

def bme280_config_bits(config):

Packs a BME280 config register value.

def bme280_config_from_bits(bits):

Parses a BME280 config register value.

def bme280_ctrl_hum_bits(humidity):

Packs a BME280 ctrl_hum register value from a humidity oversampling code.

def bme280_ctrl_hum_from_bits(bits):

Parses a BME280 ctrl_hum register value into its humidity oversampling code.

def bme280_ctrl_meas_bits(ctrl):

Packs a BME280 ctrl_meas register value.

def bme280_ctrl_meas_from_bits(bits):

Parses a BME280 ctrl_meas register value.

def bme280_filter_coefficient(code):

Returns the IIR filter coefficient a BME280 code selects, or 0 when it is off.

def bme280_image_updating(status):

Reports whether a BME280 status byte says the calibration image is loading.

def bme280_max_measurement_micros(temperature, pressure, humidity):

Returns the longest one BME280 measurement can take, in microseconds.

def bme280_measuring(status):

Reports whether a BME280 status byte says a conversion is running.

def bme280_oversampling_factor(code):

Returns how many samples a BME280 oversampling code averages, or 0 when it skips.

def bme280_sim_burst():

The eight data registers a simulated BME280 holds: one measurement a real part took.

def bme280_sim_burst_for(celsius, hectopascals, relative_humidity):

The eight data registers that compensate to a reading against the simulated calibration.

def bme280_sim_calibration():

The 26-byte temperature and pressure calibration block a simulated BME280 holds.

def bme280_sim_calibration_humidity():

The 7-byte humidity calibration block a simulated BME280 holds.

def bme280_sim_part(address):

A simulated BME280 holding a real part's calibration and one measurement it took, which compensate to 20.44 C, 848.05 hPa, and 44.65 %.

def bme280_sim_reporting(address, celsius, hectopascals, relative_humidity):

A simulated BME280 that reads what it is asked to, to within what its converter can represent.

def bme280_standby_micros(code):

Returns the normal-mode standby period a BME280 code selects, in microseconds.

def bme280_typical_measurement_micros(temperature, pressure, humidity):

Returns the typical time one BME280 measurement takes, in microseconds.

def bmp280_config_bits(config):

Packs a BMP280 config register value.

def bmp280_config_from_bits(bits):

Parses a BMP280 config register value.

def bmp280_ctrl_meas_bits(ctrl):

Packs a BMP280 ctrl_meas register value.

def bmp280_ctrl_meas_from_bits(bits):

Parses a BMP280 ctrl_meas register value.

def bmp280_image_updating(status):

Reports whether a BMP280 status byte says the calibration image is loading.

def bmp280_measurement_bytes(pressure, temperature):

Builds the six data bytes a BMP280 holding these codes would return.

def bmp280_measuring(status):

Reports whether a BMP280 status byte says a conversion is running.

def bmp280_oversampling_factor(code):

Returns how many samples a BMP280 oversampling code averages.

def bmp280_parse_measurement(data):

Unpacks the six data bytes a BMP280 burst read returns.

def bmp280_pressure_skipped(pressure):

Reports whether a raw BMP280 pressure says the measurement is switched off.

def bmp280_sim_burst():

The six data registers a simulated BMP280 holds: one measurement a real part took.

def bmp280_sim_burst_for(celsius, hectopascals):

The six data registers that compensate to a reading against the simulated trimming.

def bmp280_sim_calibration():

The 24 trimming bytes a simulated BMP280 holds.

def bmp280_sim_part(address):

A simulated BMP280 holding a real part's trimming and one measurement it took, which compensate to 20.44 C and 848.05 hPa.

def bmp280_sim_reporting(address, celsius, hectopascals):

A simulated BMP280 that reads what it is asked to, within a hundredth of a degree and of a hectopascal.

def bmp280_standby_micros(code):

Returns the normal-mode standby period a BMP280 code selects, in microseconds.

def bmp280_temperature_skipped(temperature):

Reports whether a raw BMP280 temperature says the measurement is switched off.

def can_dlc_to_len(dlc):

Returns the payload length a data length code encodes.

def can_fd_frame(id, extended, data):

Builds a CAN-FD frame, which carries up to 64 bytes at the discrete CAN-FD lengths.

def can_frame(id, extended, data):

Builds a classic CAN 2.0 frame, which carries up to eight bytes.

def can_len_to_dlc(len):

Returns the data length code that encodes a payload length.

def can_remote_frame(id, extended, len):

Builds a remote transmission request, which asks another node to send.

def cbor_to_json_bytes(cbor):

Converts a CBOR document back into its JSON encoding.

def celsius_to_fahrenheit(celsius):

Converts degrees Celsius to degrees Fahrenheit.

def celsius_to_kelvin(celsius):

Converts degrees Celsius to kelvin.

def cobs_decode(frame):

Reads the payload back out of a COBS frame.

def cobs_encode(payload):

Frames a payload as a COBS packet, terminated by its zero delimiter.

def cobs_max_encoded_len(payload_len):

Returns the largest COBS frame a payload of this length can produce.

def deadband(value, center, width):

Holds value at center while it stays within width either side, and passes it through unchanged once it is further out.

def decode_delta_samples(bytes):

Decodes a delta-encoded buffer back into its integer samples.

def decode_manifest(data):

Reads a manifest body back from its bytes.

This reads what a manifest claims; it proves nothing about who wrote it. Use verify_envelope to read one whose signature has been checked.

def dew_point(celsius, humidity_percent):

Computes the dew point, in degrees Celsius, from the air temperature in degrees Celsius and the relative humidity in percent.

def distance_between(from_latitude, from_longitude, to_latitude, to_longitude):

Returns the great-circle distance between two coordinates, in meters.

def ds18b20_build_scratchpad(celsius, bits, alarm_high, alarm_low):

Builds the nine bytes a DS18B20 in the given state puts on the bus, CRC last.

def ds18b20_celsius(raw):

Converts a raw DS18B20 temperature register to degrees Celsius.

def ds18b20_config_byte(bits):

Returns the configuration byte that selects a DS18B20 resolution.

def ds18b20_crc8(data):

Computes the Maxim CRC-8 a 1-Wire device checks its own bytes with.

def ds18b20_max_conversion_micros(bits):

Returns how long a DS18B20 conversion may take at a resolution, in microseconds.

def ds18b20_micro_celsius(raw):

Converts a raw DS18B20 temperature register to micro-degrees Celsius.

def ds18b20_parse_scratchpad(data):

Parses and CRC-checks a nine-byte DS18B20 scratchpad.

def ds18b20_parse_w1_slave(text):

Decodes the text the Linux kernel's w1_therm driver serves for a DS18B20, the contents of its w1_slave file, checking the scratchpad's CRC as well as the kernel's verdict.

def ds18b20_resolution_bits(config_byte):

Returns the resolution a DS18B20 configuration byte selects, in bits.

def ds18b20_step_micro_celsius(bits):

Returns the temperature step a DS18B20 resolution resolves, in micro-degrees.

def ds18b20_w1_slave_text(data):

Renders the text the Linux kernel's w1_therm driver serves for a nine-byte scratchpad it read cleanly, the inverse of ds18b20_parse_w1_slave. Raises PamojaError when the CRC does not match.

def encode_delta_samples(samples):

Delta-encodes a series of integer samples into a compact buffer.

def encode_manifest(manifest):

Encodes the body of a manifest, which is the part a signature covers.

def envelope_body(data):

Copies out the signed body of an envelope, without checking the signature.

This is what a gateway relays onward unchanged.

def fahrenheit_to_celsius(fahrenheit):

Converts degrees Fahrenheit to degrees Celsius.

def fingerprint(public_key):

Returns the short hex fingerprint of a public key.

def forward_kinematics(joints):

Returns the transform from a serial arm's base to its tool, or the identity for an arm with no joints.

def frame_update_block(envelope, image):

Writes a signed update into one block, for a transport that moves blocks.

The block is the signed manifest and the image behind a header that says where each begins. Nothing in the header is trusted: every rule that decides whether the image runs is still the manifest's.

def gateway_acknowledgment(packet):

Returns the acknowledgment a server owes a datagram, or None for one that needs none.

def gateway_encode(packet):

Writes a datagram to send over a socket.

def gateway_parse(datagram):

Reads a datagram that arrived.

def hdc1080_celsius(raw):

Converts a raw HDC1080 temperature register to degrees Celsius.

def hdc1080_config_from_register(raw):

Parses an HDC1080 configuration register value.

def hdc1080_config_to_register(config):

Assembles an HDC1080 configuration register value.

def hdc1080_conversion_time_micros(config):

Returns how long to wait after triggering an HDC1080 in this configuration.

def hdc1080_humidity_conversion_micros(bits):

Returns how long an HDC1080 humidity conversion takes, in microseconds.

def hdc1080_humidity_register(milli_percent):

Builds the HDC1080 humidity register that decodes to a relative humidity.

def hdc1080_measurement_bytes(temperature_raw, humidity_raw):

Builds the four bytes an HDC1080 sends for a pair of raw registers.

def hdc1080_measurement_from_physical(milli_celsius, milli_percent):

Builds the HDC1080 measurement a sensor reporting these physical values would send.

def hdc1080_milli_celsius(raw):

Converts a raw HDC1080 temperature register to milli-degrees Celsius.

def hdc1080_milli_percent(raw):

Converts a raw HDC1080 humidity register to milli-percent.

def hdc1080_parse_measurement(data):

Parses the four bytes an HDC1080 sequential read returns.

def hdc1080_relative_humidity(raw):

Converts a raw HDC1080 humidity register to a relative humidity percentage.

def hdc1080_serial_id(high, mid, low):

Joins the three HDC1080 serial-ID registers into the 40-bit serial number.

def hdc1080_serial_id_registers(serial):

Splits a serial number back into the three HDC1080 serial-ID registers.

def hdc1080_sim_part():

A simulated HDC1080 reading 22.5 C and 45 %.

def hdc1080_sim_reporting(celsius, relative_humidity):

A simulated HDC1080 that reads what it is asked to, within three thousandths of a degree and two thousandths of a percent.

def hdc1080_temperature_conversion_micros(bits):

Returns how long an HDC1080 temperature conversion takes, in microseconds.

def hdc1080_temperature_register(milli_celsius):

Builds the HDC1080 temperature register that decodes to a temperature.

def hectopascals_to_pascals(hectopascals):

Converts hectopascals to pascals.

def hkdf_sha256_expand(salt, ikm, info, length):

Expands input keying material into length bytes bound to info.

def hmac_sha256_digest(key, message):

Computes a keyed hash over a message.

This is the primitive a host uses to authenticate a pairing exchange or a single command, where a whole session would be more than the job needs.

def i2c_address_frame(address, ten_bit, read):

Returns the address bytes a controller puts on the bus for a transfer.

def i2c_address_frame_len(address, ten_bit):

Returns how many bytes an address frame occupies.

def i2c_address_is_general_call(address, ten_bit):

Reports whether an address is the general call address 0x00.

def i2c_address_is_reserved(address, ten_bit):

Reports whether a 7-bit address falls in a range the I2C specification reserves.

def image_digest(image):

Hashes a complete image, for a publisher filling in a manifest.

def ina219_adc_conversion_micros(code):

Returns how long one INA219 conversion takes at a converter code, in microseconds.

def ina219_address(a1, a0):

Returns the I2C address an INA219's A1 and A0 pin codes select, from Table 1 of its datasheet: 0 for GND, 1 for VS+, 2 for SDA, 3 for SCL.

def ina219_bus_millivolts(raw):

Converts a raw INA219 bus-voltage register to millivolts.

def ina219_bus_register(millivolts):

Builds the INA219 bus-voltage register a monitor reports for a bus voltage.

def ina219_calibration(current_lsb_microamps, shunt_milliohms):

Computes the INA219 calibration register for a shunt and current resolution.

def ina219_config_bits(config):

Assembles the 16-bit INA219 configuration register value.

def ina219_config_from_bits(bits):

Parses a 16-bit INA219 configuration register value.

def ina219_conversion_micros(config):

Returns how long one INA219 conversion cycle takes, in microseconds: the shunt and bus conversions the mode runs, one after the other.

def ina219_conversion_ready(raw):

Reports whether an INA219 bus-voltage register says a conversion is ready.

def ina219_current_microamps(raw, current_lsb_microamps):

Converts a raw INA219 current register to microamps.

def ina219_current_register(microamps, current_lsb_microamps):

Builds the INA219 current register a monitor reports for a current.

def ina219_gain_range_millivolts(code):

Returns the shunt-voltage range an INA219 gain code selects, in millivolts either side of zero.

def ina219_math_overflow(raw):

Reports whether an INA219 bus-voltage register flags a math overflow.

def ina219_minimum_current_lsb_microamps(max_expected_microamps):

Returns the smallest current resolution that still covers an expected maximum.

def ina219_power_microwatts(raw, current_lsb_microamps):

Converts a raw INA219 power register to microwatts.

def ina219_power_register(microwatts, current_lsb_microamps):

Builds the INA219 power register a monitor reports for a power.

def ina219_shunt_microvolts(raw):

Converts a raw INA219 shunt-voltage register to microvolts.

def ina219_shunt_register(microvolts):

Builds the INA219 shunt-voltage register a monitor reports for a shunt voltage.

def ina219_sim_part(address):

A simulated INA219 carrying 500 mA at 12 V through the 100 milliohm shunt a driver starts with.

def ina219_sim_reporting(address, shunt_milliohms, max_microamps, bus_millivolts, microamps):

A simulated INA219 that reads what it is asked to, calibrated for the same shunt and largest current a driver is given.

def ina226_active_alert_function(mask):

Returns the alert function an INA226 pin actually responds to.

def ina226_address(a1, a0):

Returns the I2C address an INA226's A1 and A0 pin codes select.

def ina226_averaging_samples(code):

Returns how many samples an INA226 averaging code folds into one result.

def ina226_bus_microvolts(raw):

Converts a raw INA226 bus-voltage register to microvolts.

def ina226_bus_register(microvolts):

Builds the INA226 bus-voltage register a monitor reports for a bus voltage.

def ina226_bus_volts(raw):

Converts a raw INA226 bus-voltage register to volts.

def ina226_calibration(current_lsb_microamps, shunt_milliohms):

Computes the INA226 calibration register for a shunt and current resolution.

def ina226_config_from_register(raw):

Parses an INA226 configuration register value.

def ina226_config_to_register(config):

Assembles an INA226 configuration register value.

def ina226_conversion_micros(code):

Returns the conversion time an INA226 code selects, in microseconds.

def ina226_current_amps(raw, current_lsb_microamps):

Converts a raw INA226 current register to amps.

def ina226_current_microamps(raw, current_lsb_microamps):

Converts a raw INA226 current register to microamps.

def ina226_current_register(microamps, current_lsb_microamps):

Builds the INA226 current register a monitor reports for a current.

def ina226_current_register_from_shunt(shunt, calibration):

Computes the INA226 current register the chip derives from a shunt reading.

def ina226_die_id(raw):

Splits an INA226 die-ID register into its device and revision fields.

def ina226_identify(manufacturer_id, die_id):

Checks that a pair of identification registers belongs to an INA226.

def ina226_is_continuous(code):

Reports whether an INA226 mode code keeps converting after the first result.

def ina226_mask_enable_from_register(raw):

Parses an INA226 Mask/Enable register value.

def ina226_mask_enable_to_register(mask):

Assembles an INA226 Mask/Enable register value.

def ina226_measures_bus(code):

Reports whether an INA226 mode code converts the bus voltage.

def ina226_measures_shunt(code):

Reports whether an INA226 mode code converts the shunt voltage.

def ina226_minimum_current_lsb_microamps(max_expected_microamps):

Returns the smallest current resolution that still covers an expected maximum.

def ina226_power_microwatts(raw, current_lsb_microamps):

Converts a raw INA226 power register to microwatts.

def ina226_power_register(microwatts, current_lsb_microamps):

Builds the INA226 power register a monitor reports for a power.

def ina226_power_register_from_current(current, bus):

Computes the INA226 power register the chip derives from a current reading.

def ina226_power_watts(raw, current_lsb_microamps):

Converts a raw INA226 power register to watts.

def ina226_shunt_millivolts(raw):

Converts a raw INA226 shunt-voltage register to millivolts.

def ina226_shunt_nanovolts(raw):

Converts a raw INA226 shunt-voltage register to nanovolts.

def ina226_shunt_register(nanovolts):

Builds the INA226 shunt-voltage register a monitor reports for a shunt voltage.

def ina226_sim_part(address):

A simulated INA226 carrying 500 mA at 12 V through the 100 milliohm shunt a driver starts with.

def ina226_sim_reporting(address, shunt_milliohms, max_microamps, bus_microvolts, microamps):

A simulated INA226 that reads what it is asked to, calibrated for the same shunt and largest current a driver is given.

def ina226_update_micros(config):

Returns how often an INA226 in this configuration updates its results.

def j1939_broadcast(priority, pgn, source):

Composes the identifier of a J1939 broadcast, which every node on the bus reads.

Most parameter groups are broadcast, so this is the common case; it saves a caller knowing that a broadcast is addressed to 0xFF.

def j1939_compose(priority, pgn, source, destination):

Composes the extended CAN identifier a set of J1939 fields describes.

The destination is used only for an addressed (PDU1) parameter group and ignored for a broadcast (PDU2) one.

def j1939_decode(id, extended):

Decodes the J1939 fields out of an extended CAN identifier.

Returns None for a standard 11-bit identifier, which J1939 does not use.

def j1939_limits():

Returns the named values J1939 publishes.

The order is the not-available byte, the broadcast address, and the control, default, and lowest priorities.

def json_to_cbor_bytes(json):

Converts a JSON document into its CBOR encoding, which is typically smaller.

def kelvin_to_celsius(kelvin):

Converts kelvin to degrees Celsius.

def keyexpr_canonize(key):

Rewrites a key expression into its canonical form, or None if it is malformed.

def keyexpr_includes(a, b):

Reports whether a selects every key b selects. False if either is malformed.

def keyexpr_intersects(a, b):

Reports whether two key expressions share at least one key, the relation Zenoh routes by. False if either is malformed.

def keyexpr_is_canon(key):

Reports whether a key expression is already in its canonical form.

def keyexpr_is_valid(key):

Reports whether a key expression is well formed.

def keyexpr_join(prefix, suffix):

Joins two key expressions with a / and canonizes the result, or returns None if either side is empty or the joined expression is malformed.

def keyexpr_matches(pattern, key):

Reports whether a pattern selects a key. A chunk that starts with @ is verbatim, and no wildcard selects it.

def kilopascals_to_pascals(kilopascals):

Converts kilopascals to pascals.

def lora_demodulator_snr_db(spreading_factor):

The signal-to-noise ratio the LoRa demodulator needs at a spreading factor, in dB.

def lora_fcc_max_conducted_dbm(antenna_gain_dbi, hopping_channels=None):

The most conducted power 47 CFR 15.247 allows a 902-928 MHz transmitter through an antenna, in dBm.

Without a channel count the transmitter uses digital modulation. A frequency hopping system on fewer than 25 channels comes back as None, because paragraph (b)(2) sets no limit for it.

def lora_free_space_loss_db(distance_m, frequency_hz):

The free-space basic transmission loss between isotropic antennas, in dB.

def lora_fresnel_radius_mm(near_m, far_m, frequency_hz):

The radius of the first Fresnel ellipsoid at a point on a path, in millimeters.

def lora_noise_floor_dbm(bandwidth_hz):

The thermal noise power in a channel, in dBm.

def lorawan_data_block_int_key(root_key):

Derives the key that signs a data block, TS004-2.0.0 section 3.3.

def lorawan_frag_fragment(block, frag_size, n):

Builds one fragment of a session out of a block held whole.

Up to nb_frag the fragment is a piece of the block; past that it is a coded fragment, the exclusive-or of a pseudo-random half of the pieces.

def lorawan_frag_parity_line(coded, nb_frag):

Lists the uncoded fragments a coded one is made of, appendix A.1.

coded counts from one past the uncoded fragments: a session's fragment nb_frag + 1 is coded fragment 1.

def lorawan_frag_prbs23(x):

Steps the pseudo-random sequence the parity matrix is drawn from, appendix A.1.

def lorawan_frag_session(block_len, frag_size):

Says how many fragments a block takes, and how much padding the last one needs.

def lorawan_mac_parse(direction, data):

Reads the commands packed into a frame options field, or a payload sent on port 0.

The same identifier means a different command in each direction, so the direction decides what is read and there is no default.

A command does not carry its own length, so one this build does not know cannot be stepped over. Reading stops there and returns what came before it.

Arguments

  • direction - Uplink or Downlink.
  • data - the options field, or the payload.

Returns

The commands that were readable, in order.

def lorawan_mc_app_s_key(mc_key, mc_addr):

Derives the key that reads a multicast group's payloads, section 4.3.

def lorawan_mc_ke_key(mc_root_key):

Derives the key a multicast group's key travels under, section 4.3.

def lorawan_mc_key(mc_ke_key, wrapped):

Unwraps the group key a setup command carried, section 4.3.

def lorawan_mc_nwk_s_key(mc_key, mc_addr):

Derives the key that verifies a multicast group's frames, section 4.3.

def lorawan_mc_root_key(root_key, lorawan11=False):

Derives a device's multicast root key, TS005-2.0.0 section 4.3.

lorawan11 picks the scheme: LoRaWAN 1.0.x devices derive from their GenAppKey, and 1.1 devices from their AppKey under another constant.

def lorawan_package_encode(command):

Writes one command of an application layer package.

def lorawan_package_parse(port, uplink, payload):

Reads one command of an application layer package.

uplink says which way the frame carrying it traveled, because the same identifier names a different command in each direction. A data fragment takes the whole message, as TS004-2.0.0 section 3 asks, and its bytes come back on data.

def lorawan_package_parse_all(port, uplink, payload):

Reads every command in one message, stopping at an identifier the package does not define.

def lorawan_package_status_item(payload):

Reads one group record of a multicast status answer, TS005-2.0.0 section 4.2.

def lorawan_parse_header(bytes):

Reads a frame far enough to route it, without any key.

A receiver holding many sessions uses this to find which one a frame belongs to: the device address travels in the clear.

def lorawan_parse_join_request(bytes, app_key):

Verifies a join-request and reads the identifiers out of it.

def lorawan_relay_forward_encode(metadata, frequency_hz, phy_payload):

Writes an uplink a relay forwards on port 226, section 9.1.

def lorawan_relay_forward_parse(payload):

Reads an uplink a relay forwarded, section 9.1.

def lorawan_relay_next_wor( synchronization, now_us, device_xtal_ppm, symbol_us, other_channel=False):

Picks the relay scan a synchronized end device aims its next WOR frame at, appendix 1, or None once the drift exceeds a period.

def lorawan_relay_root_wor_s_key(network_key):

Derives an end device's root relay session key from its network session key, TS011-1.0.1 section 4.4.

def lorawan_relay_second_channel(second_channel_index, data_rate, ack_offset, frequency_hz):

Reads the second channel a relay or end device configuration describes, or None when the index is not 1 or the offset is reserved.

def lorawan_relay_synchronization(wor_start_us, preamble_symbols, symbol_us, state):

Works out when a relay scanned from the WOR ACK that answered a frame.

def lorawan_relay_t_offset_ms(scan_start_us, preamble_end_us):

The offset a relay reports in a WOR ACK, appendix 1, or None when the preamble ended before the scan or more than eleven bits of milliseconds after it.

def lorawan_relay_unsynchronized_preamble(cad_periodicity, symbol_us, cad_to_rx):

The WOR preamble of an end device that does not know when the relay scans, section 5.2.

def lorawan_relay_wor_ack(keys, dev_addr, wfcnt, ack, uplink, state):

Builds a relay's WOR ACK, section 6.2.

def lorawan_relay_wor_ack_open(frame, keys, dev_addr, wfcnt, ack, uplink):

Checks and reads a WOR ACK, section 6.2.

def lorawan_relay_wor_join_request(uplink):

Builds the WOR frame ahead of a join request, section 5.3.1.

def lorawan_relay_wor_keys(root_key, dev_addr):

Derives an end device's wake-on-radio keys from its root relay session key, section 4.5.

def lorawan_relay_wor_open(frame, keys, wfcnt, wor):

Checks a WOR frame ahead of a Class A uplink and reads where the uplink follows.

def lorawan_relay_wor_parse(frame):

Reads a WOR frame, leaving an uplink's carrier sealed.

def lorawan_wrap_mc_key(mc_ke_key, mc_key):

Wraps a group key for a device, which is what a server does before sending it.

def mavlink_enum_entry(enumeration, value):

Names the entry of an enumeration that stands for a value, or None if none does.

Raises ValueError if the enumeration is unknown.

def mesh_broadcast_frame(src, id, payload, hop_limit=None):

Builds a mesh frame addressed to every node.

def mesh_crc16(data):

Computes the CRC-16 a mesh frame carries.

def mesh_frame(src, dst, id, payload, hop_limit=None):

Builds a mesh frame addressed to one node.

def mesh_limits():

Returns the frame, payload, and cache sizes a mesh node works within.

The order is the maximum frame length, the maximum payload, the broadcast address, the default hop limit, the duplicate-cache capacity, and the header length.

def mesh_parse_frame(bytes):

Parses a frame received off a radio, rejecting anything the air mangled.

def mesh_relayed(bytes):

Returns the same frame with one hop spent, or None once its hops run out.

def modbus_crc16(data):

Computes the CRC-16/MODBUS that every RTU frame ends with.

def modbus_parse_frame(data):

Parses a received RTU frame, verifying its CRC.

def modbus_raw(address, function_code, data):

Builds a request frame from a raw function code and data.

This is the escape hatch for the function codes the SDK does not name.

def modbus_read_coils(address, start, count):

Builds a read-coils request frame (function 0x01).

def modbus_read_discrete_inputs(address, start, count):

Builds a read-discrete-inputs request frame (function 0x02).

def modbus_read_holding_registers(address, start, count):

Builds a read-holding-registers request frame (function 0x03).

def modbus_read_holding_registers_reply(address, values):

Builds the reply a device sends to a read-holding-registers request.

def modbus_read_input_registers(address, start, count):

Builds a read-input-registers request frame (function 0x04).

def modbus_read_input_registers_reply(address, values):

Builds the reply a device sends to a read-input-registers request.

def modbus_write_multiple_coils(address, start, values):

Builds a write-multiple-coils request frame (function 0x0F).

def modbus_write_multiple_registers(address, start, values):

Builds a write-multiple-registers request frame (function 0x10).

def modbus_write_single_coil(address, coil, on):

Builds a write-single-coil request frame (function 0x05).

def modbus_write_single_register(address, register, value):

Builds a write-single-register request frame (function 0x06).

def obstacle_stop(twist, range_m, stop_distance_m):

Cuts forward and sideways motion when an obstacle is within stop_distance_m, keeping the turn. A range that is not a number counts as an obstacle.

def open_delegation(data, anchor_public_key):

Opens a signed delegation against the anchor that should have signed it.

def opt3001_config_bits(config):

Assembles the 16-bit OPT3001 configuration register value.

def opt3001_config_from_bits(bits):

Parses a 16-bit OPT3001 configuration register value.

def opt3001_conversion_millis(long_conversion):

Returns the conversion time an OPT3001 setting selects, in milliseconds.

def opt3001_fault_count(code):

Returns how many consecutive faults an OPT3001 fault-count code requires.

def opt3001_full_scale_milli_lux(range_number):

Returns the full scale an OPT3001 range number covers, in milli-lux.

def opt3001_is_automatic_range(range_number):

Reports whether an OPT3001 range number sets the full scale automatically.

def opt3001_lsb_milli_lux(exponent):

Returns the illuminance one count carries at an OPT3001 exponent.

def opt3001_lux(raw):

Converts a raw OPT3001 result register to lux.

def opt3001_milli_lux(raw):

Converts a raw OPT3001 result register to milli-lux.

def opt3001_raw_from_milli_lux(milli_lux):

Builds the OPT3001 result register that decodes to an illuminance.

def opt3001_sim_part(address):

A simulated OPT3001 reading 380 lux, its conversion-ready flag set.

def opt3001_sim_reporting(address, lux):

A simulated OPT3001 that reads what it is asked to, to the nearest step its exponent and mantissa represent.

def opt3001_word_from_bytes(data):

Reads the two bytes an OPT3001 sends for a register.

def opt3001_word_to_bytes(word):

Builds the two bytes an OPT3001 sends for a register.

def pascals_to_hectopascals(pascals):

Converts pascals to hectopascals.

def pascals_to_kilopascals(pascals):

Converts pascals to kilopascals.

def pascals_to_psi(pascals):

Converts pascals to pounds per square inch.

def pca9685_channel_register(channel):

Returns the first of a PCA9685 channel's four consecutive registers.

def pca9685_frequency_for_prescale(prescale, osc_hz):

Returns the update rate a PCA9685 prescale value produces, in hertz.

def pca9685_limits():

Returns the PCA9685 constants a caller sizes its arithmetic against.

The tuple is the internal oscillator frequency in hertz, the channel count, and the counts per period.

def pca9685_prescale_for_frequency(update_rate_hz, osc_hz):

Returns the prescale value that sets a PCA9685 update rate.

def pca9685_sim_part(address):

A simulated PCA9685 as it powers up: asleep at 200 Hz with every output off, keeping its datasheet's rules for writes, reads, and its register pointer.

def percent_to_ratio(percent):

Converts a percentage to a ratio from 0 to 1.

def pin_edge_triggered_by(edge, before, after):

Reports whether a change from one level to another fires an interrupt trigger.

def pin_level_from_bool(high):

Returns the level a boolean names, as "Low" or "High".

def pin_level_inverted(level):

Returns the opposite level, as "Low" or "High".

def pin_polarity_is_asserted(polarity, level):

Reports whether a physical level means the signal is asserted.

def pin_polarity_level(polarity, asserted):

Returns the physical level that represents a logical state under a polarity.

def psi_to_pascals(psi):

Converts pounds per square inch to pascals.

def pwm_counts(data):

Reads a PCA9685 setting back from the four register bytes a channel holds.

def pwm_duty(off):

Builds a channel's register bytes with no phase delay: on at 0, off at off.

The datasheet rules out the same count in on and off, so 0 is the full-off setting and 4096 or more the full-on one.

def pwm_from_counts(on, off):

Builds a channel's four register bytes from explicit on and off counts.

def pwm_full_off():

The register bytes that hold a channel continuously low, the power-on state.

def pwm_full_on():

The register bytes that hold a channel continuously high.

def pwm_servo(pulse_micros, update_rate_hz):

Builds the register bytes that drive a hobby servo to a given pulse width.

def ratio_to_percent(ratio):

Converts a ratio from 0 to 1 to a percentage.

def ros2_dds_topic(fqn, kind):

Returns the DDS topic a fully qualified name maps onto, or None if the name is not fully qualified.

def ros2_dds_type_name(ros_type):

Returns the DDS type name an interface type maps onto, or None if the type is not a valid package/namespace/Type.

def ros2_entity_key(domain_id, fqn, ros_type, type_hash):

Builds the Zenoh key an rmw_zenoh peer publishes an entity on, or None if the name, type, or hash is not usable.

def ros2_entity_kind_prefix(kind):

Returns the DDS topic prefix a subsystem uses.

def ros2_entity_kind_suffix(kind):

Returns what the middleware appends to a name for a subsystem: nothing for a topic, Request for a service request, and Reply for a service response.

def ros2_is_fully_qualified(name):

Reports whether a name is fully qualified, so it resolves with no namespace.

def ros2_is_valid_name(name):

Reports whether a string is a valid ROS 2 topic or service name.

def ros2_percent_mangle(name):

Percent-mangles a name as rmw_zenoh writes it in a liveliness token, each / as %.

def ros2_twist_from_cdr(data):

Decodes a twist from its CDR representation, or None if the bytes are not a well-formed twist.

Returns the linear and angular velocities as two (x, y, z) triples.

def ros2_twist_to_cdr(linear, angular):

Encodes a twist into its CDR representation.

The linear and angular velocities each cross as an (x, y, z) triple.

def ros2_type_hash_digest(text):

Returns the 32-byte digest a RIHS01 hash string carries, or None if the string is malformed.

def routing_default_capacity():

Returns a routing table size for a caller with no reason to choose one.

def scd4x_allowed_during_measurement(command):

Reports whether an SCD4x accepts a command while it is measuring.

def scd4x_ambient_pressure_pascals(word):

Converts an SCD4x ambient-pressure word back to pascals.

def scd4x_ambient_pressure_word(pascals):

Builds the SCD4x word that programs an ambient pressure.

def scd4x_automatic_self_calibration_enabled(word):

Reports whether an SCD4x word says automatic self-calibration is on.

def scd4x_automatic_self_calibration_word(enabled):

Builds the SCD4x word that turns automatic self-calibration on or off.

def scd4x_celsius(raw):

Converts a raw SCD4x temperature word to degrees Celsius.

def scd4x_command_frame(command):

Builds the two bytes that send a bare SCD4x command.

def scd4x_crc(data):

Computes the CRC-8 an SCD4x appends to every data word.

def scd4x_data_ready(word):

Reports whether an SCD4x data-ready word says a measurement is waiting.

def scd4x_forced_recalibration_correction_ppm(word):

Reads the correction an SCD4x reports after a forced recalibration.

def scd4x_forced_recalibration_word(correction_ppm=None):

Builds the word an SCD4x returns for a forced-recalibration outcome.

def scd4x_humidity_milli_percent(raw):

Converts a raw SCD4x humidity word to milli-percent.

def scd4x_humidity_raw(milli_percent):

Builds the SCD4x humidity word that decodes to a relative humidity.

def scd4x_max_duration_ms(command):

Returns how long an SCD4x command may take, in milliseconds.

def scd4x_measurement_bytes(co2_ppm, temperature_raw, humidity_raw):

Builds the nine bytes an SCD4x sends for a set of raw words.

def scd4x_measurement_from_physical(co2_ppm, milli_celsius, humidity_milli_percent):

Builds the SCD4x measurement a sensor reporting these physical values would send.

def scd4x_milli_celsius(raw):

Converts a raw SCD4x temperature word to milli-degrees Celsius.

def scd4x_parse_measurement(frame):

Parses and CRC-checks a nine-byte SCD4x measurement frame.

def scd4x_relative_humidity_percent(raw):

Converts a raw SCD4x humidity word to a relative humidity percentage.

def scd4x_self_test_passed(word):

Reports whether an SCD4x self-test word says the part passed.

def scd4x_serial_number(frame):

Reads a CRC-checked nine-byte SCD4x serial-number frame.

def scd4x_serial_number_frame(serial):

Builds the nine bytes an SCD4x sends for a serial number.

def scd4x_sim_part():

A simulated SCD4x reading 800 ppm, 22.5 C, and 45 %, always with a result waiting.

def scd4x_sim_reporting(co2_ppm, celsius, relative_humidity):

A simulated SCD4x that reads what it is asked to.

def scd4x_temperature_offset_milli_celsius(word):

Converts an SCD4x temperature-offset word back to milli-degrees Celsius.

def scd4x_temperature_offset_word(milli_celsius):

Builds the SCD4x word that programs a temperature offset.

def scd4x_temperature_raw(milli_celsius):

Builds the SCD4x temperature word that decodes to a temperature.

def scd4x_word(frame):

Reads a CRC-checked three-byte SCD4x word frame.

def scd4x_word_frame(value):

Builds the three bytes an SCD4x sends for a word: the word then its CRC.

def scd4x_write_frame(command, value):

Builds the five bytes that send an SCD4x command with an argument.

def serial_bits_per_character(baud, parity, stop_bits):

Returns the bits one character takes on the wire: a start bit, eight data bits, the parity bit if there is one, and the stop bits.

def serial_character_nanos(baud, parity, stop_bits):

Returns how long one character takes on the wire, in nanoseconds, rounded up.

def serial_framing_bytes():

Returns the reserved framing bytes: SLIP end, escape, the two escape codes, and the COBS delimiter.

def serial_transfer_micros(baud, parity, stop_bits, count):

Returns how long count bytes sent back to back take on the wire, in microseconds, rounded up.

def sht3x_celsius(raw):

Converts a raw SHT3x temperature word to degrees Celsius.

def sht3x_crc(data):

Computes the CRC-8 an SHT3x appends to every data word.

def sht3x_fahrenheit(raw):

Converts a raw SHT3x temperature word to degrees Fahrenheit.

def sht3x_humidity_raw_from_milli_percent(milli_percent):

Builds the SHT3x humidity word that decodes to a relative humidity.

def sht3x_humidity_raw_from_relative_humidity(percent):

Builds the SHT3x humidity word that decodes to a relative humidity percentage.

def sht3x_interval_micros(rate):

Returns the gap between SHT3x periodic measurements, in microseconds.

def sht3x_max_measurement_micros(repeatability):

Returns how long an SHT3x measurement may take, in microseconds.

def sht3x_measurement_bytes(temperature_raw, humidity_raw):

Builds the six bytes an SHT3x sends for a pair of raw words.

def sht3x_milli_celsius(raw):

Converts a raw SHT3x temperature word to milli-degrees Celsius.

def sht3x_milli_fahrenheit(raw):

Converts a raw SHT3x temperature word to milli-degrees Fahrenheit.

def sht3x_milli_percent(raw):

Converts a raw SHT3x humidity word to milli-percent.

def sht3x_parse_measurement(frame):

Parses and CRC-checks a six-byte SHT3x measurement frame.

def sht3x_parse_status(frame):

Parses and CRC-checks a three-byte SHT3x status frame.

def sht3x_periodic(repeatability, rate):

Returns the SHT3x periodic-mode command for a repeatability and rate.

def sht3x_relative_humidity(raw):

Converts a raw SHT3x humidity word to a relative humidity percentage.

def sht3x_sim_part(address):

A simulated SHT3x reading 22.5 C and 45 %.

def sht3x_sim_reporting(address, celsius, relative_humidity):

A simulated SHT3x that reads what it is asked to, within three thousandths of a degree and two thousandths of a percent.

def sht3x_single_shot(repeatability, clock_stretching):

Returns the SHT3x single-shot command for a repeatability and clock mode.

def sht3x_status_bytes(bits):

Builds the three bytes an SHT3x sends for a status word, CRC last.

def sht3x_status_from_bits(bits):

Splits an SHT3x status word into its flags.

def sht3x_temperature_raw_from_celsius(celsius):

Builds the SHT3x temperature word that decodes to a temperature in Celsius.

def sht3x_temperature_raw_from_milli_celsius(milli_celsius):

Builds the SHT3x temperature word that decodes to a temperature.

def sht3x_temperature_raw_from_milli_fahrenheit(milli_fahrenheit):

Builds the SHT3x temperature word that decodes to a temperature in Fahrenheit.

def sht3x_typical_measurement_micros(repeatability):

Returns how long an SHT3x measurement typically takes, in microseconds.

def sht3x_word(frame):

Reads a CRC-checked three-byte SHT3x word frame.

def sht3x_word_bytes(value):

Builds the three bytes an SHT3x sends for a word: the word then its CRC.

def sign_delegation(delegation, anchor):

Signs a delegation, naming a release key the anchor stands behind.

def sign_manifest(manifest, author):

Signs a manifest into the envelope that is offered to a device.

def slip_decode(frame):

Reads the payload back out of a SLIP frame.

def slip_encode(payload):

Frames a payload as a SLIP packet (RFC 1055).

def slip_max_encoded_len(payload_len):

Returns the largest SLIP frame a payload of this length can produce.

def spi_mode_clock(mode):

Returns the (CPOL, CPHA) pair an SPI mode number names.

def spi_mode_from_clock(cpol, cpha):

Returns the SPI mode number a (CPOL, CPHA) pair names.

def split_update_block(block):

Reads a block back into the signed manifest and the image.

Raises when the block does not carry this convention's header.

def station_discovery(router):

Writes the request a station sends to find its network server.

def station_discovery_parse(text):

Reads the request a station sent to find its network server, as the server does, and returns the station asking as sixteen hexadecimal digits.

def station_encode(message):

Writes a message of any kind the way the websocket carries it.

def station_eui_of(text):

Reads an identifier written in any form the protocol accepts.

def station_heard(frame, data_rate, frequency_hz, levels=None):

Reads a frame the radio heard into the message that reports it.

def station_id6(eui):

Writes an identifier in the ID6 form the protocol prefers.

def station_parse(text):

Reads a message that arrived over the websocket.

def station_router_accepted(router, muxs, uri):

Writes the answer that sends a station to the websocket its session runs on.

def station_router_parse(text):

Reads the answer a discovery endpoint gives.

def station_router_refused(router, error):

Writes the answer that refuses a station, saying why.

def station_xtime(unit, session, micros):

Builds a station clock value from the radio it was read on, the run of the station, and the microseconds that run had counted.

def station_xtime_parts(xtime):

Takes a station clock value apart into its radio unit, run, and microseconds.

def stepper_step_count(drive):

Returns how many steps make up one electrical cycle of a drive pattern.

def stepper_steps_for_degrees(degrees, steps_per_revolution):

Returns how many steps a rotation of degrees takes on a given motor.

def stepper_timing():

Returns the timing a stepper driver starts with, in microseconds.

The tuple is the pause after each step, then how long a step and direction driver holds the direction before a step pulse, and the pulse itself.

def sx126x_calibrate_image(low_hz, high_hz):

CalibrateImage over a band given by its edges in hertz.

def sx126x_clear_irq_status(irq):

ClearIrqStatus for a set of interrupts.

def sx126x_constants():

The SX126x constants: the continuous receive word, the sync words and their register, and every IRQ and device error bit, by name.

def sx126x_device_errors(answer):

Decodes a GetDeviceErrors answer into its error bits.

Raises ValueError unless the answer is two bytes.

def sx126x_frequency_word(frequency_hz):

The word SetRfFrequency takes for a frequency in hertz.

def sx126x_get_device_errors():

GetDeviceErrors, answered by the two device error bytes.

def sx126x_get_irq_status():

GetIrqStatus, answered by the two IRQ bytes.

def sx126x_get_packet_status():

GetPacketStatus, answered by the three LoRa signal level bytes.

def sx126x_get_rssi_inst():

GetRssiInst, answered by the instantaneous RSSI byte.

def sx126x_get_rx_buffer_status():

GetRxBufferStatus, answered by the payload length and its offset.

def sx126x_get_status():

GetStatus, answered by the status byte.

def sx126x_image_calibration(low_hz, high_hz):

The two CalibrateImage codes that cover a band given by its edges in hertz.

def sx126x_irq(answer):

Decodes a GetIrqStatus answer into its IRQ bits.

Raises ValueError unless the answer is two bytes.

def sx126x_llcc68_supports(link):

Reports whether an LLCC68 supports a link's spreading factor at its bandwidth: up to SF9 at 125 kHz, SF10 at 250 kHz, and SF11 at 500 kHz.

def sx126x_packet_status(answer):

Decodes a LoRa GetPacketStatus answer.

Raises ValueError unless the answer is three bytes.

def sx126x_ramp_time_us(at_least_us):

The shortest amplifier ramp time the chip offers that lasts at least a duration, in microseconds.

def sx126x_read_buffer(offset, length):

ReadBuffer for a run of the data buffer.

def sx126x_read_register(address, length):

ReadRegister for a run of consecutive registers.

def sx126x_rssi_inst_dbm(byte):

Decodes a GetRssiInst answer, in dBm.

def sx126x_rx_buffer_status(answer):

Decodes a GetRxBufferStatus answer.

Raises ValueError unless the answer is two bytes.

def sx126x_set_dio_irq_params(irq, dio1, dio2=0, dio3=0):

SetDioIrqParams: which interrupts are enabled, and which DIO lines raise them.

def sx126x_set_lora_modulation_params(link):

SetModulationParams for a LoRa link.

Raises PamojaError when the link's bandwidth is not one the SX126x offers.

def sx126x_set_lora_packet_params(link, payload_len, invert_iq):

SetPacketParams for a LoRa link, a payload length, and an IQ polarity.

def sx126x_set_pa_config(power):

SetPaConfig for a power setting.

def sx126x_set_packet_type_lora():

SetPacketType for LoRa.

def sx126x_set_rf_frequency(frequency_hz):

SetRfFrequency for a carrier frequency in hertz.

def sx126x_set_rx(timeout_us):

SetRx with a timeout in microseconds; 0 listens for one packet with no timeout.

def sx126x_set_rx_continuous():

SetRx in continuous mode, receiving packet after packet until another command.

def sx126x_set_sleep(warm_start):

SetSleep without an RTC wake-up; a warm start keeps the configuration in retention.

def sx126x_set_standby():

SetStandby into STDBY_RC.

def sx126x_set_tx(timeout_us):

SetTx with a timeout in microseconds; 0 disables the timeout.

def sx126x_set_tx_params(power, ramp_us):

SetTxParams for a power setting and the least ramp time wanted, in microseconds.

def sx126x_status(byte):

Decodes a status byte.

def sx126x_timeout_steps(timeout_us):

The 24-bit timeout word SetTx and SetRx take for a duration in microseconds.

def sx126x_tx_power(amplifier, output_dbm):

The amplifier settings for an output power, clamped to what the amplifier allows.

def sx126x_tx_power_under_ceiling(amplifier, budget, eirp_ceiling_dbm):

The amplifier settings that keep a link's EIRP at or under a ceiling, rounded down to whole decibels.

def sx126x_write_buffer(offset, payload):

A whole WriteBuffer transaction: the opcode, the offset, and the payload.

def sx126x_write_register(address, values):

A whole WriteRegister transaction: the opcode, the address, and the values.

def sx127x_automatic_if(current, automatic_if):

RegDetectOptimize with AutomaticIFOn set or clear.

def sx127x_constants():

The SX127x register values with a name: the version, the write bit, the DIO0 mappings, the amplifier and calibration bits, the sync words, and the LNA and TCXO settings.

def sx127x_frequency_from_word(word):

The frequency in hertz an SX127x RegFrf word selects.

def sx127x_frequency_word(frequency_hz):

The 24-bit RegFrf word an SX127x takes for a frequency in hertz.

def sx127x_fsk_op_mode(mode):

The RegOpMode value for an FSK operating mode, which image calibration needs.

Raises ValueError for a name that is not a mode.

def sx127x_high_bw_optimize(link, frequency_hz):

The writes of the 500 kHz sensitivity erratum for a link at a carrier.

Raises PamojaError when the SX127x has no such bandwidth.

def sx127x_image_cal_start(current):

RegImageCal with a calibration started and the automatic recalibration off.

def sx127x_invert_iq(receive, transmit):

RegInvertIQ for the IQ polarity of each path.

def sx127x_invert_iq_2(inverted):

RegInvertIQ2 for the path in use.

def sx127x_irq_flags():

The SX127x LoRa interrupt flags, by name.

def sx127x_lora_op_mode(mode):

The RegOpMode value for a LoRa operating mode, named as in Sx127xMode.

Raises ValueError for a name that is not a mode.

def sx127x_mode_from_op_mode(op_mode):

The name of the operating mode a RegOpMode value holds.

def sx127x_modem(link, frequency_hz, symbol_timeout):

The LoRa modem registers for a link at a carrier, with a single reception timeout in symbols.

Raises PamojaError when the SX127x cannot use the link at the carrier.

def sx127x_modem_status(byte):

Decodes RegModemStat.

def sx127x_ocp_register(milliamps):

RegOcp for a current limit in milliamps.

def sx127x_packet_status(answer, frequency_hz):

Decodes RegPktSnrValue and RegPktRssiValue, read together, for a packet heard at a carrier.

Raises ValueError when the answer is not two bytes.

def sx127x_read_address(address):

The SX127x address byte that reads a register.

def sx127x_registers():

The SX127x register addresses, by name.

def sx127x_rssi_dbm(byte, frequency_hz):

Decodes RegRssiValue for a receiver tuned to a carrier, in dBm.

def sx127x_spurious_reception(link):

The receive settings of the spurious reception erratum for a link.

Raises PamojaError when the SX127x has no such bandwidth.

def sx127x_symbol_timeout(link, timeout_us):

The SX127x single reception timeout for a duration in microseconds, in the link's symbols.

def sx127x_tx_power(output, output_dbm):

The SX127x amplifier settings for an output power on an output named "Rfo" or "PaBoost".

Raises ValueError for another output name.

def sx127x_tx_power_under_ceiling(output, budget, eirp_ceiling_dbm):

The SX127x amplifier settings that keep a link's EIRP at or under a ceiling in dBm.

Raises ValueError for an output name other than "Rfo" or "PaBoost".

def sx127x_write_address(address):

The SX127x address byte that writes a register.

def tilt_from_accel(ax, ay, az):

Computes roll and pitch from a three-axis accelerometer at rest; the reading's unit does not matter, since only the ratios between axes set the angles.

def tmp117_averaging_conversions(code):

Returns how many conversions a TMP117 averaging code folds into one result.

def tmp117_averaging_micros(code):

Returns how long a TMP117 averaging code takes to convert, in microseconds.

def tmp117_celsius(raw):

Converts a raw TMP117 temperature register to degrees Celsius.

def tmp117_config_bits(config):

Assembles the 16-bit TMP117 configuration register value.

def tmp117_config_from_bits(bits):

Parses a 16-bit TMP117 configuration register value.

def tmp117_cycle_micros(cycle, averaging):

Returns the TMP117 result-update interval for a cycle and averaging code.

def tmp117_cycle_nominal_micros(code):

Returns the nominal cycle a TMP117 conversion-cycle code selects, in microseconds.

def tmp117_data_ready(config):

Reports whether a TMP117 configuration register says a result is ready.

def tmp117_device_id(raw):

Reads the device identifier out of a TMP117 device-ID register.

def tmp117_eeprom_busy(config):

Reports whether a TMP117 configuration register says an EEPROM write is running.

def tmp117_eeprom_unlock_busy(unlock):

Reports whether a TMP117 EEPROM unlock register says a write is running.

def tmp117_high_alert(config):

Reports whether a TMP117 configuration register flags a high alert.

def tmp117_low_alert(config):

Reports whether a TMP117 configuration register flags a low alert.

def tmp117_micro_celsius(raw):

Converts a raw TMP117 temperature register to micro-degrees Celsius.

def tmp117_nano_celsius(raw):

Converts a raw TMP117 temperature register to nano-degrees Celsius.

def tmp117_raw_from_celsius(celsius):

Builds the TMP117 temperature register that decodes to a temperature in Celsius.

def tmp117_raw_from_micro_celsius(micro_celsius):

Builds the TMP117 temperature register that decodes to a temperature.

def tmp117_revision(raw):

Reads the die revision out of a TMP117 device-ID register.

def tmp117_sim_part(address):

A simulated TMP117 reading 21.25 C, its configuration register keeping the flags the part sets for itself, with the data-ready flag set.

def tmp117_sim_reporting(address, celsius):

A simulated TMP117 that reads what it is asked to, to the nearest 7.8125 millidegrees.

def tmp117_temperature_bytes(raw):

Builds the two bytes a TMP117 sends for a temperature register.

def tmp117_temperature_from_bytes(data):

Reads the two bytes a TMP117 sends for a temperature register.

def update_block_descriptor():

What a transport calls a block carrying a signed update, for a field that names the convention.

def update_format_raw():

The payload format meaning the payload is the image itself, byte for byte.

def update_structure_version():

The manifest structure version this build writes.

def verify(public_key, payload, signature):

Verifies that a signature covers a payload and was made by a public key.

Returns False when the payload was altered or was signed by a different device, and raises only when an argument is the wrong length.

def verify_audit_chain(public_key, entries):

Checks a whole chain that has already arrived.

Raises with the reason if any entry fails to follow the one before it or carries a signature that does not hold.

def verify_envelope(data, public_key):

Verifies an envelope against a key and reads the manifest inside it.

Raises when the signature is not from that key.

def verify_message(public_key, message):

Verifies a signed message and returns the payload it carries.

Returns None when the message is too short to hold a signature, was altered, or was signed by a different device.

def version():

Returns the version of the native pamoja module.

def window_capacity():

The most readings a windowed helper keeps, and the number it keeps unless told fewer.