Skip to content

Commit

Permalink
Merge pull request #5 from paulorb/logging
Browse files Browse the repository at this point in the history
Logging
  • Loading branch information
paulorb authored Jul 22, 2024
2 parents 8abc256 + f811a57 commit c4d4037
Show file tree
Hide file tree
Showing 11 changed files with 112 additions and 44 deletions.
7 changes: 6 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,24 @@ repositories {
}
}

val log4jVersion = "2.12.1"

dependencies {
kapt("info.picocli:picocli-codegen:4.6.1")
implementation ("info.picocli:picocli:4.6.1")
implementation("javax.xml.bind:jaxb-api:2.3.1")
implementation("com.sun.xml.bind:jaxb-core:2.3.0.1")
implementation("com.sun.xml.bind:jaxb-impl:2.3.3")
implementation ("com.github.paulorb:modbus-kt:1.0.12")
implementation ("com.github.paulorb:modbus-kt:1.0.14")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2")
implementation("org.apache.commons:commons-csv:1.10.0")
implementation("org.apache.logging.log4j:log4j-core:$log4jVersion")
implementation("org.apache.logging.log4j:log4j-api:$log4jVersion")
implementation("org.apache.logging.log4j:log4j-slf4j-impl:$log4jVersion")
testImplementation(kotlin("test"))
}


