Example #1
0
    def Receive(self, size=1):
        """Receives N bytes.

    It blocks at most timeout seconds.

    Args:
      size: number of bytes to receive. 0 means receiving what already in the
          input buffer.

    Returns:
      Received N bytes.

    Raises:
      SerialTimeoutException if it fails to receive N bytes.
    """
        start_time = time.time()
        if size == 0:
            size = self._serial.inWaiting()
        response = self._serial.read(size)
        if len(response) == size:
            if self.log:
                duration = time.time() - start_time
                logging.info('Successfully received %r. Took %.3f seconds',
                             response, duration)
            return response
        else:
            error_message = 'Receive %d bytes timeout after %.2f seconds' % (
                size, self._serial.getTimeout())
            if self.log:
                logging.warning(error_message)
            raise serial.SerialTimeoutException(error_message)
Example #2
0
 def _process_request(self, request: bytes, skip=0):
     """
     :param request: request that is sent to the monoprice
     :param skip: number of bytes to skip for end of transmission decoding
     :return: ascii string returned by monoprice
     """
     _LOGGER.debug('Sending "%s"', request)
     # clear
     self._port.reset_output_buffer()
     self._port.reset_input_buffer()
     # send
     self._port.write(request)
     self._port.flush()
     # receive
     result = bytearray()
     while True:
         c = self._port.read(1)
         if not c:
             raise serial.SerialTimeoutException(
                 'Connection timed out! Last received bytes {}'.format(
                     [hex(a) for a in result]))
         result += c
         if len(result) > skip and result[-LEN_EOL:] == EOL:
             break
     ret = bytes(result)
     _LOGGER.debug('Received "%s"', ret)
     return ret.decode('ascii')
Example #3
0
    def Send(self, command, flush=True):
        """Sends a command.

    It blocks at most write_timeout seconds.

    Args:
      command: command to send.
      flush: call flush() after write(). Default True.

    Raises:
      SerialTimeoutException if it is timeout and fails to send the command.
      SerialException if it is disconnected during sending.
    """
        try:
            start_time = time.time()
            self._serial.write(command)
            if flush:
                self._serial.flush()
            if self.log:
                duration = time.time() - start_time
                logging.info('Successfully sent %r. Took %.3f seconds',
                             command, duration)
        except serial.SerialTimeoutException:
            error_message = 'Send %r timeout after %.2f seconds' % (
                command, self._serial.getWriteTimeout())
            if self.log:
                logging.warning(error_message)
            raise serial.SerialTimeoutException(error_message)
        except serial.SerialException:
            raise serial.SerialException('Serial disconnected')
Example #4
0
    def readSerial(self):
        cnt = 0
        # read pack head
        while (True):
            tmp = self.ser.read()
            #print(tmp)
            if (tmp == b'\xaa'):
                tmp = self.ser.read()
                if (tmp == b'\x77'):
                    break
            cnt += 1
            if (50 == cnt):
                raise serial.SerialTimeoutException()

        # from here data is to be returned
        tmp = self.ser.read(3)
        ret = [0xaa, 0x77, tmp[0], tmp[1], tmp[2]]
        tmp = self.ser.read(ret[4] + 2)
        for d in tmp:
            ret.append(d)
        crc = self.CRC16_MODBUS(ret[0:-2])
        if ((crc & 0xff == ret[-2]) and ((crc >> 8) & 0xff == ret[-1])):
            return ret[2:-2]
        else:
            # print(ret)
            raise serial.SerialException("data corrupted")
