vehicle/running/emissions/components/fuelandelectric/co2gpm.js

/**
 * Calculate journey, fuel and electric ppm, total mileages
 *
 * @module
 * @since 0.1.21
 */

import { isPHEV } from '../../../../classification';
import { getMPGofficalRatio } from '../../../journey/calculate';
import { co2_kg_per_litre as skv_co2_kg_per_litre, production_uplift_percentage } from '../../../../../maths/constants';
import { kmToMiles } from '../../../../../maths/conversions';
import { getIsCSMode } from '../../../util';
import {
    productionUplift,
    tailpipeCO2gPerMile,
    iceCO2gPerMileFromWCCO2gPerMile,
    calculateElectricCO2gPerMile,
} from './calculate';

/**
 * Co2 grams per mile for PHEVs
 * @param {struct} skv_config
 * @returns {number}
 * @module
 */

const iceCO2gPerMileForPHEVs = (skv_config) => {
    // if (skv_config.is_cs_mode) {
    const skv_fuel_cfg = {
        // work out charge sustaining mode first
        co2_kg_per_litre: skv_co2_kg_per_litre[skv_config.fuel_type],
        mpg: skv_config.mpg,
        wc_mpg: skv_config.wc_mpg,
        tailpipe_co2_gpkm: skv_config.tailpipe_co2_gpkm,
        is_cs_mode: skv_config.is_cs_mode,
        battery_range_miles: skv_config.battery_range_miles,
    };

    // get the weighted combined co2 g per mile (i.e electric + ICE)
    const wc_co2_g_per_mile = kmToMiles(skv_fuel_cfg.tailpipe_co2_gpkm, true);

    // remove the electric portion from the weighted combined co2 g per mile
    return iceCO2gPerMileFromWCCO2gPerMile(wc_co2_g_per_mile, skv_config.wc_mpg, skv_config.mpg);
};

/**
 * calculate grams for ICE portion
 * @param {struct} skv_config ice_pp_litre, mpg, vat_percentage
 * @returns {struct}
 */
const iceCO2gPerMile = (skv_config) => {
    const skv_return = {
        tail_pipe: 0,
        production: 0,
    };

    const skv_default_cfg = {
        mpg: '',
        mpg_user: '',
        // weighted combined mpg
        wc_mpg: '',
        // wltp what comes out of tailpipe
        tailpipe_co2_gpkm: '',
        fuel_type: '',
        // is charging sustaining mode likely passed in when calculating a journey
        is_cs_mode: false,
        // for removing the electric portion from weighted combined
        battery_range_miles: '',
    };

    // replace default values with the ones from the config passed in
    const skv_cfg = Object.assign(skv_default_cfg, skv_config);

    if (isPHEV(skv_cfg.mpg, skv_cfg.battery_range_miles)) {
        skv_return.tail_pipe = iceCO2gPerMileForPHEVs(skv_cfg);
        skv_return.production = productionUplift(skv_return.tail_pipe, production_uplift_percentage);
    } else {
        skv_return.tail_pipe = tailpipeCO2gPerMile(skv_cfg.tailpipe_co2_gpkm);
        skv_return.production = productionUplift(skv_return.tail_pipe, production_uplift_percentage);
    }

    // at this point we've calculated co2 gram per mile based on official figures
    // if the user has provided a custom mpg then apply as a ratio
    if (skv_config.mpg_user) {
        const ratio = getMPGofficalRatio(skv_config.mpg, skv_config.mpg_user);
        skv_return.tail_pipe *= ratio;
        skv_return.production *= ratio;
    }

    return skv_return;
};

/**
 * calculate grams for Electric portion
 * @param {struct} skv_config tariff_co2_gpkwh, battery_range_miles, battery_total_capacity_kwh
 * @returns {struct}
 */
const electricCO2gPerMile = (skv_config) => {
    const skv_return = {
        production: 0,
    };

    skv_return.production = calculateElectricCO2gPerMile(skv_config);

    return skv_return;
};

/**
 * get co2 grams on electric and ice
 * @param {struct} skv_config
 * @returns {struct}
 */
const getCO2gPerMile = (skv_config) => {
    let skv_ice_result = {
        tail_pipe: 0,
        production: 0,
    };

    let skv_electric_result = {
        production: 0,
    };

    const skv_default = {
        total_miles: '',
        // ICE
        tailpipe_co2_gpkm: '',
        fuel_type: '',
        mpg: '',
        wc_mpg: '',
        // Electric
        tariff_co2_gpkwh: '',
        battery_range_miles: '',
        battery_total_capacity_kwh: '',
    };

    // replace default values with the ones from the config passed in
    const skv_local_config = Object.assign(skv_default, skv_config);

    // Charge Sustaining mode for phevs
    skv_local_config.is_cs_mode = getIsCSMode(skv_config);

    if (skv_local_config.mpg > 0) {
        skv_ice_result = iceCO2gPerMile(skv_local_config);
    }

    if (skv_config.battery_range_miles > 0) {
        skv_electric_result = electricCO2gPerMile(skv_local_config);
    }
    return {
        electric: skv_electric_result,
        ice: skv_ice_result,
    };
};

export {
    getCO2gPerMile,
    iceCO2gPerMile,
    electricCO2gPerMile,
    iceCO2gPerMileForPHEVs,
};