Reading data from Huawei inverter SUN 2000 (3KTL-10KTL) via modbus TCP and RTU

Proper setup migh depend on inverter model/firmware. The error message you got indicates that you read to little data to map it to expected type. As far I remember you need 4 bytes for uint32 (32 bits / 8 per byte => 4 bytes => 2 data registers). Make sure you adjust also read length/end.
Overall advice from huawei support I got was to read larger blocks but less often. The timeout might be result of improper handling of errors on SDongle/inverter, generally you can then assume that configuration is invalid.

Is there any documentation to check what are the address of those registries ? Otherwise it’s a high chance that I will be reading some random data. For instance I’m reading an address of 37002 and it gives me some value between 10,000 and 50,000. How would I know what I’m reading?

After reading the thread again as well as “SUN2000L V200R001 MODBUS Interface Definitions” doc file now I get it … and what’s important I made it running.

As I have all the data, I want to visualise it. Is the energie.widget.json file shared there applicable for OH4?
I don’t have much an experience with habpanel. How can I add that widget?

Each UI is a separate component, you might look at widgets shared in marketplace category as they have some examples of PV/energy widgets, but for mainui.
Ideally if you run into troubles with habpanel widget you can start new thread with more precise description of issue.

Hi,

with the help of this topic I was able to integrate my Huawei inverter into OH.
In general its working fine, however I receive random timeout errors with the setup below.

Question:
Any best practice / guidance someone can share on configuring the connection / timing / retry parameter in a better way?

Thanks in advance for any help!

  • SUN2000-4KTL-M1 inverter (SW: V100R001C00SPC153)
  • LUNA2000 battery (SW: V100R002C00SPC119)
  • Smart Dongle A-05 (SW: V100R001C00SPC125)

1 TCP thing:

thingTypeUID: modbus:tcp
configuration:
  rtuEncoded: false
  connectMaxTries: 3
  reconnectAfterMillis: 20000
  timeBetweenTransactionsMillis: 5000
  port: 502
  timeBetweenReconnectMillis: 10
  connectTimeoutMillis: 10000
  host: 192.168.58.144
  afterConnectionDelayMillis: 10000
  id: 1
  enableDiscovery: false

5 Poller things, all with the following config (of cause with different start & length):

thingTypeUID: modbus:poller
configuration:
  length: 4
  start: 37015
  refresh: 60000
  maxTries: 3
  cacheMillis: 50
  type: holding

10 Data things, all with the following config:

thingTypeUID: modbus:data
configuration:
  readValueType: uint16
  readTransform: JS:divide.js?d=10
  writeTransform: default
  readStart: "37004"
  updateUnchangedValuesEveryMillis: 30000
  writeMultipleEvenWithSingleRegisterOrCoil: false
  writeMaxTries: 3

and the following error messages in:

==> /var/log/openhab/openhab.log <==
2023-12-31 12:41:22.262 [WARN ] [rt.modbus.internal.ModbusManagerImpl] - Try 1 out of 3 failed when executing request (ModbusReadRequestBlueprint [slaveId=1, functionCode=READ_MULTIPLE_REGISTERS, start=32080, length=2, maxTries=3]). Will try again soon. Error was I/O error, so resetting the connection. Error details: net.wimpi.modbus.ModbusIOException I/O exception: SocketTimeoutException Read timed out [operation ID 99eaa83d-055d-4117-9330-8346f5404ce5]
2023-12-31 12:41:32.282 [WARN ] [rt.modbus.internal.ModbusManagerImpl] - Try 2 out of 3 failed when executing request (ModbusReadRequestBlueprint [slaveId=1, functionCode=READ_MULTIPLE_REGISTERS, start=32080, length=2, maxTries=3]). Will try again soon. The response did not match the request. Resetting the connection. Error details: org.openhab.core.io.transport.modbus.exception.ModbusUnexpectedTransactionIdException Transaction id of request (16715) does not equal response (16714). Slave response is invalid. [operation ID 99eaa83d-055d-4117-9330-8346f5404ce5]
2023-12-31 12:42:27.269 [WARN ] [rt.modbus.internal.ModbusManagerImpl] - Try 1 out of 3 failed when executing request (ModbusReadRequestBlueprint [slaveId=1, functionCode=READ_MULTIPLE_REGISTERS, start=37113, length=12, maxTries=3]). Will try again soon. Error was I/O error, so resetting the connection. Error details: net.wimpi.modbus.ModbusIOException I/O exception: SocketTimeoutException Read timed out [operation ID 142ed2b6-0263-40e4-879d-7a71fa68a91f]
1 Like

