from cefpython3 import cefpython as cefimport http.serverimport socketserverimport threadingimport osimport jsonimport socketserverimport threadingimport timefrom typing import Callable, Dict, Tuplefrom pymodbus.client import ModbusTcpClientfrom pymodbus.exceptions import ModbusExceptionek9000_ip = "10.5.5.3"robot_ip = "10.5.5.100"amr_ip = "10.2.9.171"browser = Nonebindings = Noneexternal = Nonetcp_server = Noneclass TcpServerHandler(socketserver.BaseRequestHandler):def setup(self):self.server.tcp_server.on_client_connected(self)def handle(self):while True:try:data = self.request.recv(1024)if not data:breakself.server.tcp_server.on_data_received(self, data)except Exception as e:print(f"[!] Error receiving data: {e}")breakdef finish(self):self.server.tcp_server.on_client_disconnected(self)class TcpServer:def __init__(self, host: str = "localhost", port: int = 9999):self.host = hostself.port = portself.clients: Dict[Tuple[str, int], TcpServerHandler] = {}self.on_connect_callback: Callable[[Tuple[str, int]], None] = lambda addr: Noneself.on_receive_callback: Callable[[Tuple[str, int], bytes], None] = (lambda addr, data: None)self.on_disconnect_callback: Callable[[Tuple[str, int]], None] = (lambda addr: None)self.server = socketserver.ThreadingTCPServer((self.host, self.port), TcpServerHandler)self.server.tcp_server = self # 将 TcpServer 实例绑定到 server 上def start(self):print(f"[+] TCP Server started on {self.host}:{self.port}")self.server.serve_forever()def stop(self):self.server.shutdown()self.server.server_close()print("[-] TCP Server stopped")def send_to_client(self, address: Tuple[str, int], data: bytes):client = self.clients.get(address)if client:try:client.request.sendall(data)except Exception as e:print(f"[!] Failed to send data to {address}: {e}")def broadcast(self, data: bytes):for client in self.clients.values():try:client.request.sendall(data)except Exception as e:print(f"[!] Failed to broadcast data: {e}")def on_client_connected(self, handler: TcpServerHandler):addr = handler.client_addressself.clients[addr] = handlerprint(f"[+] Client connected: {addr}")self.on_connect_callback(addr)def on_data_received(self, handler: TcpServerHandler, data: bytes):addr = handler.client_addressprint(f"[{addr[0]}] Received: {data.decode('utf-8', errors='ignore')}")self.on_receive_callback(addr, data)def on_client_disconnected(self, handler: TcpServerHandler):addr = handler.client_addressif addr in self.clients:del self.clients[addr]print(f"[-] Client disconnected: {addr}")self.on_disconnect_callback(addr)def register_on_connect(self, callback: Callable[[Tuple[str, int]], None]):self.on_connect_callback = callbackdef register_on_receive(self, callback: Callable[[Tuple[str, int], bytes], None]):self.on_receive_callback = callbackdef register_on_disconnect(self, callback: Callable[[Tuple[str, int]], None]):self.on_disconnect_callback = callbackdef read_modbus_di(host, address, port=502):"""Read digital input DI of device via Modbus TCPArgs:host (str): IP address of deviceaddress (int): Address of the discrete input to readport (int): Modbus TCP port, default is 502Returns:bool: Status of DI (True for high level, False for low level)"""# Create Modbus TCP clientclient = ModbusTcpClient(host, port=port)try:# Connect to deviceclient.connect()if not client.connected:print(f"Failed to connect to device {host}:{port}")return Noneresult = client.read_discrete_inputs(address=address, count=1)if not result.isError():di_state = result.bits[0]return di_stateelse:print(f"Error occurred while reading DI: {result}")return Noneexcept ModbusException as e:print(f"Modbus communication exception: {e}")return Noneexcept Exception as e:print(f"Other exception: {e}")return Nonefinally:# Close connectionclient.close()def control_modbus_do(host, address, state, port=502):"""Control digital output DO of device via Modbus TCPArgs:host (str): IP address of deviceaddress (int): Address of the coil to write tostate (bool): Desired state of DO (True for ON, False for OFF)port (int): Modbus TCP port, default is 502Returns:bool: Success status of the operation"""# Create Modbus TCP clientclient = ModbusTcpClient(host, port=port)try:# Connect to deviceclient.connect()if not client.connected:print(f"Failed to connect to device {host}:{port}")return Falseresult = client.write_coil(address=address, value=state)if not result.isError():print(f"Successfully set DO to {'ON' if state else 'OFF'}")return Trueelse:print(f"Error occurred while controlling DO: {result}")return Falseexcept ModbusException as e:print(f"Modbus communication exception: {e}")return Falseexcept Exception as e:print(f"Other exception: {e}")return Falsefinally:# Close connectionclient.close()def start_tcp_server():global tcp_servertcp_server = TcpServer("0.0.0.0", 9999)tcp_server.register_on_connect(on_connect)tcp_server.register_on_receive(on_receive)tcp_server.register_on_disconnect(on_disconnect)try:tcp_server.start()except KeyboardInterrupt:print("\n[!] Shutting down server...")tcp_server.stop()def start_http_server():port = 8080class MyHTTPRequestHandler(http.server.SimpleHTTPRequestHandler):def __init__(self, *args, **kwargs):super().__init__(*args, directory=os.path.dirname(os.path.abspath(__file__)), **kwargs)# 启动HTTP服务器with socketserver.TCPServer(("0.0.0.0", port), MyHTTPRequestHandler) as httpd:print(f"HTTP server started at http://0.0.0.0:{port}")httpd.serve_forever()class External(object):def __init__(self, browser):self.browser = browserself.status = 200def get_status(self, js_callback):js_callback.Call(self.status)def set_status(self, status):self.status = statusdef my_python_function(message):global bindingsglobal externalprint("Received message from JavaScript:", message)result = json.dumps({"status": "success", "data": "xxx"})browser.ExecuteJavascript(f"""receiveJsonFromPython({result})""")external.set_status(300)def InvokeJavaScript(method: str, args: dict = {}):global browserprint(f"InvokeJavaScript: {method}({args})")if browser is not None:browser.ExecuteJavascript(f"""window.{method}({json.dumps(args)})""")def initialize():global tcp_serverglobal ek9000_ipglobal robot_ipprint("invoke initialize")di_state = Falsesuccess = control_modbus_do(ek9000_ip, 0, True)if success:print("DO1 turned ON successfully")else:print("Failed to turn DO1 ON")InvokeJavaScript("onInitialze", {"code": -1})return Falsefor i in range(60):di_state = read_modbus_di(robot_ip, 8, 6502)if di_state is not None:print(f"DI8 status: {'High level' if di_state else 'Low level'}")if di_state:print("DI8 is high level")breakelse:print("Failed to read DI8 status")time.sleep(10)if not di_state:print("Failed to read DI8 status after 60 attempts")InvokeJavaScript("onInitialze", {"code": -1})return Falsesuccess = control_modbus_do(robot_ip, 40, True, 6502)if success:print("DO40 turned ON successfully")else:print("Failed to turn DO40 ON")InvokeJavaScript("onInitialze", {"code": -1})return Falsefor i in range(5):di_state = read_modbus_di(robot_ip, 9, 6502)if di_state is not None:print(f"DI9 status: {'High level' if di_state else 'Low level'}")if di_state:print("DI9 is high level")breakelse:print("Failed to read DI9 status")time.sleep(3)if not di_state:print("Failed to read DI9 status after 60 attempts")InvokeJavaScript("onInitialze", {"code": -1})return Falsesuccess = control_modbus_do(robot_ip, 42, True, 6502)if success:print("DO42 turned ON successfully")else:print("Failed to turn DO42 ON")InvokeJavaScript("onInitialze", {"code": -1})return Falsefor i in range(5):di_state = read_modbus_di(robot_ip, 10, 6502)if di_state is not None:print(f"DI10 status: {'High level' if di_state else 'Low level'}")if di_state:print("DI10 is high level")breakelse:print("Failed to read DI10 status")time.sleep(3)if not di_state:print("Failed to read DI10 status after 60 attempts")InvokeJavaScript("onInitialze", {"code": -1})return Falseprint("initialize completed")InvokeJavaScript("onInitialze", {"code": 0})return Truedef poweroff():global tcp_serverglobal ek9000_ipglobal robot_ipprint("invoke poweroff")di_state = Truesuccess = control_modbus_do(robot_ip, 43, True, 6502)if success:print("DO43 turned ON successfully")else:print("Failed to turn DO43 ON")InvokeJavaScript("onPoweroff", {"code": -1})return Falsefor i in range(5):di_state = read_modbus_di(robot_ip, 10, 6502)if di_state is not None:print(f"DI10 status: {'High level' if di_state else 'Low level'}")if not di_state:print("DI10 is low level")breakelse:print("Failed to read DI10 status")time.sleep(3)if di_state:print("Failed to read DI10 status after 60 attempts")InvokeJavaScript("onPoweroff", {"code": -1})return Falsesuccess = control_modbus_do(robot_ip, 41, True, 6502)if success:print("DO41 turned ON successfully")else:print("Failed to turn DO41 ON")InvokeJavaScript("onPoweroff", {"code": -1})return Falsefor i in range(5):di_state = read_modbus_di(robot_ip, 9, 6502)if di_state is not None:print(f"DI9 status: {'High level' if di_state else 'Low level'}")if not di_state:print("DI9 is low level")breakelse:print("Failed to read DI9 status")time.sleep(3)if di_state:print("Failed to read DI9 status after 60 attempts")InvokeJavaScript("onPoweroff", {"code": -1})return Falsesuccess = control_modbus_do(ek9000_ip, 1, True)if success:print("DO2 turned ON successfully")else:print("Failed to turn DO2 ON")InvokeJavaScript("onPoweroff", {"code": -1})return Falsedef reset():global tcp_serverprint("reset")tcp_server.broadcast("reset0円\n".encode("utf-8"))def resetGripper():global tcp_serverprint("resetGripper")tcp_server.broadcast("resetGripper0円\n".encode("utf-8"))def simpleLocation(pose):global tcp_serverprint(f"simpleLocation: {pose}")tcp_server.broadcast(f"simpleLocation {pose}0円\n".encode("utf-8"))def simpleExecuteTrajectory(trajectory):global tcp_serverprint(f"simpleExecuteTrajectory: {trajectory}")tcp_server.broadcast(f"simpleExecuteTrajectory {trajectory}0円\n".encode("utf-8"))def simpleMove(move):global tcp_serverprint(f"simpleMove: {move}")tcp_server.broadcast(f"simpleMove {move}0円\n".encode("utf-8"))def on_connect(addr):print(f"[INFO] New connection from {addr}")def on_receive(addr, data):global tcp_serverprint(f"[INFO] Data from {addr}: {data.decode('utf-8')}")try:data_str = data.decode("utf-8").strip()parts = data_str.split(",")if len(parts) >= 3:command = parts[0].strip()code = parts[1].strip()message = parts[2].strip()capitalized_command = (command[0].upper() + command[1:]if len(command) > 1else command.upper())InvokeJavaScript(f"on{capitalized_command}Response", {"code": code, "message": message})else:print(f"[WARNING] Invalid data format: {data_str}")except Exception as e:print(f"[ERROR] Failed to parse data: {e}")def on_disconnect(addr):print(f"[INFO] Disconnected from {addr}")def main():global browserglobal bindingsglobal externalif not initialize():print("initialize failed")returntcp_server_thread = threading.Thread(target=start_tcp_server, daemon=True)tcp_server_thread.start()http_server_thread = threading.Thread(target=start_http_server, daemon=True)http_server_thread.start()settings = {"context_menu": {"enabled": False},"debug": True,}cef.Initialize(settings)browser = cef.CreateBrowserSync(url="http://localhost:8080/index.html", window_title="My CEFPython App")browser.ToggleFullscreen()browser.ShowDevTools()external = External(browser)external.set_status(200)bindings = cef.JavascriptBindings()bindings.SetProperty("robotIp", amr_ip)bindings.SetFunction("initialize", initialize)bindings.SetFunction("poweroff", poweroff)bindings.SetFunction("reset", reset)bindings.SetFunction("resetGripper", resetGripper)bindings.SetFunction("simpleLocation", simpleLocation)bindings.SetFunction("simpleExecuteTrajectory", simpleExecuteTrajectory)bindings.SetFunction("simpleMove", simpleMove)browser.SetJavascriptBindings(bindings)cef.MessageLoop()cef.Shutdown()if __name__ == "__main__":main()
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。