### Install pydjirecord Source: https://rembish.github.io/pydjirecord Install the package using pip. ```bash pip install pydjirecord ``` -------------------------------- ### Install pydjirecord from source Source: https://rembish.github.io/pydjirecord/guide/installation Clone the repository and install in editable mode with development dependencies. ```bash git clone https://github.com/rembish/pydjirecord.git cd pydjirecord make install ``` -------------------------------- ### Install pydjirecord with protobuf support Source: https://rembish.github.io/pydjirecord/guide/installation Use this command to include optional protobuf support for parsing VirtualStick records. ```bash pip install 'pydjirecord[proto]' ``` -------------------------------- ### Initialize Keychain Source: https://rembish.github.io/pydjirecord/api/keychain Create a new Keychain instance for mapping feature points to decryption keys. ```python Keychain() ``` -------------------------------- ### CLI Command Syntax Source: https://rembish.github.io/pydjirecord/guide/cli General usage pattern for the djirecord command. ```bash djirecord FILE [--json | --raw | --geojson | --kml | --csv | --hardware] [-o FILE] [--api-key KEY] [--no-cache] [--no-verify] ``` -------------------------------- ### Initialize KeychainsRequest Source: https://rembish.github.io/pydjirecord/api/keychain Creates a request body for the DJI keychains API. ```python KeychainsRequest(version: int = 0, department: int = 3, keychains: list[list[EncodedKeychainFeaturePoint]] = list()) ``` -------------------------------- ### Initialize DJILog dataclass Source: https://rembish.github.io/pydjirecord/api/djilog Represents a parsed DJI flight log. Use from_bytes to construct instances. ```python DJILog(inner: bytes, prefix: Prefix, version: int, details: Details, auxiliary_version: AuxiliaryVersion | None = None) ``` -------------------------------- ### Create Empty Keychain Source: https://rembish.github.io/pydjirecord/api/keychain Returns a new Keychain instance with no feature-point keys. ```python empty() -> Keychain ``` -------------------------------- ### Hardware Report Generation Source: https://rembish.github.io/pydjirecord/guide/cli Commands to generate and view detailed hardware component reports. ```bash djirecord flight.txt --hardware --api-key YOUR_KEY ``` ```text AIRCRAFT Model: DJI Mini 4 Pro Product type: MINI4_PRO Serial: 1581F6Z9C23CP003 CAMERA Serial: 6TVQLBJ0M209BS SD card: inserted REMOTE CONTROLLER Serial: 6UZBLCN021016H Downlink: min 0%, avg 80% Uplink: min 1%, avg 85% BATTERY Serial: 7BVPLBVDA104J3 Design cap: 2590 mAh Charge cycles: 3 Charge: 99% -> 81% (used 18%) Temperature: 29.5 - 39.2 C Cells: 2, deviation 4 mV FLIGHT CONTROLLER Failsafe: GO_HOME Obstacle avd: ON ``` -------------------------------- ### Prefix Parsing Methods Source: https://rembish.github.io/pydjirecord/api/layout Methods for parsing and managing the log file prefix. ```python from_bytes(data: bytes) -> Prefix ``` ```python recover_detail_offset(offset: int) -> None ``` ```python detail_offset() -> int ``` ```python records_offset() -> int ``` ```python records_end_offset(file_size: int) -> int ``` -------------------------------- ### Initialize KeychainFeaturePoint Source: https://rembish.github.io/pydjirecord/api/keychain Represents a decoded feature point containing the AES key and IV. ```python KeychainFeaturePoint(feature_point: int, aes_key: str, aes_iv: str) ``` -------------------------------- ### Configure API Key via .env file Source: https://rembish.github.io/pydjirecord/guide/api-key Define the DJI_API_KEY variable in a .env file located in the current directory to provide the key to the application. ```text # .env file DJI_API_KEY=your_key_here ``` -------------------------------- ### Use individual compute functions Source: https://rembish.github.io/pydjirecord/guide/library Directly access compute functions for coordinates, photo counts, and video duration. ```python from pydjirecord.frame.builder import compute_coordinates, compute_photo_num, compute_video_time lat, lon = compute_coordinates(frames) # first valid GPS fix distance = frames[-1].osd.cumulative_distance if frames else 0.0 # GPS track length photos = compute_photo_num(frames) # remain_photo_num delta video_seconds = compute_video_time(frames) # sum of record_time segments ``` -------------------------------- ### Build Keychain from Feature Points Source: https://rembish.github.io/pydjirecord/api/keychain Constructs a Keychain object from a sequence of decoded feature-point entries. ```python from_feature_points(entries: Sequence[KeychainFeaturePoint]) -> Keychain ``` -------------------------------- ### ProductType Properties Source: https://rembish.github.io/pydjirecord/api/layout Properties for accessing battery configuration based on DJI aircraft product type. ```python battery_cell_num: int ``` ```python battery_num: int ``` -------------------------------- ### Build KeychainsRequest Source: https://rembish.github.io/pydjirecord/api/djilog Builds a request by parsing KeyStorage records, required for v13+ logs. ```python keychains_request() -> KeychainsRequest ``` -------------------------------- ### DJILog.keychains_request Source: https://rembish.github.io/pydjirecord/api/djilog Builds a KeychainsRequest by parsing KeyStorage records, necessary for v13+ logs. ```APIDOC ## keychains_request() -> KeychainsRequest ### Description Build a KeychainsRequest by parsing KeyStorage records. For v13+, this iterates the record stream with an empty keychain to extract the encoded feature points needed for the API call. ``` -------------------------------- ### Firmware Record Structure and Parsing Source: https://rembish.github.io/pydjirecord/api/records Defines the Firmware dataclass and its class method for parsing binary data. ```python Firmware(sender_type: SenderType, sub_sender_type: int, version: str) ``` ```python from_bytes(data: bytes, version: int = 0) -> Firmware ``` -------------------------------- ### Initialize Frame dataclass Source: https://rembish.github.io/pydjirecord/api/frames Represents a normalized frame combining all record types for a single flight moment. ```python Frame(custom: FrameCustom = FrameCustom(), osd: FrameOSD = FrameOSD(), gimbal: FrameGimbal = FrameGimbal(), camera: FrameCamera = FrameCamera(), rc: FrameRC = FrameRC(), battery: FrameBattery = FrameBattery(), home: FrameHome = FrameHome(), recover: FrameRecover = FrameRecover(), app: FrameApp = FrameApp()) ``` -------------------------------- ### SmartBattery Dataclass and Parsing Source: https://rembish.github.io/pydjirecord/api/records Defines the SmartBattery structure and provides a method to parse it from binary data. ```python SmartBattery(useful_time: int, go_home_time: int, land_time: int, go_home_battery: int, land_battery: int, safe_fly_radius: float, volume_consume: float, status: int, go_home_status: int, go_home_countdown: int, voltage: float, percent: int, low_warning: int, low_warning_go_home: int, serious_low_warning: int, serious_low_warning_landing: int) ``` ```python from_bytes(data: bytes, version: int = 0) -> SmartBattery ``` -------------------------------- ### Parse DJI flight logs in Python Source: https://rembish.github.io/pydjirecord Load a flight log file from bytes and access flight details. ```python from pydjirecord import DJILog log = DJILog.from_bytes(open("flight.txt", "rb").read()) print(log.details.aircraft_name, log.details.total_distance) ``` -------------------------------- ### Details Parsing Method Source: https://rembish.github.io/pydjirecord/api/layout Parses a Details block from data according to the specified log version. ```python from_bytes(data: bytes, version: int) -> Details ``` -------------------------------- ### Camera Record Structure and Parsing Source: https://rembish.github.io/pydjirecord/api/records Defines the Camera record dataclass and its binary parsing method. ```python Camera(is_shooting_single_photo: bool, is_recording: bool, has_sd_card: bool, sd_card_state: SDCardState, work_mode: CameraWorkMode = CameraWorkMode.CAPTURE, sd_card_total_capacity: int = 0, sd_card_remain_capacity: int = 0, remain_photo_num: int = 0, remain_video_timer: int = 0, record_time: int = 0, camera_type: int = 0) ``` ```python from_bytes(data: bytes, version: int = 0) -> Camera ``` -------------------------------- ### Map Record to FeaturePoint Source: https://rembish.github.io/pydjirecord/api/keychain Maps a record type and version to the corresponding FeaturePoint for key selection. ```python feature_point_for_record(record_type: int, version: int) -> FeaturePoint ``` -------------------------------- ### DJILog.from_bytes Source: https://rembish.github.io/pydjirecord/api/djilog Constructs a DJILog instance by parsing the header, details, and auxiliary blocks from raw log bytes. ```APIDOC ## from_bytes(data: bytes) -> DJILog ### Description Parse header, details, and auxiliary blocks from raw log bytes. ### Parameters - **data** (bytes) - Required - The raw binary log data. ``` -------------------------------- ### Home Record Structure and Parsing Source: https://rembish.github.io/pydjirecord/api/records Defines the Home point record dataclass and its binary parsing method. ```python Home(longitude: float, latitude: float, altitude: float, is_home_record: bool, go_home_mode: GoHomeMode, is_dynamic_home_point_enabled: bool, is_near_distance_limit: bool, is_near_height_limit: bool, is_multiple_mode_open: bool, has_go_home: bool, compass_state: CompassCalibrationState, is_compass_adjust: bool, is_beginner_mode: bool, is_ioc_open: bool, ioc_mode: IOCMode, aircraft_head_direction: int, go_home_height: int, ioc_course_lock_angle: int, current_flight_record_index: int, max_allowed_height: float) ``` ```python from_bytes(data: bytes, version: int) -> Home ``` -------------------------------- ### AuxiliaryVersion Dataclass and Parsing Source: https://rembish.github.io/pydjirecord/api/layout Represents the Auxiliary Version block containing department and version metadata. ```python AuxiliaryVersion(version: int, department: Department) ``` ```python from_bytes(data: bytes) -> AuxiliaryVersion ``` -------------------------------- ### Prefix Binary Layout Source: https://rembish.github.io/pydjirecord/api/layout The 100-byte little-endian binary structure of the log file header. ```text detail_offset : u64 detail_length : u16 version : u8 unknown : u8 encrypt_magic : u64 reserved : [u8; 80] ``` -------------------------------- ### Fetch Keychains from API Source: https://rembish.github.io/pydjirecord/api/keychain Retrieves decoded keychains from the DJI API, optionally using local caching. ```python fetch(api_key: str, *, cache: bool = True, verify: bool = True) -> list[list[KeychainFeaturePoint]] ``` -------------------------------- ### DJILog.fetch_keychains Source: https://rembish.github.io/pydjirecord/api/djilog Fetches decoded keychains from the DJI API, required for v13+ logs. ```APIDOC ## fetch_keychains(api_key: str, *, cache: bool = True, verify: bool = True) -> list[list[KeychainFeaturePoint]] ### Description Fetch decoded keychains from DJI API. Only needed for v13+ logs. Returns empty list for older versions. ### Parameters - **api_key** (str) - Required - The API key for authentication. - **cache** (bool) - Optional - Whether to use cached results. - **verify** (bool) - Optional - Whether to verify the connection. ``` -------------------------------- ### MCParams from_bytes Method Source: https://rembish.github.io/pydjirecord/api/records Parses flight-controller parameters record from binary data. ```python from_bytes(data: bytes, version: int = 0) -> MCParams ``` -------------------------------- ### Initialize FrameOSD dataclass Source: https://rembish.github.io/pydjirecord/api/frames Contains normalized OSD telemetry data. Fields like cumulative_distance are computed based on valid GPS positions. ```python FrameOSD(fly_time: float = 0.0, latitude: float = 0.0, longitude: float = 0.0, height: float = 0.0, height_max: float = 0.0, vps_height: float = 0.0, altitude: float = 0.0, x_speed: float = 0.0, x_speed_max: float = 0.0, y_speed: float = 0.0, y_speed_max: float = 0.0, z_speed: float = 0.0, z_speed_max: float = 0.0, h_speed: float = 0.0, h_speed_max: float = 0.0, cumulative_distance: float = 0.0, pitch: float = 0.0, roll: float = 0.0, yaw: float = 0.0, flyc_state: FlightMode | None = None, flyc_command: AppCommand | None = None, flight_action: FlightAction | None = None, is_gpd_used: bool = False, non_gps_cause: NonGPSCause | None = None, gps_num: int = 0, gps_level: int = 0, drone_type: DroneType | None = None, is_swave_work: bool = False, wave_error: bool = False, go_home_status: GoHomeStatus | None = None, battery_type: BatteryType | None = None, is_on_ground: bool = False, is_motor_on: bool = False, is_motor_blocked: bool = False, motor_start_failed_cause: MotorStartFailedCause | None = None, is_imu_preheated: bool = False, imu_init_fail_reason: ImuInitFailReason | None = None, is_acceletor_over_range: bool = False, is_barometer_dead_in_air: bool = False, is_compass_error: bool = False, is_go_home_height_modified: bool = False, can_ioc_work: bool = False, is_not_enough_force: bool = False, is_out_of_limit: bool = False, is_propeller_catapult: bool = False, is_vibrating: bool = False, is_vision_used: bool = False, voltage_warning: int = 0) ``` -------------------------------- ### Parse log from bytes Source: https://rembish.github.io/pydjirecord/api/djilog Parses header, details, and auxiliary blocks from raw log bytes. ```python from_bytes(data: bytes) -> DJILog ``` -------------------------------- ### Exporting Flight Data Source: https://rembish.github.io/pydjirecord/guide/cli Commands to export flight logs into different file formats. ```bash # JSON to stdout (details-only for v13+ without API key) djirecord flight.txt --json # JSON with frames to file djirecord flight.txt --json -o flight.json --api-key YOUR_KEY # Raw records as JSON djirecord flight.txt --raw --api-key YOUR_KEY # GeoJSON track djirecord flight.txt --geojson -o track.geojson --api-key YOUR_KEY # KML track djirecord flight.txt --kml -o track.kml --api-key YOUR_KEY # CSV telemetry djirecord flight.txt --csv -o telemetry.csv --api-key YOUR_KEY ``` -------------------------------- ### KeychainsRequest.fetch Source: https://rembish.github.io/pydjirecord/api/keychain Fetches decoded keychains from the DJI API using an API key. ```APIDOC ## KeychainsRequest.fetch ### Description Fetches decoded keychains from the DJI API. Responses are cached locally by default to avoid redundant network requests. ### Parameters - **api_key** (str) - Required - The API key for authentication. - **cache** (bool) - Optional - Whether to use local caching (default: True). - **verify** (bool) - Optional - Whether to verify SSL certificates (default: True). ### Response - **Returns** (list[list[KeychainFeaturePoint]]) - A list of decoded keychain feature points. ### Errors - **ApiKeyError** - Raised if the api_key is None or empty. ``` -------------------------------- ### Access raw records Source: https://rembish.github.io/pydjirecord/guide/library Retrieve raw records from the log using the provided keychains. ```python records = log.records(keychains) ``` -------------------------------- ### Initialize EncodedKeychainFeaturePoint Source: https://rembish.github.io/pydjirecord/api/keychain Represents an encrypted feature point retrieved from KeyStorage records. ```python EncodedKeychainFeaturePoint(feature_point: int, aes_ciphertext: str) ``` -------------------------------- ### Fetch keychains from API Source: https://rembish.github.io/pydjirecord/api/djilog Fetches decoded keychains from the DJI API, necessary for v13+ log decryption. ```python fetch_keychains(api_key: str, *, cache: bool = True, verify: bool = True) -> list[list[KeychainFeaturePoint]] ``` -------------------------------- ### Parse a flight log Source: https://rembish.github.io/pydjirecord/guide/library Initialize a DJILog object from raw bytes to access flight metadata without decryption. ```python from pydjirecord import DJILog # Parse a flight log data = open("flight.txt", "rb").read() log = DJILog.from_bytes(data) # Access flight metadata (no decryption needed) print(log.version) print(log.details.aircraft_name) print(log.details.total_distance) ``` -------------------------------- ### Convert records to frames Source: https://rembish.github.io/pydjirecord/api/djilog Parses records and converts them to normalized frames. Keychains must be provided for v13+ logs. ```python frames(keychains: list[list[KeychainFeaturePoint]] | None = None) -> list[Frame] ``` -------------------------------- ### Export flight logs via CLI Source: https://rembish.github.io/pydjirecord Convert a flight log to JSON format using the command line interface. ```bash djirecord flight.txt --json -o flight.json --api-key YOUR_KEY ``` -------------------------------- ### KeyStorage Record Structure and Parsing Source: https://rembish.github.io/pydjirecord/api/records Defines the KeyStorage dataclass for encrypted feature point data and its parsing method. ```python KeyStorage(feature_point: int, data: bytes) ``` ```python from_bytes(data: bytes, version: int = 0) -> KeyStorage ``` -------------------------------- ### Retrieve Keychain Entry Source: https://rembish.github.io/pydjirecord/api/keychain Fetches the (iv, key) tuple for a specific feature point, returning None if not found. ```python get(fp: int) -> tuple[bytes, bytes] | None ``` -------------------------------- ### AppWarn Record Structure and Parsing Source: https://rembish.github.io/pydjirecord/api/records Defines the AppWarn dataclass for warning records and its parsing method. ```python AppWarn(message: str) ``` ```python from_bytes(data: bytes, version: int = 0) -> AppWarn ``` -------------------------------- ### CenterBattery Dataclass and Parsing Source: https://rembish.github.io/pydjirecord/api/records Defines the CenterBattery structure and provides a method to parse it from binary data. ```python CenterBattery(relative_capacity: int, voltage: float, current_capacity: int, full_capacity: int, life: int, number_of_discharges: int, current: float, voltage_cell1: float, voltage_cell2: float, voltage_cell3: float, voltage_cell4: float, voltage_cell5: float, voltage_cell6: float, serial_number: int, temperature: float) ``` ```python from_bytes(data: bytes, version: int) -> CenterBattery ``` -------------------------------- ### AppTip Record Structure and Parsing Source: https://rembish.github.io/pydjirecord/api/records Defines the AppTip dataclass for notification records and its parsing method. ```python AppTip(message: str) ``` ```python from_bytes(data: bytes, version: int = 0) -> AppTip ``` -------------------------------- ### export_csv Source: https://rembish.github.io/pydjirecord/api/export Exports flight frames as a CSV file with approximately 120 columns. ```APIDOC ## export_csv(frames: list[Frame], details: Details, output: TextIO = sys.stdout) -> None ### Description Exports frames as CSV with ~120 columns. ### Parameters - **frames** (list[Frame]) - Required - The list of flight frames to export. - **details** (Details) - Required - The flight details object. - **output** (TextIO) - Optional - The output stream (defaults to sys.stdout). ``` -------------------------------- ### Gimbal Record Structure and Parsing Source: https://rembish.github.io/pydjirecord/api/records Defines the Gimbal record dataclass and its binary parsing method. ```python Gimbal(pitch: float, roll: float, yaw: float, mode: GimbalMode, is_pitch_at_limit: bool, is_roll_at_limit: bool, is_yaw_at_limit: bool, is_stuck: bool) ``` ```python from_bytes(data: bytes, version: int) -> Gimbal ``` -------------------------------- ### RC Record Structure and Parsing Source: https://rembish.github.io/pydjirecord/api/records Defines the Remote Controller record dataclass and its binary parsing method. ```python RC(aileron: int, elevator: int, throttle: int, rudder: int) ``` ```python from_bytes(data: bytes, version: int, product_type: ProductType = ProductType.NONE) -> RC ``` -------------------------------- ### ComponentSerial from_bytes Method Source: https://rembish.github.io/pydjirecord/api/records Parses component serial record from binary data. ```python from_bytes(data: bytes, version: int = 0) -> ComponentSerial ``` -------------------------------- ### Export flight data to CSV Source: https://rembish.github.io/pydjirecord/api/export Converts flight frames into a CSV format containing approximately 120 columns. ```python export_csv(frames: list[Frame], details: Details, output: TextIO = sys.stdout) -> None ``` -------------------------------- ### AuxiliaryInfo Dataclass and Parsing Source: https://rembish.github.io/pydjirecord/api/layout Represents the Auxiliary Info block containing XOR-encrypted Details data. ```python AuxiliaryInfo(version_data: int, info_data: bytes, signature_data: bytes) ``` ```python from_bytes(data: bytes) -> AuxiliaryInfo ``` -------------------------------- ### aes_decode Source: https://rembish.github.io/pydjirecord/api/decoder Performs AES-256-CBC decryption on the provided data. ```APIDOC ## aes_decode(data: bytes, iv: bytes, key: bytes) -> tuple[bytes, bytes] ### Description AES-256-CBC decrypt data, returning the plaintext and the next IV. ### Parameters - **data** (bytes) - Required - The ciphertext to decrypt. - **iv** (bytes) - Required - The initialization vector. - **key** (bytes) - Required - The decryption key. ### Returns - **tuple[bytes, bytes]** - A tuple containing the plaintext and the next_iv (the last 16 bytes of the ciphertext). ``` -------------------------------- ### Prefix Dataclass Definition Source: https://rembish.github.io/pydjirecord/api/layout Represents the log file header containing version and offset information. ```python Prefix(_detail_offset: int, version: int) ``` -------------------------------- ### Parse records from stream Source: https://rembish.github.io/pydjirecord/api/djilog Parses and decrypts all records from the binary stream. Keychains must be provided for v13+ logs. ```python records(keychains: list[list[KeychainFeaturePoint]] | None = None) -> list[Record] ``` -------------------------------- ### DJILog.frames Source: https://rembish.github.io/pydjirecord/api/djilog Parses records and converts them into normalized frames. ```APIDOC ## frames(keychains: list[list[KeychainFeaturePoint]] | None = None) -> list[Frame] ### Description Parse records and convert to normalized frames. For v13+ logs, keychains must be provided. ### Parameters - **keychains** (list[list[KeychainFeaturePoint]]) - Optional - Decoded keychains required for v13+ logs. ``` -------------------------------- ### Flight Information Retrieval Source: https://rembish.github.io/pydjirecord/guide/cli Commands for displaying flight summaries and decrypted log data. ```bash djirecord flight.txt # header-only for v13+ djirecord flight.txt --api-key KEY # decrypts frames, shows corrected values ``` ```text Log version: 14 Aircraft: Mavic Air 2 Product type: MAVIC_AIR2 Aircraft SN: ABC123 ... Flight stats: Distance: 4523.1 m Duration: 8m 42s Max height: 119.8 m Frames: 4362 Photos: 62 Video time: 1m 13s ``` -------------------------------- ### DJILog.records Source: https://rembish.github.io/pydjirecord/api/djilog Parses and decrypts all records from the binary stream. ```APIDOC ## records(keychains: list[list[KeychainFeaturePoint]] | None = None) -> list[Record] ### Description Parse and decrypt all records from the binary stream. For v13+ logs, keychains must be provided. ### Parameters - **keychains** (list[list[KeychainFeaturePoint]]) - Optional - Decoded keychains required for v13+ logs. ``` -------------------------------- ### record_decode Source: https://rembish.github.io/pydjirecord/api/decoder Decodes record data using XOR for versions 7-12 or XOR+AES for versions 13+. ```APIDOC ## record_decode(data: bytes, record_type: int, version: int, keychain: Keychain | None) -> bytes ### Description Decode record data: XOR for v7-12, XOR+AES for v13+. Returns decoded bytes ready for struct parsing. ### Parameters - **data** (bytes) - Required - The raw record data. - **record_type** (int) - Required - The type of record. - **version** (int) - Required - The version of the record. - **keychain** (Keychain | None) - Required - The keychain object for decryption keys. ### Returns - **bytes** - The decoded bytes. ``` -------------------------------- ### export_kml Source: https://rembish.github.io/pydjirecord/api/export Exports flight frames as a KML Document with a LineString track. ```APIDOC ## export_kml(frames: list[Frame], details: Details, output: BinaryIO = sys.stdout.buffer) -> None ### Description Export frames as a KML Document with LineString track. ### Parameters - **frames** (list[Frame]) - Required - The list of flight frames to export. - **details** (Details) - Required - The flight details object. - **output** (BinaryIO) - Optional - The output binary stream (defaults to sys.stdout.buffer). ``` -------------------------------- ### Export flight data to KML Source: https://rembish.github.io/pydjirecord/api/export Converts flight frames into a KML document containing a LineString track. ```python export_kml(frames: list[Frame], details: Details, output: BinaryIO = sys.stdout.buffer) -> None ``` -------------------------------- ### FrameHome Dataclass Source: https://rembish.github.io/pydjirecord/api/frames Represents normalized home point frame data. ```python FrameHome(latitude: float = 0.0, longitude: float = 0.0, altitude: float = 0.0, height_limit: float = 0.0, is_home_record: bool = False, go_home_mode: GoHomeMode | None = None, is_dynamic_home_point_enabled: bool = False, is_near_distance_limit: bool = False, is_near_height_limit: bool = False, is_compass_calibrating: bool = False, compass_calibration_state: CompassCalibrationState | None = None, is_multiple_mode_enabled: bool = False, is_beginner_mode: bool = False, is_ioc_enabled: bool = False, ioc_mode: IOCMode | None = None, go_home_height: int = 0, ioc_course_lock_angle: int | None = None, max_allowed_height: float = 0.0, current_flight_record_index: int = 0) ``` -------------------------------- ### Parse Record Function Source: https://rembish.github.io/pydjirecord/api/records Parses binary data into a Record object based on the provided magic byte and version. ```python parse_record(magic: int, data: bytes, version: int, *, product_type: Any = None) -> Record ``` -------------------------------- ### Decrypt and iterate frames Source: https://rembish.github.io/pydjirecord/guide/library Fetch keychains from the DJI API for v13+ logs to decrypt and iterate through flight frames. ```python # Decrypt and iterate frames (v13+ needs keychains from the DJI API) keychains = log.fetch_keychains("YOUR_API_KEY") if log.version >= 13 else None # Pass verify=False if you get a TLS certificate error: # keychains = log.fetch_keychains("YOUR_API_KEY", verify=False) frames = log.frames(keychains) for frame in frames: print(frame.osd.latitude, frame.osd.longitude, frame.osd.altitude) print(frame.battery.voltage, frame.battery.charge_level, frame.battery.lifetime_remaining) print(frame.gimbal.pitch, frame.gimbal.yaw) ``` -------------------------------- ### Serialize Request to Dictionary Source: https://rembish.github.io/pydjirecord/api/keychain Converts the request object into a dictionary format for the DJI API. ```python to_dict() -> dict[str, Any] ``` -------------------------------- ### Custom Dataclass and Parsing Source: https://rembish.github.io/pydjirecord/api/records Defines the Custom record structure containing a timestamp and its parsing method. ```python Custom(update_timestamp: datetime) ``` ```python from_bytes(data: bytes, version: int = 0) -> Custom ``` -------------------------------- ### AppSeriousWarn Record Structure and Parsing Source: https://rembish.github.io/pydjirecord/api/records Defines the AppSeriousWarn dataclass for serious warning records and its parsing method. ```python AppSeriousWarn(message: str) ``` ```python from_bytes(data: bytes, version: int = 0) -> AppSeriousWarn ``` -------------------------------- ### FrameBattery Dataclass Source: https://rembish.github.io/pydjirecord/api/frames Represents normalized battery frame data. ```python FrameBattery(charge_level: int = 0, voltage: float = 0.0, current: float = 0.0, design_capacity: int = 0, current_capacity: int = 0, full_capacity: int = 0, cell_num: int = 0, is_cell_voltage_estimated: bool = True, cell_voltages: list[float] = list(), cell_voltage_deviation: float = 0.0, max_cell_voltage_deviation: float = 0.0, temperature: float = 0.0, min_temperature: float = 0.0, max_temperature: float = 0.0, number_of_discharges: int = 0, lifetime_remaining: int = 0) ``` -------------------------------- ### FrameDetails Dataclass Source: https://rembish.github.io/pydjirecord/api/frames Provides simplified details for frame-mode exports. Note that fields like latitude, longitude, total_distance, photo_num, and video_time may be computed from frame data if available, otherwise falling back to raw header values. ```python FrameDetails(latitude: float = 0.0, longitude: float = 0.0, total_time: float = 0.0, total_distance: float = 0.0, max_height: float = 0.0, max_horizontal_speed: float = 0.0, max_vertical_speed: float = 0.0, photo_num: int = 0, video_time: float = 0.0, aircraft_name: str = '', aircraft_sn: str = '', camera_sn: str = '', rc_sn: str = '', app_platform: Platform | None = None, app_version: str = '', anomaly: FlightAnomaly | None = None, rc_signal: RCSignalStats | None = None) ``` -------------------------------- ### xor_decode Source: https://rembish.github.io/pydjirecord/api/decoder XOR-decodes data using a CRC64-derived 8-byte key. The first byte is consumed for key derivation and excluded from the output. ```APIDOC ## xor_decode(data: bytes, record_type: int) -> bytes ### Description XOR-decode data using a CRC64-derived 8-byte key. The first byte is consumed for key derivation and excluded from the output. ### Parameters - **data** (bytes) - Required - The data to decode. - **record_type** (int) - Required - The type of record. ### Returns - **bytes** - The decoded data. ``` -------------------------------- ### Access FeaturePoint API Name Source: https://rembish.github.io/pydjirecord/api/keychain Retrieves the string name used for DJI API serialization. ```python api_name: str ``` -------------------------------- ### FrameApp Dataclass Source: https://rembish.github.io/pydjirecord/api/frames Represents normalized application message frame data. ```python FrameApp(tip: str = '', warn: str = '') ``` -------------------------------- ### Recover Dataclass and Parsing Source: https://rembish.github.io/pydjirecord/api/records Defines the Recover record structure for aircraft identification and its parsing method. ```python Recover(product_type: ProductType, app_platform: Platform, app_version: str, aircraft_sn: str, aircraft_name: str, camera_sn: str, rc_sn: str, battery_sn: str) ``` ```python from_bytes(data: bytes, version: int) -> Recover ``` -------------------------------- ### MissingAuxiliaryDataError instantiation Source: https://rembish.github.io/pydjirecord/api/errors Represents an error when a required auxiliary block is missing, initialized with the block type. ```python MissingAuxiliaryDataError(block_type: str) ``` -------------------------------- ### Export flight data to JSON Source: https://rembish.github.io/pydjirecord/api/export Exports flight data as a JSON string. Supports raw records, normalized frames, or legacy details-only modes depending on the provided arguments. ```python export_json(log: DJILog, frames: list[Frame] | None = None, raw_records: list[Record] | None = None, output: Path | None = None) -> str ``` -------------------------------- ### Compute accurate flight statistics Source: https://rembish.github.io/pydjirecord/guide/library Use FrameDetails to automatically correct unreliable header fields using decoded frames. ```python from pydjirecord import DJILog from pydjirecord.frame.details import FrameDetails data = open("flight.txt", "rb").read() log = DJILog.from_bytes(data) keychains = log.fetch_keychains("YOUR_API_KEY") if log.version >= 13 else None frames = log.frames(keychains) # FrameDetails computes all corrected values from frames automatically details = FrameDetails.from_details(log.details, frames) print(details.latitude) # from header, or first valid OSD GPS fix if header is 0,0 print(details.longitude) # same print(details.total_distance) # cumulative GPS track length from frames print(details.photo_num) # computed from Camera remain_photo_num delta print(details.video_time) # computed from Camera record_time segments ``` -------------------------------- ### Export flight data to GeoJSON Source: https://rembish.github.io/pydjirecord/api/export Converts flight frames into a GeoJSON Feature object utilizing LineString geometry. ```python export_geojson(frames: list[Frame], details: Details, output: TextIO = sys.stdout) -> None ``` -------------------------------- ### Record decode function signature Source: https://rembish.github.io/pydjirecord/api/decoder Decodes record data by applying XOR for versions 7-12 and XOR+AES for versions 13 and above. ```python record_decode(data: bytes, record_type: int, version: int, keychain: Keychain | None) -> bytes ``` -------------------------------- ### AppGPS Record Structure and Parsing Source: https://rembish.github.io/pydjirecord/api/records Defines the AppGPS dataclass for latitude and longitude records and its parsing method. ```python AppGPS(latitude: float, longitude: float) ``` ```python from_bytes(data: bytes, version: int = 0) -> AppGPS ``` -------------------------------- ### FrameCustom Dataclass Source: https://rembish.github.io/pydjirecord/api/frames Represents custom frame data containing a timestamp. ```python FrameCustom(date_time: datetime = (lambda: datetime(1970, 1, 1, tzinfo=(timezone.utc)))()) ``` -------------------------------- ### MCParams Dataclass Definition Source: https://rembish.github.io/pydjirecord/api/records Defines the structure for flight-controller parameters. ```python MCParams(fail_safe_protection: FailSafeProtectionType, mvo_func_enabled: bool, avoid_obstacle_enabled: bool, user_avoid_enabled: bool) ``` -------------------------------- ### RCGPS from_bytes Method Source: https://rembish.github.io/pydjirecord/api/records Parses RC GPS record from binary data. ```python from_bytes(data: bytes) -> RCGPS ``` -------------------------------- ### ComponentSerial Dataclass Definition Source: https://rembish.github.io/pydjirecord/api/records Defines the structure for component serial number records. ```python ComponentSerial(component_type: ComponentType, serial: str) ``` -------------------------------- ### Update Keychain IV Source: https://rembish.github.io/pydjirecord/api/keychain Updates the IV for a feature point to support IV chaining after decryption. ```python update_iv(fp: int, iv: bytes) -> None ``` -------------------------------- ### FrameGimbal Dataclass Source: https://rembish.github.io/pydjirecord/api/frames Represents normalized gimbal frame data. ```python FrameGimbal(mode: GimbalMode | None = None, pitch: float = 0.0, roll: float = 0.0, yaw: float = 0.0, is_pitch_at_limit: bool = False, is_roll_at_limit: bool = False, is_yaw_at_limit: bool = False, is_stuck: bool = False) ``` -------------------------------- ### parse_record Source: https://rembish.github.io/pydjirecord/api/records Parses record data from a binary stream based on a magic byte. ```APIDOC ## parse_record(magic: int, data: bytes, version: int, *, product_type: Any = None) -> Record ### Description Parses record data based on a magic byte. Returns a Record object containing either a parsed struct or raw bytes for unknown types. ### Parameters - **magic** (int) - The magic byte identifying the record type. - **data** (bytes) - The raw binary data to parse. - **version** (int) - The version of the record format. - **product_type** (Any) - Optional product type identifier. ### Returns - **Record** (dataclass) - A parsed record containing the record type and data. ``` -------------------------------- ### Record Dataclass Definition Source: https://rembish.github.io/pydjirecord/api/records Represents a parsed record from the binary log stream containing a type identifier and data. ```python Record(record_type: int, data: Any) ``` -------------------------------- ### Detect flight anomalies Source: https://rembish.github.io/pydjirecord/guide/library Classify flight anomalies using FrameDetails or direct computation functions. ```python details = FrameDetails.from_details(log.details, frames) if details.anomaly and details.anomaly.severity != FlightSeverity.GREEN: print(f"Severity: {details.anomaly.severity.name}") print(f"Actions: {[a.name for a in details.anomaly.actions]}") print(f"Motor blocked: {details.anomaly.motor_blocked}") print(f"Max descent: {details.anomaly.max_descent_speed:.1f} m/s") ``` ```python from pydjirecord.frame.builder import compute_flight_anomalies from pydjirecord.frame.anomaly import FlightSeverity anomaly = compute_flight_anomalies(frames) if anomaly.severity == FlightSeverity.RED: print("Critical flight anomaly detected") ``` -------------------------------- ### Details Dataclass Definition Source: https://rembish.github.io/pydjirecord/api/layout Flight metadata parsed from the log Details header block. ```python Details(sub_street: str = '', street: str = '', city: str = '', area: str = '', is_favorite: bool = False, is_new: bool = False, needs_upload: bool = False, record_line_count: int = 0, detail_info_checksum: int = 0, start_time: datetime = (lambda: datetime(1970, 1, 1, tzinfo=(timezone.utc)))(), longitude: float = 0.0, latitude: float = 0.0, total_distance: float = 0.0, total_time: float = 0.0, max_height: float = 0.0, max_horizontal_speed: float = 0.0, max_vertical_speed: float = 0.0, capture_num: int = 0, video_time: int = 0, moment_pic_longitude: list[float] = (lambda: [0.0] * 4)(), moment_pic_latitude: list[float] = (lambda: [0.0] * 4)(), take_off_altitude: float = 0.0, product_type: ProductType = ProductType.NONE, aircraft_name: str = '', aircraft_sn: str = '', camera_sn: str = '', rc_sn: str = '', battery_sn: str = '', app_platform: Platform = (lambda: Platform(0))(), app_version: str = '') ``` -------------------------------- ### FrameRecover Dataclass Source: https://rembish.github.io/pydjirecord/api/frames Represents normalized aircraft metadata frame data. ```python FrameRecover(app_platform: Platform | None = None, app_version: str = '', aircraft_name: str = '', aircraft_sn: str = '', camera_sn: str = '', rc_sn: str = '', battery_sn: str = '') ``` -------------------------------- ### FrameCamera Dataclass Source: https://rembish.github.io/pydjirecord/api/frames Represents normalized camera frame data. ```python FrameCamera(is_photo: bool = False, is_video: bool = False, sd_card_is_inserted: bool = False, sd_card_state: SDCardState | None = None, record_time: int = 0, remain_photo_num: int = 0) ``` -------------------------------- ### export_json Source: https://rembish.github.io/pydjirecord/api/export Exports flight data as a JSON string. Supports raw records, normalized frames, or legacy details-only modes. ```APIDOC ## export_json(log: DJILog, frames: list[Frame] | None = None, raw_records: list[Record] | None = None, output: Path | None = None) -> str ### Description Export as JSON. Returns the JSON string. If raw_records is provided, exports raw records mode. If frames is provided, exports normalized frames mode. Otherwise, exports details-only mode (legacy). ### Parameters - **log** (DJILog) - Required - The DJI log object. - **frames** (list[Frame] | None) - Optional - List of normalized frames. - **raw_records** (list[Record] | None) - Optional - List of raw records. - **output** (Path | None) - Optional - File path for output. ``` -------------------------------- ### OSD Dataclass Definition Source: https://rembish.github.io/pydjirecord/api/records Contains primary flight telemetry data including positioning, speed, orientation, and status flags. ```python OSD(longitude: float, latitude: float, altitude: float, speed_x: float, speed_y: float, speed_z: float, pitch: float, roll: float, yaw: float, flight_mode: FlightMode, rc_outcontrol: bool, app_command: AppCommand, can_ioc_work: bool, ground_or_sky: GroundOrSky, is_motor_up: bool, is_swave_work: bool, go_home_status: GoHomeStatus, is_vision_used: bool, voltage_warning: int, is_imu_preheated: bool, is_gps_valid: bool, is_compass_error: bool, wave_error: bool, gps_level: int, battery_type: BatteryType, is_out_of_limit: bool, is_go_home_height_modified: bool, is_propeller_catapult: bool, is_motor_blocked: bool, is_not_enough_force: bool, is_barometer_dead_in_air: bool, is_vibrating: bool, is_acceletor_over_range: bool, gps_num: int, flight_action: FlightAction, motor_start_failed_cause: MotorStartFailedCause, non_gps_cause: NonGPSCause, battery: int, s_wave_height: float, fly_time: float, drone_type: DroneType, imu_init_fail_reason: ImuInitFailReason) ``` -------------------------------- ### FrameRC Dataclass Source: https://rembish.github.io/pydjirecord/api/frames Represents normalized remote control frame data. ```python FrameRC(downlink_signal: int | None = None, uplink_signal: int | None = None, aileron: int = 0, elevator: int = 0, throttle: int = 0, rudder: int = 0) ``` -------------------------------- ### OFDM Dataclass Definition Source: https://rembish.github.io/pydjirecord/api/records Defines the structure for OFDM radio signal records. ```python OFDM(signal_percent: int, is_up: bool) ``` -------------------------------- ### XOR decode function signature Source: https://rembish.github.io/pydjirecord/api/decoder Decodes data using a CRC64-derived 8-byte key. The first byte is consumed for key derivation and excluded from the output. ```python xor_decode(data: bytes, record_type: int) -> bytes ``` -------------------------------- ### DJI API Keychains Endpoint Source: https://rembish.github.io/pydjirecord/encryption The endpoint used to fetch AES keys for decrypting v13-14 flight records. ```text https://dev.dji.com/openapi/v1/flight-records/keychains ``` -------------------------------- ### AES decode function signature Source: https://rembish.github.io/pydjirecord/api/decoder Decrypts data using AES-256-CBC and returns the plaintext along with the next IV for chaining. ```python aes_decode(data: bytes, iv: bytes, key: bytes) -> tuple[bytes, bytes] ``` -------------------------------- ### export_geojson Source: https://rembish.github.io/pydjirecord/api/export Exports flight frames as a GeoJSON Feature containing a LineString geometry. ```APIDOC ## export_geojson(frames: list[Frame], details: Details, output: TextIO = sys.stdout) -> None ### Description Export frames as a GeoJSON Feature with LineString geometry. ### Parameters - **frames** (list[Frame]) - Required - The list of flight frames to export. - **details** (Details) - Required - The flight details object. - **output** (TextIO) - Optional - The output stream (defaults to sys.stdout). ``` -------------------------------- ### RCGPS Dataclass Definition Source: https://rembish.github.io/pydjirecord/api/records Defines the structure for remote controller GPS data, including latitude and longitude in decimal degrees. ```python RCGPS(time: RCGPSTime, latitude: float, longitude: float, velocity_x: int, velocity_y: int, gps_num: int, accuracy: float, valid_data: int) ``` -------------------------------- ### FlightAnomaly Dataclass Definition Source: https://rembish.github.io/pydjirecord/api/frames Represents the result of a flight anomaly detection process. ```python FlightAnomaly(severity: FlightSeverity = FlightSeverity.GREEN, actions: list[FlightAction] = list(), motor_blocked: bool = False, max_descent_speed: float = 0.0, final_altitude: float = 0.0, gps_degraded_ratio: float = 0.0) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.