Repository navigation
Fix: write_register() scheitert bei negativen INT_16/INT_8-Werten - #4275
Merged
LKuemmel merged 2 commits intoNov 6, 2026
Merged
Conversation
Reviewer's guide (collapsed on small PRs)Reviewer's GuideThe PR fixes negative INT_16/INT_8 writes by routing every explicitly typed value through _build_binary_payload(), while retaining raw writes without a data type and adding regression coverage for two’s-complement encoding. Sequence diagram for typed Modbus register writessequenceDiagram
participant Caller
participant Modbus as ModbusClient
participant Builder as BinaryPayloadBuilder
participant Delegate as pymodbusDelegate
Caller->>Modbus: write_register(address, value, data_type)
Modbus->>Builder: _build_binary_payload(value, data_type, byteorder, wordorder)
Builder-->>Modbus: two's-complement registers
Modbus->>Delegate: write_registers(address, registers)
Flow diagram for typed and untyped register writesflowchart TD
A[write_register] --> B{data_type is provided?}
B -->|Yes| C[_build_binary_payload]
C --> D[write_registers with encoded registers]
B -->|No| E[write_registers with raw value]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 2 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="packages/modules/common/modbus.py" line_range="226" />
<code_context>
- if data_type.bits > 16 or data_type in [ModbusDataType.FLOAT_16,
- ModbusDataType.FLOAT_32,
- ModbusDataType.FLOAT_64]:
- registers = self._build_binary_payload(value, data_type, byteorder, wordorder)
- self._delegate.write_registers(address, registers, **kwargs)
- else:
</code_context>
<issue_to_address>
**Negative INT_8 values read back incorrectly**
When a negative INT_8 value other than -1 is written and later decoded as INT_8 with the default big-endian settings, `write_register()` encodes `INT_8` with `add_16bit_int` as a sign-extended 16-bit register, while `__read_registers()` decodes only the first byte with `decode_8bit_int`, so values such as -5 read back as -1.
Encode `INT_8` values in a register representation that `decode_8bit_int` reads back correctly.
</issue_to_address>
### Comment 2
<location path="packages/modules/common/modbus_test.py" line_range="81" />
<code_context>
+ delegate.is_socket_open.return_value = True
+
+ client = ModbusClient(delegate, "test", 502)
+ client.write_register(1000, -500, data_type=ModbusDataType.INT_16, unit=1)
+
+ delegate.write_registers.assert_called_once_with(1000, [65036], unit=1)
</code_context>
<issue_to_address>
**Modbus test assertion fails**
When the added test runs with the repository's normal `packages/modules/conftest.py` fixture, `BinaryPayloadBuilder.to_registers()` returns an unconstrained `Mock`, so `_build_binary_payload()` passes that mock to the delegate instead of `[65036]` and the assertion fails, preventing the modules test suite from passing.
Configure the test fixture or test builder so `to_registers()` returns the expected register list.
Also at `packages/modules/common/modbus_test.py:83`.
</issue_to_address>
LKuemmel
requested changes
Nov 6, 2026
LKuemmel
approved these changes
Nov 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
#4226 (reply in thread)
Problem
write_register(..., data_type=ModbusDataType.INT_16)scheitert bei negativen Werten - betrifft weiterhin den Lambda-Verbraucher (#4269) und unabhängig davonego/ego/consumer.py:25, das einen literalen-1über denselben Pfad schreibt, bei jedem Aufruf.Ursache
write_register()behandelt Datentypen mitbits <= 16(außer Float) als "einfach" und reicht den rohen Wert ungekodiert an pymodbus durch - das scheitert bei negativen Werten, da die Zweierkomplement-Kodierung fehlt, die_build_binary_payload()für alle anderen Typen bereits korrekt übernimmt.Fix
Kodiert jetzt immer über
_build_binary_payload(), sobalddata_typeangegeben ist.Summary by Sourcery
Ensure typed Modbus register writes correctly encode negative signed values.
Bug Fixes:
Tests: