feat: add SunSpec register type conversion and multiple listeners per… - #57
Open
ChristophCaina wants to merge 2 commits into
Open
feat: add SunSpec register type conversion and multiple listeners per…#57ChristophCaina wants to merge 2 commits into
ChristophCaina wants to merge 2 commits into
Conversation
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.
Feature: SunSpec Register Type Conversion & Multiple Listeners per Device
Background
The SunSpec Alliance defines a standard for Modbus-based communication with
solar and energy storage devices. However, the SunSpec specification allows
vendors to implement register data in two distinct formats:
int16with a signed scale factor (sunssf)float32Both representations are fully SunSpec-compliant, but they are not
interoperable. A client expecting float32 will misinterpret int16+SF data,
and vice versa. This creates a practical problem in mixed-vendor environments
where multiple devices or energy management systems need to communicate via
Modbus TCP, but differ in which SunSpec profile they implement.
A concrete example: certain inverter manufacturers implement the integer model
while some energy management systems expect the float model — both following
the SunSpec standard, yet unable to communicate directly. This kind of
incompatibility is not limited to any specific product combination; it is an
inherent consequence of the SunSpec specification permitting both formats.
Since modbus-proxy already solves the "one device, many clients" problem at
the connection level, it is a natural fit to also solve this data type
mismatch at the protocol level — without requiring any changes to the actual
devices or clients.
Changes
1. Multiple listeners per device (
listeners)A new
listenerskey (plural) allows configuring multiple TCP serverendpoints for a single Modbus device. Each listener can have its own
conversion rules, so different clients can receive data in different formats
while the physical device is only queried once.
The existing
listen(singular) key remains fully supported forbackwards compatibility.
2. Register type conversion (
register_conversions)Each listener optionally accepts a list of
register_conversions. Each ruledescribes a single register to convert:
addresssf_addresssource_type: int16source_typeint16orfloat32)target_typeint16orfloat32)Supported conversions:
source_typetarget_typeint16float32float32int16Scale factor values are cached from previous replies, so conversions remain
stable even when the scale factor register is not included in every polling
window.
3. Scale factor caching & warmup
Scale factor
sunssfvalues are cached across replies. This ensures stable conversions even when the scale factor register is not polled in every request cycle, which is common in practice.On startup, all configured scale factor registers are queried automatically before the first client connects. This guarantees that conversions are immediately correct after a restart — no initial polling cycle is needed to warm up the cache.
4. Backwards compatibility
listen(singular) +register_conversionsat device levelcontinues to work unchanged
register_conversionsbehave exactly as beforeUse cases
This feature is useful wherever a Modbus TCP proxy sits between devices that
use different SunSpec register formats:
deliver int16+SF (or vice versa)
modern devices delivering float32
SunSpec profiles
existing clients
Testing
Validated against a live SunSpec installation:
same registers — differences within expected polling timing margin only
register_conversionsbehave identically to the previous version