Forum Migration Notice
We're transitioning to a more modern community platform by the end of this year. Learn about the upcoming changes and what to expect.

How to send commands from desktop to flexpicker via python

Hi all,
I'm trying to send a few basic commands like up down left right to flexpicker via a python code running on my desktop acting as server. The flexpicker has rapid module which is acting a client. 

Python server
import socket
import threading
import time
import sys
import errno
import psutil
import os

# TCP server parameters
TCP_IP = "192.168.10.1"  # PC's ETH_3_Robot IP
TCP_PORT = 30002
ROBOT_IP = "192.168.10.32"  # Robot's IP
tcp_server = None
client_socket = None
client_lock = threading.Lock()

def check_port_usage(port):
    print(f"Checking if port {port} is in use...")
    for conn in psutil.net_connections():
        if conn.laddr.port == port:
            print(f"Error: Port {port} is already in use by process {conn.pid}")
            return False
    print(f"Port {port} is free.")
    return True

def validate_network():
    print(f"Validating network configuration...")
    try:
        local_ip = socket.gethostbyname(socket.gethostname())
        print(f"PC IP: {local_ip}")
    except Exception as e:
        print(f"Failed to get PC IP: {str(e)}")
        return False
    
    print(f"Attempting to ping robot at {ROBOT_IP}...")
    try:
        response = os.system(f"ping -n 1 {ROBOT_IP}")
        if response == 0:
            print(f"Ping to robot {ROBOT_IP} successful.")
        else:
            print(f"Ping to robot {ROBOT_IP} failed. Check network connection or robot IP.")
            return False
    except Exception as e:
        print(f"Ping test failed: {str(e)}")
        return False
    return True

def start_tcp_server():
    global tcp_server, client_socket
    print("Starting TCP server...")
    
    if not check_port_usage(TCP_PORT):
        print("Cannot start server due to port conflict. Exiting...")
        sys.exit(1)
    
    if not validate_network():
        print("Network validation failed. Exiting...")
        sys.exit(1)
    
    try:
        tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        print("Socket created successfully.")
    except Exception as e:
        print(f"Failed to create socket: {str(e)}")
        sys.exit(1)
    
    try:
        tcp_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        print("Socket options set successfully.")
    except Exception as e:
        print(f"Failed to set socket options: {str(e)}")
        sys.exit(1)
    
    try:
        tcp_server.bind((TCP_IP, TCP_PORT))
        print(f"Socket bound to {TCP_IP}:{TCP_PORT}.")
    except socket.error as e:
        if e.errno == errno.EADDRINUSE:
            print(f"Port {TCP_PORT} is already in use. Try a different port.")
        else:
            print(f"Failed to bind socket: {str(e)}")
        sys.exit(1)
    
    try:
        tcp_server.listen(1)
        print(f"Server listening on {TCP_IP}:{TCP_PORT}, waiting for robot connection...")
    except Exception as e:
        print(f"Failed to listen: {str(e)}")
        sys.exit(1)
    
    try:
        while True:
            try:
                client_socket, addr = tcp_server.accept()
                print(f"Robot connected from {addr}")
                with client_lock:
                    client_socket.settimeout(1.0)
            except socket.timeout:
                print("Timeout waiting for connection. Retrying...")
                continue
            except Exception as e:
                print(f"Error accepting connection: {str(e)}")
                break
    except KeyboardInterrupt:
        print("Server interrupted by user.")
    finally:
        try:
            if client_socket:
                client_socket.close()
                print("Client socket closed.")
        except Exception as e:
            print(f"Error closing client socket: {str(e)}")
        try:
            if tcp_server:
                tcp_server.close()
                print("Server socket closed.")
        except Exception as e:
            print(f"Error closing server socket: {str(e)}")

def send_response(command):
    global client_socket
    message = f"{command}_OK\n"
    print(f"Preparing to send response: {message.strip()}")
    with client_lock:
        if client_socket:
            try:
                client_socket.send(message.encode())
                print(f"Sent response: {message.strip()}")
            except Exception as e:
                print(f"Failed to send response: {str(e)}")
        else:
            print("No robot connected. Waiting for connection...")

