BetterContacts: Funktionsparameter in Kontaktpunkten, Nachfolger meiner "Codezeile"

!!! Please ensure, that your contribution or question is placed into the relevant section !!!
Questions about rolling stock, for example, do not belong in "Questions about the Forum". Following is perhaps the right area where your question will be better looked after:
General questions to EEP , Splines, rolling stock, Structures in EEP, landscape elements, Signalling system and controlling, designers, Europe-wide EEP meetings , Gossip
Your cooperation to keep the forum clear is appreciated.
In the case of pictures that are attached to the article, the source must also be stated. This also applies to your own pictures, which were taken by you. Pictures without source information will be deleted!
  • Ich denke, meine "Codezeile" dürfte fast jeder kennen. Falls nicht, hier ein Link zum Thema von damals (schon fast sechs Jahre alt :ad_1:). Damit ist es möglich, in Kontaktpunkten nicht nur einen Lua-Funktionsnamen einzutragen, sondern dieser Funktion auch Parameter mitzugeben.


    Diese Codezeile hat nur einen Schönheitsfehler: Der Zugname wird als globale Variable gesetzt, und steht damit im gesamten Skript zur Verfügung, auch ohne ihn als Funktionsparameter explizit mitgegeben zu haben. So eine globale Variable mag zwar auf den ersten Blick praktisch erscheinen, kann dafür aber die Fehlersuche erheblich erschweren. Deshalb mag ich keine globalen Variablen.


    Da im Forum immer wieder Beispiele mit der "falschen" Verwendung des Zugnamens auftauchten, probierte ich letztes Jahr etwas herum, wie ich die globale Variable loswerden könnte - und war erfolgreich. Anstatt einer weiteren Variante der Codezeile entschied ich mich diesmal für ein vollwertiges Lua-Modul, das per Modellinstaller installiert und anschließend mit require eingebunden wird.

    Die Vorteile von so einem Modul sind unter anderem eine Zentralisierung der Funktionalität (sodass eventuell notwendige Änderungen nur an einer Stelle erfolgen müssen statt verstreut über viele Dateien bzw. alle Anlagen) und vor allem mehr Platz. So konnte ich noch einige nützliche Dinge einbauen wie Konfigurationsmöglichkeiten (dadurch lassen sich alle bisherigen Varianten durch das neue Modul ersetzen) und Hilfen zur Fehlersuche und -vermeidung. Im Endeffekt ist das Modul jetzt 122 Zeilen bzw. 4366 Zeichen lang geworden. Zum Vergleich: Meine Codezeile bestand (je nach Variante) aus nur 142 bis 206 Zeichen.


    "Codezeile", "Codeschnipsel", "KP-Parameter", "Funktionsargumente in Kontaktpunkten" - die bisherige Lösung hatte viele Namen und keiner davon passte so richtig. Ein einheitlicher und eindeutiger Name ist aber wichtig, wenn man über etwas reden oder danach suchen will. Und speziell zum Einbinden mittels require braucht ein Modul natürlich auch einen eindeutigen Namen. Nach einigem Brainstorming entschied ich mich für "BetterContacts" - weil dadurch die Kontakte "besser" werden.


    Der eigentliche Code war recht schnell geschrieben, aber ohne Doku ist so ein Modul recht nutzlos. Deshalb schlummerte BetterContacts für über ein Jahr auf meiner Festplatte (und auf GitHub), bis ich in den vergangenen Tagen endlich mal Zeit gefunden habe zum Dokuschreiben. So kann ich jetzt endlich verkünden:

    BetterContacts ist da!

    BetterContacts funktioniert fast genauso wie meine Codezeile, ist aber noch ein Stückchen besser.

    Der Umstieg sollte keine Probleme bereiten.


    Den Download sowie die ausführliche Dokumentation (inklusive Schnellstart- und Umstiegsanleitung) findet ihr unter obigem Link auf meiner Homepage.

    Falls es Probleme (ich hoffe nicht) oder sonstige Fragen gibt, dürft ihr euch natürlich wie immer gerne melden.


    Viele Grüße

    Benny


    PS: Noch eine Bitte an alle fleißigen Helferlein und Tipp-Geber hier im Forum: Ich erwarte natürlich nicht, dass ihr jetzt alle euren alten Beispiele anpasst. Ich würde mich aber freuen, wenn eure zukünftigen Hilfestellungen nicht mehr die nun veraltete Codezeile nutzen, sondern BetterContacts. Dankeschön :aa_1:

  • Kann man bitte den Beitrag und den Link an ganz zentraler Stelle im Forum ganz fest anpinnen, so dass man ihn wirklich jederzeit mit (fast) jedem Suchbegriff immer wiederfindet, auch wenn man sich nur gelegentlich mal mit dem Thema befasst. Danke sehr

  • Hallo Klaus,

    Kann man bitte den Beitrag und den Link an ganz zentraler Stelle im Forum ganz fest anpinnen, so dass man ihn wirklich jederzeit mit (fast) jedem Suchbegriff immer wiederfindet, auch wenn man sich nur gelegentlich mal mit dem Thema befasst.

    Kann man und ist geschehen. Einmal wurde der Faden mit einem schönen Label versehen und zum zweiten wurde auf dem Portal in der Box Interessante Links ein Link eingefügt.

    Danke sehr

    Bitte sehr und Danke für den Anschubser. :aq_1:

  • Hallo Benny,


    ich hab gerade mal bisschen probiert, funktioniert tadellos - so wie gewohnt bei Dir...

    ein bisschen bin ich auf Dein Gehirn neidisch :aa_1:


    Gruß Frank

    aus St. Egidien in Sachsen

    Bin nur noch lesendes Mitglied... (meistens:aa_1:)

  • Moin zusammen,

    bei mir funktioniert es leider nicht. Bekomme diese Fehlermeldung:



    Ich bin so vorgegangen, wie beschrieben:

    - Datei in Lua Ordner kopiert,

    - alten Code-Schnipsel aus Parry's Tool Box entfernt, bzw, auskommentiert,

    - Datei mit require("BetterContacts_BH2") aufgerufen,

    - print Zeile print("BetterContacts_BH2") am Ende eingefügt, damit ich sehen kann, ob sie ordnungsgemäss eingebunden wurde.


    Ergebnis siehe Meldung im Ereignis Fenster. Bin ratlos :aw_1:

    es grüßt Michael aus Flensburg


    PC: Intel® Core™ i3-4170, CPU: @ 3,7 GHZ, GPU: NVIDIA GeForce GTX 960

    RAM: 4,00 GB, BS: Windows 10 Home 64 Bit, Version 19041, Virenschutz: Windows Defender

    Tastatur: Logitech G213, Maus: Logitech G502

    EEP 17.1 [x64] Patch 1, Plugins 1

    EEP 13 - 16 komplett

    EEP Classic 6.1

    Zusätzlich: Modellexplorer, Modellkatalog, Modellkonverter,


    Life isn't how to survive the storm, it's about how to dance in the rain.

  • Hallo Michael Raumpatrouille


    so wie es aussieht, ist dir ein Fehler beim Einfügen der print-Zeile passiert.


    Evtl. wurde die Datei nach der Änderung (in EEP oder externer Editor??) als *.lua.txt oder in einem anderen Verzeichnis abgespeichert.


    Möglichkeit der Überprüfung:

    nochmals Bennys Datei installieren und ohne Änderung testen!


    :aq_1:

    eep_gogo ( RG3 )

    -------------------------

    Intel i3-540 3,2GHz 8GB, RAID10, HD 6570 1GB, W7/64 Prof., EEP 6-6.1, 10-17.0, HN13+15/16+15/16DEV, TM, "Schiefe Ebene 6 + 8", "Bahn2000", "Faszination der St. Gotthard-Nordrampe"

  • Ich bin so vorgegangen, wie beschrieben:

    - Datei in Lua Ordner kopiert,

    - alten Code-Schnipsel aus Parry's Tool Box entfernt, bzw, auskommentiert,

    - Datei mit require("BetterContacts_BH2") aufgerufen,

    - print Zeile print("BetterContacts_BH2") am Ende eingefügt, damit ich sehen kann, ob sie ordnungsgemäss eingebunden wurde.

    Mewine Vorgehensweise ist die gleiche, außer ich habe den print("BetterContacts_BH2") an den Anfang gesetzt und es funktioniert tadelos.

    Es grüßt aus dem schönen Westerwald


    Michael


  • Hallo Michael,

    wie eep_gogo (RG3) schon gesagt hast, hast du vermutlich beim Einfügen der print-Zeile einen Fehler gemacht.


    Die letzte Zeile in meinem Skript lautet return betterContacts. Lua erwartet, dass nach einem return nichts mehr kommt. Wenn du da jetzt noch ein print dahintergeschrieben hast, kommt es zur genannten Fehlermeldung.


    Wenn du unbedingt ein print einbauen willst, dann muss es vor das return.

    Aber eigentlich sollte es gar nicht nötig sein: Wenn beim Einbinden etwas nicht klappt, kommt eigentlich immer eine Fehlermeldung. Wenn keine Fehlermeldung kommt, kannst du also erstmal davon ausgehen, dass es geklappt hat (solange du nicht explizit das Gegenteil feststellst).


    Ich empfehle generell, an fremden Modulen keine eigenen Änderungen vorzunehmen. Es besteht sonst immer die Gefahr, dass bei einem Update des Moduls deine Änderungen überschrieben werden.



    Viele Grüße

    Benny

  • Das Einbinden vor return war's.

    Jetzt ist sie eingebunden.

    Aber jetzt sieht es noch schlimmer aus: :am_1:



    Verträgt sich da was mit Parry's Tool Box nicht?


    Ich werde es wohl beim alten Schnipsel lassen.

    es grüßt Michael aus Flensburg


    PC: Intel® Core™ i3-4170, CPU: @ 3,7 GHZ, GPU: NVIDIA GeForce GTX 960

    RAM: 4,00 GB, BS: Windows 10 Home 64 Bit, Version 19041, Virenschutz: Windows Defender

    Tastatur: Logitech G213, Maus: Logitech G502

    EEP 17.1 [x64] Patch 1, Plugins 1

    EEP 13 - 16 komplett

    EEP Classic 6.1

    Zusätzlich: Modellexplorer, Modellkatalog, Modellkonverter,


    Life isn't how to survive the storm, it's about how to dance in the rain.

  • Das sieht so aus, als würde Parrys Toolbox von Zugname als globale Variable Gebrauch machen. Du kannst diesen (von mir ungeliebten) Modus auch in BetterContacts aktivieren (siehe Doku auf meiner Homepage, Stichwort deprecatedUseGlobal).

    Oder du lässt die Toolbox unverändert und wartest darauf, dass Parry seine Toolbox anpasst (wobei das wohl auch nichts an der Verwendung der globalen Variable ändert; oder wenn doch, müsstest du alle Kontaktpunkte anfassen, um den Zugnamen explizit mitzugeben).


    Viele Grüße

    Benny

  • Stichwort deprecatedUseGlobal).

    Das war die entscheidende Lösung.

    Jetzt läuft's wie geschmiert. :ap_1:


    Danke Dir. :be_1:

    es grüßt Michael aus Flensburg


    PC: Intel® Core™ i3-4170, CPU: @ 3,7 GHZ, GPU: NVIDIA GeForce GTX 960

    RAM: 4,00 GB, BS: Windows 10 Home 64 Bit, Version 19041, Virenschutz: Windows Defender

    Tastatur: Logitech G213, Maus: Logitech G502

    EEP 17.1 [x64] Patch 1, Plugins 1

    EEP 13 - 16 komplett

    EEP Classic 6.1

    Zusätzlich: Modellexplorer, Modellkatalog, Modellkonverter,


    Life isn't how to survive the storm, it's about how to dance in the rain.

  • Ich kann nur ausdrücklich davor warnen, Benny´s neue Mammut Konstruktion

    in meine Scripte einzubinden.
    Die Angstmacherei vor der sogenannten globalen Variablen "Zugname" ist
    total unbegründet, da diese Variable Zugname nicht global ist, sehr leicht

    nachweisbar durch den Printaufruf :

    print("Das soll eine Globale sein: ", Zugname)

    Im übrigen hat Benny in seinem Codeschnipsel mit der Zeile:

    Zugname = s     -- local(s) Zugname, ist nur innerhalb der Funktion gültig.


    dafür gesorgt, dass die Variable mit nil belegt wird, und somit außerhalb

    dieser Funktion nicht mehr gültig und nicht sichtbar ist.


    Wer weiterhin mein rus Paket nutzen möchte, sollte das Modul nicht in seine Scripte einbinden.


    Gruß Dieter

    1.MSI 17,3" Intel® i7-8750H 16GB SSD + HDD GeForce® GTX 1060 »GV72 8RE-013DE (00179E-013)

    2. PC:Win10/64, i7-7700K, 4.2 GHz, GPU GTX 1070/8 GB, 16 GB RAM(DDR4), SSD 960 Evo 500GB, Ilyama PL2490
    EEP 6.1 - EEP 15 E, HomeNos 15


    Ich wünsche mir eine freizügige Script-Sprache und eine leistungsfähige Grafik Engine für EEP.
    Ein Leben ohne EEP ist möglich, aber sinnlos, so ganz sicher bin ich mir nicht mehr.

    "mal was ganz Einfaches" "rundum sorglos Paket"

    Parrys YouTube Videos
    https://www.twitch.tv/parry_36/

    The post was edited 2 times, last by Parry36 ().

  • Hallo Dieter,

    wenn ich sage, dass Zugname global ist, dann meine ich das auch so. Die Variable steht während des KP-Aufrufs (also während das, was im Kontaktpunkt drinsteht, von Lua abgearbeitet wird) global im gesamten Skript zur Verfügung. Wenn du währenddessen print(Zugname) machst, wirst du den Zugnamen auch sehen.

    Nach dem KP-Aufruf wird (durch die von dir zitierte Zeile, wobei der Kommentar nicht von mir stammt) die globale Variable Zugname unmittelbar wieder zurückgesetzt auf das, was vorher drinstand, um ungewollte Effekte möglichst klein zu halten. Wenn die Variable vorher "nicht definiert" (=nil) war, wird sie das hinterher auch wieder sein.


    Ich will keine Angst machen vor globalen Variablen. Aber ich persönlich mag sie nicht, und habe das meiner Meinung nach auch begründet. Wenn die Begründung nicht ausreichend war, kann ich bei Bedarf (und wenn ich Zeit finde) noch mehr dazu schreiben.


    Ich verlange nicht, dass du meine Meinung bezüglich globaler Variablen teilst. Ich denke, es ist offensichtlich, dass wir da unterschiedlicher Meinung sind.

    Und wenn du irgendeinen Grund hast, vor dem Einsatz von BetterContacts zu warnen, darfst du das auch gerne machen. Dann wäre es aber schön, wenn du den Grund auch nennen würdest. So eine unbegründete Warnung finde ich doch etwas befremdlich.


    Wer weiterhin mein rus Paket nutzen möchte, sollte das Modul nicht in seine Scripte einbinden.

    Das akzeptiere ich so erstmal. Wobei ich mir (bis zum "Beweis" des Gegenteils) sehr sicher bin, dass bei entsprechender Konfiguration (Stichwort deprecatedUseGlobal) auch mit BetterContacts alles so funktioniert wie vorher.


    Viele Grüße

    Benny

  • Hallo Benny,


    dein "Modul" funktioniert in meinen Skripten tadellos. :be_1::aq_1:

    Aber eigentlich sollte es gar nicht nötig sein: Wenn beim Einbinden etwas nicht klappt, kommt eigentlich immer eine Fehlermeldung

    Da Du aber selbst mit Versionsnummern arbeitest, kann es natürlich sein, wenn Du ein Update einspielst, ändert sich logischer Weise auch die Version. Damit man nicht immer in jedes Skript nachschaut, welche Version gerade aktiv ist, wäre es sinnvoll, wenn es im Ereignisfenster stehen würde. Ich habe stellenweise über 16 Skript-Module mit unterschiedlichen Versionsnummern aktiv. Damit habe ich gleich einen Überblick, mit welcher Version ich gerade arbeite, denn stellenweise habe ich auch mehrere Anlagen zum Testen aktiv.

    Ich würde mir daher einen Ausdruck wünschen. Zur Zeit habe ich selbst einen "print" gesetzt.

    Ich empfehle generell, an fremden Modulen keine eigenen Änderungen vorzunehmen. Es besteht sonst immer die Gefahr, dass bei einem Update des Moduls deine Änderungen überschrieben werden.

    Deshalb der Wunsch von mir.:ae_1::ay_1:

    MfG. Jörg
    Ausstattung: Notebook: i7-6700K, 4[8]x4.0 GHz, 32GB RAM DDR4, NVIDIA GTX 980M 8GB, Windows 10, 64-Bit
    Installiert: EEP17.1 Patch1 und Plugin1

    Zusatzprogramme: ResourcenSwitcher2, EEP-Gleisplan (Frank Buchholz)

  • Hallo Benny,

    du sagst : "so eine unbegründete Warnung findest du befremdlich".

    Die Antwort hast du bereits in #9 gegeben:

    Ich empfehle generell, an fremden Modulen keine eigenen Änderungen vorzunehmen.

    Aus diesem Grund möchte ich nicht, dass dein Mammut-Script in mein rus Paket

    eingebunden wird.

    Mir entzieht sich das Verständnis, das bisherige kleine Script, mit gerade mal

    15 Zeilen, ein aufgeblähtes Script mit sagenhaften über 100 Zeilen gegenüber
    zu stellen.

    Um im Kontaktpunkt eine Stringfunktion mit Parametern auszuführen genügt

    ein kleines setmetatable() :

    Wenn Lua bei einem Aufruf nicht klarkommt sucht es nach einer Metatabelle, etwa so:


    LUA Source Code
    1. setmetatable(_ENV,{__index = function(s,k)
    2. local p = load(k)
    3. if p then
    4. _ENV[k] = p;
    5. return p
    6. end
    7. return nil
    8. end})

    Das hat nur einen Haken, wie komme ich an den Zugnamen, den EEP

    im KP übegibt, und da gibt es die glorreiche Prototypefunktion, (hat uns

    mal Goetz gezeigt) und die ist mit wenigen Zeilen zu erledigen.

    Da frage ich mich, warum der ganze aufgeblähte Zauber?


    Gruß Dieter

    1.MSI 17,3" Intel® i7-8750H 16GB SSD + HDD GeForce® GTX 1060 »GV72 8RE-013DE (00179E-013)

    2. PC:Win10/64, i7-7700K, 4.2 GHz, GPU GTX 1070/8 GB, 16 GB RAM(DDR4), SSD 960 Evo 500GB, Ilyama PL2490
    EEP 6.1 - EEP 15 E, HomeNos 15


    Ich wünsche mir eine freizügige Script-Sprache und eine leistungsfähige Grafik Engine für EEP.
    Ein Leben ohne EEP ist möglich, aber sinnlos, so ganz sicher bin ich mir nicht mehr.

    "mal was ganz Einfaches" "rundum sorglos Paket"

    Parrys YouTube Videos
    https://www.twitch.tv/parry_36/

    The post was edited 1 time, last by Parry36 ().

  • Hallo, alles gut und schön, aber warum kann man wenn es wirklich soo gut ist nicht

    Beide sich zusammensetzen und gemeinsam ein Modul konstruieren.

    Ich warte auf jedem Fall bis Parry in seiner Tool Box es eingebunden hat.

    LG aus Sachsen

    Dietmar

    HP envy 360 Convertible 15, i7-- 8550U 1,8 GHz, 8 GB), 250 GB SSD (für EEP 16,1), 1 TB HDD, Windows 10

    ASUS VE278 und ASUS VS247

  • Hallo Jörg,

    meiner Meinung nach sollte es nicht nötig sein, jedesmal die Versionsnummer auszugeben. Da alle deine Anlagen auf die gleiche Datei (BetterContacts_BH2.lua) zugreifen, laufen auch alle Anlagen mit der gleichen Version. Wenn du von einem Update erfährst, kannst du diese eine Datei einmal ersetzen, danach ist das Update erledigt und du musst dich nicht mehr drum kümmern.

    Darüberhinaus kannst du auch "von außen" (also aus dem Anlagenskript heraus) auf die Versionsnummer zugreifen:

    LUA Source Code
    1. print("Die Version von BetterContacts ist " .. table.concat(require("BetterContacts_BH2")._VERSION, "."))

    Der erneute require-Aufruf tut nicht weh, da sich Lua das "Ergebnis" gemerkt hat und somit der Code innerhalb der eingebundenen Datei nicht erneut ausgeführt wird.


    Wenn du trotzdem an deinem Wunsch festhältst und auch andere dies wollen, könnte ich eine weitere Option namens printVersionInfo hinzufügen, die dann die gewünschte Info ausgibt.

    Eine standardmäßige Ausgabe will ich nicht, weil ich gerne selbst bestimme, was im Ereignisfenster steht (am besten möglichst wenig).



    Hallo Dieter,

    dann war das wohl ein Missverständnis. Ich hatte deine Aussage so verstanden, dass du generell von der Benutzung von BetterContacts abrätst. Dass du nicht willst, dass in deinen Skripten "rumgefummelt" wird, kann ich voll und ganz nachvollziehen. Vielleicht liegt das ganze Missverständnis auch nur an einem kleinen Tippfehler, und statt...

    Ich kann nur ausdrücklich davor warnen, Benny´s neue Mammut Konstruktion in seine Scripte einzubinden.

    meintest du "... meine Scripte"?


    Mir entzieht sich das Verständnis, das bisherige kleine Script, mit gerade mal 15 Zeilen, ein aufgeblähtes Script mit sagenhaften über 100 Zeilen gegenüber zu stellen.

    Nunja, man könnte den 15 Zeilen* auch die eine require-Zeile gegenüberstellen. Du sollst ja nicht das gesamte BetterContacts in dein Anlagenskript oder rus-Pakt reinkopieren.

    * Ich weiß nicht mal genau, wo du deine 15 Zeilen überhaupt her hast. Ich habe auf meiner Homepage einen Einzeiler bereitgestellt.


    Die ganze "Aufblähung" kommt übrigens hauptsächlich durch die ganzen neuen Komfort- und Sicherheitsmerkmale zustande.


    Dein(?) Codebeispiel ist die Essenz von dem, was meine bisherige Codezeile und jetzt BetterContacts macht. Nur halt ohne alles drumherum.


    Da frage ich mich, warum der ganze Zauber?

    Ich meine, die Gründe habe ich im Ausgangsbeitrag genannt.


    Viele Grüße

    Benny


    Nachtrag, weil erst nach dem Abschicken gesehen:

    aber warum kann [...] nicht Beide sich zusammensetzen und gemeinsam ein Modul konstruieren.

    Ich wüsste nicht, was es "gemeinsam zu konstrieren" gäbe. Mein Modul ist fertig.

    Außerdem sind unsere Vorstellungen von verschiedenen Dingen doch recht unterschiedlich. Aber an mir soll es nicht scheitern.

  • Dietmar,

    da kannst du aber lange warten, ich werde auch weiterhin den
    Schnipsel in meiner Toobox nutzen.


    Gruß Dieter

    1.MSI 17,3" Intel® i7-8750H 16GB SSD + HDD GeForce® GTX 1060 »GV72 8RE-013DE (00179E-013)

    2. PC:Win10/64, i7-7700K, 4.2 GHz, GPU GTX 1070/8 GB, 16 GB RAM(DDR4), SSD 960 Evo 500GB, Ilyama PL2490
    EEP 6.1 - EEP 15 E, HomeNos 15


    Ich wünsche mir eine freizügige Script-Sprache und eine leistungsfähige Grafik Engine für EEP.
    Ein Leben ohne EEP ist möglich, aber sinnlos, so ganz sicher bin ich mir nicht mehr.

    "mal was ganz Einfaches" "rundum sorglos Paket"

    Parrys YouTube Videos
    https://www.twitch.tv/parry_36/

  • Hallo Benny,

    Alles super. Eingebunden in bestehende Anlagen ohne Probleme. Die Rangelei um Lokale Variablen ist unnötig weil im Profi-Bereich, in allen Programmiersprachen, immer Lokale bevorzugt werden.

    Vielen Dank für die Erweiterung.

    Gruss aus Namibia, JPB

    Windows 11 Pro

    Motherboard Gigabyte Z690 Gaming X

    Intel(R) Core(TM) i9-12900 CPU 16-Core 24 Threads

    2 x NVIDIA GeForce GTX 1080

    2 x Dell U2713HM (DP) 2560 x 1440 (on GK 01)

    2 x Dell P2715Q 3840 x 2160 (on GK 02)

    6 x 6TB HD

    1 x 512GB SSD

    64 GB RAM


    EEP Expert Version Installed:

    16.4 Plug-In 4 und Update 2

    17.2

    EEP Zug Explorer/PlanEX 3.20/EEP Modell Explorer/Modell Katalog/Anlageverbinder EEP16/Tauschmanager 15/Home Nostructor V13/Bulkinstaller/uvm