"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.mapOsCommandResponse = exports.kublerEncoderSubcommands = exports.smmAcyclicHandlerSubcommands = exports.osCommands = exports.kublerEncoderRegisterValueMeaning = exports.kublerEncoderRegisterCommunicationWriteOsCommandErrors = exports.kublerEncoderRegisterCommunicationReadOsCommandErrors = exports.createKublerEncoderRegisterCommunicationOsCommand = exports.createUseInternalEncoderVelocityOsCommand = exports.kublerEncoderCommandOsCommandErrors = exports.createKublerEncoderCommandWriteFirmwareOsCommand = exports.createKublerEncoderCommandCheckFirmwareUpdateSizeOsCommand = exports.createKublerEncoderOsCommand = exports.KublerEncoderSubcommandId = exports.triggerErrorTypes = exports.createTriggerErrorOsCommand = exports.systemIdentificationParameters = exports.SystemIdentificationOsCommandStartProcedure = exports.SystemIdentificationOsCommandSignalType = exports.createSystemIdentificationOsCommand = exports.createIgnoreBissStatusBitsOsCommand = exports.createSkippedCyclesCounterOsCommand = exports.createSmmAcyclicHandlerConfigureSoftwareUpdateOsCommand = exports.createSmmAcyclicHandlerReadSmmParameterOsCommand = exports.createSmmAcyclicHandlerOsCommand = exports.createTorqueConstantMeasurementOsCommand = exports.createPhaseInductanceMeasurementOsCommand = exports.createPhaseResistanceMeasurementOsCommand = exports.createPolePairDetectionOsCommand = exports.openPhaseDetectionErrors = exports.createOpenPhaseDetectionOsCommand = exports.createCommutationOffsetMeasurementOsCommand = exports.createMotorPhaseOrderDetectionOsCommand = exports.convertHrdSamplesToCsv = exports.parseHrdBuffer = exports.hrdStreamingOsCommandErrors = exports.createHrdStreamingOsCommand = exports.HrdStreamingOsCommandDataIndex = exports.HrdStreamingOsCommandAction = exports.openLoopFieldModeParameters = exports.createOpenLoopFieldModeOsCommand = exports.createIcMuCalibrationModeOsCommand = exports.createEncoderRegisterCommunicationOsCommand = exports.createOsCommandTypedArray = exports.osCommandErrorCode = exports.SmmAcyclicHandlerSubcommandId = exports.OsCommandId = exports.OsCommandMode = exports.parseOsCommandResponse = exports.isOsCommandResponse = void 0;
const rxjs_1 = require("rxjs");
const util_1 = require("./util");
/**
 * Type guard to determine if the provided value is a OS Command Response object.
 */