def receive_command():
    global client_socket
    while True:
        with client_lock:
            if client_socket:
                try:
                    data = client_socket.recv(1024).decode().strip()
                    if data:
                        print(f"Received command from robot: {data}")
                        send_response(data)
                except socket.timeout:
                    continue
                except Exception as e:
                    print(f"Error receiving command: {str(e)}")
                    break
        time.sleep(0.1)

if __name__ == "__main__":
    # Start TCP server in a separate thread
    tcp_thread = threading.Thread(target=start_tcp_server, daemon=True)
    tcp_thread.start()

    # Start receiving commands in a separate thread
    receive_thread = threading.Thread(target=receive_command, daemon=True)
    receive_thread.start()

    # Keep the main thread running
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        print("Application stopped by user.")
    finally:
        try:
            if client_socket:
                client_socket.close()
                print("Client socket closed (main).")
        except Exception as e:
            print(f"Error closing client socket (main): {str(e)}")
        try:
            if tcp_server:
                tcp_server.close()
                print("Server socket closed (main).")
        except Exception as e:
            print(f"Error closing server socket (main): {str(e)}")
        print("Application stopped.")


My Robot_client.mod 
MODULE RobotClient

    VAR socketdev server_socket;
    VAR string received_data;
    VAR bool connected := FALSE;
    VAR num retry_count := 0;

    PROC main()
        VAR string host := "192.168.10.1";  ! PC's ETH_3_Robot IP
        VAR num port := 30002;

        WHILE TRUE DO
            IF NOT connected THEN
                TPWrite "Attempting to create socket... Retry count: " + NumToStr(retry_count, 0);
                SocketCreate server_socket;
                IF SocketGetStatus(server_socket) <> SOCKET_CREATED THEN
                    TPWrite "Failed to create socket.";
                    WaitTime 2;
                    retry_count := retry_count + 1;
                    IF retry_count >= 5 THEN
                        TPWrite "Max retries reached. Exiting...";
                        ExitCycle;
                    ENDIF
                ELSE
                    TPWrite "Socket created successfully.";
                ENDIF

                TPWrite "Attempting to connect to " + host + ":" + NumToStr(port, 0);
                SocketConnect server_socket, host, port \Time:=5;
                IF SocketGetStatus(server_socket) = SOCKET_CONNECTED THEN
                    connected := TRUE;
                    TPWrite "Connected to PC at " + host + ":" + NumToStr(port, 0);
                    retry_count := 0;
                ELSE
                    TPWrite "Failed to connect to PC. Retrying...";
                    SocketClose server_socket;
                    WaitTime 2;
                    retry_count := retry_count + 1;
                    IF retry_count >= 5 THEN
                        TPWrite "Max retries reached. Exiting...";
                        ExitCycle;
                    ENDIF
                ENDIF
            ENDIF

            IF connected THEN
                ! Send a test command
                SocketSend server_socket \Str:="UP\n";
                TPWrite "Sent command: UP";

                ! Receive response
                SocketReceive server_socket \Str:=received_data \Time:=5;
                IF received_data <> "" THEN
                    TPWrite "Received response: " + received_data;
                    received_data := "";
                ELSE
                    TPWrite "No response received.";
                ENDIF

                WaitTime 2;  ! Wait before sending the next command
            ENDIF
        ENDWHILE
    ERROR
        IF ERRNO = ERR_SOCK_TIMEOUT THEN
            received_data := "";
            RETRY;
        ELSEIF ERRNO = ERR_SOCK_CLOSED THEN
            connected := FALSE;
            SocketClose server_socket;
            TPWrite "Connection closed. Reconnecting...";
            retry_count := 0;
            RETRY;
        ELSE
            TPWrite "Unexpected error: " + NumToStr(ERRNO, 0);
            SocketClose server_socket;
            WaitTime 2;
            RETRY;
        ENDIF
    ENDPROC

ENDMODULE