=== pymycobot 4.0.4 generate.py (send_angles)
    def send_angles(self, angles, speed, _async=False):
        """Send the angles of all joints to robot arm.

        Args:
            angles: a list of angle values(List[float]). len 6.
            speed : (int) 1 ~ 100
        """
        self.calibration_parameters(class_name=self.__class__.__name__, angles=angles, speed=speed)
        angles = [self._angle2int(angle) for angle in angles]
        return self._mesg(ProtocolCode.SEND_ANGLES, angles, speed, has_reply=True, _async=_async)

=== pymycobot 4.0.4 mycobot.py (MyCobot._mesg / _res)
    def _mesg(self, genre, *args, **kwargs):
        """

        Args:
            genre: command type (Command)
            *args: other data.
                   It is converted to octal by default.
                   If the data needs to be encapsulated into hexadecimal,
                   the array is used to include them. (Data cannot be nested)
            **kwargs: support `has_reply`
                has_reply: Whether there is a return value to accept.
        """
        real_command, has_reply, _async = super(
            MyCobot, self)._mesg(genre, *args, **kwargs)
        if self.thread_lock:
            with self.lock:
                return self._res(real_command, has_reply, genre)
        else:
            return self._res(real_command, has_reply, genre)
            
    def _res(self, real_command, has_reply, genre):
        try_count = 0
        while try_count < 3:
            self._write(self._flatten(real_command))
            data = self._read(genre)
            if data is not None and data != b'':
                break
            try_count += 1
        else:
            return -1

=== pymycobot 4.0.4 common.py (read の待ち時間)
def read(self, genre, method=None, command=None, _class=None, timeout=None, real_command=None):
    datas = b""
    data_len = -1
    k = 0
    pre = 0
    t = time.time()
    if platform.system() == "Windows":
        wait_time = 0.15
    else:
        wait_time = 0.5
    if method is not None:
        wait_time = 0.3
    if timeout is not None:
        wait_time = timeout

=== pymycobot 2.9.6 generate.py (send_angles)
    def send_angles(self, degrees, speed):
        """Send the degrees of all joints to robot arm.

        Args:
            degrees: a list of degree values(List[float]).\n
                        for mycobot: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0].\n
                        for mypalletizer: [0.0, 0.0, 0.0, 0.0]
                        for mypalletizer 340: [0.0, 0.0, 0.0]
            speed : (int) 0 ~ 100
        """
        # self.calibration_parameters(degrees=degrees, speed=speed)
        degrees = [self._angle2int(degree) for degree in degrees]
        return self._mesg(ProtocolCode.SEND_ANGLES, degrees, speed)

=== pymycobot 2.9.6 mycobot.py (_mesg)
    def _mesg(self, genre, *args, **kwargs):
        """

        Args:
            genre: command type (Command)
            *args: other data.
                   It is converted to octal by default.
                   If the data needs to be encapsulated into hexadecimal,
                   the array is used to include them. (Data cannot be nested)
            **kwargs: support `has_reply`
                has_reply: Whether there is a return value to accept.
        """
        real_command, has_reply = super(
            MyCobot, self)._mesg(genre, *args, **kwargs)
        self._write(self._flatten(real_command))

        if has_reply:
            data = self._read(genre)
            if genre == ProtocolCode.SET_SSID_PWD:
                return None
            res = self._process_received(data, genre)

=== pymycobot 2.9.6 common.py (read の待ち時間)
def read(self, genre):
    datas = b""
    data_len = -1
    k = 0
    pre = 0
    t = time.time()
    wait_time = 0.1
    if genre == ProtocolCode.GET_SSID_PWD:
        time.sleep(0.1)
        if self._serial_port.inWaiting()>0:
            datas = self._serial_port.read(self._serial_port.inWaiting())
        return datas
    elif genre == ProtocolCode.GET_ACCEI_DATA:
        wait_time = 1
    while True and time.time() - t < wait_time: 
        data = self._serial_port.read()

=== pymycobot 2.9.6 generate.py (jog_angle / jog_stop)
    def jog_angle(self, joint_id, direction, speed):
        """Jog control angle.

        Args:
            joint_id: int
                    For mycobot: int 1-6.\n
                    For mypalletizer: int 1-4.
                    For mypalletizer 340: int 1-3.
            direction: 0 - decrease, 1 - increase
            speed: int (0 - 100)
        """
        return self._mesg(ProtocolCode.JOG_ANGLE, joint_id, direction, speed)

    def jog_stop(self):
        """Stop jog moving"""
        return self._mesg(ProtocolCode.JOG_STOP)
