I created an issue with attachment https://github.com/apache/plc4x/issues/743
On Sun, Jan 15, 2023 at 5:02 PM Christofer Dutz <[email protected]> wrote: > Could you do a wireshark dump and attach that to an issue? > > Chris > > From: Christofer Dutz <[email protected]> > Date: Sunday, 15. January 2023 at 16:47 > To: [email protected] <[email protected]> > Subject: Re: [Modbus] Handling 'too large' blocks of registers > Hi Niels, > > I think this might be related to what happens when reading Strings in S7 > without providing a length. > In this case each string is 255 charaters long and it already exceeds the > size-limit of 200 or so of a S7 1200. > > In S7 we use some code to split up multiple tags into multiple requests, > but rewriting the query to support automatic splitting of one single tag > into multiple requests is quite a bit more difficult. > > I thought you were reading multiple tags that in sum exceeded the 125 > registers and for that case simply something similar to the S7 query > updater should also work for other protocols. > > Do I understand you correctly, that in your case you want to read one tag, > that is bigger? > > Chris > > From: Niels Basjes <[email protected]> > Date: Sunday, 15. January 2023 at 16:38 > To: [email protected] <[email protected]> > Subject: [Modbus] Handling 'too large' blocks of registers > Hi, > > A few weeks ago some code of mine was merged to limit the number of > registers that can be requested in a single ModbusTag because asking for > more than 125 registers in a single request will always fail (because of > the way modbus works). > https://github.com/apache/plc4x/pull/721 > > One of the comments was asking if it can be automated in a generic way to > split a "too large" request into multiple smaller requests. > So If I ask for a block of 200 registers then plc4x would simply split it > into multiple requests (like 125 and 75 for example, or 100 and 100) and > afterwards merge the resulting registers of the two requests back into a > single block of 200 registers for the upstream application to analyze. > > I said I would look into this and this is what I found while doing some > experimenting with my real solar converter. > This device uses the SunSpec standard for defining meaning to modbus > registers. > > My current conclusion at this point is that it is impossible to handle this > at the modbus level and I'm looking for you guys to challenge me in this. > > Why do I say this? > One of the logical values you can retrieve is the name of the Manufacturer > and the Model of the device that are both stored as UTF-8 in a set of 16 > registers (i.e. usually 32 characters). > https://github.com/sunspec/models/blob/master/json/model_1.json#L27 > https://github.com/sunspec/models/blob/master/json/model_1.json#L36 > > I found that if I try to fetch only a part of this logical value I get > either an error (INVALID_ADDRESS) or bad data. > When I fetch the entire value I get the 16 registers which hold the correct > data. > > Output of my test program that fetches the Model of the device (which is in > my case "SB3.6-1AV-41" ). > ModbusTag[4x40021:UINT[16]]: 0x5342 0x332E 0x362D 0x3141 0x562D 0x3431 > 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 > ModbusTag[4x40021:UINT[15]]: INVALID_ADDRESS > ModbusTag[4x40022:UINT[15]]: 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF > 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF > > So if I retrieve the correct block I get it. > If I try to get 1 register less than I should I get an error. > If I try to get the registers starting from the 2nd register I get only > 0xFFFF (important: NO error and a PlcResponseCode.OK !!) > > I expect there to be many other modbus devices that have similar effects > when the logical value requires multiple registers. > > So for now I come to the conclusion that fetching only part of the > registers that make up a logical variable in general will not work and (in > some cases) cannot be detected to have failed. > > At this point my assessment is that the only way to handle this is by > actually knowing the meaning of the block of registers (i.e. which must be > read together in a single read) and work from there. > > Note that the current SunSpec definition also has the concept of a 'sync' > group of points (logical values that consist of 1 or more registers) which > are grouped in the specification with the intent of "indicating > that the points in the group must be read and written atomically", which > effectively means you cannot read them individually from the modbus > standpoint. > > Looking for your feedback on this. > Do you know of existing software to generically handle this ? > > -- > Best regards / Met vriendelijke groeten, > > Niels Basjes > -- Best regards / Met vriendelijke groeten, Niels Basjes
