# This file is autogenerated. Please do not edit
import struct
from .tcp_client import TcpClientBase

class TcpClientV1(TcpClientBase):
    protocol_version = 1
    def motion_input(self, surge_motion_input, sway_motion_input, heave_motion_input, yaw_motion_input, slow_input, boost_input):
        """Send a motion_input command over TCP

        Args:
            surge_motion_input (numpy data type:<f4): valid range is <-1, 1> 
            sway_motion_input (numpy data type:<f4): valid range is <-1, 1> 
            heave_motion_input (numpy data type:<f4): valid range is <-1, 1> 
            yaw_motion_input (numpy data type:<f4): valid range is <-1, 1> 
            slow_input (numpy data type:<f4): valid range is <0, 1> 
            boost_input (numpy data type:<f4): valid range is <0, 1> 
        """
        if not -1 <= surge_motion_input <= 1:
            raise ValueError(
                "Input argument out of range:" +
                " valid range for surge_motion_input is" +
                " <{lower_limit}, {upper_limit}>".format(lower_limit=-1, upper_limit=1) +
                " but got value: {name}".format(name=surge_motion_input))

        if not -1 <= sway_motion_input <= 1:
            raise ValueError(
                "Input argument out of range:" +
                " valid range for sway_motion_input is" +
                " <{lower_limit}, {upper_limit}>".format(lower_limit=-1, upper_limit=1) +
                " but got value: {name}".format(name=sway_motion_input))

        if not -1 <= heave_motion_input <= 1:
            raise ValueError(
                "Input argument out of range:" +
                " valid range for heave_motion_input is" +
                " <{lower_limit}, {upper_limit}>".format(lower_limit=-1, upper_limit=1) +
                " but got value: {name}".format(name=heave_motion_input))

        if not -1 <= yaw_motion_input <= 1:
            raise ValueError(
                "Input argument out of range:" +
                " valid range for yaw_motion_input is" +
                " <{lower_limit}, {upper_limit}>".format(lower_limit=-1, upper_limit=1) +
                " but got value: {name}".format(name=yaw_motion_input))

        if not 0 <= slow_input <= 1:
            raise ValueError(
                "Input argument out of range:" +
                " valid range for slow_input is" +
                " <{lower_limit}, {upper_limit}>".format(lower_limit=0, upper_limit=1) +
                " but got value: {name}".format(name=slow_input))

        if not 0 <= boost_input <= 1:
            raise ValueError(
                "Input argument out of range:" +
                " valid range for boost_input is" +
                " <{lower_limit}, {upper_limit}>".format(lower_limit=0, upper_limit=1) +
                " but got value: {name}".format(name=boost_input))

        command_identifier = b'j'
        msg = command_identifier
        msg += struct.pack('ffffff', surge_motion_input, sway_motion_input, heave_motion_input, yaw_motion_input, slow_input, boost_input)
        self.send_and_receive(msg, expects_reply=False)

    def set_lights(self, brightness_upper, brightness_lower):
        """Send a set_lights command over TCP

        Args:
            brightness_upper (numpy data type:<u1): valid range is <0, 255> 
            brightness_lower (numpy data type:<u1): valid range is <0, 255> 
        """
        if not 0 <= brightness_upper <= 255:
            raise ValueError(
                "Input argument out of range:" +
                " valid range for brightness_upper is" +
                " <{lower_limit}, {upper_limit}>".format(lower_limit=0, upper_limit=255) +
                " but got value: {name}".format(name=brightness_upper))

        if not 0 <= brightness_lower <= 255:
            raise ValueError(
                "Input argument out of range:" +
                " valid range for brightness_lower is" +
                " <{lower_limit}, {upper_limit}>".format(lower_limit=0, upper_limit=255) +
                " but got value: {name}".format(name=brightness_lower))

        command_identifier = b'l'
        msg = command_identifier
        msg += struct.pack('BB', brightness_upper, brightness_lower)
        self.send_and_receive(msg, expects_reply=False)

    def ping(self):
        """Send a ping command over TCP
        """
        command_identifier = b'p'
        msg = command_identifier
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=1)
        self.check_reply(reply, b'P')

    def start_recording(self):
        """Send a start_recording command over TCP
        """
        command_identifier = b'r'
        msg = command_identifier
        self.send_and_receive(msg, expects_reply=False)

    def stop_recording(self):
        """Send a stop_recording command over TCP
        """
        command_identifier = b'R'
        msg = command_identifier
        self.send_and_receive(msg, expects_reply=False)

    def start_compass_calibration(self):
        """Send a start_compass_calibration command over TCP
        """
        command_identifier = b'i'
        msg = command_identifier
        self.send_and_receive(msg, expects_reply=False)

    def cancel_compass_calibration(self):
        """Send a cancel_compass_calibration command over TCP
        """
        command_identifier = b'I'
        msg = command_identifier
        self.send_and_receive(msg, expects_reply=False)

    def save_compass_calibration(self):
        """Send a save_compass_calibration command over TCP
        """
        command_identifier = b'c'
        msg = command_identifier
        self.send_and_receive(msg, expects_reply=False)

    def user_geo_location(self, longitude, latitude):
        """Send a user_geo_location command over TCP

        Args:
            longitude (numpy data type:<f8): longitude that is included in the log file in degrees
            latitude (numpy data type:<f8): latitude that is included in the log file in degrees
        """
        command_identifier = b'g'
        msg = command_identifier
        msg += struct.pack('dd', longitude, latitude)
        self.send_and_receive(msg, expects_reply=False)

    def watchdog(self, connection_duration):
        """Send a watchdog command over TCP

        Args:
            connection_duration (numpy data type:<i2): time in seconds since connected to drone
        """
        command_identifier = b'w'
        msg = command_identifier
        msg += struct.pack('h', connection_duration)
        self.send_and_receive(msg, expects_reply=False)

    def auto_heading_on(self):
        """Send a auto_heading_on command over TCP
        """
        command_identifier = b'h'
        msg = command_identifier
        self.send_and_receive(msg, expects_reply=False)

    def auto_heading_off(self):
        """Send a auto_heading_off command over TCP
        """
        command_identifier = b'H'
        msg = command_identifier
        self.send_and_receive(msg, expects_reply=False)

    def auto_depth_on(self):
        """Send a auto_depth_on command over TCP
        """
        command_identifier = b'd'
        msg = command_identifier
        self.send_and_receive(msg, expects_reply=False)

    def auto_depth_off(self):
        """Send a auto_depth_off command over TCP
        """
        command_identifier = b'D'
        msg = command_identifier
        self.send_and_receive(msg, expects_reply=False)

    def set_system_time(self, unix_timestamp):
        """Send a set_system_time command over TCP

        set the system time on the on-board computer

        Args:
            unix_timestamp (numpy data type:<i4): 
        """
        command_identifier = b't'
        msg = command_identifier
        msg += struct.pack('i', unix_timestamp)
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=1)
        self.check_reply(reply, b'a')

    def set_camera_exposure(self, exposure_value):
        """Send a set_camera_exposure command over TCP

        Args:
            exposure_value (numpy data type:<i4): 1 = 1/1000th of a second, 5 = 1/200th of a second. Valid values are in the range <1, 5000>
        """
        command_identifier = b've'
        msg = command_identifier
        msg += struct.pack('i', exposure_value)
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=1)
        self.check_reply(reply, b'a')

    def set_camera_whitebalance(self, whitebalance_value):
        """Send a set_camera_whitebalance command over TCP

        Args:
            whitebalance_value (numpy data type:<i4): valid values are in the range <2800, 9300>
        """
        command_identifier = b'vw'
        msg = command_identifier
        msg += struct.pack('i', whitebalance_value)
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=1)
        self.check_reply(reply, b'a')

    def set_camera_hue(self, hue_value):
        """Send a set_camera_hue command over TCP

        Args:
            hue_value (numpy data type:<i4): valid values are in the range <-40, 40>
        """
        command_identifier = b'vh'
        msg = command_identifier
        msg += struct.pack('i', hue_value)
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=1)
        self.check_reply(reply, b'a')

    def set_camera_bitrate(self, bitrate_value):
        """Send a set_camera_bitrate command over TCP

        Args:
            bitrate_value (numpy data type:<i4): set camera bitrate in bits. Valid values are in range <1 000 000, 16 000 000> 
        """
        command_identifier = b'vb'
        msg = command_identifier
        msg += struct.pack('i', bitrate_value)
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=1)
        self.check_reply(reply, b'a')

    def get_camera_parameters(self):
        """Send a get_camera_parameters command over TCP

        Returns:
            parameter (numtyp data type:<u1)
            camera_bitrate (numtyp data type:<i4)
            camera_exposure (numtyp data type:<i4)
            camera_whitebalance (numtyp data type:<i4)
            camera_hue (numtyp data type:<i4)
        """
        command_identifier = b'Va'
        msg = command_identifier
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=17)
        return struct.unpack('<Biiii', reply)


