Compare commits

...

5 Commits

6 changed files with 108 additions and 57 deletions
+2
View File
@@ -165,3 +165,5 @@ cython_debug/
/data /data
/work /work
/log /log
work/easy.dxf
work/easy_todraw_edit.json
+46 -1
View File
@@ -4,7 +4,6 @@
# Kabel für die Ventile # Kabel für die Ventile
[WD_Q] [WD_Q]
# Länge in m zu Sivaseintrag
1.0=722001300 1.0=722001300
2.0=722001301 2.0=722001301
2.5=722001308 2.5=722001308
@@ -58,6 +57,30 @@
30.0=722001357 30.0=722001357
40.0=722001359 40.0=722001359
# Daten-Kabel für Scanner (Patchkabel)
[WF_B]
0.25=726001062
0.5=726001040
1.0=726001041
1.5=726001042
2.0=726001043
3.0=726001044
5.0=726001045
10.0=726001046
15.0=726001047
20.0=726001048
25.0=726001049
30.0=726001050
35.0=726001051
40.0=726001052
45.0=726001053
50.0=726001054
55.0=726001055
60.0=726001056
65.0=726001057
85.0=726001060
95.0=726001061
# Bezeichner jeder Verbindungsleitung # Bezeichner jeder Verbindungsleitung
[Sivasnummern] [Sivasnummern]
@@ -96,3 +119,25 @@
722001357=M12 St-0°/ M12 Bu-0° 30m 722001357=M12 St-0°/ M12 Bu-0° 30m
722001358=M12 St-0°/ M12 Bu-0° 2,5m 722001358=M12 St-0°/ M12 Bu-0° 2,5m
722001359=M12 St-0°/ M12 Bu-0° 40m 722001359=M12 St-0°/ M12 Bu-0° 40m
726001062=Patchkabel 2xRJ45 0,25m
726001040=Patchkabel 2xRJ45 0,5m
726001041=Patchkabel 2xRJ45 1,0m
726001042=Patchkabel 2xRJ45 1,5m
726001043=Patchkabel 2xRJ45 2,0m
726001044=Patchkabel 2xRJ45 3,0m
726001045=Patchkabel 2xRJ45 5,0m
726001046=Patchkabel 2xRJ45 10m
726001047=Patchkabel 2xRJ45 15m
726001048=Patchkabel 2xRJ45 20m
726001049=Patchkabel 2xRJ45 25m
726001050=Patchkabel 2xRJ45 30m
726001051=Patchkabel 2xRJ45 35m
726001052=Patchkabel 2xRJ45 40m
726001053=Patchkabel 2xRJ45 45m
726001054=Patchkabel 2xRJ45 50m
726001055=Patchkabel 2xRJ45 55m
726001056=Patchkabel 2xRJ45 60m
726001057=Patchkabel 2xRJ45 65m
726001060=Patchkabel 2xRJ45 85m
726001061=Patchkabel 2xRJ45 95m
+44 -44
View File
@@ -20,6 +20,7 @@ class Point:
@dataclass @dataclass
class Polyline: class Polyline:
id: str id: str
s_artinr: str
coords: List[Point] coords: List[Point]
length: float length: float
@@ -270,13 +271,12 @@ def parse_sensors_from_json(positions_json):
def export_excel(plines, out_path): def export_excel(plines, out_path):
# Hier für Excel Export # Hier für Excel Export
print("creating excel file with cable information ..") print("creating excel file with cable information ..")
sens2cable = map_sensor_to_cable(sensors, plines) write_excel_from_json(plines, out_path)
write_excel_from_json(plines, sens2cable, out_path)
print("done") print("done")
def write_excel_from_json(plines:Polylines, sens2cable: dict, outpath:str): def write_excel_from_json(plines:Polylines, outpath:str):
wb = Workbook() wb = Workbook()
sens2cable = map_sensor_to_cable(plines)
# Dicts für Anzahl bzw kummulierte Länge # Dicts für Anzahl bzw kummulierte Länge
count_summary = defaultdict(int) count_summary = defaultdict(int)
length_summary = defaultdict(float) length_summary = defaultdict(float)
@@ -284,24 +284,21 @@ def write_excel_from_json(plines:Polylines, sens2cable: dict, outpath:str):
#Worksheet 1 - Kabellängen nach Kabel-ID #Worksheet 1 - Kabellängen nach Kabel-ID
ws1 = wb.active ws1 = wb.active
ws1.title = "Length by ID" ws1.title = "Length by ID"
ws1.append(["Cable-ID", "True Length (m)", "Cable-ArtNr"]) ws1.append(["Cable-ID", "True Length (m)", "Cable-ArtNr", "Cable-Name (short)"])
for pl in plines.kabel: for pl in plines.kabel:
length = pl.length /1000 # Umrechnung von mm in m length = pl.length /1000 # Umrechnung von mm in m
artnr = sens2cable[pl.id] for artnr in sens2cable[pl.id]:
ws1.append([pl.id, length, artnr]) cable_name = ""
if artnr != "Kabel länger als max. Kabellänge":
cable_name = cable_cfg["Sivasnummern"][artnr]
ws1.append([pl.id, length, artnr, cable_name])
if "MA" in pl.id: if "MA" in pl.id:
length_summary[artnr] += math.ceil(length) # Aufrunden von z.b. 10,3 auf 11 m (volle Meter!) length_summary[artnr] += math.ceil(length) # Aufrunden von z.b. 10,3 auf 11 m (volle Meter!)
else:
# MB als Motor gesetzt! Beachte auch Zuordnung in get_cable_artnr!! count_summary[artnr] += 1
elif "MB" in pl.id: # MB statt MA zur Motor-Kennzeichnung
length_summary[artnr] += math.ceil(length) # Aufrunden von z.b. 10,3 auf 11 m (volle Meter!)
else:
count_summary[artnr] += 1
# Worksheet 2 - Kabelnummern und Stückzahlen # Worksheet 2 - Kabelnummern und Stückzahlen
ws2 = wb.create_sheet("Cables SIVAS") ws2 = wb.create_sheet("Cables SIVAS")
@@ -444,45 +441,47 @@ def get_cable_artnr(section, length):
return None return None
def map_sensor_to_cable(sensors, plines): def map_sensor_to_cable(plines):
sens2cable = defaultdict() sens2cable = defaultdict(list)
for pl in plines.kabel: for pl in plines.kabel:
# Sensorname von Kabel-ID extraieren
sensor_name = pl.id.split('-')[-1] sensor_name = pl.id.split('-')[-1]
# Kabellänge aus gleichem Eintrag auslesen + in m umrechnen
cable_length = pl.length/1000 cable_length = pl.length/1000
sensor_artinr = pl.s_artinr
# Sensor Artikelnummer aus positions.json holen
sensor_artinr = sensors[sensor_name].artinr
# Verzweigung, um welchen Typ es sich handelt (Special Keys)
name_prefix = sensor_name[0:2] name_prefix = sensor_name[0:2]
section = None #Default sections = [] #Default
# Hier MB ebenfalls als Motor gezählt. Motoren in Fortna-Layout nicht angebunden! if name_prefix == "MA":
if name_prefix == "MA" or name_prefix == "MB": sections = ["MA"] # Sektion für Motor-Kabel
section = "MA"
elif name_prefix == "MB":
sections = ["WD_Q"] # Sektion für Ventil-Kabel
elif name_prefix == "QM": elif name_prefix == "QM":
section = "WD_Q" sections = ["WD_Q"] # Sektion für Ventil-Kabel
elif sensor_name.startswith("B"): elif sensor_name.startswith("B"): # Sensor Name beginnt mit B -> Sensor jeglicher Art
if sensor_artinr == 829422026: if name_prefix == "BX": # Wenn "BX", dann Scanner
section = "WD_I-829422026" sections = ["WF_B", "WD_I"] # Sektion für Scanner Patch-Kabel und Sektion für Standard-Sensorkabel zur Spannungsversorgung
cable_length = max(0.0, cable_length -4.0) # 4 Meter abziehen, da bereits 5m Kabelschwanz an Scanner dran
elif sensor_artinr == 829422026:
sections = ["WD_I-829422026"]
elif sensor_artinr == 720002003: elif sensor_artinr == 720002003:
section = "WD_I-720002003" sections = ["WD_I-720002003"]
else: else:
section = "WD_I" sections = ["WD_I"]
if section is None: if not sections:
cable_artnr = "Kein Kabeltyp zu Sensor-Artikelnummer zugewiesen" sens2cable[pl.id].append ("Kein Kabeltyp zugewiesen")
else: continue
for section in sections:
cable_artnr = get_cable_artnr(section, cable_length) cable_artnr = get_cable_artnr(section, cable_length)
if cable_artnr is None: if cable_artnr is None:
cable_artnr = "Kabel länger als max. Kabellänge" sens2cable[pl.id].append(f"Kabel länger als max. Kabellänge")
else:
sens2cable[pl.id] = cable_artnr sens2cable[pl.id].append(cable_artnr)
return sens2cable return sens2cable
@@ -531,7 +530,8 @@ if __name__ == '__main__':
# Config für Kabel-Atikelnummern laden # Config für Kabel-Atikelnummern laden
cable_cfg = configparser.ConfigParser() cable_cfg = configparser.ConfigParser()
cable_cfg.optionxform = str #Keys case-sensitive cable_cfg.optionxform = str #Keys case-sensitive
cable_cfg.read(os.path.join(config_dir, "kabel.cfg")) with open(os.path.join(config_dir, "kabel.cfg"), encoding="utf-8") as f:
cable_cfg.read_file(f)
dxf_file = args.dxf dxf_file = args.dxf
+5 -9
View File
@@ -38,14 +38,15 @@ def merge_two_dicts(x, y):
def get_type_of_name(name): def get_type_of_name(name):
SpecialKeys = ["MB", # Separator SpecialKeys = ["MB", # Ventil
"MA", # Motor "MA", # Motor
"BG", # Stausensor "BG", # Stausensor
"BP" # Schalter Druckluft "BP", # Schalter Druckluft
"QM" # Ventile "QM", # Ventile
"BX" # Scanner
] ]
KabelKey = ["WD"] KabelKey = ["WD", "WF"]
DropKeys = [ DropKeys = [
"FC", # Motorschutzschalter "FC", # Motorschutzschalter
"PF", # Leuchtmelder "PF", # Leuchtmelder
@@ -233,11 +234,6 @@ def get_subdistributor_positions(msp, dist2sensors):
match = re.search("-"+distname, text.dxf.text) match = re.search("-"+distname, text.dxf.text)
if match: if match:
ret[distname] = (round(text.dxf.insert[0],1), round(text.dxf.insert[1],1)) #nur x und y Koordinate in Json schreiben ret[distname] = (round(text.dxf.insert[0],1), round(text.dxf.insert[1],1)) #nur x und y Koordinate in Json schreiben
# for mtext in msp.query("MTEXT"):
# print(f"Inhalt: {mtext.text}")
# print(f"Layer: {mtext.dxf.layer}")
# print(f"Einfügepunkt: {mtext.dxf.insert}")
# print("---")
return ret return ret
def get_subdistributor_positions_iter(dxf_path, dist2sensors): def get_subdistributor_positions_iter(dxf_path, dist2sensors):
+4
View File
@@ -367,6 +367,9 @@ class Anlage():
return self._sensors[sname] return self._sensors[sname]
raise Exception("Sensor not found") raise Exception("Sensor not found")
def set_sensor_artnrs(self, artnr_dict: dict):
self._sensor_artnrs = artnr_dict
def connect_sensors_to_racks(self) -> list: def connect_sensors_to_racks(self) -> list:
'''verbindet die Sensoren mit den Racks. '''verbindet die Sensoren mit den Racks.
die Rückgabe enthält ein Tuple, welche Sensoren keinem Rack zugeordnet werden konnten die Rückgabe enthält ein Tuple, welche Sensoren keinem Rack zugeordnet werden konnten
@@ -599,6 +602,7 @@ class Anlage():
ld = dict() ld = dict()
ld['id'] = f"{dname}-{sname}" ld['id'] = f"{dname}-{sname}"
ld['s_artinr'] = self._sensor_artnrs.get(sname, "")
ld["coords"]= [{"x":round(p.x,1), "y":round(p.y,1)} for p in pfad_coords] ld["coords"]= [{"x":round(p.x,1), "y":round(p.y,1)} for p in pfad_coords]
ld["length"]= round(pfad_length,1) ld["length"]= round(pfad_length,1)
#ld["nodes"]=pfad_nodes #ld["nodes"]=pfad_nodes
+7 -3
View File
@@ -63,8 +63,9 @@ def create_plant(racks:dict, sensors:dict, distributors:dict, mapping:dict, tunn
an.set_racks(racks) an.set_racks(racks)
# Verbinde Racks miteinander (ggf. verlängere ungenaue Racks) # Verbinde Racks miteinander (ggf. verlängere ungenaue Racks)
an.join_racks() an.join_racks()
# Füge Sensoren als Knoten hinzu # Füge Sensoren als Knoten hinzu und speichere Sensoren mit deren Artikelnummern
an.add_sensors(sensors) an.add_sensors({sname: sdata["point"] for sname, sdata in sensors.items()}) # nur Punkte zu jeweiligem sname übergeben
an.set_sensor_artnrs({sname: sdata["artinr"] for sname, sdata in sensors.items()}) # nur Artikelnummern zu jeweiligem sname übergeben
# Verbinde Sensoren mit deren naheliegendsten Racks # Verbinde Sensoren mit deren naheliegendsten Racks
errors_sensors = an.connect_sensors_to_racks() errors_sensors = an.connect_sensors_to_racks()
# Füge UV hinzu # Füge UV hinzu
@@ -111,7 +112,10 @@ def prepare_data(rawdata:dict):
sensors = rawdata["sensors"] sensors = rawdata["sensors"]
dsensors = dict() dsensors = dict()
for sname, sdata in sensors.items(): for sname, sdata in sensors.items():
dsensors[sname] = Point(sdata["pos"]) dsensors[sname] = {
"point": Point(sdata["pos"]),
"artinr": sdata.get("ARTINR","")
}
subdists = rawdata["distributors"] subdists = rawdata["distributors"]
dsubdists = dict() dsubdists = dict()