import socket
import serial
import time


class MovingRailServer:
    def __init__(self):
        self.port = None
        self.motor_on = False
        self.recv_buff = ""

    def connect(self, device, baudrate, timeout=1):
        self.port = serial.Serial(device, baudrate, timeout=timeout)
        self.port.send_break()

    def is_connected(self):
        return self.port is not None

    def close(self):
        self.port.close()
        self.port = None

    def home(self):
        cmd = "G28"
        success = self._write(cmd)
        return success

    def move(self, pos, feedrate=10):
        cmd = "G1 X{} F{}".format(pos, feedrate)
        success = self._write(cmd)
        return success

    def _write(self, data, add_break=True):
        if add_break:
            data += "\n"
        data_b = bytes(data, encoding="ascii")
        self.port.write(data_b)
        return True


def main():
    # local IP/port (to be replaced)
    UDP_IP = "0.0.0.0"
    UDP_PORT = 5810
    SER_PORT = "COM1"

    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.settimeout(1.0)
    sock.bind((UDP_IP, UDP_PORT))
    
    print("Init rail...")
    rail_server = MovingRailServer()
    rail_server.connect(SER_PORT, 9600)
    time.sleep(2)
    rail_server.home()
    print("Listening on {}:{}".format(UDP_IP, UDP_PORT))

    while True:
        try:
            data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
        except socket.timeout:
            continue
        data = str(data, encoding="utf-8")
        print('received: "{}" from {}'.format(data, addr))
        rail_server._write(data, False)
        data_reply = "OK"
        sent = sock.sendto(bytearray(data, encoding="utf-8"), addr)
        print('send: "{}" to {}'.format(data_reply, addr))


if __name__ == "__main__":
    main()
