TomNewChao commented on PR #2656:
URL: https://github.com/apache/plc4x/pull/2656#issuecomment-5103845018

   > Now that I had the time to catch up with everything else after my holiday 
yesterday, now I had the time to thorougly read your initial 
message.在昨天假期过后,我有时间重新整理了一下其他的事情,现在我有时间仔细阅读了你们发来的原始消息。
   > 
   > So the PLC4Net doesn't have to be identical to the Java version. It was 
allways our goal to make the libratries feel natural in their normal ecosystem. 
With Java we're using CompletableFutures, with Go we're using channels ... 
whatever is the best way to do things in the target language.因此,PLC4Net 不必与 
Java 版本完全相同。我们的目标始终是让这些库在各自的生态系统中能够自然融合。对于 Java 语言,我们使用 CompletableFutures;而对于 
Go 语言,则使用通道……无论哪种方式都能达到目标语言的最佳效果。
   > 
   > What we do try to keep, is the general usage pattern: So if connections 
are synchronous in Java, it would sort of be bad if it wasn't in other 
languages. Also if the naming of things was kept ... like the usage of "Tag" 
and "Query" and that you can add a Tag or a TagString, 
....我们努力保留的是这些通用的使用模式:如果在 Java 
中连接是同步的,那么在其他语言中这种特性就可能会变得不好用。另外,如果能够保持一些命名规范的话……比如继续使用“Tag”和“Query”这样的命名方式,并且可以添加“Tag”或“TagString”这样的元素……
   > 
   > Admittedly I don't quite understand what you mean with your first 
divergence: "ConnectionString is a public type in the API, not the SPI. It has 
no SPI dependency, and PlcDriverManager — which lives in the API — needs it to 
route the protocol code." Could you please explain 
that?诚然,我不太理解你所说的“第一次分歧”是什么意思。你的意思是:“ConnectionString 是 API 中的公共类型,而不是 SPI 
中的类型。它没有任何 SPI 依赖关系,而位于 API 中的 PlcDriverManager 则需要使用它来配置协议代码。”请能解释一下这一点吗?
   > 
   > I think when I did the first work on PLC4Net, I chose KNX as this used the 
most of our mspec-functionality ... I thought if I get this driver working, the 
rest will most probably also work. Usually when starting on a new language I 
started with Modbus as this is the simplest one of them all for which a 
test-bench is cheaply available. KNX also had this super odd encoding for 16 
bit float which isn't really a full half-precision-iec float. In the new SPI3 
java version, I think I used a dedicated float implementation:我记得在第一次开发 PLC4Net 
项目时,我选择了 KNX 作为协议选择,因为 KNX 利用了我们 MSpec 
功能的最多部分……我认为,如果我能让这个驱动程序正常工作,那么其他协议也很有可能会顺利实现。通常,在开始使用一种新的协议时,我会从 ModBus 
开始尝试,因为 ModBus 是最简单的协议之一,相关的测试平台也很便宜。而 KNX 则采用了一种非常特殊的 16 位浮点�
 ��方式,实际上并不是真正的半精度 IEC 浮点编码。在新的 SPI3 Java 版本中,我认为我们使用了专门的浮点实现方式来处理这种编码问题。
   > 
   > ```
   >         ['PDT_KNX_FLOAT' REAL
   >             [simple   float 16      value floatEncoding='"KNXFloat"']
   >         ]
   > ```
   > 
   > The implementation is here:实施工作已经开始了: 
plc4j/spi/buffers/byte/src/main/java/org/apache/plc4x/java/spi/buffers/bytebased/encoding/EncodingKnxFloat.java
   > 
   > However, I built things in SPI3 so theoretically a protocol module could 
bring along it's own Encoding implementation by putting the class in the driver 
module and registering it via a 
org.apache.plc4x.java.spi.buffers.bytebased.encoding.Encoding property 
file.不过,我使用的是 SPI3 框架来构建应用程序。因此,理论上,一个协议模块可以通过在驱动模块中引入自己的编码实现,并通过 
org.apache.plc4x.java.spi.buffers.bytebased.encoding.Encoding 属性文件来注册该编码实现。
   > 
   > As you could see I never really got very far with the .Net version as the 