function isOsCommandResponse(value) {
    return (value === null || value === void 0 ? void 0 : value.command) instanceof Uint8Array;
}
exports.isOsCommandResponse = isOsCommandResponse;
function parseOsCommandResponse(response, command) {
    const status = response.at(0);
    if (status === undefined) {
        throw new Error(`No status is available in the typed array response ${JSON.stringify(response)}`);
    }
    let data;
    let errorCode;
    let errorName;
    let errorDescription;
    let progress;
    let request = 'started';
    // Determine the status of the OS command.
    if (status === 0 || status === 1) {
        request = 'succeeded';
    }
    else if (status === 2 || status === 3) {
        request = 'failed';
    }
    else if ((status >= 100 && status <= 200) || status === 255) {
        request = 'running';
    }
    else {
        throw new Error(`Unknown OS command response status: ${status}`);
    }
    // Command in progress with percentage.
    if (status >= 100 && status <= 200) {
        progress = status - 100;
    }
    // Command completed with error and with response.
    if (status === 3) {
        errorCode = response.at(2);
        if (errorCode !== undefined) {
            errorName = exports.osCommandErrorCode[errorCode];
        }
    }
    if (status === 1) {
        // 6 bytes for data when last command completed, no errors, response data available
        data = Array.from(response.slice(2));
    }
    else if (status === 3) {
        // 5 bytes for data when last command completed, error, response data available
        data = Array.from(response.slice(3));
    }
    return { command, data, errorCode, errorName, errorDescription, progress, request, response };
}
exports.parseOsCommandResponse = parseOsCommandResponse;
var OsCommandMode;
(function (OsCommandMode) {
    OsCommandMode[OsCommandMode["EXECUTE_THE_NEXT_COMMAND_IMMEDIATELY"] = 0] = "EXECUTE_THE_NEXT_COMMAND_IMMEDIATELY";
    OsCommandMode[OsCommandMode["ABORT_THE_CURRENT_COMMAND_AND_ALL_COMMANDS_IN_THE_BUFFER"] = 3] = "ABORT_THE_CURRENT_COMMAND_AND_ALL_COMMANDS_IN_THE_BUFFER";
})(OsCommandMode = exports.OsCommandMode || (exports.OsCommandMode = {}));
var OsCommandId;
(function (OsCommandId) {
    OsCommandId[OsCommandId["CUSTOM_OS_COMMAND"] = -1] = "CUSTOM_OS_COMMAND";
    OsCommandId[OsCommandId["ENCODER_REGISTER_COMMUNICATION"] = 0] = "ENCODER_REGISTER_COMMUNICATION";
    OsCommandId[OsCommandId["ICMU_CALIBRATION_MODE"] = 1] = "ICMU_CALIBRATION_MODE";
    OsCommandId[OsCommandId["OPEN_LOOP_FIELD_MODE"] = 2] = "OPEN_LOOP_FIELD_MODE";
    OsCommandId[OsCommandId["HRD_STREAMING"] = 3] = "HRD_STREAMING";
    OsCommandId[OsCommandId["MOTOR_PHASE_ORDER_DETECTION"] = 4] = "MOTOR_PHASE_ORDER_DETECTION";
    OsCommandId[OsCommandId["COMMUTATION_OFFSET_MEASUREMENT"] = 5] = "COMMUTATION_OFFSET_MEASUREMENT";
    OsCommandId[OsCommandId["OPEN_PHASE_DETECTION"] = 6] = "OPEN_PHASE_DETECTION";
    OsCommandId[OsCommandId["POLE_PAIR_DETECTION"] = 7] = "POLE_PAIR_DETECTION";
    OsCommandId[OsCommandId["PHASE_RESISTANCE_MEASUREMENT"] = 8] = "PHASE_RESISTANCE_MEASUREMENT";
    OsCommandId[OsCommandId["PHASE_INDUCTANCE_MEASUREMENT"] = 9] = "PHASE_INDUCTANCE_MEASUREMENT";
    OsCommandId[OsCommandId["TORQUE_CONSTANT_MEASUREMENT"] = 10] = "TORQUE_CONSTANT_MEASUREMENT";
    OsCommandId[OsCommandId["SMM_ACYCLIC_HANDLER"] = 11] = "SMM_ACYCLIC_HANDLER";
    OsCommandId[OsCommandId["SKIPPED_CYCLED_COUNTER"] = 13] = "SKIPPED_CYCLED_COUNTER";
    OsCommandId[OsCommandId["IGNORE_BISS_STATUS_BITS"] = 14] = "IGNORE_BISS_STATUS_BITS";
    OsCommandId[OsCommandId["SYSTEM_IDENTIFICATION"] = 15] = "SYSTEM_IDENTIFICATION";
    OsCommandId[OsCommandId["TRIGGER_ERROR"] = 16] = "TRIGGER_ERROR";
    OsCommandId[OsCommandId["KUBLER_ENCODER_COMMAND"] = 17] = "KUBLER_ENCODER_COMMAND";
    OsCommandId[OsCommandId["USE_INTERNAL_ENCODER_VELOCITY"] = 18] = "USE_INTERNAL_ENCODER_VELOCITY";
    OsCommandId[OsCommandId["KUBLER_ENCODER_REGISTER_COMMUNICATION"] = 19] = "KUBLER_ENCODER_REGISTER_COMMUNICATION";
})(OsCommandId = exports.OsCommandId || (exports.OsCommandId = {}));
var SmmAcyclicHandlerSubcommandId;
(function (SmmAcyclicHandlerSubcommandId) {
    SmmAcyclicHandlerSubcommandId[SmmAcyclicHandlerSubcommandId["PARAMETER_DOWNLOAD_LOGIN"] = 1] = "PARAMETER_DOWNLOAD_LOGIN";
    SmmAcyclicHandlerSubcommandId[SmmAcyclicHandlerSubcommandId["TRANSMIT_PARAMETERS"] = 2] = "TRANSMIT_PARAMETERS";
    SmmAcyclicHandlerSubcommandId[SmmAcyclicHandlerSubcommandId["LOAD_PARAMETERS_FOR_VERIFICATION"] = 3] = "LOAD_PARAMETERS_FOR_VERIFICATION";
    SmmAcyclicHandlerSubcommandId[SmmAcyclicHandlerSubcommandId["VERIFY_PARAMETERS"] = 4] = "VERIFY_PARAMETERS";
    SmmAcyclicHandlerSubcommandId[SmmAcyclicHandlerSubcommandId["LOAD_VALIDATION_FILE"] = 5] = "LOAD_VALIDATION_FILE";
    SmmAcyclicHandlerSubcommandId[SmmAcyclicHandlerSubcommandId["VALIDATE_CONFIGURATION"] = 6] = "VALIDATE_CONFIGURATION";
    SmmAcyclicHandlerSubcommandId[SmmAcyclicHandlerSubcommandId["CHANGE_PASSWORD"] = 7] = "CHANGE_PASSWORD";
    SmmAcyclicHandlerSubcommandId[SmmAcyclicHandlerSubcommandId["LOGOUT"] = 8] = "LOGOUT";
    SmmAcyclicHandlerSubcommandId[SmmAcyclicHandlerSubcommandId["SOFTWARE_UPDATE_LOGIN"] = 9] = "SOFTWARE_UPDATE_LOGIN";
    SmmAcyclicHandlerSubcommandId[SmmAcyclicHandlerSubcommandId["CONFIGURE_SOFTWARE_UPDATE"] = 10] = "CONFIGURE_SOFTWARE_UPDATE";
    SmmAcyclicHandlerSubcommandId[SmmAcyclicHandlerSubcommandId["TRANSMIT_SOFTWARE"] = 11] = "TRANSMIT_SOFTWARE";
    SmmAcyclicHandlerSubcommandId[SmmAcyclicHandlerSubcommandId["FINALIZE_SOFTWARE_UPDATE"] = 12] = "FINALIZE_SOFTWARE_UPDATE";
    SmmAcyclicHandlerSubcommandId[SmmAcyclicHandlerSubcommandId["READ_SMM_PARAMETER"] = 13] = "READ_SMM_PARAMETER";
    SmmAcyclicHandlerSubcommandId[SmmAcyclicHandlerSubcommandId["IO_FAILURE_ACKNOWLEDGE"] = 14] = "IO_FAILURE_ACKNOWLEDGE";
    SmmAcyclicHandlerSubcommandId[SmmAcyclicHandlerSubcommandId["TRIGGER_RESTART"] = 15] = "TRIGGER_RESTART";
})(SmmAcyclicHandlerSubcommandId = exports.SmmAcyclicHandlerSubcommandId || (exports.SmmAcyclicHandlerSubcommandId = {}));
exports.osCommandErrorCode = {
    251: 'Command not allowed',
    252: 'Command aborted',
    253: 'Command timeout',
    254: 'Command unsupported',
};
function createOsCommandTypedArray(elements) {
    return new Uint8Array(elements.concat(new Array(8 - elements.length).fill(0)));
}
exports.createOsCommandTypedArray = createOsCommandTypedArray;
/**
 * OS command 0: Encoder register communication
 *
 * This OS command is utilized for reading or writing registers from an encoder service.
 * Presently, the only service supporting this functionality is BiSS, but it can be easily extended to other encoder services.
 * For more information on how BiSS register communication operates, please consult the official BiSS C Interface Protocol Description.
 *
 * |        | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
 * |--------|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|
 * | Byte 0 |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |
 * | Byte 1 |   -   |   -   |   -   |   -   |   -   |   A   |   A   |   A   |
 * | Byte 2 |   B   |   B   |   B   |   B   |   B   |   B   |   B   |   C   |
 * | Byte 3 |   D   |   D   |   D   |   D   |   D   |   D   |   D   |   D   |
 * | Byte 4 |   E   |   E   |   E   |   E   |   E   |   E   |   E   |   E   |
 * | Byte 5 |   -   |   -   |   -   |   -   |   -   |   -   |   -   |   -   |
 * | Byte 6 |   -   |   -   |   -   |   -   |   -   |   -   |   -   |   -   |
 * | Byte 7 |   -   |   -   |   -   |   -   |   -   |   -   |   -   |   -   |
 *
 * @param encoderOrdinal (A) 2^3=8 encoder ordinals. Counting starts from 1, so '1' refers to Encoder 1 configured in 0x2110.
 * @param slaveAddress (B) 2^7=128 slave addresses. Select the address of the slave to read (BiSS protocol level). Since our BiSS service doesn't support multiple slaves in the same device, this value should always be 0.
 * @param rw (C) Read or write the encoder register. Select the direction of the command: 0 for reading a register, and 1 for writing it.
 * @param registerAddress (D) Register to be read/written.
 * @param registerWriteValue (E) The value to write to the register. This value is ignored when reading a register (when rw is set to 0).
 */
