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.
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:
nanovolts
The voltage in nanovolts, exact in integer arithmetic.
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.
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.
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.
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.
CHIRPSTACK_UPLINK_TOPIC =
'application/+/device/+/event/up'
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.
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):
def
write_f64(self, /, value):
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
link_settings(self, /, data_rate):
Returns the radio settings an uplink data rate selects, ready to hand to
airtime_us, or None if the number is reserved or not carried by LoRa.
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
downlink_channel_frequency_hz(self, /, channel):
Returns the frequency of a numbered downlink channel, or None past the last.
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.
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:
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.
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.
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.
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.
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
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
uplink(self, /, heard):
Reads a packet the gateway forwarded.
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.
snr_db
Its signal-to-noise ratio in dB.
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.
data_rate
The data rate it arrived at.
frequency_hz
The frequency it arrived on, in hertz.
class
GatewayRxpk:
A packet the gateway heard, with the metadata the protocol carries beside it.
link
The spreading factor, bandwidth, and coding rate, for a LoRa packet.
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.
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.
class
GatewaySlot:
Where and when a downlink answers an uplink, in the concentrator's own terms.
link
The settings to transmit with.
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.
downlinks
How many downlink datagrams it received.
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.
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.
frequency_hz
The frequency to transmit on, in hertz.
gpstime
The GPS time to transmit at.
rctx
The radio to transmit on.
class
GatewayStationDataRate:
One number of a configuration's data-rate table.
downlink_only
Whether the rate is used only for downlinks.
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.
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.
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.
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.
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.
link
The spreading factor, bandwidth, and coding rate, for a LoRa packet.
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.
without_crc
Whether to leave the physical CRC off, as LoRaWAN downlinks are.
rf_chain
The radio chain to transmit from.
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
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.
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.
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.
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.
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.
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.
shunt_millivolts
The shunt voltage in millivolts.
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.
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.
LORAWAN_ADR_ACK_DELAY =
32
LORAWAN_ADR_ACK_LIMIT =
64
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_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
uplink(self, /, transport):
Adds a rung that only sends, tried after the rungs already added.
The ladder sends over it in its turn but never subscribes it or listens on
it, whatever the transport could do: a satellite messenger, a LoRa uplink, or
any link a node reports over but takes no commands from. The transport is
consumed.
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.
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
link(self, /):
Creates a link to this broker, for driving directly.
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.
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.
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
LoraLink:
The radio settings of a LoRa link.
def
symbol_time_us(self, /):
The duration of one symbol on this link, in microseconds.
def
low_data_rate_optimization(self, /):
Whether the link uses low data rate optimization.
It is on when a symbol lasts longer than 16 ms, which is SF11 and SF12 at 125 kHz
and SF12 at 250 kHz. The airtime assumes it, so a radio set up from these settings
must turn it on too.
def
airtime_us(self, /, payload_len):
The time on air of a payload, in microseconds.
This is the channel occupancy a transmission costs, which sets both the
duty-cycle budget and most of the energy the transmission spends.
def
min_off_time_us(self, /, payload_len, duty_cycle_permille):
The minimum silence after a transmission to honor a duty-cycle limit.
The limit is in parts per thousand, so 10 is 1%. A limit of 0 forbids
transmitting at all, which comes back as None, and one of 1000 or more, the whole
of the time, owes no silence.
def
messages_per_hour(self, /, payload_len, duty_cycle_permille):
How many transmissions of a payload fit in an hour under a duty-cycle limit.
A transmission really costs its airtime plus the silence the limit forces after
it. A limit of 0 forbids transmitting, which comes back as 0.
spreading_factor
The spreading factor, 5 (fastest) to 12 (longest range).
bandwidth_hz
The channel bandwidth in hertz, such as 125_000.
preamble_symbols
The preamble length in symbols; the LoRa default is 8.
coding_rate_denominator
The coding-rate denominator, 5 to 8, for 4/5 to 4/8.
crc
Whether the frame carries a CRC.
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.
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.
downlink_data_rate_count
How many downlink data-rate numbers 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.
uplink_data_rate_count
How many uplink data-rate numbers the plan defines, reserved included.
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.
downlink_channel_block_count
How many downlink channel blocks the plan defines.
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
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.
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.
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.
link
The spreading factor, bandwidth, coding rate, preamble, header, and CRC.
output_dbm
The output power the amplifier was asked for, in dBm.
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.
link
The LoRa settings to listen with.
class
LorawanAcknowledgment:
The acknowledgment a relay answers a wake-on-radio frame with.
airtime_us
How long it holds the air, in microseconds.
start_us
When to start sending it, in microseconds.
link
Its LoRa settings, sent with inverted IQ.
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.
def
uplink(self, /, at_default_data_rate):
Counts one new uplink, and says what to do before sending it.
Call it once per uplink the frame counter moves for, passing whether the device is
already at its default data rate. A repeat of the same uplink does not count.
def
downlink(self, /):
Counts a Class A downlink, which proves the network still hears the device and
resets the count.
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.
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.
uplink_hz
Where uplinks go out, in hertz.
min_data_rate
The slowest data rate the channel carries.
downlink_hz
Where the first receive window listens, in hertz.
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.
link_check
The answer to a link check the device asked for, as the margin in dB and the gateway
count, or None.
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.
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.
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_link_check(self, /):
Asks the network, with the next uplink, how well it hears the device.
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
LorawanForwardedUplink:
An end device's uplink as a relay forwards it on port 226.
frequency_hz
The frequency it arrived on, in hertz.
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
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.
link
Its LoRa settings, heard with standard IQ.
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.
global_uplink_reload_rate
Uplinks a relay forwards an hour across every trusted end device.
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.
uplink_frequency_exists
Whether the channel already had an uplink frequency to pair a downlink with.
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.
global_uplink_bucket_size
The global uplink bucket size multiplier.
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.
uplink_dwell
Whether an uplink is held to 400 ms of air time.
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.
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.
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.
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
heard_uplink(self, /, frame, rssi_dbm, snr_db, ended_us):
Reads the uplink a wake-on-radio frame announced, and holds it to forward.
Returns when to forward it: fifty milliseconds after it ended.
def
uplink_missed(self, /):
Clears the uplink a wake-on-radio frame announced, once listening heard nothing.
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.
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.
uplink_start_us
When the uplink itself goes out, in microseconds, whether or not the acknowledgment
arrives.
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.
downlink
The downlink to send the end device on, for downlink.
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.
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
LorawanRxrDownlink:
A downlink for an end device, to send in its relay window.
link
Its LoRa settings, sent with inverted IQ and a payload CRC.
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.
airtime_us
How long it holds the air, in microseconds.
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.
link
The LoRa settings of a wake-on-radio frame, heard with inverted IQ.
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
encode_uplink( self, /, fcnt, fport, payload, confirmed=False, adr=False, ack=False, fopts=None, adr_ack_req=False):
Encodes an uplink, encrypting the payload and appending the MIC.
adr_ack_req asks the network to answer, which a device running adaptive data
rate does once it has gone too long without hearing it.
def
encode_downlink( self, /, fcnt, fport, payload, confirmed=False, adr=False, ack=False, fpending=False, fopts=None):
Encodes a downlink, encrypting the payload and appending the MIC.
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.
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.
link
The LoRa settings: an eight-symbol preamble, an explicit header and a payload CRC,
sent with standard IQ.
rx1
The first receive window.
data_rate
The data rate, as the region numbers them.
output_dbm
The power to ask of the radio, conducted, in dBm.
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.
link
Its LoRa settings, with the preamble this frame needs, sent with inverted IQ.
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.
delay_us
How long after the end of the transmission the window opens, in microseconds.
link
The LoRa settings to listen with: no payload CRC, and inverted IQ, as RP002-1.0.5 table
112 has for a downlink.
data_rate
The downlink data rate, as the region numbers them.
class
LorawanWor:
A wake-on-radio frame, as a relay reads it.
dev_addr
The address an uplink WOR names.
wfcnt
The low sixteen bits of its frame counter.
uplink
Where and how fast a join request follows; an uplink's carrier stays sealed until
lorawan_relay_wor_open reads it.
class
LorawanWorKeys:
The integrity and encryption keys of one end device's wake-on-radio frames, TS011-1.0.1.
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.
uplink
True to send the uplink at the time the exchange named anyway.
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.
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.
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
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.
link_id
Which link this signer signs on.
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
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.
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.
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_holding_registers(self, /, unit, start, quantity):
Reads holding registers, function 0x03.
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.
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_holding_registers(self, /, start, values):
Sets holding 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
holding_register(self, /, address):
A holding 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.
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.
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.
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.
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.
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.
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.
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.
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, /):
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_milli_percent
The relative humidity in milli-percent.
class
SealedMessage:
A message that has been sealed, with the header that travels beside it.
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
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.
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.
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.
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.
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_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.
rx_ongoing
A reception is under way.
class
Sx127xPacketStatus:
The signal levels of a packet an SX127x received.
snr_db
The estimated signal-to-noise ratio, in dB.
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.
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
Trend:
Fits a line through recent readings, so a slow drift is visible before it matters.
def
push(self, /, 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
chirpstack_uplink_topic(application_id):
Builds the MQTT topic an application's uplink events are published on, with a wildcard in
place of the device: application/<id>/device/+/event/up.
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
link_cost_threshold(cost):
Returns the level a named link cost calls for.
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_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_relay_wor_uplink(keys, dev_addr, wfcnt, uplink, wor):
Builds the WOR frame ahead of a Class A uplink, section 5.3.2.
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_crc16_mcrf4xx(data):
Returns the CRC-16/MCRF4XX checksum of a byte string.
This is the checksum every MAVLink frame carries, exposed because a host that
implements part of the protocol itself needs the same arithmetic.
def
mavlink_enum_entries(enumeration):
Returns every entry of an enumeration as (name, value) pairs, in dialect
order.
Raises ValueError if the enumeration is unknown.
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
mavlink_enum_is_bitmask(enumeration):
Reports whether an enumeration's values combine as bits.
Raises ValueError if the enumeration is unknown.
def
mavlink_enum_names(enumeration, value):
Names the entries a value is made of: for a bitmask, each entry whose bits
are set in it, in dialect order; otherwise the one entry that names it.
Empty when none applies.
Raises ValueError if the enumeration is unknown.
def
mavlink_enum_value(entry):
Returns the value a dialect entry name stands for, whichever enumeration it
belongs to.
Raises ValueError if no entry of any dialect enumeration has that name.
def
mavlink_known_enums():
Returns the names of every enumeration the dialect table holds, in the order
the dialect defines them.
def
mavlink_known_messages():
Returns the names of every message this build types, in message-id order.
def
mavlink_offboard_global_position( header, time_boot_ms, coordinate_frame, target_system, target_component, lat_int, lon_int, alt):
Builds a global-frame position setpoint frame, with latitude and longitude
in degrees times ten million and altitude in meters.
def
mavlink_offboard_local_position( header, time_boot_ms, coordinate_frame, target_system, target_component, x, y, z):
Builds a local-frame position setpoint frame, in meters in the chosen
MAV_FRAME.
def
mavlink_offboard_local_velocity( header, time_boot_ms, coordinate_frame, target_system, target_component, vx, vy, vz):
Builds a local-frame velocity setpoint frame, in meters per second in the
chosen MAV_FRAME.
def
mavlink_offboard_type_mask(flags):
Builds a setpoint type_mask from the fields to use.
flags is a bitwise-or of the TypeMask flags; fields left out are
ignored. Returns the mask as the type_mask field of a setpoint carries it.
def
mavlink_timestamp_from_unix_micros(unix_micros):
Converts Unix time into the timestamp MAVLink signing counts in.
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_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_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_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_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():
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_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):
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_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_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.