blob: 188eb8a78e1d4f938567ea1f3d2605836cf75cc6 [file]
==============================================================
(Unreleased) Apache PLC4X 1.0.0-SNAPSHOT
==============================================================
New Features
------------
- Java Configurations of drivers now support a "FILE" type
of configuration parameter.
- Subscription of change-of-state values now supports
providing a min time interval to prevent excessive
notifications.
- Added a new PlcCertificateAuthentication to the API module.
- Initial version of a new Java UMAS driver.
- Initial version of a new Java SLMP (Mitsubishi MELSEC) driver:
read and write access to word devices (D/W/R) using binary 3E
frames over TCP (including Batch Write).
- The 'plc4x' proxy driver now supports TLS as a transport and
requires mandatory username/password authentication
(configured via the new "username" and "password" connection
parameters).
- The Go serial transport now supports the full set of serial
options in the connection string: data-bits, stop-bits, parity,
flow-control, dtr, rts, read-timeout and write-timeout.
- The Go serial transport supports sharing one physical serial port
between multiple connections ("reuse-port", e.g. multi-slave Modbus
RTU) with broadcast reads and serialized writes, plus inter-frame
write pacing ("interframe-delay") on both shared and dedicated ports.
- The Java serial transport's shared-port mode ("reuse-port") now uses a
single broadcast reader per physical port, fixing responses being split
between connections, and "interframe-delay" write pacing works on both
shared and dedicated ports (gap measured from the last write or
received data).
- The Java Modbus RTU codec now frames responses by function code with
CRC validation and byte-wise resynchronization: batched deliveries
(e.g. on shared serial ports) yield every frame instead of only the
first, and partial or corrupted frames no longer discard buffered data.
- Java Modbus serial connections (RTU/ASCII) now serialize their requests
per connection (single outstanding transaction, matching the protocol),
fixing concurrent same-unit requests receiving each other's responses;
unknown Modbus exception codes map to REMOTE_ERROR instead of failing;
shared serial ports dispatch each connection's callbacks on their own
thread, so one blocked callback no longer stalls the whole port.
Responses are additionally validated against the pending request's
function code (late responses from timed-out requests are discarded
instead of completing the wrong caller), and the request timeout now
covers the full time from submission, including queueing.
- Drivers that don't natively support subscriptions (Modbus,
EtherNet/IP, AB-ETH, SLMP, UMAS) now provide subscriptions
through a polling-based emulation layer, supporting CYCLIC and
CHANGE_OF_STATE subscriptions.
- Added a new remote-data-fetching component (event-pump)
replacing the old scraper.
- Re-implemented the connection-cache with more reliable resource
handling and transparent re-subscription after a connection was
lost and re-established.
- New TCP transport implementation using per-connection
virtual-thread blocking I/O (replacing the NIO selector),
scaling better on Java 21.
- OPC-UA: Added reading and writing of structured values
(PlcStruct) and corrected array handling.
- OPC-UA: Tag data types are now derived from the server's type
model instead of being guessed from the input data.
- OPC-UA: Added browse support, resolving server-side types and
access rights.
- Simulated driver: Added STRING support.
- CANopen: Added NMT command support.
- Go: Added a production-grade BACnet/IP driver (segmentation,
write priority, directed/multi-target WhoIs, routed addressing,
array/bit-string property decoding).
- Go: The connection-cache now supports a configurable max idle
time, and connections carrying subscriptions are exempt from the
idle TTL.
- The Object-PLC-Mapping (OPM) module was ported to SPI3.
- PlcBrowseItem now reports which subscription types each item
supports via a new getSupportedSubscriptionTypes() method, so
browse results carry subscription capability information.
- OPC-UA: Improved Siemens S7-1500 support, including reading and
writing of (almost) all variant types.
- Updated the bundled KNX manufacturer data and the BACnet/KNX
vendor IDs for broader device recognition.
- Go: Connections can now be invalidated (Invalidate()) to mark
themselves irrecoverably failed for lease management, and
transport errors are now classified and propagated through
codecs/transports (TransportErrorKind).
- Performance: Sped up byte-aligned integer read/write in the Java
byte-based SPI buffers.
- EtherNet/IP: The CIP bit-string types (BYTE, WORD, DWORD, LWORD)
and unsigned integer types (USINT, UINT, UDINT, ULINT) can now be
read and written, in both the Java and the Go drivers. They were
accepted by the address parser but not decoded, so reading such a
tag returned INTERNAL_ERROR. All eight are unsigned over their
full range: a DWORD reads as 0 to 4294967295 and an LWORD as 0 to
18446744073709551615. Their signed counterparts are unchanged - a
DINT of 0xFFFFFFFF still reads as -1.
Incompatible changes
--------------------
- Configuration parameters now use one vocabulary across PLC4J and PLC4Go.
A duration in milliseconds ends in "-ms", TLS settings live under "tls.",
and a parameter aimed at a transport no longer repeats that transport's
code. Old names are removed rather than deprecated: supplying one is
reported as an unknown parameter, naming the replacement, and the setting
does not apply. The full table is below.
Durations:
request-timeout -> request-timeout-ms
timeout-request (ads) -> request-timeout-ms
connect-timeout -> connect-timeout-ms
read-timeout -> read-timeout-ms
write-timeout -> write-timeout-ms
session-timeout -> session-timeout-ms
channel-lifetime -> channel-lifetime-ms
min-channel-lifetime -> min-channel-lifetime-ms
ha-heartbeat-interval -> ha-heartbeat-interval-ms
ha-failover-timeout -> ha-failover-timeout-ms
Establishing a socket and completing a protocol handshake are two
settings, not one, so they now have two names. "connect-timeout-ms" is
the socket connect; the COTP handshake and the OPC UA negotiation steps
are "handshake-timeout-ms":
cotp.cotp-connection-timeout -> cotp.handshake-timeout-ms
negotiation-timeout (opcua) -> handshake-timeout-ms
Transport parameters no longer repeat their transport's code, which the
prefix already supplies:
tcp.tcp-no-delay -> tcp.no-delay
cotp.cotp-tpdu-size -> cotp.tpdu-size
tls.tls-version -> tls.version
TLS settings are addressed under "tls.":
tls.verify-ssl -> tls.verify
key-store-file (opcua) -> tls.keystore
key-store-password -> tls.keystore-password
key-store-type -> tls.keystore-type
trust-store-file -> tls.trust-store
trust-store-password -> tls.trust-store-password
trust-store-type -> tls.trust-store-type
The trust store drops "-file" for the same reason the key store does:
every one of these names a store, so saying so adds nothing. The TLS
transport already spelled them "tls.trust-store-file"; that becomes
"tls.trust-store" too, so the opcua and ctrlx drivers, which declare
their own, now agree with it.
A name a protocol specification fixes keeps its own spelling and units:
SLMP's "monitoring-timer" is a field of the 3E request frame in the
protocol's own units, not a value in milliseconds, so it is unchanged and
carries a comment at its declaration saying why.
- The OPC UA driver's "insecure-certificate-verification" became
"tls.verify", with the opposite sense. A connection that set
"insecure-certificate-verification=true" must now set "tls.verify=false".
This one is not just a rename: if it is missed, the new default applies,
which is to verify the server certificate. That fails loudly against a
server whose certificate does not validate rather than connecting
insecurely, but it is a behaviour change and not a silent one.
- An unrecognised connection-string parameter is now reported in PLC4Go as
well as PLC4J, naming the parameter and, where it can, the nearest known
one. It remains a warning: a stray parameter does not fail a connection
that would otherwise work. PLC4Go's OPC UA driver previously *refused*
the connection on an unknown option; it now warns like every other
driver, so a connection string accepted by PLC4J is no longer rejected
there.
In PLC4Go this covers the drivers that parse their configuration in one
place: ab-eth, bacnet-ip, c-bus, EtherNet/IP, firmata, IEC 60870-5-104,
Modbus, OPC UA, S7, SLMP and UMAS. The ADS, KNXnet/IP and simulated
drivers read their options where they are used rather than parsing a
configuration, so there is no point at which the leftovers are known;
they are unchanged and still report nothing.
The report also knows which transport the connection actually uses, so a
parameter that belongs to a different transport - "serial.baud-rate" on a
TCP connection - is called out as misdirected instead of being silently
excused as "some transport's".
A suggestion is offered only among the names the consumer that reported
actually read, so a parameter belonging to a transport is named as
unknown with nothing to suggest. PLC4J does better here: it draws the
known names from the driver, the transport, the audit log and the
connection-control options, and matches on the last segment, so a
missing prefix is recognised for what it is.
- Configuration values carrying secrets are marked at their declaration -
"@Secret" in PLC4J, a `secret:"true"` struct tag in PLC4Go - and render
as "<redacted>" wherever a configuration is rendered. This replaces
guessing from parameter names, which could only ever be one parameter
behind: a pre-shared key was logged in clear until its name was added to
the list by hand. A name-based check remains for parameters no
configuration declares, since a credential passed under an unknown name
is still a credential.
- PLC4Go's S7 driver reads the rack and slot as "cotp.local-rack",
"cotp.local-slot", "cotp.remote-rack" and "cotp.remote-slot". It read
them unprefixed, while PLC4J declares them on the COTP transport's
configuration and every S7 example in the documentation spells them with
the prefix - so the documented connection string set nothing in PLC4Go
and said so nowhere. The unprefixed names are now reported as unknown.
- Fixed PLC4Go logging connection strings verbatim. A password in a Go
connection string reached the log in clear at debug level, at twenty
call sites across the driver manager and the connection cache. They are
redacted now, along with credentials in a URI's userinfo. The parsed
URL and the connection container render redacted too - both reached the
same log lines by another route, so a redacted field sat beside the
credential it was hiding.
- PLC4Go addresses a transport's connection-string options under the
transport's own code, as PLC4J does and as the documentation has always
said: "tcp.connect-timeout-ms", "serial.baud-rate", "udp.so-reuse",
"pcap.speed-factor". They were read unprefixed, so every documented
transport setting was ignored in PLC4Go and left at its default. The
unprefixed names are now reported as unknown rather than silently
doing nothing. Options a driver injects into the map itself
("defaultTcpPort") are not addressed by anyone and keep their bare
names.
- PLC4Go's OPC UA driver reads the parameter names PLC4J declares and the
documentation lists - "tls.keystore", "tls.keystore-password",
"security-policy", "allow-unverified-security-policies" - rather than
names derived from its own Go struct fields ("keyStoreFile",
"securityPolicy"). The documented connection string reached it as a
set of unknown options and was ignored.
- A secret marking in PLC4Go applies whatever the field's type is. The
generator honoured "secret:\"true\"" only where it rendered a string, so
the tag on any other kind of field was accepted and silently did
nothing. The OPC UA key pair now carries the marking in both the
configuration and the secure channel.
- Redaction decides from the parameter name the driver will read, not the
name as written: "?%70assword=hunter2" is the password parameter once
the query is decoded, and was previously logged in clear. A connection
string nested inside another (the PLC4X proxy driver's
"remote-connection-string") is redacted as a connection string in its
own right, so its credentials no longer travel through the outer one -
while which PLC the proxy talks to stays visible.
- A BACnet/IP connection reported each unknown option once rather than
twice. Its options are parsed both by the driver, for the discovery
timeout, and by the connection; both reported, so one mistake read as
two.
- The connection-creating methods of the API moved from
"PlcConnectionManager" to a new "PlcConnectionFactory"
interface, which the "PlcDriverManager" hands out via
"getConnectionFactory()" (formerly "getConnectionManager()").
"PlcConnectionManager" now extends "PlcConnectionFactory" and
adds the "close()" method, and is only implemented by managers
that keep the connections they hand out, such as the connection
cache.
- The connection cache was renamed from
"CachedPlcConnectionManager" to "PlcConnectionCache", matching
the name the concept already has in PLC4Go. Its builder method
"withConnectionManager()" became "withConnectionFactory()", and
"PlcConnectionManagerClosedException" became
"PlcConnectionCacheClosedException". The Maven artifactId
("plc4j-tools-connection-cache") and the package are
unchanged.
- All drivers were migrated to a new shared SPI ("SPI3"):
dependency-free Read/Write buffers, an updated code-generation
framework, a pluggable-transport system and a layered
protocol-driver model.
- Drivers now reject connection strings using an unsupported
transport with an exception. The check can be force-disabled
via a configuration parameter.
- Several Maven artifactIds changed (tools, transports, scraper);
see the "Changed Maven Coordinates" section below for the full
mapping. Consumers must update their coordinates.
- The PlcBrowseItem interface gained a
getSupportedSubscriptionTypes() method that custom
implementations must now provide.
- Dropped support for Java 11, new baseline Java version is
Java 21.
- Migrated the build to Apache Maven 4.
- The Go serial transport's default baud-rate changed from 115200
to 9600 (aligning with common serial defaults and the Java
transport). Specify baud-rate explicitly if you relied on the
previous default.
- Go serial reads/writes without an explicit context deadline are
now bounded by the new read-timeout/write-timeout options
(default 1000 ms; set to 0 for the previous blocking behavior),
and invalid serial option values now fail connection creation
instead of being silently ignored.
- The Java serial transport removed the unused options
"break-enabled", "receive-buffer-size" and "send-buffer-size",
removed the combined "RTS_CTS_XON_XOFF" flow-control mode, and now
rejects invalid parity/flow-control values instead of silently
falling back to defaults. Option values are case-insensitive and
accept "-" or "_" as separator (canonical forms: none, odd, even,
mark, space; none, rts-cts, xon-xoff).
- Acquiring a shared Java serial port ("reuse-port") with a configuration
differing from the first connection's now fails with an error instead
of silently reusing the first configuration.
- The 'plc4x' proxy driver now defaults to the TLS transport
instead of plaintext TCP. Existing plaintext connections must
switch to an explicit transport prefix (e.g. "plc4x:tcp://...").
When using TLS against a server with a self-signed certificate,
set "tls.verify-ssl=false" (or pin the certificate).
- The 'plc4x' proxy driver now requires username/password
authentication on connect; connecting without credentials, or
with invalid ones, is rejected with an ACCESS_DENIED handshake.
- The PLC4J-API module however is intentionally held at
Java 17 to allow alternate driver implementations to support
Java 17.
- Updated the signature of the PlcBrowseRequestInterceptor to
also accept a queryName, query and item instead of just an
item.
- The ConnectionStateListener interface was updated to no longer
have a connected() and disconnected() method, but use a
onConnectionStateChanged method instead that accepts
PlcConnectionStateChangedEvent events which have many more
state change options beyond a simple connected and disconnected
event.
- The OPC UA driver's "security-policy" now defaults to
Basic256Sha256 instead of NONE. NONE means the channel is
neither signed nor encrypted, so anything on the network path
can read and alter what is exchanged, and the server is not
authenticated at all.
A protected channel needs the server's certificate to be known
before the channel is opened. The discovery phase that would
otherwise fetch it runs unprotected by necessity, and a
certificate learned from the peer it is meant to authenticate
establishes nothing - so the driver no longer proceeds from
discovery onto a channel weaker than the one configured. It used
to do exactly that, silently: a connection asking for
Basic256Sha256 got a session with neither signing nor encryption
and no indication of it.
Together this means a connection that names no certificate now
fails where it previously came up unprotected. Name one with
"server-certificate-file", or a trust store with
"tls.trust-store"; or set "discovery=false" if the endpoint needs
no discovery; or ask for "security-policy=NONE" to accept an
unprotected channel as before.
Note that a protected channel also needs a client key pair:
supply one with "key-store-file", or the driver generates a
throwaway self-signed certificate, which a server that
authenticates its clients will not accept.
- The OPC UA driver refuses to send a username and password over a
channel that neither signs nor encrypts, because the password is
then readable by anything on the path and stays useful long after
it is read. The new "allow-insecure-credentials" parameter sends
them anyway, with a warning.
- The OPC UA driver now requires an endpoint to match both the
requested security policy and the requested message security
mode, and selects the strongest endpoint that matches rather than
the weakest. It previously accepted an endpoint matching either
one and then chose the lowest security level on offer, so a
server publishing a wide-open endpoint beside a protected one was
usually reached over the wide-open one. Where two endpoints are
equally strong, one whose user token policy protects the token is
preferred.
- The ctrlX driver no longer trusts the Bosch factory default
certificate that ships inside the driver jar, and no longer
accepts a certificate for any host regardless of the name it was
issued for. It also asks for a TLS context rather than the
legacy "SSL" one. That certificate identifies nobody - anything
presenting it and its key was trusted - and because it was the
only trust anchor, a device carrying a properly issued
certificate could not be reached at all. The credentials for the
connection travel over that channel.
Connections to a device still on its factory certificate will
now fail. The new "allow-factory-default-certificate" parameter
restores the old behaviour, with a warning; alternatively
"server-certificate-file" names a single PEM certificate to
trust, or "tls.trust-store" (with "tls.trust-store-password" and
"tls.trust-store-type") a key store of them, matching the names used
by the OPC UA driver and the TLS transport.
"ignore-common-name" is also available if the certificate is
trusted but names a different host.
- The TLS transport now checks that the server's certificate was
issued for the host it connected to. The "ignore-common-name"
parameter was declared but never consulted, so this check did
not happen at all: with "verify-ssl" on, any certificate from a
trusted issuer was accepted for any host, which is what a
machine in the middle needs. Setting "ignore-common-name=true"
restores the old behaviour and logs a warning saying so.
A connection to a device whose certificate names something other
than the address it is reached at will now fail where it
previously succeeded.
Two new parameters make the check usable where a device carries
its own certificate: "tls.trust-store" (with
"tls.trust-store-password" and "tls.trust-store-type") names the
certificates to trust instead of the public authorities the JVM
ships with. Previously the only way past a private CA was
"verify-ssl=false", which turns off both the chain check and
this one.
- The IEC 60870-5-104 driver now derives its S-format
acknowledgements from the send sequence number of the frames it
received, counted modulo 2^15 and encoded in the upper fifteen
bits of the control field, as the standard requires. It
previously sent the received frame's receive sequence number
plus one, which is the station reporting how much of our traffic
it had taken in - a different number, and one that said nothing
about how far we had read. This changes what the driver puts on
the wire in response to received telemetry, so a station that
checks acknowledgements will see different (correct) values, and
one that had adapted to the old behaviour may need attention.
The frame format itself is unchanged.
- Tag addresses naming an implausible number of elements are now
rejected as invalid addresses rather than acted on. An element
count is a request to allocate, and it was taken at face value:
in the s7 driver a count is now measured against the 2097151
bytes an S7 address can reach (for the string forms, against
what one string of the declared length costs, which is the same
arithmetic the optimizer does in an int and where an unbounded
count overflowed); in the ads driver an index group, index
offset and element count must each fit the four bytes ADS
carries them in; in the firmata driver a digital tag must stay
within the 256 pins the protocol can name, having previously
turned its count into that many set bits at parse time. In all
three, a count too wide to be a number used to escape as a
NumberFormatException instead of the PlcInvalidTagException the
tag parsers promise.
- The OPC UA driver bounds a browse, which previously walked
whatever tree the server described for as long as it described
one. "browse-max-references-per-node" (default 65536) limits the
references collected for one node and is now also asked of the
server, "browse-max-total-nodes" (default 1000000) limits how
many nodes one browse expands, and "browse-max-depth" (default
64) limits how deep it recurses. Set any of them to 0 for no
limit. Reaching one warns and returns what was found rather
than failing, so an address space within these sizes is
unaffected.
- The ctrlX driver bounds a browse the same way, with
"browse-max-total-nodes" (default 1000000) and
"browse-max-depth" (default 64). Its browse also now always
completes its future: a node answering with no child list used
to throw inside the executor's task, where nothing caught it and
the caller was left waiting on a future that was never
completed. Such a node is now read as the leaf it says it is.
- The simulated driver bounds how much data one tag may ask it to
make up. The count in the address was multiplied by the size of
one element in an int to size the array it fills, so a large
enough count asked for a negative array rather than a large one,
and anything below that got what it asked for - three hundred
million doubles being 2.4 GB. The product is now measured
against a budget of 16 MiB per tag.
The Go driver carries that count as a uint16, where a count
above it used to be truncated to its low two bytes rather than
refused - a request for 70000 elements handing back a tag of
4464, and one for 65536 handing back a tag of none. Both are
now invalid addresses, as is a count of zero, which the Java
driver already refused.
- The modbus, profinet and profinet-ng tag parsers now report a
count, address or slot too wide to be a number as an invalid
tag. All three already bounded these values, but the checks ran
after the number was read, so anything too wide to read left as
a NumberFormatException instead. The digit widths are capped in
the address patterns, at what each field can hold.
- Every generated parser now refuses a message that nests its
types deeper than 1024 levels, in both the Java and the Go
bindings. Several types contain themselves - BACnet constructed
data holds further constructed data, an OPC UA variant of type
24 holds further variants - so the depth of the value tree is
the sender's to choose and one level costs a single byte on the
wire. Deep enough, that ran the parser out of stack: in Java a
StackOverflowError, which is neither a parse failure the driver
can report nor an error the receive path contains, so a frame
that should have cost one frame ended the connection; in Go a
goroutine out of stack takes the process with it rather than
the request. Set PLC4X_MAX_NESTING_DEPTH for a device whose
messages genuinely nest deeper - it means the same thing in
both bindings, and a value that is not a positive number leaves
the default in place with a warning. The deepest message in the
project's own testsuites nests 36 levels, so this bounds only
what no real device sends. Note for Go consumers that the
default rose from 255 to 1024 in the process, so one setting of
the variable now means one depth whichever binding reads it.
- plc4go now requires Go 1.27. The uuid package it used to take
from github.com/google/uuid now comes from the standard library,
which drops that dependency outright - it is gone from go.mod and
go.sum - at the cost of the version floor.
- EtherNet/IP: Two CIP data type codes were wrong and are
corrected. LWORD moves from 0x00D3 to 0x00D4 and STRINGI from
0x00DD to 0x00DE. Each had been sharing its value with another
type (DWORD and ENGUNIT respectively), and a duplicate key is
silently dropped from the generated lookup tables, so LWORD and
STRINGI could not be resolved by name or by value at all. Anyone
who hardcoded the old LWORD value was addressing a DWORD.
- EtherNet/IP: A string write now emits the structure the read path
parses - a 2-byte structure handle, a 4-byte length and then the
characters - so what the driver writes reads back as the same
value. Previously it wrote a bare length followed by the
characters, which no read could decode. The length is now the
number of UTF-8 bytes rather than of characters; the two differ
for any non-ASCII text, which used to read back truncated. Text
that does not fit the type's fixed payload is reported instead of
overflowing. Because CIPDataTypeCode.STRING declares a size of 0,
the serializer emits no payload for it at all, so a write
addressed as ":STRING" is now rejected rather than silently sent
empty - write strings as ":STRUCTURED".
- Go: Several values now serialize under their own names and in
their canonical forms, which changes the output anything parsing
it will see. PlcDWORD, PlcSINT, PlcULINT and PlcWSTRING were
serialized as PlcDINT, PlcINT, PlcUINT and PlcSTRING; PlcTIME and
PlcLTIME render ISO-8601 with hours/minutes/seconds and a
sub-second fraction instead of truncating to whole seconds;
PlcDATE_AND_TIME renders the UTC wall time in ISO-8601 rather
than Go's local-zone default; and PlcStruct keeps a deterministic
member order. String-ish values now carry encoding="UTF-8".
- Java: The unsigned bit-string values WORD, DWORD and LWORD now
serialize as dataType="uint" rather than through the signed
writers, PlcBYTE serializes as a bit string, and PlcTIME renders
as an ISO-8601 string like PlcLTIME. This aligns the Java and Go
renderings of the same value.
- EtherNet/IP: EipTag is now immutable, matching every other
driver's tag in both bindings - it was the only tag class in
plc4j that exposed setters. setType(...) and setElementNb(...)
are gone; give the type and the element count to the
constructor instead. An element count below one is normalised
to one rather than kept, so a tag built as ":INT:0", or through
the (tag, type) constructor which used to leave the count at
zero, now reads one element instead of none.
- All Java drivers now select array elements with one shared notation, written
before the data type: `[n]` for a single element, `[lo..hi]` for an
inclusive range, an optional `;base` for an array the PLC declares as
starting somewhere other than zero, and one bracket per dimension. The
dimensions of one array may also be written comma-separated inside a single
bracket - `[1..2,3..4]` is the same as `[1..2][3..4]` - which is the form
Allen-Bradley and others use; addresses are always rendered back in the
one-bracket-per-dimension form. See the "Addressing arrays" page.
This replaces four incompatible spellings. `[4]` meant "four elements" in
seven tag classes and "the fifth element" in two; it now means one element
everywhere, and a count is written as a range. Addresses in the old form no
longer parse, and the error names the address to write instead - so an
upgrade reports the change rather than quietly returning different data.
The affected forms, by driver:
S7 %DB42:28.0:BYTE[4] -> %DB42:28.0[0..3]:BYTE
S7 (string) %DB1:0:STRING(20)[4] -> %DB1:0[0..3]:STRING(20)
Modbus holding-register:1:INT[4] -> holding-register:1[0..3]:INT
SLMP D100:INT[4] -> D100[0..3]:INT
ADS (direct) 0x4020/0:DINT[4] -> 0x4020/0[0..3]:DINT
EtherNet/IP myArray[0]:DINT:4 -> myArray[0..3]:DINT
Profinet tag:INT[4] -> tag[0..3]:INT
Profinet-NG 1.2.INPUT.0:INT[4] -> 1.2.INPUT.0[0..3]:INT
Simulated RANDOM/foo:INT[4] -> RANDOM/foo[0..3]:INT
OPC-UA addresses are unchanged - its implementation is the one the shared
notation was extracted from - and ADS and UMAS symbolic addresses keep
their existing form while gaining ranges.
- Firmata is the one driver whose addresses change meaning silently. They
carry no data type (`3[4]`), so the brackets did not move and there is
nothing to reject: `3[4]` used to read four pins starting at pin 3 and now
reads one pin, the fifth. Rewrite these as `3[0..3]`.
- An address that selects nothing now asks for the whole value rather than a
single element. For a scalar that is unchanged; for an array it is every
element, on the drivers that can determine the extent from the device
(OPC-UA, ADS, UMAS). The others read one element as before, because their
addresses are memory offsets with no declared array at them.
- A single index and a one-element range are no longer the same thing.
`myTag[4]` selects one element and yields a scalar, while `myTag[4..4]`
yields a list of one. `PlcTag.getArrayInfo()` reports the shape of the
value received - empty for a scalar, one entry per dimension for an array -
so a consumer can tell the two apart without knowing the protocol.
- `ArrayInfo` gains `getBase()` and `isRange()`, both as default methods, so
existing implementations keep compiling. Its javadoc described `[6]` as a
six-element array, which was never what the drivers did and is not what the
notation means.
- EtherNet/IP rejects an array index above 255 while parsing the address; a
CIP MemberID carries a `uint 8`. A range may run past it, since the request
carries a start and a count, but it cannot begin there.
- ADS and UMAS verify a `;base` written in the address against the bounds the
device declares, and report a disagreement. The device is authoritative; a
base that differs means the address was written against a different layout,
which would otherwise read silently shifted data.
- ADS rejects an address that names a member of an array without saying which
element - `MAIN.g_arr.member` on an array `g_arr`. It previously resolved
against the first element and reported the result as though it were the
whole path.
- Selecting array elements over UMAS is reported as UNSUPPORTED rather than
returning the whole variable. The driver has no per-element arithmetic yet;
the address parses, and the refusal is explicit.
- Fixed `getArrayInfo()` reporting one element too many on the ADS direct and
Firmata drivers, whose inclusive bounds were built from the element count
rather than the last index.
- Fixed a direct ADS array selection transferring every element it asked for
and decoding only the first, in both PLC4J and PLC4Go. The size of the
request was multiplied by the element count while the decoder was given no
shape, so `0x4020/0[0..3]:DINT` returned one value for four elements' worth
of bytes - a well-formed answer to a question nobody asked.
- Fixed a symbolic ADS selection being ignored in PLC4Go. `MAIN.arr[1..4]`
resolved like `MAIN.arr`: the whole array, from its original offset. The
selection now moves the read to the first selected element and transfers
only what it spans, across as many dimensions as the address names
(`MAIN.grid[3,1..3]`), and a selection outside what the device declares is
refused rather than approximated.
- Fixed the shape of a partly selected multi-dimensional ADS array in PLC4J.
`MAIN.grid[1..2]` on an `ARRAY [0..9,0..4]` reported two elements rather
than two rows of five: the dimensions the selection did not name were
dropped from the shape while their bytes were still transferred. They are
selected whole, and are part of the value.
- A dimension of an ADS selection written as a bare index now collapses,
where before every named dimension added a level of list. `grid[3,1..3]` is
a list of three, not a list of one list of three, and `grid[3,2]` is a
scalar. This is the same rule the notation states for a single dimension.
- Fixed SLMP reporting a one-element range as a scalar in PLC4J. `D100[4..4]`
now returns a list of one, as `D100[4]` returns a scalar and as PLC4Go's
SLMP driver already did. Its shape came from the element count, which
cannot express the difference.
- PLC4Go now uses the same array notation as PLC4J, so one address means one
thing in either language. The grammar, the rules and the rendering are the
ones described above; the two share a specification rather than code, and
the Go parser is tested against the Java cases directly.
The forms that changed, by driver:
S7 %M100:INT[10] -> %M100[0..9]:INT
S7 (string) %DB69.DBX68:WSTRING[3] -> %DB69.DBX68[0..2]:WSTRING
Modbus holding-register:1:INT[4] -> holding-register:1[0..3]:INT
SLMP D100:INT[4] -> D100[0..3]:INT
EtherNet/IP %rate:DINT:4 -> %rate[0..3]:DINT
Simulated RANDOM/foo:INT[4] -> RANDOM/foo[0..3]:INT
KNXnet/IP 1.2.3#4B1C:UINT[4] -> 1.2.3#4B1C[0..3]:UINT
KNXnet/IP 1.2.3#11/1/1[4] -> 1.2.3#11/1/1[0..3]
Addresses in the old form no longer parse, and the error names the address
to write instead - with two exceptions, below, where the address parses
either way and only its meaning moves.
- Two Go drivers change the meaning of addresses that still parse, so there is
nothing to reject and nothing to warn about at runtime:
* ADS `[n]` was a *count* of n elements and is now the element at index n.
`MAIN.g_arr[3]` read three elements and now reads one. Rewrite as
`MAIN.g_arr[0..2]`. This also means Go and Java ADS now agree about the
same address; they did not before.
* Firmata `[n]` was a run of n pins and is now the pin at index n, exactly
as in PLC4J. `digital:2[3]` read three pins from pin 2 and now reads
pin 5. Rewrite as `digital:2[0..2]`.
- ADS also drops the `[a:b]` start-and-count form, which had no counterpart in
PLC4J. `MAIN.g_arr[2:4]` is written `MAIN.g_arr[2..5]`.
- A count of zero no longer has a spelling. Several Go drivers accepted `[0]`
and rejected it as "quantity must be greater than zero"; a range is written
with the indices it covers, so there is no way to ask for none, and `[0]`
now selects the first element.
- `ArrayInfo` bounds are inclusive in PLC4Go, as they are in PLC4J:
`GetSize()` returns `UpperBound - LowerBound + 1`. They were exclusive,
documented as a deliberate divergence, so `[0..7]` reported eight elements
in Java and seven in Go - the same disagreement about the same address that
this change exists to remove. Code reading `GetUpperBound()` directly must
be revisited.
- `ArrayInfo` gains `GetBase()` and `IsRange()`. Go has no default methods, so
any implementation outside PLC4Go must add them.
- Addresses that a driver rendered back are now spelled the way its parser
reads them. Several never round-tripped: BACnet/IP rendered `:` where the
syntax wants `,`, gave every property a leading `:`, and printed the address
of the pointer holding an array index rather than the index; KNXnet/IP
device addresses rendered `/` where the syntax wants `.`; the ADS direct
form printed its index group as decimal digits behind an `0x` prefix, so
16416 came back as `0x16416` - a different address; and the S7 tag rendered
as "0:INT[8]", naming neither the memory area nor the offset it read.
- Fixed the Go BACnet/IP driver asking for one element fewer than requested
when a read carried an element count, which followed from the bounds
becoming inclusive.
- C-Bus addresses are unchanged. Its brackets carry the arguments of a CAL
command (`recall=[param, count]`), not a selection appended to an address.
- KNXnet/IP group addresses are unchanged. Their brackets hold a set of group
addresses to match (`[1-3,5]`), not an array selection. Only the two device
address forms, which carry a real element count, moved to the new notation.
- BACnet/IP addresses are unchanged. Its bracket is a property array index,
which already meant what the notation says an index means.
Changed Maven Coordinates
-------------------------
The Maven groupId of all modules is unchanged ("org.apache.plc4x").
The following artifactIds changed; consumers must update their
dependency coordinates accordingly:
- The "tools" modules were renamed to the "plc4j-tools-*" pattern:
plc4j-capture-replay -> plc4j-tools-capture-replay
plc4j-connection-cache -> plc4j-tools-connection-cache
plc4j-opm -> plc4j-tools-opm
- The transport modules were renamed from the singular
"plc4j-transport-*" to the plural "plc4j-transports-*":
plc4j-transport-can -> plc4j-transports-can
plc4j-transport-pcap-replay -> plc4j-transports-pcap-replay
plc4j-transport-raw-socket -> plc4j-transports-raw-socket
plc4j-transport-serial -> plc4j-transports-serial
plc4j-transport-tcp -> plc4j-transports-tcp
plc4j-transport-test -> plc4j-transports-test
plc4j-transport-udp -> plc4j-transports-udp
plc4j-transport-socketcan -> plc4j-transports-can-socketcan
plc4j-transport-virtualcan -> plc4j-transports-can-virtualcan
- The scraper was replaced by the new event-pump component:
plc4j-scraper -> plc4j-tools-event-pump
- Removed modules (no direct replacement):
plc4j-scraper-ng (experimental, dropped)
plc4j-transport-pcap-shared (obsolete)
Note: this release also adds a number of new SPI3 modules (e.g.
the "plc4j-spi-*" buffers/config/drivers/values split, the new
"plc4j-transports-api"/"-cotp"/"-tls" transports, the
"plc4j-utils-audit-log*" and "plc4j-utils-subscription-emulation"
utilities). These are new artifacts, not renames.
Bug Fixes
---------
- Fixed the Java S7 driver's tags reporting no address at all:
"getAddressString()" returned null, so anything carrying a tag as a string -
a log line, a browse result, a serialized request - got nothing from an S7
tag. It now spells the address the way the parser reads it back, including
the declared length of a fixed-length string and the counter number of a
COUNTER address, which is stored split across the byte and bit offsets.
- The Open Protocol driver's tag class now reports that it has no tag
addressing yet instead of returning null. "OpenProtocolTag.of()" handed a
null tag to callers of "prepareTag()", so the failure surfaced later as a
NullPointerException; it now throws PlcInvalidTagException, matching the
driver's tag handler, which already rejected every address.
- Fixed the Go S7 driver reading a fixed-length string from the wrong data
block. The long-form address ("%DB69.DBX68:STRING(10)") built its tag with
a hard-coded block number of zero, so it read DB0 and reported the result
as though it had come from DB69. The short form ("%DB69:68:STRING(10)")
and every non-string address were unaffected, as is PLC4J, which parses
the block number for all of them.
- Fixed serialization in the 'plc4x' proxy driver's message
codec, which did not configure the buffer integer/string
encodings under SPI3 and failed to serialize any message.
- OPC-UA: Fixed several issues: a hang during discovery /
encrypted-policy negotiation, a divide-by-zero when the server
provided no certificate, and hardened parsing of corrupt or
malicious responses that could previously cause an
OutOfMemoryError.
- ADS: The connect handshake now honors the configured AMS ports
instead of hardcoding RUNTIME_SYSTEM_01/851.
- ADS: Fixed an invalid size calculation in AdsDataTypeArrayInfo.
- ADS: Fixed serialization of STRING/WSTRING values.
- S7: Fixed duplicate TSAP information at the COTP and S7 level.
- Connection-cache: Fixed a deadlock when obtaining a connection,
plus a race condition and idle-timer/cleanup issues.
- The base driver now redacts password information from console
logs.
- TCP transport: Close the SocketChannel on a failed bind /
socket-option setup.
- Request objects were made more null-safe (#2280).
- OPC-UA: All consumers registered on a shared subscription now
receive notifications (previously only one consumer was
registered).
- AB-ETH: Fixed reading a tag after the SPI3 refactoring.
- The socket is now disconnected when the handshake fails instead
of being left hanging (#2290).
- Go Modbus: Hardened frame parsing against truncated/extended
frames, trailing CRCs from misbehaving gateways and TCP
keep-alive padding, with stream resynchronization on desync.
- Go: Numerous stability and resource-leak fixes (connection cache
no longer hands out dead connections, goroutine and codec-worker
leaks on Modbus reconnect, robust Modbus receive with
desync/resync, TCP/UDP transport deadline and reset races, codec
disconnect deadlock).
- Go: Generated code ignored the string encoding declared in the
mspec and read and wrote every string as UTF-8. A WSTRING, which
ADS declares as UTF-16LE, stopped at the first NUL byte, so
"wolf" decoded as "w". The generated code now carries the real
encodings (UTF-16LE, UTF-16BE, ASCII, ISO-8859-1, Windows-1252),
and the byte-based write buffer passes the single-byte encodings
through instead of zero-filling anything it did not recognise.
Reading a string likewise honors the requested encoding, decoding
UTF-16 per code unit rather than per byte.
- Java: The XML buffer could not read back everything its own
writer produced. A field discriminating on a typed enum was
written under the enum's name but read under the field's, and a
text node larger than the parser's chunk size - the ADS symbol
and data-type tables run to 70-80k characters - failed with
"Expected end element" because the reader was not coalescing.
- ADS (Go): Several fixes. The connection accepts the same
kebab-case parameters as the Java driver (source-ams-net-id and
friends), and a missing targetAmsNetId is now reported as such
rather than as sourceAmsNetId. The device-info request uses the
configured AMS ports instead of a hardcoded 851/800. Multi-tag
subscriptions run in request order rather than in map order,
honor the requested interval as the notification cycle time, and
no longer panic when a data type is missing from the table. The
data type table is keyed by the name symbols actually reference.
- ADS (Go): Direct-address reads and writes all failed with
"invalid tag item type" - the request paths expected a pointer
where the tag handler produced a value - and never filled in the
tag's data type. Hex address parts with an odd number of digits
(0x8) were rejected, though the Java driver accepts them.
- EtherNet/IP: A reply carrying fewer bytes than a single-element
tag declares no longer throws out of the response handler; it is
reported as INTERNAL_ERROR for that tag, which is what a
truncated multi-element reply already did.
==============================================================
Apache PLC4X 0.13.1
==============================================================
New Features
------------
- Extended the PlcRawByteArray to provide access to a List of
USINT objects.
Incompatible changes
--------------------
Bug Fixes
---------
- When reading an array of bits, the old s7 driver seems to hang.
- The s7 driver causes issues when writing arrays of bits.
- The block optimizer used in s7-light causes errors, if a tag
references the same byte multiple times.
- When using the new block-optimizer in the s7-light driver,
when reading multiple BOOL values located in the same byte
produces errors
==============================================================
Apache PLC4X 0.13.0
==============================================================
New Features
------------
- The CachedPlcConnectionManager now has a maxIdleTimeout time
which defaults to 5 minutes. If a connection is not being
used for that amount of time, the connection is closed and
removed from the cache.
- The CachedPlcConnectionManager now has a close method, which
shuts down all connections.
- The CachedPlcConnection now implements the EventPlcConnection
interface which forwards listener registrations to the
connection.
- The S7 driver is now able to automatically split up large
array requests into multiple ones and transparently merge
them back together. It is now possible to read arrays of
almost unlimited size.
- Added an Optimizer to the Modbus driver, that improves read
performance of multi-item read requests by more than 10 times.
- Added an optimizer to the Modbus protocol, that allows reading
multiple fields in one request.
- Added support for Modbus encodings of BIG_ENDIAN_WORD_SWAP
and LITTLE_ENDIAN_WORD_SWAP.
- Modbus tags allow specifying the unit-id in order to address
multiple devices using one serial modbus connection.
- Added a new optimizer to the S7 protocol, that ready chunks
of data instead of individual fields, which allows reading
a lot more fields in one request.
- Added a new variant of the S7 driver, called s7-light, which
doesn't have support for subscriptions, but is less likely
to cause connection problems.
- Added auto-discovery to the KNX Driver in PLC4J.
- Added auto-discovery to EIP in PLC4J.
- Added auto-discovery to S7 in PLC4J.
- Improved some things in the SPI, that caused issues with
drivers under heavy load.
- The Modbus driver uses the "Single Register Request" if a
tag fits into one register. This can help communicating with
devices that don't support "Multi Register Requests".
Incompatible changes
--------------------
- When reading byte arrays with the s7 driver, now the more
efficient PlcRawByteArray type is used, that gives users
direct access to the bytes returned from the PLC instead of
a list of PlcValues.
- The builders for read-, write- ans subscription.requests now
process tags and values on a per-field level. If one field
has an invalid address it will now only fail the one item
related to that. Same applies to values. Only the tag who's
value was invalid will be considered failed and no longer an
exception should be thrown.
- Subscription-requests now allow registering a handler for
all fields in the subscription.
- The addPreRegisteredConsumer method was removed and versions
of the "addXYZ" methods were added, that allow providing
individual consumers for each tag.
Bug Fixes
---------
==============================================================
Apache PLC4X 0.12.0
==============================================================
New Features
------------
- API: Made several bits of information available via the API
allowing tools to provide more content assist when dealing
with PLC4X connections.
- S7: The S7 driver now supports reading of STRING and
WSTRING data-types without providing a maximum length.
- Build: Worked on making PLC4X provide reproducible builds.
- Added "Ping" functionality to: ADS, EIP, KNX, Mock, Modbus
and Simulated drivers.
- The OPC-UA Java driver now support certificate-based
authentication and encryption.
Incompatible changes
--------------------
- Java 8 is no longer officially supported and Java 11 is the
new base-line.
- Renamed the PlcDriverManager method `listDrivers` to
`getProtocolCodes`
- Renamed the PlcDriverMetadata method `canDiscover` to
`isDiscoverySupported`
- Renamed the PlcConnectionMetadata methods `canRead`, `canWrite`
`canSubscribe` and `canBrowse` to `isReadSupported`,
`isWriteSupported`, `isSubscribeSupported` and `isBrowseSupported`
- The configuration syntax for configuring transport-related
config options in the connection-string was updated to be
now prefixed with the transport name the option belongs to.
Bug Fixes
---------
- S7: Several bugs and issues regarding supporting various
duration, date and time data-types.
- S7: Implemented the missing 64bit (L-) types.
- KNX: Fixed an issue with decoding 16 bit floating point
numbers.
- NiFi-Integration: The NiFi integration module was greatly
improved.
- Core: Fixed several leaks of open threads.
==============================================================
Apache PLC4X 0.11.0
==============================================================
New Features
------------
- IEC-60870-5-104 driver
- Completely rewritten EIP driver that should now support
Allen-Bradley controllers
- Completely rewritten the ADS driver that now supports
Auto-Discovery, Browse, UDOs and auto-configuration of
remote AMS routes
- Support for S7 200 subscriptions
- Added a docker-compose setup in a preparation for reproducible
builds
- Added SBOM generation
- Improved Apache NiFi support
- Added support for the latest ETS version in KNX
- Started implementing the ping() method for some drivers
- Greatly updated Apache NiFi integration
Incompatible changes
--------------------
- Java 1.8 is no longer supported and Java 11 is now the new
baseline version we support.
- We've updated the APIs of both PLC4J and PLC4Go to be more in
sync. We also refined some of the terminology.
- We've also re-written the `connection-cache`, which now replaces
both the old `connection-pool` and the old `connection-cache`.
- The UI module has been removed as it relied on JavaFX, which is
no longer bundled with the JDK and therefore the LGPL license
renders is dad for Apache projects.
- The Apache Camel integration was moved over to the Apache Camel
project.
- The prototype-driver for PROFINET was completely updated
- Due to the extreme refactoring of S7, ADS and EIP, the Go versions
of these drivers are currently not going to work as well as before
(We're going to address these issues in the next phase after the
release)
- Changed the return type of the PLC4J Ping method to return more
information on if the ping was successful
Bug Fixes
---------
Fixed issues with memory leaks in the ConnectionManager
Fixed multiple issues reported for the handling of data-types in
S7, Modbus and ADS protocols when reading and writing.
==============================================================
Apache PLC4X 0.10.0
==============================================================
A lot of the work in this version went into refactoring and
cleaning up our code generation. The code generation itself is
now a lot cleaner and simpler as well as the code generated
for Java. We also added a number of new field-types to allow
implementing more sophisticated protocols. PLC4C now should
also support all of the constructs mspec has to offer.
New Features
------------
- Implemented a `PLC4X-Server` and `PLC4X-Driver` that allows
using the server as a proxy for communicating with PLCs.
- The Modbus driver is now also available in the variants:
"modbus-rtu" and "modbus-ascii" (Both using Serial
communication, which however can be tunneled through a
"tcp" and "udp" transport)
- The KNX driver in Java now supports reading "knxproj" files
exported from the new ETS version 6.
Incompatible changes
--------------------
- The name of the Modbus TCP driver was changed from "modbus"
to "modbus-tcp".
- Removed the Apache Edgent (incubating) integration and
examples related, as Edgent is abandoned and there were
CVEs reported, which will not be fixed.
- We have replaced the BitString types with BYTE, WORD, DWORD,
and LWORD which generally match their unsigned integer
counterparts. So we are no longer returning lists of boolean
values for any of these types.
Bug Fixes
---------
- Fixed a big bug in the KNX Datapoint decoding, which caused
byte-aligned data types to parse with an offset of 8 bit.
(This bug affected both the Java and the Go driver)
==============================================================
Apache PLC4X 0.9.0
==============================================================
New Features
------------
- The OPC UA driver has been replaced with a native driver. Previously
Eclipse Milo was being used.
- Permit customized package names for code generation
- Added an initial draft of a Discover and Browse API to PLC4J
- PLC4Go now supports many more drivers
- PLC4Go received a huge internal refactoring and cleanup
- Major cleanup of PLC4C
- S7 Driver now supports event and alarm handling on some S7 models
Incompatible changes
--------------------
Bug Fixes
---------
PLC4X-200 OPC-UA Driver not connecting if params string is not provided
PLC4X-201 OPC-UA PlcList underlying type not compatible with Eclipse Milo
PLC4X-202 OPC-UA Driver cannot write Unsigned Types
PLC4X-276 [S7] The most of the supported types don't work correctly
PLC4X-278 Double Reading Error
PLC4X-279 nioEventLoopGroup thread proliferation
PLC4X-280 ADS route request swapped positions of route name and address
PLC4X-291 DefaultPlcSubscriptionField cannot be cast to class OpcuaField
PLC4X-298 [S7] When writing REAL values the Write
operation fails with an internal error
PLC4X-299 Modbus - Kafka Connect Configuration
PLC4X-312 CAN NOT READ STRING FROM S7 PLC
PLC4X-314 CAN NOT WRITING MANY DATA TO S7 ONE TIME
==============================================================
Apache PLC4X 0.8.0
==============================================================
This is an ordinary PLC4X release, containing changes that
accumulated over time. It doesn't have an explicit focus on
a particular topic.
New Features
------------
- The KNXnet/IP Driver now supports writing of values.
- The Modbus driver now supports more common notations of
Modbus addresses using a pure-numeric notation.
- The ADS, KNX, Modbus, S7 and simulated drivers have been
updated to support the IEC 61131-3 data-types.
- We are now including PLC4Go as PLC4X implementation in
the programming language Go(lang)
- Integration with the Milo OPC UA Server is now available.
- Kafka Connect workers have been updated source and sink connectors
are now included.
Incompatible changes
--------------------
- The syntax of the S7 addresses changed slightly allowing to
provide a string length. Without this, a STRING datatype will
read 254 characters, by adding the size in round brackets to
the type name will use the specified number.
Examples:
Read one String which is max 10 chars long:
%DB2:30:STRING(10)
Read an array of 3 Strings where each is max 10 chars long:
%DB2:30:STRING(10)[3]
- The PLCValue types have been refactored to align with the types
defined in IEC 61131-3 (https://en.wikipedia.org/wiki/IEC_61131-3)
directly using the older Java types (PlcBoolean) is no longer
possible.
Bug Fixes
---------
A lot of testing was done regarding the IEC 61131-3 data-types.
This resulted in numerous bugfixes in many protocols.
PLC4X-132 [S7] Communication to S7 PLC dies in some situations
PLC4X-206 When writing short values exceptions are thrown
while preparing the write request.
PLC4X-207 No registered handler found for message TPKTPacket[],
using default decode method - Communication with S7
and Modbus device hangs
PLC4X-209 [S7] When writing INT and DINT values the Write
operation fails with an internal error
PLC4X-210 [KNX] When running a KNX Tunneling Subscription
for a longer time there are packets that kill
the connection
PLC4X-211 PlcValues seem to always return "true" on the
isXYZ" checks.
PLC4X-212 When writing multiple values in one request the
item status is not correctly set
PLC4X-213 [Modbus] The Modbus driver doesn't handle error
responses gracefully
PLC4X-214 [Modbus] Holding register addresses have an offset
of 1 (Not reading the correct address)
PLC4X-215 Drivers using the BaseOptimizer
(SingleFieldOptimizer) don't handle error responses
gracefully
PLC4X-218 [Scraper] After stopping the scraper still the
statistics are logged and the application doesn't
terminate
PLC4X-239 Read DTL (Date and Time)
PLC4X-240 Protocol error in reading string
PLC4X-246 S7 driver hangs on read
PLC4X-245 [Modbus] Apache NiFi processor throws
java.io.IOException after a while
PLC4X-255 Kafka Connector Source Task doesn't block within poll()
resulting in high CPU usage.
PLC4X-261 Pooled connection manager returns a connection that isn't
connected in some situations.
PLC4X-272 When splitting up large requests, too big sub-requests
are generated (S7)
PLC4X-256 ReadBuffer truncate last byte of even small payloads
PLC4X-262 Error in reading Array
PLC4X-270 Ads driver does not accept double-digit array indexes
==============================================================
Apache PLC4X 0.7.0
==============================================================
This version is the first after a major refactoring of the driver
core. All previous driver versions are now considered deprecated
and have been replaced by versions using the new driver structure
and generated driver codebase.
New Features
------------
- Drivers now support structured types using PlcValues
- The EIP (EtherNet/IP) driver no longer requires an external
library and is implemented fully in the PLC4X project
- The Modbus driver no longer requires an external library
and is implemented fully in the PLC4X project
- The new S7 Driver supports writing multiple entries in one
request (The API allowed this from the beginning now not
every item is wrapped in a single request. It should bring
significant performance gains when writing multiple values)
- S7 Driver now supports String datatypes.
- OSGi : Implementation of Drivers/Transports as OSGi services
to be able to use them in an OSGi container.
- New Firmata protocol driver
Incompatible changes
--------------------
- Due to the refactoring of the driver core there might be issues
running drivers built against older core versions.
- This version doesn't provide a Beckhoff AMS/ADS driver as this
driver is still being ported to the new mspec format.
- All drivers connection strings now follow the same pattern:
{protocol-code:(transport-code:)?//{transport-config}(?{params})?
Please check the drivers documentation on our website:
https://plc4x.apache.org/users/protocols/s7.html
- The karaf-feature modules are removed as the drivers now all
provide both a feature.xml as well as a `kar` bundled archive
Bug Fixes
---------
PLC4X-174 UDP Transport does not accept ports containing 0
PLC4X-134 S7 is terminating the connection during handshake
PLC4X-192 Support for conversion of complex connection string
parameters
==============================================================
Apache PLC4X 0.6.0
==============================================================
This is the last release of PLC4X with the "handwritten" drivers.
This Minor release will thus receive updates and fixes until
most users have switched to 0.7 and above (with generated drivers).
If you are using the S7 Driver you should update to this Version
as the critical (memory leak) bug PLC4X-163 is fixed.
New Features
------------
- PLC4X-168 A shorter S7 Field Syntax is Introduced.
This release contains no further features and mostly stabilization.
Incompatible changes
--------------------
- Moved the C++, C# and Python drivers into the `sandbox`
Bug Fixes
---------
- Fixed Promise Chain for InternalPlcWriteRequest
- PLC4X-45 Add float support to Modbus Protocol
- PLC4X-164 Fix wrong NOT FOUND exception in OPC UA Driver
- PLC4X-166 Fixed Download Page
- PLC4X-163 Fixed Netty ByteBuf Leaks for S7 Driver
- PLC4X-158 Added Warning if no Pooled Driver is used for Scraper
==============================================================
Apache PLC4X 0.5.0
==============================================================
This is the first release containing our new generated drivers (AB-ETH)
New Features
------------
- Implemented a new Apache Kafka Connect integration module
- Implemented a new Apache NiFi integration module
- Implemented a new Logstash integration module
- Implemented a driver for the AB-ETH protocol
- Implemented Apache Karaf features for S7 OSGI drivers
- PLC4X-121 Develop Code Generation to allow Generated Drivers in multiple Languages
Sandbox (Beta-Features)
- Implemented a new BACnet/IP passive mode driver
- Implemented a new Serial DF1 driver
Incompatible changes
--------------------
Bug Fixes
---------
- PLC4X-104 S7 Driver Datatype TIME_OF_DAY causes ArrayOutOfBoundException
- PLC4X-134 S7 is terminating the connection during handshake
- PLC4X-139 PLC4X leaks sockets in case of connection problems
- PLC4X-141 String with real length of greater 127 throw an exception
- PLC4X-144 When requesting invalid addresses, the DefaultS7MessageProcessor produces errors
==============================================================
Apache PLC4X 0.4.0
==============================================================
This is the first release of Apache PLC4X as top-level project.
New Features
------------
- The PlcConnection now supports a `ping` method to allow checking if an existing connection is still alive.
- Support of the OPC-UA protocol with the `opc-ua-driver`.
- Other Languages Support:
-- Added first versions of a C# .Net PLC4X API (`plc4net`)
-- Added first versions of a Python PLC4X API (`plc4py`)
- Added an Interop server which allows to relay requests from other languages to a Java Server
Incompatible changes
--------------------
- ElasticSearch example was updated to use ElasticSearch 7.0.1, this might cause problems with older Kibana versions.
Bug Fixes
---------
==============================================================
Apache PLC4X (incubating) 0.3.1
==============================================================
This is a bugfix-release, that fixes some problems with S7 driver.
Bug Fixes
---------
- The S7 driver didn't correctly handle "fill-bytes" in multi-item read-responses and multi-item write-requests
- PLC4X-83: fixed NPE when reading odd-length array of one-byte base types
- PLC4X-82: renamed flags "F" to Siemens Standard "M" (Marker)
- PLC4X-84: Fixed a bug in the DefaultS7MessageProcessor which didn't correctly merge together split up items
==============================================================
Apache PLC4X (incubating) 0.3.0
==============================================================
This is the third official release of Apache PLC4X.
Some new features have been added (e.g. plc-scraper) multiple
new integrations are included (apache-karaf, apache-calcite)
and a lot of (technical) refactoring has been done to prepare
future work on adapters in different languages.
New Features
------------
- Object PLC Mapping (OPM) now has a Alias Registry to allow
variable substitution at runtime and write support
- New module `plc-scraper` for applications that have to
scrape a lot of sps fields with high frequency
- New integration `apache-karaf` to enable plc4j in a karaf
runtime environment
Incompatible changes
--------------------
- The 'plc4j-core' module has been merged into 'plc4j-api'.
So there is no 'plc4j-core' module anymore. Just remove that
dependency.
- The driver artifact names have changed so if you were using
a `plc4j-protocol-{name}` you now need to change this to
`plc4j-driver-{name}`
Bug Fixes
---------
PLC4X-75 Fixing dependency to the wrap url-handler
PLC4X-76 When receiving responses with more than 512 byte,
the IsoOnTcp protocol doesn't work
PLC4X-77 When the last item in a request is a DINT, the
DefaultS7MessageProcessor dies
PLC4X-78 Write operations seem to fail
- Fixed a Bug where S7 was not able to read arrays.
==============================================================
Apache PLC4X (incubating) 0.2.0
==============================================================
This is the second official release of Apache PLC4X.
Especially have we addressed all issues reported during
our first release, that were of non-technical nature.
These were tracked in:
PLC4X-60 Fix findings by the last release
New Features
------------
A new connection-pool was added, which allows automatic
pooling and reuse of PLC connections.
A new OPM module was added, which allows JPA like read-
communication using POJOs, very similar to JPA.
A stub of a new driver for the Emerson DeltaV protocol
has been added, but is not yet a fully functional PLC4X
driver. This is also a first test of our new `passive-
mode-driver` concept.
Incompatible changes
--------------------
We have refactored the API in order to eliminate the
need of passing `x-requests` to `x-methods` and added
an `execute` method to each request type. This greatly
simplifies the client code. However this requires
refactoring of applications using the direct PLC4X API.
Miscellaneous changes
---------------------
We have increased the test coverage greatly and fixed
a lot of little errors we found on the way.
Known Issues
------------
Bug Fixes
---------
PLC4X-56 [S7] S7Field does not recognize addresses
with numElements present
PLC4X-57 [S7] Response for address with numElements
contains only first item
PLC4X-61 Installation fails plc4j-protocoll-ethernetip
needs license
PLC4X-62 Modbus results deliver null-Value due to missing
implementation of getShort, getLong ...
==============================================================
Apache PLC4X (incubating) 0.1.0
==============================================================
This is the first official release of Apache PLC4X.
It contains drivers for the following protocols:
- Siemens S7comm (0x32)
- Beckhoff ADS
- Modbus
- EtherNet/IP
However the Siemens driver definitely is the most
mature driver, the rest should be treated experimental.
New Features
------------
PLC4X-29 [S7] Implement PDU Fragmentation
PLC4X-39 Extend the Edgent integration with the new Subscription features of PLC4X
Incompatible changes
--------------------
- NONE -
Miscellaneous changes
---------------------
- NONE -
Known Issues
------------
- NONE -
Most drivers should be treated experimental and are not near production ready.
The S7 driver is probably the furthest implemented and tested driver and hereby can be
considered to be the most mature.
Bug Fixes
---------
PLC4X-20 Jacoco doesn't seem to be working at all
PLC4X-21 Code coverage doesn't seem to work
PLC4X-47 S7 driver silently ignores surplus ReadRequestItems
PLC4X-48 S7 driver fails to parse response with multiple items