Example #5
0
    def _recv_once(self):
        """Receive once, filter output and update switch state by parsing prompt"""
        # First, call self.readlines().
        # It reads from serial port and gets a list with one line per list item.
        # In each of the list's item, remove any \r or \n, but only at end of line (right strip)
        # For each line of the output, give it to _filter
        # This will filter out switch comments and put them into a separated list
        # Finally, use filter(None, list) to remove empty elements
        coms = []
        try:
            out = filter(None, [
                self._filter(l.rstrip("\r\n"), coms)
                for l in self.sock.readlines()
            ])
        except serial.SerialException:
            logger.error("The switch port seems to be busy. Aborting")
            raise

        # out should never be empty. Otherwise it means we have a problem...
        if not out:
            raise serial.SerialTimeoutException("The read timed out.")

        # However, out may become empty after prompt parsing (prompt will be removed)
        self.state = self._parse_prompt(out)
        if self.state:
            logger.debug("Switch state is: '%s'", self.state.name)
        else:
            logger.error("Switch state is unknown")

        return (out, coms)
Example #6
0
        def _process_request(self, request: str):
            """
            Send data to serial
            :param request: request that is sent ot the Nuvo
            :return: ascii string returned by Nuvo
            """

            # clear the port
            self._port.reset_output_buffer()
            self._port.reset_input_buffer()

            # send request
            #format and send output command
            lineout = "*" + request + "\r"
            self._port.write(lineout.encode())
            self._port.flush()
            _LOGGER.debug('Sending "%s"', lineout)

            # receive response
            result = bytearray()
            while True:
                c = self._port.read(1)
                if c is None:
                    break
                if not c:
                    raise serial.SerialTimeoutException(
                        'Connection timed out! Last received bytes {}'.format([hex(a) for a in result]))
                result += c
                if result [-LEN_EOL:] == EOL:
                    break
            ret = bytes (result)
            _LOGGER.debug('Received "%s"', ret)
            return ret.decode('ascii')
Example #7
0
  def Send(self, command):
    """Sends a command.

    It blocks at most write_timeout seconds.

    Args:
      command: command to send.

    Raises:
      SerialTimeoutException if it is timeout and fails to send the command.
      SerialException if it is disconnected during sending.
    """
    try:
      self._serial.write(command)
      self._serial.flush()
      if self.log:
        logging.info('Successfully sent %r', command)
    except serial.SerialTimeoutException:
      error_message = 'Send %r timeout after %.2f seconds' % (
          command, self._serial.getWriteTimeout())
      if self.log:
        logging.warning(error_message)
      raise serial.SerialTimeoutException(error_message)
    except serial.SerialException:
      raise serial.SerialException('Serial disconnected')
Example #8
0
    def _recv_command(self):
        """Reads a full line from the microcontroller

    We expect to complete a read when this is invoked, so don't invoke unless
    you expect to get data from the microcontroller. we raise a timeout if we
    cannot read a command in the alloted timeout interval."""
        # we rely on the passed-in timeout
        while True:
            c = self._serial.read(1)
            if not c:
                raise serial.SerialTimeoutException(
                    "Couldn't recv command in %d seconds" %
                    self.IO_TIMEOUT_SEC)

            # finished reading an entire COBS structure
            if c == '\x00':
                # grab the data and reset the buffer
                data = self._read_buf[0:self._read_buf_pos]
                self._reset_read_buf()

                # return decoded data
                return cobs.decode(str(bytearray(data)))

            # still got reading to do
            else:
                self._read_buf[self._read_buf_pos] = c
                self._read_buf_pos += 1

                # ugh. buffer overflow. wat do?
                if self._read_buf_pos == len(self._read_buf):
                    # resetting the buffer likely means the next recv will fail, too (we lost the start bits)
                    self._reset_read_buf()
                    raise RuntimeError("IO read buffer overflow :(")
Example #9
0
 def isReady(self):
     self.ser.write(serial.to_bytes(self.setAddrBytes))
     rcv = self.ser.read(7)
     if len(rcv) == 7:
         unpacked = struct.unpack("!7B", rcv)
         if (self.checkChecksum(unpacked)):
             return True
     else:
         raise serial.SerialTimeoutException("Timeout setting address")
Example #10
0
 def readCurrent(self):
     self.ser.write(serial.to_bytes(self.readCurrentBytes))
     rcv = self.ser.read(7)
     if len(rcv) == 7:
         unpaked = struct.unpack("!7B", rcv)
         if (self.checkChecksum(unpacked)):
             current = unpacket[2] + unpacked[3] / 100.0
     else:
         raise serial.SerialTimeoutException("Timeout reading current")