function createEncoderRegisterCommunicationOsCommand(encoderOrdinal = 1, slaveAddress = 0, rw = 0, registerAddress = 0, registerWriteValue = 0) {
    const byte2 = (slaveAddress << 1) | rw;
    const elements = [
        OsCommandId.ENCODER_REGISTER_COMMUNICATION,
        encoderOrdinal,
        byte2,
        registerAddress,
        registerWriteValue,
    ];
    return createOsCommandTypedArray(elements);
}
exports.createEncoderRegisterCommunicationOsCommand = createEncoderRegisterCommunicationOsCommand;
/**
 * OS command 1: iC-MU calibration mode
 *
 * This command is used to set a particular BiSS mode when using an iC-MU encoder, which is primarily employed for iC-MU calibration.
 *
 * The supported modes are explained below:
 *
 * **Configuration mode**: The BiSS service clocks the encoder normally, but it only utilizes the bits for register communication and discards the rest,
 * thereby not updating the encoder data.
 * This also implies that the BisCrc error is not triggered while in this mode.
 * This mode is intended to allow the user to change the configuration in the encoder BiSS registers without encountering a BisCrc error.
 *
 * **Raw mode**: The BiSS service clocks the encoder assuming it was correctly configured for raw mode.
 * It continues to calculate all the encoder data, but additionally, it averages the raw data and makes it available in 0x2704 User MISO, as follows:
 *
 * <table border="1">
 *   <tr>
 *     <td>31</td>
 *     <td>30</td>
 *     <td>29</td>
 *     <td>28</td>
 *     <td>27</td>
 *     <td>26</td>
 *     <td>25</td>
 *     <td>24</td>
 *     <td>23</td>
 *     <td>22</td>
 *     <td>21</td>
 *     <td>20</td>
 *     <td>19</td>
 *     <td>18</td>
 *     <td>17</td>
 *     <td>16</td>
 *     <td>15</td>
 *     <td>14</td>
 *     <td>13</td>
 *     <td>12</td>
 *     <td>11</td>
 *     <td>10</td>
 *     <td>9</td>
 *     <td>8</td>
 *     <td>7</td>
 *     <td>6</td>
 *     <td>5</td>
 *     <td>4</td>
 *     <td>3</td>
 *     <td>2</td>
 *     <td>1</td>
 *     <td>0</td>
 *   </tr>
 *   <tr>
 *     <td colspan="4" style="text-align: center;">0</td>
 *     <td colspan="14" style="text-align: center;">Nonius count</td>
 *     <td colspan="14" style="text-align: center;">Master count</td>
 *   </tr>
 * </table>
 *
 * This data can also be read by using OS command 3.
 *
 * **Standard mode**: The BiSS service clocks the encoder normally.
 *
 * When transitioning from any mode to Configuration mode, the current position is saved.
 * If we subsequently switch to Raw mode, this saved position serves as the starting point for position calculation because the raw data is relative.
 * Therefore, the motor should not be moved while in Configuration mode if there are plans to switch to Raw mode afterward.
 *
 * @param encoderOrdinal (A) 2^3=8 encoder ordinals. Counting starts from 1, so '1' refers to Encoder 1 configured in 0x2110.
 * @param modeEnable: Select the iC-MU calibration mode. Configuration mode is 0, raw mode is 1, and standard mode is 2.
 */
function createIcMuCalibrationModeOsCommand(encoderOrdinal = 1, modeEnable = 0) {
    const byte2 = (modeEnable << 3) | encoderOrdinal;
    const elements = [OsCommandId.ICMU_CALIBRATION_MODE, byte2];
    return createOsCommandTypedArray(elements);
}
exports.createIcMuCalibrationModeOsCommand = createIcMuCalibrationModeOsCommand;
function createOpenLoopFieldModeOsCommand(parameterIndex = 0, parameterValue = 0) {
    let msb = (parameterValue >> 24) & 0xff;
    let msb1 = (parameterValue >> 16) & 0xff;
    let msb2 = (parameterValue >> 8) & 0xff;
    let lsb = parameterValue & 0xff;
    const elements = [OsCommandId.OPEN_LOOP_FIELD_MODE, parameterIndex, msb, msb1, msb2, lsb];
    return createOsCommandTypedArray(elements);
}
exports.createOpenLoopFieldModeOsCommand = createOpenLoopFieldModeOsCommand;
exports.openLoopFieldModeParameters = [
    { parameterIndex: 0, parameterName: 'Starting electrical angle [mrad]' },
    { parameterIndex: 1, parameterName: 'Ending electrical angle [mrad]' },
    { parameterIndex: 2, parameterName: 'Maximum electrical rotational speed [rad / s]' },
    { parameterIndex: 3, parameterName: 'Electrical rotational acceleration [rad / s²]' },
    { parameterIndex: 4, parameterName: 'Starting length [per thousand rated current]' },
    { parameterIndex: 5, parameterName: 'Ending length [per thousand rated current]' },
    { parameterIndex: 6, parameterName: 'Increasing length rate [per thousand rated current / s]' },
];
/**
 * Enum for selecting the action to perform in HRD streaming.
 */
var HrdStreamingOsCommandAction;
(function (HrdStreamingOsCommandAction) {
    /**
     * Deletes all previous HRD files from the filesystem.
     * The user then configures the stream duration and the variable to stream.
     * File deletion may take up to approximately 5 seconds in the worst-case scenario.
     */
    HrdStreamingOsCommandAction[HrdStreamingOsCommandAction["CONFIGURE_STREAM"] = 0] = "CONFIGURE_STREAM";
    /**
     * Starts the stream using the previously configured settings.
     */
    HrdStreamingOsCommandAction[HrdStreamingOsCommandAction["START_STREAM"] = 1] = "START_STREAM";
})(HrdStreamingOsCommandAction = exports.HrdStreamingOsCommandAction || (exports.HrdStreamingOsCommandAction = {}));
/**
 * Enum for selecting the data to stream.
 *
 * This value is used only when the selected Action is Configure Stream (0).
 */
var HrdStreamingOsCommandDataIndex;
(function (HrdStreamingOsCommandDataIndex) {
    /**
     * Record raw encoder data.
     *
     * The encoder must be set up first using OS command 1.
     */
    HrdStreamingOsCommandDataIndex[HrdStreamingOsCommandDataIndex["ENCODER_RAW_DATA"] = 0] = "ENCODER_RAW_DATA";
    /**
     * Record system identification data.
     *
     * The identification procedure must be configured with OS command 15 and started before recording.
     */
    HrdStreamingOsCommandDataIndex[HrdStreamingOsCommandDataIndex["SYSTEM_IDENTIFICATION_DATA"] = 1] = "SYSTEM_IDENTIFICATION_DATA";
})(HrdStreamingOsCommandDataIndex = exports.HrdStreamingOsCommandDataIndex || (exports.HrdStreamingOsCommandDataIndex = {}));
function createHrdStreamingOsCommand(action = 0, dataIndex = 0, duration = 10000) {
    let msb = (duration >> 8) & 0xff;
    let lsb = duration & 0xff;
    const elements = [OsCommandId.HRD_STREAMING, action, dataIndex, msb, lsb];
    return createOsCommandTypedArray(elements);
}
exports.createHrdStreamingOsCommand = createHrdStreamingOsCommand;
exports.hrdStreamingOsCommandErrors = {
    0: {
        errorName: 'Initialization error',
        errorDescription: 'The command failed to initialize',
    },
    1: {
        errorName: 'Streaming error',
        errorDescription: 'Something failed while streaming was in progress',
    },
    2: {
        errorName: 'Duration value',
        errorDescription: 'The selected Duration value is larger than 10000ms',
    },
    3: {
        errorName: 'Data index value',
        errorDescription: 'The selected Data index is unknown',
    },
    4: {
        errorName: 'Action value',
        errorDescription: 'The selected Action is unknown',
    },
};
/**
 * Parses a binary HRD data buffer into an array of velocity/torque samples.
 *
 * Each sample in the buffer consists of:
 * - 4 bytes: velocity (signed 32-bit integer, little-endian, Q15 fixed-point format)
 * - 2 bytes: torque (signed 16-bit integer, little-endian)
 *
 * The function iterates through the buffer in 6-byte chunks, extracting
 * velocity and torque for each sample. The velocity is converted from
 * Q15 fixed-point format to a floating-point number and **rounded to an integer**.
 *
 * Each returned sample is a tuple of the form:
 * `[velocityQ15, torque, velocity]`, where:
 * - `velocityQ15` is the original 32-bit Q15 integer from the buffer
 * - `torque` is the 16-bit signed integer from the buffer
 * - `velocity` is the floating-point velocity value converted from Q15 and rounded to an integer
 *
 * If the buffer length is not a multiple of 6, a warning is logged and any trailing bytes are discarded.
 *
 * @param data - A `Uint8Array` containing raw HRD binary data.
 * @returns An array of `[velocityQ15, torque, velocity]` tuples one per sample.
 */
