Skip to content

Commit 4152385

Browse files
committed
Added sub operation
1 parent 43a77a9 commit 4152385

File tree

6 files changed

+223
-120
lines changed

6 files changed

+223
-120
lines changed

docs/getting-started/operations.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,18 @@ Supported registers: **HOLDING_REGISTER**, **INPUT_REGISTER**
3030
*For **INPUT_REGISTER** type *FLOAT32* is not supported!*
3131

3232

33+
## Sub
34+
Sub (as the name implies) subtract a certain value of a variable, like the example below:
35+
36+
```xml
37+
<sub symbol="MOTOR_SPEED1">1.12</sub>
38+
```
39+
40+
Both **symbol** and **value** are mandatory fields. **value** can be of type *FLOAT32* , *INT16* which must
41+
follow the same type of the specified **symbol** definition.
42+
43+
Supported registers: **HOLDING_REGISTER**, **INPUT_REGISTER**
44+
45+
*For **INPUT_REGISTER** type *FLOAT32* is not supported!*
46+
47+

src/main/kotlin/PlcSimulation.kt

Lines changed: 2 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import kotlinx.coroutines.*
2+
import operations.*
23
import java.lang.Float
34

4-
55
class PlcSimulation(
66
configurationParser: ConfigurationParser,
77
memory: PlcMemory,
@@ -39,7 +39,7 @@ class PlcSimulation(
3939
}
4040

4141
is Sub -> {
42-
//TODO
42+
subOperation(element, configuration, memory)
4343
}
4444

4545
else -> throw UnsupportedOperationException("Unknown simulation step type")
@@ -61,130 +61,12 @@ class PlcSimulation(
6161

6262
}
6363

64-
private fun addOperation(element: Add, configuration: Configuration, memory: PlcMemory){
65-
println("Add symbol ${element.symbol} value ${element.value}")
66-
var variable = configuration.registers.getVarConfiguration(element.symbol)
67-
if (variable == null) {
68-
println("ERROR: Symbol ${element.symbol} not found during Set execution")
69-
throw CancellationException("Error - Add")
70-
} else {
71-
if(variable.addressType == AddressType.COIL || variable.addressType == AddressType.DISCRETE_INPUT){
72-
println("ERROR: Symbol ${element.symbol} is of type COIL or DISCRETE_INPUT which is not support by Add operation")
73-
throw CancellationException("Error - Add")
74-
}
75-
76-
when (variable.addressType) {
7764

78-
AddressType.HOLDING_REGISTER -> {
79-
//get the current value
80-
//add
81-
//set back the new value
82-
83-
if (variable.datatype == "FLOAT32") {
84-
var currentValue = memory.readHoldingRegister(variable.address.toInt(), 2)
85-
if(currentValue.isEmpty()){
86-
println("ERROR: Add Operation - Unable to get value of ${element.symbol} address ${variable.address} ")
87-
throw CancellationException("Error - Add")
88-
}
89-
val intValue = (( currentValue[1].toInt() shl 16) or (currentValue[0].toInt() and 0xFFFF))
90-
val currentFloatValue = java.lang.Float.intBitsToFloat(intValue)
91-
var floatValue = element.value.toFloat()
92-
floatValue += currentFloatValue
93-
setHoldingRegisterFloat32(floatValue, memory, variable)
94-
} else {
95-
var currentValue = memory.readHoldingRegister(variable.address.toInt(), 1)
96-
if(currentValue.isEmpty()){
97-
println("ERROR: Add Operation - Unable to get value of ${element.symbol} address ${variable.address} ")
98-
throw CancellationException("Error - Add")
99-
}
100-
var intValue = element.value.toInt()
101-
intValue += currentValue.first().toInt()
102-
setHoldingRegisterInt16(memory, variable, intValue.toShort())
103-
}
104-
}
105-
AddressType.INPUT_REGISTER -> {
106-
val currentValue = memory.readInputRegister(variable.address.toInt(), 1)
107-
val newValue = currentValue.first() + element.value.toShort()
108-
memory.setInputRegister(variable.address.toInt(),newValue.toShort())
109-
}
110-
111-
else -> {
112-
throw CancellationException("Error - Add")
113-
}
114-
}
115-
}
116-
}
11765

118-
private fun setOperation(element: Set, configuration: Configuration, memory: PlcMemory) {
119-
println("Set symbol ${element.symbol} value ${element.value}")
120-
var variable = configuration.registers.getVarConfiguration(element.symbol)
121-
if (variable == null) {
122-
println("ERROR: Symbol ${element.symbol} not found during Set execution")
123-
throw CancellationException("Error - Set")
124-
} else {
125-
if ((variable.addressType == AddressType.COIL || variable.addressType == AddressType.DISCRETE_INPUT) && (variable.value != "0" && variable.value != "1")) {
126-
println("ERROR: Invalid value format. Symbol ${element.symbol} is of BOOL type and supports only values 0 or 1 not ${variable.value}")
127-
}
128-
when (variable.addressType) {
129-
AddressType.HOLDING_REGISTER -> {
130-
if (variable.datatype == "FLOAT32") {
131-
val floatValue = element.value.toFloat()
132-
setHoldingRegisterFloat32(floatValue, memory, variable)
133-
} else {
134-
//Int16
135-
val intValue = element.value.toShort()
136-
setHoldingRegisterInt16(memory, variable, intValue)
137-
}
138-
}
13966

140-
AddressType.COIL -> {
141-
memory.forceSingleCoil(
142-
variable.address.toInt(),
143-
element.value.toBooleanFromBinary()
144-
)
145-
}
14667

147-
AddressType.DISCRETE_INPUT -> {
148-
memory.setDiscreteInput(
149-
variable.address.toInt(),
150-
element.value.toBooleanFromBinary()
151-
)
152-
}
15368

154-
AddressType.INPUT_REGISTER -> {
155-
memory.setInputRegister(variable.address.toInt(), element.value.toShort())
156-
}
157-
}
158-
}
159-
}
16069

161-
private fun setHoldingRegisterInt16(memory: PlcMemory, variable: Register, intValue: Short) {
162-
memory.presetMultipleRegisters(
163-
mutableListOf<Pair<Int, Short>>(
164-
Pair<Int, Short>(
165-
variable.address.toInt(),
166-
intValue
167-
)
168-
)
169-
)
170-
}
17170

172-
private fun setHoldingRegisterFloat32(floatValue: kotlin.Float, memory: PlcMemory, variable: Register) {
173-
val intValue = Float.floatToIntBits(floatValue)
174-
val lowWord = intValue and 0xFFFF
175-
val highWord = (intValue ushr 16) and 0xFFFF
176-
memory.presetMultipleRegisters(
177-
mutableListOf<Pair<Int, Short>>(
178-
Pair<Int, Short>(
179-
variable.address.toInt(),
180-
lowWord.toShort()
181-
),
182-
Pair<Int, Short>(
183-
variable.address.toInt() + 1,
184-
highWord.toShort()
185-
),
186-
)
187-
)
188-
}
18971

19072
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package operations
2+
3+
import Configuration
4+
import PlcMemory
5+
import Add
6+
import java.util.concurrent.CancellationException
7+
import toBooleanFromBinary
8+
fun addOperation(element: Add, configuration: Configuration, memory: PlcMemory){
9+
println("Add symbol ${element.symbol} value ${element.value}")
10+
var variable = configuration.registers.getVarConfiguration(element.symbol)
11+
if (variable == null) {
12+
println("ERROR: Symbol ${element.symbol} not found during Set execution")
13+
throw CancellationException("Error - Add")
14+
} else {
15+
if(variable.addressType == AddressType.COIL || variable.addressType == AddressType.DISCRETE_INPUT){
16+
println("ERROR: Symbol ${element.symbol} is of type COIL or DISCRETE_INPUT which is not support by Add operation")
17+
throw CancellationException("Error - Add")
18+
}
19+
20+
when (variable.addressType) {
21+
22+
AddressType.HOLDING_REGISTER -> {
23+
//get the current value
24+
//add
25+
//set back the new value
26+
27+
if (variable.datatype == "FLOAT32") {
28+
var currentValue = memory.readHoldingRegister(variable.address.toInt(), 2)
29+
if(currentValue.isEmpty()){
30+
println("ERROR: Add Operation - Unable to get value of ${element.symbol} address ${variable.address} ")
31+
throw CancellationException("Error - Add")
32+
}
33+
val intValue = (( currentValue[1].toInt() shl 16) or (currentValue[0].toInt() and 0xFFFF))
34+
val currentFloatValue = java.lang.Float.intBitsToFloat(intValue)
35+
var floatValue = element.value.toFloat()
36+
floatValue += currentFloatValue
37+
setHoldingRegisterFloat32(floatValue, memory, variable)
38+
} else {
39+
var currentValue = memory.readHoldingRegister(variable.address.toInt(), 1)
40+
if(currentValue.isEmpty()){
41+
println("ERROR: Add Operation - Unable to get value of ${element.symbol} address ${variable.address} ")
42+
throw CancellationException("Error - Add")
43+
}
44+
var intValue = element.value.toInt()
45+
intValue += currentValue.first().toInt()
46+
setHoldingRegisterInt16(memory, variable, intValue.toShort())
47+
}
48+
}
49+
AddressType.INPUT_REGISTER -> {
50+
val currentValue = memory.readInputRegister(variable.address.toInt(), 1)
51+
val newValue = currentValue.first() + element.value.toShort()
52+
memory.setInputRegister(variable.address.toInt(),newValue.toShort())
53+
}
54+
55+
else -> {
56+
throw CancellationException("Error - Add")
57+
}
58+
}
59+
}
60+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package operations
2+
3+
import PlcMemory
4+
import Register
5+
import java.lang.Float
6+
import toBooleanFromBinary
7+
8+
fun setHoldingRegisterFloat32(floatValue: kotlin.Float, memory: PlcMemory, variable: Register) {
9+
val intValue = Float.floatToIntBits(floatValue)
10+
val lowWord = intValue and 0xFFFF
11+
val highWord = (intValue ushr 16) and 0xFFFF
12+
memory.presetMultipleRegisters(
13+
mutableListOf<Pair<Int, Short>>(
14+
Pair<Int, Short>(
15+
variable.address.toInt(),
16+
lowWord.toShort()
17+
),
18+
Pair<Int, Short>(
19+
variable.address.toInt() + 1,
20+
highWord.toShort()
21+
),
22+
)
23+
)
24+
}
25+
26+
fun setHoldingRegisterInt16(memory: PlcMemory, variable: Register, intValue: Short) {
27+
memory.presetMultipleRegisters(
28+
mutableListOf<Pair<Int, Short>>(
29+
Pair<Int, Short>(
30+
variable.address.toInt(),
31+
intValue
32+
)
33+
)
34+
)
35+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package operations
2+
3+
import Configuration
4+
import PlcMemory
5+
import Set
6+
import toBooleanFromBinary
7+
import java.util.concurrent.CancellationException
8+
fun setOperation(element: Set, configuration: Configuration, memory: PlcMemory) {
9+
println("Set symbol ${element.symbol} value ${element.value}")
10+
var variable = configuration.registers.getVarConfiguration(element.symbol)
11+
if (variable == null) {
12+
println("ERROR: Symbol ${element.symbol} not found during Set execution")
13+
throw CancellationException("Error - Set")
14+
} else {
15+
if ((variable.addressType == AddressType.COIL || variable.addressType == AddressType.DISCRETE_INPUT) && (variable.value != "0" && variable.value != "1")) {
16+
println("ERROR: Invalid value format. Symbol ${element.symbol} is of BOOL type and supports only values 0 or 1 not ${variable.value}")
17+
}
18+
when (variable.addressType) {
19+
AddressType.HOLDING_REGISTER -> {
20+
if (variable.datatype == "FLOAT32") {
21+
val floatValue = element.value.toFloat()
22+
setHoldingRegisterFloat32(floatValue, memory, variable)
23+
} else {
24+
//Int16
25+
val intValue = element.value.toShort()
26+
setHoldingRegisterInt16(memory, variable, intValue)
27+
}
28+
}
29+
30+
AddressType.COIL -> {
31+
memory.forceSingleCoil(
32+
variable.address.toInt(),
33+
element.value.toBooleanFromBinary()
34+
)
35+
}
36+
37+
AddressType.DISCRETE_INPUT -> {
38+
memory.setDiscreteInput(
39+
variable.address.toInt(),
40+
element.value.toBooleanFromBinary()
41+
)
42+
}
43+
44+
AddressType.INPUT_REGISTER -> {
45+
memory.setInputRegister(variable.address.toInt(), element.value.toShort())
46+
}
47+
}
48+
}
49+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package operations
2+
3+
4+
import Configuration
5+
import PlcMemory
6+
import Sub
7+
import java.util.concurrent.CancellationException
8+
import toBooleanFromBinary
9+
10+
fun subOperation(element: Sub, configuration: Configuration, memory: PlcMemory){
11+
println("Sub symbol ${element.symbol} value ${element.value}")
12+
var variable = configuration.registers.getVarConfiguration(element.symbol)
13+
if (variable == null) {
14+
println("ERROR: Symbol ${element.symbol} not found during Set execution")
15+
throw CancellationException("Error - Sub")
16+
} else {
17+
if(variable.addressType == AddressType.COIL || variable.addressType == AddressType.DISCRETE_INPUT){
18+
println("ERROR: Symbol ${element.symbol} is of type COIL or DISCRETE_INPUT which is not support by Sub operation")
19+
throw CancellationException("Error - Sub")
20+
}
21+
22+
when (variable.addressType) {
23+
24+
AddressType.HOLDING_REGISTER -> {
25+
//get the current value
26+
//add
27+
//set back the new value
28+
29+
if (variable.datatype == "FLOAT32") {
30+
var currentValue = memory.readHoldingRegister(variable.address.toInt(), 2)
31+
if(currentValue.isEmpty()){
32+
println("ERROR: Add Operation - Unable to get value of ${element.symbol} address ${variable.address} ")
33+
throw CancellationException("Error - Add")
34+
}
35+
val intValue = (( currentValue[1].toInt() shl 16) or (currentValue[0].toInt() and 0xFFFF))
36+
val currentFloatValue = java.lang.Float.intBitsToFloat(intValue)
37+
var floatValue = element.value.toFloat()
38+
floatValue -= currentFloatValue
39+
setHoldingRegisterFloat32(floatValue, memory, variable)
40+
} else {
41+
var currentValue = memory.readHoldingRegister(variable.address.toInt(), 1)
42+
if(currentValue.isEmpty()){
43+
println("ERROR: Add Operation - Unable to get value of ${element.symbol} address ${variable.address} ")
44+
throw CancellationException("Error - Add")
45+
}
46+
var intValue = element.value.toInt()
47+
intValue -= currentValue.first().toInt()
48+
setHoldingRegisterInt16(memory, variable, intValue.toShort())
49+
}
50+
}
51+
AddressType.INPUT_REGISTER -> {
52+
val currentValue = memory.readInputRegister(variable.address.toInt(), 1)
53+
val newValue = currentValue.first() - element.value.toShort()
54+
memory.setInputRegister(variable.address.toInt(),newValue.toShort())
55+
}
56+
57+
else -> {
58+
throw CancellationException("Error - Sub")
59+
}
60+
}
61+
}
62+
}

0 commit comments

Comments
 (0)