Example #11
0
    def _send_command_raw(self, command, opt=''):
        """
        Description:

            The TV doesn't handle long running connections very well,
            so we open a new connection every time.
            There might be a better way to do this,
            but it's pretty quick and resilient.

        Returns:
            If a value is being requested ( opt2 is "?" ),
            then the return value is returned.
            If a value is being set,
            it returns True for "OK" or False for "ERR"
        """
        # According to the documentation:
        # http://files.sharpusa.com/Downloads/ForHome/
        # HomeEntertainment/LCDTVs/Manuals/tel_man_LC40_46_52_60LE830U.pdf
        # Page 58 - Communication conditions for IP
        # The connection could be lost (but not only after 3 minutes),
        # so we need to the remote commands to be sure about states
        # clear

        self._port.reset_output_buffer()
        self._port.reset_input_buffer()
        # Send command
        if opt != '':
            command += str(opt)
        command = command.ljust(8)+'\r\n'
        command = command.encode('utf-8')
        _LOGGER.debug('*Sending "%s"', command)
        self._port.write(command)
        self._port.flush()
        # receive
        result = bytearray()
        while True:
            char = self._port.read(1)
            if char is None:
                break
            if not char:
                raise serial.SerialTimeoutException(
                    'Connection timed out! Last received bytes {}'
                    .format([hex(a) for a in result]))
            result += char
            if result and result[-1:] == b'\r':
                break
        status = bytes(result).strip().decode("utf-8")
        _LOGGER.debug('*Received "%s"', status)

        if "OK" in status:
            return True
        if "ERR" in status:
            return False
        try:
            return int(status)
        except ValueError:
            return status
Example #12
0
 def readVoltage(self):
     self.ser.write(serial.to_bytes(self.readVoltageBytes))
     rcv = self.ser.read(7)
     if len(rcv) == 7:
         unpacked = struct.unpack("!7B", rcv)
         if (self.checkChecksum(unpacked)):
             tension = unpacked[2] + unpacked[3] / 10.0
             return tension
     else:
         raise serial.SerialTimeoutException("Timeout reading tension")
Example #13
0
 def readPower(self):
     self.ser.write(serial.to_bytes(self.readPowerBytes))
     rcv = self.ser.read(7)
     if len(rcv) == 7:
         unpacked = struct.unpack("!7B", rcv)
         if (self.checkChecksum(unpacked)):
             power = unpacked[1] * 256 + unpacked[2]
             return power
     else:
         raise serial.SerialTimeoutException("Timeout reading power")
def waitForSync():
    """ Waits for the SYNC character from Sparki

        arguments:
        none

        returns:
        nothing
    """
    global serial_conn
    global serial_is_connected

    if not serial_is_connected:
        printDebug("Sparki is not connected - use init()", DEBUG_CRITICAL)
        raise RuntimeError(
            "Attempt to listen for message from Sparki without initialization")

    serial_conn.flushInput()  # get rid of any waiting bytes

    start_time = time.time()

    inByte = -1
    loop_wait = 0
    if platform.system(
    ) == "Darwin":  # Macs seem to be extremely likely to timeout -- this is attempting to deal with that quickly
        retries = 1  # the number of times to retry connecting in the case of a timeout
        loop_wait = 0  # pause this long each time through the loop
    else:
        retries = 5  # the number of times to retry connecting in the case of a timeout
        loop_wait = .01  # pause this long each time through the loop

    while inByte != SYNC.encode(
    ):  # loop, doing nothing substantive, while we wait for SYNC
        if time.time() > start_time + (CONN_TIMEOUT * retries):
            if platform.system(
            ) == "Darwin":  # Macs seem to be extremely likely to timeout -- so we report at a different debug level
                printDebug(
                    "In waitForSync, unable to sync with Sparki (this may not be due to power saving settings)",
                    DEBUG_INFO)
            else:
                printDebug("In waitForSync, unable to sync with Sparki",
                           DEBUG_ERROR)
            raise serial.SerialTimeoutException(
                "Unable to sync with Sparki -- may be temporary error due to power saving"
            )

        try:
            inByte = serial_conn.read()
        except serial.SerialTimeoutException:
            printDebug(
                "SerialTimeoutException caught in waitForSync, unable to sync with Sparki",
                DEBUG_ERROR)
            raise

        time.sleep(loop_wait)