person that claimed to want to help decided to go away. Usually my process was 
that I hand wrote some types from Modbus in the target language, then I copied 
the java templates and started adjusting them till the output matched the 
hand-written one. the data-io template you found was simply one copied but 
never touched by me as the work stopped before I had time to do 
that.如您所见,那个.NET 版本的工作我并没有取得太大进展。那个声称愿意帮忙的人后来就离开了。通常我的工作流程是:先用目标语言手动编写一些 Modbus 
协议的数据类型,然后复制 Java 
模板,并不断调整它们,直到输出结果与手动编写的结果一致。您看到的那个数据输入输出模板就是直接复制过来的,但我并没有对其进行任何修改,因为在我完成之前,工作就停止了。
   > 
   > As you saw on the discussion list, we're currently considering splitting 
out Go and also creating go-native code generators. Possibly this is something 
you would also like to do. Initially the idea was to have one system for 
generating code. One system anyone would understand and maintaining would 
therefore be easier. Also is it one thing to understand a programming language, 
but it's a totally different thing to understand the tooling available in a 
language, the best practices and how to nicely integrate this into a smoothly 
running build. For java and maven we knew how to do this, for the others not so 
much ;-) So the current template+maven approch was simply a quick win that we 
knew how to do.正如你在讨论帖中看到的,我们目前正在考虑将 Go 语言分离出来,同时开发专门针对 Go 
语言的代码生成工具。也许这也是你希望做的事情。最初的想法是建立一个统一的代码生成系统,这样大家就能更容易理解和维护
 这个系统。不过,理解一种编程语言是一回事,而了解该语言提供的工具、最佳实践以及如何将它们很好地整合到流畅运行的构建过程中则是另一回事。对于 Java 和 
Maven 来说,我们懂得如何做到这一点,但对于其他语言来说则不太容易哦;-)所以,目前采用模板+Maven 的方法只是我们能够成功实现的一个例子而已。
   > 
   > However, have I found out with my own closed-source work, that there are 
huge benefits for running this in a tool-native fashion ... then I guess only 
the resolution of the protocol modules would need to be implemented and the 
code-gen is built per language. The mspec format is documented in an Antlr4 
grammar for which there should be tooling in most languages. The core mspec 
format is described 
here:不过,通过我自己使用开源框架进行开发的经验来看,以工具原生的方式来实现这一功能确实有着巨大的优势……我认为,只需要实现协议模块的相关功能,然后针对每种语言分别生成相应的代码即可。mspec
 格式有相应的文档说明,它遵循 Antlr4 语法规范,因此大多数语言都应该有相应的工具来支持这种格式。关于 mspec 核心格式的描述可以在这里找到: 
code-generation/protocol-base-mspec/src/main/antlr4/org/apache/plc4x/plugins/codegenerator/language/mspec/MSpec.g4代码
 生成/协议基础 MSpec 源码目录结构如下: src/main/antlr4/ org/apache/plc4x/plugins/代码生成器/ 
language/MSpec/MSpec.g4 The expression syntax used in the little expression 
blocks inside are documented here:这些小表达式块中使用的表达式语法在这里有详细说明: 
code-generation/protocol-base-mspec/src/main/antlr4/org/apache/plc4x/plugins/codegenerator/language/mspec/expression/Expression.g4代码生成/协议基础
 MSpec 源码目录结构如下: src/main/antlr4/ org/apache/plc4x/plugins/代码生成器 -> 
language/MSpec -> expression/Expression.g4
   > 
   > I hope I manged to answer your questions ... if not ... don't hesitate to 
ask ... ideally here ... if it has to be quickly and you see I'm online in 
Slack, just ask there.希望我已经回答了你的问题……如果没有回答到的话,请随时提问。如果情况需要快速处理,而且你看到我正在 Slack 
上在线,那就直接在那里提问吧。
   
   Thanks — knowing the goal is to make the libraries feel natural in their 
