Пример #1
0
    def _check_ack(self, message, check_ACK=False):
        function_code = message.get_function()

        if function_code == 0x15:  # NAK
            raise CommunicationError('Received a NAK')

        if check_ACK == True and function_code != 0x06:  # ACK
            raise CommunicationError('Received NOT a ACK')
Пример #2
0
    def _read_response(self, command: Command):

        try:
            # Read exactly one byte. This is the verification of the cesar unit
            # its either ACK (0x06) or NACK (0x15)
            verification = self._transport.read(1)

            self._logger.debug(
                "Received ACK/NAK byte: {}".format(verification))

            if verification == self.ACK:
                pass
            elif verification == self.NAK:
                raise CommunicationError("Device returned NAK")

            # in fact, we can compute how long the response will be, based on the first two bytes read
            # but this works for us and we dont care about more details...
            raw_response = self._transport.read(self.RESPONSE_MAX_LENGTH)
            self._logger.debug("Received {}".format(" ".join(
                map(hex, raw_response))))

            # Now send back a ACK since we got our data, even if the data is not valid
            # We just don't care about this. If the data is not valid, we throw an exception
            # and the calling api will re-engage into sending the message
            self._transport.write(bytearray([self.ACK]))
            self._logger.debug("Sent ACK to device")

        except SerialTimeoutException:
            raise CommunicationError("Could not read response. Timeout")

        raw_response = bytearray(raw_response)

        msg = MessagePacket.from_raw(raw_response)

        if not msg.is_valid():
            raise CommunicationError("Received response is not valid")

        response = Response(command.get_outputs())

        # we received not the same amount of data than expected. This occurs only in two cases:
        # 1. The protocol was not correctly specified by the user
        # 2. The device returns just an CSR code instead of the data
        if command.get_expected_response_data_length() != msg.get_data_length(
        ):
            # This is then the case 2
            if msg.get_data_length() == 1:
                response.get_csr().set_raw(msg.get_data())
            else:
                raise CommunicationError(
                    "Received an unexpected amount of data ({} bytes) from device. Expected {} bytes (excluding CSR)"
                    .format(msg.get_data_length,
                            command.get_expected_response_data_length()))
        else:
            # Here we just assign the data to the correct output
            self._assign_data(msg.get_data(), command.get_outputs())

        return response
    def is_acknowledged(self):
        response = self.get_response()

        if self.is_nack(response):
            raise CommunicationError(
                "Acknowledgement error! Negative Acknowledgement received")

        if not self.is_ack(response):
            raise CommunicationError(
                "Acknowledgement error! No acknowledgement was sent back from gauge"
            )
Пример #4
0
    def _read_response(self, msg):
        assert isinstance(msg, AbstractMessage)

        frames = self._read_response_frames()
        responses = []
        resp_class = msg.get_response_class()

        for frame in frames:

            # We received an invalid frame. This can mean the following:
            #   1. the relay did not produce a correct message
            #   2. we got some bit errors on the transmission process
            #
            # However, one invalid frame means that we cant trust any other frame.
            if not frame.is_valid():
                self._logger.error("Received an invalid frame: {}", frame)
                raise CommunicationError("Received an invalid frame")

            message = Message()
            message.set_frame(frame)

            # create the response from the message. the response class is derived from the message which was
            # sent to the relay card. Every message has a corresponding response.
            response = resp_class(message)

            # only add valid responses, and discard 'relayed messages'
            #
            # A relayed message can appear in the following case:
            #   Any cmd is sent to a non-existing relay (eg. address not existing), the
            #   cmd will be forwarded to the next relay until the last relay in the chain reads it.
            #   This relay will then just send the cmd back to the controlling pc.
            if response.is_valid():
                responses.append(response)
            else:
                self._logger.debug(
                    "Got invalid response '{}' of type {}".format(
                        response, resp_class.__name__))

        # At least one response has to be valid. Note that not all responses are necessary valid.
        #
        #
        # Note: An invalid response is not the same as an invalid frame.
        # Invalid frame: the byte representation is not correct
        # Invalid response: We received a correct frame, but the content (e.g. command id) is unexpected or unknown.
        #
        # Consider for example the Setup message. The last response will be a relayed message, thus being invalid.
        # If we get only invalid messages, raise this exception.
        if len(responses) == 0:
            raise CommunicationError("Received no valid response")

        return Responses(responses)
Пример #5
0
 def _read_response(self, transport):
     try:
         resp = list(transport.read_bytes(5))
         self.logger.debug('Received message: %s', repr(map(hex, resp)))
         return resp
     except slave.transport.Timeout:
         raise CommunicationError('Timeout while receive response')