Example #15
0
 def readEnergy(self):
     self.ser.write(serial.to_bytes(self.readEnergyBytes))
     rcv = self.ser.read(7)
     if len(rcv) == 7:
         unpacked = struct.unpack("!7B", rcv)
         if (self.checkChecksum(unpacked)):
             energy = unpacked[1] * 256 * 256 + unpacked[
                 2] * 256 + unpacked[3]
             return energy
     else:
         raise serial.SerialTimeoutException(
             "Timeout reading registered power")
Example #16
0
    def _recv_once_retry(self):
        """Try to receive once, and retries with increasing timeout if it fails"""
        for _ in range(config.READ_RETRIES + 1):
            try:
                return self._recv_once()
            except serial.SerialTimeoutException:
                logger.error("Read failed with timeout %fs. Will retry...",
                             self.sock.timeout)
                self.sock.timeout = self.sock.timeout * 2

        msg = "All read attempts timed out. Is the switch dead or the port already busy?"
        logger.error(msg)
        raise serial.SerialTimeoutException(msg)
    def readAll(self):
        """Returns all values (voltage, current, wattage, watt hours)

    Raises:
        serial.SerialTimeoutException: Timeout on PZEM connection

    Returns:
        tuple: All values (voltage, current, wattage, watt hours)
    """
        if self.isReady():
            return (self.readVoltage(), self.readCurrent(), self.readWattage(),
                    self.readWattHours())

        raise serial.SerialTimeoutException("Timeout reading registered power")
Example #18
0
 def _query(self, cmd):
     """tx/rx to/from PS"""
     self._debug("PPS <- %s<CR>\n" % cmd)
     self._serial.write((cmd + "\r").encode())
     b = []
     self._debug("PPS -> ")
     while True:
         b.append(self._serial.read(1))
         self._debug(b[-1].replace(b"\r", b"<CR>").decode())
         if b[-1] == "":
             raise serial.SerialTimeoutException()
         if b"".join(b[-3:]) == b"OK\r":
             break
     self._debug("\n")
     return (b"".join(b[:-4])).decode()
Example #19
0
        def _read(self, skip=0):
            result = bytearray()
            while True:
                c = self._port.read(1)
                if not c:
                    raise serial.SerialTimeoutException(
                        'Connection timed out! Last received bytes {}'.format(
                            [hex(a) for a in result]))
                result += c
                if len(result) > skip and result[-LEN_EOL:] == EOL:
                    result = result[:-LEN_EOL]  # strip off end of line
                    break

            ret = bytes(result).decode(ENCODING)
            LOG.debug(f"Received: {ret}")
            return ret
        def _process_request(self, request: bytes, skip=0):
            """
            Send data to socket
            :param request: request that is sent to the blackbird
            :param skip: number of bytes to skip for end of transmission decoding
            :return: ascii string returned by blackbird
            """
            _LOGGER.debug('Sending "%s"', request)

            if use_serial:
                # clear
                self._port.reset_output_buffer()
                self._port.reset_input_buffer()
                # send
                self._port.write(request)
                self._port.flush()
                # receive
                result = bytearray()
                while True:
                    c = self._port.read(1)
                    if c is None:
                        break
                    if not c:
                        raise serial.SerialTimeoutException(
                            'Connection timed out! Last received bytes {}'.
                            format([hex(a) for a in result]))
                    result += c
                    if len(result) > skip and result[-LEN_EOL:] == EOL:
                        break
                ret = bytes(result)
                _LOGGER.debug('Received "%s"', ret)
                return ret.decode('ascii')

            else:
                self.socket.send(request)

                response = ''

                while True:

                    data = self.socket.recv(SOCKET_RECV)
                    response += data.decode('ascii')

                    if EOL in data and len(response) > skip:
                        break

                return response
