OpenDTU
OpenDTU copied to clipboard
Added Modbus to OpenDTU
Added Modbus TCP/IP
Hello, Any idea why there is error? In VisualStudio Code there is not any error.
Ist die Modbus unterstützung dann auch für das OLIMEX Modul gedacht? also man kann dann direkt per LAN damit arbeiten?
the build fails as it can't find the "ModbusDTU.h" file you include
For my understanding: will this PR provide the capability to read the Hoymiles power/energy from e.g. a Kostal Smart Energy Meter? -- Or is there another use case behind?
This change allows you to read data from OpenDTU over Modbus. It runs parallel to MQTT.
@ArekKubacki can you please offer me a compiled binary? I would like to try out if this can be added at fronius gen24 as "Power Meter"
If you need Modbus registers, see here
https://github.com/ArekKubacki/OpenDTU/blob/master/src/ModbusDtu.cpp
to get sure: This would act as Modbus TCP (port 502 on OpenDTU-IP) or as Modbus RTU ? is there additional config necessary? I tried to read registers 40072 to 40193 - I think this would be sunspec, but not sure at all - but nothing there. the registers you mentioned are maybe (decimal) 4096 to 4115 ?
thanks. :-)
As TCP, port 502. No additional config necessary.
If you need Modbus registers, see here
https://github.com/ArekKubacki/OpenDTU/blob/master/src/ModbusDtu.cpp
the good thing is: something works. the bad thing is: I have no plan and knowledge to handle the data.
I can see it is not in the format which the fronius inverter would require. it would like to communicate with a "fronius smart meter" which has (like kostal seem to have in registers 8192 and upwards) vendor specific identification in registers 40001 and upwards. see some code here: https://github.com/americanium/fronius_sm_simulator/blob/a3ce3f847d0bddc48378f469ed677cf376da1fd1/bin/frsmsimulator.py#LL323C9-L323C14
out of interest: you chose modbus registers 4096 and above (at least there I get some data with node red, which I cannot interpret). is there a reason for not chosing sunspec defined one? would be (I think) 40071 and above for the data, or 40000 and above for the manufacurer specific data (like fronius has). reference for sunspec I found: https://www.kostal-solar-electric.com/en-gb/products/accessories/smart-energy-meter/-/media/document-library-folder---kse/2020/12/15/14/22/ba_kostal_interface_ksem_de.pdf page 9
the idea behind: e.g. fronius gen24 inverters offers to add "production meters" so it is able to calculate correctly the current power usage of your entire house (as soon as you add another inverter, the gen24 does not know it's production and therefore it does not know how much power you use currently in your house). the inverter powermeter(fronius smart meter) you could add is about 350€ - and additional cable needed.
so, if your implementation would follow the sunspec registers, and would offer to announce itself as "Fronius Smart Meter" it most probably could just be added ad Modbus TCP and be used. 👍 🥇
Selected registers are the same as those in the original DTU and adapted to libraries reading data from the original DTU. Unfortunately, they implemented 8-bit modbus there, which hangs all the time. Add-on designed to work with Home Assistance and add-on https://github.com/ArekKubacki/Hoymiles-Plant-DTU-Pro
When it comes to Sunspec, user should select the operating mode in the original DTU, and it should be probably the same in the case of OpenDTU. Currently, this is a redundant function for me, so adding it would have to wait.
trying on myself leads to: [{ "resource": "/d:/Profile/Documents/VSCode/OpenDTU/src/ModbusDtu.cpp", "owner": "C/C++: IntelliSense", "code": "1696", "severity": 8, "message": "cannot open source file "Arduino.h" (dependency of "ModbusDtu.h")", "source": "C/C++", "startLineNumber": 1, "startColumn": 1, "endLineNumber": 1, "endColumn": 23 },{ "resource": "/d:/Profile/Documents/VSCode/OpenDTU/src/ModbusDtu.cpp", "owner": "C/C++: IntelliSense", "code": "1696", "severity": 8, "message": "#include errors detected. Please update your includePath. Squiggles are disabled for this translation unit (D:\Profile\Documents\VSCode\OpenDTU\src\ModbusDtu.cpp).", "source": "C/C++", "startLineNumber": 1, "startColumn": 1, "endLineNumber": 1, "endColumn": 23 }]
the file itself is there - I think there are something rudimentary missing - a fresh installed vscode with your repo checked out like described in the wikipage from the project do you have any hints for me? Thanks. :-)
Are you using PlatformIO?
Are you using PlatformIO?
yes. fixed it by myself, this was most probably a (by whatever reason) not-complete installed PlatformIO extension in vscode. 🤦
@ArekKubacki can you please help me out with two values I would need?
registers 0x1038 and 0x1039 (current inverter PV Power) and registers 0x103C 0x103D 0x103E 0x103F (inverter Total Production)
I do not know which variables to use there and in case of total production how to split the values in 4 registers
so e.g. the things you did here: b.Hreg(chan* 20 + 0x100A, ((uint16_t)(((uint32_t)(inv->Statistics()->getChannelFieldValue(t, c, FLD_YT)1000)) >> 16)) & 0xFFFF); mb.Hreg(chan 20 + 0x100B, (((uint16_t)(inv->Statistics()->getChannelFieldValue(t, c, FLD_YT)*1000))) & 0xFFFF);
where FLD_YT would need the currently overall inverter PV power
and the same for interter total production splittet to 4 registers instead of two
thank you so much :-)
There you have ready to use library: https://github.com/ArekKubacki/Hoymiles-Plant-DTU-Pro/tree/main/custom_components/hoymiles_dtu/hoymiles
in python plant_data = HoymilesModbusTCP('192.168.1.xx', port=502, microinverter_type=MicroinverterType.HM, unit_id=modbusID, dtu_type=1).plant_data
I am not in python, I am in ModbusDtu.cpp I adding there registers to match the fronius smart meter stuff in reference to https://www.shinetech-power.de/wp-content/uploads/2021/07/Technical-Note-Modbus-implementation-using-3Gen-DTU-Pro-V1.2.pdf
and the only "dynamically" written register I need would match to 0x103C 0x103D 0x103E 0x103F (Total Production) and 0x1038 and 0x1039 (current inverter PV Power)
in fronius smartmeter emulation the registers 9CA1 needs to be filled with current inverter power and 9CC1 and 9CC1 for total production.
but I do not know which opendtu variables (like getChannelFieldValue(t, c, FLD_UDC) ) need to be used and how to split the values accordingly to two registers
Fornius 9CA1 = 0x1008 For power 0x100A and 0x100B
Remember, however, that if you have more than one microinverter, the addresses jump every 20. If you want to send all the power and all the production, you will not be able to do without an additional script.
thank you I could now write to the correct registers, but now I am stuck with data types (again):
e.g. the original smartmeter uses two registers to reflect the "current inverter power". in nodejs, on reading the buffers, this looks like (also with values parsed from smartmeter below): parseFloat(msg.payload.buffer.readFloatBE(52,53,54,55).toFixed(0)) where 52 and 53 are values "c5f4" from modbus register 0x9ca1 and 54 and 55 are values "e800" from modbus register 0x9ca2
the "c5f4e800" was in this case converted to "-7837"
how do I get now from (uint16_t)(inv->Statistics()->getChannelFieldValue(t, c, FLD_PDC)*10) a) to a negative value - should be only multiplied by "-10" instead of 10, should it b) furthermore to the BE float using two registers instead of one
thank you! :-)
have it. this does the trick ... (also inverter totals used) :-)
float CurrPWR = (Datastore.getTotalAcPowerEnabled()*-1); uint16_t *myhex = (uint16_t *)&CurrPWR; mb.Hreg(0x9ca1, myhex[1]); mb.Hreg(0x9ca2, myhex[0]); float TotYLD = (Datastore.getTotalAcYieldTotalEnabled()*1000); uint16_t *myhex2 = (uint16_t *)&TotYLD; mb.Hreg(0x9cc1, myhex2[1]); mb.Hreg(0x9cc2, myhex2[0]);
success 🥳
is there a reason for not merging this PR into OpenDTU?
If you need Modbus registers, see here
https://github.com/ArekKubacki/OpenDTU/blob/master/src/ModbusDtu.cpp
I tried your precompiled firmware to use Modbus with iobroker. But everything i tried failed. If I try to read a register, for example 4096 I only get an error "illegal data address". Is Modbus provided in the firmware you posted above? If not, is there a ready-to-flash firmware available?
Any chance that this will be implemented in the master branch?
@AloisKlingler @fantilator @ArekKubacki
is there a reason for not merging this PR into OpenDTU?
IMHO yes.
- The commits mess around with libraries (I assume a change in CR/LF cause by an editor).
- Every new feature which is not essentially necessary should be able to be turned on/off. At least at runtime, and if it consume a lot of codespace then it should be configurable at compile time also.
- Pull requests should look "nice" in the history of the main project when they get merged. So if this would be my project, I would not merge a PR with 22 commits and half of it are "fix this" "fix that" "merge...". I recommend a rebase of the pull request.
This is just my personal opinion, I am not the project owner.
Hello, I am new here,
@AloisKlingler is it possible that I get the AC_Power in an Register?
Unfortunately, only the DC channels are provided. I would have been more interested in the AC channel.
@ArekKubacki have you considered / asked to add your PR/changes to the OpenDTU-onBattery fork from Helge Erbe ?
I know Helge has included a couple of plugins to retrieve Power Meter readings via MQTT, so maybe adding ModBus support there might be easier and straight forward ?
https://github.com/helgeerbe/OpenDTU-OnBattery
I think that one day I will come back to mastering Modbus and creating a subpage where I can set everything up. How closely does this version follow the original OpenDTU?
@ArekKubacki I have not checked what your PR actually does, but OpenDTU-onBattery has a PowerMeter.cpp class which has support for several PowerMeter Sources, including HTTP, MQTT, SML and something called SOURCE_SDM1PH/3PH. As far as I know the SDM Smart Meters are read via ModBus / RS485 too ?
https://github.com/helgeerbe/OpenDTU-OnBattery/blob/development/src/PowerMeter.cpp
Regarding the fork Helge seems to be rather quick in merging changes which are inteoduced by Thomas in upstream OpenDTU. I can not remember any delays in the past year. So thanks to the great jobs of both project maintainers this fork is really well maintained !