function parseHrdBuffer(data) {
    const bytesPerSample = 6;
    const validLength = data.byteLength - (data.byteLength % bytesPerSample);
    if (validLength !== data.byteLength) {
        console.warn(`HRD buffer length ${data.byteLength} is not a multiple of ${bytesPerSample}. ` +
            `Discarding ${data.byteLength - validLength} trailing byte(s).`);
    }
    const samples = [];
    const view = new DataView(data.buffer, data.byteOffset, validLength);
    let offset = 0;
    while (offset < validLength) {
        const velocityQ15 = view.getInt32(offset, true); // 4 bytes little-endian, Q15 format
        const torque = view.getInt16(offset + 4, true); // 2 bytes little-endian
        const velocity = (0, util_1.fromQ)(velocityQ15, 15, true); // converted from Q15 and rounded to an integer
        samples.push([velocityQ15, torque, velocity]);
        offset += bytesPerSample;
    }
    return samples;
}
exports.parseHrdBuffer = parseHrdBuffer;
/**
 * Converts a 2D array of HRD (High Resolution Data) samples into a CSV-formatted string.
 *
 * @param samples - A two-dimensional array where each inner array represents a single sample
 *   in the format `[velocityQ15, torque, velocity]`.
 * @returns A CSV string with a header row and one row per sample.
 *          Returns an empty string if no samples are provided.
 *
 * @example
 * ```ts
 * const samples = [
 *   [12345, 1.23, 100.5],
 *   [12346, 1.20, 101.2]
 * ];
 *
 * const csv = convertHrdSamplesToCsv(samples);
 * // "HRD Velocity (Q15),HRD Torque [‰],HRD Velocity [RPM]\n12345,1.23,100.5\n12346,1.20,101.2\n"
 * ```
 *
 * @remarks
 * - The CSV header is fixed as: `"HRD Velocity (Q15),HRD Torque [‰],HRD Velocity [RPM]"`.
 * - Each sample is written on a new line, with comma-separated values.
 */
function convertHrdSamplesToCsv(samples) {
    if (samples.length === 0) {
        return '';
    }
    const header = 'HRD Velocity (Q15),HRD Torque [‰],HRD Velocity [RPM]\n';
    const rows = samples.map(([velocityQ15, torque, velocity]) => {
        return `${velocityQ15},${torque},${velocity}\n`;
    });
    return header + rows.join('');
}
exports.convertHrdSamplesToCsv = convertHrdSamplesToCsv;
/**
 * Command 4: Motor phase order detection
 *
 * This command is used to detect the order of the motor phases.
 * When this command finishes successfully, the found value is automatically written to the object 0x2003:5 Motor phases inverted.
 * This command rotates the motor.
 *
 * This OS command has no arguments.
 *
 * When the command finishes successfully, it will return a value of 0 for normal and 1 for inverted motor phases.
 *
 * This command doesn't have any command-specific OS error code, so this status will only happen when a general OS error code occurs.
 *
 * This command will report its progress without indicating a percentage.
 *
 * This command can only be run when the opmode is -2 (OPMODE_DIAGNOSTICS), the CIA402 state is Operation enabled, there is no active limit switch,
 * and the brake status is disengaged (in case there is a configured brake). If any of these conditions is not true during the execution of the command,
 * the execution will stop, and it will return the OS error code 251 (command not allowed).
 */
function createMotorPhaseOrderDetectionOsCommand() {
    const elements = [OsCommandId.MOTOR_PHASE_ORDER_DETECTION];
    return createOsCommandTypedArray(elements);
}
exports.createMotorPhaseOrderDetectionOsCommand = createMotorPhaseOrderDetectionOsCommand;
/**
 * Command 5: Commutation offset measurement
 *
 * This command is used to measure the commutation angle offset.
 * The configuration of the procedure is derived from the pre-existing and previously used commutation offset objects in the object dictionary.
 * Upon successful completion of this command, the determined value is automatically written to:
 * - 0x2001:00 Commutation angle offset
 * - 0x2009:01 State is set to OFFSET_VALID
 *
 * In version 5.0, three different methods can be selected for command 5. These methods are named:
 * - Commutation offset measurement - method 0
 * - Commutation offset measurement - method 1
 * - Commutation offset measurement - method 2
 * Among these three methods, "method 0" and "method 1" involve rotating the rotor.
 *
 * This command can only be run when the opmode is -2 (OPMODE_DIAGNOSTICS) and the CIA402 state is Operation enabled.
 * Additionally, if the commutation offset measurement method (0x2009:3) is set to 0 or 1,
 * the command is permissible only when there are no active limit switches, and the brake status is disengaged (in case a brake is configured).
 * If any of these conditions is not met during the execution of the command, the execution will be halted,
 * and it will return the OS error code 251 (Command not allowed).
 */
function createCommutationOffsetMeasurementOsCommand() {
    const elements = [OsCommandId.COMMUTATION_OFFSET_MEASUREMENT];
    return createOsCommandTypedArray(elements);
}
exports.createCommutationOffsetMeasurementOsCommand = createCommutationOffsetMeasurementOsCommand;
/**
 * Command 6: Open phase detection
 *
 * This command is used to detect whether one of the phases is open.
 * It might rotate the motor if there is no brake or if it is disengaged.
 *
 * If this command finishes successfully, it indicates that all motor phases seem to be fine.
 *
 * This command can only be run when the opmode is -2 (OPMODE_DIAGNOSTICS), the CIA402 state is Operation enabled,
 * and there is no limit switch active. If any of these conditions is not true during the execution of the command,
 * the execution will stop, and it will return the OS error code 251 (Command not allowed).
 */
function createOpenPhaseDetectionOsCommand() {
    const elements = [OsCommandId.OPEN_PHASE_DETECTION];
    return createOsCommandTypedArray(elements);
}
exports.createOpenPhaseDetectionOsCommand = createOpenPhaseDetectionOsCommand;
exports.openPhaseDetectionErrors = {
    0: {
        errorName: 'Open terminal A',
        errorDescription: 'Terminal A of the Drive is not connected',
    },
    1: {
        errorName: 'Open terminal B',
        errorDescription: 'Terminal B of the Drive is not connected',
    },
    2: {
        errorName: 'Open terminal C',
        errorDescription: 'Terminal C of the Drive is not connected',
    },
    3: {
        errorName: 'Open FET A high',
        errorDescription: 'Upper FET in leg A of the Drive is not conducting (open circuit fault)',
    },
    4: {
        errorName: 'Open FET A low',
        errorDescription: 'Lower  FET in leg A of the Drive is not conducting (open circuit fault)',
    },
    5: {
        errorName: 'Open FET B high',
        errorDescription: 'Upper FET in leg B of the Drive is not conducting (open circuit fault)',
    },
    6: {
        errorName: 'Open FET B low',
        errorDescription: 'Lower  FET in leg B of the Drive is not conducting (open circuit fault)',
    },
    7: {
        errorName: 'Open FET C high',
        errorDescription: 'Upper FET in leg C of the Drive is not conducting (open circuit fault)',
    },
    8: {
        errorName: 'Open FET C low',
        errorDescription: 'Lower  FET in leg C of the Drive is not conducting (open circuit fault)',
    },
};
/**
 * Command 7: Pole pair detection
 *
 * This command is used to detect the number of pole pairs that the connected motor has.
 * It requires the rotation of the rotor.
 *
 * This command can only be run when the opmode is -2 (OPMODE_DIAGNOSTICS), the CIA402 state is Operation enabled,
 * and there is no limit switch active. If any of these conditions is not true during the execution of the command,
 * the execution will stop, and it will return the OS error code 251 (Command not allowed).
 */
