Compare commits

...

5 Commits

6 changed files with 108 additions and 57 deletions
+2
View File
@@ -165,3 +165,5 @@ cython_debug/
/data
/work
/log
work/easy.dxf
work/easy_todraw_edit.json
+46 -1
View File
@@ -4,7 +4,6 @@
# Kabel für die Ventile
[WD_Q]
# Länge in m zu Sivaseintrag
1.0=722001300
2.0=722001301
2.5=722001308
@@ -58,6 +57,30 @@
30.0=722001357
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
[Sivasnummern]
@@ -96,3 +119,25 @@
722001357=M12 St-0°/ M12 Bu-0° 30m
722001358=M12 St-0°/ M12 Bu-0° 2,5m
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
class Polyline:
id: str
s_artinr: str
coords: List[Point]
length: float
@@ -270,13 +271,12 @@ def parse_sensors_from_json(positions_json):
def export_excel(plines, out_path):
# Hier für Excel Export
print("creating excel file with cable information ..")
sens2cable = map_sensor_to_cable(sensors, plines)
write_excel_from_json(plines, sens2cable, out_path)
write_excel_from_json(plines, out_path)
print("done")
def write_excel_from_json(plines:Polylines, sens2cable: dict, outpath:str):
def write_excel_from_json(plines:Polylines, outpath:str):
wb = Workbook()
sens2cable = map_sensor_to_cable(plines)
# Dicts für Anzahl bzw kummulierte Länge
count_summary = defaultdict(int)
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
ws1 = wb.active
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:
length = pl.length /1000 # Umrechnung von mm in m
artnr = sens2cable[pl.id]
ws1.append([pl.id, length, artnr])
for artnr in sens2cable[pl.id]:
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:
length_summary[artnr] += math.ceil(length) # Aufrunden von z.b. 10,3 auf 11 m (volle Meter!)
# MB als Motor gesetzt! Beachte auch Zuordnung in get_cable_artnr!!
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
if "MA" in pl.id:
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
ws2 = wb.create_sheet("Cables SIVAS")
@@ -444,45 +441,47 @@ def get_cable_artnr(section, length):
return None
def map_sensor_to_cable(sensors, plines):
sens2cable = defaultdict()
def map_sensor_to_cable(plines):
sens2cable = defaultdict(list)
for pl in plines.kabel:
# Sensorname von Kabel-ID extraieren
sensor_name = pl.id.split('-')[-1]
# Kabellänge aus gleichem Eintrag auslesen + in m umrechnen
cable_length = pl.length/1000
# Sensor Artikelnummer aus positions.json holen
sensor_artinr = sensors[sensor_name].artinr
# Verzweigung, um welchen Typ es sich handelt (Special Keys)
sensor_artinr = pl.s_artinr
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" or name_prefix == "MB":
section = "MA"
if name_prefix == "MA":
sections = ["MA"] # Sektion für Motor-Kabel
elif name_prefix == "MB":
sections = ["WD_Q"] # Sektion für Ventil-Kabel
elif name_prefix == "QM":
section = "WD_Q"
sections = ["WD_Q"] # Sektion für Ventil-Kabel
elif sensor_name.startswith("B"):
if sensor_artinr == 829422026:
section = "WD_I-829422026"
elif sensor_name.startswith("B"): # Sensor Name beginnt mit B -> Sensor jeglicher Art
if name_prefix == "BX": # Wenn "BX", dann Scanner
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:
section = "WD_I-720002003"
sections = ["WD_I-720002003"]
else:
section = "WD_I"
sections = ["WD_I"]
if section is None:
cable_artnr = "Kein Kabeltyp zu Sensor-Artikelnummer zugewiesen"
else:
if not sections:
sens2cable[pl.id].append ("Kein Kabeltyp zugewiesen")
continue
for section in sections:
cable_artnr = get_cable_artnr(section, cable_length)
if cable_artnr is None:
cable_artnr = "Kabel länger als max. Kabellänge"
sens2cable[pl.id] = cable_artnr
sens2cable[pl.id].append(f"Kabel länger als max. Kabellänge")
else:
sens2cable[pl.id].append(cable_artnr)
return sens2cable
@@ -531,7 +530,8 @@ if __name__ == '__main__':
# Config für Kabel-Atikelnummern laden
cable_cfg = configparser.ConfigParser()
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
+5 -9
View File
@@ -38,14 +38,15 @@ def merge_two_dicts(x, y):
def get_type_of_name(name):
SpecialKeys = ["MB", # Separator
SpecialKeys = ["MB", # Ventil
"MA", # Motor
"BG", # Stausensor
"BP" # Schalter Druckluft
"QM" # Ventile
"BP", # Schalter Druckluft
"QM", # Ventile
"BX" # Scanner
]
KabelKey = ["WD"]
KabelKey = ["WD", "WF"]
DropKeys = [
"FC", # Motorschutzschalter
"PF", # Leuchtmelder
@@ -233,11 +234,6 @@ def get_subdistributor_positions(msp, dist2sensors):
match = re.search("-"+distname, text.dxf.text)
if match:
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
def get_subdistributor_positions_iter(dxf_path, dist2sensors):
+4
View File
@@ -367,6 +367,9 @@ class Anlage():
return self._sensors[sname]
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:
'''verbindet die Sensoren mit den Racks.
die Rückgabe enthält ein Tuple, welche Sensoren keinem Rack zugeordnet werden konnten
@@ -599,6 +602,7 @@ class Anlage():
ld = dict()
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["length"]= round(pfad_length,1)
#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)
# Verbinde Racks miteinander (ggf. verlängere ungenaue Racks)
an.join_racks()
# Füge Sensoren als Knoten hinzu
an.add_sensors(sensors)
# Füge Sensoren als Knoten hinzu und speichere Sensoren mit deren Artikelnummern
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
errors_sensors = an.connect_sensors_to_racks()
# Füge UV hinzu
@@ -111,7 +112,10 @@ def prepare_data(rawdata:dict):
sensors = rawdata["sensors"]
dsensors = dict()
for sname, sdata in sensors.items():
dsensors[sname] = Point(sdata["pos"])
dsensors[sname] = {
"point": Point(sdata["pos"]),
"artinr": sdata.get("ARTINR","")
}
subdists = rawdata["distributors"]
dsubdists = dict()