I wrote some time ago about this, there is a severe bug in SDongle, it confuses requests when multiple connections are being made. Make sure you have only one tcp connection at the time!

Don’t ask how I found it. :wink:

That sounds reasonable.

I only have OH connecting via modbus to the dongle and using the fusion solar app. As the app is not using modbus it will not count towards the connection limit (at least that’s my understanding).

There is no other device / server (beside OH) that will connect to the dongle.

How can I configure my things, that they do not create multiple connections (I only have 1 tcp thing)?

Hi Matze,

would it be possible to post your full setup? Items, things etc?
I don’t get it working unforunately :-/

Thanks in advance.

I can have a look later, as I have managed everything via UI I need to copy and paste this.

I tried item based configuration before an also was failing, as all things went online at the same time and to many poller sending requests. Only if I enable one thing slowly after another, it will work.

Maybe that’s already helpful to know

1 Like

Which firmware do you have? I get every Bridge and Thing online, but the Items only contains NULL values. And the log file is full of error…

Dongle firmware V100R001C00SPC125
Inverter (SUN2000-5KTL-M1) Firmware: V100R001C00SPC153

2024-02-10 09:50:09.129 [WARN ] [rt.modbus.internal.ModbusManagerImpl] - Execution of scheduled (5000ms) poll task BasicPollTask [getEndpoint=ModbusIPSlaveEndpoint [address=wechselrichter.fritz.box, port=502], request=ModbusReadRequestBlueprint [slaveId=1, functionCode=READ_MULTIPLE_REGISTERS, start=32064, length=31, maxTries=3], getResultCallback()=org.openhab.binding.modbus.handler.ModbusPollerThingHandler$ReadCallbackDelegator@2c11578f, getFailureCallback()=org.openhab.binding.modbus.handler.ModbusPollerThingHandler$ReadCallbackDelegator@2c11578f] failed unexpectedly. Ignoring exception, polling again according to poll interval.
java.lang.NullPointerException: Cannot invoke "java.util.Map.put(Object, Object)" because "this.global" is null
	at com.oracle.truffle.js.scriptengine.GraalJSBindings.put(GraalJSBindings.java:130) ~[?:?]
	at javax.script.SimpleScriptContext.setAttribute(SimpleScriptContext.java:246) ~[java.scripting:?]
	at org.openhab.core.automation.module.script.ScriptTransformationService.transform(ScriptTransformationService.java:187) ~[?:?]
	at org.openhab.binding.modbus.internal.SingleValueTransformation.transform(SingleValueTransformation.java:140) ~[?:?]
	at org.openhab.binding.modbus.internal.CascadedValueTransformationImpl.transform(CascadedValueTransformationImpl.java:50) ~[?:?]
	at org.openhab.binding.modbus.internal.ValueTransformation.transformState(ValueTransformation.java:48) ~[?:?]
	at org.openhab.binding.modbus.internal.handler.ModbusDataThingHandler.lambda$16(ModbusDataThingHandler.java:999) ~[?:?]
	at java.util.HashMap$KeySpliterator.forEachRemaining(HashMap.java:1707) ~[?:?]
	at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762) ~[?:?]
	at org.openhab.binding.modbus.internal.handler.ModbusDataThingHandler.processUpdatedValue(ModbusDataThingHandler.java:967) ~[?:?]
	at org.openhab.binding.modbus.internal.handler.ModbusDataThingHandler.onRegisters(ModbusDataThingHandler.java:845) ~[?:?]
	at org.openhab.binding.modbus.internal.handler.ModbusDataThingHandler.lambda$11(ModbusDataThingHandler.java:799) ~[?:?]
	at java.util.Optional.ifPresent(Optional.java:178) ~[?:?]
	at org.openhab.binding.modbus.internal.handler.ModbusDataThingHandler.onReadResult(ModbusDataThingHandler.java:799) ~[?:?]
	at org.openhab.binding.modbus.handler.ModbusPollerThingHandler$ReadCallbackDelegator.lambda$2(ModbusPollerThingHandler.java:144) ~[?:?]
	at java.util.concurrent.CopyOnWriteArrayList.forEach(CopyOnWriteArrayList.java:807) ~[?:?]
	at org.openhab.binding.modbus.handler.ModbusPollerThingHandler$ReadCallbackDelegator.notifyChildren(ModbusPollerThingHandler.java:142) ~[?:?]
	at org.openhab.binding.modbus.handler.ModbusPollerThingHandler$ReadCallbackDelegator.handleResult(ModbusPollerThingHandler.java:88) ~[?:?]
	at org.openhab.binding.modbus.handler.ModbusPollerThingHandler$ReadCallbackDelegator.handle(ModbusPollerThingHandler.java:105) ~[?:?]
	at org.openhab.core.io.transport.modbus.internal.ModbusLibraryWrapper.invokeCallbackWithResponse(ModbusLibraryWrapper.java:332) ~[?:?]
	at org.openhab.core.io.transport.modbus.internal.ModbusManagerImpl$PollOperation.lambda$1(ModbusManagerImpl.java:216) ~[?:?]
	at org.openhab.core.io.transport.modbus.internal.SimpleStopWatch.timeRunnable(SimpleStopWatch.java:152) ~[?:?]
	at org.openhab.core.io.transport.modbus.internal.ModbusManagerImpl$PollOperation.accept(ModbusManagerImpl.java:216) ~[?:?]
	at org.openhab.core.io.transport.modbus.internal.ModbusManagerImpl$PollOperation.accept(ModbusManagerImpl.java:1) ~[?:?]
	at org.openhab.core.io.transport.modbus.internal.ModbusManagerImpl.executeOperation(ModbusManagerImpl.java:613) ~[?:?]
	at org.openhab.core.io.transport.modbus.internal.ModbusManagerImpl$ModbusCommunicationInterfaceImpl.lambda$1(ModbusManagerImpl.java:810) ~[?:?]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) [?:?]
	at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) [?:?]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) [?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) [?:?]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) [?:?]
	at java.lang.Thread.run(Thread.java:840) [?:?]
