//
//  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

= Simulated

The simulated driver holds its state in the client process and speaks to no real device.
It exists so PLC4X functionality can be exercised and demonstrated without a PLC to
connect to, and it is the driver most people reach for first when learning PLC4X.

== Supported Operations

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

|
| `read`
| Supports all standard IEC 61131 data types outlined below.

|
| `write`
| Supports all standard IEC 61131 data types outlined below.

|
| `subscribe`
| Java only, and a real implementation rather than polling-emulated: it supports
CYCLIC, CHANGE_OF_STATE and EVENT subscriptions directly. The Go driver's subscriber
is a stub and does not subscribe.

|===

== Connection String

The simulated driver runs entirely in-process and never opens a transport. The connection
string names an in-memory device rather than an address:
----
simulated:{device-name}
----
An example connection string would look like:
----
simulated:foobar
----
Each call creates a fresh in-memory device; values written through one connection do not
survive its close, and devices are not shared between connections.

== Connection String Options

include::partial$simulated.adoc[]

== Tag Addresses

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

=== General Format

The simulated addresses have this format:

----
{simulation-type}/{alias}:{data-type}[{array-size}]
----

If the array-size part is omitted, the default size of `1` is assumed.
If the data-type part is omitted, it defaults to STRING.

[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].
====

=== Simulation Types

The simulation device supports 3 different simulation types

- STATE - This holds in memory a value for a given alias. This value can be read or written to, however this
should only be used in conjunction with a persistent connection. Once the connection is closed the memory area is cleared.
- RANDOM - This provides a new random value for each read. When writing, a log message is recorded and the value is discarded.
- STDOUT - Always returns a null value when reading. When writing, a log message is recorded and the value is discarded.

=== Alias

Aliases are used to identify the different field addresses.
They should only contain alpha-numeric and the full stop (.) character.
For readability and language specific technical purposes they should be less than 256 characters.

=== 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)
- LINT (int 64)
- ULINT (uint 64)
- LWORD (uint 64)
- REAL (float)
- LREAL (double)
- CHAR (char)
- WCHAR (2 byte char)
- STRING (254 bytes)

=== Examples

All of these address formats are valid:-

- RANDOM/foo:INT
- RANDOM/foo:UDINT
- RANDOM/foo[0..7]:INT
- RANDOM/test[0..1]:DINT
- STATE/bar:DINT
- STATE/foo:String
- STDOUT/foo:BOOL

== Notes and Tips

The simulation driver uses a lot of the same logic templates that is used for the other drivers. It is a good way to test PLC4X
functionality without having a device to connect to.