function createPolePairDetectionOsCommand() {
    const elements = [OsCommandId.POLE_PAIR_DETECTION];
    return createOsCommandTypedArray(elements);
}
exports.createPolePairDetectionOsCommand = createPolePairDetectionOsCommand;
/**
 * Command 8: Phase resistance measurement
 *
 * This command is used to measure the phase resistance of the motor in milliohms (mΩ).
 * It might rotate the motor if there is no brake or if it is disengaged.
 *
 * This command can only be run when the opmode is -2 (OPMODE_DIAGNOSTICS), the CIA402 state is Operation enabled,
 * and there is no limit switch active. If any of these conditions is not true during the execution of the command,
 * the execution will stop, and it will return the OS error code 251 (Command not allowed).
 */
function createPhaseResistanceMeasurementOsCommand() {
    const elements = [OsCommandId.PHASE_RESISTANCE_MEASUREMENT];
    return createOsCommandTypedArray(elements);
}
exports.createPhaseResistanceMeasurementOsCommand = createPhaseResistanceMeasurementOsCommand;
/**
 * Command 9: Phase inductance measurement
 *
 * This command is used to measure the phase inductance of the motor in microhenries (μH).
 * It might rotate the motor if there is no brake or if it is disengaged.
 *
 * This command can only be run when the opmode is -2 (OPMODE_DIAGNOSTICS), the CIA402 state is Operation enabled,
 * and there is no limit switch active. If any of these conditions is not true during the execution of the command,
 * the execution will stop, and it will return the OS error code 251 (Command not allowed).
 */
