Ejemplo n.º 1
0
def main(argc, argv):
    '''Main Function.'''
    # Check and parse program options from arguments
    options = parse_options()
    # Serial Port
    serial_port = ""
    if options["port"] is None:
        show_help()
        sys_exit(RC.OK)
    serial_port = options["port"][0]
    # Serial Bauds
    serial_bauds = 0
    if options["bauds"] is None:
        print_log(LOG.INFO, "BaudRate not provided, detecting...")
        serial_bauds = auto_detect_serial_bauds(serial_port)
        if serial_bauds == 0:
            print_log(LOG.INFO, "BaudRate detection fail.")
            sys_exit(RC.OK)
    else:
        serial_bauds = options["bauds"][0]
    # Serial log file
    serial_log = ""
    if options["log"] is not None:
        serial_log = options["log"][0]
    # Serial Terminal
    rc = serial_terminal(serial_port, serial_bauds)
    # Program end
    if not rc:
        program_exit(RC.FAIL)
    program_exit(RC.OK)
Ejemplo n.º 2
0
def cmd_script_parse(cmdscript):
    '''Parse cmdscript and check for unexpected or usupported keywords.'''
    # DOS to UNIX EOLs
    cmdscript = cmdscript.replace("\r\n", "\n")
    # Split the text in lines
    cmdscript = cmdscript.split("\n")
    # Iterate over each line detecting wich ones would be ignored
    lines_to_rm_index = []
    for i in range(len(cmdscript) - 1):
        line = cmdscript[i]
        # Check for empty and comment lines
        if (len(line) == 0) or (line[0] == "#"):
            lines_to_rm_index.append(i)
            continue
        # Check for unsupported/unkown command
        if line.split()[0] not in CONST.CMDSCRIPT_COMMANDS:
            print_log(LOG.WARNING, TEXT.UNEXPECTED_CMDSCRIPT_CMD.format(line))
            lines_to_rm_index.append(i)
            continue
    # Remove lines to ignore from cmdscript
    removed = 0
    for i in lines_to_rm_index:
        del cmdscript[i - removed]
        removed = removed + 1
    return cmdscript
Ejemplo n.º 3
0
def cmd_eol(args):
    '''Command EOL (send an End Of Line character/s to Serial CLI)'''
    # Send the EOL
    rc = serial_write(ser, eol)
    if rc is None:
        print_log(LOG.ERROR, TEXT.EOL_FAIL)
        return False
    print_log(LOG.INFO, TEXT.EOL_SEND)
    return True
Ejemplo n.º 4
0
def serial_read_str(ser=None, num_bytes=1024, timeout=None):
    '''Try to read from a Serial Port and return read data as string.'''
    raw_read = serial_read(ser, num_bytes, timeout)
    str_read = ""
    try:
        str_read = raw_read.decode()
    except Exception as e:
        print_log(LOG.ERROR, str(e))
    print_log(LOG.DEBUG, "Serial read (str):\n{}".format(str_read))
    return str_read
Ejemplo n.º 5
0
def create_parents_dirs(file_path):
    '''Create all parents directories from provided file path (mkdir -p $file_path).'''
    try:
        parentdirpath = os_path.dirname(file_path)
        if not os_path.exists(parentdirpath):
            os_makedirs(parentdirpath, 0o775)
    except Exception as e:
        print_log(
            LOG.ERROR, "Can't create parents directories of {}. {}".format(
                file_path, str(e)))
Ejemplo n.º 6
0
def file_clear(file_path):
    '''Remove and recreate a file to empty file content.'''
    create_parents_dirs(file_path)
    try:
        if os_path.exists(file_path):
            os_remove(file_path)
        with open(file_path, 'a'):
            os_utime(file_path, None)
    except Exception as e:
        print_log(LOG.ERROR,
                  "Can't clear file {}. {}".format(file_path, str(e)))
Ejemplo n.º 7
0
def program_exit(return_code):
    '''Finish function.'''
    global ser
    # Check if unexpected exit code provided and use RC.FAIL in that case
    if (return_code != RC.OK) and (return_code != RC.FAIL):
        return_code = RC.FAIL
    # Close and free any pending memory
    if (ser is not None) and ser.isOpen():
        serial_close(ser)
    # Exit
    print_log(LOG.DEBUG, "Program exit ({}).\n".format(return_code))
    sys_exit(return_code)
Ejemplo n.º 8
0
def cmd_disconnect(args):
    '''Command DISCONNECT (make a Serial Connection)'''
    global ser
    # Check for expected number of arguments
    if len(args) < 1:
        print_log(LOG.ERROR, TEXT.CMD_NO_ARGS.format("DISCONNECT"))
        return False
    serial_port = args[0]
    # Just close current porresponset (multiple ports support unimplemnted)
    if (ser is not None) and ser.isOpen():
        serial_close(ser)
    print_log(LOG.INFO, TEXT.DISCONNECT_CLOSE)
    return True
Ejemplo n.º 9
0
def serial_read_until(ser=None, expected=LF, num_bytes=1024, timeout=None):
    '''Try to read from a Serial Port until an expected bytes/substring.'''
    # Check if no port provided
    if ser is None:
        return ""
    # Setup read timeout
    backup_timeout = ser.timeout
    if timeout is not None:
        ser.timeout = timeout
    try:
        raw_read = ser.read_until(expected, num_bytes)
    except Exception as e:
        print_log(LOG.ERROR, str(e))
        return ""
    ser.timeout = backup_timeout
    print_log(LOG.DEBUG, "Serial read (bytes):\n{}".format(raw_read))
    # Parse to string
    str_read = ""
    try:
        str_read = str(raw_read)  # str_read = raw_read.decode()
    except Exception as e:
        print_log(LOG.ERROR, str(e))
        return ""
    print_log(LOG.DEBUG, "Serial read (str):\n{}".format(str_read))
    return str_read
Ejemplo n.º 10
0
def file_read_all_bin(file_path):
    '''Read all file content as binary and return it.'''
    # Check if no path provided or file doesnt exists
    if file_path is None:
        return None
    if not os_path.exists(file_path):
        print_log(LOG.ERROR, "File {} not found.".format(file_path))
        return None
    # File exists, so open and read it
    read = None
    try:
        with open(file_path, "rb") as f:
            read = f.read()
    except Exception as e:
        print_log(LOG.ERROR,
                  "Can't open and read file {}. {}".format(file_path, str(e)))
    return read
Ejemplo n.º 11
0
def serial_read(ser=None, num_bytes=1024, timeout=None):
    '''Try to read from a Serial Port.'''
    # Check if no port provided
    if ser is None:
        return b''
    # Setup read timeout
    backup_timeout = ser.timeout
    if timeout is not None:
        ser.timeout = timeout
    # Read and restore default read timeout
    try:
        raw_read = ser.read(num_bytes)
    except Exception as e:
        print_log(LOG.ERROR, str(e))
    ser.timeout = backup_timeout
    print_log(LOG.DEBUG, "Serial read (bytes):\n{}".format(raw_read))
    if not raw_read:
        return b''
    return raw_read
Ejemplo n.º 12
0
def file_read_all_text(file_path):
    '''Read all text file content and return it in a string.'''
    read = ""
    # Check if file doesnt exists
    if not os_path.exists(file_path):
        print_log(LOG.ERROR, "File {} not found.".format(file_path))
    # File exists, so open and read it
    else:
        try:
            if is_running_with_py3():
                with open(file_path, "r", encoding="utf-8") as f:
                    read = f.read()
            else:
                with open(file_path, "r") as f:
                    read = f.read()
        except Exception as e:
            print_log(
                LOG.ERROR,
                "Can't open and read file {}. {}".format(file_path, str(e)))
    return read
Ejemplo n.º 13
0
def cmdscript_interpreter(cmdscript):
    '''cmdscript interpreter'''
    for line in cmdscript:
        command = line.split()
        operation = command[0]
        args = command[1:]
        # Ignore unsupported operations
        if operation not in CONST.CMDSCRIPT_COMMANDS:
            continue
        # Handle Commands
        if operation == "CONNECT":
            if not cmd_connect(args):
                return False
        elif operation == "DISCONNECT":
            if not cmd_disconnect(args):
                return False
        elif operation == "CFGRESTIMEOUT":
            if not cmd_cfrestimeout(args):
                return False
        elif operation == "CFGEOL":
            if not cmd_cfgeol(args):
                return False
        elif operation == "DELAY":
            if not cmd_delay(args):
                return False
        elif operation == "DELAYMS":
            if not cmd_delayms(args):
                return False
        elif operation == "EOL":
            if not cmd_eol(args):
                return False
        elif operation == "CMD":
            if not cmd_command(args):
                return False
        elif operation == "RES":
            if not cmd_response(args):
                return False
        else:
            print_log(LOG.WARNING, TEXT.INVALID_CMDSCRIPT_CMD.format(command))
    return True