Example #21
0
 def _query(self, cmd):
     """
     tx/rx to/from PS
     """
     if self._debug: _pps_debug("PPS <- %s<CR>\n" % cmd)
     self._Serial.write((cmd + "\r").encode())
     b = []
     if self._debug: _pps_debug("PPS -> ")
     while True:
         b.append(self._Serial.read(1))
         if self._debug: _pps_debug(b[-1].replace(b'\r', b'<CR>').decode())
         if b[-1] == "":
             raise serial.SerialTimeoutException()
         if b[-3:] == [bytes(c, encoding="ASCII") for c in "OK\r"]:
             break
     if self._debug: _pps_debug('\n')
     return (b"".join(b[:-4])).decode()
    def isReady(self):
        """Checks whether the PZEM is ready to return data

    Raises:
        serial.SerialTimeoutException: Timeout on PZEM connection

    Returns:
        bool: Whether the PZEM is ready or not
    """
        self.ser.write(serial.to_bytes(self.setAddrBytes))
        rcv = self.ser.read(7)
        if len(rcv) == 7:
            unpacked = unpack("!7B", rcv)
            if self.checkChecksum(unpacked):
                return True

        raise serial.SerialTimeoutException("Timeout setting address")
Example #23
0
def recv_command():
    global receive_pos
    while True:
        c = serial_port.read(1)
        if not c:
            raise serial.SerialTimeoutException(
                "Couldn't recv command in %d seconds" % IO_TIMEOUT_SEC)

        if c == '\r':
            # End of packet.
            data = str(bytearray(receive_buf[0:receive_pos]))
            reset_receive_buf()

            # Ignore short packets.
            if len(data) <= 8:
                print "Short packet"
                continue

            # Verify checksum.
            sum = data[-8:]
            data = data[:-8]
            checksum = binascii.crc32(data) & 0xFFFFFFFF
            if sum[0] != chr(97 + (checksum >> 28 & 0xf)) or \
               sum[1] != chr(97 + (checksum >> 24 & 0xf)) or \
               sum[2] != chr(97 + (checksum >> 20 & 0xf)) or \
               sum[3] != chr(97 + (checksum >> 16 & 0xf)) or \
               sum[4] != chr(97 + (checksum >> 12 & 0xf)) or \
               sum[5] != chr(97 + (checksum >> 8 & 0xf)) or \
               sum[6] != chr(97 + (checksum >> 4 & 0xf)) or \
               sum[7] != chr(97 + (checksum & 0xf)):
                print "Bad checksum:", sum
                continue

            # Return received data.
            #print repr(data)
            return data

        #print "'" + c + "'"
        receive_buf[receive_pos] = c
        receive_pos += 1

        if receive_pos == len(receive_buf):
            # Buffer overflow.
            reset_receive_buf()
            raise RuntimeError("IO read buffer overflow")
Example #24
0
    def SendReceive(self,
                    command,
                    size=1,
                    retry=0,
                    interval_secs=None,
                    suppress_log=False):
        """Sends a command and returns a N bytes response.

    Args:
      command: command to send
      size: number of bytes to receive. 0 means receiving what already in the
          input buffer.
      retry: number of retry.
      interval_secs: #seconds to wait between send and receive. If specified,
          overrides self.send_receive_interval_secs.
      suppress_log: True to disable log regardless of self.log value.

    Returns:
      Received N bytes.

    Raises:
      SerialTimeoutException if it fails to receive N bytes.
    """
        for nth_run in range(retry + 1):
            self.FlushBuffer()
            try:
                self.Send(command)
                if interval_secs is None:
                    time.sleep(self.send_receive_interval_secs)
                else:
                    time.sleep(interval_secs)
                response = self.Receive(size)
                if not suppress_log and self.log:
                    logging.info('Successfully sent %r and received %r',
                                 command, response)
                return response
            except serial.SerialTimeoutException:
                if nth_run < retry:
                    time.sleep(self.retry_interval_secs)

        error_message = 'Timeout receiving %d bytes for command %r' % (size,
                                                                       command)
        if not suppress_log and self.log:
            logging.warning(error_message)
        raise serial.SerialTimeoutException(error_message)
