Einfache Konfiguration mit dem FabAccess Config Generator
Wolfram vom MakerSpace Leipzig hat 2024 ein umfangreiches Tool - den FabAccess Config Generator - entwickelt, um eine Konfiguration (bffh.dhall
) anhang einer Maschinenliste im CSV-Format zu erzeugen.
Funktionsumfang
- Generierung von Maschinen
- Generierung von Rollen
- Generierung von Aktoren
- Generierung von einfachen Aktoren-Verbindungen
- Export einer gesonderten Rollenliste (interne ID & Anzeigename der Rolle)
- Abbildung der Struktur mittels Mermaid-Diagramm
- Direkte Aktualisierung einer bestehenden
bffh.dhall
Funktionsweise
Die CSV-Datei enthält pro Zeile einen Eintrag für eine Maschine. Neben Angaben zur Maschine selbst (ID, Wiki-URL etc.) werden Angaben zum Bereich vermerkt, in dem sich die Maschine befindet. Aus den Angaben zu den Bereichen werden dann alle Rollen abgeleitet.
Installation
cd /opt/fabinfra/
git clone https://github.com/elem74/fabaccess-config-generator.git
cd fabaccess-config-generator/
Konfigurationsdatei maschinenliste.csv editieren
vim maschinenliste.csv
Konfigurationsdatei bffh.dhall erzeugen
python3 config-generator.py
Das Tool schreibt automatisch ins Unterverzeichnis output/
die folgenden Dateien:
- bffh-dhall-data.txt
- mermaid-code.txt
- roles.csv
Die Beispiel Dhall Daten sehen dabei wie folgt aus:
bffh-dhall-data.txt
roles = {
Admin = {
permissions = [
"bffh.users.manage",
"bffh.users.info",
"bffh.users.admin",
"beispielw.*",
]
},
_manager_schichtleitung = {
permissions = [
"beispielw.*",
]
},
beispielw_holz_manager = {
permissions = [
"beispielw.holz.*",
]
},
beispielw_holz_bandsaege_user = {
permissions = [
"beispielw.holz.bandsaege.disclose.*",
"beispielw.holz.bandsaege.read.*",
"beispielw.holz.bandsaege.write.*",
]
},
beispielw_holz_hobelmaschine_user = {
permissions = [
"beispielw.holz.hobelmaschine.disclose.*",
"beispielw.holz.hobelmaschine.read.*",
"beispielw.holz.hobelmaschine.write.*",
]
},
beispielw_holz_holzcnc_user = {
permissions = [
"beispielw.holz.holzcnc.disclose.*",
"beispielw.holz.holzcnc.read.*",
"beispielw.holz.holzcnc.write.*",
]
},
beispielw_holz_user = {
permissions = [
"beispielw.holz.disclose.*",
"beispielw.holz.read.*",
"beispielw.holz.write.*",
]
},
beispielw_textil_manager = {
permissions = [
"beispielw.textil.*",
]
},
beispielw_textil_user = {
permissions = [
"beispielw.textil.disclose.*",
"beispielw.textil.read.*",
"beispielw.textil.write.*",
]
},
beispielw_fablab_manager = {
permissions = [
"beispielw.fablab.*",
]
},
beispielw_fablab_3dprint_manager = {
permissions = [
"beispielw.fablab.3dprint.*",
]
},
beispielw_fablab_3dprint_user = {
permissions = [
"beispielw.fablab.3dprint.disclose.*",
"beispielw.fablab.3dprint.read.*",
"beispielw.fablab.3dprint.write.*",
]
},
beispielw_fablab_laser_manager = {
permissions = [
"beispielw.fablab.laser.*",
]
},
beispielw_fablab_laser_user = {
permissions = [
"beispielw.fablab.laser.disclose.*",
"beispielw.fablab.laser.read.*",
"beispielw.fablab.laser.write.*",
]
},
beispielw_siebdruck_manager = {
permissions = [
"beispielw.siebdruck.*",
]
},
beispielw_siebdruck_user = {
permissions = [
"beispielw.siebdruck.disclose.*",
"beispielw.siebdruck.read.*",
"beispielw.siebdruck.write.*",
]
},
beispielw_drucker = {
permissions = [
"beispielw.siebdruck.disclose.a3drucker",
"beispielw.siebdruck.read.a3drucker",
"beispielw.siebdruck.write.a3drucker",
"beispielw.buero.disclose.drucker",
"beispielw.buero.read.drucker",
"beispielw.buero.write.drucker",
]
},
beispielw_buero_manager = {
permissions = [
"beispielw.buero.*",
]
},
},
machines = {
beispielw-holz-bandsaege-bandsaege = {
name = "Bandsäge",
description = "Bandsäge im Holzbereich",
wiki = "",
category = "Holzwerkstatt",
disclose = "beispielw.holz.bandsaege.disclose.bandsaege",
read = "beispielw.holz.bandsaege.read.bandsaege",
write = "beispielw.holz.bandsaege.write.bandsaege",
manage = "beispielw.holz.bandsaege.manage.bandsaege",
},
beispielw-holz-hobelmaschine-hobelmaschine = {
name = "Hobelmaschine",
description = "Hobelmaschine im Holzbereich",
wiki = "",
category = "Holzwerkstatt",
disclose = "beispielw.holz.hobelmaschine.disclose.hobelmaschine",
read = "beispielw.holz.hobelmaschine.read.hobelmaschine",
write = "beispielw.holz.hobelmaschine.write.hobelmaschine",
manage = "beispielw.holz.hobelmaschine.manage.hobelmaschine",
},
beispielw-holz-holzcnc-holzcncfraese = {
name = "CNC-Fräse",
description = "CNC Fräse im Holzbereich",
wiki = "",
category = "Holzwerkstatt",
disclose = "beispielw.holz.holzcnc.disclose.holzcncfraese",
read = "beispielw.holz.holzcnc.read.holzcncfraese",
write = "beispielw.holz.holzcnc.write.holzcncfraese",
manage = "beispielw.holz.holzcnc.manage.holzcncfraese",
},
beispielw-holz-kappsaege = {
name = "Kappsäge",
description = "Kappsäge mit allgemeiner Einweisung Holz",
wiki = "",
category = "Holzwerkstatt",
disclose = "beispielw.holz.disclose.kappsaege",
read = "beispielw.holz.read.kappsaege",
write = "beispielw.holz.write.kappsaege",
manage = "beispielw.holz.manage.kappsaege",
},
beispielw-holz-bandschleifer = {
name = "Bandschleifer",
description = "Bandschleifer mit allgemeiner Einweisung Holz",
wiki = "",
category = "Holzwerkstatt",
disclose = "beispielw.holz.disclose.bandschleifer",
read = "beispielw.holz.read.bandschleifer",
write = "beispielw.holz.write.bandschleifer",
manage = "beispielw.holz.manage.bandschleifer",
},
beispielw-holz-staenderbohrmaschine = {
name = "Ständerbohrmaschine",
description = "Ständerbohrmaschine mit allgemeiner Einweisung Holz",
wiki = "",
category = "Holzwerkstatt",
disclose = "beispielw.holz.disclose.staenderbohrmaschine",
read = "beispielw.holz.read.staenderbohrmaschine",
write = "beispielw.holz.write.staenderbohrmaschine",
manage = "beispielw.holz.manage.staenderbohrmaschine",
},
beispielw-textil-naehmaschine1 = {
name = "Nähmaschine 1",
description = "Nähmaschine Nummer 1",
wiki = "",
category = "Textilwerkstatt",
disclose = "beispielw.textil.disclose.naehmaschine1",
read = "beispielw.textil.read.naehmaschine1",
write = "beispielw.textil.write.naehmaschine1",
manage = "beispielw.textil.manage.naehmaschine1",
},
beispielw-textil-naehmaschine2 = {
name = "Nähmaschine 2",
description = "Nähmaschine Nummer 2",
wiki = "",
category = "Textilwerkstatt",
disclose = "beispielw.textil.disclose.naehmaschine2",
read = "beispielw.textil.read.naehmaschine2",
write = "beispielw.textil.write.naehmaschine2",
manage = "beispielw.textil.manage.naehmaschine2",
},
beispielw-fablab-3dprint-3ddrucker1 = {
name = "3D-Drucker 1",
description = "3D-Drucker Modell 111",
wiki = "",
category = "FabLab",
disclose = "beispielw.fablab.3dprint.disclose.3ddrucker1",
read = "beispielw.fablab.3dprint.read.3ddrucker1",
write = "beispielw.fablab.3dprint.write.3ddrucker1",
manage = "beispielw.fablab.3dprint.manage.3ddrucker1",
},
beispielw-fablab-3dprint-3ddrucker2 = {
name = "3D-Drucker 2",
description = "3D-Drucker Modell 222",
wiki = "",
category = "FabLab",
disclose = "beispielw.fablab.3dprint.disclose.3ddrucker2",
read = "beispielw.fablab.3dprint.read.3ddrucker2",
write = "beispielw.fablab.3dprint.write.3ddrucker2",
manage = "beispielw.fablab.3dprint.manage.3ddrucker2",
},
beispielw-fablab-laser-laser3000 = {
name = "Lasercutter",
description = "Modell Laser3000",
wiki = "https://www.fiktivedoku.de",
category = "FabLab",
disclose = "beispielw.fablab.laser.disclose.laser3000",
read = "beispielw.fablab.laser.read.laser3000",
write = "beispielw.fablab.laser.write.laser3000",
manage = "beispielw.fablab.laser.manage.laser3000",
},
beispielw-fablab-laser-kuehlung3000 = {
name = "Kühlung",
description = "Modell Kühlung3000",
wiki = "",
category = "FabLab",
disclose = "beispielw.fablab.laser.disclose.kuehlung3000",
read = "beispielw.fablab.laser.read.kuehlung3000",
write = "beispielw.fablab.laser.write.kuehlung3000",
manage = "beispielw.fablab.laser.manage.kuehlung3000",
},
beispielw-siebdruck-sdbelichter = {
name = "SD-Belichter",
description = "Belichter für die Siebe",
wiki = "",
category = "Siebdruck",
disclose = "beispielw.siebdruck.disclose.sdbelichter",
read = "beispielw.siebdruck.read.sdbelichter",
write = "beispielw.siebdruck.write.sdbelichter",
manage = "beispielw.siebdruck.manage.sdbelichter",
},
beispielw-siebdruck-a3drucker = {
name = "A3-Drucker",
description = "A3 Drucker im Siebdruck Bereich",
wiki = "",
category = "Siebdruck",
disclose = "beispielw.siebdruck.disclose.a3drucker",
read = "beispielw.siebdruck.read.a3drucker",
write = "beispielw.siebdruck.write.a3drucker",
manage = "beispielw.siebdruck.manage.a3drucker",
},
beispielw-buero-drucker = {
name = "Drucker",
description = "",
wiki = "",
category = "Büro",
disclose = "beispielw.buero.disclose.drucker",
read = "beispielw.buero.read.drucker",
write = "beispielw.buero.write.drucker",
manage = "beispielw.buero.manage.drucker",
},
},
actors = {
tasmota_1 =
{
module = "Process",
params =
{
cmd = "/usr/local/lib/bffh/adapters/tasmota/main.py",
args = "--host mqtt --tasmota 1",
}
},
tasmota_2 =
{
module = "Process",
params =
{
cmd = "/usr/local/lib/bffh/adapters/tasmota/main.py",
args = "--host mqtt --tasmota 2",
}
},
tasmota_6 =
{
module = "Process",
params =
{
cmd = "/usr/local/lib/bffh/adapters/tasmota/main.py",
args = "--host mqtt --tasmota 6",
}
},
tasmota_7 =
{
module = "Process",
params =
{
cmd = "/usr/local/lib/bffh/adapters/tasmota/main.py",
args = "--host mqtt --tasmota 7",
}
},
tasmota_8 =
{
module = "Process",
params =
{
cmd = "/usr/local/lib/bffh/adapters/tasmota/main.py",
args = "--host mqtt --tasmota 8",
}
},
tasmota_9 =
{
module = "Process",
params =
{
cmd = "/usr/local/lib/bffh/adapters/tasmota/main.py",
args = "--host mqtt --tasmota 9",
}
},
tasmota_10 =
{
module = "Process",
params =
{
cmd = "/usr/local/lib/bffh/adapters/tasmota/main.py",
args = "--host mqtt --tasmota 10",
}
},
tasmota_11 =
{
module = "Process",
params =
{
cmd = "/usr/local/lib/bffh/adapters/tasmota/main.py",
args = "--host mqtt --tasmota 11",
}
},
tasmota_12 =
{
module = "Process",
params =
{
cmd = "/usr/local/lib/bffh/adapters/tasmota/main.py",
args = "--host mqtt --tasmota 12",
}
},
tasmota_13 =
{
module = "Process",
params =
{
cmd = "/usr/local/lib/bffh/adapters/tasmota/main.py",
args = "--host mqtt --tasmota 13",
}
},
tasmota_14 =
{
module = "Process",
params =
{
cmd = "/usr/local/lib/bffh/adapters/tasmota/main.py",
args = "--host mqtt --tasmota 14",
}
},
tasmota_15 =
{
module = "Process",
params =
{
cmd = "/usr/local/lib/bffh/adapters/tasmota/main.py",
args = "--host mqtt --tasmota 15",
}
},
tasmota_16 =
{
module = "Process",
params =
{
cmd = "/usr/local/lib/bffh/adapters/tasmota/main.py",
args = "--host mqtt --tasmota 16",
}
},
tasmota_17 =
{
module = "Process",
params =
{
cmd = "/usr/local/lib/bffh/adapters/tasmota/main.py",
args = "--host mqtt --tasmota 17",
}
},
tasmota_18 =
{
module = "Process",
params =
{
cmd = "/usr/local/lib/bffh/adapters/tasmota/main.py",
args = "--host mqtt --tasmota 18",
}
},
},
actor_connections = [
{ machine = "beispielw-holz-bandsaege-bandsaege", actor = "tasmota_1" },
{ machine = "beispielw-holz-hobelmaschine-hobelmaschine", actor = "tasmota_2" },
{ machine = "beispielw-holz-holzcnc-holzcncfraese", actor = "tasmota_6" },
{ machine = "beispielw-holz-kappsaege", actor = "tasmota_7" },
{ machine = "beispielw-holz-bandschleifer", actor = "tasmota_8" },
{ machine = "beispielw-holz-staenderbohrmaschine", actor = "tasmota_9" },
{ machine = "beispielw-textil-naehmaschine1", actor = "tasmota_10" },
{ machine = "beispielw-textil-naehmaschine2", actor = "tasmota_11" },
{ machine = "beispielw-fablab-3dprint-3ddrucker1", actor = "tasmota_12" },
{ machine = "beispielw-fablab-3dprint-3ddrucker2", actor = "tasmota_13" },
{ machine = "beispielw-fablab-laser-laser3000", actor = "tasmota_14" },
{ machine = "beispielw-fablab-laser-kuehlung3000", actor = "tasmota_15" },
{ machine = "beispielw-siebdruck-sdbelichter", actor = "tasmota_16" },
{ machine = "beispielw-siebdruck-a3drucker", actor = "tasmota_17" },
{ machine = "beispielw-buero-drucker", actor = "tasmota_18" },
],
Der Beispiel Mermaid Code sieht wie folgt aus und kann in https://mermaid.live gerendet werden.
mermaid-code.txt
%%{init: {"flowchart" : {"curve" : "linear"}}}%%
flowchart TD
subgraph legende["<b>Legende</b><p style="text-align:left;">👑 = Administrator
🛠️ = Manager
👷♂️ = Benutzer
👩🚀 = Benutzer (Alternativrolle)"]
end
subgraph root["
<p style="font-size: 2em">Infrastruktur</p><p style="text-align: left; margin-top: 20px;"><b><center>Rollen</center></b>👑_Admin FabAccess<br>🛠️_Manager Schichtleitung</p></p>
<p style="text-align: left; margin-top: 0px;"></p>
<p style="opacity: 0;">.</p>
"]
end
subgraph root_beispielw["
<p style="font-size: 1.75em">Beispielwerkstatt </p><p style="text-align: left; margin-top: 20px;"><b><center>Rollen</center></b>🛠️Manager Beispielwerkstatt </p></p>
<p style="text-align: left; margin-top: 0px;"></p>
<p style="opacity: 0;">.</p>
"]
end
root ------ root_beispielw
root_beispielw ---- root_beispielw_buero_wrapper
subgraph root_beispielw_buero_wrapper["<p style="opacity: 0;">.</p>"]
style root_beispielw_buero_wrapper stroke: none, fill: none
subgraph root_beispielw_buero["
<p style="font-size: 1.5em">Büro</p><p style="text-align: left; margin-top: 20px;"><b><center>Rollen</center></b>🛠️Manager Büro<br>👷♂️Benutzer Büro<br>👩🚀Benutzer Druckernutzung</p></p>
<p style="text-align: left; margin-top: 0px;"><b><center>Maschinen</center></b>Drucker (👩🚀Benutzer Druckernutzung)</p>
<p style="opacity: 0;">.</p>
"]
end
subgraph filler_root_beispielw_buero_1["
<p style="opacity: 0;">
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
</p>"]
end
style filler_root_beispielw_buero_1 fill: none, stroke: none
root_beispielw_buero~~~~~~filler_root_beispielw_buero_1
subgraph filler_root_beispielw_buero_2["
<p style="opacity: 0;">
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
</p>"]
end
style filler_root_beispielw_buero_2 fill: none, stroke: none
filler_root_beispielw_buero_1~~~~~filler_root_beispielw_buero_2
end
root_beispielw ---- root_beispielw_fablab_wrapper
subgraph root_beispielw_fablab_wrapper["<p style="opacity: 0;">.</p>"]
style root_beispielw_fablab_wrapper stroke: none, fill: none
subgraph root_beispielw_fablab["
<p style="font-size: 1.5em">FabLab</p><p style="text-align: left; margin-top: 20px;"><b><center>Rollen</center></b>🛠️Manager FabLab<br>👷♂️Benutzer FabLab</p></p>
<p style="text-align: left; margin-top: 0px;"></p>
<p style="opacity: 0;">.</p>
"]
end
subgraph root_beispielw_fablab_3dprint["
<p style="font-size: 1.25em">3D-Druck</p><p style="text-align: left; margin-top: 20px;"><b><center>Rollen</center></b>🛠️Manager FabLab 3D-Druck<br>👷♂️Benutzer FabLab 3D-Druck</p></p>
<p style="text-align: left; margin-top: 0px;"><b><center>Maschinen</center></b>3D-Drucker 1<br>3D-Drucker 2</p>
<p style="opacity: 0;">.</p>
"]
end
root_beispielw_fablab ------ root_beispielw_fablab_3dprint
subgraph root_beispielw_fablab_laser["
<p style="font-size: 1.25em">Laser</p><p style="text-align: left; margin-top: 20px;"><b><center>Rollen</center></b>🛠️Manager FabLab Laser<br>👷♂️Benutzer FabLab Laser</p></p>
<p style="text-align: left; margin-top: 0px;"><b><center>Maschinen</center></b>Lasercutter<br>Kühlung</p>
<p style="opacity: 0;">.</p>
"]
end
root_beispielw_fablab ------ root_beispielw_fablab_laser
end
root_beispielw ---- root_beispielw_holz_wrapper
subgraph root_beispielw_holz_wrapper["<p style="opacity: 0;">.</p>"]
style root_beispielw_holz_wrapper stroke: none, fill: none
subgraph root_beispielw_holz["
<p style="font-size: 1.5em">Holzwerkstatt</p><p style="text-align: left; margin-top: 20px;"><b><center>Rollen</center></b>🛠️Manager Holzwerkstatt<br>👷♂️Benutzer Holzwerkstatt</p></p>
<p style="text-align: left; margin-top: 0px;"><b><center>Maschinen</center></b>Kappsäge<br>Bandschleifer<br>Ständerbohrmaschine</p>
<p style="opacity: 0;">.</p>
"]
end
subgraph root_beispielw_holz_bandsaege["
<p style="font-size: 1.25em">Bandsäge</p><p style="text-align: left; margin-top: 20px;"><b><center>Rollen</center></b>🛠️Manager Holzwerkstatt Bandsäge<br>👷♂️Benutzer Holzwerkstatt Bandsäge</p></p>
<p style="text-align: left; margin-top: 0px;"><b><center>Maschinen</center></b>Bandsäge</p>
<p style="opacity: 0;">.</p>
"]
end
root_beispielw_holz ------ root_beispielw_holz_bandsaege
subgraph root_beispielw_holz_hobelmaschine["
<p style="font-size: 1.25em">Hobelmaschine</p><p style="text-align: left; margin-top: 20px;"><b><center>Rollen</center></b>🛠️Manager Holzwerkstatt Hobelmaschine<br>👷♂️Benutzer Holzwerkstatt Hobelmaschine</p></p>
<p style="text-align: left; margin-top: 0px;"><b><center>Maschinen</center></b>Hobelmaschine</p>
<p style="opacity: 0;">.</p>
"]
end
root_beispielw_holz ------ root_beispielw_holz_hobelmaschine
subgraph root_beispielw_holz_holzcnc["
<p style="font-size: 1.25em">CNC-Fräse</p><p style="text-align: left; margin-top: 20px;"><b><center>Rollen</center></b>🛠️Manager Holzwerkstatt CNC-Fräse<br>👷♂️Benutzer Holzwerkstatt CNC-Fräse</p></p>
<p style="text-align: left; margin-top: 0px;"><b><center>Maschinen</center></b>CNC-Fräse</p>
<p style="opacity: 0;">.</p>
"]
end
root_beispielw_holz ------ root_beispielw_holz_holzcnc
end
root_beispielw ---- root_beispielw_siebdruck_wrapper
subgraph root_beispielw_siebdruck_wrapper["<p style="opacity: 0;">.</p>"]
style root_beispielw_siebdruck_wrapper stroke: none, fill: none
subgraph root_beispielw_siebdruck["
<p style="font-size: 1.5em">Siebdruck</p><p style="text-align: left; margin-top: 20px;"><b><center>Rollen</center></b>🛠️Manager Siebdruck<br>👷♂️Benutzer Siebdruck<br>👩🚀Benutzer Druckernutzung</p></p>
<p style="text-align: left; margin-top: 0px;"><b><center>Maschinen</center></b>SD-Belichter<br>A3-Drucker (👩🚀Benutzer Druckernutzung)</p>
<p style="opacity: 0;">.</p>
"]
end
subgraph filler_root_beispielw_siebdruck_1["
<p style="opacity: 0;">
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
</p>"]
end
style filler_root_beispielw_siebdruck_1 fill: none, stroke: none
root_beispielw_siebdruck~~~~~~filler_root_beispielw_siebdruck_1
subgraph filler_root_beispielw_siebdruck_2["
<p style="opacity: 0;">
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
</p>"]
end
style filler_root_beispielw_siebdruck_2 fill: none, stroke: none
filler_root_beispielw_siebdruck_1~~~~~filler_root_beispielw_siebdruck_2
end
root_beispielw ---- root_beispielw_textil_wrapper
subgraph root_beispielw_textil_wrapper["<p style="opacity: 0;">.</p>"]
style root_beispielw_textil_wrapper stroke: none, fill: none
subgraph root_beispielw_textil["
<p style="font-size: 1.5em">Textilwerkstatt</p><p style="text-align: left; margin-top: 20px;"><b><center>Rollen</center></b>🛠️Manager Textilwerkstatt<br>👷♂️Benutzer Textilwerkstatt</p></p>
<p style="text-align: left; margin-top: 0px;"><b><center>Maschinen</center></b>Nähmaschine 1<br>Nähmaschine 2</p>
<p style="opacity: 0;">.</p>
"]
end
subgraph filler_root_beispielw_textil_1["
<p style="opacity: 0;">
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
</p>"]
end
style filler_root_beispielw_textil_1 fill: none, stroke: none
root_beispielw_textil~~~~~~filler_root_beispielw_textil_1
subgraph filler_root_beispielw_textil_2["
<p style="opacity: 0;">
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
</p>"]
end
style filler_root_beispielw_textil_2 fill: none, stroke: none
filler_root_beispielw_textil_1~~~~~filler_root_beispielw_textil_2
end