/**
* Works out emissions and costs based on journey miles
* @module
* @since 0.1.21
*/
import { isPHEV } from '../classification';
import { getPPM } from './costs/components/fuelandelectric/ppm';
import { getCO2gPerMile } from './emissions/components/fuelandelectric/co2gpm';
import { getMPG, getBatteryRangeMiles, getIsCSMode } from './util';
import {
totalCostOfAllJourneys,
numberOfJourneys,
journeyCostPortion,
journeyCostTotal,
journeyEmissionsPortion,
journeyEmissionsTotal,
totalEmissionsOfAllJourneys,
getJourneyMilesForPHEVs,
getElectricMiles,
getICEMiles,
getJourneyFuelRatio,
} from './journey/calculate';
/**
* Calculate journeys and mileages taken
* @returns {struct} electric, ice and totals
*/
const getSplit = (skv_config) => {
const skv_default_config = {
journey_miles: '',
mpg: 0,
battery_range_miles: 0,
};
const skv_local_config = Object.assign(skv_default_config, skv_config);
let journey_miles = 0;
const is_phev = isPHEV(skv_local_config.mpg, getBatteryRangeMiles(skv_local_config));
// if its a PHEV then we may need to make adjustments to the journey miles
// using Charge Sustaining mode (previously called Condition B)
if (is_phev) {
journey_miles = getJourneyMilesForPHEVs(skv_local_config);
} else {
journey_miles = skv_local_config.journey_miles;
}
// calculate the split between ICE and electric
const electric_miles = getElectricMiles(getBatteryRangeMiles(skv_local_config), getMPG(skv_local_config), journey_miles);
// what we have left from the total battery range minus the electric range
const ice_miles = getICEMiles(electric_miles, journey_miles);
// proportion of journey carried out on electric miles
const electric_ratio = getJourneyFuelRatio(electric_miles, journey_miles);
// proportion of journey carried out on ICE miles
const ice_ratio = getJourneyFuelRatio(ice_miles, journey_miles);
return {
electric: {
miles: electric_miles,
ratio: electric_ratio,
},
ice: {
miles: ice_miles,
ratio: ice_ratio,
},
};
};
/**
* get journey miles on electric and ice
* @param {struct} skv_config
* @returns {struct}
*/
const getJourney = (skv_config) => {
const skv_journey_config = {
mpg: getMPG(skv_config),
battery_range_miles: getBatteryRangeMiles(skv_config),
};
// add journey_miles if it exists in the config
if (Object.prototype.hasOwnProperty.call(skv_config, 'journey_miles')) {
skv_journey_config.journey_miles = skv_config.journey_miles;
}
return getSplit(skv_journey_config);
};
/* *******************************************
***************** COSTS *******************
*******************************************
*/
/**
* calculate a single journey cost
* @param {struct} skv_journey_split miles of journey on electric and ice
* @param {struct} skv_ppm pence per mile on electric and ice
* @returns {struct}
*/
const singleJourneyCost = (skv_journey_split, skv_ppm) => {
// calculate individual electric and ICE portions of the journey
const skv_return = {
electric: {
ppm: skv_ppm.electric,
distance: skv_journey_split.electric,
total_pounds: journeyCostPortion(skv_journey_split.electric, skv_ppm.electric),
},
ice: {
ppm: skv_ppm.ice,
distance: skv_journey_split.ice,
total_pounds: journeyCostPortion(skv_journey_split.ice, skv_ppm.ice),
},
};
// calculate the total combined cost
skv_return.combined = journeyCostTotal(skv_return);
return skv_return;
};
/**
*
* @returns {struct}
*/
const getCost = (skv_config) => {
const skv_return = {
journey: {},
total: {
journeys: {},
ice: {},
electric: {},
combined: {},
},
};
const skv_journey_split = getJourney(skv_config);
const skv_ppm = getPPM(skv_config);
// get the costs for a single journey by combined the split and the ppm
skv_return.journey = singleJourneyCost(skv_journey_split, skv_ppm);
skv_return.total.journeys.amount = numberOfJourneys(skv_config.journey_miles, skv_config.total_miles);
// calculate the total cost based on the total mileage passed in
const result = totalCostOfAllJourneys(skv_return.journey, skv_config.total_miles);
skv_return.total.electric = result.electric;
skv_return.total.ice = result.ice;
skv_return.total.combined = result.combined;
return skv_return;
};
/* *******************************************
*************** EMISSIONS *****************
*******************************************
*/
/**
* calculate a single journey emissions
* @param {struct} skv_journey_split miles of journey on electric and ice
* @param {struct} skv_co2_g_per_mile
* @returns {struct}
*/
const singleJourneyEmissions = (skv_journey_split, skv_co2_g_per_mile) => {
// calculate individual electric and ICE portions of the journey
const skv_return = {
electric: {
co2_g_per_mile: skv_co2_g_per_mile.electric,
distance: skv_journey_split.electric,
total_co2_g: journeyEmissionsPortion(skv_journey_split.electric, skv_co2_g_per_mile.electric),
},
ice: {
co2_g_per_mile: skv_co2_g_per_mile.ice,
distance: skv_journey_split.ice,
total_co2_g: journeyEmissionsPortion(skv_journey_split.ice, skv_co2_g_per_mile.ice),
},
};
// calculate the total combined cost
skv_return.combined = journeyEmissionsTotal(skv_return);
return skv_return;
};
/**
*
* @returns {struct}
*/
const getEmissions = (skv_config) => {
const skv_return = {
journey: {},
total: {
journeys: {},
ice: {},
electric: {},
combined: {},
},
};
const skv_journey_split = getJourney(skv_config);
const skv_co2_g_per_mile = getCO2gPerMile(skv_config);
// get the costs for a single journey by combined the split and the ppm
skv_return.journey = singleJourneyEmissions(skv_journey_split, skv_co2_g_per_mile);
skv_return.total.journeys.amount = numberOfJourneys(skv_config.journey_miles, skv_config.total_miles);
// // calculate the total cost based on the total mileage passed in
const result = totalEmissionsOfAllJourneys(skv_return.journey, skv_config.total_miles);
skv_return.total.electric = result.electric;
skv_return.total.ice = result.ice;
skv_return.total.combined = result.combined;
return skv_return;
};
export {
getSplit,
getIsCSMode,
getJourney,
// costs
getCost,
singleJourneyCost,
// emissions
getEmissions,
singleJourneyEmissions,
};