function createPhaseInductanceMeasurementOsCommand() {
    const elements = [OsCommandId.PHASE_INDUCTANCE_MEASUREMENT];
    return createOsCommandTypedArray(elements);
}
exports.createPhaseInductanceMeasurementOsCommand = createPhaseInductanceMeasurementOsCommand;
function createTorqueConstantMeasurementOsCommand() {
    const elements = [OsCommandId.TORQUE_CONSTANT_MEASUREMENT];
    return createOsCommandTypedArray(elements);
}
exports.createTorqueConstantMeasurementOsCommand = createTorqueConstantMeasurementOsCommand;
function createSmmAcyclicHandlerOsCommand(subcommandId) {
    const elements = [OsCommandId.SMM_ACYCLIC_HANDLER, subcommandId];
    return createOsCommandTypedArray(elements);
}
exports.createSmmAcyclicHandlerOsCommand = createSmmAcyclicHandlerOsCommand;
function createSmmAcyclicHandlerReadSmmParameterOsCommand(index, subindex = 0) {
    let indexMsb = (index >> 8) & 0xff;
    let indexLsb = index & 0xff;
    const subindexByte = subindex & 0xff;
    const elements = [
        OsCommandId.SMM_ACYCLIC_HANDLER,
        SmmAcyclicHandlerSubcommandId.READ_SMM_PARAMETER,
        indexLsb,
        indexMsb,
        subindexByte,
    ];
    return createOsCommandTypedArray(elements);
}
exports.createSmmAcyclicHandlerReadSmmParameterOsCommand = createSmmAcyclicHandlerReadSmmParameterOsCommand;
function createSmmAcyclicHandlerConfigureSoftwareUpdateOsCommand(fileSize) {
    const b2 = (fileSize >> 0) & 0xff;
    const b3 = (fileSize >> 8) & 0xff;
    const b4 = (fileSize >> 16) & 0xff;
    const b5 = (fileSize >> 24) & 0xff;
    const elements = [
        OsCommandId.SMM_ACYCLIC_HANDLER,
        SmmAcyclicHandlerSubcommandId.CONFIGURE_SOFTWARE_UPDATE,
        b2,
        b3,
        b4,
        b5,
    ];
    return createOsCommandTypedArray(elements);
}
exports.createSmmAcyclicHandlerConfigureSoftwareUpdateOsCommand = createSmmAcyclicHandlerConfigureSoftwareUpdateOsCommand;
function createSkippedCyclesCounterOsCommand(firmwareService = 0) {
    const elements = [OsCommandId.SKIPPED_CYCLED_COUNTER, firmwareService];
    return createOsCommandTypedArray(elements);
}
exports.createSkippedCyclesCounterOsCommand = createSkippedCyclesCounterOsCommand;
function createIgnoreBissStatusBitsOsCommand(trigger = 1, encoderOrdinal = 1) {
    const byte2 = (encoderOrdinal << 1) | trigger;
    const elements = [OsCommandId.IGNORE_BISS_STATUS_BITS, byte2];
    return createOsCommandTypedArray(elements);
}
exports.createIgnoreBissStatusBitsOsCommand = createIgnoreBissStatusBitsOsCommand;
function createSystemIdentificationOsCommand(parameterIndex = 0, parameterValue = 0) {
    let msb = (parameterValue >> 24) & 0xff;
    let msb1 = (parameterValue >> 16) & 0xff;
    let msb2 = (parameterValue >> 8) & 0xff;
    let lsb = parameterValue & 0xff;
    const elements = [OsCommandId.SYSTEM_IDENTIFICATION, parameterIndex, msb, msb1, msb2, lsb];
    return createOsCommandTypedArray(elements);
}
exports.createSystemIdentificationOsCommand = createSystemIdentificationOsCommand;
var SystemIdentificationOsCommandSignalType;
(function (SystemIdentificationOsCommandSignalType) {
    SystemIdentificationOsCommandSignalType[SystemIdentificationOsCommandSignalType["LOGARITHMIC_WITH_AMPLITUDE_MODULATION"] = 0] = "LOGARITHMIC_WITH_AMPLITUDE_MODULATION";
    SystemIdentificationOsCommandSignalType[SystemIdentificationOsCommandSignalType["LINEAR_WITH_CONSTANT_AMPLITUDE"] = 1] = "LINEAR_WITH_CONSTANT_AMPLITUDE";
})(SystemIdentificationOsCommandSignalType = exports.SystemIdentificationOsCommandSignalType || (exports.SystemIdentificationOsCommandSignalType = {}));
var SystemIdentificationOsCommandStartProcedure;
(function (SystemIdentificationOsCommandStartProcedure) {
    SystemIdentificationOsCommandStartProcedure[SystemIdentificationOsCommandStartProcedure["NO_ACTION"] = 0] = "NO_ACTION";
    SystemIdentificationOsCommandStartProcedure[SystemIdentificationOsCommandStartProcedure["IMMEDIATELLY"] = 1] = "IMMEDIATELLY";
    SystemIdentificationOsCommandStartProcedure[SystemIdentificationOsCommandStartProcedure["WAIT_FOR_HRD_STREAMING_TO_START"] = 2] = "WAIT_FOR_HRD_STREAMING_TO_START";
})(SystemIdentificationOsCommandStartProcedure = exports.SystemIdentificationOsCommandStartProcedure || (exports.SystemIdentificationOsCommandStartProcedure = {}));
exports.systemIdentificationParameters = [
    { parameterIndex: 0, parameterName: 'Start frequency [mHz]' },
    { parameterIndex: 1, parameterName: 'Target frequency [mHz]' },
    { parameterIndex: 2, parameterName: 'Target amplitude [permilles of rated torque]' },
    { parameterIndex: 3, parameterName: 'Transition time [ms]' },
    { parameterIndex: 4, parameterName: 'Signal type' },
    { parameterIndex: 5, parameterName: 'Start the procedure' },
];
function createTriggerErrorOsCommand(firmwareService = 0, errorType = 11) {
    const elements = [OsCommandId.TRIGGER_ERROR, firmwareService, errorType];
    return createOsCommandTypedArray(elements);
}
exports.createTriggerErrorOsCommand = createTriggerErrorOsCommand;
exports.triggerErrorTypes = [
    { value: 4, name: 'RAISE ET_LOAD_STORE EXCEPTION' },
    { value: 6, name: 'RAISE ET_ARITHMETIC EXCEPTION' },
    { value: 7, name: 'RAISE ET_ECALL EXCEPTION' },
    { value: 10, name: 'HANG IN AN ENDLESS LOOP' },
    { value: 11, name: 'RAISE RESETTABLE FIRMWARE ERROR `DiagErr`' },
];
var KublerEncoderSubcommandId;
(function (KublerEncoderSubcommandId) {
    KublerEncoderSubcommandId[KublerEncoderSubcommandId["WRITE_CORRECTION_TABLE"] = 0] = "WRITE_CORRECTION_TABLE";
    KublerEncoderSubcommandId[KublerEncoderSubcommandId["SEND_SCPI_COMMAND"] = 1] = "SEND_SCPI_COMMAND";
    KublerEncoderSubcommandId[KublerEncoderSubcommandId["SWITCH_TO_BOOTLOADER_FIRMWARE"] = 2] = "SWITCH_TO_BOOTLOADER_FIRMWARE";
    KublerEncoderSubcommandId[KublerEncoderSubcommandId["CHECK_FIRMWARE_UPDATE_SIZE"] = 3] = "CHECK_FIRMWARE_UPDATE_SIZE";
    KublerEncoderSubcommandId[KublerEncoderSubcommandId["ERASE_FIRMWARE"] = 4] = "ERASE_FIRMWARE";
    KublerEncoderSubcommandId[KublerEncoderSubcommandId["WRITE_FIRMWARE"] = 5] = "WRITE_FIRMWARE";
    KublerEncoderSubcommandId[KublerEncoderSubcommandId["EXIT_BOOTLOADER_MODE"] = 6] = "EXIT_BOOTLOADER_MODE";
    KublerEncoderSubcommandId[KublerEncoderSubcommandId["READ_CORRECTION_TABLE"] = 7] = "READ_CORRECTION_TABLE";
})(KublerEncoderSubcommandId = exports.KublerEncoderSubcommandId || (exports.KublerEncoderSubcommandId = {}));
function createKublerEncoderOsCommand(subcommandId) {
    const elements = [OsCommandId.KUBLER_ENCODER_COMMAND, subcommandId];
    return createOsCommandTypedArray(elements);
}
exports.createKublerEncoderOsCommand = createKublerEncoderOsCommand;
function createKublerEncoderCommandCheckFirmwareUpdateSizeOsCommand(firmwareSize) {
    let lsb = firmwareSize & 0xff;
    let lsb1 = (firmwareSize >> 8) & 0xff;
    let lsb2 = (firmwareSize >> 16) & 0xff;
    let msb = (firmwareSize >> 24) & 0xff;
    const elements = [
        OsCommandId.KUBLER_ENCODER_COMMAND,
        KublerEncoderSubcommandId.CHECK_FIRMWARE_UPDATE_SIZE,
        lsb,
        lsb1,
        lsb2,
        msb,
    ];
    return createOsCommandTypedArray(elements);
}
exports.createKublerEncoderCommandCheckFirmwareUpdateSizeOsCommand = createKublerEncoderCommandCheckFirmwareUpdateSizeOsCommand;
function createKublerEncoderCommandWriteFirmwareOsCommand(firmwareSize) {
    let lsb = firmwareSize & 0xff;
    let lsb1 = (firmwareSize >> 8) & 0xff;
    let lsb2 = (firmwareSize >> 16) & 0xff;
    let msb = (firmwareSize >> 24) & 0xff;
    const elements = [OsCommandId.KUBLER_ENCODER_COMMAND, KublerEncoderSubcommandId.WRITE_FIRMWARE, lsb, lsb1, lsb2, msb];
    return createOsCommandTypedArray(elements);
}
exports.createKublerEncoderCommandWriteFirmwareOsCommand = createKublerEncoderCommandWriteFirmwareOsCommand;
exports.kublerEncoderCommandOsCommandErrors = {
    0: {
        errorName: 'Async communication in progress',
        errorDescription: 'The command is currently not allowed because another asynchronous encoder communication is already being executed.',
    },
    1: {
        errorName: 'Buffer timeout error',
        errorDescription: 'The FOE buffer was empty for more than 10 seconds.',
    },
    2: {
        errorName: 'Unknown command',
        errorDescription: 'The received command is not known.',
    },
    3: {
        errorName: 'Wrong data length',
        errorDescription: 'The provided correction table is too short or too long. In any case, the firmware will ensure to write 1024 bytes to the encoder so that the correction table writing is finished.',
    },
    4: {
        errorName: 'Timeout',
        errorDescription: "The encoder didn't respond to the request after 10 ms.",
    },
    5: {
        errorName: 'Command not acknowledged',
        errorDescription: 'The encoder sent a NACK for the command (not acknowledge).',
    },
    6: {
        errorName: 'Command error received',
        errorDescription: 'The encoder sent a Command Error.',
    },
    7: {
        errorName: 'Firmware verification failed',
        errorDescription: 'The firmware was written to flash, but the encoder verification failed.',
    },
};
function createUseInternalEncoderVelocityOsCommand(trigger = 0) {
    const elements = [OsCommandId.USE_INTERNAL_ENCODER_VELOCITY, trigger];
    return createOsCommandTypedArray(elements);
}
exports.createUseInternalEncoderVelocityOsCommand = createUseInternalEncoderVelocityOsCommand;
function createKublerEncoderRegisterCommunicationOsCommand(rw = 0, registerAddress = 0, registerLength = 0, registerWriteValue = 0) {
    let msb = (registerWriteValue >> 24) & 0xff;
    let msb1 = (registerWriteValue >> 16) & 0xff;
    let msb2 = (registerWriteValue >> 8) & 0xff;
    let lsb = registerWriteValue & 0xff;
    const elements = [
        OsCommandId.KUBLER_ENCODER_REGISTER_COMMUNICATION,
        rw,
        registerAddress,
        registerLength,
        lsb,
        msb2,
        msb1,
        msb,
    ];
    return createOsCommandTypedArray(elements);
}
exports.createKublerEncoderRegisterCommunicationOsCommand = createKublerEncoderRegisterCommunicationOsCommand;
exports.kublerEncoderRegisterCommunicationReadOsCommandErrors = {
    0: {
        errorName: 'Async communication in progress',
        errorDescription: 'The command is currently not allowed because another asynchronous encoder communication is already being executed.',
    },
    1: {
        errorName: 'Invalid register length',
        errorDescription: 'The register length selected is lower than 1 or higher than 4.',
    },
    2: {
        errorName: 'Encoder Timeout',
        errorDescription: "The encoder didn't return a register value after 10ms.",
    },
    3: {
        errorName: 'Wrong byte count',
        errorDescription: "The register value returned by the encoder doesn't have the same size as the register length specified.",
    },
};
exports.kublerEncoderRegisterCommunicationWriteOsCommandErrors = {
    0: {
        errorName: 'Async communication in progress',
        errorDescription: 'The command is currently not allowed because another asynchronous encoder communication is already being executed.',
    },
    1: {
        errorName: 'Invalid register length',
        errorDescription: 'The register length selected is lower than 1 or higher than 4.',
    },
};
exports.kublerEncoderRegisterValueMeaning = {
    36: {
        1: 'POA auto-calibration is not running.',
        25: 'POA auto-calibration reached good results but is still running at the moment.',
        17: 'POA auto-calibration reached good results and is finished, obtained values are saved automatically.',
        9: 'POA auto-calibration did not reach good results yet and is still running.',
    },
};
exports.osCommands = [
    { id: OsCommandId.CUSTOM_OS_COMMAND, name: 'Custom OS command' },
    { id: OsCommandId.ENCODER_REGISTER_COMMUNICATION, name: 'Encoder register communication' },
    { id: OsCommandId.ICMU_CALIBRATION_MODE, name: 'iC-MU calibration mode' },
    { id: OsCommandId.OPEN_LOOP_FIELD_MODE, name: 'Open Loop Field Mode (OLFM)' },
    { id: OsCommandId.HRD_STREAMING, name: 'HRD streaming' },
    { id: OsCommandId.MOTOR_PHASE_ORDER_DETECTION, name: 'Motor phase order detection' },
    { id: OsCommandId.COMMUTATION_OFFSET_MEASUREMENT, name: 'Commutation offset detection' },
    { id: OsCommandId.OPEN_PHASE_DETECTION, name: 'Open phase detection' },
    { id: OsCommandId.POLE_PAIR_DETECTION, name: 'Pole pair detection' },
    { id: OsCommandId.PHASE_RESISTANCE_MEASUREMENT, name: 'Phase resistance measurement' },
    { id: OsCommandId.PHASE_INDUCTANCE_MEASUREMENT, name: 'Phase inductance measurement' },
    { id: OsCommandId.TORQUE_CONSTANT_MEASUREMENT, name: 'Torque constant measurement' },
    { id: OsCommandId.SMM_ACYCLIC_HANDLER, name: 'SMM Acyclic Handler' },
    { id: OsCommandId.SKIPPED_CYCLED_COUNTER, name: 'Skipped cycles counter' },
    { id: OsCommandId.IGNORE_BISS_STATUS_BITS, name: 'Ignore BISS status bits' },
    { id: OsCommandId.SYSTEM_IDENTIFICATION, name: 'System identification' },
    { id: OsCommandId.TRIGGER_ERROR, name: 'Trigger error' },
    { id: OsCommandId.KUBLER_ENCODER_COMMAND, name: 'Kübler Encoder Command' },
    { id: OsCommandId.USE_INTERNAL_ENCODER_VELOCITY, name: 'Use Internal Encoder Velocity' },
    { id: OsCommandId.KUBLER_ENCODER_REGISTER_COMMUNICATION, name: 'Kübler Encoder Register Communication' },
];
exports.smmAcyclicHandlerSubcommands = [
    { id: SmmAcyclicHandlerSubcommandId.PARAMETER_DOWNLOAD_LOGIN, name: 'Parameter Download Login' },
    { id: SmmAcyclicHandlerSubcommandId.TRANSMIT_PARAMETERS, name: 'Transmit Parameters' },
    { id: SmmAcyclicHandlerSubcommandId.LOAD_PARAMETERS_FOR_VERIFICATION, name: 'Load Parameters for Verification' },
    { id: SmmAcyclicHandlerSubcommandId.VERIFY_PARAMETERS, name: 'Verify Parameters' },
    { id: SmmAcyclicHandlerSubcommandId.LOAD_VALIDATION_FILE, name: 'Load Validation File' },
    { id: SmmAcyclicHandlerSubcommandId.VALIDATE_CONFIGURATION, name: 'Validate Configuration' },
    { id: SmmAcyclicHandlerSubcommandId.CHANGE_PASSWORD, name: 'Change Password' },
    { id: SmmAcyclicHandlerSubcommandId.LOGOUT, name: 'Logout' },
    { id: SmmAcyclicHandlerSubcommandId.SOFTWARE_UPDATE_LOGIN, name: 'Software Update Login' },
    { id: SmmAcyclicHandlerSubcommandId.CONFIGURE_SOFTWARE_UPDATE, name: 'Configure Software Update' },
    { id: SmmAcyclicHandlerSubcommandId.TRANSMIT_SOFTWARE, name: 'Transmit Software' },
    { id: SmmAcyclicHandlerSubcommandId.FINALIZE_SOFTWARE_UPDATE, name: 'Finalize Software Update' },
    { id: SmmAcyclicHandlerSubcommandId.READ_SMM_PARAMETER, name: 'Read SMM Parameter' },
    { id: SmmAcyclicHandlerSubcommandId.IO_FAILURE_ACKNOWLEDGE, name: 'IO Failure Acknowledge' },
    { id: SmmAcyclicHandlerSubcommandId.TRIGGER_RESTART, name: 'Trigger Restart' },
];
exports.kublerEncoderSubcommands = [
    { id: KublerEncoderSubcommandId.WRITE_CORRECTION_TABLE, name: 'Write Correction Table' },
    { id: KublerEncoderSubcommandId.SEND_SCPI_COMMAND, name: 'Send SCPI Command' },
    { id: KublerEncoderSubcommandId.SWITCH_TO_BOOTLOADER_FIRMWARE, name: 'Switch to Bootloader Firmware' },
    { id: KublerEncoderSubcommandId.CHECK_FIRMWARE_UPDATE_SIZE, name: 'Check Firmware Update Size' },
    { id: KublerEncoderSubcommandId.ERASE_FIRMWARE, name: 'Erase Firmware' },
    { id: KublerEncoderSubcommandId.WRITE_FIRMWARE, name: 'Write Firmware' },
    { id: KublerEncoderSubcommandId.EXIT_BOOTLOADER_MODE, name: 'Exit Bootloader Mode' },
    { id: KublerEncoderSubcommandId.READ_CORRECTION_TABLE, name: 'Read Correction Table' },
];
/**
 * Maps an OS command response to a specific object, effectively adding more
 * properties to the response object, such as the computed commutation angle offset.
 */
