Source code for fleetmanager.model.tco_calculator

import numpy as np
import numpy_financial as npf


[docs]class TCOCalculator: """ Class used all over the project to calculate the consequence based on the methods provided in "Partnerskab for offentlige grønne indkøb"s tool "miljoestyrelsen-tco-vaerktoej-motorkoeretoejer". Made to be independent of xlwings dependencies unavailable to linux. The methods have been written directly from the tool and thus makes the same assumptions. Originals can be seen in src.fleetmanager.model.pogi """ def __init__(self, **kwargs): """ Parameters should be loaded with the initialisation. Most importantly is to define; "drivmiddel", "bil_type", "koerselsforbrug" (based on the actual allocated trips), Essential lambda functions here are: aarlig_braendstofforbrug : calculates the fuel usage - fossile: km / kml, electrical: km * wh / 1000 aarlig_driftsomkostning : calculates the yearly fule expense: usage * price * count nutidsvaerdi_drift : calculates the projected fuel expense: yearly fuel expense * (1 + interest rate / 100) ** -year_index Parameters ---------- kwargs """ # oplysninger om produktet self.etableringsgebyr = 0 self.braendstofforbrug = 15 self.leasingydelse = 0 self.leasingtype = "operationel" self.ejerafgift = 0 self.elforbrug = 200 self.service = 0 # oplysninger om brugeren self.antal = 1 self.koerselsforbrug = 30000 # baggrundsdata self.diskonteringsrente = 4 self.evalueringsperiode = 4 # 2020 = 0 self.fremskrivnings_aar = 0 self.prisstigning_benzin = 1.39 self.prisstigning_diesel = 1.45 self.pris_el = 2.13 self.prisstigning_el = 1.67 self.pris_benzin = 12.33 self.pris_diesel = 10.83 self.drivmiddel = "benzin" self.bil_type = "benzin" self.forsikring = 0 self.loebende_omkostninger = 0 self.foerste_aars_brugsperiode = 2021 self.vaerdisaetning_tons_co2 = 1500 # Fra CO2e udledninger Fremskrivningsarket self.co2e_udledninger_diesel = np.full(30, 2.98) self.co2e_udledninger_benzin = np.full(30, 2.52) self.co2e_udledninger_el = [ 0.089, 0.07, 0.058, 0.054, 0.05, 0.042, 0.037, 0.032, 0.013, ] + ([0.012] * 21) self.__dict__.update(kwargs) # functions self.fremskrivning = { "benzin": self.drivmiddel_udvikling( self.pris_benzin, self.prisstigning_benzin ), "diesel": self.drivmiddel_udvikling( self.pris_diesel, self.prisstigning_diesel ), "el": self.drivmiddel_udvikling(self.pris_el, self.prisstigning_el), } self.aarlig_braendstofforbrug = ( lambda koersel, kml, drivmiddel: koersel / kml if drivmiddel.lower() != "el" else koersel * kml / 1000 ) # kwh to wh self.aarlig_driftsomkostning = ( lambda forbrug, pris, antal=1: forbrug * pris * antal ) self.nutidsvaerdi_drift = ( lambda driftsomkostning, rente, aar_index: driftsomkostning * (1 + rente / 100) ** -aar_index ) # calculated self.driftsomkostninger_aar = self.driftsomkostninger() self.driftsomkostning = sum(self.driftsomkostninger_aar) self.omkostning = self.omkostninger() self.tco = self.driftsomkostning + self.omkostning + self.etableringsgebyr self.tco_average = self.tco_yearly() self.omkostning_average = self.omkostning_yearly()
[docs] def driftsomkostninger(self): """ Calculates the summed fuel expense on the vehicle. Returns ------- list of expense on fuel over the selected evaluation period """ if self.drivmiddel not in ["benzin", "diesel", "el"]: return [0] return [ self.nutidsvaerdi_drift( self.aarlig_driftsomkostning( self.aarlig_braendstofforbrug( self.koerselsforbrug, self.elforbrug if self.drivmiddel.lower() == "el" else self.braendstofforbrug, self.drivmiddel, ), self.fremskrivning[self.drivmiddel][k - 1], ), self.diskonteringsrente, k, ) for k in range(1, self.evalueringsperiode + 1) ]
[docs] def drivmiddel_udvikling(self, pris, stigning): """ Projecting the development in price of the fuel. Parameters ---------- pris : int, current price stigning : int, percentage rate of fuel increase Returns ------- list of fuel price for the next 30 years """ udvikling = [pris] for _ in range(30): udvikling.append(udvikling[-1] * (1 + stigning / 100)) return udvikling
[docs] def omkostninger(self): """ Summing the expenses not related to fuel expense over the evaluation period """ return sum( ( max(self.leasingydelse, 0) + max(self.ejerafgift, 0) + max(self.forsikring, 0) + max(self.service, 0) + max(self.loebende_omkostninger, 0) ) * (1 + self.diskonteringsrente / 100) ** -aar for aar in range(1, self.evalueringsperiode + 1) )
[docs] def omkostning_yearly(self): """ Getting the yearly expense with the defined discount interest rate """ return abs( npf.pmt( pv=self.omkostning, fv=0, rate=self.diskonteringsrente / 100, nper=self.evalueringsperiode, ) )
[docs] def tco_yearly(self): return abs( npf.pmt( pv=self.tco, fv=0, rate=self.diskonteringsrente / 100, nper=self.evalueringsperiode, ) )
[docs] def ekstern_miljoevirkning(self, sum_it=False): udledninger = [] aarligt_forbrug_benzin_diesel = ( 0 if self.braendstofforbrug == 0 else self.koerselsforbrug / self.braendstofforbrug ) el_aarligt_stroemforbrug = self.elforbrug / 1000 * self.koerselsforbrug el_hybrid_aarligt_forbrug = ( 0 if self.elforbrug == 0 else self.koerselsforbrug / self.elforbrug ) if self.bil_type == "benzin": udledninger = [ aarligt_forbrug_benzin_diesel * self.antal * k / 1000 for k in self.co2e_udledninger_benzin ] elif self.bil_type == "diesel": udledninger = [ aarligt_forbrug_benzin_diesel * self.antal * k / 1000 for k in self.co2e_udledninger_diesel ] elif self.bil_type == "el": udledninger = [ self.antal * el_aarligt_stroemforbrug * k / 1000 for k in self.co2e_udledninger_el ] elif self.bil_type == "plugin hybrid benzin": udledninger_el = [ self.antal * el_aarligt_stroemforbrug * k / 1000 for k in self.co2e_udledninger_el ] udledninger_benzin = [ el_hybrid_aarligt_forbrug * self.antal * k / 1000 for k in self.co2e_udledninger_benzin ] udledninger = [a + b for a, b in zip(udledninger_el, udledninger_benzin)] elif self.bil_type == "plugin hybrid diesel": udledninger_el = [ self.antal * el_aarligt_stroemforbrug * k / 1000 for k in self.co2e_udledninger_el ] udledninger_diesel = [ el_hybrid_aarligt_forbrug * self.antal * k / 1000 for k in self.co2e_udledninger_diesel ] udledninger = [a + b for a, b in zip(udledninger_el, udledninger_diesel)] udledninger = udledninger[ self.fremskrivnings_aar : self.fremskrivnings_aar + self.evalueringsperiode ] ekstern_virkninger = [ udl * self.vaerdisaetning_tons_co2 * (1 + self.diskonteringsrente / 100) ** -(k + 1) for k, udl in enumerate(udledninger) ] if sum_it: return sum(udledninger), sum(ekstern_virkninger) return udledninger, ekstern_virkninger