Skip to content

Commit 20d18b5

Browse files
authored
Merge pull request #8 from paulorb/trace
Added Trace operation
2 parents 02b4781 + 3f19cd7 commit 20d18b5

File tree

7 files changed

+104
-4
lines changed

7 files changed

+104
-4
lines changed

.github/badges/branches.svg

Lines changed: 1 addition & 1 deletion
Loading

.github/badges/jacoco.svg

Lines changed: 1 addition & 1 deletion
Loading

docs/getting-started/operations.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,4 +123,16 @@ Example using a parameter as a value
123123
</ifEqual>
124124
```
125125

126-
Please note the **symbol** and **value** datatype needs to match.
126+
Please note the **symbol** and **value** datatype needs to match.
127+
128+
129+
## Trace
130+
131+
Trace operation provides a tool for debugging, by printing (tracing) the current
132+
value of symbols
133+
134+
Supported registers: **HOLDING_REGISTER**, **COIL**, **DISCRETE_INPUT**, **INPUT_REGISTER**
135+
136+
```
137+
<trace symbol="RPM_MOTOR" />
138+
```

examples/configuration_simulation.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,9 @@
7878
<csv symbol="TEMPERATURE_MOTOR4" file="test_data.csv" column="2" step="2" startRow="2" endRow="5" replay="true"/>
7979
<set symbol="RELAYON">1</set>
8080
<set symbol="RELAY_STATUS">1</set>
81+
<trace symbol="RPM_MOTOR" />
8182
<set symbol="RPM_MOTOR">400</set>
83+
<trace symbol="RPM_MOTOR" />
8284
<delay>1000</delay>
8385
<add symbol="MOTOR_SPEED1">15</add>
8486
<add symbol="RPM7">1</add>

src/main/kotlin/ConfigurationParser.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class ConfigurationParser {
2323
}
2424
private fun load(): Device? {
2525
try {
26-
val context = JAXBContext.newInstance(Device::class.java, Set::class.java, Random::class.java, Delay::class.java, Linear::class.java, Add::class.java, Sub::class.java, Csv::class.java, IfEqual::class.java, Parameters::class.java, Parameter::class.java)
26+
val context = JAXBContext.newInstance(Device::class.java, Set::class.java, Random::class.java, Delay::class.java, Linear::class.java, Add::class.java, Sub::class.java, Csv::class.java, IfEqual::class.java, Parameters::class.java, Parameter::class.java, Trace::class.java)
2727
val unmarshaller = context.createUnmarshaller()
2828
return if(fileName.isEmpty() ) {
2929
val reader = StringReader(this::class.java.classLoader.getResource("configuration.xml")!!.readText())
@@ -151,6 +151,17 @@ data class Sub(
151151
}
152152

153153

154+
//<trace symbol="MOTOR_SPEED1"></trace>
155+
@XmlRootElement(name="trace")
156+
data class Trace(
157+
@field:XmlAttribute(required = true)
158+
val symbol: String,
159+
){
160+
constructor(): this("")
161+
}
162+
163+
164+
154165
//<add symbol="MOTOR_SPEED1">RPM_MOTOR1</add>
155166
@XmlRootElement(name="add")
156167
data class Add(

src/main/kotlin/PlcSimulation.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class PlcSimulation(
1414
): BaseOperation(parameters,configurationParser.getConfiguredDevice().configuration ) {
1515
val linearOperations = LinearOperation()
1616
val csvOperations = CsvOperation()
17+
var traceOperation = TraceOperation(configurationParser.getConfiguredDevice().configuration, memory, parameters)
1718
val addOperation = AddOperation(configurationParser.getConfiguredDevice().configuration, memory, parameters)
1819
val setOperation = SetOperation(configurationParser.getConfiguredDevice().configuration, memory, parameters)
1920
val subOperation = SubOperation(configurationParser.getConfiguredDevice().configuration, memory, parameters)
@@ -83,6 +84,10 @@ class PlcSimulation(
8384
ifEqual(element, configuration, memory)
8485
}
8586

87+
is Trace -> {
88+
traceOperation.traceOperation(element)
89+
}
90+
8691
else -> throw UnsupportedOperationException("Unknown simulation step type")
8792
}
8893
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package operations
2+
3+
import Configuration
4+
import EnvironmentVariables
5+
import PlcMemory
6+
import Trace
7+
import org.slf4j.LoggerFactory
8+
import java.util.concurrent.CancellationException
9+
10+
class TraceOperation(
11+
private val configuration: Configuration, private val memory: PlcMemory, environmentVariables: EnvironmentVariables
12+
13+
) : BaseOperation(environmentVariables, configuration) {
14+
companion object {
15+
val logger = LoggerFactory.getLogger("TraceOperation")
16+
}
17+
18+
fun traceOperation(element: Trace) {
19+
var valueToTrace : String = ""
20+
var variable = configuration.registers.getVarConfiguration(element.symbol)
21+
if (variable == null) {
22+
TraceOperation.logger.error("Symbol ${element.symbol} not found during Trace execution")
23+
throw CancellationException("Error - Trace")
24+
} else {
25+
when (variable.addressType) {
26+
27+
AddressType.HOLDING_REGISTER -> {
28+
//get the current value
29+
30+
if (variable.datatype == "FLOAT32") {
31+
var currentValue = memory.readHoldingRegister(variable.address.toInt(), 2)
32+
if (currentValue.isEmpty()) {
33+
SubOperation.logger.error("Trace Operation - Unable to get value of ${element.symbol} address ${variable.address} ")
34+
throw CancellationException("Error - Trace")
35+
}
36+
val intValue = ((currentValue[1].toInt() shl 16) or (currentValue[0].toInt() and 0xFFFF))
37+
val currentFloatValue = java.lang.Float.intBitsToFloat(intValue)
38+
valueToTrace = currentValue.toString()
39+
} else {
40+
var currentValue = memory.readHoldingRegister(variable.address.toInt(), 1)
41+
if (currentValue.isEmpty()) {
42+
SubOperation.logger.error("Trace Operation - Unable to get value of ${element.symbol} address ${variable.address} ")
43+
throw CancellationException("Error - Add")
44+
}
45+
valueToTrace = currentValue.first().toInt().toString()
46+
}
47+
}
48+
49+
AddressType.INPUT_REGISTER -> {
50+
val currentValue = memory.readInputRegister(variable.address.toInt(), 1)
51+
valueToTrace = currentValue.first().toString()
52+
}
53+
54+
AddressType.COIL -> {
55+
val currentValue = memory.readCoilStatus(variable.address.toInt(), 1)
56+
valueToTrace = currentValue.first().toString()
57+
}
58+
59+
AddressType.DISCRETE_INPUT -> {
60+
val currentValue = memory.readInputStatus(variable.address.toInt(), 1)
61+
valueToTrace = currentValue.first().toString()
62+
}
63+
64+
}
65+
TraceOperation.logger.info("TRACE - Symbol: ${element.symbol} Value: $valueToTrace")
66+
67+
}
68+
}
69+
70+
}

0 commit comments

Comments
 (0)