This is an automated email from the ASF dual-hosted git repository.
chrisdutz pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git
The following commit(s) were added to refs/heads/develop by this push:
new 1a814bb4af docs(website): Updated the Other driver documentations
1a814bb4af is described below
commit 1a814bb4afc0d131c49dcea7f5e81f19a99640af
Author: Christofer Dutz <[email protected]>
AuthorDate: Fri Aug 14 12:26:15 2026 +0200
docs(website): Updated the Other driver documentations
---
.../java/ads/configuration/AdsConfiguration.java | 2 +-
website/asciidoc/modules/users/nav.adoc | 5 -
.../modules/users/pages/protocols/ads.adoc | 41 +++
.../modules/users/pages/protocols/bacnet.adoc | 28 +-
.../modules/users/pages/protocols/can.adoc | 74 +++--
.../modules/users/pages/protocols/deltav.adoc | 22 --
.../modules/users/pages/protocols/df1.adoc | 35 +++
.../modules/users/pages/protocols/iec-60870.adoc | 7 +
.../modules/users/pages/protocols/index.adoc | 20 +-
.../modules/users/pages/protocols/knxnetip.adoc | 20 +-
.../modules/users/pages/protocols/logix.adoc | 32 +-
.../modules/users/pages/protocols/modbus.adoc | 50 +++-
.../modules/users/pages/protocols/opcua.adoc | 38 ++-
.../modules/users/pages/protocols/profinet.adoc | 7 +-
.../modules/users/pages/protocols/s7-light.adoc | 321 ---------------------
.../asciidoc/modules/users/pages/protocols/s7.adoc | 22 +-
16 files changed, 254 insertions(+), 470 deletions(-)
diff --git
a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/configuration/AdsConfiguration.java
b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/configuration/AdsConfiguration.java
index aba219be30..b299b56ec2 100644
---
a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/configuration/AdsConfiguration.java
+++
b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/configuration/AdsConfiguration.java
@@ -66,7 +66,7 @@ public class AdsConfiguration implements Configuration {
@ConfigurationParameter("load-symbol-and-data-type-tables")
@BooleanDefaultValue(true)
- @Description("Configures, if when connecting the data-type- and
symbol-table should be read. This is an optimization that can help in cases,
where the PLC program is pretty large and downloading the full tables is
causing problems. When disabled, symbolic addresses will manually be resolved
as soon as an address is used.")
+ @Description("Configures, if when connecting the data-type- and
symbol-table should be read. This is an optimization that can help in cases,
where the PLC program is pretty large and downloading the full tables is
causing problems. When disabled, only direct addresses
(`{IndexGroup}/{IndexOffset}:{TYPE}`) can be used: symbolic addresses are
resolved against these tables and will fail with `Unknown symbol` if they were
not loaded. Browsing is unavailable too, as it lists the symbol table.")
protected boolean loadSymbolAndDataTypeTables;
public AmsNetId getTargetAmsNetId() {
diff --git a/website/asciidoc/modules/users/nav.adoc
b/website/asciidoc/modules/users/nav.adoc
index 72adbe74c5..c9d016a6d5 100644
--- a/website/asciidoc/modules/users/nav.adoc
+++ b/website/asciidoc/modules/users/nav.adoc
@@ -39,9 +39,6 @@
*** xref:protocols/bacnet.adoc[]
*** xref:protocols/c-bus.adoc[]
*** xref:protocols/canopen.adoc[]
-*** xref:protocols/ctrlx.adoc[]
-*** xref:protocols/deltav.adoc[]
-*** xref:protocols/df1.adoc[]
*** xref:protocols/eip.adoc[]
*** xref:protocols/firmata.adoc[]
*** xref:protocols/genericcan.adoc[]
@@ -52,11 +49,9 @@
*** xref:protocols/opcua.adoc[]
*** xref:protocols/open-protocol.adoc[]
*** xref:protocols/plc4x.adoc[]
-*** xref:protocols/profinet.adoc[]
*** xref:protocols/s7.adoc[]
*** xref:protocols/simulated.adoc[]
*** xref:protocols/slmp.adoc[]
-*** xref:protocols/umas.adoc[]
** xref:transports/index.adoc[]
*** xref:transports/tcp.adoc[]
diff --git a/website/asciidoc/modules/users/pages/protocols/ads.adoc
b/website/asciidoc/modules/users/pages/protocols/ads.adoc
index dc44c95416..f8803f4752 100644
--- a/website/asciidoc/modules/users/pages/protocols/ads.adoc
+++ b/website/asciidoc/modules/users/pages/protocols/ads.adoc
@@ -37,6 +37,47 @@ ADS (Automation Device Specification) is the TwinCAT
communication protocol that
AMS (Automation Message Specification) specifies the exchange of the ADS data.
A major component of the communication protocol is the AmsNetId. This is
specified in the AMS/ADS package for the source and target device. An ADS
device can be explicitly addressed using the AmsNetId.
Source
https://infosys.beckhoff.com/english.php?content=../content/1033/ams_nat/4275563275.html&id=
(accessed 7 August 2022)
+== Address Format
+
+The driver accepts three kinds of addresses.
+
+*Symbolic addresses* use the variable name as it is known in the PLC program:
+
+----
+MAIN.g_plant.channels[1].setpoints[4]
+----
+
+Array indices may appear at any position of the path, not only at the end.
Symbolic addresses are
+resolved against the symbol- and data-type-table, so they require
+`load-symbol-and-data-type-tables` to be enabled (the default).
+
+*Direct addresses* name the index group and index offset explicitly, in
decimal or hexadecimal, and
+carry the data type:
+
+----
+{IndexGroup}/{IndexOffset}:{TYPE}
+{IndexGroup}/{IndexOffset}:{TYPE}[{numberOfElements}]
+----
+
+.Examples
+[cols="2" ,options="header"]
+|===
+|Address |Meaning
+|`16448/16448:DINT` |one DINT at index group 16448, offset 16448
+|`0x4040/0x4040:DINT` |the same address in hexadecimal
+|`16448/16448:INT[10]` |an array of 10 INTs
+|===
+
+*Direct string addresses* additionally carry the fixed length of the string:
+
+----
+{IndexGroup}/{IndexOffset}:STRING({length})
+{IndexGroup}/{IndexOffset}:WSTRING({length})
+----
+
+Unlike symbolic addresses, direct addresses need no symbol table and therefore
work regardless of
+the `load-symbol-and-data-type-tables` setting.
+
== Connection String Options
include::partial$ads.adoc[]
diff --git a/website/asciidoc/modules/users/pages/protocols/bacnet.adoc
b/website/asciidoc/modules/users/pages/protocols/bacnet.adoc
index 7ddc96d2dc..0dcc4bf573 100644
--- a/website/asciidoc/modules/users/pages/protocols/bacnet.adoc
+++ b/website/asciidoc/modules/users/pages/protocols/bacnet.adoc
@@ -27,29 +27,21 @@ image::users/protocols/bacnet_banner.png[banner,512,167]
== BACnet (Building Automation and Control Networks)
-== Connection String Options
-
-include::partial$bacnet-ip.adoc[]
+== Supported Operations
-[%header, cols=3*]
-|===
-| Data array
-| Size
-| Description
+IMPORTANT: This driver is a *passive listener*. It supports subscriptions only
- reading, writing
+and browsing are not implemented and a request for any of them is rejected.
-|
-|
-|
+The driver joins the network and reports the change-of-value (COV)
notifications it observes. There
+is no handshake with a device and no request/response exchange.
-|
-|
-|
+Tag addresses are not interpreted yet, so a subscription cannot be narrowed to
a single object -
+every registered consumer receives all COV notifications seen on the network,
and has to filter
+them itself.
-|
-|
-|
+== Connection String Options
-|===
+include::partial$bacnet-ip.adoc[]
== More details on
diff --git a/website/asciidoc/modules/users/pages/protocols/can.adoc
b/website/asciidoc/modules/users/pages/protocols/can.adoc
index 96c8d785f4..fc3cdc9183 100644
--- a/website/asciidoc/modules/users/pages/protocols/can.adoc
+++ b/website/asciidoc/modules/users/pages/protocols/can.adoc
@@ -17,57 +17,49 @@
:imagesdir: ../../images/users/protocols
:icons: font
-= CAN Bus Driver Adapter
+= CAN Bus
image::users/protocols/can_banner.png[banner,512,167]
+NOTE: This page describes how the CAN drivers are put together. There is no
driver with the
+protocol code `can` - connect with xref:canopen.adoc[CANopen] (`canopen`) or
+xref:genericcan.adoc[GenericCAN] (`genericcan`) instead.
+CAN differs from the other buses PLC4X supports in that the wire carries
short, identifier-tagged
+frames rather than a request/response stream. The transports own the bus
access and hand the
+drivers a uniform frame type; each driver then interprets those frames
according to its own
+application-layer protocol.
-The CAN Bus driver is a special kind of driver which does not bring any logic.
-Its responsibility is to combine link:../transports/can.html[CAN transport
facade] and custom application layer protocols.
-In this way, the protocol can use its own "root frame" type which is not
delivered from CAN bus frame.
+== Transport and frame model
-== More details on the driver
+The link:../transports/can.html[CAN transport facade] provides a single frame
representation that
+all CAN drivers work against:
-The `CANDriverAdapter` is a full implementation of Apache PLC4X API.
-Under the hood adapter will forward all operations to delegate driver.
-Work which is done by the adapter is to transform data incoming via CAN
transport into frame supported by driver.
-In this regard the `CANDriverAdapter` does not implement any real protocol.
-All it does is transformation of incoming frames into frame desired by real
driver.
+* `CanFrame` (`plc4j/transports/can`) - an identifier, up to 8 data bytes, and
the standard/extended
+and remote-transmission-request flags. Standard identifiers are 11 bit
(`MAX_STANDARD_ID`), extended
+ones 29 bit (`MAX_EXTENDED_ID`).
+* `CanFrameBuilder` - obtained from `CanFrame.builder()`, used by the drivers
to construct outgoing
+frames.
+* `CanIdFilter` - lets a driver subscribe to a subset of identifiers instead
of the whole bus.
-Below diagram explains how driver adapter works with CANopen.
-Given that this is currently biggest CAN driver implemented in Apache PLC4X we
will use it as a reference.
+Two transports implement this facade: `can-socketcan` (Linux SocketCAN, the
usual choice on real
+hardware) and `can-virtualcan` (an in-process bus, useful for tests and for
running two PLC4X
+components against each other without a physical interface).
-[ditaa,apache-plc4x-can-canopen]
-....
-
+--------------------------------------------+
- | CAN Driver
Adapter |
+== Driver structure
-
+----------------------------------------------------------+
- Conversation
| CANopen Driver |
- Protocol Context
Protocol
- CAN Transport Root Frame Wrapper
Frame Handler Root Frame Protocol Logic
- wire /---------\ /------------\
/---------\ |
- -----> | receive | --------------> | SocketCAN | -----[transform] ------> [
map to protocol ] -----> | CANopen | ---------> | receive
- |---------| | Frame |
| Frame | |
- <------| write |---------------- \------------/ <----------------------- [
map to transport] <----- \---------/ <--------- | publish
- \---------/
|
-....
+Each CAN driver is a `ConnectionBase` implementation that owns a message codec
translating between
+`CanFrame` and its own protocol frame:
-Looking at left most side of diagram we can see a CAN transport.
-The transport knows how to receive and send data to the CAN bus.
-Transport can create its own intermediate representation of CAN data frame.
-In case of `SocketCAN` there is a dedicated type called `SocketCANFrame`.
+* xref:canopen.adoc[CANopen] - `CANOpenConnection` with `CANOpenMessageCodec`,
implementing the
+CANopen service model (SDO, PDO, NMT, heartbeat).
+* xref:genericcan.adoc[GenericCAN] - `GenericCANConnection`, which applies no
application-layer
+semantics at all and simply maps identifiers to typed payload slices.
-Most of other drivers in Apache PLC4X which rely on TCP, UDP or serial
transports can unify right above transport.
-Yet due to variety of APIs which are possible to be used with CAN bus such
early unification at API level is not possible.
+Incoming frames arrive from the codec and are dispatched to the subscriptions
registered for the
+matching node id; outgoing writes are encoded and handed straight back to the
codec.
-Place where `CANDriverAdapter` jumps in is once transport formed the frame
structure.
-Then, adapter asks the transport to turn that structure into a `FrameData`.
-An instance of `FrameData` is then passed to an adapter delivered by CANopen
Driver.
-This adapter can then create a `CANopenFrame` which is processed by desired
driver logic.
-
-The return side, when desired driver wants to publish information is a bit
simplified.
-Because `FrameData` does not be a real type (it is an interface) we can skip
it.
-With a help of a `CANFrameBuilder` provided by CAN transport driver can easily
construct a structure which is supported by it.
-While this makes an API asymmetric it also makes it possible to use any third
party transport with `CANopenDriver`.
\ No newline at end of file
+NOTE: Earlier releases interposed a separate `CANDriverAdapter` between the
transport and the
+driver, with a `FrameData` interface and per-transport frame types such as
`SocketCANFrame`. That
+indirection was removed when the drivers were ported to the new SPI: the
adapter's work is now done
+by the driver's own connection class, and every transport produces a
`CanFrame` directly.
diff --git a/website/asciidoc/modules/users/pages/protocols/deltav.adoc
b/website/asciidoc/modules/users/pages/protocols/deltav.adoc
deleted file mode 100644
index 3aed797ff3..0000000000
--- a/website/asciidoc/modules/users/pages/protocols/deltav.adoc
+++ /dev/null
@@ -1,22 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License. You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-:imagesdir: ../../images/users/protocols
-:icons: font
-
-= DeltaV
-
-
diff --git a/website/asciidoc/modules/users/pages/protocols/df1.adoc
b/website/asciidoc/modules/users/pages/protocols/df1.adoc
index 9784f49ffa..ecc86851e7 100644
--- a/website/asciidoc/modules/users/pages/protocols/df1.adoc
+++ b/website/asciidoc/modules/users/pages/protocols/df1.adoc
@@ -19,4 +19,39 @@
= DF1
+IMPORTANT: There is no DF1 driver you can connect with. DF1 currently exists
as a protocol
+specification and a generated read/write model only - there is no `df1`
connection code in any of
+the language ports, so there is nothing to put a connection string into. This
page is kept for
+reference and is not linked from the navigation.
+Allen-Bradley's DF1 is the serial protocol used by the SLC-500 and PLC-5
family, and by the
+MicroLogix controllers over their RS-232 port.
+
+== What exists today
+
+The protocol is described in
`protocols/df1/src/main/resources/protocols/df1/df1.mspec` and code is
+generated from it for Go, under `plc4go/protocols/df1/readwrite`. The
generated model covers the
+symbol/framing layer and the unprotected read exchange:
+
+* `DF1Symbol` with the `DF1SymbolMessageFrame`, `DF1SymbolMessageFrameACK` and
+ `DF1SymbolMessageFrameNAK` variants
+* `DF1Command` with `DF1UnprotectedReadRequest` and
`DF1UnprotectedReadResponse`
+* a CRC helper in `StaticHelper.go`, exercised by its own unit test
+
+This model is verified by a ParserSerializer test suite
+(`plc4go/assets/testing/protocols/df1/`), so the wire format is known to
round-trip - but nothing
+builds a connection, transport or tag handler on top of it.
+
+== Related: AB-ETH
+
+The DF1 *command* layer is reused by the xref:ab-eth.adoc[AB-ETH] driver,
which tunnels DF1
+commands inside CIP encapsulation over Ethernet. That is a working driver in
Java, and it is what
+you want if your device is reachable over Ethernet rather than a serial port.
The DF1 message types
+it uses are generated into the ab-eth module rather than shared from here.
+
+== Contributing
+
+A DF1 driver would need a serial transport binding, the framing/ACK-NAK state
machine on top of
+`DF1Symbol`, and a tag address syntax for the SLC/PLC-5 data-file notation
(e.g. `N7:0`). The
+protocol layer is the part that already exists, so a contribution can start at
the driver logic.
+Please raise it on [email protected] before starting.
diff --git a/website/asciidoc/modules/users/pages/protocols/iec-60870.adoc
b/website/asciidoc/modules/users/pages/protocols/iec-60870.adoc
index a9fed39c5f..6273787e27 100644
--- a/website/asciidoc/modules/users/pages/protocols/iec-60870.adoc
+++ b/website/asciidoc/modules/users/pages/protocols/iec-60870.adoc
@@ -19,7 +19,14 @@
= IEC-60870
+== Supported Operations
+IMPORTANT: This driver supports *subscriptions only* - reading, writing and
browsing are not
+implemented and a request for any of them is rejected.
+
+Tag addresses are currently not interpreted: any address string is accepted
without error, and the
+subscription receives all incoming ASDUs rather than those matching the
address. Consumers have to
+filter the incoming events themselves.
== Connection String Options
diff --git a/website/asciidoc/modules/users/pages/protocols/index.adoc
b/website/asciidoc/modules/users/pages/protocols/index.adoc
index c16fffed18..9c468c97b7 100644
--- a/website/asciidoc/modules/users/pages/protocols/index.adoc
+++ b/website/asciidoc/modules/users/pages/protocols/index.adoc
@@ -58,18 +58,11 @@
|icon:exclamation[role="yellow"]
|icon:times[role="red"]
-|DeltaV
-|icon:times[role="red"]
-|icon:times[role="red"]
-|icon:times[role="red"]
-|icon:exclamation[role="yellow"]
-|icon:times[role="red"]
-
|DF1
|icon:times[role="red"]
|icon:times[role="red"]
|icon:times[role="red"]
-|icon:exclamation[role="yellow"]
+|icon:times[role="red"]
|icon:times[role="red"]
|EtherNet/IP
@@ -244,17 +237,6 @@ The following table contains a list of operations and the
protocols that support
|icon:question[role="red"]
|icon:question[role="red"]
-|DeltaV
-|icon:question[role="red"]
-|icon:question[role="red"]
-|icon:question[role="red"]
-|icon:question[role="red"]
-|icon:question[role="red"]
-|icon:question[role="red"]
-|icon:question[role="red"]
-|icon:question[role="red"]
-|icon:question[role="red"]
-
|DF1
|icon:question[role="red"]
|icon:question[role="red"]
diff --git a/website/asciidoc/modules/users/pages/protocols/knxnetip.adoc
b/website/asciidoc/modules/users/pages/protocols/knxnetip.adoc
index 444b7e8cc0..5ff53a5a0c 100644
--- a/website/asciidoc/modules/users/pages/protocols/knxnetip.adoc
+++ b/website/asciidoc/modules/users/pages/protocols/knxnetip.adoc
@@ -33,11 +33,25 @@ include::partial$knxnet-ip.adoc[]
KNX Addresses usually have one of the following structures:
-- 3-level Address:
`{main-group(0-15)}`/`{middle-group(0-15)}`/`{sub-group(0-255)}`
-- 2-level Address: `{main-group(0-15)}`/`{sub-group(0-4095)}`
+- 3-level Address:
`{main-group(0-31)}`/`{middle-group(0-7)}`/`{sub-group(0-255)}`
+- 2-level Address: `{main-group(0-31)}`/`{sub-group(0-2047)}`
- 1-level Address: `{sub-group(0-65535)}`
-Depending on the `group-address-type` configured in the connection string or
defined in the knxproj-file configured by the `knxproj-file-path` connection
string parameter, the corresponding address pattern has to be used.
+Depending on the `group-address-num-levels` configured in the connection
string or defined in the knxproj-file configured by the `knxproj-file-path`
connection string parameter, the corresponding address pattern has to be used.
+
+=== Datapoint Type Suffix
+
+An address may carry an optional datapoint-type suffix `:DPT{main}[.{sub}]`,
which tells the driver
+how to interpret the value on the wire:
+
+----
+1/2/3:DPT9.001
+----
+
+The KNX protocol does not transport the datatype of a group address, so the
driver has to get it
+from somewhere. If no `knxproj-file-path` is configured, this suffix is
*required* for reading and
+writing - a request for a plain `1/2/3` fails because the datapoint type
cannot be resolved.
+Browsing likewise requires a `knxproj-file-path`.
However, when subscribing for events, each segment allows using of the
wildcard character `*`.
If the addresses used in the KNX installation are structured, this way it is
possible to, for example (depending on the scheme used):
diff --git a/website/asciidoc/modules/users/pages/protocols/logix.adoc
b/website/asciidoc/modules/users/pages/protocols/logix.adoc
index aee5cb13cf..e382d8eb8c 100644
--- a/website/asciidoc/modules/users/pages/protocols/logix.adoc
+++ b/website/asciidoc/modules/users/pages/protocols/logix.adoc
@@ -35,7 +35,7 @@ logix:tcp://{ip-address}:{port}?{options}
----
An example connection string would look like:-
----
-logix:tcp://127.0.0.1:502?communicationPath=[1,1]
+logix:tcp://127.0.0.1:44818?communication-path=[1,1]
----
Note the port and option fields are optional.
@@ -45,12 +45,21 @@ Note the port and option fields are optional.
In general all Logix addresses have this format:
----
-{address}:{data-type}[{array-size}]
+{tagname}
+{tagname}:{DataType}
+{tagname}:{numberOfElements}
+{tagname}[{startIndex}]:{DataType}:{numberOfElements}
----
-If the array-size part is omitted, the size-default of `1` is assumed.
-If the data-type part is omitted, the data type from the controller is used
-The address format matches that found in the controller.
+The tag name matches that found in the controller and may optionally be
prefixed with `%`.
+An array index is appended to the tag name and has to be its last part.
+
+If the number-of-elements part is omitted, `1` is assumed.
+If the data type is omitted it defaults to `DINT`, so for anything that is not
a 32-bit integer it
+has to be given explicitly - also when reading.
+
+NOTE: The data type comes *before* the number of elements. Reading four DINTs
starting at index 0
+is `myArray[0]:DINT:4`.
=== Data Types
@@ -58,13 +67,12 @@ The following data types are supported
- BOOL (boolean)
- SINT (int 8)
-- USINT (uint 8)
-- BYTE (uint 8)
- INT (int 16)
-- UINT (uint 16)
-- WORD (uint 16)
- DINT (int 32)
-- UDINT (uint 32)
-- DWORD (uint 32)
- LINT (int 64)
-- REAL (float)
\ No newline at end of file
+- REAL (float)
+- LREAL (double)
+- STRING (character string)
+
+NOTE: Other CIP data types are accepted by the address parser but are not
encoded or decoded by the
+driver; reading such a tag results in a response code of `INTERNAL_ERROR`
rather than a value.
\ No newline at end of file
diff --git a/website/asciidoc/modules/users/pages/protocols/modbus.adoc
b/website/asciidoc/modules/users/pages/protocols/modbus.adoc
index 092895d0b2..b86ae4aa31 100644
--- a/website/asciidoc/modules/users/pages/protocols/modbus.adoc
+++ b/website/asciidoc/modules/users/pages/protocols/modbus.adoc
@@ -70,7 +70,7 @@ Note the transport, port and option fields are optional.
In general all Modbus addresses have this format:
----
-{memory-Area}{start-address}:{data-type}[{array-size}]:{name-value-tag-options}
+{memory-Area}{start-address}:{data-type}[{array-size}]{name-value-tag-options}
----
If the array-size part is omitted, the size-default of `1` is assumed.
@@ -81,12 +81,12 @@ Additionally address can contain tag configuration:
----
{unit-id: 123}
----
-Specifying this value overrides value of `default-unit-id` parameter specified
at the connection string.
+Specifying this value overrides value of `default-unit-identifier` parameter
specified at the connection string.
----
{byte-order: 'LITTLE_ENDIAN'}
----
-With this, can the default byte-order be overridden on a per-tag basis. If not
provided the default-byte-order from the connection string is used, or
BIG_ENDIAN, if this is also not provided.
+With this, can the default byte-order be overridden on a per-tag basis. If not
provided the `default-payload-byte-order` from the connection string is used,
or BIG_ENDIAN, if this is also not provided.
=== Memory Areas
@@ -117,10 +117,36 @@ When using the shorter versions there are two formats
available i.e. 30001 and
With the shorter format 3XXXX being limited to between 30001 and 39999, while
the longer format 3XXXXX being limited to between 300001 and 365535.
These memory areas all start at address 1.
+==== Addresses are 1-based, the wire is 0-based
+
+This is a Modbus speciality worth spelling out, because it is a frequent
source of off-by-one
+confusion: the Modbus specification and virtually all device documentation
number the registers and
+coils starting at *1*, but the address actually transmitted in the request is
that number *minus
+one*.
+
+PLC4X follows the documentation convention - you write the address exactly as
the device's manual
+lists it, and the driver decrements it on the way to the wire:
+
+[cols="2,2,2" ,options="header"]
+|===
+|Tag address |Address on the wire |Meaning
+|`coil:1` |0 |the first coil
+|`holding-register:1` |0 |the first holding register
+|`holding-register:100` |99 |the 100th holding register
+|===
+
+So a device manual documenting "holding register 40001" is addressed as
`holding-register:1` (or
+`4x00001`), and the request that leaves PLC4X carries address 0.
+
+NOTE: The extended register area is the exception - it is genuinely 0-based in
the specification, so
+no decrement is applied there and its lowest usable tag address is
`extended-register:1` (which is
+also address 1 on the wire). `extended-register:0` is rejected.
+
For the extended register area the addresses 0-99999 are able to be specified.
These registers are mapped to file records with a length of 10000. Address
600000 corresponds to the first address in file record 0.
Address 610000 is then the first address in the second file record and so on.
It is noted that there is generally only 10 file records (600000 thru to
699999) however the spec allows for 65536 file records.
Using the extended-register: format you are able to reference all of these, if
the shorter format is used then it is limited to 699999.
-This memory area starts at address 0.
+Unlike the other memory areas this one is 0-based in the specification, so its
addresses are passed
+through unchanged; the lowest usable tag address is nevertheless
`extended-register:1`.
=== Data Types
@@ -143,6 +169,22 @@ The following data types are supported
- LREAL (double)
- CHAR (char)
- WCHAR (2 byte char)
+- STRING (utf-8)
+- WSTRING (utf-16)
+- TIME (duration, milliseconds)
+- LTIME (duration, nanoseconds)
+- DATE (date)
+- LDATE (date)
+- TIME_OF_DAY (time of day)
+- LTIME_OF_DAY (time of day)
+- DATE_AND_TIME (date and time)
+- LDATE_AND_TIME (date and time)
+
+NOTE: Coils and discrete inputs hold a single bit each and therefore support
only `BOOL`. A coil or
+discrete-input tag declared with any other data type is accepted by the
address parser, but the read
+returns the response code `UNSUPPORTED`.
+
+Reading an array of coils returns all of its elements: `coil:1:BOOL[8]` yields
a list of 8 values.
=== Some useful tips
diff --git a/website/asciidoc/modules/users/pages/protocols/opcua.adoc
b/website/asciidoc/modules/users/pages/protocols/opcua.adoc
index d7c0b56961..0d20f0aad4 100644
--- a/website/asciidoc/modules/users/pages/protocols/opcua.adoc
+++ b/website/asciidoc/modules/users/pages/protocols/opcua.adoc
@@ -77,11 +77,20 @@ The `SIGN` mode gives possibility o browse packets in tools
such wireshark.
=== Certificate verification
The OPC UA specification defines its own procedures for certificate validation.
-In order to simplify implementation by default server certificate validation
is relaxed.
-Unless explicitly disabled through configuration of `trust-store-file` all
server certificates will be accepted without validation.
-In case when secure communication is enabled the `trust-store-file` option
might be used to point certificates which client should accept.
-The acceptance rely on regular TLS checks (expiry date, certificate path
etc.), does not validate OPC UA specific parts such as application URI.
+The driver verifies the server certificate by default and fails closed: if no
trust anchor is
+configured, the server certificate is rejected and the connection fails.
Configure one of:
+
+* `trust-store-file` - validate the certificate chain against the given trust
store. The acceptance
+relies on regular TLS checks (expiry date, certificate path etc.); it does not
validate OPC UA
+specific parts such as the application URI.
+* `server-certificate-file` - pin trust to exactly that certificate. Only the
certificate read from
+the configured file is trusted; a certificate learned over the unauthenticated
discovery channel is
+never used as a trust anchor.
+
+WARNING: `insecure-certificate-verification=true` disables server certificate
verification
+altogether. This makes the connection vulnerable to man-in-the-middle attacks
and is intended for
+local testing only.
=== Negotiation procedure
Depending on settings driver might or might not attempt to discover endpoints
from remote server.
@@ -126,19 +135,23 @@ The following data types are supported
- BYTE (uint 8)
- INT (int 16)
- UINT (uint 16)
-- WORD (uint 16)
- DINT (int 32)
- UDINT (uint 32)
-- DWORD (uint 32)
- LINT (int 64)
- ULINT (uint 64)
-- LWORD (uint 64)
- REAL (float)
- LREAL (double)
- CHAR (char)
- WCHAR (2 byte char)
- STRING (utf-8)
-- WSTRING (utf-16)
+- TIME (duration, milliseconds)
+- LTIME (duration, nanoseconds)
+- DATE (date)
+- LDATE (date)
+- TIME_OF_DAY (time of day)
+- LTIME_OF_DAY (time of day)
+- DATE_AND_TIME (date and time)
+- LDATE_AND_TIME (date and time)
=== Example of a valid OPC UA address:
@@ -165,12 +178,15 @@ ns=2;g=09087e75-8e5e-499b-954f-f2a8624db28a;a=Value;REAL
----
Event Subscription:
----
-ns=0;i=2253;a=EventNotifier;BOOL{EventId: '', EventType: '', Severity: '',
Time: '', Message: ''}
+ns=0;i=2253;a=EventNotifier;BOOL|EventId=x,EventType=x,Severity=x,Time=x,Message=x
----
Note the Identifiers `s`,`i`,`b` and `g` specify the format of the address not
the data type of the returned value.
The `a` attribute is required only for event subscriptions which additionally
makes use of tag config.
-Tag config is a list of key-value pairs which rely on simplified JSON syntax.
+Tag config is appended after a `|` as a comma-separated `key=value` list
naming the event
+fields to request. The values are placeholders and are ignored, but they must
be non-empty
+and alphanumeric, and a `;{Data Type}` segment has to precede the `|` -
otherwise the config
+is silently dropped.
== Some useful tips
@@ -217,7 +233,7 @@ Fields which are supported are defined in OPC UA
`BaseEventType`:
- `Message`
- `Severity`
-Example syntax: `ns=0;i=2253;a=EventNotifier;BOOL{EventId: '', EventType: '',
Severity: '', Time: '', Message: ''}`.
+Example syntax:
`ns=0;i=2253;a=EventNotifier;BOOL|EventId=x,EventType=x,Severity=x,Time=x,Message=x`.
Subscription event generated by client upon receiving notification will
contain an object (`PlcSTRUCT`/`Map`) which will contain all requested fields.
Please note that Apache PLC4X does only basic normalization of data, thus your
application need to take care of actual processing of event data.
diff --git a/website/asciidoc/modules/users/pages/protocols/profinet.adoc
b/website/asciidoc/modules/users/pages/protocols/profinet.adoc
index e88ce97e48..b785b9f828 100644
--- a/website/asciidoc/modules/users/pages/protocols/profinet.adoc
+++ b/website/asciidoc/modules/users/pages/protocols/profinet.adoc
@@ -19,7 +19,11 @@
= Profinet (In Development)
-
+WARNING: The PROFINET driver is not usable yet. Two parallel implementations
exist in the code base
+(`plc4j-driver-profinet` and `plc4j-driver-profinet-ng`, of which only the
latter is shipped) and
+neither completes a working exchange - the subscription response future is
never completed and
+cyclic IO frames are logged rather than dispatched. This page describes the
intended design and is
+kept for reference; it is not linked from the navigation.
The PROFINET driver implements a class 3 real time controller. Which is able
to communicate with multiple devices
on the same network segment.
@@ -116,4 +120,3 @@ Although the GSD file contains all the information needed
to configure which dat
The easiest approach is to use the browsing function of the Profinet driver to
return a list of all available tags.
Then only the addresses of interest can be selected.
-|===
diff --git a/website/asciidoc/modules/users/pages/protocols/s7-light.adoc
b/website/asciidoc/modules/users/pages/protocols/s7-light.adoc
deleted file mode 100644
index b60b241633..0000000000
--- a/website/asciidoc/modules/users/pages/protocols/s7-light.adoc
+++ /dev/null
@@ -1,321 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License. You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-:imagesdir: ../../images/
-:icons: image
-:iconsdir: ../../images/users/protocols
-:source-highlighter: rouge
-//:coderay-linenums-mode: inline
-//:coderay-css: class
-
-= S7-Light (Step7)
-
-image::users/protocols/s7_banner.png[banner,512,167]
-
-NOTE: When trying to connect to a Siemens `LOGO` device, it is important to
add one connection option, as Siemens seems to have only partially implemented
the protocol, the device simply terminates the connection as soon as our driver
tried to read the SZL table in order to find out which type of S7 device it is
talking to. This can be disabled by passing in the type of PLC. For a Siemens
LOGO device therefore please add `?controller-type=LOGO` to the connection
string.
-
-The S7-Light driver is a stripped-down version of the full S7 driver.
-It's main goal is to simplify communication for S7 devices, that do not
support subscriptions, as under heavy load, these have proven to cause issues.
-As soon as we have rewritten the PLC4X SPI, we will most probably merge both
back together again.
-
-== Connecting as easy as 1-2-3.
-
-=== ONE
-
-In PLC4X the URL philosophy is used as the data source for the connection for
the specification of the driver and its connection parameters, this is almost a
standard in network applications (pointing to the best practices). It is also
possible to create an instance of the driver directly and assign its parameters
with the typical "set" methods.
-
-[NOTE,icon=s7_note.png]
-In the following, reference will be made to the Java-based driver, which
implements all the functionalities indicated in this manual.
-
-The specified URL has the structure
-
-image::users/protocols/s7_url.png[s7_url,,,,align="center"]
-
-. SCHEMA: Defines the protocol to be used, in our particular case S7
-. DOMAINE NAME: Physical address of the PLC or CP's.
-. PARAMETERS: List of key/value values separated by ampersand "&". They define
the behavior of the driver.
-
-The SCHEMA and DOMAINE NAME are almost standard for any URL and do not require
further explanation. The PARAMETERS that define the behavior of the driver are
defined in the following table.
-
-== Connection String Options
-
-include::partial$s7-light.adoc[]
-
-[cols="2,2a,5a"]
-|===
-|Name |Value |Description
-
-3+|Supported Operations
-
-|
-| `read`
-| Only supported with `tcp` transport.
-
-|
-| `write`
-| Only supported with `tcp` transport.
-
-|===
-
-=== TWO
-
-After defining the URL, the connection is made. Driver selection from the URL
is done via PLC4X's SPI support, so driver instantiation and mapping
originating from the URL is done transparently by the Java SPI services.
-
-Any inconsistency in the URL definition will generate an exception that must
be handled by the user program.
-
-
-[source,java]
-----
- .
- .
- .
-try {
- PlcConnection connection new
DefaultPlcDriverManager().getConnection("s7://10.10.1.33?remote-rack=0&remote-slot=3&controller-type=S7_400");
//(2.1)
- final PlcReadRequest.Builder subscription
connection.readRequestBuilder(); //(2.2)
- .
- .
- .
- }
-----
-
-In (2.1) the driver instance is created, you only have to ensure that the
required driver is in the CLASSPATH of your Java environment. Already in (2.2)
it defines the type of service required (read/write or a subscription), here a
read request is indicated.
-
-No problems? Then we are ready to configure and request the data that we
require from the PLC. Let's go to step "three".
-
-
-=== THREE
-
-By having the connection we can start building and executing our requests.
-
-[source,java]
-----
-.
-.
-.
- readrequest.addTagAddress("MySZL", "SZL_ID=16#0091;INDEX=16#0000"); //(3.1)
-
- final PlcReadRequest rr readrequest.build(); //(3.2)
- final PlcReadResponse szlresponse rr.execute().get(); //(3.3)
- if (szlresponse.getResponseCode("MySZL") = PlcResponseCode.OK) {//(3.4)
- }
-.
-.
-.
-----
-
-In (3.1) the request for a PLCTag is constructed, in this particular case a
list of controller system status. In step (3.2) we build the request and in
(3.3) we execute the request using the futures pattern in Java. We verify in
(3.4) that everything is fine and that our data was acquired.
-
-These steps are shown separately for ease of analysis, but can be simplified
into one statement to avoid excessive code.
-
-
-A detailed explanation of the format for addressing PLCTags in the S7 driver
will be given in the following sections.
-
-
-== Individual Resource Address Format
-
-When programming Siemens PLCs, usually the tool used to do that is called TIA
Portal.
-
-The PLC4X S7 Driver is therefore sticking to the address format defined by
this tool as it simplifies exchanging address information.
-
-=== General Format
-
-In general all S7 addresses have this format:
-
-----
-. %{Memory-Area}{start-address}:{Data-Type}[{array-size}]
-----
-
-If the array-part is omitted, the size-default of `1` is assumed.
-
-Generally there are two types of addresses:
-
-----
-. Bit-Addresses
{Memory-Area-Code}{Start-Byte-Address}.{Bit-Offset}:BOOL[{Count}]
-. Byte-Addresses
{Memory-Area-Code}{Start-Byte-Address}:{Data-Type-Code}[{count}]
-----
-
-Bit addresses are only used if the datatype: `BOOL` is used.
-
-The array notation of these can be omitted. In this case a `Count` of 1 is
used per default.
-
-`Start-Byte-Address` and `Bit-Offset` in above list both represent unsigned
integer values.
-
-In case of accessing data in the `data block` memory area, the syntax is quite
a bit more complex:
-
-----
-.
DB{Data-Block-Number}.DB{Short-Data-Type-Code}{Start-Byte-Address}.{Bit-Offset}:BOOL[{Count}]
-.
DB{Data-Block-Number}.DB{Short-Data-Type-Code}{Start-Byte-Address}:{Data-Type-Code}[{Count}]
-----
-
-When reading a `STRING` datatype, currently 254 characters would automatically
be fetched from the PLC.
-
-In order to limit the amount of data, we extended the `STRING` type
declaration syntax to allow limiting this.
-
-With the following format less than 254 characters can be read:
-
-----
-.
DB{Data-Block-Number}.DB{Short-Data-Type-Code}{Start-Byte-Address}:STRING({string-length})[{Count}]
-----
-
-These addresses can usually be copied directly out of TIA portal.
-However we also implemented a shorter version, as above version does have some
unnecesary boilerplate parts (The `.DB` in the middle as well as the
`Short-Data-Type-Code`)
-
-The shorter syntax looks like this:
-
-----
-. DB{Data-Block-Number}:{Start-Byte-Address}.{Bit-Offset}:BOOL[{Count}]
-. DB{Data-Block-Number}:{Start-Byte-Address}:{Data-Type-Code}[{Count}]
-. DB{Data-Block-Number}:{Start-Byte-Address}:STRING({string-length})[{Count}]
-----
-
-The S7 driver will handle both types of notation equally.
-
-=== Memory Areas
-
-The S7 driver currently allows access to the following memory areas.
-
-The `Code` column represents the code that is used in above general address
syntax:
-
-Not all S7 device types support the same full set of memory areas, so the last
column gives more information on which types a given memory area is supported
on.
-
-[cols="2,2,5a,2"]
-|===
-|Code |Name |Description |Supported PLC Types
-
-|C
-|COUNTERS
-|TODO: Document this
-|TODO: Document this
-
-|T
-|TIMERS
-|TODO: Document this
-|TODO: Document this
-
-|D
-|DIRECT_PERIPHERAL_ACCESS
-|TODO: Document this
-|TODO: Document this
-
-|I
-|INPUTS
-|Inputs (Digital and Analog ... usually Analog Inputs just have a
start-address offset to separate them from the digital ones)
-|All
-
-|Q
-|OUTPUTS
-|Outputs (Digital and Analog ... usually Analog Outputs just have a
start-address offset to separate them from the digital ones)
-|All
-
-|M
-|FLAGS_MARKERS
-|TODO: Document this
-|TODO: Document this
-
-|DB
-|DATA_BLOCKS
-|Memory areas containing user-defined data structures usually accessed by the
integer data block number. antease note that data block addresses have a little
more complex address format.
-|All
-
-|DBI
-|INSTANCE_DATA_BLOCKS
-|TODO: Document this
-|TODO: Document this
-
-|LD
-|LOCAL_DATA
-|TODO: Document this
-|TODO: Document this
-
-|===
-
-=== Data Types
-
-[cols="1,1,2,4,1,1"]
-|===
-|Code | Short-Code |Name |Description |Size in bits | Supported PLC Types
-
-6+|Bit-Strings (Will all interpreted as sequence of boolean values in PLC4X)
-|BOOL |X |Bit |Single boolean value |1
|All
-|BYTE |B |Byte |Array of 8 boolean values |1
|All
-|WORD |W |Word |Array of 16 boolean values |2
|All
-|DWORD |D |Double-Word |Array of 32 boolean values |4
|All
-|LWORD |X |Long-Word |Array of 64 boolean values |8
|S7_1500
-
-6+|Integer values
-|SINT |B |Small int |8 bit integer (signed) |1
|S7_1200, S7_1500
-|USINT |B |Small unsigned int |8 bit integer (unsigned) |1
|S7_1200, S7_1500
-|INT |W |Integer |16 bit integer (signed) |2
|All
-|UINT |W |Unsigned integer |16 bit integer (unsigned) |2
|S7_1200, S7_1500
-|DINT |D |Double integer |32 bit integer (signed) |4
|All
-|UDINT |D |Unsigned Double Integer |32 bit integer (unsigned) |4
|S7_1200, S7_1500
-|LINT |X |Long integer |64 bit integer (signed) |8
|S7_1500
-|ULINT |X |Unsigned long integer |64 bit integer (unsigned) |8
|S7_1500
-
-6+|Floating point values
-|REAL |D |Real |32 bit IEEE 754 full precision
floating point value (signed) |4 |All
-|LREAL |X |Long Real |64 bit IEEE 754 double precision
floating point value (signed) |8 |S7_1200, S7_1500
-
-6+|Character values
-|CHAR |B |Character |8 bit character
|1 |All
-|WCHAR |X |Double byte character |16 bit character value
|2 |S7_1200, S7_1500
-|STRING |X |String |String 2 + n bytes
|1 |All
- |WSTRING |X |Double byte String |String of 16 bit characters 2 +
n bytes |1 |S7_1200, S7_1500
-
-6+|Temporal values
-|S5TIME |X |S5 Time |S5 Time (like in duration)
|2 |S7_300, S7_400,
S7_1500
-|TIME |X |Time |Time (like in duration) (Minutes,
Seconds, Milliseconds) |4 |All
-|LTIME |X |Long Time |Long Time (like in duration)
(Minutes, Seconds, Milliseconds, Microseconds, Nanoseconds) |8 |S7_1500
-|DATE |X |Date |Date
|2 |All
-|TIME_OF_DAY |X |Time of day |Time (like in 4:40PM)
|4 |All
-|DATE_AND_TIME |X |Date and Time |Date and time (like in 03.05.2020
4:40 PM) |8 |S7_300, S7_400,
S7_1500
-|===
-
-=== Some useful tips
-
-Especially when it comes to the input- and output addresses for analog
channels, the start addresses are configurable and hereby don't always start at
the same address.
-In order to find out what addresses these ports have, please go to the `device
setting` of your PLC in `TIA Portal`
-
-image::users/protocols/s7-tia-device-settings.png[devsettings,640,480,,align="center"]
-
-Especially pay attention to this part:
-
-image::users/protocols/s7-tia-io-settings.png[iosettings,600,144,,align="center"]
-
-In above image you can see that this device has 8 digital inputs (`DI 8`) and
2 analog inputs (`AI 2_1`) as well as 6 digital outputs (`DQ 6`).
-
-The start addresses of the digital inputs and outputs start directly at `0`.
-
-The analog inputs however start at address `64`.
-
-Each digital input and output can be addresses by a single bit-address
(start-address and offset) or can be read in a block by reading a full byte
starting at the given start address without providing a bit offset.
-
-=== Resources
-1. https://snap7.sourceforge.net/
-2.
https://support.industry.siemens.com/cs/document/13649203/simatic-net-pc-software-s7-programming-interface?dti=0&dl=en&lc=es-ES
-1.
https://support.industry.siemens.com/cs/document/109797648/simatic-comparison-list-for-s7-300-s7-400-s7-1200-s7-1500?dti=0&lc=en-WW
-2. https://support.industry.siemens.com/cs/mdm/109746537?c=98956468747&lc=es-DO
-3.
https://support.industry.siemens.com/cs/document/15166942/writing-user-specific-information-to-the-diagnostic-buffer-of-a-cpu-(sfc-52)?dti=0&lc=en-ES
-4.
https://support.industry.siemens.com/cs/document/24013249/how-do-you-display-alarm_s-or-alarm_d-messages-with-process-values-(so-called-associated-values)-on-a-wincc-flexible-operator-panel-?dti=0&lc=en-WW
-5.
https://support.industry.siemens.com/cs/document/109481157/comunicaci%C3%B3n-entre-paneles-de-operador-simatic-hmi-y-convertidores-de-frecuencia-sinamics-g120-para-el-manejo-y-la-visualizaci%C3%B3n-de-avisos-de-fallo-y-de-advertencia-(enlace-directo-sin-controlador)?dti=0&lc=es-WW
-6.
https://support.industry.siemens.com/cs/document/97550333/sinamics-g-s-hmi-direct-access?dti=0&lc=en-WW
-7.
https://support.industry.siemens.com/cs/document/21402122/technology-cpus-technology-template-error-messages-?dti=0&lc=en-WW
-8.
https://support.industry.siemens.com/cs/document/77467239/transforming-warning-and-error-messages-of-a-sinamics-drive-with-the-aid-of-the-xml-parser-and-integrating-them-into-a-step-7-hmi-project?dti=0&lc=en-WW
-9.
https://support.industry.siemens.com/cs/document/24037531/%C2%BFqu%C3%A9-pasos-de-configuraci%C3%B3n-hay-que-realizar-en-el-simotion-scout-y-el-wincc-flexible-para-que-se-muestren-los-avisos-alarm_s-y-las-alarmas-tecnol%C3%B3gicas-dentro-del-wincc-flexible-runtime-?dti=0&lc=es-ES
-
-
-
-
diff --git a/website/asciidoc/modules/users/pages/protocols/s7.adoc
b/website/asciidoc/modules/users/pages/protocols/s7.adoc
index 2e0d5a44cb..4a890e74fb 100644
--- a/website/asciidoc/modules/users/pages/protocols/s7.adoc
+++ b/website/asciidoc/modules/users/pages/protocols/s7.adoc
@@ -104,11 +104,11 @@ include::partial$s7.adoc[]
|
| `read`
-| Only supported with `tcp` transport.
+| Only supported with `cotp` transport.
|
| `write`
-| Only supported with `tcp` transport.
+| Only supported with `cotp` transport.
//|
//| `subscribe`
@@ -130,7 +130,7 @@ Any inconsistency in the URL definition will generate an
exception that must be
.
.
try {
- PlcConnection connection new
DefaultPlcDriverManager().getConnection("s7://10.10.1.33?remote-rack=0&remote-slot=3&controller-type=S7_400");
//(2.1)
+ PlcConnection connection new
DefaultPlcDriverManager().getConnection("s7://10.10.1.33?cotp.remote-rack=0&cotp.remote-slot=3&controller-type=S7_400");
//(2.1)
final PlcReadRequest.Builder subscription
connection.readRequestBuilder(); //(2.2)
.
.
@@ -344,18 +344,18 @@ This section collects what the community has found to
work (see PLC4X issues #19
Two things are important when connecting to an S7-200 (Smart):
. Disable the automatic controller-type detection by passing
`controller-type=S7_200`. The S7-200 does not answer the SZL/SSL identification
request the driver normally uses to auto-detect the CPU family, so — as with
the `LOGO` device mentioned above — the type has to be provided explicitly.
-. Provide the TSAP (Transport Service Access Point) values explicitly. The
S7-200 (Smart) expects both the local and the remote TSAP to be `0x0200`, which
is `512` in decimal. Set them with `local-tsap=512` and `remote-tsap=512`; a
non-zero TSAP overrides the rack/slot based addressing.
+. Provide the TSAP (Transport Service Access Point) values explicitly. The
S7-200 (Smart) expects both the local and the remote TSAP to be `0x0200`, which
is `512` in decimal. Set them with `cotp.local-tsap=512` and
`cotp.remote-tsap=512`; a non-zero TSAP overrides the rack/slot based
addressing.
A minimal, working connection string therefore looks like this:
----
-s7://192.168.12.100?local-tsap=512&remote-tsap=512&controller-type=S7_200
+s7://192.168.12.100?cotp.local-tsap=512&cotp.remote-tsap=512&controller-type=S7_200
----
-`remote-rack=0` and `remote-slot=0` are the defaults, so they are optional,
but may be added for clarity:
+`cotp.remote-rack=0` and `cotp.remote-slot=0` are the defaults, so they are
optional, but may be added for clarity:
----
-s7://192.168.12.100?remote-rack=0&remote-slot=0&local-tsap=512&remote-tsap=512&controller-type=S7_200
+s7://192.168.12.100?cotp.remote-rack=0&cotp.remote-slot=0&cotp.local-tsap=512&cotp.remote-tsap=512&controller-type=S7_200
----
Both reading and writing have been confirmed to work against an S7-200 Smart
with this configuration.
@@ -582,7 +582,7 @@ public class PLCEventModeSubscription {
public static void main(String[] args) throws Exception {
try (PlcConnection connection new PlcDriverManager()
-
.getConnection("s7://192.168.1.51?remote-rack=0&remote-slot=3&controller-type=S7_400"))
{
+
.getConnection("s7://192.168.1.51?cotp.remote-rack=0&cotp.remote-slot=3&controller-type=S7_400"))
{
final PlcSubscriptionRequest.Builder subscription
connection.subscriptionRequestBuilder(); // <01>
@@ -765,7 +765,7 @@ Below is an example code for the subscription of events
type *SYS*.
----
public static void main(String[] args) throws Exception {
try (PlcConnection connection new PlcDriverManager().
-
getConnection("s7://192.168.1.51?remote-rack=0&remote-slot=3&controller-type=S7_400"))
{
+
getConnection("s7://192.168.1.51?cotp.remote-rack=0&cotp.remote-slot=3&controller-type=S7_400"))
{
final PlcSubscriptionRequest.Builder subscription
connection.subscriptionRequestBuilder(); //<01>
@@ -805,7 +805,7 @@ And below is an example code for the subscription of events
type *USR*.
----
public static void main(String[] args) throws Exception {
try (PlcConnection connection new PlcDriverManager().
-
getConnection("s7://192.168.1.51?remote-rack=0&remote-slot=3&controller-type=S7_400"))
{
+
getConnection("s7://192.168.1.51?cotp.remote-rack=0&cotp.remote-slot=3&controller-type=S7_400"))
{
final PlcSubscriptionRequest.Builder subscription
connection.subscriptionRequestBuilder();
@@ -1074,7 +1074,7 @@ public static void main(String[] args) throws Exception {
System.out.println("URL:
https://cache.industry.siemens.com/dl/files/604/44240604/att_67003/v1/s7sfc_en-EN.pdf");
System.out.println("******************************************************************************************");
- try (PlcConnection connection new
DefaultPlcDriverManager().getConnection("s7://10.10.1.33?remote-rack=0&remote-slot=3&controller-type=S7_400"))
{ //(01)
+ try (PlcConnection connection new
DefaultPlcDriverManager().getConnection("s7://10.10.1.33?cotp.remote-rack=0&cotp.remote-slot=3&controller-type=S7_400"))
{ //(01)
final PlcReadRequest.Builder readrequest
connection.readRequestBuilder(); //(02)