| ============================================================== |
| (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 |