python files verschoben
This commit is contained in:
+2
-1
@@ -1,2 +1,3 @@
|
|||||||
call ecalc_setenv.bat
|
call ecalc_setenv.bat
|
||||||
python %ECALC_LIB%\calc_site.py --infile=jayjay.cfg
|
python %ECALC_LIB%\calc_site.py --infile=jayjay.cfg --outfile=JayJay_old.xlsx
|
||||||
|
python %ECALC_LIB%\calc_site.py --infile=jayjay.cfg --config=Sivas_Daten_jayjay.cfg --outfile=JayJay_new.xlsx
|
||||||
|
|||||||
@@ -0,0 +1,167 @@
|
|||||||
|
import pandas as pd
|
||||||
|
import configparser
|
||||||
|
import os.path
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
"""
|
||||||
|
Erstellung einer Excel-Datei mit aktuellen Preisen aus Sivas ist leicht möglich.
|
||||||
|
Diese soll in einer config-Datei für die Berechnung der rieter-eKalkulation verwendet werden.
|
||||||
|
Den Parametern der rieter_ekalk werden die entsprechenden Sivas-Nummern zugewiesen, und damit die aktuellen Preise.
|
||||||
|
Diese Zuordnung von Parametern und ihren aktuellen Preisen wird wieder in eine config-Datei geschrieben, die mit den Preisen der Sivas_Daten.cfg-Datei abzugleichen ist, auf die rieter_ekalk zugreift.
|
||||||
|
"""
|
||||||
|
|
||||||
|
class Kosten():
|
||||||
|
"""
|
||||||
|
Liest die Sivas-Excel-Liste ein und schreibt eine neue config Datei mit den aktuellen Preisen der in rieter-ekalk verwendeten Sivas-IDs.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, pathNew="Zuordnung_Teilenummern.cfg", pathOld="Sivas_Daten.cfg", sivasData="grid_export.xlsx"):
|
||||||
|
"""
|
||||||
|
:param pathNew: cfg-Datei, die den Bauteilen ihre Sivas-Nummern zuweist z.B. "schaltschrankgehaeuse_b2x800_zubehoer = 790821101"
|
||||||
|
:param pathOld: cfg-Datei, die in rieter_ekalk verwendet wird und den Bauteilen Preise zuweist z.B. "schaltschrankgehaeuse_b2x800_zubehoer = 4663.45"
|
||||||
|
:param sivasData: Excel-Datei mit Sivas-Nummern und entsprechenden Preisen, Überschrift: Teilenummer, Laufende Materialkosten
|
||||||
|
"""
|
||||||
|
df = pd.read_excel(sivasData, header=0, index_col=0, usecols=["Teilenummer", "Laufende Materialkosten" ])
|
||||||
|
self._kosten = df.to_dict()
|
||||||
|
|
||||||
|
self._given = True
|
||||||
|
if os.path.exists(pathNew):
|
||||||
|
self._zuordnung = configparser.ConfigParser(inline_comment_prefixes="#")
|
||||||
|
self._zuordnung.read_file(open(pathNew))
|
||||||
|
else:
|
||||||
|
self._given = False
|
||||||
|
self._zuordnung = None
|
||||||
|
|
||||||
|
self._default = configparser.ConfigParser(inline_comment_prefixes="#")
|
||||||
|
self._default.read_file(open(pathOld))
|
||||||
|
|
||||||
|
# wird verwendet, um die Werte der alten config zu speichern
|
||||||
|
self._HW_Einzelpreise = None
|
||||||
|
|
||||||
|
def exists(self):
|
||||||
|
return self._given
|
||||||
|
|
||||||
|
def getNewPricesAsDict(self, not_found_keys):
|
||||||
|
"""
|
||||||
|
Gibt die neuen Preise als Dict zurück.
|
||||||
|
|
||||||
|
:param not_found_keys: Dict von Bauteilen, denen eine Nummer zugeordnet ist, die in Sivas nicht existiert z.B. {'schaltschrankgehaeuse_b1x800_zubehoer': '----'}
|
||||||
|
"""
|
||||||
|
faktoren = self.getZuordnungTeilenummernAsDict("Faktoren")
|
||||||
|
newDict = {}
|
||||||
|
for key, val in self.getZuordnungTeilenummernAsDict("HW_Einzelpreise").items():
|
||||||
|
number = val.strip()
|
||||||
|
self.getPriceFromNumber(key, number, newDict, not_found_keys)
|
||||||
|
if "+" in number:
|
||||||
|
del not_found_keys[key]
|
||||||
|
split_sivas_ids = number.split('+')
|
||||||
|
self.getPriceFromAddedNumbers(key, split_sivas_ids, newDict, not_found_keys)
|
||||||
|
if key in faktoren:
|
||||||
|
newDict[key] *= float(faktoren[key])
|
||||||
|
|
||||||
|
return newDict
|
||||||
|
|
||||||
|
def getPriceFromAddedNumbers(self, key, split_sivas_ids, newDict, not_found_keys):
|
||||||
|
"""
|
||||||
|
Trägt die Zuordnung Bauteil:Gesamtpreis in das newDict Dictionary ein, wenn das Bauteil mehrere Sivas-Nummern beinhaltet.
|
||||||
|
Ist die Nummer eines Summanden nicht in Sivas enthalten, wird er in das Dict "not_found_keys" eingetragen.
|
||||||
|
|
||||||
|
:param split_sivas_ids: Liste von Sivas IDs, die addiert werden z.B. [' 827072204', ' 721000041']
|
||||||
|
:param key: Name z.B. "anlagenrechner_ohne_bildschirm"
|
||||||
|
:param newDict: z.B. {'schaltschrankgehaeuse_b2x800_zubehoer':9490.23, ...}
|
||||||
|
:param not_found_keys: Dict von Bauteilen, denen eine Nummer zugeordnet ist, die in Sivas nicht existiert z.B. {'schaltschrankgehaeuse_b1x800_zubehoer': '----'}
|
||||||
|
"""
|
||||||
|
price = 0
|
||||||
|
for summand in split_sivas_ids:
|
||||||
|
summand = summand.strip()
|
||||||
|
# summand: einzelner Summand z.B. '827072204'
|
||||||
|
if summand in self._kosten["Laufende Materialkosten"]:
|
||||||
|
cost = self._kosten["Laufende Materialkosten"][summand]
|
||||||
|
# cost: Einzelpreis eines Summanden [€]
|
||||||
|
if type(cost) is type(int) or type(float):
|
||||||
|
price += cost
|
||||||
|
# price: Gesamtpreis
|
||||||
|
newDict.update({key: price})
|
||||||
|
else:
|
||||||
|
not_found_keys.update({key:summand})
|
||||||
|
|
||||||
|
|
||||||
|
def getPriceFromNumber(self, key, number, newDict, not_found_keys):
|
||||||
|
"""
|
||||||
|
Trägt die Zuordnung Bauteil:Gesamtpreis in das newDict Dictionary ein, wenn das Bauteil eine Sivas-Nummer beinhaltet.
|
||||||
|
In Sivas nicht existierende Nummern werden in das Dict "not_found_keys" zurückgegeben.
|
||||||
|
|
||||||
|
:param key: Name z.B. "anlagenrechner_ohne_bildschirm"
|
||||||
|
:param number: Sivas Nummer zum key z.B. '827072204'
|
||||||
|
:param newDict: z.B. {'schaltschrankgehaeuse_b2x800_zubehoer':9490.23, ...}
|
||||||
|
:param not_found_keys: Dict von Bauteilen, denen eine Nummer zugeordnet ist, die in Sivas nicht existiert z.B. {'schaltschrankgehaeuse_b1x800_zubehoer': '----'}
|
||||||
|
"""
|
||||||
|
if number in self._kosten["Laufende Materialkosten"]:
|
||||||
|
price = self._kosten["Laufende Materialkosten"][number]
|
||||||
|
if price is int or float:
|
||||||
|
newDict.update({key: price})
|
||||||
|
else:
|
||||||
|
not_found_keys.update({key:number})
|
||||||
|
def getDefaultDictAsFloat(self, section_name):
|
||||||
|
res = dict()
|
||||||
|
for key, val in self._default.items(section_name):
|
||||||
|
res[key] = float(val)
|
||||||
|
return res
|
||||||
|
|
||||||
|
def getZuordnungTeilenummernAsDict(self, section_name):
|
||||||
|
res = dict()
|
||||||
|
for key, val in self._zuordnung.items(section_name):
|
||||||
|
res[key] = val
|
||||||
|
return res
|
||||||
|
|
||||||
|
def writeNewConfig(self, name='Sivas_Abgleich.cfg'):
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
config["HW_Einzelpreise"] = latest_costs
|
||||||
|
config["Preise durch Sivas nicht ermittelbar"] = not_found_in_sivas
|
||||||
|
with open(name, 'w') as configfile:
|
||||||
|
config.write(configfile)
|
||||||
|
|
||||||
|
def writePriceIncrements(self, name='Preis_Increments.xlsx'):
|
||||||
|
not_found_in_sivas = dict()
|
||||||
|
latest_costs = self.getNewPricesAsDict(not_found_in_sivas)
|
||||||
|
sivas_numbers = list()
|
||||||
|
old_prices = list()
|
||||||
|
new_prices = list()
|
||||||
|
for sivas_number in latest_costs.keys():
|
||||||
|
sivas_numbers.append(sivas_number)
|
||||||
|
old_prices.append(self.getDefaultDictAsFloat("HW_Einzelpreise").get(sivas_number))
|
||||||
|
new_prices.append(latest_costs.get(sivas_number))
|
||||||
|
data = {"Sivas-Nummern":sivas_numbers, "Alte Preise":old_prices, "Neue Preise":new_prices}
|
||||||
|
df = pd.DataFrame.from_dict(data)
|
||||||
|
df.to_excel(name, sheet_name="Preisänderungen", index_label="Sivas-Nummern")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
parser = argparse.ArgumentParser(description='calculation of a system according to Bös', prog='ecalc')
|
||||||
|
parser.add_argument('-o', '--outfile', action='store', help='name of the output excel file', default="Preis_Increments.xlsx")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
zuordCfgFilePath = os.path.join(os.environ.get('ECALC_CFG'), "Zuordnung_Teilenummern.cfg")
|
||||||
|
sivasCfgFilePath = os.path.join(os.environ.get('ECALC_CFG'), "Sivas_Daten.cfg")
|
||||||
|
gridExportFilePath = os.path.join(os.environ.get('ECALC_CFG'), "grid_export.xlsx")
|
||||||
|
|
||||||
|
if not os.path.isfile(zuordCfgFilePath):
|
||||||
|
print("no Zuordnung_Teilenummern.cfg in ECALC_CFG")
|
||||||
|
if not os.path.isfile(sivasCfgFilePath):
|
||||||
|
print("no Sivas_Daten.cfg in ECALC_CFG")
|
||||||
|
if not os.path.isfile(gridExportFilePath):
|
||||||
|
print("no grid_export.xlsx with prices from SIVAS in ECALC_CFG")
|
||||||
|
|
||||||
|
# lies die alten config und die Excel-Liste mit den Sivas-Daten
|
||||||
|
costs = Kosten(zuordCfgFilePath, sivasCfgFilePath, gridExportFilePath)
|
||||||
|
not_found_in_sivas = dict()
|
||||||
|
latest_costs = costs.getNewPricesAsDict(not_found_in_sivas)
|
||||||
|
# schreibe die neue config mit den aktuellen Preisen
|
||||||
|
outCfg = os.path.join(os.environ.get('ECALC_WORK'), "Sivas_Abgleich.cfg")
|
||||||
|
costs.writeNewConfig(outCfg)
|
||||||
|
|
||||||
|
# schreibe die Preisänderungen in eine Excel-Datei
|
||||||
|
outPath = os.path.join(os.environ.get('ECALC_WORK'), args.outfile)
|
||||||
|
costs.writePriceIncrements(outPath)
|
||||||
@@ -0,0 +1,158 @@
|
|||||||
|
import rieter_ekalk as rek
|
||||||
|
import pandas as pd
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import configparser
|
||||||
|
|
||||||
|
|
||||||
|
class cfg():
|
||||||
|
"""
|
||||||
|
Liest die config-Datei ein, in der Stückpreise und Zeiteinheiten pro Bauteil wie in der rieter_ekalk Excel-Datei verwendet angegeben sind, und schreibt sie in ein Dictionary.
|
||||||
|
"""
|
||||||
|
def __init__(self, path="Sivas_Daten.cfg"):
|
||||||
|
"""
|
||||||
|
:param path: Die config-Datei, in der Stückpreise und Zeiteinheiten der jeweiligen Bauteile aufgelistet sind z.B.[HW_Einzelpreise]
|
||||||
|
# Schaltschrank Einzelpreis
|
||||||
|
schaltschrankgehaeuse_b1x800_zubehoer = 2000
|
||||||
|
"""
|
||||||
|
self._hasConfig = True
|
||||||
|
if os.path.exists(path):
|
||||||
|
self._cfg = configparser.ConfigParser(inline_comment_prefixes="#")
|
||||||
|
self._cfg.optionxform = str
|
||||||
|
self._cfg.read_file(open(path))
|
||||||
|
else:
|
||||||
|
self._hasConfig = False
|
||||||
|
self._cfg = None
|
||||||
|
|
||||||
|
def exists(self):
|
||||||
|
return self._hasConfig
|
||||||
|
|
||||||
|
def isfloat(self, num):
|
||||||
|
try:
|
||||||
|
float(num)
|
||||||
|
return True
|
||||||
|
except ValueError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def getTypedDict(self, section:str):
|
||||||
|
"""
|
||||||
|
Schreibt die Zuordnungen von Bauteil:Stückpreis/Zeiteinheit (je nach gewählter Überschrift) aus der config-Datei in ein Dictionary.
|
||||||
|
:param section: Überschrift in der config-Datei z.B. "HW_Einzelpreise"
|
||||||
|
"""
|
||||||
|
if section not in self._cfg.sections():
|
||||||
|
return dict()
|
||||||
|
res = dict()
|
||||||
|
for key, val in self._cfg.items(section):
|
||||||
|
if val.lower() in ['true']:
|
||||||
|
res[key] =True
|
||||||
|
elif val.lower() in ['false']:
|
||||||
|
res[key] =False
|
||||||
|
elif val.startswith("-"):
|
||||||
|
res[key] = float(val)
|
||||||
|
elif self.isfloat(val):
|
||||||
|
res[key] = float(val)
|
||||||
|
else:
|
||||||
|
res[key] = val
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
def run_calc(infile, outfile, SivasConfig):
|
||||||
|
|
||||||
|
|
||||||
|
infileCfg = cfg(infile)
|
||||||
|
|
||||||
|
Anzahl_MG = infileCfg.getTypedDict("allgemein")
|
||||||
|
rsm_direct_eingabe = infileCfg.getTypedDict("rsm_direct")
|
||||||
|
rsm_fa_eingabe = infileCfg.getTypedDict("rsm_fa")
|
||||||
|
flyer_f40_eingabe = infileCfg.getTypedDict("flyer_f40")
|
||||||
|
neuenhauser_eingabe = infileCfg.getTypedDict("neuenhauser")
|
||||||
|
flyer_eingabe = infileCfg.getTypedDict("flyer")
|
||||||
|
verbindungsstrecken_w_eingabe = infileCfg.getTypedDict("verbindungsstrecken_w")
|
||||||
|
puffer_eingabe = infileCfg.getTypedDict("puffer")
|
||||||
|
turm_eingabe = infileCfg.getTypedDict("turm")
|
||||||
|
mg = rek.MG(Anzahl_MG,
|
||||||
|
rsm_direct=rsm_direct_eingabe,
|
||||||
|
rsm_fa=rsm_fa_eingabe,
|
||||||
|
flyer_f40=flyer_f40_eingabe,
|
||||||
|
neuenhauser=neuenhauser_eingabe,
|
||||||
|
flyer=flyer_eingabe,
|
||||||
|
verbindungsstrecken_w=verbindungsstrecken_w_eingabe,
|
||||||
|
puffer=puffer_eingabe,
|
||||||
|
turm=turm_eingabe)
|
||||||
|
|
||||||
|
|
||||||
|
anStr = SivasConfig.getTypedDict("Antriebsstrom")
|
||||||
|
cosPhi = SivasConfig.getTypedDict("cos phi")
|
||||||
|
al = rek.Anschlussl(anStr, cosPhi)
|
||||||
|
Anzahl_AL ={}
|
||||||
|
al.calc(Anzahl_AL, mg)
|
||||||
|
# self.assertEqual(al._ANZAHL.get("Anzahl_Motor"), 48)
|
||||||
|
# self.assertAlmostEqual(al._ANZAHL.get("Summe_Strom_Motor"), 26.4)
|
||||||
|
# self.assertAlmostEqual(al._ANZAHL.get("Summe_Strom_Motor_SPS_Peripherie"), 29.4)
|
||||||
|
# self.assertAlmostEqual(al._ANZAHL.get("GZF"), 16.2)
|
||||||
|
# self.assertAlmostEqual(al._ANZAHL.get("Res"), 1.62)
|
||||||
|
# self.assertAlmostEqual(al._ANZAHL.get("Gesamtstrom"), 17.82)
|
||||||
|
# self.assertAlmostEqual(al._Anschlussspannung, 400)
|
||||||
|
# self.assertAlmostEqual(al._ANZAHL.get("Leistung"), 12.345696)
|
||||||
|
# self.assertAlmostEqual(al._ANZAHL.get("Gesamtanschlussleistung"), 13)
|
||||||
|
|
||||||
|
Anzahl_EAS = infileCfg.getTypedDict("EAS")
|
||||||
|
eas = rek.EA(Anzahl_EAS, mg)
|
||||||
|
|
||||||
|
Anzahl_HW = infileCfg.getTypedDict("HW")
|
||||||
|
|
||||||
|
|
||||||
|
hwep = SivasConfig.getTypedDict("HW_Einzelpreise")
|
||||||
|
hwhp = SivasConfig.getTypedDict("HW_Zeiten Hardwareplanung")
|
||||||
|
hwzew = SivasConfig.getTypedDict("HW_Zeiten Elektro-Werkstatt")
|
||||||
|
|
||||||
|
hw = rek.HW(hwep, hwhp, hwzew)
|
||||||
|
hw.calc(Anzahl_HW, mg, eas)
|
||||||
|
|
||||||
|
emoz = SivasConfig.getTypedDict("Elektro-Montagezeiten")
|
||||||
|
emo = rek.EMO(emoz)
|
||||||
|
emo.calc(eas, hw, mg)
|
||||||
|
|
||||||
|
Anzahl_DL = infileCfg.getTypedDict("DL")
|
||||||
|
dl = rek.Dienstleistung(Anzahl_DL, hw)
|
||||||
|
|
||||||
|
Anzahl_Ergebnis = infileCfg.getTypedDict("Ergebnis")
|
||||||
|
kph = SivasConfig.getTypedDict("Kosten pro h")
|
||||||
|
erg = rek.Ergebnis(kph)
|
||||||
|
erg.calc(Anzahl_Ergebnis, hw, dl, emo)
|
||||||
|
|
||||||
|
summary = erg.summary_costs(hw)
|
||||||
|
|
||||||
|
df = pd.DataFrame.from_dict(data=summary, orient='index', columns=['Aufwand'])
|
||||||
|
df.to_excel(outfile, sheet_name="Kostenaufstellung")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
parser = argparse.ArgumentParser(description='calculation of a system according to Bös', prog='ecalc')
|
||||||
|
parser.add_argument('-i', '--infile', action='store', help='name of the input file', default="jayjay.cfg")
|
||||||
|
parser.add_argument('-o', '--outfile', action='store', help='name of the output .xlsx file. If none given, name of the input file is used.')
|
||||||
|
parser.add_argument('-c', '--config', action='store', help='name of the config file inside of cfg folder to use. Default is Sivas_Daten.cfg', default="Sivas_Daten.cfg")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
sivasCfgFilePath = os.path.join(os.environ.get('ECALC_CFG'), args.config)
|
||||||
|
RieterConfig = cfg(sivasCfgFilePath)
|
||||||
|
|
||||||
|
inFilePath = os.path.join(os.environ.get('ECALC_WORK'), args.infile)
|
||||||
|
if os.path.isfile(inFilePath):
|
||||||
|
if args.outfile:
|
||||||
|
outPath = os.path.join(os.environ.get('ECALC_WORK'), args.outfile)
|
||||||
|
else:
|
||||||
|
(fname, ext) = os.path.splitext(args.infile)
|
||||||
|
outPath = os.path.join(os.environ.get('ECALC_WORK'), fname + '.xlsx')
|
||||||
|
run_calc(inFilePath, outPath, RieterConfig)
|
||||||
|
else:
|
||||||
|
print("no such file in ECALC_WORK")
|
||||||
|
# os.environ.get('ECALC_BIN')
|
||||||
|
# os.environ.get('ECALC_WORK')
|
||||||
|
# os.environ.get('ECALC_CFG')
|
||||||
|
# os.environ.get('ECALC_LIB')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
+2716
File diff suppressed because it is too large
Load Diff
+2199
File diff suppressed because it is too large
Load Diff
+4014
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user