2024-02-10 09:50:24.501 [WARN ] [rt.modbus.internal.ModbusManagerImpl] - Execution of scheduled (10000ms) poll task BasicPollTask [getEndpoint=ModbusIPSlaveEndpoint [address=wechselrichter.fritz.box, port=502], request=ModbusReadRequestBlueprint [slaveId=1, functionCode=READ_MULTIPLE_REGISTERS, start=30073, length=10, maxTries=3], getResultCallback()=org.openhab.binding.modbus.handler.ModbusPollerThingHandler$ReadCallbackDelegator@31dc4737, getFailureCallback()=org.openhab.binding.modbus.handler.ModbusPollerThingHandler$ReadCallbackDelegator@31dc4737] failed unexpectedly. Ignoring exception, polling again according to poll interval.
java.lang.NullPointerException: Cannot invoke "java.util.Map.put(Object, Object)" because "this.global" is null
	at com.oracle.truffle.js.scriptengine.GraalJSBindings.put(GraalJSBindings.java:130) ~[?:?]
	at javax.script.SimpleScriptContext.setAttribute(SimpleScriptContext.java:246) ~[java.scripting:?]
	at org.openhab.core.automation.module.script.ScriptTransformationService.transform(ScriptTransformationService.java:187) ~[?:?]
	at org.openhab.binding.modbus.internal.SingleValueTransformation.transform(SingleValueTransformation.java:140) ~[?:?]
	at org.openhab.binding.modbus.internal.CascadedValueTransformationImpl.transform(CascadedValueTransformationImpl.java:50) ~[?:?]
	at org.openhab.binding.modbus.internal.ValueTransformation.transformState(ValueTransformation.java:48) ~[?:?]
	at org.openhab.binding.modbus.internal.handler.ModbusDataThingHandler.lambda$16(ModbusDataThingHandler.java:999) ~[?:?]
	at java.util.HashMap$KeySpliterator.forEachRemaining(HashMap.java:1707) ~[?:?]
	at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762) ~[?:?]
	at org.openhab.binding.modbus.internal.handler.ModbusDataThingHandler.processUpdatedValue(ModbusDataThingHandler.java:967) ~[?:?]
	at org.openhab.binding.modbus.internal.handler.ModbusDataThingHandler.onRegisters(ModbusDataThingHandler.java:845) ~[?:?]
	at org.openhab.binding.modbus.internal.handler.ModbusDataThingHandler.lambda$11(ModbusDataThingHandler.java:799) ~[?:?]
	at java.util.Optional.ifPresent(Optional.java:178) ~[?:?]
	at org.openhab.binding.modbus.internal.handler.ModbusDataThingHandler.onReadResult(ModbusDataThingHandler.java:799) ~[?:?]
	at org.openhab.binding.modbus.handler.ModbusPollerThingHandler$ReadCallbackDelegator.lambda$2(ModbusPollerThingHandler.java:144) ~[?:?]
	at java.util.concurrent.CopyOnWriteArrayList.forEach(CopyOnWriteArrayList.java:807) ~[?:?]
	at org.openhab.binding.modbus.handler.ModbusPollerThingHandler$ReadCallbackDelegator.notifyChildren(ModbusPollerThingHandler.java:142) ~[?:?]
	at org.openhab.binding.modbus.handler.ModbusPollerThingHandler$ReadCallbackDelegator.handleResult(ModbusPollerThingHandler.java:88) ~[?:?]
	at org.openhab.binding.modbus.handler.ModbusPollerThingHandler$ReadCallbackDelegator.handle(ModbusPollerThingHandler.java:105) ~[?:?]
	at org.openhab.core.io.transport.modbus.internal.ModbusLibraryWrapper.invokeCallbackWithResponse(ModbusLibraryWrapper.java:332) ~[?:?]
	at org.openhab.core.io.transport.modbus.internal.ModbusManagerImpl$PollOperation.lambda$1(ModbusManagerImpl.java:216) ~[?:?]
	at org.openhab.core.io.transport.modbus.internal.SimpleStopWatch.timeRunnable(SimpleStopWatch.java:152) ~[?:?]
	at org.openhab.core.io.transport.modbus.internal.ModbusManagerImpl$PollOperation.accept(ModbusManagerImpl.java:216) ~[?:?]
	at org.openhab.core.io.transport.modbus.internal.ModbusManagerImpl$PollOperation.accept(ModbusManagerImpl.java:1) ~[?:?]
	at org.openhab.core.io.transport.modbus.internal.ModbusManagerImpl.executeOperation(ModbusManagerImpl.java:613) ~[?:?]
	at org.openhab.core.io.transport.modbus.internal.ModbusManagerImpl$ModbusCommunicationInterfaceImpl.lambda$1(ModbusManagerImpl.java:810) ~[?:?]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) [?:?]
	at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) [?:?]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) [?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) [?:?]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) [?:?]
	at java.lang.Thread.run(Thread.java:840) [?:?]