kapt {
arguments {
arg("project", "${project.group}/${project.name}")
Expand Down
12 changes: 9 additions & 3 deletions src/main/kotlin/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import picocli.CommandLine.Model.CommandSpec
import java.util.*
import java.util.concurrent.Callable
import kotlin.system.exitProcess

import org.apache.logging.log4j.core.config.Configurator
import org.slf4j.LoggerFactory

data class EnvParameter(
var symbol : String,
Expand Down Expand Up @@ -50,6 +51,10 @@ class Checksum : Callable<Int> {
private lateinit var modbusServer: ModbusServer
private lateinit var environmentParameters: List<EnvParameter>

companion object {
val logger = LoggerFactory.getLogger("main")
}

private fun processEnvironmentParameters(parameters: MutableList<String?>?): List<EnvParameter> {
val envParameter = mutableListOf<EnvParameter>()
parameters?.forEach { param ->
Expand All @@ -66,17 +71,18 @@ class Checksum : Callable<Int> {
}

override fun call(): Int {
Configurator.initialize(null, "log4j2.xml")
val mainCoroutineScope = CoroutineScope(Dispatchers.Default)
val configuration = ConfigurationParser()

if(simulationRandomValues && file.isNotEmpty()){
println("-f and -sr cannot be mixed, one of the simulations must be chosen")
logger.error("-f and -sr cannot be mixed, one of the simulations must be chosen")
return -1
}

environmentParameters = processEnvironmentParameters(parameters)
if(environmentParameters.isNotEmpty()){
println("environment parameters: ${environmentParameters.toString()}")
logger.info("environment parameters: ${environmentParameters.toString()}")
}

//val fileContents = Files.readAllBytes(file.toPath())
Expand Down
25 changes: 15 additions & 10 deletions src/main/kotlin/PlcMemory.kt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import org.slf4j.LoggerFactory
import java.util.InvalidPropertiesFormatException
import java.util.concurrent.ConcurrentHashMap

Expand All @@ -10,6 +11,10 @@ class PlcMemory(configurationParser: ConfigurationParser) : IModbusServerEventL
private var holdingRegister: ConcurrentHashMap<Int, Short> = ConcurrentHashMap()
private var device = configurationParser.getConfiguredDevice()

companion object {
val logger = LoggerFactory.getLogger("PlcMemory")
}

init {
device.configuration.registers.register.forEach { register ->
when(register.addressType){
Expand Down Expand Up @@ -37,15 +42,15 @@ class PlcMemory(configurationParser: ConfigurationParser) : IModbusServerEventL

//0x
override fun forceMultipleCoils(addressValueList: MutableList<Pair<Int, Boolean>>) {
println("(0x) forceMultipleCoils")
logger.debug("(0x) forceMultipleCoils")
addressValueList.forEach { coil ->
coils[coil.first] = coil.second
}
}

//0x
override fun forceSingleCoil(address: Int, value: Boolean) {
println("(0x) forceSingleCoil")
logger.debug("(0x) forceSingleCoil")
coils[address] = value
}

Expand All @@ -61,7 +66,7 @@ class PlcMemory(configurationParser: ConfigurationParser) : IModbusServerEventL

// 4x
override fun presetMultipleRegisters(addressValueList: MutableList<Pair<Int, Short>>) {
println("(4x) presetMultipleRegisters")
logger.debug("(4x) presetMultipleRegisters")
addressValueList.forEach { register ->
holdingRegister[register.first] = register.second
}
Expand All @@ -70,13 +75,13 @@ class PlcMemory(configurationParser: ConfigurationParser) : IModbusServerEventL


override fun presetSingleRegister(address: Int, value: Boolean) {
println("presetSingleRegister")
logger.debug("presetSingleRegister")
TODO("Not yet implemented")
}

// 0x Registers
override fun readCoilStatus(startAddress: Int, numberOfRegisters: Int): List<Boolean> {
println("(0x) readCoilStatus")
logger.debug("(0x) readCoilStatus")
val listCoils = mutableListOf<Boolean>()
for(i in startAddress until startAddress + numberOfRegisters) {
if(coils[i] != null){
Expand All @@ -90,14 +95,14 @@ class PlcMemory(configurationParser: ConfigurationParser) : IModbusServerEventL

// 4x
override fun readHoldingRegister(startAddress: Int, numberOfRegisters: Int): List<Short> {
println("(4x) readHoldingRegister")
logger.debug("(4x) readHoldingRegister")
val listHoldingRegisters = mutableListOf<Short>()
for(i in startAddress until startAddress + numberOfRegisters) {
if(holdingRegister[i] != null){
println("readHoldingRegister address $i value=${holdingRegister[i]}")
logger.debug("readHoldingRegister address $i value=${holdingRegister[i]}")
listHoldingRegisters.add(holdingRegister[i]!!)
}else{
println("readHoldingRegister address $i value=0")
logger.debug("readHoldingRegister address $i value=0")
listHoldingRegisters.add(0)
}
}
Expand All @@ -106,7 +111,7 @@ class PlcMemory(configurationParser: ConfigurationParser) : IModbusServerEventL

// 3x register
override fun readInputRegister(startAddress: Int, numberOfRegisters: Int): List<Short> {
println("(3x) readInputRegister")
logger.debug("(3x) readInputRegister")
val listInputRegisters = mutableListOf<Short>()
for(i in startAddress until startAddress + numberOfRegisters) {
if(inputRegister[i] != null){
Expand All @@ -120,7 +125,7 @@ class PlcMemory(configurationParser: ConfigurationParser) : IModbusServerEventL

// 1x register
override fun readInputStatus(startAddress: Int, numberOfRegisters: Int): List<Boolean> {
println("readInputStatus")
logger.debug("readInputStatus")
val listCoils = mutableListOf<Boolean>()
for(i in startAddress until startAddress + numberOfRegisters) {
if(inputStatus[i] != null){
Expand Down
28 changes: 17 additions & 11 deletions src/main/kotlin/PlcSimulation.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import kotlinx.coroutines.*
import operations.*
import org.slf4j.LoggerFactory
import java.lang.Float
import java.rmi.NotBoundException
import java.util.*
Expand All @@ -16,6 +17,11 @@ class PlcSimulation(
val addOperation = AddOperation(configurationParser.getConfiguredDevice().configuration, memory, parameters)
val setOperation = SetOperation(configurationParser.getConfiguredDevice().configuration, memory, parameters)
val subOperation = SubOperation(configurationParser.getConfiguredDevice().configuration, memory, parameters)

companion object {
val logger = LoggerFactory.getLogger("PlcSimulation")
}

init {
var simulationConfiguration = configurationParser.getConfiguredDevice().simulation
var configuration = configurationParser.getConfiguredDevice().configuration
Expand All @@ -34,9 +40,9 @@ class PlcSimulation(
}
}
} catch (e: Exception) {
println("Exception - ${e.message}")
logger.error("Exception - ${e.message}")
} finally {
println("Job: Finally block, cleaning up resources")
logger.error("Job: Finally block, cleaning up resources")
}
}

Expand All @@ -53,7 +59,7 @@ class PlcSimulation(
}

is Delay -> {
println("Delay value ${element.value}")
logger.info("Delay value ${element.value}")
delay(element.value.toLong())
}

Expand Down Expand Up @@ -85,7 +91,7 @@ class PlcSimulation(


suspend fun ifEqual(element: IfEqual, configuration: Configuration, memory: PlcMemory) {
println("IfEqual symbol ${element.symbol} value ${element.value}")
logger.info("IfEqual symbol ${element.symbol} value ${element.value}")
var value = processValue(element.value)
var variable = configuration.registers.getVarConfiguration(element.symbol)
if (variable == null) {
Expand Down Expand Up @@ -113,11 +119,11 @@ class PlcSimulation(
processOperationElement(subElement, configuration, memory)
}
}else {
println("ERROR: Symbol ${element.symbol} has invalid datatype during IfEqual execution")
logger.error("Symbol ${element.symbol} has invalid datatype during IfEqual execution")
}

}else {
println("ERROR: Symbol ${element.symbol} not found during IfEqual execution")
logger.error("Symbol ${element.symbol} not found during IfEqual execution")
throw CancellationException("Error - IfEqual")
}
} else {
Expand All @@ -132,7 +138,7 @@ class PlcSimulation(
if (variable.datatype == "FLOAT32") {
var currentValue = memory.readHoldingRegister(variable.address.toInt(), 2)
if(currentValue.isEmpty()){
println("ERROR: Add Operation - Unable to get value of ${element.symbol} address ${variable.address} ")
logger.error("Add Operation - Unable to get value of ${element.symbol} address ${variable.address} ")
throw CancellationException("Error - Add")
}
val intValue = (( currentValue[1].toInt() shl 16) or (currentValue[0].toInt() and 0xFFFF))
Expand All @@ -153,7 +159,7 @@ class PlcSimulation(
} else {
var currentValue = memory.readHoldingRegister(variable.address.toInt(), 1)
if(currentValue.isEmpty()){
println("ERROR: IfEqual Operation - Unable to get value of ${element.symbol} address ${variable.address} ")
logger.error("IfEqual Operation - Unable to get value of ${element.symbol} address ${variable.address} ")
throw CancellationException("Error - IfEqual")
}
//compare
Expand All @@ -172,7 +178,7 @@ class PlcSimulation(
AddressType.INPUT_REGISTER -> {
val currentValue = memory.readInputRegister(variable.address.toInt(), 1)
if(currentValue.isEmpty()){
println("ERROR: IfEqual Operation - Unable to get value of ${element.symbol} address ${variable.address} ")
logger.error("IfEqual Operation - Unable to get value of ${element.symbol} address ${variable.address} ")
throw CancellationException("Error - IfEqual")
}
//compare
Expand All @@ -188,11 +194,11 @@ class PlcSimulation(
}
AddressType.COIL -> {
if ( (element.value != "0" && element.value != "1")) {
println("ERROR: Invalid value format on IfEqual. Symbol ${element.symbol} is of BOOL type and supports only values 0 or 1 not ${element.value} for comparison")
logger.error("Invalid value format on IfEqual. Symbol ${element.symbol} is of BOOL type and supports only values 0 or 1 not ${element.value} for comparison")
}
var currentValue = memory.readCoilStatus(variable.address.toInt(), 2)
if(currentValue.isEmpty()){
println("ERROR: IfEqual Operation - Unable to get value of ${element.symbol} address ${variable.address} ")
logger.error("IfEqual Operation - Unable to get value of ${element.symbol} address ${variable.address} ")
throw CancellationException("Error - IfEqual")
}
//compare
Expand Down
16 changes: 11 additions & 5 deletions src/main/kotlin/operations/AddOperation.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,27 @@ import Configuration
import PlcMemory
import Add
import EnvironmentVariables
import org.slf4j.LoggerFactory
import java.util.concurrent.CancellationException
import toBooleanFromBinary

class AddOperation(private val configuration: Configuration,private val memory: PlcMemory, environmentVariables: EnvironmentVariables
) : BaseOperation(environmentVariables, configuration) {

companion object {
val logger = LoggerFactory.getLogger("AddOperation")
}

fun addOperation(element: Add){
println("Add symbol ${element.symbol} value ${element.value}")
logger.info("Add symbol ${element.symbol} value ${element.value}")
var value = processValue(element.value)
var variable = configuration.registers.getVarConfiguration(element.symbol)
if (variable == null) {
println("ERROR: Symbol ${element.symbol} not found during Set execution")
logger.error("Symbol ${element.symbol} not found during Set execution")
throw CancellationException("Error - Add")
} else {
if(variable.addressType == AddressType.COIL || variable.addressType == AddressType.DISCRETE_INPUT){
println("ERROR: Symbol ${element.symbol} is of type COIL or DISCRETE_INPUT which is not support by Add operation")
logger.error("Symbol ${element.symbol} is of type COIL or DISCRETE_INPUT which is not support by Add operation")
throw CancellationException("Error - Add")
}

Expand All @@ -32,7 +38,7 @@ class AddOperation(private val configuration: Configuration,private val memory:
if (variable.datatype == "FLOAT32") {
var currentValue = memory.readHoldingRegister(variable.address.toInt(), 2)
if(currentValue.isEmpty()){
println("ERROR: Add Operation - Unable to get value of ${element.symbol} address ${variable.address} ")
logger.error("Add Operation - Unable to get value of ${element.symbol} address ${variable.address} ")
throw CancellationException("Error - Add")
}
val intValue = (( currentValue[1].toInt() shl 16) or (currentValue[0].toInt() and 0xFFFF))
Expand All @@ -43,7 +49,7 @@ class AddOperation(private val configuration: Configuration,private val memory:
} else {
var currentValue = memory.readHoldingRegister(variable.address.toInt(), 1)
if(currentValue.isEmpty()){
println("ERROR: Add Operation - Unable to get value of ${element.symbol} address ${variable.address} ")
logger.error("Add Operation - Unable to get value of ${element.symbol} address ${variable.address} ")
throw CancellationException("Error - Add")
}
var intValue = value.toInt()
Expand Down
7 changes: 6 additions & 1 deletion src/main/kotlin/operations/CsvOperation.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Csv
import PlcMemory
import org.apache.commons.csv.CSVFormat
import org.apache.commons.csv.CSVParser
import org.slf4j.LoggerFactory
import java.io.FileReader
import java.nio.file.Paths
import java.util.concurrent.CancellationException
Expand All @@ -13,6 +14,9 @@ data class CsvOperationInfo(var position: Int, var csvColumn: List<String>)
class CsvOperation {
private var csvVariables: MutableMap<String, CsvOperationInfo> = mutableMapOf<String, CsvOperationInfo>()

companion object {
val logger = LoggerFactory.getLogger("CsvOperation")
}
@Throws(InternalError::class)
private fun parseCsv(csvFileName: String, column: Int) : List<String> {
val columnValues = mutableListOf<String>()
Expand Down Expand Up @@ -50,9 +54,10 @@ class CsvOperation {
}
fun process(element: Csv, configuration: Configuration, memory: PlcMemory) {
var nextValue = getNextValue(element)
AddOperation.logger.info("Csv symbol ${element.symbol} value $nextValue")
var variable = configuration.registers.getVarConfiguration(element.symbol)
if (variable == null) {
println("ERROR: Symbol ${element.symbol} not found during CSV execution")
logger.error("Symbol ${element.symbol} not found during CSV execution")
throw CancellationException("Error - CSV")
} else {
when (variable.addressType) {
Expand Down
10 changes: 8 additions & 2 deletions src/main/kotlin/operations/LinearOperation.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@ package operations
import Configuration
import PlcMemory
import Linear
import org.slf4j.LoggerFactory
import java.util.concurrent.CancellationException

class LinearOperation {
private var linearVariables: MutableMap<String, Double> = mutableMapOf<String, Double>()

companion object {
val logger = LoggerFactory.getLogger("LinearOperation")
}

private fun getNextValue(linear: Linear): String {
var x =0.0
if(linear.endX > linear.startX) {
Expand Down Expand Up @@ -36,13 +41,14 @@ class LinearOperation {

fun process(element: Linear, configuration: Configuration, memory: PlcMemory) {
var nextValue = getNextValue(element)
logger.info("Linear symbol ${element.symbol} value $nextValue")
var variable = configuration.registers.getVarConfiguration(element.symbol)
if (variable == null) {
println("ERROR: Symbol ${element.symbol} not found during Linear execution")
logger.error("Symbol ${element.symbol} not found during Linear execution")
throw CancellationException("Error - Linear")
} else {
if (variable.addressType == AddressType.COIL || variable.addressType == AddressType.DISCRETE_INPUT) {
println("ERROR: Symbol ${element.symbol} is of type COIL or DISCRETE_INPUT which is not support by Linear operation")
logger.error("Symbol ${element.symbol} is of type COIL or DISCRETE_INPUT which is not support by Linear operation")
throw CancellationException("Error - Linear")
}

Expand Down
Loading

0 comments on commit c4d4037

Please sign in to comment.