[modbus.sungrow] Added some more registers#18364
[modbus.sungrow] Added some more registers#18364tscholand wants to merge 15 commits intoopenhab:mainfrom
Conversation
|
Ok, I just realized, that the checks didn't succeed. I guess, I will have to look into the problems, before this should be reviewed. |
5192e2e to
b253c19
Compare
|
I fixed the errors stated by the build pipeline. |
lsiepel
left a comment
There was a problem hiding this comment.
Thanks you for your contribution. There are some minor comments to fix. Besides the added registers, there are more changes (like default poll interval) could you list the changes clearly in the start post? It's ok for now, but we usually prefer to have the changes seperated, it makes it easier to backport changes, improve review speed and it improve the release notes / documentation.
As some channels are removed and others are added, this PR also needs upgrade instructions. For reference: https://www.openhab.org/docs/developer/bindings/thing-xml.html#updating-thing-types You could also inspect a binding (like plugwiseha) to see how it works.
bundles/org.openhab.binding.modbus.sungrow/doc/WiNet-S2_Modbus.png
Outdated
Show resolved
Hide resolved
...sungrow/src/main/java/org/openhab/binding/modbus/sungrow/internal/mapper/ToStringMapper.java
Outdated
Show resolved
Hide resolved
.../src/main/java/org/openhab/binding/modbus/sungrow/internal/mapper/impl/DeviceTypeMapper.java
Outdated
Show resolved
Hide resolved
...ow/src/main/java/org/openhab/binding/modbus/sungrow/internal/mapper/impl/DrmStateMapper.java
Outdated
Show resolved
Hide resolved
bundles/org.openhab.binding.modbus.sungrow/src/main/resources/OH-INF/thing/thing-types.xml
Outdated
Show resolved
Hide resolved
bundles/org.openhab.binding.modbus.sungrow/src/main/resources/OH-INF/thing/thing-types.xml
Outdated
Show resolved
Hide resolved
bundles/org.openhab.binding.modbus.sungrow/src/main/resources/OH-INF/thing/thing-types.xml
Outdated
Show resolved
Hide resolved
bundles/org.openhab.binding.modbus.sungrow/src/main/resources/OH-INF/thing/thing-types.xml
Outdated
Show resolved
Hide resolved
bundles/org.openhab.binding.modbus.sungrow/src/main/resources/OH-INF/thing/thing-types.xml
Outdated
Show resolved
Hide resolved
|
As mentioned in the issue #17486, this breaks compatibility with inverters that don't provide this additional registers and requires a little more refactoring. |
|
I just had one idea how to solve this problem: We could add a new flag for all registers "optional".
The thing-initialization could then be done as follows:
As in 2 only the optional registers are checked, the amount of modbus/network requests is lower (than checking every register). This has the following advantages:
How do you think about? |
b253c19 to
18a8bb5
Compare
Hi, your idea sounds good. I'll have a look at this later. For now I tried to correct the points from the review above. |
Only 2 comments are left open. |
|
Gentle ping @tscholand code freeze for oh5 is sunday, so if you want to have this in oh5, please look at the remaining comments. |
There was a problem hiding this comment.
Pull Request Overview
This PR adds numerous new registers to the Sungrow modbus binding, expanding the range of data available from Sungrow inverters. The implementation follows the Communication Protocol of Residential Hybrid Inverter V1.1.5 documentation and includes power flow information, additional MPPT channels, backup power data, and various settings.
Key changes include:
- Added power flow status registers with bit-level state extraction
- Introduced new mapper classes for string state conversion (device type, running state, output type, DRM state)
- Extended channel support for MPPT3/4, backup power information, and high-precision measurements
- Updated test coverage for new functionality
Reviewed Changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| SungrowInverterRegistersTest.java | Added comprehensive tests for new device type mapping, power flow states, and percent state handling |
| thing-types.xml | Extensive XML configuration additions for new channel groups and channel types |
| sungrow.properties | Added internationalization labels for all new channels and channel groups |
| RunningStateMapper.java | New mapper for converting hex codes to human-readable running states |
| OutputTypeMapper.java | New mapper for output type conversion (SINGLE, 3P4L, 3P3L) |
| DrmStateMapper.java | New mapper for DRM state values with uncertainty noted in comments |
| DeviceTypeMapper.java | New mapper for device type hex codes to model names |
| ToStringMapper.java | New interface for BigDecimal to String mapping functionality |
| SungrowInverterRegisters.java | Major expansion with 40+ new registers, new state factories, and improved scaling constants |
| ConversionConstants.java | Added new scaling constants and improved precision in temperature conversion |
| README.md | Updated documentation with new specification version and simplified inverter list |
Comments suppressed due to low confidence (1)
bundles/org.openhab.binding.modbus.sungrow/src/test/java/org/openhab/binding/modbus/sungrow/internal/SungrowInverterRegistersTest.java:112
- [nitpick] The variable name POWERFLOW_STATE should follow camelCase convention and be named powerFlowState instead of using SCREAMING_SNAKE_CASE which is typically reserved for constants.
final String POWERFLOW_STATE = "10010011";
...ow/src/main/java/org/openhab/binding/modbus/sungrow/internal/mapper/impl/DrmStateMapper.java
Show resolved
Hide resolved
| try { | ||
| String binaryString = Integer.toBinaryString(value.intValue()); | ||
| StringBuilder sb = new StringBuilder(binaryString); | ||
| sb.reverse(); // binary notation is backwards (10100: the last 0 is bit0). Note that there are no | ||
| // leading zeros! | ||
| char bitChar = sb.charAt(bitIndex); | ||
| if (Character.getNumericValue(bitChar) == 1) { | ||
| return OnOffType.ON; | ||
| } | ||
| } catch (IndexOutOfBoundsException e) { | ||
| // There was no bit at the bitIndex. No leading zeros in bit representation. Return OFF. | ||
| } |
There was a problem hiding this comment.
Using exceptions for control flow is generally discouraged. Consider checking the string length before accessing the character at bitIndex to avoid the exception.
| try { | |
| String binaryString = Integer.toBinaryString(value.intValue()); | |
| StringBuilder sb = new StringBuilder(binaryString); | |
| sb.reverse(); // binary notation is backwards (10100: the last 0 is bit0). Note that there are no | |
| // leading zeros! | |
| char bitChar = sb.charAt(bitIndex); | |
| if (Character.getNumericValue(bitChar) == 1) { | |
| return OnOffType.ON; | |
| } | |
| } catch (IndexOutOfBoundsException e) { | |
| // There was no bit at the bitIndex. No leading zeros in bit representation. Return OFF. | |
| } | |
| String binaryString = Integer.toBinaryString(value.intValue()); | |
| StringBuilder sb = new StringBuilder(binaryString); | |
| sb.reverse(); // binary notation is backwards (10100: the last 0 is bit0). Note that there are no | |
| // leading zeros! | |
| if (bitIndex < sb.length()) { | |
| char bitChar = sb.charAt(bitIndex); | |
| if (Character.getNumericValue(bitChar) == 1) { | |
| return OnOffType.ON; | |
| } | |
| } | |
| // If bitIndex is out of bounds or the bit is 0, return OFF. |
| String binaryString = Integer.toBinaryString(value.intValue()); | ||
| StringBuilder sb = new StringBuilder(binaryString); | ||
| sb.reverse(); // binary notation is backwards (10100: the last 0 is bit0). Note that there are no | ||
| // leading zeros! | ||
| char bitChar = sb.charAt(bitIndex); | ||
| if (Character.getNumericValue(bitChar) == 1) { | ||
| return OnOffType.ON; | ||
| } | ||
| } catch (IndexOutOfBoundsException e) { | ||
| // There was no bit at the bitIndex. No leading zeros in bit representation. Return OFF. |
There was a problem hiding this comment.
Creating a StringBuilder and reversing it for each bit check is inefficient. Consider using bitwise operations like ((value.intValue() >> bitIndex) & 1) == 1 for better performance.
| String binaryString = Integer.toBinaryString(value.intValue()); | |
| StringBuilder sb = new StringBuilder(binaryString); | |
| sb.reverse(); // binary notation is backwards (10100: the last 0 is bit0). Note that there are no | |
| // leading zeros! | |
| char bitChar = sb.charAt(bitIndex); | |
| if (Character.getNumericValue(bitChar) == 1) { | |
| return OnOffType.ON; | |
| } | |
| } catch (IndexOutOfBoundsException e) { | |
| // There was no bit at the bitIndex. No leading zeros in bit representation. Return OFF. | |
| int intValue = value.intValue(); | |
| if (((intValue >> bitIndex) & 1) == 1) { // Extract the bit at the specified index | |
| return OnOffType.ON; | |
| } | |
| } catch (ArithmeticException e) { | |
| // Handle cases where bitIndex is invalid (e.g., negative or too large). Return OFF. |
bundles/org.openhab.binding.modbus.sungrow/src/main/resources/OH-INF/thing/thing-types.xml
Outdated
Show resolved
Hide resolved
|
@tscholand Let me know when we can proceed and fix the last few comments, i think we are close to succesfully merging this PR. |
|
Hi @lsiepel , |
|
Maybe it is enough to create a configuration option If needed i can help to add this as it woudl be a straight forward 15 minuten task and prevnts the work done on this PR to be lost. |
|
I'll give it a try to check, which registers are causing this problems and give a status update, once i've new information on this. |
|
So i've tested and checked today. I've checked some of the registers from the error messages with QModbusMaster. Result: I've checked out the PR and rebased onto the current main and tested some things:
I now sometimes get a SocketTimeoutException when reading data, but i've recently fixed #19186 and added retries when reading data. I've only one explanation for this: Recently my inverter got a firmware update and afterwards some modbus registers stopped working (battary level was 100% all the time, btw. iSolarCloud App und Website behaved the same, as they relay on same data). Someday (without any actions, while waiting for technican, the cloud showed the correct data, but not the modbus export. I've then switched from winet-s dongle to internal lan port, (which did not work at all when implementing this binding). I've also written a tool based on the openhab modbus code, that queries every single sungrow register and checks if this throws an error. But nothing happend, evereything went okay :/ So i've tried to get some version information from the inverter and added thing properties for device type, software version, protocol version etc. This may help to figure out differences, when getting user feedback. One point i've remarked: @tscholand I would suggest to omit the channels that provide "static" data as Device model, output and nominal power (and have already added them as properties. Did you have anything in mind to provide them as channel instead of properties? |
|
@soenkekueper I did not have anything special in mind, when adding the static values as channels. I was just trying to get all the values from the registers into openhab. But I guess it does not really make sense to provide static values as channels. |
|
So i've just
see https://github.com/soenkekueper/openhab-addons/tree/sungrow_additions @tscholand Maybe you want to have a look at my changes and afterwards i would suggest to provide this to the community to do some wider tests (as only us two). If there are no problems occuring - i would be happy to see this merged. Sorry for my first reactions - but i've made bad experiences during implementation and wanted to keep this binding as stable as possible. |
|
@soenkekueper I installed the addon with your latest changes and it seems to work for me. The only things, that are still off:
But even without fixing that, I would like to see this merged. :-) |
|
Please also fix the conflict. |
Hey, the power factor is explained here: The register mapping was correct, but the channel type was declared as Number:Dimensionless, so the value will be displayed as percentage. Just change the item to be number, and the value will be displayed correct. I've pushed a commit that changes the default value within thing-types.xml for this. DRM value seems to be valid, as i've no device attached the value is unkown too. |
Fixes openhab#17486 Signed-off-by: Tim <tim.scholand@gmail.com>
Signed-off-by: Sönke Küper <soenkekueper@gmx.de>
Signed-off-by: Sönke Küper <soenkekueper@gmx.de>
Signed-off-by: Sönke Küper <soenkekueper@gmx.de>
Signed-off-by: Sönke Küper <soenkekueper@gmx.de>
Signed-off-by: Sönke Küper <soenkekueper@gmx.de>
Signed-off-by: Sönke Küper <soenkekueper@gmx.de>
Signed-off-by: Sönke Küper <soenkekueper@gmx.de>
Signed-off-by: Sönke Küper <soenkekueper@gmx.de>
Signed-off-by: Sönke Küper <soenkekueper@gmx.de>
Signed-off-by: Sönke Küper <soenkekueper@gmx.de>
Signed-off-by: Sönke Küper <soenkekueper@gmx.de>
…sionless value. Signed-off-by: Sönke Küper <soenkekueper@gmx.de>
Signed-off-by: Sönke Küper <soenkekueper@gmx.de>
I've just rebased my branch upon the latest upstream/main branch without conflicts or problems. @tscholand May you rebase your branch (and with that this PR) upon my branch so this PR is up-to-date? |
18a8bb5 to
5ff0472
Compare
|
So, I rebased the PR and it now contains @soenkekueper's commits. However, it says, there is still one requested change. I'm not sure, what that change is... |
|
There are two burried comments left from me: There are also some copilot review comments. Please comment on each one so we can finish up this PR. |
|
I commented on the requested changes and resolved them, but it is still showing 1 requested change... |
...ungrow/src/main/java/org/openhab/binding/modbus/sungrow/internal/SungrowInverterHandler.java
Outdated
Show resolved
Hide resolved
...ungrow/src/main/java/org/openhab/binding/modbus/sungrow/internal/SungrowInverterHandler.java
Outdated
Show resolved
Hide resolved
Signed-off-by: Tim <tim.scholand@gmail.com>
|
Sorry, i asked this before and it somehow got lost in the conversation, but as the existing thing types are changed, upgrade instructions are expected. You can also check a binding like plugwiseha to see this in action. |


[modbus.sungrow] Added some more registers
This is my first contribution to openhab and my first work with modbus.
Description
I added some registers, among others (power flow state, mppt3 and mppt4 and some more), using the documentation "Communication Protocol of Residential Hybrid Inverter V1.1.5".
This should fix issue #17486
Testing
We need to get some positive testing feedback from people, who use the current version of the addon, as I am not 100% sure, if querying the added registers might produce errors or even render the addon unusable for them.
Testing can be done with the jar at https://github.com/tscholand/openhab-addons/releases/download/TESTING/org.openhab.binding.modbus.sungrow-5.0.0-SNAPSHOT.jar