RS-485
Through the RS-485 port, OrionMeter LA-IP-RSP and LA-IP-RSP[A] modems poll connected instruments with a Modbus RTU interface. The device reads the slave registers on a schedule and sends them over LoRaWAN, and on a server command it performs a one-shot read or write. This page is for those who configure the port and polling over the air and decode device packets on their own server. Here "device" means the OrionMeter modem and "slave" means the instrument connected to its RS-485 port. The description matches firmware METER_V3.1.5.84; what depends on the version is collected in Firmware versions.
What the interface provides
- There is one RS-485 port with up to four slaves on it — slots 0–3. Each slot has its own slave address, register groups and schedule.
- The exchange protocol is set by the driver. Exactly one driver goes into the firmware at build time, and all slots of the port work through it.
- Current firmware builds are released for LA-IP-RSP[A] with the Modbus RTU driver (DRV ID 14, 0x0E). The driver is visible in the firmware file name:
..._DRV(MODBUS_UNI)_public.zipmeans Modbus RTU. - The firmware driver table lists other drivers too, for example the Pulsar water meter driver (DRV ID 33, 0x21): according to the codec description, LA-IP-RSP modems on water meters work with it. These drivers are not in the current builds, so this page covers Modbus RTU only.
| LA-IP-RSP | LA-IP-RSP[A] | |
|---|---|---|
| Modem power | Battery | AC mains |
| LoRaWAN class | A | A, C |
| RS-485 port | 1 port, 4 slots | 1 port, 4 slots |
| Slave power from the port | 3.3 or 9 V for the duration of a poll | 3.3 or 9 V for the duration of a poll, or kept on between polls |
| Allowed current at DC 9 V (per specification) | 40 mA | 50 mA |
| Register monitoring | No | Yes |
| Power control command 0xAA | No | Yes |
| Minimum gap between wake-ups of one slot | 60 seconds | 2 seconds |
Connection and power for the slave
The port is half-duplex: the firmware switches the transceiver direction between transmit and receive.
The device can power a slave that has no supply of its own for the interface. The source is set by bits 6–7 of the DEVCFG byte in the slot configuration:
| Value | Slave power |
|---|---|
| 0 | Off |
| 1 | 3.3 V for the duration of a poll |
| 2 | "Unchanged", LA-IP-RSP[A] only: the device does not switch the supply before or after a poll. It is switched on and off with command 0xAA, see Power control. On LA-IP-RSP value 2 works as 0 |
| 3 | 9 V for the duration of a poll |
With values 1 and 3 the device switches the supply on before a poll, waits the power-on delay and switches the supply off when the poll ends. The delay is set by bits 0–3 of DEVCFG in steps of 333 ms: 0 to 15 steps, that is up to 5 seconds. The allowed load current is given in the specification: up to 40 mA for LA-IP-RSP and up to 50 mA for LA-IP-RSP[A] at DC 9 V.
On LA-IP-RSP[A], after the first poll with power value 2 — from the slot DEVCFG or from the power byte of a one-shot command — or after a 0xAA command, the device no longer switches the supply off after polls of slots with values 1 and 3, until it reboots. Do not mix slots with value 2 and slots with values 0, 1, 3 on one port.
Setup order
The port and polling are configured with a Protocol 78 downlink packet on fPort 2; the device also accepts configuration on fPort 1. The header — ID 0x78, SEQ, FLAGS — is followed by items: a FORMAT byte, a LEN byte with the length of the item body, then the body. A frame can carry several items, and the device processes them in order.
| FORMAT | Item |
|---|---|
| 0x06 | Slot configuration or one-shot command |
| 0x07 | Port settings |
| 0x16 | Part of a slot configuration that does not fit into one frame |
- Send the slot configuration — item 0x06. If the Modbus RTU driver has never been loaded on the port, the device loads it and stores the default port settings: 9600 bit/s, 8N1. Previously stored settings are kept when the driver is loaded again.
- If the slave needs other port settings, send item 0x07. Until the driver has been loaded for the first time, the device rejects this item. Both items can go in one frame, with 0x06 first.
- Check the device reply: each item is answered with a CFG_ID, and a bit in CFG_RESULT shows whether the item was applied, see Configuration acknowledgement.
To send the frame through ONS, use the downlink_data_req command: data is the frame in hex, fport is 2.
Port settings (FORMAT 0x07)
Item: 07 04, then 4 body bytes.
| Body bytes | Meaning |
|---|---|
| 0–1 | In the codec, the port number (PORT, uint16). The firmware skips these bytes and always configures port 0. Send 00 00 |
| 2–3 | SERIAL_CFG, uint16, least significant byte first |
| SERIAL_CFG bits | Parameter | Values |
|---|---|---|
| 0–3 | Baud rate | Index in the list below |
| 4–5 | Parity | 0 — none, 1 — even, 2 — odd |
| 6–7 | Stop bits | 0 — 1, 1 — 0.5, 2 — 2, 3 — 1.5 |
| 8–9 | Word length | 0 — 7 bits, 1 — 8 bits, 2 — 9 bits |
| 10–15 | Reserved | 0 |
Baud rate, bit/s: 0 — 300, 1 — 600, 2 — 1200, 3 — 2400, 4 — 4800, 5 — 9600, 6 — 14,400, 7 — 19,200, 8 — 38,400, 9 — 57,600, 10 — 115,200, 11 — 128,000, 12 — 230,400, 13 — 256,000.
The word length includes the parity bit: the firmware passes the value to the UART as is, and a 9-bit word is 8 data bits plus the parity bit. So with even or odd parity set the length one higher: for 8E1 use 2 (9 bits).
Example: 9600 bit/s, 8E1.
78 00 00 07 04 00 00 15 02
| Bytes | Meaning |
|---|---|
78 00 00 | Protocol 78 header: ID, SEQ, FLAGS |
07 | FORMAT 0x07 — port settings |
04 | LEN: 4 body bytes |
00 00 | Port number, skipped by the firmware |
15 02 | SERIAL_CFG = 0x0215: baud rate 5 (9600), parity 1 (even), stop bits 0 (1), word length 2 (9 bits) |
The device answers this item with CFG_ID 08 03 07 8F.
The settings belong to the port, so all four slots share them. The device does not check the values on receipt and stores them as sent. If an index is out of range — baud rate 14–15, parity 3, word length 3 — the port cannot be opened at the next poll, and the poll ends with an error event with code 7.
Modbus RTU polling configuration (FORMAT 0x06)
Item header
Item: 06 <LEN> <DRV_HDR, 2 bytes> <LEN_TYPE> <data>.
| DRV_HDR bits (uint16, least significant byte first) | Meaning |
|---|---|
| 0–11 | DRV ID: 14 (0x00E) — Modbus RTU |
| 12–13 | Slot, 0–3 |
| 14 | Not read by the firmware; TRIGGER/FORCED in the codec. Send 0 |
| 15 | ENABLED: 1 — slot enabled, 0 — disable the slot |
| LEN_TYPE bits | Meaning |
|---|---|
| 0–5 | Data length minus 1 |
| 6–7 | Type: 0 — EMPTY (no configuration), 1 — CONFIG (polling configuration), 3 — COMMAND (one-shot command, see One-shot commands). The device rejects type 2 |
Configuration data
| Bytes | Meaning |
|---|---|
| 0 | Slave address |
| 1 | DEVCFG: power-on delay, number of attempts, slave power |
| 2 | Reserved, 0 |
| 3–13 | Group 1 |
| 14–24 | Group 2 |
| 25–35 | Group 3 |
| 36–46 | Group 4 |
A full configuration is 47 bytes. The codec sends only the groups you define: the example below has one group, 14 data bytes.
| DEVCFG bits | Meaning |
|---|---|
| 0–3 | Delay after switching the slave power on, in steps of 333 ms: 0–15 |
| 4–5 | Number of attempts per block for scheduled polls: 0 and 1 — one, 2 — two, 3 — three |
| 6–7 | Slave power: 0 — off, 1 — 3.3 V, 2 — unchanged, 3 — 9 V, see Connection and power for the slave |
The device waits up to 2 seconds for a slave response. The pauses between attempts are 300, 600 and 1200 ms.
Groups and register blocks
A group is 11 bytes: PARAM CFG (3 bytes) and two register blocks (4 bytes each). All numbers are least significant byte first.
| PARAM CFG bits (uint24) | Meaning |
|---|---|
| 0–12 | Poll interval: (value + 1) × 10 minutes |
| 13–17 | Start hour in UTC, 0–23; 31 — random hour |
| 18–19 | Reserved |
| 20–21 | Digital input: 0 — no binding, 1–3 — input 1–3, see Binding a group to a digital input |
| 22 | Expected input state: 0 — open, 1 — closed |
| 23 | Group active |
| Block bits (uint32) | Meaning |
|---|---|
| 0–1 | Function: 0 — FC01 (coils), 1 — FC02 (discrete inputs), 2 — FC03 (holding registers), 3 — FC04 (input registers) |
| 2–4 | Monitoring divider, 0 — off. LA-IP-RSP[A] only, see Register monitoring |
| 5 | Monitoring: critical value — send immediately |
| 6 | Monitoring: send with LoRaWAN confirmation |
| 7 | Reserved |
| 8–15 | Number of registers or bits; 0 — block off |
| 16–31 | First register address |
What the device rejects
The driver rejects the whole configuration if:
- an active group has a count of 0 in both blocks;
- both blocks of a group are enabled and have the same function and address;
- an FC03 or FC04 block has more than 125 registers;
- no group is active.
A rejected configuration does not change how the slot works: it keeps polling with its previous working configuration.
Example: read 10 registers once an hour
Slave address 1, two attempts, 9 V power, power-on delay 3 × 333 ms. One group: every 60 minutes starting at 00:00 UTC, read 10 holding registers from address 0.
78 00 00 06 11 0E 80 4D 01 E3 00 05 00 80 02 0A 00 00 00 00 00 00
| Bytes | Meaning |
|---|---|
78 00 00 | Protocol 78 header |
06 11 | FORMAT 0x06, LEN 17 |
0E 80 | DRV_HDR 0x800E: DRV ID 14, slot 0, ENABLED |
4D | LEN_TYPE: CONFIG, 14 data bytes |
01 | Slave address 1 |
E3 | DEVCFG: delay 3, 2 attempts, power 3 (9 V) |
00 | Reserved |
05 00 80 | PARAM CFG 0x800005: interval (5 + 1) × 10 = 60 minutes, start hour 0, group active |
02 0A 00 00 | Block 1: FC03, 10 registers from address 0 |
00 00 00 00 | Block 2 off |
The device answers with CFG_ID 08 03 06 60 and, if the configuration was applied, CFG_RESULT 08 02 01 00.
Schedule and first poll
Each active group is polled every (value + 1) × 10 minutes — from 10 to 81,920 minutes. Polls are aligned to the start hour: start hour + k × interval. The device clock runs in UTC, so the start hour is in UTC too. For example, an interval of 6 hours (value 35) and start hour 3 give polls at 03:00, 09:00, 15:00 and 21:00 UTC.
- Start hour 31 is random: the device picks it once at startup.
- Start hour 24–30 means the group is never polled on schedule.
The first poll after a configuration is applied:
- The slot wakes up after 60 seconds in class A or after 10 seconds in class C. A one-shot command in class A runs after 3 seconds.
- The device does a full poll right away, keeping the minimum gap between wake-ups of the slot: 60 seconds on LA-IP-RSP, 2 seconds on LA-IP-RSP[A].
- If the next scheduled poll is less than half an interval away, the device does not poll right away and waits for that poll.
On LA-IP-RSP a poll is postponed by 90 seconds while the power manager does not allow the extra load on the battery.
Binding a group to a digital input
A group can be bound to one of the three digital inputs: bits 20–21 of PARAM CFG hold the input number, bit 22 the expected state. The scheduled poll of the group runs only if the input is enabled in Digital mode and is in the expected state. Otherwise this poll is skipped.
If the input is disabled or works in counting mode, its state is undefined, and the group is polled unconditionally.
Register monitoring
Monitoring works on LA-IP-RSP[A] only. The device reads a block with a non-zero divider N times per group interval, at a step of interval / N: one full poll and N − 1 monitoring reads between full polls. The step is never shorter than the minimum gap between wake-ups of a slot (2 seconds).
| Divider (block bits 2–4) | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|
| N — reads per interval | 300 | 200 | 100 | 50 | 40 | 30 | 20 |
- The device sends monitoring data only if it has changed, with reason 7 in record 0x20.
- Bits 5 (critical value — send immediately) and 6 (with LoRaWAN confirmation) apply only to monitoring reads.
- Error events from monitoring are limited to one per 600 seconds per slot. The low nibble of subCode in such an event is the number of failures.
LA-IP-RSP firmware has no monitoring, and the divider has no effect.
One-shot commands
A one-shot command is item 0x06 with type COMMAND (LEN_TYPE bits 6–7 = 3). A command is addressed to an enabled slot: the device rejects a command to a disabled slot or for a driver that is not loaded on the port. A command that arrives while the driver is busy polling is also rejected — with an event with code 19, failure point 1.
Read and write
| Field | Size | Meaning |
|---|---|---|
| Type | 1 byte | 0x01 — read, 0x02 — write, 0xAA — power control |
| Function | 1 byte | Modbus function code: 01–04 — read; 05, 06, 0F, 10 — write |
| First register | 2 bytes, least significant first | |
| Count | 1 byte | Registers or bits. Not used for FC05 and FC06 |
| Flags | 2 bytes, least significant first | See the table below |
| Slave address | 1 byte | Only with bit 3. Without it, the address from the slot configuration is used |
| Power | 1 byte | Only with bit 4: bits 0–3 — delay in steps of 333 ms; bits 4–5 — slave power: 0 — off, 1 — 3.3 V, 2 — unchanged, 3 — 9 V |
| Port settings | 2 bytes | Only with bit 5: SERIAL_CFG, as in FORMAT 0x07 |
| Delay after write | 2 bytes, ms | Write with bit 7 only |
| Data byte count | 1 byte | Write only: 1–32. Otherwise the device answers with an event with code 7 |
| Data | 1–32 bytes | Write only. For FC05 and FC06 the value is the first two bytes, most significant first |
| Flag bits | Meaning |
|---|---|
| 0–2 | Result priority: 1 — low, 2 — normal, 3 — high, 4 — critical, the uplink goes out at once. 0 — a write without bit 6 returns no data, only a 0x20 record with reason 4; a read result comes with low priority |
| 3 | Own slave address |
| 4 | Own power byte |
| 5 | Own port settings |
| 6 | Read after write |
| 7 | Delay after write |
| 14–15 | Number of attempts minus 1: 0–3 — 1 to 4 attempts |
The whole command, from the type byte to the last data byte, must not exceed 41 bytes; the device rejects a longer one with code 19, failure point 8. So with optional fields fewer than 32 data bytes fit: up to 31 with the delay after write, up to 27 with all fields.
Example: read 4 holding registers from address 0x0100 of slave 17 on slot 1.
78 00 00 06 0B 0E 90 C7 01 03 00 01 04 0A 00 11
| Bytes | Meaning |
|---|---|
06 0B | FORMAT 0x06, LEN 11 |
0E 90 | DRV_HDR 0x900E: DRV ID 14, slot 1, ENABLED |
C7 | LEN_TYPE: COMMAND, 8 data bytes |
01 | Read |
03 | FC03 |
00 01 | First register 0x0100 |
04 | 4 registers |
0A 00 | Flags 0x000A: priority 2, own slave address, one attempt |
11 | Slave address 17 |
Example: write two registers from address 0x0010 with function FC16 (0x10) and read them back after 500 ms.
78 00 00 06 11 0E 80 CD 02 10 10 00 02 C2 00 F4 01 04 00 01 00 02
| Bytes | Meaning |
|---|---|
06 11 | FORMAT 0x06, LEN 17 |
0E 80 | DRV ID 14, slot 0, ENABLED |
CD | LEN_TYPE: COMMAND, 14 data bytes |
02 | Write |
10 | FC16 |
10 00 | First register 0x0010 |
02 | 2 registers |
C2 00 | Flags 0x00C2: priority 2, read after write, delay after write; slave address from the slot configuration |
F4 01 | Delay 500 ms |
04 | 4 data bytes |
00 01 00 02 | Data |
The command result arrives in record 0x20 with reason 1 (read), 4, 5 or 6 (write), see Data from the device.
Power control
Command 0xAA: AA <state> <report>. State: 0 — switch off, 1 — 3.3 V, 2 — leave as is, 3 — 9 V. A non-zero report byte makes the device send an event with code 0.
The command works only on LA-IP-RSP[A] and only if the slot's slave power is "unchanged" (value 2 in DEVCFG). Otherwise the device answers with an event with code 5, and LA-IP-RSP with code 9. The supply stays in the commanded state until the next 0xAA command or until a poll of another slot with power 0, 1 or 3 changes it: the port supply is shared, and such a poll switches it on or off.
Example: switch 9 V on and send a report.
78 00 00 06 06 0E 80 C2 AA 03 FF
| Bytes | Meaning |
|---|---|
06 06 | FORMAT 0x06, LEN 6 |
0E 80 | DRV ID 14, slot 0, ENABLED |
C2 | LEN_TYPE: COMMAND, 3 data bytes |
AA | Power control |
03 | 9 V |
FF | Send a report |
Data from the device (record 0x20)
The device sends the registers it has read in uplink record 0x20 — FORMAT MODBUS of the Protocol 78 packet format.
| Field | Size | Meaning |
|---|---|---|
| FORMAT | 1 byte | 0x20 |
| TIMESTAMP | 4 bytes, least significant first | Time of the slave response: seconds since 2000-01-01 UTC. UNIX time = value + 946684800 |
| FLAGS | 1 byte | Bits 0–1 — slot; bits 2–6 — number of blocks after the first; bit 7 — EXT_FLAGS present |
| EXT_FLAGS | 2 bytes, least significant first | Bits 0–2 — reason; bit 5 — block split into parts |
| Block | Function (1 byte: 0–3 — FC01–FC04), count (1 byte), start address (2 bytes, least significant first), data |
The block data are the bytes of the slave response after the byte count field: for FC03 and FC04, registers most significant byte first, 2 bytes per register; for FC01 and FC02, bits packed 8 per byte, (count + 7) / 8 bytes. Blocks with the same timestamp, slot and flags are merged into one record.
| Reason | What was read |
|---|---|
| 0 | Scheduled poll |
| 1 | One-shot read command |
| 4 | Write done, no data |
| 5 | Written data |
| 6 | Read after write |
| 7 | Monitoring |
Reasons 2 and 3 belong to event-triggered polling, which is off in the current firmware.
Example: scheduled poll, slot 0, registers 0 and 1.
78 02 00 20 40 42 5A 32 80 00 00 02 02 00 00 00 0A 00 14
| Bytes | Meaning |
|---|---|
78 02 00 | Protocol 78 header |
20 | Modbus record |
40 42 5A 32 | 0x325A4240 = 844776000; 844776000 + 946684800 = 1791460800 — 2026-10-08 12:00:00 UTC |
80 | FLAGS: slot 0, one block, EXT_FLAGS present |
00 00 | EXT_FLAGS: reason 0 — schedule |
02 | FC03 |
02 | 2 registers |
00 00 | Start address 0 |
00 0A 00 14 | Register 0 = 0x000A, register 1 = 0x0014 |
Codec output fragment for this packet (service fields omitted). The codec calls slot 0 bus1 and outputs the function as the real Modbus code, 3:
"serial": {
"bus1": {
"utctimestamp": "2026-10-08T12:00:00.000Z",
"trigger": { "type": { "value": 0, "description": "Scheduled reading" } },
"modbus1": {
"function": 3,
"count": 2,
"start_address": 0,
"data": { "0": { "value": "000A" }, "1": { "value": "0014" } }
}
}
}
Long blocks
An FC03 or FC04 block that does not fit into an uplink frame is split into parts. Each part has EXT_FLAGS bit 5 = 1, and 3 bytes follow EXT_FLAGS before the block header:
| Byte | Meaning |
|---|---|
| 0 | Bits 0–2 — packet number, 0–7; bits 3–7 — part number |
| 1 | Total number of registers in the block |
| 2 | Bits 0–6 — number of registers in this part; bit 7 — last part |
FC01 and FC02 blocks are never split.
Sending with LoRaWAN confirmation
A slot's data can be sent with LoRaWAN confirmation — system command 0x15 (FORMAT 0x00): 00 03 15 <slot> <groups>, where bits 0–3 of the last byte are groups 1–4. In the current firmware the bit is picked by the block's position in the run rather than strictly by group number, so enable all groups when you need confirmed delivery:
78 00 00 00 03 15 00 0F
Exchange errors (record 0x08, subtype 0x07)
The device reports errors of the exchange with a slave in service record 0x08, subtype 0x07: 08 07 <TIMESTAMP, 4 bytes> <2 bytes: bits 0–11 — DRV ID, 12–13 — slot, 14 — port> <code> <subCode>.
| Code | Meaning | subCode |
|---|---|---|
| 0 | No error — execution report | |
| 1 | Slave did not respond | Block position |
| 2 | Response checksum mismatch | Block position |
| 5 | Exchange fault | |
| 7 | Configuration error | |
| 8 | Protocol violation | Slave address or function code from a foreign response; 0 — wrong data length; block position if the byte count in the response does not match the request (since METER_V3.1.5.62) |
| 9 | Internal driver error | 0xF0 — run aborted by the port timer (60 seconds); 0–4 — internal driver state; 0 — also the LA-IP-RSP answer to command 0xAA |
| 10 | Modbus exception | Exception code from the slave |
| 11 | UART receiver overrun | Block position |
| 12 | Framing error on the line | Block position |
| 13 | Noise on the line | Block position |
| 14 | UART hardware fault | |
| 15 | Parity error | |
| 16 | Overrun, framing error and noise at once | Block position |
| 17 | Uplink queue full, data lost | Block position |
| 18 | Response shorter than 5 bytes | Block position |
| 19 | Downlink configuration or command not applied | High nibble — failure point 1–12, low nibble — slot |
| 255 | Unrecognized error | Block position |
Block position: the high nibble is the block number in the configuration, 0–7 (group × 2 + block, zero-based); the low nibble is how many blocks of the run were left, including this one. For blocks with monitoring the low nibble is the number of failures.
| Failure point (code 19) | Where |
|---|---|
| 1 | Driver busy — command rejected |
| 2 | Invalid slot number |
| 3 | Command to a disabled slot |
| 4 | Disabling the slot |
| 5 | Loading the driver, including a driver missing from the build |
| 6 | Starting the driver |
| 7 | The driver has no handlers |
| 8 | The driver rejected the configuration |
| 9 | Writing the configuration to memory |
| 10 | No stored configuration to enable the slot |
| 11 | Enabling the slot |
| 12 | Command for a driver that is not loaded on the port |
Example: timeout on slot 1.
78 01 00 08 07 40 42 5A 32 0E 10 01 13
0E 10 — DRV ID 14, slot 1; 01 — slave did not respond; 13 — block 1 (group 1, second block), 3 blocks were left. Codec output fragment:
"serial": {
"bus2": {
"error": {
"utctimestamp": "2026-10-08T12:00:00.000Z",
"drvId": 14,
"code": 1,
"codeDescription": "Timeout",
"subCode": 19
}
}
}
When a run is aborted
A run is the poll of all blocks of a slot during one wake-up. If a block is not read after all attempts, the device reports the error and moves on to the next block. The whole run is aborted if:
- the slave did not respond to the first block;
- the slave responded with a Modbus exception;
- a response came with a foreign slave address or an unknown function;
- a block of a one-shot command was not read.
A run longer than 60 seconds is aborted by the port timer (code 9, subCode 0xF0); after that the slot continues on schedule.
Configuration acknowledgement
- Each 0x06 and 0x16 item is answered with a CFG_ID record
08 03 06 <cfg_id>:cfg_id = (tag6 << 2) | slot, where tag6 is the low 6 bits of CRC-16/MODBUS over the item bytes after FORMAT and LEN. The server computes tag6 over the bytes it sent and compares it with the reply. - A 0x07 item is answered with
08 03 07 <tag8>, where tag8 is the low byte of the same CRC. For the 9600 8E1 example it is 0x8F. - Whether an item was applied is shown by CFG_RESULT
08 02 <uint16, least significant byte first>: the bit numbered by the item's order among the configuration items of the frame is 1 if the item was applied. Only items the device answers with a CFG_ID are counted: 0x11 requests and items the device skips (for example 0x05) get no number. - A CFG_ID only confirms that the item was processed — success is shown by the CFG_RESULT bit.
The codec decodes 08 03 06 B6 as slot 2, tag6 = 45.
If a configuration arrives while the driver is busy polling, the device queues it and applies it once the driver is idle. In this case the CFG_ID arrives in one of the following uplinks as 08 0D <block> <cfg_id> <item number>; the item number is the bit number in the CFG_RESULT of the same uplink. The queue holds one item per slot: while one waits, the device rejects the next item for the same slot — its CFG_RESULT bit is 0 and no code 19 event is sent.
Disabling and re-enabling a slot
- To disable a slot, send item 0x06 with ENABLED = 0.
- To enable it again with its stored configuration, send item 0x06 of type EMPTY with ENABLED = 1. The stored configuration must be for the same driver, otherwise the device answers with an event with code 19, failure point 10.
At least one data byte must follow LEN_TYPE, even for EMPTY: the length field holds the length minus 1. For slot 0:
78 00 00 06 04 0E 00 00 00 — disable
78 00 00 06 04 0E 80 00 00 — enable with the stored configuration
Reading the settings back from the device
The current slot configuration and port settings can be read with service request 0x11, type 0x04:
78 00 00 11 03 04 06 00 — configuration of slot 0 (the last byte is the slot)
78 00 00 11 03 04 07 00 — port settings
The answer arrives as record 08 0B, or in parts as 08 0C if it does not fit into a frame. The codec builds these requests and decodes the answers.
Large configurations
At DR0–DR2 in the EU868 and KZ865 frequency plans a downlink frame is at most 51 bytes. The header, FORMAT, LEN, DRV_HDR and LEN_TYPE take 8 bytes, leaving 43 bytes for driver data. A three-group configuration (36 bytes) fits, a four-group one (47 bytes) does not: such a frame is 55 bytes, and the codec warns about it. ONS rejects a downlink_data_req whose data exceed the limit with error 4. The limit is computed for the data rate from the dr field, and without it for the data rate of the last uplink, see max_dl_data_req.
A configuration that does not fit into a frame is sent in parts — items 0x16: 16 <LEN> <DRV_HDR> <FRAG> <data part>. The item has no LEN_TYPE byte.
| FRAG bits | Meaning |
|---|---|
| 0–5 | Offset of the part in the configuration data |
| 6 | Reserved, 0 |
| 7 | LAST — last part |
- The device assembles the parts in memory and applies the whole configuration only after the part with LAST.
- A part with offset 0 starts the assembly over. The device rejects a part with a gap or a part for another slot.
- Parts must have ENABLED = 1. A slot is disabled with a plain 0x06 item.
- Each part gets its own CFG_ID.
The codec splits a configuration into frames itself. Example: slot 0, four groups — 10 holding registers from address 0 and 10 from address 100 once an hour, 4 input registers from address 0 once an hour, 16 coils from address 0 once a day from 03:00 UTC.
78 00 00 16 2E 0E 80 00 01 E3 00 05 00 80 02 0A 00 00 00 00 00 00 05 00 80 02 0A 64 00 00 00 00 00 05 00 80 03 04 00 00 00 00 00 00 8F 60 80 00 10 00 00
78 01 00 16 07 0E 80 AB 00 00 00 00
The first frame is 51 bytes: FRAG 0x00 — offset 0, not the last part, 43 data bytes; expected CFG_ID 08 03 06 44. The second is 12 bytes: FRAG 0xAB — offset 43, LAST, the remaining 4 bytes; expected CFG_ID 08 03 06 38.
Send the frames strictly in order and queue the next one only after the previous one has gone out: ONS sends the most recently queued frame first, see downlink_data_req.
Firmware versions
Version numbers do not increase with date: METER_V3.0.4.7 was built in August 2026, METER_V3.0.4.137 in May 2026, and METER_V3.1.5.0–3.1.5.12 were built in June 2026, before both. So check a capability against the table, which gives a separate number for the 3.1.5 line.
| Capability | First version |
|---|---|
| Configuration parts, FORMAT 0x16 | METER_V3.0.4.7; in the 3.1.5 line, METER_V3.1.5.13. Older firmware skips item 0x16 |
| CFG_ID for 0x06 items | METER_V3.0.4.137 |
| CFG_ID for every item of a frame | METER_V3.0.5.4; in the 3.1.5 line, METER_V3.1.5.13 |
| Run continues after a lost block; 300, 600 and 1200 ms pauses between attempts | METER_V3.1.5.34 |
| Error code 18 | METER_V3.1.5.49 |
| Error code 19 | METER_V3.1.5.55 |
| Rejection of type 2 in LEN_TYPE | METER_V3.1.5.60 |
Deferred CFG_ID 08 0D | METER_V3.1.5.73 |
| Bits 6 and 7 of the write command flags | METER_V3.1.5.77. In older firmware bit 6 has no effect (the write runs without a read-back), and with bit 7 the command is parsed with an offset: the low byte of the delay is taken as the data byte count. If it is 0 or above 32, the command is rejected with code 7; otherwise the slave receives a write with wrong data. Do not set these bits on older firmware |
In addition, in the current firmware:
- a 0x06 item for a driver that is not in the build is rejected without affecting the working slots; in earlier firmware such an item could disable the Modbus slots;
- a configuration rejected by the driver leaves the slot working with its previous configuration.
The same in METER_V3.0.4.132 and the current firmware: the port settings layout and baud rate list, the "driver first, then 0x07" rule, the Modbus configuration layout, the number of attempts and the absence of monitoring on LA-IP-RSP.
Good to know
- Port 1 is not supported. The codec can build items 0x05 and 0x15 for port 1, but LA-IP-RSP skips them: no CFG_RESULT bit and no CFG_ID. Use 0x06 and 0x16.
- Driver first, then the port. Item 0x07 is rejected before the first slot configuration. Port settings are shared by all slots.
- 0x07 values are not checked on receipt. A wrong baud rate, parity or word length index shows up at the next poll as an event with code 7.
- The start hour is in UTC. The time zone is not taken into account when the schedule is computed.
- A CFG_ID is not a sign of success. Success is shown by the CFG_RESULT bit.
- There is no transparent channel. Arbitrary bytes cannot be passed to RS-485 over LoRaWAN.
- There is no event-triggered polling. Polling by a digital input or magnet (system command 0x11, reasons 2 and 3 in record 0x20) is off in line 3.1.5. Binding a group to a digital input is a different feature, and it works.
See also
- Specification — number of ports, power for RS-485 slaves, LoRaWAN classes.
- Digital — the input mode a polling group is bound to.
- Protocol 78 packet format — packet header and FORMAT list.
- Protocol 78 playground — decoding device packets in the browser.
- Sending data to a device — how to queue a frame through the ONS WebSocket API and check its status.