Python ValueError with 256-byte blocks over serial. Works with 128 bytes. Device supports 256 with other software. How to fix?
Error: ValueError: byte must be in range(0, 256)
When performing a firmware update over a serial (HDLC) connection, the process fails during the first block transfer.
Problem:
The library correctly reads the meter's imageBlockSize (which is 256 bytes). However, it then attempts to use this 256-byte block size for the transfer over the serial line. This packet is too large for the HDLC frame, causing the meter to fail to respond and eventually disconnect. This issue does not occur over TCP/IP.
Logs:
Here's the sequence from the application log:
Reading image block size from meter...
Meter reported image block size: 256 bytes
Final block size for transfer will be: 256 bytes
Step 1: Initiating transfer...
-> Initiation successful.
Step 2: Transferring image in 957 blocks...
-> Transferring block 1/957
Warning: Failed to transfer block 1 on attempt 1. Error: byte must be in range(0, 256)
FATAL: Failed to transfer block 1 after 3 attempts.
Firmware update process interrupted by an error: byte must be in range(0, 256)
This is a normal case with image updating. The 256 block is split into HDLC frames. You need to check your code. Is there a reason why you can't use the existing method?
Python ValueError with 256…
Python ValueError with 256-byte blocks over serial. Works with 128 bytes. Device supports 256 with other software. How to fix?
Error: ValueError: byte must be in range(0, 256)
HI, I need more information…
HI,
I need more information about this. Can you add a trace of where you get this error? You try to add value that doesn't fit a byte. Check that first.
BR,
Mikko
App Log:- Starting full…
App Log:-
Starting full firmware update process...
[18:29:53.963] HLS with Encryption: Configuring client for Part-2 configuration task.
[18:29:53.963] Connecting via Serial Port COM1
[18:29:54.010] Connection opened.
[18:29:54.955] Connection initialized successfully.
[18:29:54.955] Reading firmware image file: rl78i1c_user_app.rbin
[18:29:54.956] Image size: 244748 bytes
[18:29:54.957] Reading image block size from meter...
[18:29:55.146] Meter reported image block size: 256 bytes
[18:29:55.146] Final block size for transfer will be: 256 bytes
[18:29:55.147] Step 1: Initiating transfer...
[18:29:58.247] -> Initiation successful.
[18:29:58.248] Step 2: Transferring image in 957 blocks...
[18:29:58.248] -> Transferring block 1/957
[18:29:58.252] Warning: Failed to transfer block 1 on attempt 1. Error: byte must be in range(0, 256)
Raw Data Log:-
TX: 18:29:59 7E A0 07 03 A1 93 C3 8D 7E
RX: 18:29:59 7E A0 20 A1 03 73 9F 94 81 80 14 05 02 03 40 06 02 01 70 07 04 00 00 00 01 08 04 00 00 00 01 13 3B 7E
TX: 18:29:59 7E A0 6B 03 A1 10 80 35 E6 E6 00 60 5D A1 09 06 07 60 85 74 05 08 01 03 A6 0A 04 08 52 45 53 5F 50 55 53 48 8A 02 07 80 8B 07 60 85 74 05 08 02 02 AC 12 80 10 BC 42 00 2F 9D 09 6D A3 30 B2 45 FD C4 BF D2 BA BE 23 04 21 21 1F 30 00 00 00 01 1A 13 24 1C 33 25 A9 1D C2 00 F8 1D 7A 02 B1 BA E1 42 18 87 11 EF 6B EA A5 75 F2 5A 7E
RX: 18:29:59 7E A0 77 A1 03 30 37 66 E6 E7 00 61 69 A1 09 06 07 60 85 74 05 08 01 03 A2 03 02 01 00 A3 05 A1 03 02 01 0E A4 0A 04 08 41 4B 55 30 30 30 30 30 88 02 07 80 89 07 60 85 74 05 08 02 02 AA 12 80 10 41 42 43 44 45 46 47 48 41 42 43 44 45 46 47 48 BE 23 04 21 28 1F 30 00 00 00 00 3C 2F 75 EC 45 2D 13 B5 EC BF E9 1A 7B B0 A8 3D 95 1A A8 0C E7 65 FB 3E B7 B6 FE AF 7E
Decrypted PDU: C3 01 C1 00 0F 00 00 28 00 00 FF 01 01 09 10 41 CF 5C 37 4A BC 1E E7 AC 49 2A C0 6B 4A 5C A6
<ActionRequest>
<ActionRequestNormal>
<InvokeIdAndPriority Value="C1" />
<MethodDescriptor>
<ClassId Value="000F" />
<InstanceId Value="0000280000FF" />
<MethodId Value="01" />
</MethodDescriptor>
<MethodInvocationParameters>
<OctetString Value="41CF5C374ABC1EE7AC492AC06B4A5CA6" />
</MethodInvocationParameters>
</ActionRequestNormal>
</ActionRequest>
TX: 18:29:59 7E A0 3E 03 A1 32 D1 8C E6 E6 00 CB 30 30 00 00 00 03 20 DA 6F 8E 60 88 FF 49 0A 5F 3D 97 D2 8E 84 5E EF CB FE DF CD 79 C7 A2 E3 A4 A9 D2 F3 9B 6C 92 68 92 89 D1 36 80 ED 6F A2 F8 3B F5 C3 7E
Decrypted PDU: C7 01 C1 00 01 00 09 10 E6 7E 06 B0 FA C4 90 0D AC 3A 0E 0B 65 B7 36 D2
<ActionResponse>
<ActionResponseNormal>
<InvokeIdAndPriority Value="C1" />
<Result Value="Success" />
<ReturnParameters>
<Data>
<OctetString Value="E67E06B0FAC4900DAC3A0E0B65B736D2" />
</Data>
</ReturnParameters>
</ActionResponseNormal>
</ActionResponse>
RX: 18:30:00 7E A0 37 A1 03 52 94 30 E6 E7 00 CF 29 30 00 00 00 01 90 7A FA 47 A5 97 0D B6 1C B4 C7 C2 31 D4 8F 12 17 E3 E8 1D EC 6A AC 47 4D A2 1E AE 59 FF 82 A7 AB 06 3C 2A F7 E2 7E
Invalid StoC:E6 7E 06 B0 FA C4 90 0D AC 3A 0E 0B 65 B7 36 D2-BF 6C 4C E0 0B 04 FB 9A C4 68 23 CF 04 F5 AE 21
DisconnectRequest
TX: 18:30:00 7E A0 07 03 A1 53 CF 4B 7E
RX: 18:30:00 7E A0 20 A1 03 73 9F 94 81 80 14 05 02 03 40 06 02 01 70 07 04 00 00 00 01 08 04 00 00 00 01 13 3B 7E
Code:-
try:
if (block_num + 1) % 10 == 0 or (block_num + 1) == num_blocks or block_num == 0:
log_msg = f"-> Transferring block {block_num + 1}/{num_blocks}"
if attempt > 0:
log_msg += f" (Attempt {attempt + 1})"
self.log(log_msg)
start_index = block_num * block_size
end_index = min(start_index + block_size, image_size)
chunk = firmware_data[start_index:end_index]
block_data = GXByteBuffer()
block_data.setUInt8(2); block_data.setUInt8(2)
_GXCommon.setData(None, block_data, DataType.UINT32, int(block_num))
_GXCommon.setData(None, block_data, DataType.OCTET_STRING, chunk)
reply = GXReplyData()
block_packets = reader.client.method(image_transfer_obj, 2, block_data, DataType.ARRAY)
reader.readDLMSPacket(block_packets, reply)
break
Is this you asked for?
Hi, Any update here?
Hi, Any update here?
Hi, Check image updating:…
Hi,
Check image updating:
https://gurux.fi/Gurux.DLMS.Client
BR,
Mikko
Well thats what i…
Well thats what i implemented and getting this
When performing a firmware update over a serial (HDLC) connection, the process fails during the first block transfer.
Problem:
The library correctly reads the meter's imageBlockSize (which is 256 bytes). However, it then attempts to use this 256-byte block size for the transfer over the serial line. This packet is too large for the HDLC frame, causing the meter to fail to respond and eventually disconnect. This issue does not occur over TCP/IP.
Logs:
Here's the sequence from the application log:
Reading image block size from meter...
Meter reported image block size: 256 bytes
Final block size for transfer will be: 256 bytes
Step 1: Initiating transfer...
-> Initiation successful.
Step 2: Transferring image in 957 blocks...
-> Transferring block 1/957
Warning: Failed to transfer block 1 on attempt 1. Error: byte must be in range(0, 256)
FATAL: Failed to transfer block 1 after 3 attempts.
Firmware update process interrupted by an error: byte must be in range(0, 256)
Hi, This is a normal case…
Hi,
This is a normal case with image updating. The 256 block is split into HDLC frames. You need to check your code. Is there a reason why you can't use the existing method?
BR,
Mikko
GXSerial has a limit of HDLC…
GXSerial has a limit of HDLC send buffer and i think thats why its not able to send 256 block using HDLC. Can you please check this once.
Hi, As I told you earlier,…
Hi,
As I told you earlier, this is a normal use case. The PDU size is 256 bytes, not HDLC frame size.
You should read PDU and frame size. I hope you get the idea of how this works.
https://www.gurux.fi/DLMSInNutshell
BR,
Mikko