Ejemplo n.º 14
0
def auto_detect_serial_bauds(serial_port):
    '''Automatic Serial baudrate detection (check for ascii text in commons
    bauds).'''
    bauds = 0
    ser = None
    for common_baud in CONST.SERIAL_COMMON_BAUDS:
        # Try to open Serial port at current common baud rate
        # If port can't be open, continue to next common bauds
        print("\nChecking {} bauds...".format(common_baud))
        ser = serial_open(serial_port, common_baud, 1.0, 1.0)
        if ser is None:
            continue
        time.sleep(2)
        # Send some strange string with end of line and read response
        serial_write(ser, CONST.SERIAL_AUTODETECT_BAUDS_SEND)
        readed_bytes = serial_read_str(ser)
        if len(readed_bytes) == 0:
            serial_close(ser)
            continue
        # Remove end of line bytes
        readed_bytes = readed_bytes.replace("\r", "")
        readed_bytes = readed_bytes.replace("\n", "")
        # Ignore if readed bytes are less than 10 characters
        if len(readed_bytes) < 5:
            serial_close(ser)
            continue
        # Check how many characters are commons in human texts
        num_human_chars = 0
        for character in readed_bytes:
            if character in CONST.SERIAL_AUTODETECT_ASCII_LIST:
                num_human_chars = num_human_chars + 1
        # If >=70% of the read string are common human text characters
        # Assume that this is the correct baud rate
        if ((num_human_chars / len(readed_bytes)) *100) >= 70:
            bauds = common_baud
            print_log(LOG.INFO, "Seems that BuadRate is {}".format(bauds))
            serial_close(ser)
            break
        serial_close(ser)
    return bauds
Ejemplo n.º 15
0
def cmd_connect(args):
    '''Command CONNECT (make a Serial Connection)'''
    global ser
    # Check for expected number of arguments
    if len(args) < 2:
        print_log(LOG.ERROR, TEXT.CMD_NO_ARGS.format("CONNECT"))
        return False
    # Get and check arguments
    serial_port = args[0]
    serial_bauds = args[1]
    if not is_int(serial_bauds):
        print_log(LOG.ERROR, TEXT.CONNECT_INVALID_BAUDS)
        return False
    serial_bauds = int(serial_bauds)
    # Try to open the serial port
    print_log(LOG.INFO, TEXT.CONNECT_OPENING.format(serial_port, serial_bauds))
    ser = serial_open(serial_port, serial_bauds, res_timeout, 1.0)
    if (ser is None) or (not ser.isOpen()):
        print_log(LOG.INFO, TEXT.CONNECT_OPEN_FAIL)
        return False
    print_log(LOG.INFO, TEXT.CONNECT_OPEN)
    return True
Ejemplo n.º 16
0
def serial_terminal(port, bauds):
    '''Handle a Serial Terminal.'''
    global ser
    global th_read, th_write
    # Opening Serial Port
    print("\nOpening port {} at {} bauds...".format(port, bauds))
    ser = serial_open(port, bauds, 1.0, 1.0)
    if (ser is None) or (not ser.isOpen()):
        print_log(LOG.INFO, "Can't open Serial port.")
        return False
    time.sleep(2)
    # Launching Serial read and write threads
    th_read = Thread(target=th_serial_read, args=(ser,))
    th_write = Thread(target=th_serial_write, args=(ser,))
    print("\nSerial Terminal Start")
    th_read.start()
    th_write.start()
    th_read.join()
    th_write.join()
    # Close Serial Port
    if (ser is not None) and ser.isOpen():
        serial_close(ser)
    return True
Ejemplo n.º 17
0
def serial_close(ser=None):
    '''Try to close a Serial Port.'''
    # Check if no port provided
    if ser is None:
        return
    port = ser.port
    print_log(LOG.INFO, "Closing Serial port {}...".format(port))
    try:
        ser.close()
        print_log(LOG.INFO, "Serial port {} closed.".format(port))
    except SerialException as e:
        print_log(LOG.ERROR, str(e))
Ejemplo n.º 18
0
def serial_write(ser=None, to_write=None):
    '''Basic Serial write function managed for Py2 and Py3 support.'''
    if ser is None:
        return None
    print_log(LOG.DEBUG, "Serial write (str):\n{}".format(to_write))
    if is_running_with_py3():
        to_write = to_write.encode()
    try:
        ser.write(to_write)
    except Exception as e:
        print_log(LOG.ERROR, str(e))
    print_log(LOG.DEBUG, "Serial write (bytes):\n{}".format(to_write))
    ser.flush()
Ejemplo n.º 19
0
def serial_open(port, baudrate, read_timeout=None, write_timeout=None):
    '''Try to open a Serial Port.'''
    ser = None
    print_log(LOG.INFO,
              "Opening Serial port {} at {}bps...".format(port, str(baudrate)))
    try:
        ser = Serial(port=None)
        ser.port = port
        ser.baudrate = baudrate
        ser.timeout = read_timeout
        ser.write_timeout = write_timeout
        if not ser.isOpen():
            ser.open()
        ser.flush()
        print_log(LOG.INFO, "Port successfully open.")
    except Exception as e:
        print_log(LOG.ERROR, str(e))
    if (ser is None) or (not ser.isOpen()):
        ser = None
        print_log(LOG.ERROR, "Can't open serial port.")
    return ser
