Wraps a generated end device.
The generated device this facade delegates to.
The data rate the next uplink goes out at, before any back-off step.
The address the device is on the network by, or null before joining.
The last downlink frame counter accepted, or null before any downlink.
The next uplink frame counter, which a device stores to carry over a restart.
The lowest and highest frequency the device transmits or listens on.
Whether the device is on a network: once joined, or from the start when personalized.
The delay from the end of an uplink to the first receive window, in microseconds.
How the device decides whether to use a relay.
Whether the next uplink goes through a relay.
What the relay's last acknowledgment said about itself, or null before one arrived.
What the device knows of when its relay listens, TS011-1.0.1 section 3.9.
Where the second receive window listens.
How many times each uplink goes out, as the network last set it.
The WOR frame counter the next frame will use, TS011-1.0.1 section 5.3.2.
Reads a frame heard in one of the receive windows of the last transmission.
TS001-1.0.4 section 4.1 has a device discard a frame whose MACPayload is longer than the data rate it was received at carries. Name the window and the frame is held to that window's limit; leave it out and it may be as long as the faster window allows.
The bytes the radio received.
The frame's signal-to-noise ratio, which a DevStatusAns reports.
Optionalwindow: LorawanReceiveWindow
The window the radio heard it in, when known.
The join, or the downlink read and acted on.
A DeviceError: NothingPending, Foreign, Replayed, CounterGap,
Refused or Frame. The windows stay open, so the second still listens.
Reads the acknowledgment a relay answered the last WOR 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.
The seven bytes the radio received in the acknowledgment window.
What the relay said about itself.
A DeviceError: NothingPending with no exchange waiting, or Frame for
an acknowledgment that does not verify.
Builds a join request.
A nonce this device has never used with its join EUI.
The time, in microseconds.
What to transmit, with the join accept windows.
A DeviceError: NoCredentials, Busy or Wait.
Says what comes next once both receive windows closed with nothing for the device.
The time the second window closed, in microseconds.
Whether to repeat the frame, join again, or move on.
A DeviceError: NothingPending.
Says what to do once the acknowledgment window closed with nothing in it.
The time the window closed, in microseconds.
Whether to send the uplink at the time the exchange named anyway, or wake the relay again first, as the network's back-off asks.
A DeviceError: NothingPending.
Sends the last uplink again, the same frame on a channel chosen afresh.
The time, in microseconds.
What to transmit, with its receive windows.
A DeviceError: NothingPending or Wait.
Asks the network, with the next uplink, for the time.
Asks the network, with the next uplink, how well it hears the device.
Puts a saved state back on a device made the same way.
The state EndDevice.save returned.
The time on the clock the device woke to, in microseconds.
A DeviceError: State for a state of the wrong length, a corrupt one, one
in another format, or one from another plan, and Busy.
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.
The time, in microseconds.
The state.
A DeviceError: NotJoined or Busy.
Builds an uplink carrying a payload.
The application port, 1 to 223, or 224 for the certification test port.
The payload, as bytes or text encoded as UTF-8.
The time, in microseconds.
Whether to ask the network to acknowledge it.
What to transmit, with its receive windows.
A DeviceError: NotJoined, Busy, Wait, PayloadTooLong, or Frame
for port 0.
Builds an uplink with no payload, carrying the answers the device owes, an acknowledgment, or an ADR acknowledgment request.
The time, in microseconds.
What to transmit, with its receive windows.
A DeviceError, as EndDevice.send.
Sets what the device reports its battery as when a network asks.
A level from 1, empty, to 254, full; 'external' on external power;
or 'unknown' or null when it cannot tell.
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
the network takes it over with an EndDeviceConfReq or hands it back.
Whether the next uplinks go through a relay.
false when the network holds the decision, leaving the mode as it was.
StaticoverMakes a device that joins over the air.
A published channel plan, from planFor or cn470Plan.
The 8-byte device EUI.
The 8-byte join EUI.
The 16-byte root key.
What the radio can do; only the output power range is required.
Optionalcounters: FrameCounters
Frame counters carried over a restart; a join starts them over.
The device, not yet joined.
StaticpersonalizedMakes a device activated by personalization.
Such a device never resets its frame counters, so one that lost power passes the ones it kept.
A published channel plan.
The address the device was provisioned with.
The 16-byte network session key.
The 16-byte application session key.
What the radio can do.
Optionalcounters: FrameCounters
The frame counters the device kept.
The device, ready to send at its slowest data rate.
A LoRaWAN Class A end device, without a radio.
It joins, chooses a channel and data rate for each uplink, says when and where to listen for the answer, reads what comes back, and does what the network's MAC commands ask. It owns no radio and no clock: every call takes the time in microseconds and hands back what to put on the air, so the same device runs over any radio, or in a test with none.
One exchange runs like this. EndDevice.join or EndDevice.send returns a transmission and two receive windows timed from its end. A frame heard in either window goes to EndDevice.heard. If neither held one, EndDevice.nothingHeard says whether to EndDevice.repeat the frame, or move on.
A call that cannot be done throws a DeviceError; isDeviceError tells which.
Example