这是使用PyQT5作为UI的首次提交,将后端和UI合并到1个工程中,统一使用了Python,没有使用JS和HTML
This commit is contained in:
474
bk/plc_comm.py
Normal file
474
bk/plc_comm.py
Normal file
@@ -0,0 +1,474 @@
|
||||
import array
|
||||
import time
|
||||
import serial
|
||||
import threading
|
||||
import binascii
|
||||
import datetime
|
||||
import struct
|
||||
import requests
|
||||
from queue import Queue
|
||||
|
||||
print_condition = False
|
||||
all_plc_recv = 0
|
||||
# 定义颜色代码
|
||||
RED = '\033[31m'
|
||||
GREEN = '\033[32m'
|
||||
YELLOW = '\033[33m'
|
||||
BLUE = '\033[34m'
|
||||
MAGENTA = '\033[35m'
|
||||
CYAN = '\033[36m'
|
||||
WHITE = '\033[37m'
|
||||
RESET = '\033[m'
|
||||
|
||||
|
||||
def bcd_coder_array(value=0, lenght=4):
|
||||
return int_to_bcd(value, lenght)
|
||||
|
||||
|
||||
def int_to_bcd(number=0, length=5):
|
||||
bcd_array = []
|
||||
try:
|
||||
int_number = int(round(number)) # 使用round函数四舍五入,然后转成整数
|
||||
while int_number > 0:
|
||||
bcd = int_number % 100
|
||||
bcd_array.insert(0, (bcd // 10) << 4 | (bcd % 10))
|
||||
int_number = int_number // 100
|
||||
except:
|
||||
pass
|
||||
|
||||
while len(bcd_array) < length:
|
||||
bcd_array.insert(0, 0)
|
||||
|
||||
return bcd_array
|
||||
|
||||
|
||||
def int_to_ascii_array(number, length):
|
||||
# 将整数转换为ASCII码字符串
|
||||
ascii_str = str(number)
|
||||
# 获取ASCII码字符串的长度
|
||||
ascii_str_length = len(ascii_str)
|
||||
# 如果ASCII码字符串的长度小于指定长度,则在前面补0
|
||||
if ascii_str_length < length:
|
||||
ascii_str = '0' * (length - ascii_str_length) + ascii_str
|
||||
# 将ASCII码字符串转换为ASCII码数组
|
||||
ascii_array = [ord(c) for c in ascii_str]
|
||||
return ascii_array
|
||||
|
||||
|
||||
def str_to_ascii_array(str, length):
|
||||
# 获取ASCII码字符串的长度
|
||||
ascii_str_length = len(str)
|
||||
# 如果ASCII码字符串的长度小于指定长度,则在前面补0
|
||||
if ascii_str_length < length:
|
||||
ascii_str = '0' * (length - ascii_str_length) + str
|
||||
# 将ASCII码字符串转换为ASCII码数组
|
||||
ascii_array = [ord(c) for c in str]
|
||||
return ascii_array
|
||||
|
||||
|
||||
def hex_to_ascii_arr(hex_num, lenth):
|
||||
str_num = hex(hex_num)[2:].upper().rjust(lenth, '0')
|
||||
array = [ord(c) for c in str_num]
|
||||
return array
|
||||
|
||||
|
||||
def convert_ascii_to_num(ascii_val):
|
||||
if ord('0') <= ascii_val <= ord('9'):
|
||||
return ascii_val - ord('0')
|
||||
elif ord('A') <= ascii_val <= ord('F'):
|
||||
return ascii_val - ord('A') + 10
|
||||
elif ord('a') <= ascii_val <= ord('f'):
|
||||
return ascii_val - ord('a') + 10
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
def ascii_array_to_word(ascii_array):
|
||||
if len(ascii_array) != 4:
|
||||
return 0
|
||||
return convert_ascii_to_num(ascii_array[0]) * 0x1000 + \
|
||||
convert_ascii_to_num(ascii_array[1]) * 0x0100 + \
|
||||
convert_ascii_to_num(ascii_array[2]) * 0x010 + \
|
||||
convert_ascii_to_num(ascii_array[3])
|
||||
|
||||
|
||||
def date_to_bcd(date_str): # 0:06:20.585233
|
||||
# condition_print("date=",date_str,type(date_str))
|
||||
# 移除日期中的"-"字符
|
||||
date_str = date_str.replace("-", "")
|
||||
# 按照两位数字进行分割
|
||||
date_parts = [date_str[i:i + 2] for i in range(0, len(date_str), 2)]
|
||||
# 将每个部分转换为十六进制数
|
||||
bcd_array = [int(part, 16) for part in date_parts]
|
||||
return bcd_array
|
||||
|
||||
|
||||
def time_to_bcd(time_str): # 10:06:20.585233
|
||||
time_str = time_str.split('.')[0] # 去除掉后面的毫秒
|
||||
time_parts = time_str.split(':') # 按":"分割
|
||||
bcd = [int(part) for part in time_parts] # 分别转为整数
|
||||
bcd = [int(str(i), 16) for i in bcd] # 分别转为16进制
|
||||
return bcd
|
||||
|
||||
|
||||
def condition_print(*args, **kwargs):
|
||||
global print_condition # 使用全局变量
|
||||
message = ' '.join(str(arg) for arg in args)
|
||||
if kwargs:
|
||||
message += ', ' + ', '.join("{}={}".format(key, value) for key, value in kwargs.items())
|
||||
|
||||
if print_condition:
|
||||
print(message)
|
||||
|
||||
|
||||
class DevicePLC:
|
||||
def __init__(self, plc_port, comm_config):
|
||||
global print_condition, api_condition, all_plc_recv
|
||||
port_opened = False
|
||||
print("DevicePLC init")
|
||||
self.event_format_long = False
|
||||
|
||||
try:
|
||||
self.ser = serial.Serial(port=plc_port,
|
||||
baudrate=comm_config['baudrate'],
|
||||
parity=comm_config['parity'],
|
||||
bytesize=comm_config['bytesize'],
|
||||
stopbits=comm_config['stopbits'],
|
||||
timeout=1, rtscts=False)
|
||||
except:
|
||||
condition_print("\033[91m {}\033[00m".format("plc " + plc_port + " open error"))
|
||||
try:
|
||||
self.ser = serial.Serial(port="com1", baudrate=baudrate, parity=serial.PARITY_EVEN,
|
||||
bytesize=serial.EIGHTBITS,
|
||||
stopbits=serial.STOPBITS_ONE,
|
||||
timeout=2, rtscts=False)
|
||||
except:
|
||||
condition_print("\033[91m {}\033[00m".format("plc " + "com1" + " open error"))
|
||||
else:
|
||||
port_opened = True
|
||||
condition_print("\033[92m {}\033[00m".format("plc " + "com1" + " open success"))
|
||||
else:
|
||||
port_opened = True
|
||||
condition_print("\033[92m {}\033[00m".format("plc " + plc_port + " open success--1"))
|
||||
finally:
|
||||
pass
|
||||
|
||||
if port_opened:
|
||||
self.link_down_timer = threading.Timer(5.0, self.link_down_timeout) # 创建一个5秒后执行的定时器
|
||||
# self.link_down_timer.start()
|
||||
self.link_down_event = threading.Event()
|
||||
|
||||
if self.port_is_opened():
|
||||
# self.recv_thread.start();
|
||||
pass
|
||||
|
||||
def port_is_opened(self):
|
||||
if hasattr(self, 'ser') and self.ser:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
return False
|
||||
|
||||
def link_down_timeout(self):
|
||||
self.link_down_event.set()
|
||||
self.link_down_timer = threading.Timer(5.0, self.link_down_timeout) # 创建一个5秒后执行的定时器
|
||||
self.link_down_timer.start()
|
||||
|
||||
def reset_link_down_timer(self):
|
||||
if self.link_down_timer:
|
||||
self.link_down_timer.cancel()
|
||||
self.link_down_timer = threading.Timer(5.0, self.link_down_timeout) # 创建一个5秒后执行的定时器
|
||||
self.link_down_timer.start()
|
||||
|
||||
def send_heartBit(self):
|
||||
if self.port_is_opened():
|
||||
pass
|
||||
|
||||
def crc16_ccitt(self, data: bytearray): # CRC16/CCITT
|
||||
crcval = 0x0000
|
||||
for c in data:
|
||||
q = (crcval ^ c) & 0x0F
|
||||
crcval = (crcval >> 4) ^ (q * 0o10201)
|
||||
q = (crcval ^ (c >> 4)) & 0x0F
|
||||
crcval = (crcval >> 4) ^ (q * 0o10201)
|
||||
return crcval
|
||||
|
||||
def plc_read_frame(self, command, plc_no=0x01, pc_no=0xFF, address='D0160', len=0x02):
|
||||
frame = []
|
||||
frame.append(0x05)
|
||||
frame.extend(hex_to_ascii_arr(plc_no, 2))
|
||||
frame.extend(hex_to_ascii_arr(pc_no, 2))
|
||||
frame.extend([ord(c) for c in command]) # word read command
|
||||
frame.append(0x30)
|
||||
frame.extend(str_to_ascii_array(address, 5)) # eg.D0160
|
||||
frame.extend(int_to_ascii_array(len, 2))
|
||||
checksum = sum(frame[1:]) & 0xFF
|
||||
frame.extend(hex_to_ascii_arr(checksum, 2))
|
||||
# condition_print("frame=",frame,type(frame))
|
||||
condition_print('frame intent to read plc: [', ', '.join('{:02x}'.format(x) for x in frame), ']')
|
||||
return frame
|
||||
|
||||
def plc_write_frame(self, command, plc_no=0x01, pc_no=0xFF, address='D0160', date_len=0x02, data=[]):
|
||||
frame = [0x05]
|
||||
frame.extend(hex_to_ascii_arr(plc_no, 2))
|
||||
frame.extend(hex_to_ascii_arr(pc_no, 2))
|
||||
frame.extend([ord(c) for c in command]) # word write command bit write command
|
||||
frame.append(0x30)
|
||||
frame.extend(str_to_ascii_array(address, 5)) # eg.D0160
|
||||
frame.extend(int_to_ascii_array(date_len, 2))
|
||||
data_index = 0
|
||||
while date_len > 0:
|
||||
value = data[data_index]
|
||||
data_index = data_index + 1
|
||||
if command == 'BW':
|
||||
arr_len = 1
|
||||
else:
|
||||
arr_len = 4
|
||||
word_ascii_array = hex_to_ascii_arr(value, arr_len)
|
||||
# condition_print(word,'[', ', '.join('{:02x}'.format(x) for x in word_ascii_array), ']')
|
||||
frame.extend(word_ascii_array)
|
||||
date_len = date_len - 1
|
||||
checksum = sum(frame[1:]) & 0xFF
|
||||
frame.extend(hex_to_ascii_arr(checksum, 2))
|
||||
condition_print('frame intend to write plc: [', ', '.join('{:02x}'.format(x) for x in frame), ']')
|
||||
return frame
|
||||
|
||||
# Symbol name Description Code (hexadecimal)
|
||||
# STX Start of Text 02H
|
||||
# ETX End of Text 03H
|
||||
# EOT End of Transmission 04H
|
||||
# ENQ Enquiry 05H
|
||||
# ACK Acknowledge 06H
|
||||
# LF Line Feed 0AH
|
||||
# CL Clear 0CH
|
||||
# CR Carriage Return ODH
|
||||
# NAK Negative Acknowledge 15H
|
||||
def frame_is_valid(self, frame):
|
||||
# 检查第一个字节是否为控制代码
|
||||
control_code = frame[0]
|
||||
ETX: bool = False
|
||||
if control_code not in [0x05, 0x02, 0x03, 0x4, 0x06, 0x15]:
|
||||
condition_print("First byte is not a control code.")
|
||||
return False
|
||||
# 检查最后两个字节是否为校验和代码
|
||||
hex_string = ''.join(chr(char) for char in frame[-2:])
|
||||
# 然后,你可以使用int函数将这个16进制的字符串转换为一个整数,指定基数为16
|
||||
checksum = int(hex_string, 16)
|
||||
if frame[0] == 0x02 and frame[-3] != 0x03:
|
||||
return False
|
||||
if frame[0] == 0x06 or frame[0] == 0x15:
|
||||
return True
|
||||
if frame[-3] == 0x03:
|
||||
ETX = True
|
||||
end_position = -3 if ETX else -2
|
||||
checksum_calc = sum(frame[1:-2]) & 0xFF # 计算校验和并取第八位
|
||||
if checksum != checksum_calc:
|
||||
condition_print("Last two bytes do not match checksum.", checksum, checksum_calc, frame[-2] - 0x30, frame[-1] - 0x30)
|
||||
return False
|
||||
# 创建一个包含所有有效字符的字符串
|
||||
valid_chars = '0123456789abcdefABCDEF'
|
||||
|
||||
# 定义一个函数来检查bytes对象中的每个元素
|
||||
for i in frame[1:end_position]:
|
||||
char = chr(i)
|
||||
if char not in valid_chars:
|
||||
condition_print(f'{char} ({i}) is not a valid character.')
|
||||
# 在此处添加其他的逻辑处理代码,例如抛出异常
|
||||
# raise ValueError(f'{char} ({i}) is not a valid character.')
|
||||
return False
|
||||
else:
|
||||
# condition_print(f'{char} ({i}) is a valid character.')
|
||||
pass
|
||||
return True
|
||||
def plc_write(self, command='WW', plc_no=0x01, pc_no=0xFF, address='D0160', len=0x02, data=0x00000000):
|
||||
frame = self.plc_write_frame(command, plc_no, pc_no, address, len, data)
|
||||
timeout = 2 # 设置超时时间为2秒
|
||||
|
||||
if hasattr(self, 'ser') and self.ser:
|
||||
self.ser.write(frame)
|
||||
frame = self.ser.read(1);
|
||||
time.sleep(0.06)
|
||||
start_time = time.time() # 记录开始时间
|
||||
while self.ser.in_waiting:
|
||||
# 检查是否超时
|
||||
if time.time() - start_time > timeout:
|
||||
condition_print("serial com read Time's out!--", time)
|
||||
return {"status": "error", "msg": "serial com read Time's out!"}
|
||||
break
|
||||
frame += self.ser.read(self.ser.in_waiting) # 读取剩余的数据
|
||||
if self.frame_is_valid(frame) == False:
|
||||
condition_print("recv frame is not valid", '[', ', '.join('{:02x}'.format(x) for x in frame), ']')
|
||||
return {"status": "error", "msg": "recv frame is not valid"}
|
||||
else:
|
||||
condition_print("--write data to plc success", "resp", ' [',
|
||||
', '.join('{:02x}'.format(x) for x in frame), ']')
|
||||
# condition_print('recv pld frame: [', ', '.join('{:02x}'.format(x) for x in frame), ']')
|
||||
return {"status": "success", "data": frame}
|
||||
else:
|
||||
return {"status":"error", "msg": "serial com is not open!"}
|
||||
pass
|
||||
|
||||
def plc_read(self, command, plc_no=0x01, pc_no=0xFF, address='D0160', len=0x01):
|
||||
frame = self.plc_read_frame(command, plc_no, pc_no, address, len)
|
||||
timeout = 2 # 设置超时时间为2秒
|
||||
if hasattr(self, 'ser') and self.ser:
|
||||
self.ser.write(frame)
|
||||
frame = self.ser.read(1);
|
||||
time.sleep(0.06)
|
||||
start_time = time.time() # 记录开始时间
|
||||
while self.ser.in_waiting:
|
||||
# 检查是否超时
|
||||
if time.time() - start_time > timeout:
|
||||
condition_print("serial com read Time's out!--", time)
|
||||
return {"status": "error", "msg": "serial com read Time's out!"}
|
||||
break
|
||||
frame += self.ser.read(self.ser.in_waiting) # 读取剩余的数据
|
||||
if self.frame_is_valid(frame) == False:
|
||||
condition_print("recv frame is not valid")
|
||||
return {"status": "error", "msg": "recv frame is not valid"}
|
||||
else:
|
||||
condition_print('--read data return: [', ', '.join('{:02x}'.format(x) for x in frame), ']')
|
||||
return {"status": "success", "data": frame}
|
||||
else:
|
||||
return {"status":"error", "msg": "serial com is not open!"}
|
||||
def plc_read_words(self, plc_no=0x01, pc_no=0xFF, address='D0160', length=0x01):
|
||||
resp = {'status': 'error'}
|
||||
result = self.plc_read('WR', plc_no, pc_no, address, length)
|
||||
if result and 'status' in result and result['status'] == 'success' and 'data' in result:
|
||||
frame = result['data']
|
||||
data_len = (len(frame) - 8) / 4
|
||||
if data_len == length:
|
||||
value = [ascii_array_to_word(frame[5 + 4 * i:5 + 4 * (i + 1)]) for i in range(length)]
|
||||
resp = {'status': 'success', 'length': data_len, 'data': value}
|
||||
return resp
|
||||
|
||||
def plc_read_bits(self, plc_no=0x01, pc_no=0xFF, address='D0160', length=0x01):
|
||||
resp = {'status': 'error'}
|
||||
result = self.plc_read('BR', plc_no, pc_no, address, length)
|
||||
condition_print('plc_read_bits result',result) #cyx
|
||||
if 'status' in result and result['status'] == 'success' and 'data' in result:
|
||||
frame = result['data']
|
||||
data_len = (len(frame) - 8) / 1
|
||||
if data_len == length:
|
||||
value = [(frame[5 + 1 * i] - 0x30) for i in range(length)]
|
||||
resp = {'status': 'success', 'length': data_len, 'data': value}
|
||||
return resp
|
||||
|
||||
def plc_write_word(self, plc_no=0x01, pc_no=0xFF, address='D0160', data=0x0000):
|
||||
return self.plc_write('WW', plc_no, pc_no, address, 0x01, list([data]))
|
||||
|
||||
def plc_write_dword(self, plc_no=0x01, pc_no=0xFF, address='D0160', data=0x00000000):
|
||||
return self.plc_write('WW', plc_no, pc_no, address, 0x02, list([data >> 16, data & 0xFFFF]))
|
||||
|
||||
def plc_write_words(self, plc_no=0x01, pc_no=0xFF, start_addr='D0160', length=0x04, data=[]):
|
||||
return self.plc_write('WW', plc_no, pc_no, start_addr, length, data)
|
||||
|
||||
def plc_write_bits(self, plc_no=0x01, pc_no=0xFF, address='D0160', length=0x01, data=[]):
|
||||
return self.plc_write('BW', plc_no, pc_no, address, length, data)
|
||||
|
||||
|
||||
|
||||
|
||||
class DtmMachine:
|
||||
def __init__(self, comm_port, comm_config={}, drop_register={}, plc_address=0x01):
|
||||
self.machine_plc = DevicePLC(comm_port, comm_config)
|
||||
self.drop_register = drop_register
|
||||
self.plc_address = plc_address
|
||||
self.plc_comm_lock = threading.Lock()
|
||||
pass
|
||||
|
||||
def set_station_dropheight(self, station_no, height):
|
||||
value_return = {'status': 'error'}
|
||||
with self.plc_comm_lock:
|
||||
resp = self.machine_plc.plc_write_word(self.plc_address, 0xFF, self.drop_register[station_no]['height'], height)
|
||||
if 'status' in resp and resp['status'] == 'success' and 'data' in resp:
|
||||
if resp['data'][0] == 0x06: # ACK
|
||||
value_return = {'status': 'success'}
|
||||
condition_print(f'write {station_no} height {height} success')
|
||||
return value_return
|
||||
|
||||
def set_station_cycles(self, station_no, cycles):
|
||||
value_return = {'status': 'error'}
|
||||
with self.plc_comm_lock:
|
||||
resp = self.machine_plc.plc_write_word(self.plc_address, 0xFF, self.drop_register[station_no]['cycles'], cycles)
|
||||
if 'status' in resp and resp['status'] == 'success' and 'data' in resp:
|
||||
if resp['data'][0] == 0x06: # ACK
|
||||
value_return = {'status': 'success'}
|
||||
condition_print(f'write {station_no} cycles {cycles} success')
|
||||
return value_return
|
||||
|
||||
def set_station_finished(self, station_no, finished):
|
||||
value_return = {'status': 'error'}
|
||||
with self.plc_comm_lock:
|
||||
resp = self.machine_plc.plc_write_word(self.plc_address, 0xFF, self.drop_register[station_no]['cyclesFinished'], finished)
|
||||
if 'status' in resp and resp['status'] == 'success' and 'data' in resp:
|
||||
if resp['data'][0] == 0x06: # ACK
|
||||
value_return = {'status': 'success'}
|
||||
condition_print(f'write {station_no} cyclesFinished {finished} success')
|
||||
return value_return
|
||||
|
||||
def read_station_dropheight(self, station_no):
|
||||
value_return = {'status': 'error'}
|
||||
with self.plc_comm_lock:
|
||||
resp = self.machine_plc.plc_read_words(self.plc_address, 0xFF, self.drop_register[station_no]['height'], 0x01)
|
||||
if 'status' in resp and resp['status'] == 'success' and 'data' in resp and resp['length'] == 0x01:
|
||||
value_return = {'status': 'success', 'value': resp['data'][0]}
|
||||
condition_print(f'read {station_no} height success', resp['data'][0])
|
||||
return value_return
|
||||
|
||||
def read_station_cyclesFinished(self, station_no):
|
||||
value_return = {'status': 'error'}
|
||||
with self.plc_comm_lock:
|
||||
resp = self.machine_plc.plc_read_words(self.plc_address, 0xFF, self.drop_register[station_no]['cyclesFinished'],
|
||||
0x01)
|
||||
if 'status' in resp and resp['status'] == 'success' and 'data' in resp and resp['length'] == 0x01:
|
||||
value_return = {'status': 'success', 'value': resp['data'][0]}
|
||||
condition_print(f'read {station_no} cyclesFinished success', resp['data'][0])
|
||||
return value_return
|
||||
|
||||
def start_station(self, station_no):
|
||||
value_return = {'status': 'error'}
|
||||
with self.plc_comm_lock:
|
||||
resp1 = self.machine_plc.plc_write_bits(self.plc_address, 0xFF, self.drop_register[station_no]['start'],
|
||||
0x01, [0x01])
|
||||
resp2 = self.machine_plc.plc_write_bits(self.plc_address, 0xFF, self.drop_register[station_no]['stop'],
|
||||
0x01, [0x00])
|
||||
if 'status' in resp1 and resp1['status'] == 'success' and 'data' in resp1 and resp1['data'][0] == 0x06 and \
|
||||
'status' in resp2 and resp2['status'] == 'success' and 'data' in resp2 and resp2['data'][0] == 0x06: # ACK
|
||||
value_return = {'status': 'success'}
|
||||
condition_print(f'plc start {station_no} success')
|
||||
|
||||
return value_return
|
||||
|
||||
def resume_station(self, station_no):
|
||||
value_return = {'status': 'error'}
|
||||
with self.plc_comm_lock:
|
||||
resp1 = self.machine_plc.plc_write_bits(self.plc_address, 0xFF, self.drop_register[station_no]['start'],
|
||||
0x01, [0x01])
|
||||
resp2 = self.machine_plc.plc_write_bits(self.plc_address, 0xFF, self.drop_register[station_no]['stop'],
|
||||
0x01, [0x00])
|
||||
if 'status' in resp1 and resp1['status'] == 'success' and 'data' in resp1 and resp1['data'][0] == 0x06 and \
|
||||
'status' in resp2 and resp2['status'] == 'success' and 'data' in resp2 and resp2['data'][0] == 0x06: # ACK
|
||||
value_return = {'status': 'success'}
|
||||
condition_print(f'plc resume {station_no} success')
|
||||
|
||||
return value_return
|
||||
def stop_station(self, station_no):
|
||||
value_return = {'status': 'error'}
|
||||
with self.plc_comm_lock:
|
||||
resp1 = self.machine_plc.plc_write_bits(self.plc_address, 0xFF, self.drop_register[station_no]['start'], 0x01, [0x00])
|
||||
resp2 = self.machine_plc.plc_write_bits(self.plc_address, 0xFF, self.drop_register[station_no]['stop'], 0x01, [0x01])
|
||||
if 'status' in resp1 and resp1['status'] == 'success' and 'data' in resp1 and resp1['data'][0] == 0x06 and \
|
||||
'status' in resp2 and resp2['status'] == 'success' and 'data' in resp2 and resp2['data'][0] == 0x06: # ACK
|
||||
value_return = {'status': 'success'}
|
||||
condition_print(f'plc stop {station_no} success')
|
||||
return value_return
|
||||
|
||||
def station_start_status(self, station_no):
|
||||
value_return = {'status': 'error'}
|
||||
with self.plc_comm_lock:
|
||||
resp = self.machine_plc.plc_read_bits(self.plc_address, 0xFF, self.drop_register[station_no]['start'], 0x01)
|
||||
if 'status' in resp and resp['status'] == 'success' and 'data' in resp and resp['length'] == 0x01:
|
||||
value_return = {'status': 'success', 'value': resp['data'][0]}
|
||||
condition_print(f'plc read {station_no} cyclesFinished success', resp['data'][0])
|
||||
return value_return
|
||||
Reference in New Issue
Block a user