Example #25
0
 def wait_for(self, msg, timeout=0) -> str:
     """
     Wait for a specific message response for a specific amount of time.
     msg: String message to wait for (potentially as part of larger output).
     timeout: int number of seconds to wait for.
     Returns full received buffer as a str.
     """
     start = time.time()
     buffer = ''
     if timeout == 0:
         timeout = self.default_timeout
     while time.time() - start < timeout:
         if self.cnxn.in_waiting > 0:
             buffer += self.cnxn.read().decode(self.encoding)
             if msg in buffer:
                 return buffer
     raise serial.SerialTimeoutException(
         'Device timed out waiting for msg: {!r}'.format(msg))
    def readVoltage(self):
        """Read the voltage from the PZEM

    Raises:
        serial.SerialTimeoutException: Timeout on PZEM connection

    Returns:
        float: Voltage (V) as float
    """
        self.ser.write(serial.to_bytes(self.readVoltageBytes))
        rcv = self.ser.read(7)
        if len(rcv) == 7:
            unpacked = unpack("!7B", rcv)
            if self.checkChecksum(unpacked):
                tension = unpacked[2] + unpacked[3] / 10.0
                return tension

        raise serial.SerialTimeoutException("Timeout reading tension")
    def readCurrent(self):
        """Read the current from the PZEM

    Raises:
        serial.SerialTimeoutException: Timeout on PZEM connection

    Returns:
        float: Current (A) as float
    """
        self.ser.write(serial.to_bytes(self.readCurrentBytes))
        rcv = self.ser.read(7)
        if len(rcv) == 7:
            unpacked = unpack("!7B", rcv)
            if self.checkChecksum(unpacked):
                current = unpacked[2] + unpacked[3] / 100.0
                return current

        raise serial.SerialTimeoutException("Timeout reading current")
    def readWattage(self):
        """Read the wattage from the PZEM

    Raises:
        serial.SerialTimeoutException: Timeout on PZEM connection

    Returns:
        int: Wattage (W) as int
    """
        self.ser.write(serial.to_bytes(self.readWattageBytes))
        rcv = self.ser.read(7)
        if len(rcv) == 7:
            unpacked = unpack("!7B", rcv)
            if self.checkChecksum(unpacked):
                power = unpacked[1] * 256 + unpacked[2]
                return power

        raise serial.SerialTimeoutException("Timeout reading power")
Example #29
0
    def _query(self, cmd):
        """
        tx/rx to/from PS
        """
        if self._debug: _pps_debug("PPS <- %s<CR>\n" % cmd)
        self._Serial.write((cmd + '\r').encode())

        b = []
        if self._debug: _pps_debug("PPS -> ")
        while True:
            b.append(self._Serial.read(1).decode('utf-8'))
            if self._debug: _pps_debug(b[-1].replace('\r', '<CR>'))
            if b[-1] == "":
                raise serial.SerialTimeoutException()
            if b[-3:] == list("OK\r"):
                break
        if self._debug: _pps_debug('\n')
        return "".join(b[:-4])
    def readWattHours(self):
        """Reads the stored watt hours from the PZEM

    Raises:
        serial.SerialTimeoutException: Timeout on PZEM connection

    Returns:
        int: Watt Hours (Wh) as int
    """
        self.ser.write(serial.to_bytes(self.readWattHourBytes))
        rcv = self.ser.read(7)
        if len(rcv) == 7:
            unpacked = unpack("!7B", rcv)
            if self.checkChecksum(unpacked):
                regPower = unpacked[1] * 256 * 256 + unpacked[
                    2] * 256 + unpacked[3]
                return regPower

        raise serial.SerialTimeoutException("Timeout reading registered power")