normal
   ecosystem while keeping the usage pattern and the naming settles several 
things I
   was unsure about. Let me answer your question first, then lay out where I 
would
   like to take this.
   
   On the ConnectionString divergence — it does not hold up
   
   The three states side by side:
   
   
   
     (*) = the full connection-string parser
           protocol code + transport code + host + port + query params + URL 
decoding
   
   (1) and (2) are the same shape. I broke that in (3).
   
   What happened: I read "Uri cannot parse the whole s7:cotp://host form" — 
which
   is true, Host comes back empty and Port -1 — as "Uri cannot be used here"
   the manager only ever needs the protocol code, and I had never checked what 
Java
   actually does there. Both behave identically:
   
                                        java.net.URI          System.Uri
                                        scheme / host         Scheme / Host
   
     s7://192.168.0.1                   s7   / 192.168.0.1    s7   / 192.168.0.1
     s7:cotp://10.0.0.5:102             s7   / null           s7   / ""
     modbus-tcp://10.0.0.9:502?u=1      modbus-tcp / 10.0.0.9 modbus-tcp / 
10.0.0.9
     opcua:tcp://localhost:4840/milo    opcua / null          opcua / ""
   
   Java has exactly the same limitation on the two-scheme form and lives with 
it,
   because DefaultPlcDriverManager only ever takes the scheme. So the thing I
   treated as a blocker was never one.
   
   Counting the consumers settles which module the type belongs in:
   
   api/PlcDriverManager.cs:60     ConnectionString.Parse(..)    1 site   <- the 
line I added
   spi/drivers/DriverBase.cs:83   ConnectionString parameter    3 sites  <- 
genuine; these
   spi/drivers/DriverBase.cs:101  ConnectionString.Parse(..)             need 
transport code,
   spi/drivers/DriverBase.cs:130  ResolveTransportCode(..)               host, 
port, params
   
   Revert that one line and the type has no consumers left in the api module. 
So it
   moves down next to DriverBase and the manager goes back to Uri.Scheme. I will
   fix that.
   
   On the general approach
   
   My intent throughout has been to follow how the Go and Java modules are u
   the project keeps one consistent shape. Your point about the usage pattern 
and
   the naming is a fair hit — IPlcReadRequestBuilder still exposes
   AddItem(name, fieldQuery), which is both the old "field" wording and missing
   the Tag/TagString pair. I will align it with addTag/addTagAddress. Query I
   would rather leave until there is browse support behind it — plc4net 
currently
   has no PlcBrowser and no browse request at all, so adding the type on its own
   would be the name without the capability.
   
   On KNX
   
   I did not choose it, I inherited it — plc4net/drivers/knxnetip/src already
   carries the generated model, so finishing that capability looked like the
   first step. My own roadmap is different: Modbus, then S7, then OPC UA, 
because
   what I actually need is to reach PLCs from several vendors and feed them 
into an
   IoT platform. Your note that you normally start with Modbus matches where
   heading anyway.
   
   On tool-native code generation
   
   I agree with building it per language. Each language has its own idioms, 
tooling
   and best practices, and a tool-native generator fits that far better than one
   shared toolchain. Thanks for the two grammar pointers — I have looked at 
them and
   they seem very tractable from .NET, so the part left to work out is the
   resolution of the protocol modules you mentioned.
   
   Where I would like to go next
   
   1. Get the CLA filed.
   2. Start with Modbus and prove the path end to end.
   3. Extend outwards to the protocols the PLCs I work with actually speak.
   
   One request
   
   This PR is really me probing for direction rather than proposing something
   finished, and properly absorbing this project is going to take me a while
   you consider creating a feature/plc4net branch I could target instead of
   develop? contributing.adoc already describes feature branches with that
   prefix, and it would let this land in reviewable increments without any o
   touching the 1.0.0 release — which I think also answers @sruehl's question 
above.
   Happy to work that way if it suits you.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to