185 lines
6.5 KiB
Python
185 lines
6.5 KiB
Python
|
import socket
|
|||
|
import threading
|
|||
|
import time
|
|||
|
#ping 192.168.0.105 -t
|
|||
|
class Modbus:
|
|||
|
def __init__(self, dev_logger=None):
|
|||
|
self.dev_logger = dev_logger
|
|||
|
|
|||
|
self.server_ip = '192.168.0.105'
|
|||
|
self.server_port = 10001
|
|||
|
self.time_delay = 0.03
|
|||
|
self.io_state = [0x00]
|
|||
|
|
|||
|
# write 8 byte data
|
|||
|
self.com1_Status = False
|
|||
|
self.com2_Status = False
|
|||
|
self.com3_Status = False
|
|||
|
self.com4_Status = False
|
|||
|
self.com2andcom3_Status = False
|
|||
|
|
|||
|
self.modbus_reconnect_time = 0#設定IO卡閒置重新連線時間
|
|||
|
|
|||
|
# 在初始化中进行连接
|
|||
|
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|||
|
server_full_addr = (self.server_ip, self.server_port)
|
|||
|
try:
|
|||
|
self.sock.connect(server_full_addr)
|
|||
|
self.Modbus_isOpen = True
|
|||
|
self.CloseModbus = False
|
|||
|
|
|||
|
threading.Thread(target=self.reconnect_periodically, args=(900,)).start()
|
|||
|
self.dev_logger.info('IO卡連線成功')
|
|||
|
except:
|
|||
|
print('IO卡連線失敗')
|
|||
|
self.dev_logger.error('IO卡連線失敗')
|
|||
|
self.Modbus_isOpen = False
|
|||
|
|
|||
|
print("Connected to the server successfully.")
|
|||
|
self.com_all_off()
|
|||
|
|
|||
|
# Function to convert bytes to a hexadecimal string
|
|||
|
def byte_to_hex_str(self, byte_array, length):
|
|||
|
return ' '.join(['{:02X}'.format(b) for b in byte_array[:length]])
|
|||
|
def close_connection(self):
|
|||
|
self.sock.close()
|
|||
|
|
|||
|
def reconnect_periodically(self, interval):
|
|||
|
self.dev_logger.info('IO reconnect_periodically Start')
|
|||
|
while True:
|
|||
|
for i in range(0, interval):
|
|||
|
time.sleep(1) # 等待一段时间
|
|||
|
if self.CloseModbus:
|
|||
|
break
|
|||
|
if self.CloseModbus:
|
|||
|
break
|
|||
|
self.Modbus_isOpen = False
|
|||
|
time.sleep(10) # 等待當前計算結束
|
|||
|
self.close_connection() # 关闭连接
|
|||
|
time.sleep(3) # 可选的延迟,确保连接关闭
|
|||
|
try:
|
|||
|
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|||
|
server_full_addr = (self.server_ip, self.server_port)
|
|||
|
self.sock.connect(server_full_addr)
|
|||
|
self.Modbus_isOpen = True
|
|||
|
print("Reconnected to the server.")
|
|||
|
self.dev_logger.info('IO Reconnected to the server')
|
|||
|
|
|||
|
except Exception as e:
|
|||
|
print('Failed to reconnect:', str(e))
|
|||
|
self.Modbus_isOpen = False
|
|||
|
self.dev_logger.error(f'Failed to reconnect: {str(e)}')
|
|||
|
self.dev_logger.info('IO reconnect_periodically End')
|
|||
|
|
|||
|
|
|||
|
def control_com(self):
|
|||
|
try:
|
|||
|
self.modbus_reconnect_time = 0#有對IO進行通訊,把重新連線計時器歸0
|
|||
|
# Build the message for the 8-channel open command
|
|||
|
byte_message = bytearray()
|
|||
|
# TID - Transfer Identifier
|
|||
|
byte_message.extend([0x00, 0x00])
|
|||
|
# PID - Protocol Identifier (default is 0)
|
|||
|
byte_message.extend([0x00, 0x00])
|
|||
|
# Number of bytes to follow (0x08)
|
|||
|
byte_message.extend([0x00, 0x08])
|
|||
|
# UID - Modbus module address
|
|||
|
byte_message.extend([0x01])
|
|||
|
# MODBUS command number (0x0f for writing multiple discrete outputs)
|
|||
|
byte_message.extend([0x0f])
|
|||
|
# Start address for writing (Y1 address is 0x0000)
|
|||
|
byte_message.extend([0x00, 0x00])
|
|||
|
# Number of outputs to operate (8)
|
|||
|
byte_message.extend([0x00, 0x08])
|
|||
|
# Number of bytes following (0x01)
|
|||
|
byte_message.extend([0x01])
|
|||
|
# Data for the 8 channels
|
|||
|
byte_message.extend(self.io_state * 8)
|
|||
|
# Send the message
|
|||
|
self.sock.send(byte_message)
|
|||
|
# Receive data
|
|||
|
# message_rcv = self.sock.recv(1024)
|
|||
|
# Display received data as a hexadecimal string
|
|||
|
# print("Received data: ", self.byte_to_hex_str(message_rcv, len(message_rcv)))
|
|||
|
time.sleep(self.time_delay)
|
|||
|
except Exception as ee:
|
|||
|
print("Failed to connect to the server:", str(ee))
|
|||
|
self.dev_logger.error(f'Failed to connect to the server: {str(ee)}')
|
|||
|
|
|||
|
# finally:
|
|||
|
# time.sleep(self.time_delay)
|
|||
|
# self.sock.close()
|
|||
|
def com_all_on(self):
|
|||
|
# print(self.io_state)
|
|||
|
self.io_state = [16]
|
|||
|
# print(self.io_state)
|
|||
|
self.control_com()
|
|||
|
def com_all_off(self):
|
|||
|
# print(self.io_state)
|
|||
|
self.io_state = [0]
|
|||
|
# print(self.io_state)
|
|||
|
self.control_com()
|
|||
|
def com1_on(self):
|
|||
|
# print(self.io_state)
|
|||
|
self.io_state = [a + 0x01 for a in self.io_state]
|
|||
|
# print(self.io_state)
|
|||
|
self.control_com()
|
|||
|
def com2_on(self):
|
|||
|
# print(self.io_state)
|
|||
|
self.io_state = [a + 0x02 for a in self.io_state]
|
|||
|
# print(self.io_state)
|
|||
|
self.control_com()
|
|||
|
def com2andcom3_on(self):
|
|||
|
# print(self.io_state)
|
|||
|
self.io_state = [a + 0x06 for a in self.io_state]
|
|||
|
print(self.io_state)
|
|||
|
self.control_com()
|
|||
|
def com3_on(self):
|
|||
|
# print(self.io_state)
|
|||
|
self.io_state = [a + 0x04 for a in self.io_state]
|
|||
|
# print(self.io_state)
|
|||
|
self.control_com()
|
|||
|
def com4_on(self):
|
|||
|
# print(self.io_state)
|
|||
|
self.io_state = [a + 0x08 for a in self.io_state]
|
|||
|
# print(self.io_state)
|
|||
|
self.control_com()
|
|||
|
def com1_off(self):
|
|||
|
# print(self.io_state)
|
|||
|
self.io_state = [a - 0x01 for a in self.io_state]
|
|||
|
# print(self.io_state)
|
|||
|
self.control_com()
|
|||
|
def com2_off(self):
|
|||
|
# print(self.io_state)
|
|||
|
self.io_state = [a - 0x02 for a in self.io_state]
|
|||
|
# print(self.io_state)
|
|||
|
self.control_com()
|
|||
|
def com2andcom3_off(self):
|
|||
|
# print(self.io_state)
|
|||
|
self.io_state = [a - 0x06 for a in self.io_state]
|
|||
|
# print(self.io_state)
|
|||
|
self.control_com()
|
|||
|
def com3_off(self):
|
|||
|
# print(self.io_state)
|
|||
|
self.io_state = [a - 0x04 for a in self.io_state]
|
|||
|
# print(self.io_state)
|
|||
|
self.control_com()
|
|||
|
def com4_off(self):
|
|||
|
# print(self.io_state)
|
|||
|
self.io_state = [a - 0x08 for a in self.io_state]
|
|||
|
# print(self.io_state)
|
|||
|
self.control_com()
|
|||
|
|
|||
|
if __name__ == '__main__':
|
|||
|
modbus = Modbus()
|
|||
|
modbus.com1_on()
|
|||
|
modbus.com2_on()
|
|||
|
modbus.com3_on()
|
|||
|
modbus.com4_on()
|
|||
|
time.sleep(5)
|
|||
|
modbus.com1_off()
|
|||
|
modbus.com2_off()
|
|||
|
modbus.com3_off()
|
|||
|
modbus.com4_off()
|
|||
|
|