function mapOsCommandResponse() {
    return (0, rxjs_1.pipe)((0, rxjs_1.map)((response) => {
        if (response && response.command) {
            const osCommandId = response.command[0];
            if (osCommandId === OsCommandId.ENCODER_REGISTER_COMMUNICATION) {
                if (response.request === 'succeeded' && response.data) {
                    return Object.assign(Object.assign({}, response), { registerValue: response.data[0] });
                }
            }
            if (osCommandId === OsCommandId.ICMU_CALIBRATION_MODE) {
                if (response.request === 'succeeded') {
                    return Object.assign(Object.assign({}, response), { calibrationModeSet: true });
                }
            }
            if (osCommandId === OsCommandId.OPEN_LOOP_FIELD_MODE) {
                if (response.request === 'succeeded') {
                    return Object.assign(Object.assign({}, response), { openLoopFieldMode: true });
                }
            }
            if (osCommandId === OsCommandId.HRD_STREAMING) {
                if (response.request === 'succeeded') {
                    return Object.assign(Object.assign({}, response), { hrdStreamingComplete: true });
                }
                if (response.request === 'failed') {
                    if (typeof response.errorCode === 'number' && response.errorCode <= 250) {
                        const { errorName, errorDescription } = exports.hrdStreamingOsCommandErrors[response.errorCode];
                        return Object.assign(Object.assign({}, response), { hrdStreamingComplete: false, errorName, errorDescription });
                    }
                    return Object.assign(Object.assign({}, response), { hrdStreamingComplete: false });
                }
            }
            if (osCommandId === OsCommandId.MOTOR_PHASE_ORDER_DETECTION) {
                if (response.request === 'succeeded' && response.data) {
                    return Object.assign(Object.assign({}, response), { motorPhaseOrder: response.data[0] });
                }
            }
            if (osCommandId === OsCommandId.COMMUTATION_OFFSET_MEASUREMENT) {
                if (response.request === 'succeeded' && response.data) {
                    const [b0, b1] = response.data;
                    const commutationAngleOffset = (b0 << 8) | b1;
                    return Object.assign(Object.assign({}, response), { commutationAngleOffset });
                }
            }
            if (osCommandId === OsCommandId.OPEN_PHASE_DETECTION) {
                if (response.request === 'succeeded') {
                    return Object.assign(Object.assign({}, response), { phaseOpened: false });
                }
                if (response.request === 'failed') {
                    if (typeof response.errorCode === 'number' && response.errorCode <= 250) {
                        const { errorName, errorDescription } = exports.openPhaseDetectionErrors[response.errorCode];
                        return Object.assign(Object.assign({}, response), { phaseOpened: true, errorName, errorDescription });
                    }
                    return Object.assign(Object.assign({}, response), { phaseOpened: true });
                }
            }
            if (osCommandId === OsCommandId.POLE_PAIR_DETECTION) {
                if (response.request === 'succeeded' && response.data) {
                    return Object.assign(Object.assign({}, response), { numberOfPolePairs: response.data[0] });
                }
                if (response.request === 'failed') {
                    if (typeof response.errorCode === 'number' && response.errorCode === 0) {
                        return Object.assign(Object.assign({}, response), { errorName: 'Current amplitude error', errorDescription: 'The drive is not able to increase the amplitude of motor phase currents to the required value. This problem can occur due to limited Vdc or high motor phase impedances.' });
                    }
                }
            }
            if (osCommandId === OsCommandId.PHASE_RESISTANCE_MEASUREMENT) {
                if (response.request === 'succeeded' && response.data) {
                    const [b0, b1, b2, b3] = response.data;
                    const phaseResistance = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
                    return Object.assign(Object.assign({}, response), { phaseResistance });
                }
                if (response.request === 'failed') {
                    if (typeof response.errorCode === 'number' && response.errorCode === 0) {
                        return Object.assign(Object.assign({}, response), { errorName: 'Current amplitude error', errorDescription: 'Unable to increase the current amplitude.' });
                    }
                }
            }
            if (osCommandId === OsCommandId.PHASE_INDUCTANCE_MEASUREMENT) {
                if (response.request === 'succeeded' && response.data) {
                    const [b0, b1, b2, b3] = response.data;
                    const phaseInductance = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
                    return Object.assign(Object.assign({}, response), { phaseInductance });
                }
                if (response.request === 'failed') {
                    if (typeof response.errorCode === 'number' && response.errorCode === 0) {
                        return Object.assign(Object.assign({}, response), { errorName: 'Current amplitude error', errorDescription: 'Unable to increase the current amplitude.' });
                    }
                }
            }
            if (osCommandId === OsCommandId.TORQUE_CONSTANT_MEASUREMENT) {
                if (response.request === 'succeeded' && response.data) {
                    const [b0, b1, b2, b3] = response.data;
                    const torqueConstant = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
                    return Object.assign(Object.assign({}, response), { torqueConstant });
                }
            }
            if (osCommandId === OsCommandId.SKIPPED_CYCLED_COUNTER) {
                if (response.request === 'succeeded' && response.data) {
                    const [b0, b1, b2, b3] = response.data;
                    const skippedCycles = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
                    return Object.assign(Object.assign({}, response), { skippedCycles });
                }
            }
            if (osCommandId === OsCommandId.IGNORE_BISS_STATUS_BITS) {
                if (response.request === 'succeeded') {
                    return Object.assign(Object.assign({}, response), { ignoringBissStatusBits: true });
                }
            }
            if (osCommandId === OsCommandId.SYSTEM_IDENTIFICATION) {
                if (response.request === 'succeeded') {
                    return Object.assign(Object.assign({}, response), { systemIdentificationCompleted: true });
                }
            }
            if (osCommandId === OsCommandId.TRIGGER_ERROR) {
                if (response.request === 'succeeded') {
                    return Object.assign(Object.assign({}, response), { errorSet: true });
                }
            }
            if (osCommandId === OsCommandId.KUBLER_ENCODER_COMMAND) {
                if (response.request === 'succeeded' && response.data) {
                    const numberOfBytesWritten = (response.data[0] << 8) | response.data[1];
                    const responseInFoeBuffer = response.data[2];
                    return Object.assign(Object.assign({}, response), { numberOfBytesWritten, responseInFoeBuffer });
                }
                if (response.request === 'failed') {
                    if (typeof response.errorCode === 'number' && response.errorCode <= 250) {
                        const { errorName, errorDescription } = exports.kublerEncoderCommandOsCommandErrors[response.errorCode];
                        return Object.assign(Object.assign({}, response), { errorName, errorDescription });
                    }
                }
            }
            if (osCommandId === OsCommandId.USE_INTERNAL_ENCODER_VELOCITY) {
                if (response.request === 'succeeded') {
                    return Object.assign(Object.assign({}, response), { usingInternalEncoderVelocity: true });
                }
            }
            if (osCommandId === OsCommandId.KUBLER_ENCODER_REGISTER_COMMUNICATION) {
                if (response.request === 'succeeded' && response.data) {
                    const [b0, b1, b2, b3] = response.data;
                    const kublerRegisterValue = b0 | (b1 << 8) | (b2 << 16) | (b3 << 24);
                    return Object.assign(Object.assign({}, response), { kublerRegisterValue });
                }
                if (response.request === 'failed') {
                    if (typeof response.errorCode === 'number' && response.errorCode <= 250) {
                        const { errorName, errorDescription } = exports.kublerEncoderRegisterCommunicationReadOsCommandErrors[response.errorCode];
                        return Object.assign(Object.assign({}, response), { errorName, errorDescription });
                    }
                }
            }
        }
        return response;
    }));
}
exports.mapOsCommandResponse = mapOsCommandResponse;
//# sourceMappingURL=os-command.js.map