2024-02-10 09:50:40.411 [WARN ] [rt.modbus.internal.ModbusManagerImpl] - Execution of scheduled (5000ms) poll task BasicPollTask [getEndpoint=ModbusIPSlaveEndpoint [address=wechselrichter.fritz.box, port=502], request=ModbusReadRequestBlueprint [slaveId=1, functionCode=READ_MULTIPLE_REGISTERS, start=32064, length=31, maxTries=3], getResultCallback()=org.openhab.binding.modbus.handler.ModbusPollerThingHandler$ReadCallbackDelegator@2c11578f, getFailureCallback()=org.openhab.binding.modbus.handler.ModbusPollerThingHandler$ReadCallbackDelegator@2c11578f] failed unexpectedly. Ignoring exception, polling again according to poll interval.
java.lang.NullPointerException: Cannot invoke "java.util.Map.put(Object, Object)" because "this.global" is null
	at com.oracle.truffle.js.scriptengine.GraalJSBindings.put(GraalJSBindings.java:130) ~[?:?]
	at javax.script.SimpleScriptContext.setAttribute(SimpleScriptContext.java:246) ~[java.scripting:?]
	at org.openhab.core.automation.module.script.ScriptTransformationService.transform(ScriptTransformationService.java:187) ~[?:?]
	at org.openhab.binding.modbus.internal.SingleValueTransformation.transform(SingleValueTransformation.java:140) ~[?:?]
	at org.openhab.binding.modbus.internal.CascadedValueTransformationImpl.transform(CascadedValueTransformationImpl.java:50) ~[?:?]
	at org.openhab.binding.modbus.internal.ValueTransformation.transformState(ValueTransformation.java:48) ~[?:?]
	at org.openhab.binding.modbus.internal.handler.ModbusDataThingHandler.lambda$16(ModbusDataThingHandler.java:999) ~[?:?]
	at java.util.HashMap$KeySpliterator.forEachRemaining(HashMap.java:1707) ~[?:?]
	at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762) ~[?:?]
	at org.openhab.binding.modbus.internal.handler.ModbusDataThingHandler.processUpdatedValue(ModbusDataThingHandler.java:967) ~[?:?]
	at org.openhab.binding.modbus.internal.handler.ModbusDataThingHandler.onRegisters(ModbusDataThingHandler.java:845) ~[?:?]
	at org.openhab.binding.modbus.internal.handler.ModbusDataThingHandler.lambda$11(ModbusDataThingHandler.java:799) ~[?:?]
	at java.util.Optional.ifPresent(Optional.java:178) ~[?:?]
	at org.openhab.binding.modbus.internal.handler.ModbusDataThingHandler.onReadResult(ModbusDataThingHandler.java:799) ~[?:?]
	at org.openhab.binding.modbus.handler.ModbusPollerThingHandler$ReadCallbackDelegator.lambda$2(ModbusPollerThingHandler.java:144) ~[?:?]
	at java.util.concurrent.CopyOnWriteArrayList.forEach(CopyOnWriteArrayList.java:807) ~[?:?]
	at org.openhab.binding.modbus.handler.ModbusPollerThingHandler$ReadCallbackDelegator.notifyChildren(ModbusPollerThingHandler.java:142) ~[?:?]
	at org.openhab.binding.modbus.handler.ModbusPollerThingHandler$ReadCallbackDelegator.handleResult(ModbusPollerThingHandler.java:88) ~[?:?]
	at org.openhab.binding.modbus.handler.ModbusPollerThingHandler$ReadCallbackDelegator.handle(ModbusPollerThingHandler.java:105) ~[?:?]
	at org.openhab.core.io.transport.modbus.internal.ModbusLibraryWrapper.invokeCallbackWithResponse(ModbusLibraryWrapper.java:332) ~[?:?]
	at org.openhab.core.io.transport.modbus.internal.ModbusManagerImpl$PollOperation.lambda$1(ModbusManagerImpl.java:216) ~[?:?]
	at org.openhab.core.io.transport.modbus.internal.SimpleStopWatch.timeRunnable(SimpleStopWatch.java:152) ~[?:?]
	at org.openhab.core.io.transport.modbus.internal.ModbusManagerImpl$PollOperation.accept(ModbusManagerImpl.java:216) ~[?:?]
	at org.openhab.core.io.transport.modbus.internal.ModbusManagerImpl$PollOperation.accept(ModbusManagerImpl.java:1) ~[?:?]
	at org.openhab.core.io.transport.modbus.internal.ModbusManagerImpl.executeOperation(ModbusManagerImpl.java:613) ~[?:?]
	at org.openhab.core.io.transport.modbus.internal.ModbusManagerImpl$ModbusCommunicationInterfaceImpl.lambda$1(ModbusManagerImpl.java:810) ~[?:?]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) [?:?]
	at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) [?:?]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) [?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) [?:?]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) [?:?]
	at java.lang.Thread.run(Thread.java:840) [?:?]

