def read
      buffer = []

      loop do
        char = @serial.getbyte
        fail(ReadTimeout) if char.nil?

        buffer << char

        fail(BadPacket, 'invalid header') if buffer.size == 2 && buffer != [0xA5, 0xA5]

        break if buffer[-2, 2] == [0x0A, 0x0D]

        fail(BadPacket, 'packet too big') if buffer.size > 256
      end

      header = [buffer.shift, buffer.shift]
      fail(BadPacket, 'invalid header') unless header == [0xA5, 0xA5]

      src = buffer.shift
      dst = buffer.shift

      ctrl = buffer.shift
      func = buffer.shift

      size = buffer.shift

      # TODO: My unit seems to return the wrong size here (Maybe we should have an option if not all units do this)
      size -= 2 if [ctrl, func] == Jfy::Codes::QUERY_SET_INFO_RESP

      data = buffer.take(size)
      buffer = buffer.drop(size)

      checksum = [buffer.shift, buffer.shift]
      ender = [buffer.shift, buffer.shift]

      packet = Packet.new([ctrl, func], data, :src => src, :dst => dst)
      p packet if @debug

      fail(BadPacket, 'invalid checksum') if checksum != packet.checksum &&
                                             [ctrl, func] != Jfy::Codes::QUERY_SET_INFO_RESP

      fail(BadPacket, 'invalid ender') unless ender == [0x0A, 0x0D]

      packet
    end
def read
      buffer = []

      loop do
        char = @serial.getbyte
        fail(ReadTimeout) if char.nil?

        buffer << char

        fail(BadPacket, 'invalid header') if buffer.size == 2 && buffer != [0xA5, 0xA5]

        break if buffer[-2, 2] == [0x0A, 0x0D]

        fail(BadPacket, 'packet too big') if buffer.size > 256
      end

      header = [buffer.shift, buffer.shift]
      fail(BadPacket, 'invalid header') unless header == [0xA5, 0xA5]

      src = buffer.shift
      dst = buffer.shift

      ctrl = buffer.shift
      func = buffer.shift

      size = buffer.shift

      # TODO: My unit seems to return the wrong size here (Maybe we should have an option if not all units do this)
      size -= 2 if [ctrl, func] == Jfy::Codes::QUERY_SET_INFO_RESP

      data = buffer.take(size)
      buffer = buffer.drop(size)

      checksum = [buffer.shift, buffer.shift]
      ender = [buffer.shift, buffer.shift]

      packet = Packet.new([ctrl, func], data, :src => src, :dst => dst)
      p packet if @debug

      fail(BadPacket, 'invalid checksum') if checksum != packet.checksum &&
                                             [ctrl, func] != Jfy::Codes::QUERY_SET_INFO_RESP

      fail(BadPacket, 'invalid ender') unless ender == [0x0A, 0x0D]

      packet
    end
rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity