完善reboot指令,hr的实例化需要手动关闭,并且会自动重连
This commit is contained in:
parent
57d9da7bc7
commit
50f150d685
@ -25,19 +25,21 @@ setdefaulttimeout(TIMEOUT)
|
|||||||
PREFIX = "../assets"
|
PREFIX = "../assets"
|
||||||
log_path = f"{PREFIX}/logs/"
|
log_path = f"{PREFIX}/logs/"
|
||||||
log_data_debug = f"{PREFIX}/logs/debug.log"
|
log_data_debug = f"{PREFIX}/logs/debug.log"
|
||||||
|
log_data_reqs = f"{PREFIX}/logs/reqs.log"
|
||||||
|
|
||||||
if not exists(log_path):
|
if not exists(log_path):
|
||||||
mkdir(log_path)
|
mkdir(log_path)
|
||||||
else:
|
else:
|
||||||
for _ in listdir(log_path):
|
for _ in listdir(log_path):
|
||||||
remove("".join([log_path, _]))
|
remove("".join([log_path, _]))
|
||||||
|
|
||||||
logger.remove()
|
logger.remove()
|
||||||
logger.add(stdout, level="INFO")
|
logger.add(stdout, level="INFO")
|
||||||
logger.add(
|
logger.add(
|
||||||
sink=log_data_debug,
|
sink=log_data_debug,
|
||||||
level="DEBUG",
|
level="DEBUG",
|
||||||
format="{time: YYYY-MM-DD HH:mm:ss} | {level} | {message}",
|
format="{time: YYYY-MM-DD HH:mm:ss} | {level} | {message}",
|
||||||
rotation="10 KB",
|
rotation="50 MB",
|
||||||
encoding="utf-8",
|
encoding="utf-8",
|
||||||
enqueue=True,
|
enqueue=True,
|
||||||
diagnose=True,
|
diagnose=True,
|
||||||
|
153
code/openapi.py
153
code/openapi.py
@ -4,11 +4,12 @@ from inspect import currentframe
|
|||||||
from socket import socket, AF_INET, SOCK_STREAM
|
from socket import socket, AF_INET, SOCK_STREAM
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
import selectors
|
import selectors
|
||||||
from time import time, sleep
|
from time import time, sleep, strftime, localtime
|
||||||
from pymodbus.client.tcp import ModbusTcpClient
|
from pymodbus.client.tcp import ModbusTcpClient
|
||||||
# from pymodbus.payload import BinaryPayloadDecoder, BinaryPayloadBuilder
|
# from pymodbus.payload import BinaryPayloadDecoder, BinaryPayloadBuilder
|
||||||
# from pymodbus.constants import Endian
|
# from pymodbus.constants import Endian
|
||||||
from paramiko import SSHClient, AutoAddPolicy
|
from paramiko import SSHClient, AutoAddPolicy
|
||||||
|
from datetime import datetime
|
||||||
import clibs
|
import clibs
|
||||||
|
|
||||||
|
|
||||||
@ -249,15 +250,31 @@ class HmiRequest(object):
|
|||||||
self.__leftover = 0
|
self.__leftover = 0
|
||||||
self.__flag_xs = 0
|
self.__flag_xs = 0
|
||||||
self.__response_xs = ""
|
self.__response_xs = ""
|
||||||
self.__t_bool = True
|
self.__is_connected = False
|
||||||
|
self.__silence = False
|
||||||
self.__pkg_size = 0
|
self.__pkg_size = 0
|
||||||
self.__broke = 0
|
self.__broke = 0
|
||||||
self.__half = 0
|
self.__half = 0
|
||||||
self.__half_length = 0
|
self.__half_length = 0
|
||||||
self.__index = 0
|
self.__index = 0
|
||||||
self.__reset_index = 0
|
self.__reset_index = 0
|
||||||
|
self.__close_hmi = False
|
||||||
|
|
||||||
|
# self.__sock_conn()
|
||||||
|
self.__t_is_alive = Thread(target=self.__is_alive)
|
||||||
|
self.__t_is_alive.daemon = False
|
||||||
|
self.__t_is_alive.start()
|
||||||
|
|
||||||
|
def __is_alive(self):
|
||||||
|
first_time = True
|
||||||
|
while not self.__close_hmi:
|
||||||
|
if not self.__is_connected:
|
||||||
|
if not first_time:
|
||||||
|
clibs.logger.info("重新连接中...")
|
||||||
|
first_time = False
|
||||||
|
self.__silence = True
|
||||||
self.__sock_conn()
|
self.__sock_conn()
|
||||||
|
if self.__is_connected:
|
||||||
self.__t_heartbeat = Thread(target=self.__heartbeat)
|
self.__t_heartbeat = Thread(target=self.__heartbeat)
|
||||||
self.__t_heartbeat.daemon = True
|
self.__t_heartbeat.daemon = True
|
||||||
self.__t_heartbeat.start()
|
self.__t_heartbeat.start()
|
||||||
@ -267,6 +284,20 @@ class HmiRequest(object):
|
|||||||
self.__t_unpackage_xs = Thread(target=self.__unpackage_xs, args=(self.__c_xs,))
|
self.__t_unpackage_xs = Thread(target=self.__unpackage_xs, args=(self.__c_xs,))
|
||||||
self.__t_unpackage_xs.daemon = True
|
self.__t_unpackage_xs.daemon = True
|
||||||
self.__t_unpackage_xs.start()
|
self.__t_unpackage_xs.start()
|
||||||
|
else:
|
||||||
|
self.__silence = False
|
||||||
|
first_time = True
|
||||||
|
|
||||||
|
sleep(clibs.interval*10)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def connection_state(self):
|
||||||
|
return self.__is_connected
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
self.__close_hmi = True
|
||||||
|
self.__is_connected = False
|
||||||
|
self.__silence = True
|
||||||
|
|
||||||
def __sock_conn(self):
|
def __sock_conn(self):
|
||||||
try:
|
try:
|
||||||
@ -281,18 +312,19 @@ class HmiRequest(object):
|
|||||||
for _ in range(3):
|
for _ in range(3):
|
||||||
self.execution("controller.heart")
|
self.execution("controller.heart")
|
||||||
sleep(clibs.interval)
|
sleep(clibs.interval)
|
||||||
|
else:
|
||||||
|
self.__is_connected = True
|
||||||
clibs.logger.success("HMI connection success...")
|
clibs.logger.success("HMI connection success...")
|
||||||
except Exception as Err:
|
except Exception as Err:
|
||||||
clibs.logger.error(f"HMI connection failed...{Err}")
|
self.__sth_wrong(9, f"HMI connection failed...{Err}")
|
||||||
self.__sth_wrong(9)
|
|
||||||
|
|
||||||
def __sth_wrong(self, ex_code):
|
def __sth_wrong(self, ex_code, err_desc=""):
|
||||||
self.__t_bool = False
|
self.__is_connected = False
|
||||||
clibs.logger.error(f"[{ex_code}] Something wrong happened!!! "
|
if not self.__silence:
|
||||||
f"可能是HMI无法连接到 {clibs.ip_addr}:{clibs.socket_port},也可能是其他问题... "
|
clibs.logger.error(f"[{ex_code}] 可能是 HMI 无法连接到 {clibs.ip_addr}:{clibs.socket_port}...")
|
||||||
f"确认无问题后,可尝试重新运行!")
|
if err_desc != "":
|
||||||
exit(ex_code)
|
clibs.logger.error(f"[{ex_code}] {err_desc}")
|
||||||
|
# exit(ex_code)
|
||||||
|
|
||||||
def __header_check(self, index, data):
|
def __header_check(self, index, data):
|
||||||
if index + 8 < len(data):
|
if index + 8 < len(data):
|
||||||
@ -305,8 +337,7 @@ class HmiRequest(object):
|
|||||||
return index + 8, _frame_size, _pkg_size
|
return index + 8, _frame_size, _pkg_size
|
||||||
else:
|
else:
|
||||||
print(data)
|
print(data)
|
||||||
clibs.logger.critical("Header Check: 解包数据有误,需要确认!")
|
self.__sth_wrong(6, "Header Check: 解包数据有误,需要确认!")
|
||||||
self.__sth_wrong(6)
|
|
||||||
else:
|
else:
|
||||||
self.__half_length = len(data) - index
|
self.__half_length = len(data) - index
|
||||||
self.__half = data[index:]
|
self.__half = data[index:]
|
||||||
@ -315,7 +346,7 @@ class HmiRequest(object):
|
|||||||
return index, 0, 0
|
return index, 0, 0
|
||||||
|
|
||||||
def __heartbeat(self):
|
def __heartbeat(self):
|
||||||
while self.__t_bool:
|
while self.__is_connected:
|
||||||
self.execution("controller.heart")
|
self.execution("controller.heart")
|
||||||
sleep(clibs.heartbeat_interval)
|
sleep(clibs.heartbeat_interval)
|
||||||
|
|
||||||
@ -336,37 +367,37 @@ class HmiRequest(object):
|
|||||||
if not error_code:
|
if not error_code:
|
||||||
return eval(line.split("|")[-1].strip())
|
return eval(line.split("|")[-1].strip())
|
||||||
else:
|
else:
|
||||||
clibs.logger.error(f"请求 {msg_id} 的返回错误码为 {error_code}")
|
self.__sth_wrong(7, f"请求 {msg_id} 的返回错误码为 {error_code}")
|
||||||
self.__sth_wrong(7)
|
|
||||||
|
def find_response_xs(log_data):
|
||||||
|
with open(log_data, mode="r", encoding="utf-8") as f_log:
|
||||||
|
for line in reversed(f_log.readlines()):
|
||||||
|
if line.split("|")[1].strip() != "DEBUG":
|
||||||
|
continue
|
||||||
|
if msg_id in line.strip():
|
||||||
|
return eval(line.split("|")[-1].strip())
|
||||||
|
|
||||||
if flag == 0:
|
if flag == 0:
|
||||||
for _ in range(3):
|
for _ in range(3):
|
||||||
res = find_response(clibs.log_data_debug)
|
res = find_response(clibs.log_data_debug)
|
||||||
if res is not None:
|
if res is not None:
|
||||||
return res["data"]
|
return res["data"]
|
||||||
sleep(clibs.interval)
|
sleep(clibs.interval*2)
|
||||||
else: # 尝试在上一次分割的日志中查找,只做一次
|
else: # 尝试在上一次分割的日志中查找,只做一次
|
||||||
res = find_response("".join([clibs.log_path, listdir(clibs.log_path)[0]]))
|
res = find_response("".join([clibs.log_path, listdir(clibs.log_path)[0]]))
|
||||||
if res is not None:
|
if res is not None:
|
||||||
return res["data"]
|
return res["data"]
|
||||||
elif flag == 1:
|
elif flag == 1:
|
||||||
sleep(1)
|
for _ in range(3):
|
||||||
with open(clibs.log_data_debug, mode="r", encoding="utf-8") as f_log:
|
res = find_response_xs(clibs.log_data_debug)
|
||||||
for line in reversed(f_log.readlines()):
|
if res is not None:
|
||||||
if line.split("|")[1].strip() != "DEBUG":
|
return res
|
||||||
continue
|
sleep(clibs.interval*2)
|
||||||
if msg_id in line.strip():
|
|
||||||
return eval(line.split("|")[-1].strip())
|
|
||||||
else:
|
else:
|
||||||
with open("".join([clibs.log_path, listdir(clibs.log_path)[0]]), mode="r", encoding="utf-8") as f_log:
|
res = find_response_xs("".join([clibs.log_path, listdir(clibs.log_path)[0]]))
|
||||||
for line in reversed(f_log.readlines()):
|
if res is not None:
|
||||||
if line.split("|")[1].strip() != "DEBUG":
|
return res
|
||||||
continue
|
self.__sth_wrong(11, f"无法找到请求 {msg_id} 的返回结果")
|
||||||
if msg_id in line.strip():
|
|
||||||
return eval(line.split("|")[-1].strip())
|
|
||||||
else:
|
|
||||||
clibs.logger.error(f"无法找到 xService 请求 {msg_id} 的返回结果")
|
|
||||||
self.__sth_wrong(11)
|
|
||||||
|
|
||||||
def __msg_storage(self, response, flag=0):
|
def __msg_storage(self, response, flag=0):
|
||||||
# response是解码后的字符串
|
# response是解码后的字符串
|
||||||
@ -395,8 +426,7 @@ class HmiRequest(object):
|
|||||||
_reserved = int.from_bytes(_full[7:8], byteorder="big")
|
_reserved = int.from_bytes(_full[7:8], byteorder="big")
|
||||||
if _reserved != 0 or _protocol != 2:
|
if _reserved != 0 or _protocol != 2:
|
||||||
print(data)
|
print(data)
|
||||||
clibs.logger.critical("in get_response: 解包数据有误,需要确认!")
|
self.__sth_wrong(10, "in get_response: 解包数据有误,需要确认!")
|
||||||
self.__sth_wrong(10)
|
|
||||||
|
|
||||||
self.__pkg_size = _pkg_size
|
self.__pkg_size = _pkg_size
|
||||||
self.__index = 8 - self.__half_length
|
self.__index = 8 - self.__half_length
|
||||||
@ -552,14 +582,13 @@ class HmiRequest(object):
|
|||||||
sel = selectors.DefaultSelector()
|
sel = selectors.DefaultSelector()
|
||||||
sel.register(sock, selectors.EVENT_READ, to_read)
|
sel.register(sock, selectors.EVENT_READ, to_read)
|
||||||
|
|
||||||
while self.__t_bool:
|
while self.__is_connected:
|
||||||
events = sel.select()
|
events = sel.select()
|
||||||
for key, mask in events:
|
for key, mask in events:
|
||||||
callback = key.data
|
callback = key.data
|
||||||
callback(key.fileobj, mask)
|
callback(key.fileobj, mask)
|
||||||
except Exception as Err:
|
except Exception as Err:
|
||||||
clibs.logger.error(Err)
|
self.__sth_wrong(3, f"错误信息:{Err}")
|
||||||
self.__sth_wrong(3)
|
|
||||||
|
|
||||||
def __unpackage_xs(self, sock):
|
def __unpackage_xs(self, sock):
|
||||||
def to_read(conn, mask):
|
def to_read(conn, mask):
|
||||||
@ -576,24 +605,27 @@ class HmiRequest(object):
|
|||||||
sel = selectors.DefaultSelector()
|
sel = selectors.DefaultSelector()
|
||||||
sel.register(sock, selectors.EVENT_READ, to_read)
|
sel.register(sock, selectors.EVENT_READ, to_read)
|
||||||
|
|
||||||
while self.__t_bool:
|
while self.__is_connected:
|
||||||
events = sel.select()
|
events = sel.select()
|
||||||
for key, mask in events:
|
for key, mask in events:
|
||||||
callback = key.data
|
callback = key.data
|
||||||
callback(key.fileobj, mask)
|
callback(key.fileobj, mask)
|
||||||
except Exception as Err:
|
except Exception as Err:
|
||||||
clibs.logger.error(Err)
|
self.__sth_wrong(8, f"错误信息:{Err}")
|
||||||
self.__sth_wrong(8)
|
|
||||||
|
|
||||||
def execution(self, command, protocol_flag=0, **kwargs):
|
def execution(self, command, protocol_flag=0, **kwargs):
|
||||||
|
def log_reqs(request):
|
||||||
|
with open(clibs.log_data_reqs, mode="a", encoding="utf-8") as f_log:
|
||||||
|
log_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
|
||||||
|
f_log.write(" ".join([log_time, dumps(req), "\n"]))
|
||||||
|
|
||||||
if protocol_flag == 0: # for old protocols
|
if protocol_flag == 0: # for old protocols
|
||||||
req = None
|
req = None
|
||||||
try:
|
try:
|
||||||
with open(f"{clibs.PREFIX}/json/{command}.json", encoding="utf-8", mode="r") as f_json:
|
with open(f"{clibs.PREFIX}/json/{command}.json", encoding="utf-8", mode="r") as f_json:
|
||||||
req = load(f_json)
|
req = load(f_json)
|
||||||
except Exception as Err:
|
except Exception as Err:
|
||||||
clibs.logger.info(f"暂不支持 {command} 功能,或确认该功能存在...\n{Err}")
|
self.__sth_wrong(5, f"暂不支持 {command} 功能,或确认该功能存在... {Err}")
|
||||||
self.__sth_wrong(5)
|
|
||||||
|
|
||||||
match command:
|
match command:
|
||||||
case "state.set_tp_mode":
|
case "state.set_tp_mode":
|
||||||
@ -716,11 +748,11 @@ class HmiRequest(object):
|
|||||||
req["id"] = self.__gen_id(command)
|
req["id"] = self.__gen_id(command)
|
||||||
cmd = dumps(req, separators=(",", ":"))
|
cmd = dumps(req, separators=(",", ":"))
|
||||||
try:
|
try:
|
||||||
|
log_reqs(req)
|
||||||
self.__c.send(self.__package(cmd))
|
self.__c.send(self.__package(cmd))
|
||||||
sleep(clibs.interval*2)
|
sleep(clibs.interval)
|
||||||
except Exception as Err:
|
except Exception as Err:
|
||||||
clibs.logger.error(f"{Err} 请求发送失败:{cmd}")
|
self.__sth_wrong(4, f"{Err} 请求发送失败:{cmd}")
|
||||||
self.__sth_wrong(4)
|
|
||||||
return req["id"]
|
return req["id"]
|
||||||
elif protocol_flag == 1: # for xService
|
elif protocol_flag == 1: # for xService
|
||||||
req = None
|
req = None
|
||||||
@ -728,8 +760,7 @@ class HmiRequest(object):
|
|||||||
with open(f"{clibs.PREFIX}/json/{command}.json", encoding="utf-8", mode="r") as f_json:
|
with open(f"{clibs.PREFIX}/json/{command}.json", encoding="utf-8", mode="r") as f_json:
|
||||||
req = load(f_json)
|
req = load(f_json)
|
||||||
except Exception as Err:
|
except Exception as Err:
|
||||||
clibs.logger.info(f"暂不支持 {command} 功能,或确认该功能存在...\n{Err}")
|
self.__sth_wrong(1, f"暂不支持 {command} 功能,或确认该功能存在... {Err}")
|
||||||
self.__sth_wrong(1)
|
|
||||||
|
|
||||||
match command:
|
match command:
|
||||||
case "safety.safety_area.signal_enable":
|
case "safety.safety_area.signal_enable":
|
||||||
@ -743,12 +774,13 @@ class HmiRequest(object):
|
|||||||
req["c"]["safety.safety_area.safety_area_enable"]["enable"] = kwargs["enable"]
|
req["c"]["safety.safety_area.safety_area_enable"]["enable"] = kwargs["enable"]
|
||||||
case _:
|
case _:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
log_reqs(req)
|
||||||
self.__c_xs.send(self.__package_xs(req))
|
self.__c_xs.send(self.__package_xs(req))
|
||||||
sleep(clibs.interval*2)
|
sleep(clibs.interval)
|
||||||
except Exception as Err:
|
except Exception as Err:
|
||||||
clibs.logger.error(f"{Err} 请求发送失败:{req}")
|
self.__sth_wrong(2, f"{Err} 请求发送失败:{req}")
|
||||||
self.__sth_wrong(2)
|
|
||||||
return command
|
return command
|
||||||
|
|
||||||
# =================================== ↓↓↓ specific functions ↓↓↓ ===================================
|
# =================================== ↓↓↓ specific functions ↓↓↓ ===================================
|
||||||
@ -845,6 +877,23 @@ class HmiRequest(object):
|
|||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
self.execution("controller.reboot")
|
self.execution("controller.reboot")
|
||||||
|
clibs.logger.info(f"控制器重启中,重连预计需要等待 100s 左右...")
|
||||||
|
ts = time()
|
||||||
|
sleep(30)
|
||||||
|
while True:
|
||||||
|
sleep(5)
|
||||||
|
te = time()
|
||||||
|
if te - ts > 180:
|
||||||
|
self.__silence = False
|
||||||
|
self.__sth_wrong("3min 内未能完成重新连接,需要查看后台控制器是否正常启动,或者 ip/port 是否正确")
|
||||||
|
break
|
||||||
|
for _ in range(3):
|
||||||
|
if not self.connection_state:
|
||||||
|
break
|
||||||
|
sleep(2)
|
||||||
|
else:
|
||||||
|
clibs.logger.info("HMI 重新连接成功...")
|
||||||
|
break
|
||||||
|
|
||||||
def reload_io(self):
|
def reload_io(self):
|
||||||
"""
|
"""
|
||||||
@ -1930,7 +1979,7 @@ class ExternalCommunication(object):
|
|||||||
|
|
||||||
def __exec_cmd(self, directive, description):
|
def __exec_cmd(self, directive, description):
|
||||||
self.s_string(directive)
|
self.s_string(directive)
|
||||||
result = self.r_string()
|
result = self.r_string().strip()
|
||||||
clibs.logger.info(f"外部通信:执行{description} {directive} 指令,返回值为 {result}")
|
clibs.logger.info(f"外部通信:执行{description} {directive} 指令,返回值为 {result}")
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user