Dongle (SDongleA-05) V100R001C00SPC133
Inverter (SUN2000-5KTL-M1) V100R001C00SPC153

works for me

What I read from the error message is, that your script transformation is not working correctly.
Try without transformation first to validate, if the binding is working and you see the raw data.

Sorry, it took a while.

But that’s my config:

TCP thing

UID: modbus:tcp:PV_TCP
label: PV Anlage - Modbus TCP Slave
thingTypeUID: modbus:tcp
configuration:
  rtuEncoded: false
  connectMaxTries: 3
  reconnectAfterMillis: 10000
  timeBetweenTransactionsMillis: 5000
  port: 502
  timeBetweenReconnectMillis: 10
  connectTimeoutMillis: 10000
  host: XXX
  afterConnectionDelayMillis: 10000
  id: 1
  enableDiscovery: false

Poller thing (active power from the meter in this case):

UID: modbus:poller:PV_TCP:PV_Poll_Meter_ActivePower
label: PV Poll Meter Active Power
thingTypeUID: modbus:poller
configuration:
  length: 12
  start: 37113
  refresh: 60000
  maxTries: 3
  cacheMillis: 50
  type: holding
bridgeUID: modbus:tcp:PV_TCP

Data Thing:

UID: modbus:data:PV_Poll_Meter_ActivePower:PV_Data_Meter_ActivePower
label: PV Data Meter Active Power
thingTypeUID: modbus:data
configuration:
  readValueType: int32
  readTransform: JS:divide.js?d=1
  writeTransform: default
  readStart: "37113"
  updateUnchangedValuesEveryMillis: 30000
  writeMultipleEvenWithSingleRegisterOrCoil: false
  writeMaxTries: 3
bridgeUID: modbus:poller:PV_TCP:PV_Poll_Meter_ActivePower

Item is a number item linked to the “Value as Number” channel with default profile.

Things I observed:
If you tested with other tools to establish a modbus connection, maybe the old connection is still open and it helps to restart the inverter.

If you mass create the things via thing file and all things go online at the same time, it did not worked for me.
I therefore created them via gui one by one.
Also after restarting OH this sometimes leads to issues and I manually need to disable all modbus things and enable them one after the other.