You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

133 lines
4.5 KiB
Python

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import modbus_tk
import modbus_tk.defines as cst
from modbus_tk import modbus_tcp, hooks
from modbus_tk.exceptions import *
import serial
import struct
from .ByteOrder import *
from .SetMessage import *
# PORT = 'COM3'
#PORT = '/dev/ptyp5'
class TCPSlave():
def __init__(self, address = '127.0.0.1', port = 502):
try:
self.server = modbus_tcp.TcpServer(address=address, port=port)
self.server.start()
print(f"TCP Slave started on {address}:{port}")
except Exception as e:
print(f"Failed to start TCP Slave on {address}:{port}: {e}")
raise e
# hooks.install_hook('modbus.Server.before_handle_request', afterRecv)
# hooks.install_hook("modbus.Server.after_handle_request", afterSend)
# 创建从站
# 添加存储区
# supported block types
# COILS = 1
# DISCRETE_INPUTS = 2
# HOLDING_REGISTERS = 3
# ANALOG_INPUTS = 4
def addSlave(self, slaveId):
try:
self.server.add_slave(slaveId)
slave = self.server.get_slave(slaveId)
# 添加存储区 - 使用正确的地址范围
slave.add_block('0', cst.COILS, 0, 9999) # 线圈 0-9999
slave.add_block('1', cst.DISCRETE_INPUTS, 10000, 19999) # 离散输入 10000-19999
slave.add_block('3', cst.ANALOG_INPUTS, 30000, 39999) # 输入寄存器 30000-39999
slave.add_block('4', cst.HOLDING_REGISTERS, 40000, 49999) # 保持寄存器 40000-49999
print(f"Added slave {slaveId} with storage blocks")
return True
except Exception as e:
print(f"Failed to add slave {slaveId}: {e}")
return False
def setValue(self, slaveId, name, address, value, order='ABCD'):
try:
slave = self.server.get_slave(slaveId)
if '.' not in str(value) and order == 'int':
# 整数值处理
intValue = int(value)
slave.set_values(name, address, intValue)
else:
# 浮点数处理或者order != 'int'时的浮点数转换)
if '.' not in str(value):
floatValue = int(value)
else:
floatValue = float(value)
if order == 'ABCD': # 大端模式
valueByte = floatToABCD(floatValue)
elif order == 'DCBA': # 小端模式
valueByte = floatToDCBA(floatValue)
elif order == 'BADC':
valueByte = floatToBADC(floatValue)
elif order == 'CDAB':
valueByte = floatToCDAB(floatValue)
else:
valueByte = floatToABCD(floatValue)
slave.set_values(name, address, valueByte)
return True
except Exception as e:
print(f"TCP Slave setValue error: {e}")
print(f"Error details - slaveId: {slaveId}, name: {name}, address: {address}, value: {value}")
return False
def readValue(self, slaveId, name, address, order = 'int'):
try:
try:
slave = self.server.get_slave(slaveId)
except Exception as e:
if type(e) == MissingKeyError:
self.addSlave(slaveId)
if order == 'int':
value = slave.get_values(name, address, 1)[0]
else:
value = slave.get_values(name, address, 2)
if order == 'ABCD': # 大端模式
value = ABCDToFloat(value)
elif order == 'DCBA': # 小端模式
value = DCBAToFloat(value)
elif order == 'BADC':
value = BADCToFloat(value)
elif order == 'CDAB':
value = CDABToFloat(value)
return value
except Exception as e:
return 'error'
if __name__ == "__main__":
a = TCPSlave()
a.addSlave(1)
a.setValue(1, '0', 0, 1)
a.readValue(1, '0', 0)
a.setValue(1, '1', 10000, 1)
a.readValue(1, '1', 10000)
a.setValue(1, '3', 30000, 2)
a.readValue(1, '3', 30000)
a.setValue(1, '3', 30002, 2.5121231)
a.readValue(1, '3', 30002, order ='ABCD')
a.setValue(1, '4', 40000, 3)
a.readValue(1, '4', 40000)
a.setValue(1, '4', 40002, 3.51231234564)
a.readValue(1, '4', 40002, order ='ABCD')