class TcpClientV2(TcpClientBase):
    protocol_version = 2
    def motion_input(self, surge_motion_input, sway_motion_input, heave_motion_input, yaw_motion_input, slow_input, boost_input):
        """Send a motion_input command over TCP

        Args:
            surge_motion_input (numpy data type:<f4): valid range is <-1, 1> 
            sway_motion_input (numpy data type:<f4): valid range is <-1, 1> 
            heave_motion_input (numpy data type:<f4): valid range is <-1, 1> 
            yaw_motion_input (numpy data type:<f4): valid range is <-1, 1> 
            slow_input (numpy data type:<f4): valid range is <0, 1> 
            boost_input (numpy data type:<f4): valid range is <0, 1> 
        """
        if not -1 <= surge_motion_input <= 1:
            raise ValueError(
                "Input argument out of range:" +
                " valid range for surge_motion_input is" +
                " <{lower_limit}, {upper_limit}>".format(lower_limit=-1, upper_limit=1) +
                " but got value: {name}".format(name=surge_motion_input))

        if not -1 <= sway_motion_input <= 1:
            raise ValueError(
                "Input argument out of range:" +
                " valid range for sway_motion_input is" +
                " <{lower_limit}, {upper_limit}>".format(lower_limit=-1, upper_limit=1) +
                " but got value: {name}".format(name=sway_motion_input))

        if not -1 <= heave_motion_input <= 1:
            raise ValueError(
                "Input argument out of range:" +
                " valid range for heave_motion_input is" +
                " <{lower_limit}, {upper_limit}>".format(lower_limit=-1, upper_limit=1) +
                " but got value: {name}".format(name=heave_motion_input))

        if not -1 <= yaw_motion_input <= 1:
            raise ValueError(
                "Input argument out of range:" +
                " valid range for yaw_motion_input is" +
                " <{lower_limit}, {upper_limit}>".format(lower_limit=-1, upper_limit=1) +
                " but got value: {name}".format(name=yaw_motion_input))

        if not 0 <= slow_input <= 1:
            raise ValueError(
                "Input argument out of range:" +
                " valid range for slow_input is" +
                " <{lower_limit}, {upper_limit}>".format(lower_limit=0, upper_limit=1) +
                " but got value: {name}".format(name=slow_input))

        if not 0 <= boost_input <= 1:
            raise ValueError(
                "Input argument out of range:" +
                " valid range for boost_input is" +
                " <{lower_limit}, {upper_limit}>".format(lower_limit=0, upper_limit=1) +
                " but got value: {name}".format(name=boost_input))

        command_identifier = b'j'
        msg = command_identifier
        msg += struct.pack('ffffff', surge_motion_input, sway_motion_input, heave_motion_input, yaw_motion_input, slow_input, boost_input)
        self.send_and_receive(msg, expects_reply=False)

    def motion_input_tilt(self, surge_motion_input, sway_motion_input, heave_motion_input, yaw_motion_input, slow_input, boost_input, tilt_speed_input):
        """Send a motion_input_tilt command over TCP

        Args:
            surge_motion_input (numpy data type:<f4): valid range is <-1, 1> 
            sway_motion_input (numpy data type:<f4): valid range is <-1, 1> 
            heave_motion_input (numpy data type:<f4): valid range is <-1, 1> 
            yaw_motion_input (numpy data type:<f4): valid range is <-1, 1> 
            slow_input (numpy data type:<f4): valid range is <0, 1> 
            boost_input (numpy data type:<f4): valid range is <0, 1> 
            tilt_speed_input (numpy data type:<f4): valid range is <-1, 1> Speed input for the camera tilt angle. 1 for max up, -1 for max down, 0 for stop.
        """
        if not -1 <= surge_motion_input <= 1:
            raise ValueError(
                "Input argument out of range:" +
                " valid range for surge_motion_input is" +
                " <{lower_limit}, {upper_limit}>".format(lower_limit=-1, upper_limit=1) +
                " but got value: {name}".format(name=surge_motion_input))

        if not -1 <= sway_motion_input <= 1:
            raise ValueError(
                "Input argument out of range:" +
                " valid range for sway_motion_input is" +
                " <{lower_limit}, {upper_limit}>".format(lower_limit=-1, upper_limit=1) +
                " but got value: {name}".format(name=sway_motion_input))

        if not -1 <= heave_motion_input <= 1:
            raise ValueError(
                "Input argument out of range:" +
                " valid range for heave_motion_input is" +
                " <{lower_limit}, {upper_limit}>".format(lower_limit=-1, upper_limit=1) +
                " but got value: {name}".format(name=heave_motion_input))

        if not -1 <= yaw_motion_input <= 1:
            raise ValueError(
                "Input argument out of range:" +
                " valid range for yaw_motion_input is" +
                " <{lower_limit}, {upper_limit}>".format(lower_limit=-1, upper_limit=1) +
                " but got value: {name}".format(name=yaw_motion_input))

        if not 0 <= slow_input <= 1:
            raise ValueError(
                "Input argument out of range:" +
                " valid range for slow_input is" +
                " <{lower_limit}, {upper_limit}>".format(lower_limit=0, upper_limit=1) +
                " but got value: {name}".format(name=slow_input))

        if not 0 <= boost_input <= 1:
            raise ValueError(
                "Input argument out of range:" +
                " valid range for boost_input is" +
                " <{lower_limit}, {upper_limit}>".format(lower_limit=0, upper_limit=1) +
                " but got value: {name}".format(name=boost_input))

        if not -1 <= tilt_speed_input <= 1:
            raise ValueError(
                "Input argument out of range:" +
                " valid range for tilt_speed_input is" +
                " <{lower_limit}, {upper_limit}>".format(lower_limit=-1, upper_limit=1) +
                " but got value: {name}".format(name=tilt_speed_input))

        command_identifier = b'J'
        msg = command_identifier
        msg += struct.pack('fffffff', surge_motion_input, sway_motion_input, heave_motion_input, yaw_motion_input, slow_input, boost_input, tilt_speed_input)
        self.send_and_receive(msg, expects_reply=False)

    def set_lights(self, brightness_upper, brightness_lower):
        """Send a set_lights command over TCP

        Args:
            brightness_upper (numpy data type:<u1): valid range is <0, 255> 
            brightness_lower (numpy data type:<u1): valid range is <0, 255> 
        """
        if not 0 <= brightness_upper <= 255:
            raise ValueError(
                "Input argument out of range:" +
                " valid range for brightness_upper is" +
                " <{lower_limit}, {upper_limit}>".format(lower_limit=0, upper_limit=255) +
                " but got value: {name}".format(name=brightness_upper))

        if not 0 <= brightness_lower <= 255:
            raise ValueError(
                "Input argument out of range:" +
                " valid range for brightness_lower is" +
                " <{lower_limit}, {upper_limit}>".format(lower_limit=0, upper_limit=255) +
                " but got value: {name}".format(name=brightness_lower))

        command_identifier = b'l'
        msg = command_identifier
        msg += struct.pack('BB', brightness_upper, brightness_lower)
        self.send_and_receive(msg, expects_reply=False)

    def ping(self):
        """Send a ping command over TCP
        """
        command_identifier = b'p'
        msg = command_identifier
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=1)
        self.check_reply(reply, b'P')

    def start_recording(self):
        """Send a start_recording command over TCP
        """
        command_identifier = b'r'
        msg = command_identifier
        self.send_and_receive(msg, expects_reply=False)

    def stop_recording(self):
        """Send a stop_recording command over TCP
        """
        command_identifier = b'R'
        msg = command_identifier
        self.send_and_receive(msg, expects_reply=False)

    def set_overlay_temperature_enabled(self, overlay_temperature_enabled):
        """Send a set_overlay_temperature_enabled command over TCP

        Args:
            overlay_temperature_enabled (numpy data type:<u1): 1 is true, 0 is false
        """
        command_identifier = b'ot'
        msg = command_identifier
        msg += struct.pack('B', overlay_temperature_enabled)
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=1)
        self.check_reply(reply, b'a')

    def set_overlay_depth_enabled(self, overlay_depth_enabled):
        """Send a set_overlay_depth_enabled command over TCP

        Args:
            overlay_depth_enabled (numpy data type:<u1): 1 is true, 0 is false
        """
        command_identifier = b'od'
        msg = command_identifier
        msg += struct.pack('B', overlay_depth_enabled)
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=1)
        self.check_reply(reply, b'a')

    def set_overlay_heading_enabled(self, overlay_heading_enabled):
        """Send a set_overlay_heading_enabled command over TCP

        Args:
            overlay_heading_enabled (numpy data type:<u1): 1 is true, 0 is false
        """
        command_identifier = b'oh'
        msg = command_identifier
        msg += struct.pack('B', overlay_heading_enabled)
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=1)
        self.check_reply(reply, b'a')

    def set_overlay_tilt_enabled(self, overlay_tilt_enabled):
        """Send a set_overlay_tilt_enabled command over TCP

        Args:
            overlay_tilt_enabled (numpy data type:<u1): 1 is true, 0 is false
        """
        command_identifier = b'ol'
        msg = command_identifier
        msg += struct.pack('B', overlay_tilt_enabled)
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=1)
        self.check_reply(reply, b'a')

    def set_overlay_date_enabled(self, overlay_date_enabled):
        """Send a set_overlay_date_enabled command over TCP

        Args:
            overlay_date_enabled (numpy data type:<u1): 1 is true, 0 is false
        """
        command_identifier = b'oa'
        msg = command_identifier
        msg += struct.pack('B', overlay_date_enabled)
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=1)
        self.check_reply(reply, b'a')

    def set_overlay_logo_index(self, overlay_logo_index):
        """Send a set_overlay_logo_index command over TCP

        Args:
            overlay_logo_index (numpy data type:<i4): enum { NONE = 0, DEFAULT = 1, CUSTOM = 2 }
        """
        command_identifier = b'oo'
        msg = command_identifier
        msg += struct.pack('i', overlay_logo_index)
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=1)
        self.check_reply(reply, b'a')

    def set_overlay_depth_unit(self, overlay_depth_unit):
        """Send a set_overlay_depth_unit command over TCP

        Args:
            overlay_depth_unit (numpy data type:<i4): enum { METERS = 0, FEET = 1 }
        """
        command_identifier = b'oD'
        msg = command_identifier
        msg += struct.pack('i', overlay_depth_unit)
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=1)
        self.check_reply(reply, b'a')

    def set_overlay_temperature_unit(self, overlay_temperature_unit):
        """Send a set_overlay_temperature_unit command over TCP

        Args:
            overlay_temperature_unit (numpy data type:<i4): enum { CELSIUS = 0, FAHRENHEIT = 1 }
        """
        command_identifier = b'oT'
        msg = command_identifier
        msg += struct.pack('i', overlay_temperature_unit)
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=1)
        self.check_reply(reply, b'a')

    def set_overlay_tz_offset(self, overlay_tz_offset):
        """Send a set_overlay_tz_offset command over TCP

        Args:
            overlay_tz_offset (numpy data type:<i4): time zone offset in minutes
        """
        command_identifier = b'oz'
        msg = command_identifier
        msg += struct.pack('i', overlay_tz_offset)
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=1)
        self.check_reply(reply, b'a')

    def set_overlay_margin_width(self, overlay_margin_width):
        """Send a set_overlay_margin_width command over TCP

        Args:
            overlay_margin_width (numpy data type:<i4): margin width in pixels
        """
        command_identifier = b'ow'
        msg = command_identifier
        msg += struct.pack('i', overlay_margin_width)
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=1)
        self.check_reply(reply, b'a')

    def set_overlay_margin_height(self, overlay_margin_height):
        """Send a set_overlay_margin_height command over TCP

        Args:
            overlay_margin_height (numpy data type:<i4): margin height in pixels
        """
        command_identifier = b'oH'
        msg = command_identifier
        msg += struct.pack('i', overlay_margin_height)
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=1)
        self.check_reply(reply, b'a')

    def set_overlay_font_size(self, overlay_font_size):
        """Send a set_overlay_font_size command over TCP

        Args:
            overlay_font_size (numpy data type:<i4): choose from: { 15, 20, 25, 30, 35, 40 }
        """
        command_identifier = b'of'
        msg = command_identifier
        msg += struct.pack('i', overlay_font_size)
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=1)
        self.check_reply(reply, b'a')

    def set_overlay_title(self, overlay_title):
        """Send a set_overlay_title command over TCP

        Args:
            overlay_title (numpy data type:<u1[64]): Null terminated utf8 string padded to 64 characters. Only utf8 characters representable in latin1 will be rendered correctly.
        """
        command_identifier = b'oi'
        msg = command_identifier
        msg += struct.pack('64s', overlay_title)
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=1)
        self.check_reply(reply, b'a')

    def set_overlay_subtitle(self, overlay_subtitle):
        """Send a set_overlay_subtitle command over TCP

        Args:
            overlay_subtitle (numpy data type:<u1[64]): Null terminated utf8 string padded to 64 characters. Only utf8 characters representable in latin1 will be rendered correctly.
        """
        command_identifier = b'os'
        msg = command_identifier
        msg += struct.pack('64s', overlay_subtitle)
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=1)
        self.check_reply(reply, b'a')

    def set_overlay_date_format(self, overlay_date_format):
        """Send a set_overlay_date_format command over TCP

        Args:
            overlay_date_format (numpy data type:<u1[64]): Null terminated utf8 string padded to 64 characters. Only utf8 characters representable in latin1 will be rendered correctly.
        """
        command_identifier = b'oA'
        msg = command_identifier
        msg += struct.pack('64s', overlay_date_format)
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=1)
        self.check_reply(reply, b'a')

    def get_overlay_parameters(self):
        """Send a get_overlay_parameters command over TCP

        Returns:
            parameter (numtyp data type:<u1)
            temperature_enabled (numtyp data type:<u1)
            depth_enabled (numtyp data type:<u1)
            heading_enabled (numtyp data type:<u1)
            tilt_enabled (numtyp data type:<u1)
            date_enabled (numtyp data type:<u1)
            logo_index (numtyp data type:<i4)
            depth_unit (numtyp data type:<i4)
            temperature_unit (numtyp data type:<i4)
            tz_offset (numtyp data type:<i4)
            margin_width (numtyp data type:<i4)
            margin_height (numtyp data type:<i4)
            font_size (numtyp data type:<i4)
            title (numtyp data type:<u1[64])
            subtitle (numtyp data type:<u1[64])
            date_format (numtyp data type:<u1[64])
        """
        command_identifier = b'Oa'
        msg = command_identifier
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=226)
        return struct.unpack('<BBBBBBiiiiiii64s64s64s', reply)

    def start_compass_calibration(self):
        """Send a start_compass_calibration command over TCP
        """
        command_identifier = b'i'
        msg = command_identifier
        self.send_and_receive(msg, expects_reply=False)

    def cancel_compass_calibration(self):
        """Send a cancel_compass_calibration command over TCP
        """
        command_identifier = b'I'
        msg = command_identifier
        self.send_and_receive(msg, expects_reply=False)

    def save_compass_calibration(self):
        """Send a save_compass_calibration command over TCP
        """
        command_identifier = b'c'
        msg = command_identifier
        self.send_and_receive(msg, expects_reply=False)

    def user_geo_location(self, longitude, latitude):
        """Send a user_geo_location command over TCP

        Args:
            longitude (numpy data type:<f8): longitude that is included in the log file in degrees
            latitude (numpy data type:<f8): latitude that is included in the log file in degrees
        """
        command_identifier = b'g'
        msg = command_identifier
        msg += struct.pack('dd', longitude, latitude)
        self.send_and_receive(msg, expects_reply=False)

    def watchdog(self, connection_duration):
        """Send a watchdog command over TCP

        Args:
            connection_duration (numpy data type:<i2): time in seconds since connected to drone
        """
        command_identifier = b'w'
        msg = command_identifier
        msg += struct.pack('h', connection_duration)
        self.send_and_receive(msg, expects_reply=False)

    def auto_heading_on(self):
        """Send a auto_heading_on command over TCP
        """
        command_identifier = b'h'
        msg = command_identifier
        self.send_and_receive(msg, expects_reply=False)

    def auto_heading_off(self):
        """Send a auto_heading_off command over TCP
        """
        command_identifier = b'H'
        msg = command_identifier
        self.send_and_receive(msg, expects_reply=False)

    def auto_depth_on(self):
        """Send a auto_depth_on command over TCP
        """
        command_identifier = b'd'
        msg = command_identifier
        self.send_and_receive(msg, expects_reply=False)

    def auto_depth_off(self):
        """Send a auto_depth_off command over TCP
        """
        command_identifier = b'D'
        msg = command_identifier
        self.send_and_receive(msg, expects_reply=False)

    def auto_depth_step(self, direction):
        """Send a auto_depth_step command over TCP

        Args:
            direction (numpy data type:<i2):  1 for up, -1 for down
        """
        command_identifier = b'a'
        msg = command_identifier
        msg += struct.pack('h', direction)
        self.send_and_receive(msg, expects_reply=False)

    def auto_heading_step(self, direction):
        """Send a auto_heading_step command over TCP

        Args:
            direction (numpy data type:<i2): 1 for up, -1 for down
        """
        command_identifier = b'A'
        msg = command_identifier
        msg += struct.pack('h', direction)
        self.send_and_receive(msg, expects_reply=False)

    def set_system_time(self, unix_timestamp):
        """Send a set_system_time command over TCP

        set the system time on the on-board computer

        Args:
            unix_timestamp (numpy data type:<u4): 
        """
        command_identifier = b't'
        msg = command_identifier
        msg += struct.pack('I', unix_timestamp)
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=1)
        self.check_reply(reply, b'a')

    def set_water_density(self, water_density):
        """Send a set_water_density command over TCP

        Set the water density for improved accuracy of the depth sensor.

        Args:
            water_density (numpy data type:<i2): water density in grams per liter
        """
        command_identifier = b'W'
        msg = command_identifier
        msg += struct.pack('h', water_density)
        self.send_and_receive(msg, expects_reply=False)

    def take_still_picture(self):
        """Send a take_still_picture command over TCP

        Takes a still picture and stores it locally on the drone.
        """
        command_identifier = b's'
        msg = command_identifier
        self.send_and_receive(msg, expects_reply=False)

    def toggle_tilt_stabilization(self):
        """Send a toggle_tilt_stabilization command over TCP

        Toggle active tilt stabilization on or off
        """
        command_identifier = b'S'
        msg = command_identifier
        self.send_and_receive(msg, expects_reply=False)

    def set_camera_exposure(self, exposure_value):
        """Send a set_camera_exposure command over TCP

        Args:
            exposure_value (numpy data type:<i4): 1 = 1/1000th of a second, 5 = 1/200th of a second. Valid values are in the range <1, 5000>
        """
        command_identifier = b've'
        msg = command_identifier
        msg += struct.pack('i', exposure_value)
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=1)
        self.check_reply(reply, b'a')

    def set_camera_whitebalance(self, whitebalance_value):
        """Send a set_camera_whitebalance command over TCP

        Args:
            whitebalance_value (numpy data type:<i4): valid values are in the range <2800, 9300>
        """
        command_identifier = b'vw'
        msg = command_identifier
        msg += struct.pack('i', whitebalance_value)
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=1)
        self.check_reply(reply, b'a')

    def set_camera_hue(self, hue_value):
        """Send a set_camera_hue command over TCP

        Args:
            hue_value (numpy data type:<i4): valid values are in the range <-40, 40>
        """
        command_identifier = b'vh'
        msg = command_identifier
        msg += struct.pack('i', hue_value)
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=1)
        self.check_reply(reply, b'a')

    def set_camera_bitrate(self, bitrate_value):
        """Send a set_camera_bitrate command over TCP

        Args:
            bitrate_value (numpy data type:<i4): set camera bitrate in bits. Valid values are in range <1 000 000, 16 000 000> 
        """
        command_identifier = b'vb'
        msg = command_identifier
        msg += struct.pack('i', bitrate_value)
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=1)
        self.check_reply(reply, b'a')

    def set_camera_framerate(self, framerate_value):
        """Send a set_camera_framerate command over TCP

        Args:
            framerate_value (numpy data type:<i4): valid values are 25 or 30
        """
        command_identifier = b'vf'
        msg = command_identifier
        msg += struct.pack('i', framerate_value)
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=1)
        self.check_reply(reply, b'a')

    def set_camera_resolution(self, resolution_value):
        """Send a set_camera_resolution command over TCP

        Args:
            resolution_value (numpy data type:<i4): valid values are 720 or 1080
        """
        command_identifier = b'vr'
        msg = command_identifier
        msg += struct.pack('i', resolution_value)
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=1)
        self.check_reply(reply, b'a')

    def get_camera_parameters(self):
        """Send a get_camera_parameters command over TCP

        Returns:
            parameter (numtyp data type:<u1)
            camera_bitrate (numtyp data type:<i4)
            camera_exposure (numtyp data type:<i4)
            camera_whitebalance (numtyp data type:<i4)
            camera_hue (numtyp data type:<i4)
            camera_resolution (numtyp data type:<i4)
            camera_framerate (numtyp data type:<i4)
        """
        command_identifier = b'Va'
        msg = command_identifier
        reply = self.send_and_receive(msg, expects_reply=True, receive_size=25)
        return struct.unpack('<Biiiiii', reply)

    def set_gripper_velocities(self, gripping_velocity, rotational_velocity):
        """Send a set_gripper_velocities command over TCP

        Args:
            gripping_velocity (numpy data type:<f4): valid range is <-1, 1> The opening/closing velocity of the gripper. Positive values for opening, negative for closing
            rotational_velocity (numpy data type:<f4): valid range is <-1, 1> The rotational velocity of the gripper. Positive values for clockwise, negative for counter-clockwise
        """
        if not -1 <= gripping_velocity <= 1:
            raise ValueError(
                "Input argument out of range:" +
                " valid range for gripping_velocity is" +
                " <{lower_limit}, {upper_limit}>".format(lower_limit=-1, upper_limit=1) +
                " but got value: {name}".format(name=gripping_velocity))

        if not -1 <= rotational_velocity <= 1:
            raise ValueError(
                "Input argument out of range:" +
                " valid range for rotational_velocity is" +
                " <{lower_limit}, {upper_limit}>".format(lower_limit=-1, upper_limit=1) +
                " but got value: {name}".format(name=rotational_velocity))

        command_identifier = b'G'
        msg = command_identifier
        msg += struct.pack('ff', gripping_velocity, rotational_velocity)
        self.send_and_receive(msg, expects_reply=False)

    def set_thickness_gauge_sound_veloctiy(self, sound_velocity):
        """Send a set_thickness_gauge_sound_veloctiy command over TCP

        Args:
            sound_velocity (numpy data type:<i2): Sound velocity used for thickness calculation [m/s]
        """
        command_identifier = b'C'
        msg = command_identifier
        msg += struct.pack('h', sound_velocity)
        self.send_and_receive(msg, expects_reply=False)


class TcpClient:
    def __new__(self, protocol_version=None, *args, **kwargs):
        if protocol_version == None:
            return TcpClientV2(*args, **kwargs)
        elif protocol_version == 1:
            return TcpClientV1(*args, **kwargs)
        elif protocol_version == 2:
            return TcpClientV2(*args, **kwargs)
        else:
            raise ValueError(f"Unsupported protocol version: {protocol_version}")
            