From edc88367e3a9c319e469c9747ed9f7d2ab02ff66 Mon Sep 17 00:00:00 2001 From: papipano Date: Sun, 26 Mar 2023 20:19:35 +0200 Subject: [PATCH 1/9] Update modbusClient.py --- easymodbus/modbusClient.py | 103 +++++++++++++++++++++++++++++++++++-- 1 file changed, 98 insertions(+), 5 deletions(-) diff --git a/easymodbus/modbusClient.py b/easymodbus/modbusClient.py index 059646a..6eedfee 100644 --- a/easymodbus/modbusClient.py +++ b/easymodbus/modbusClient.py @@ -191,7 +191,7 @@ def read_input_registers(self, starting_address, quantity): """ logging.info("Request to read Input Registers (FC04), starting address: {0}, quantity: {1}" .format(str(starting_address), str(quantity))) - return_value = self.read_analogs(starting_address, quantity, FunctionCode.READ_INPUT_REGISTERS) + return_value = self.read_execute_read_order(starting_address, quantity, FunctionCode.READ_INPUT_REGISTERS) logging.info("Response to Input Registers (FC04), values: {0}" .format(str(return_value))) return return_value @@ -562,7 +562,36 @@ def convert_double_to_two_registers(doubleValue, register_order=RegisterOrder.lo return myList -def convert_float_to_two_registers(floatValue, register_order=RegisterOrder.lowHigh): +def convert_quad_to_four_registers(quadValue, register_order=RegisterOrder.lowHigh): + """ + Convert 64 Bit Value to four 16 Bit Value to send as Modbus Registers + quadValue: Value to be converted + register_order: Desired Word Order (Low Register first or High Register first - Default: RegisterOrder.lowHigh + return: 16 Bit Register values int[] + """ + myList = list() + + # Append Least Significant Word + myList.append(int(quadValue & 0x000000000000FFFF)) + # Append a little bit more Significant Word + myList.append(int((quadValue & 0x00000000FFFF0000) >> 16)) + # Append a bit more Significant Word + myList.append(int((quadValue & 0x0000FFFF00000000) >> 32)) + # Append Most Significant Word + myList.append(int((quadValue & 0xFFFF000000000000) >> 48)) + if register_order == RegisterOrder.highLow: + # Append Most Significant Word + myList[0] = (int((quadValue & 0xFFFF000000000000) >> 48)) + # Append a little bit less Significant Word + myList[1] = (int((quadValue & 0x0000FFFF00000000) >> 32)) + # Append a bit less Significant Word + myList[2] = (int((quadValue & 0x00000000FFFF0000) >> 16)) + # Append Least Significant Word + myList[3] = (int(quadValue & 0x000000000000FFFF)) + return myList + + +def convert_float32_to_two_registers(floatValue, register_order=RegisterOrder.lowHigh): """ Convert 32 Bit real Value to two 16 Bit Value to send as Modbus Registers floatValue: Value to be converted @@ -578,9 +607,30 @@ def convert_float_to_two_registers(floatValue, register_order=RegisterOrder.lowH return myList +def convert_float64_to_four_registers(float64Value, register_order=RegisterOrder.lowHigh): + """ + Convert 64 Bit real Value to two 16 Bit Value to send as Modbus Registers + floatValue: Value to be converted + return: 16 Bit Register values int[] + """ + myList = list() + s = bytearray(struct.pack('> 8 + b[2] = (registers[1] & 0xff) + b[3] = (registers[1] & 0xff00) >> 8 + b[4] = (registers[2] & 0xff) + b[5] = (registers[2] & 0xff00) >> 8 + b[6] = (registers[3] & 0xff) + b[7] = (registers[3] & 0xff00) >> 8 + if register_order == RegisterOrder.highLow: + b[6] = registers[0] & 0xff + b[7] = (registers[0] & 0xff00) >> 8 + b[4] = registers[0] & 0xff + b[5] = (registers[0] & 0xff00) >> 8 + b[2] = registers[0] & 0xff + b[3] = (registers[0] & 0xff00) >> 8 + b[0] = (registers[1] & 0xff) + b[1] = (registers[1] & 0xff00) >> 8 + returnValue = struct.unpack(' Date: Sun, 26 Mar 2023 20:44:00 +0200 Subject: [PATCH 2/9] Update modbusClient.py --- easymodbus/modbusClient.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/easymodbus/modbusClient.py b/easymodbus/modbusClient.py index 6eedfee..7021ca7 100644 --- a/easymodbus/modbusClient.py +++ b/easymodbus/modbusClient.py @@ -591,7 +591,7 @@ def convert_quad_to_four_registers(quadValue, register_order=RegisterOrder.lowHi return myList -def convert_float32_to_two_registers(floatValue, register_order=RegisterOrder.lowHigh): +def convert_float_to_two_registers(floatValue, register_order=RegisterOrder.lowHigh): """ Convert 32 Bit real Value to two 16 Bit Value to send as Modbus Registers floatValue: Value to be converted @@ -654,7 +654,7 @@ def convert_registers_to_quad(registers, register_order=RegisterOrder.lowHigh): return returnValue -def convert_registers_to_float32(registers, register_order=RegisterOrder.lowHigh): +def convert_registers_to_float(registers, register_order=RegisterOrder.lowHigh): """ Convert two 16 Bit Registers to 32 Bit real value - Used to receive float values from Modbus (Modbus Registers are 16 Bit long) From 1cbaf76b8eb4f26dbe0ea60395d43fa9dfe94f44 Mon Sep 17 00:00:00 2001 From: papipano Date: Sun, 26 Mar 2023 20:46:38 +0200 Subject: [PATCH 3/9] Update modbusClient.py --- easymodbus/modbusClient.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/easymodbus/modbusClient.py b/easymodbus/modbusClient.py index 7021ca7..4f25129 100644 --- a/easymodbus/modbusClient.py +++ b/easymodbus/modbusClient.py @@ -444,14 +444,14 @@ def baudrate(self, baudrate): @property def parity(self): """ - Gets the of Parity in case of serial connection + Gets the value of Parity in case of serial connection """ return self.__parity @parity.setter def parity(self, parity): """ - Sets the of Parity in case of serial connection + Sets the value of Parity in case of serial connection Example modbusClient.Parity = Parity.even """ self.__parity = parity From 2f09067eb8fa9cc34d8d84f3d0b36f04eb01a321 Mon Sep 17 00:00:00 2001 From: papipano Date: Sun, 26 Mar 2023 20:48:33 +0200 Subject: [PATCH 4/9] First commit --- easymodbus/modbusClient.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easymodbus/modbusClient.py b/easymodbus/modbusClient.py index 4f25129..2570dcd 100644 --- a/easymodbus/modbusClient.py +++ b/easymodbus/modbusClient.py @@ -191,7 +191,7 @@ def read_input_registers(self, starting_address, quantity): """ logging.info("Request to read Input Registers (FC04), starting address: {0}, quantity: {1}" .format(str(starting_address), str(quantity))) - return_value = self.read_execute_read_order(starting_address, quantity, FunctionCode.READ_INPUT_REGISTERS) + return_value = self.execute_read_order(starting_address, quantity, FunctionCode.READ_INPUT_REGISTERS) logging.info("Response to Input Registers (FC04), values: {0}" .format(str(return_value))) return return_value From 4d6c34a16e4eb12f127513971f907a0f5a134a7d Mon Sep 17 00:00:00 2001 From: papipano Date: Sun, 26 Mar 2023 20:53:13 +0200 Subject: [PATCH 5/9] First commit --- easymodbus/modbus_protocol.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/easymodbus/modbus_protocol.py b/easymodbus/modbus_protocol.py index c832f39..058af8b 100644 --- a/easymodbus/modbus_protocol.py +++ b/easymodbus/modbus_protocol.py @@ -96,7 +96,7 @@ def decode(self, data): if exception_code == 1: raise Exceptions.function_codeNotSupportedException("Function code not supported by master") elif exception_code == 2: - raise Exceptions.starting_addressInvalidException( + raise Exceptions.starting_AddressInvalidException( "Starting address invalid or starting address + quantity invalid") elif exception_code == 3: raise Exceptions.QuantityInvalidException("quantity invalid") @@ -158,4 +158,4 @@ def __calculateCRC(self, data, numberOfBytes, startByte): crc = crc ^ 0xA001 else: crc = crc >> 1 - return crc \ No newline at end of file + return crc From 97ed3f7ea262019475a9909b82bcb91e1c0eca1e Mon Sep 17 00:00:00 2001 From: papipano Date: Sun, 26 Mar 2023 20:56:59 +0200 Subject: [PATCH 6/9] Changed exception call in decode function from Exceptions.starting_addressInvalidException to Exceptions.StartingAddressInvalidException --- easymodbus/modbus_protocol.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easymodbus/modbus_protocol.py b/easymodbus/modbus_protocol.py index 058af8b..2ed5b7a 100644 --- a/easymodbus/modbus_protocol.py +++ b/easymodbus/modbus_protocol.py @@ -96,7 +96,7 @@ def decode(self, data): if exception_code == 1: raise Exceptions.function_codeNotSupportedException("Function code not supported by master") elif exception_code == 2: - raise Exceptions.starting_AddressInvalidException( + raise Exceptions.StartingAddressInvalidException( "Starting address invalid or starting address + quantity invalid") elif exception_code == 3: raise Exceptions.QuantityInvalidException("quantity invalid") From 0ed0c34b1b08cf967c61ba6e82decdf9c8e00c60 Mon Sep 17 00:00:00 2001 From: papipano Date: Sun, 26 Mar 2023 21:04:04 +0200 Subject: [PATCH 7/9] Added module name in import statement --- easymodbus/run.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/easymodbus/run.py b/easymodbus/run.py index 9d5dfa2..b113a03 100644 --- a/easymodbus/run.py +++ b/easymodbus/run.py @@ -6,7 +6,7 @@ ''' # @UnresolvedImport -from modbusClient import * +from easymodbus.modbusClient import * # @UnresolvedImport modbusClient = ModbusClient('127.0.0.1', 502) @@ -30,4 +30,4 @@ modbusClient.write_single_register(0, 777) modbusClient.write_multiple_coils(0, [True,True,True,True,True,False,True,True]) modbusClient.write_multiple_registers(0, convert_float_to_two_registers(3.141517)) -modbusClient.close() \ No newline at end of file +modbusClient.close() From 7dd2eb0ea4db5421bb305273605af7706a9fa74f Mon Sep 17 00:00:00 2001 From: papipano Date: Sun, 26 Mar 2023 22:05:42 +0200 Subject: [PATCH 8/9] Shorten the comment lines longest than 80 chars --- easymodbus/modbus_protocol.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/easymodbus/modbus_protocol.py b/easymodbus/modbus_protocol.py index 2ed5b7a..64f6999 100644 --- a/easymodbus/modbus_protocol.py +++ b/easymodbus/modbus_protocol.py @@ -78,7 +78,8 @@ def decode(self, data: bytearray): @dataclass class PDU: """ - Dataclass which represents the PDU (Protocol Data Unit) - Both for Modbus RTU and Modbus TCP + Dataclass which represents the PDU (Protocol Data Unit) + - Both for Modbus RTU and Modbus TCP function_code(1 Byte): Service specified by the Function code """ function_code: FunctionCode = FunctionCode.READ_COILS @@ -108,7 +109,8 @@ def decode(self, data): @dataclass class ADU: """ - Dataclass which represents the ADU (Application Data Unit) - Both for Modbus RTU and Modbus TCP + Dataclass which represents the ADU (Application Data Unit) + - Both for Modbus RTU and Modbus TCP mbap_header: only relevant for Modbus TCP pdu: both for Modbus TCP and RTU crc: Error check only relevant for Modbus RTU From bbc57dd8d90333c5ed6e2c837e01fb31b21b6131 Mon Sep 17 00:00:00 2001 From: papipano Date: Mon, 27 Mar 2023 09:52:16 +0200 Subject: [PATCH 9/9] Added description of 4 words register --- README.md | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4725edd..7374ad0 100644 --- a/README.md +++ b/README.md @@ -355,6 +355,13 @@ doubleValue: Value to be converted register_order: Desired Word Order (Low Register first or High Register first - Default: RegisterOrder.lowHigh return: 16 Bit Register values int[] +**def convert_quad_to_four_registers(quadValue, register_order=RegisterOrder.lowHigh): + +Convert 64 Bit Value to four 16 Bit Value to send as Modbus Registers +quadValue: Value to be converted +register_order: Desired Word Order (Low Register first or High Register first - Default: RegisterOrder.lowHigh +return: 16 Bit Register values int[] + **def convert_float_to_two_registers(floatValue, register_order=RegisterOrder.lowHigh)** Convert 32 Bit real Value to two 16 Bit Value to send as Modbus Registers @@ -362,6 +369,12 @@ floatValue: Value to be converted register_order: Desired Word Order (Low Register first or High Register first - Default: RegisterOrder.lowHigh return: 16 Bit Register values int[] +**def convert_float64_to_four_registers(float64Value, register_order=RegisterOrder.lowHigh): + +Convert 64 Bit real Value to two 16 Bit Value to send as Modbus Registers +floatValue: Value to be converted +return: 16 Bit Register values int[] + **def convert_registers_to_double(registers, register_order=RegisterOrder.lowHigh)** Convert two 16 Bit Registers to 32 Bit long value - Used to receive 32 Bit values from Modbus (Modbus Registers are 16 Bit long) @@ -369,9 +382,21 @@ registers: 16 Bit Registers register_order: Desired Word Order (Low Register first or High Register first - Default: RegisterOrder.lowHigh return: 32 bit value +def convert_registers_to_quad(registers, register_order=RegisterOrder.lowHigh): + +Convert four 16 Bit Registers to 64 Bit long value - Used to receive 64Bit values from Modbus (Modbus Registers are 16 Bit long) +registers: 16 Bit Registers +return: 64 bit value + **def convert_registers_to_float(registers, register_order=RegisterOrder.lowHigh)** Convert two 16 Bit Registers to 32 Bit real value - Used to receive float values from Modbus (Modbus Registers are 16 Bit long) registers: 16 Bit Registers register_order: Desired Word Order (Low Register first or High Register first - Default: RegisterOrder.lowHigh -return: 32 bit value real \ No newline at end of file +return: 32 bit value real + +**def convert_registers_to_float64(registers, register_order=RegisterOrder.lowHigh): + +Convert two 16 Bit Registers to 64 Bit real value - Used to receive float values from Modbus (Modbus Registers are 16 Bit long) +registers: 16 Bit Registers +return: 64 bit value real