Пример #6
0
 def get_response(self, transport):
     try:
         raw = transport.read_until(RawMessage.TERMINATOR)
         return "".join([chr(x) for x in raw]) + RawMessage.TERMINATOR
     except slave.transport.Timeout:
         raise CommunicationError(
             "Received a timeout while reading response")
Пример #7
0
    def query(self, transport, message):
        with InterProcessTransportLock(transport):
            self.send_message(transport, message)

            length = message.response_length()
            raw_response = transport.read_bytes(length)

            self.logger.debug('Recevied response (%s bytes): "%s"',
                              str(length), " ".join(map(hex, raw_response)))

            response_as_hex = []

            for i in range(0, length):
                response_as_hex.append(raw_response[i])

            response = message.create_response(response_as_hex)

            if not response.is_valid_crc():
                raise CommunicationError(
                    'Received an invalid response packet. CRC dismatch.')

            if response.is_nack():
                self.logger.warning('Received a NAK Response')

            return response
Пример #8
0
 def _send_message(self, message):
     try:
         raw_message = message + "\r"
         self._logger.debug("Sending message %s", repr(message))
         self._transport.write(raw_message)
     except SerialTimeoutException:
         self._logger.exception("Error while sending message")
         raise CommunicationError("Could not send message. timeout")
Пример #9
0
 def read_response(self):
     try:
         # remove the last two bytes since they are just \r\n
         resp = self._transport.read_until("\r\n")[0:-2]
         self._logger.debug('Response: "%s"', repr(resp))
         return resp
     except:
         raise CommunicationError("Could not read response")
Пример #10
0
 def _receive_message(self):
     try:
         msg = self._transport.read_until("\r\n")
         self._logger.debug("Received message %s", repr(msg))
         return "".join(map(chr, msg))
     except SerialTimeoutException:
         self._logger.exception("Error while receiving message")
         raise CommunicationError("Could not receive message. Timeout")
Пример #11
0
 def read_response(self, transport):
     with InterProcessTransportLock(transport):
         try:
             resp = transport.read_exactly(21)
             self.logger.debug('Received response: "%s"', repr(resp))
             return resp
         except slave.transport.Timeout:
             raise CommunicationError("Could not read response")
Пример #12
0
 def get_response(self):
     try:
         resp = self._transport.read_until(
             self.responseTerminal.encode(self.encoding))
         self._logger.debug("Received {}".format(repr(resp)))
         # now remove the response terminal
         return resp[:-len(self.responseTerminal)]
     except SerialTimeoutException:
         raise CommunicationError("Received a timeout")
Пример #13
0
    def _read_response(self):
        raw_response = self._transport.read_until(AsciiMessage.END)
        self._logger.debug("Received message '{}'".format(repr(raw_response)))
        response = AsciiResponse.from_raw(raw_response)

        if response.get_cmd() == '???':
            raise CommunicationError(
                "Unknown message send to device. Device did not understand.")

        return response
 def read_response(self, transport):
     try:
         response = transport.read_until(Message.ETX)
         ret = []
         for chunk in response:
             ret.append(chr(chunk))
         ret.append(Message.ETX)
         return ret
     except:
         raise CommunicationError("Could not read response")
    def query(self, transport, message):
        with InterProcessTransportLock(transport):
            if not isinstance(message, AbstractMessage):
                raise TypeError(
                    "message must be an instance of AbstractMessage")

            msg = message.get_message()
            msg.set_address(self.receiver)
            msg.set_checksum(msg.compute_checksum())

            self.send_message(transport, msg)
            response = self.read_response(transport)

            resp = message.create_response(response)

            if not resp.is_valid():
                self.logger.error("Received invalid response: %s", resp)
                raise CommunicationError("Invalid response")

            if not resp.is_successful():
                self.logger.warning("Action (%s) was not successful: %s",
                                    message, resp)

            return resp
Пример #16
0
 def check_checksum(self, message):
     if message.compute_checksum() != message.get_checksum():
         raise CommunicationError('Received an invalid checksum')
Пример #17
0
 def _send_raw(self, transport, data):
     try:
         self.logger.debug('Sending message: %s', repr(data))
         transport.write(data)
     except slave.transport.Timeout:
         raise CommunicationError('Timeout while sending message %s' % repr(data))
Пример #18
0
 def send_message(self, raw_data):
     try:
         self._logger.debug('Sending: "%s"', repr(raw_data))
         self._transport.write(raw_data)
     except:
         raise CommunicationError("Could not send data")