Skip to main content
Home
for DLMS smart meters

Main navigation

  • Home
  • Products
  • About us
  • Open Source
  • Community
  • Forum
  • Downloads
User account menu
  • Log in

Breadcrumb

  1. Home
  2. Bug Report: Python Serial Firmware Update Fails At 256-byte Block Size

Bug Report: Python Serial Firmware Update Fails at 256-byte Block Size

By rajput_saurabh07, 5 September, 2025
Forums
Gurux.DLMS

rajput_saurabh07

5 months 1 week ago

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)

Profile picture for user Kurumi

Kurumi

5 months 1 week ago

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

rajput_saurabh07

5 months 1 week ago

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?

rajput_saurabh07

5 months ago

Hi, Any update here?

Hi, Any update here?

Profile picture for user Kurumi

Kurumi

5 months ago

Hi, Check image updating:…

Hi,

Check image updating:
https://gurux.fi/Gurux.DLMS.Client

BR,
Mikko

rajput_saurabh07

5 months ago

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)

Profile picture for user Kurumi

Kurumi

5 months ago

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

rajput_saurabh07

5 months ago

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.

Profile picture for user Kurumi

Kurumi

5 months ago

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

  • Create new account
  • Reset your password

Hire Us!

Latest Releases

  • Sun, 02/01/2026 - 19:47
    gurux.dlms.cpp 9.0.2602.0101
  • Tue, 01/20/2026 - 10:38
    gurux.dlms.java 4.0.89
  • Wed, 01/14/2026 - 14:29
    Gurux.DLMS.Python 1.0.196
  • Mon, 12/29/2025 - 10:38
    Gurux.Serial.Android 3.0.5
  • Mon, 12/15/2025 - 08:11
    Gurux.DLMS.Net 4.0.87

New forum topics

  • Landisgyr meter
  • GxDateTime always return DayOfWeek as FF
  • Asynchronous support in Gurux DLMS stack (.NET)?
  • Multiple meter loop On OFF Problem
  • Python GXDLMSTranslator
More
RSS feed
Privacy FAQ GXDN Issues Contact
Follow Gurux on Twitter Follow Gurux on Linkedin