Ejemplo n.º 20
0
def cmd_delayms(args):
    '''Command DELAYMS (wait for some milli-seconds)'''
    # Check for expected number of arguments
    if len(args) < 1:
        print_log(LOG.ERROR, TEXT.CMD_NO_ARGS.format("DELAYMS"))
        return False
    # Check for valid time value
    if not is_int(args[0]):
        print_log(LOG.ERROR, TEXT.DELAYMS_INVALID)
        return False
    delay_time_ms = int(args[0])
    print_log(LOG.INFO, TEXT.DELAYMS.format(delay_time_ms))
    sleep(delay_time_ms / 1000)
    return True
Ejemplo n.º 21
0
def cmd_command(args):
    '''Command CMD (send a command to Serial CLI)'''
    # Check for expected number of arguments
    if len(args) < 1:
        print_log(LOG.ERROR, TEXT.CMD_NO_ARGS.format("CMD"))
        return False
    # Compose command string and add EOL character/s
    cmd_str = " ".join(args)
    cmd_str_eol = "{}{}".format(cmd_str, eol)
    # Send the command
    if not serial_write(ser, cmd_str_eol):
        print_log(LOG.ERROR, TEXT.CMD_SEND_FAIL.format(cmd_str))
        return False
    print_log(LOG.INFO, TEXT.CMD_SEND.format(cmd_str))
    return True
Ejemplo n.º 22
0
def cmd_response(args):
    '''Command RES (read for a response from Serial CLI)'''
    # Check for expected number of arguments
    if len(args) < 1:
        print_log(LOG.ERROR, TEXT.CMD_NO_ARGS.format("RES"))
        return False
    # Compose response string to expect
    res_str = " ".join(args)
    # Receive and read response
    res = serial_read_until(ser, res_str, timeout=res_timeout)
    if res == "":
        print_log(LOG.ERROR, TEXT.RES_FAIL.format(res_str, res))
        return False
    print_log(LOG.INFO, TEXT.RES_OK.format(res_str))
    return True
Ejemplo n.º 23
0
def cmd_cfrestimeout(args):
    '''Command CFGRESTIMEOUT (set Serial read timeout)'''
    global res_timeout
    # Check for expected number of arguments
    if len(args) < 1:
        print_log(LOG.ERROR, TEXT.CMD_NO_ARGS.format("CFGRESTIMEOUT"))
        return False
    # Check for valid timeout value
    if not is_int(args[0]):
        print_log(LOG.ERROR, TEXT.CFGRESTIMEOUT_INVALID)
        return False
    res_timeout = int(args[0]) / 1000
    if ser is not None:
        ser.timeout = res_timeout
    print_log(LOG.INFO, TEXT.CFGRESTIMEOUT_SET.format(res_timeout))
    return True
Ejemplo n.º 24
0
def cmd_cfgeol(args):
    '''Command CFGEOL (set Serial End Of Line character)'''
    global eol
    # Check for expected number of arguments
    if len(args) < 1:
        print_log(LOG.ERROR, TEXT.CMD_NO_ARGS.format("CFGEOL"))
        return False
    # Check for valid EOL value
    if args[0] not in ["CR", "LF", "CRLF"]:
        print_log(LOG.ERROR, TEXT.CFGEOL_INVALID)
        return False
    # Set EOL
    if args[0] == "CR":
        eol = EOL.CR
    elif args[0] == "LF":
        eol = EOL.LF
    elif args[0] == "CRLF":
        eol = EOL.CRLF
    print_log(LOG.INFO, TEXT.CFGEOL_SET.format(args[0]))
    return True
Ejemplo n.º 25
0
def file_write(file_path, text=""):
    '''Write text to provided file.'''
    create_parents_dirs(file_path)
    # Determine if file exists and set open mode to write or append
    if not os_path.exists(file_path):
        print_log(LOG.INFO,
                  "File {} not found, creating it...".format(file_path))
    # Try to Open and write to file
    if is_running_with_py3():
        try:
            with open(file_path, 'a', encoding="utf-8") as f:
                f.write(text)
        except Exception as e:
            print_log(LOG.ERROR,
                      "Can't write to file {}. {}".format(file_path, str(e)))
    else:
        try:
            with open(file_path, 'a') as f:
                f.write(text)
        except Exception as e:
            print_log(LOG.ERROR,
                      "Can't write to file {}. {}".format(file_path, str(e)))