//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
:imagesdir: ../../images/users/protocols
:icons: font

= UMAS (Schneider Electric PLCs)

This protocol is used by Schneider Electric PLCs such as the M340, M580 and the Quantum PLCs with the Unity firmware.

This driver supports reading, writing and browsing of PLC tags.

The Data Dictionary needs to be enabled on the PLC.

NOTE: The driver is available in Java and in Plc4Py. The tag address syntax differs slightly
between the two; where that is the case it is called out below.

== Supported Operations

[cols="2,2a,5a"]
|===
|Name |Value |Description

|
2+| `read`

|
2+| `write`

|
2+| `browse`

|
2+| `ping`

|
| `subscribe`
| Java, polling-emulated. Go, native - the Go driver's subscriptions are not built on
top of polling reads.
|===

== Connection String

UMAS has the following connection string format:-
----
umas:{transport}://{ip-address}:{port}?{options}
----
An example connection string would look like:-
----
umas:tcp://127.0.0.1:502
----
Note the transport, port and option fields are optional.

== Connection String Options

include::partial$umas.adoc[]

== Tag Addresses

Addressing is implemented in Go, Java and Python. See the
xref:protocols/index.adoc[protocol support matrix] for what each implementation does.

=== General Format

UMAS addresses are the symbolic names declared in the PLC program, following the usual
IEC 61131-3 conventions:

----
{tag-name}
{tag-name}[{index}]
{tag-name}.{child-name}
{tag-name}.{child-name}[{index}].{child-name}
----

Depending on the type of tag the child-name parameters are optional.
e.g. A tag with a BOOL data type could be `TESTING_BOOL_1`, whereas if it is a UDT the tag name is
followed by the child `TESTING_UDT_1.START`, which in itself could be a BOOL.
An index in square brackets selects a single element and may appear at any position of the path.

[NOTE]
====
Array selection uses the shared notation - a single index, an inclusive range, and
optionally the array's declared lower bound, placed before the type. See
xref:array-notation.adoc[Addressing arrays].
====

IMPORTANT: The Java driver takes the data type from the PLC's data dictionary, so an address carries
no `:\{data-type}` suffix - appending one makes the address invalid.

=== Memory Areas

Apart from tags defined in the PLC, Plc4Py is also able to access the %S and %SW
system memory areas.

The specific address details of the data in these areas are outlined in the devices
manual.

An example of the address format of these areas is %SW1 or %S20.

NOTE: These system memory addresses are supported by Plc4Py only. The Java driver's address parser
accepts symbolic names only and rejects addresses starting with `%`.

=== Data Types

The following data types are supported

- BOOL (boolean)
- SINT (int 8)
- USINT (uint 8)
- BYTE (uint 8)
- INT (int 16)
- UINT (uint 16)
- WORD (uint 16)
- DINT (int 32)
- UDINT (uint 32)
- DWORD (uint 32)
- REAL (float)
- STRING (char)
- TIME
- DATE
- TOD (Time of Day)
- DATE_AND_TIME

=== Examples

[cols="2" ,options="header"]
|===
|Address |Meaning
|`g_r32` |a simple global variable
|`g_plant.meta.r32` |a nested struct member
|`g_arrInt[3]` |the fourth element of an array
|`g_plant.items[2].value` |mixed struct and array access
|===

== Notes and Tips

The Go driver's generated `DataItem` parser has no case for `DATE`, `TIME_OF_DAY` (`TOD`) or
`DATE_AND_TIME` - by itself it would fall through to "unsupported type" for those three.
The driver works around that gap: `decodeReadResponse` and `encodeWriteValue` in
`plc4go/internal/umas/Values.go` hand-decode and hand-encode all three temporal types (plus
`STRING`), the same way plc4j's `UmasConnection` does, so reads and writes of `DATE` and
`TIME_OF_DAY` tags succeed rather than being refused. Every data type listed above reads and
writes in both languages.

UMAS ships no captured test data in any language - there is no packet capture or golden byte
sequence for either driver to compare against. The Java and Go drivers are instead verified
against each other: their symbolic-address pattern is byte-for-byte identical, and the Go
temporal/string decoding above is a deliberate port of plc4j's hand-decoding. Treat this driver's
correctness as validated by cross-implementation agreement, not by a real captured exchange.
