From 1e1474c6d0285311561ab42665700f96fa74da56 Mon Sep 17 00:00:00 2001 From: paulorb Date: Wed, 7 Aug 2024 21:40:24 +0400 Subject: [PATCH 1/3] Added support for trace operation --- examples/configuration_simulation.xml | 2 + src/main/kotlin/ConfigurationParser.kt | 13 +++- src/main/kotlin/PlcSimulation.kt | 5 ++ src/main/kotlin/operations/TraceOperation.kt | 70 ++++++++++++++++++++ 4 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/operations/TraceOperation.kt diff --git a/examples/configuration_simulation.xml b/examples/configuration_simulation.xml index 23f471b..5bfa98d 100644 --- a/examples/configuration_simulation.xml +++ b/examples/configuration_simulation.xml @@ -78,7 +78,9 @@ 1 1 + 400 + 1000 15 1 diff --git a/src/main/kotlin/ConfigurationParser.kt b/src/main/kotlin/ConfigurationParser.kt index c3dc792..f0062d5 100644 --- a/src/main/kotlin/ConfigurationParser.kt +++ b/src/main/kotlin/ConfigurationParser.kt @@ -23,7 +23,7 @@ class ConfigurationParser { } private fun load(): Device? { try { - 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) + 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) val unmarshaller = context.createUnmarshaller() return if(fileName.isEmpty() ) { val reader = StringReader(this::class.java.classLoader.getResource("configuration.xml")!!.readText()) @@ -151,6 +151,17 @@ data class Sub( } +// +@XmlRootElement(name="trace") +data class Trace( + @field:XmlAttribute(required = true) + val symbol: String, +){ + constructor(): this("") +} + + + //RPM_MOTOR1 @XmlRootElement(name="add") data class Add( diff --git a/src/main/kotlin/PlcSimulation.kt b/src/main/kotlin/PlcSimulation.kt index 54a0d76..6c2f13c 100644 --- a/src/main/kotlin/PlcSimulation.kt +++ b/src/main/kotlin/PlcSimulation.kt @@ -14,6 +14,7 @@ class PlcSimulation( ): BaseOperation(parameters,configurationParser.getConfiguredDevice().configuration ) { val linearOperations = LinearOperation() val csvOperations = CsvOperation() + var traceOperation = TraceOperation(configurationParser.getConfiguredDevice().configuration, memory, parameters) val addOperation = AddOperation(configurationParser.getConfiguredDevice().configuration, memory, parameters) val setOperation = SetOperation(configurationParser.getConfiguredDevice().configuration, memory, parameters) val subOperation = SubOperation(configurationParser.getConfiguredDevice().configuration, memory, parameters) @@ -83,6 +84,10 @@ class PlcSimulation( ifEqual(element, configuration, memory) } + is Trace -> { + traceOperation.traceOperation(element) + } + else -> throw UnsupportedOperationException("Unknown simulation step type") } } diff --git a/src/main/kotlin/operations/TraceOperation.kt b/src/main/kotlin/operations/TraceOperation.kt new file mode 100644 index 0000000..46da23c --- /dev/null +++ b/src/main/kotlin/operations/TraceOperation.kt @@ -0,0 +1,70 @@ +package operations + +import Configuration +import EnvironmentVariables +import PlcMemory +import Trace +import org.slf4j.LoggerFactory +import java.util.concurrent.CancellationException + +class TraceOperation( + private val configuration: Configuration, private val memory: PlcMemory, environmentVariables: EnvironmentVariables + +) : BaseOperation(environmentVariables, configuration) { + companion object { + val logger = LoggerFactory.getLogger("TraceOperation") + } + + fun traceOperation(element: Trace) { + var valueToTrace : String = "" + var variable = configuration.registers.getVarConfiguration(element.symbol) + if (variable == null) { + TraceOperation.logger.error("Symbol ${element.symbol} not found during Trace execution") + throw CancellationException("Error - Trace") + } else { + when (variable.addressType) { + + AddressType.HOLDING_REGISTER -> { + //get the current value + + if (variable.datatype == "FLOAT32") { + var currentValue = memory.readHoldingRegister(variable.address.toInt(), 2) + if (currentValue.isEmpty()) { + SubOperation.logger.error("Trace Operation - Unable to get value of ${element.symbol} address ${variable.address} ") + throw CancellationException("Error - Trace") + } + val intValue = ((currentValue[1].toInt() shl 16) or (currentValue[0].toInt() and 0xFFFF)) + val currentFloatValue = java.lang.Float.intBitsToFloat(intValue) + valueToTrace = currentValue.toString() + } else { + var currentValue = memory.readHoldingRegister(variable.address.toInt(), 1) + if (currentValue.isEmpty()) { + SubOperation.logger.error("Trace Operation - Unable to get value of ${element.symbol} address ${variable.address} ") + throw CancellationException("Error - Add") + } + valueToTrace = currentValue.first().toInt().toString() + } + } + + AddressType.INPUT_REGISTER -> { + val currentValue = memory.readInputRegister(variable.address.toInt(), 1) + valueToTrace = currentValue.first().toString() + } + + AddressType.COIL -> { + val currentValue = memory.readCoilStatus(variable.address.toInt(), 1) + valueToTrace = currentValue.first().toString() + } + + AddressType.DISCRETE_INPUT -> { + val currentValue = memory.readInputStatus(variable.address.toInt(), 1) + valueToTrace = currentValue.first().toString() + } + + } + TraceOperation.logger.info("TRACE - Symbol: ${element.symbol} Value: $valueToTrace") + + } + } + +} \ No newline at end of file From ef71912ac54b24a50d8e52b568c4d79216880bae Mon Sep 17 00:00:00 2001 From: paulorb Date: Wed, 7 Aug 2024 21:45:15 +0400 Subject: [PATCH 2/3] Add documentation for the trace operation --- docs/getting-started/operations.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/getting-started/operations.md b/docs/getting-started/operations.md index 480e23e..aa7c527 100644 --- a/docs/getting-started/operations.md +++ b/docs/getting-started/operations.md @@ -123,4 +123,16 @@ Example using a parameter as a value ``` -Please note the **symbol** and **value** datatype needs to match. \ No newline at end of file +Please note the **symbol** and **value** datatype needs to match. + + +## Trace + +Trace operation provides a tool for debugging, by printing (tracing) the current +value of symbols + +Supported registers: **HOLDING_REGISTER**, **COIL**, **DISCRETE_INPUT**, **INPUT_REGISTER** + +``` + +``` \ No newline at end of file From 3f19cd7534314189cc36c770a306633a39eb3d88 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 7 Aug 2024 17:52:01 +0000 Subject: [PATCH 3/3] commit badge --- .github/badges/branches.svg | 2 +- .github/badges/jacoco.svg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/badges/branches.svg b/.github/badges/branches.svg index 3e8cbef..13099bb 100644 --- a/.github/badges/branches.svg +++ b/.github/badges/branches.svg @@ -1 +1 @@ -branches12.2% \ No newline at end of file +branches11.6% \ No newline at end of file diff --git a/.github/badges/jacoco.svg b/.github/badges/jacoco.svg index 9b0e293..5c6b8b1 100644 --- a/.github/badges/jacoco.svg +++ b/.github/badges/jacoco.svg @@ -1 +1 @@ -coverage20.9% \ No newline at end of file +coverage19.8% \ No newline at end of file