Script starten wenn VUPlus On/Standby geht

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    • Script starten wenn VUPlus On/Standby geht

      Hallo zusammen,

      Ich hatte bisher eine Dreambox8000, welche nun altershalber den Geist aufgegeben hat, und habe diese nun mit einer VuPlus Ultimo 4k ersetzt welche auf dem VTi-13.0.1 läuft.

      Die alte Dreambox8000 hatte ich in meiner FHEM Home Automation integriert. Ich hatte dieses bewerkstelligt in dem ich das Plugin "enigma2-plugin-extensions-executeonpowerevent_1.01-20130106_mips32el.ipk" eingesetzt habe welches jeweils bei Drücken der On Taste die Dreambox gestartet hat (aus dem Standby) und dabei das Script "enigma_standby_on.sh" gestartet hat.
      Dieses Script hat jeweils mittels echo über die Console (telnet auf fhem-ip:7072) einen Dummy auf On gesetzt. Diesen habe ich im Fhem mit notify abgefragt. Wenn der Dummy auf on geht, habe ich ich die entsprechenden Lichtquellen gestartet, sowie Fernseher und Surround eingeschaltet.



      Bei drücken der Off Taste der Dreambox Fernbedienung habe ich dann wiederum ein Script "enigma_standby_off.sh" gestartet welches den Dummy auf Off setzt und die Auschaltung der Fernseh Umgebung und des Lichts angesteuert hat.


      Ich müsste nun in der VUPlus auch diese Scripte starten können wenn jeweils die Box aus dem Standby kommt oder in den Standby geht.


      Am elegantesten wäre sicherlich wieder die Verwendung des Plugins, da dieses den Vorteil hat dass nicht bei jedem Update wieder nachgebessert werden muss. Leider lässt sich das Plugin "enigma2-plugin-extensions-executeonpowerevent_1.01-20130106_mips32el.ipk" nicht installieren. Es meldet immer 0 Pakete mit 0 Fehler installiert. Ich nehme mal an dass die Version des Dreambox8000 Plugins mit dem VTi Image nicht kompatibel ist. Hier konnte jeweils einfach bei On/Standby entweder ein Script unter "/usr/script" konfiguriert werden oder ein bestimmter URL eingegeben werden der aufgerufen werden sollte.


      Frage:

      - Gibt es eine Version des Plugins "enigma2-plugin-extensions-executeonpowerevent_1.01-20130106_mips32el.ipk" die auch auf der

      VUPlus unter VTi funktioniert, und wo wäre das zu finden?


      - Falls nicht, gibt es ein ähnliches Plugin für die VUPlus oder kann sonst wie ein Script bei On/Standby ausgelöst werden?
      Wenn ja, wie?

      - Gibt es allenfalls die Möglichkeit die Scripts als Symlinks beim Boot Prozess zu triggern?
      Falls ja, gibt es ne Beschreibung zur Bootreihenfolge um rauszufinden an welcher Stelle der erstellt werden müsste?

      In Sachen Linux stehe ich noch ziemlich am Anfang und wäre hier um jeden Tipp wirklich sehr dankbar.


      Mit freundlichem Grusss


      Philipp
    • happy3127 schrieb:

      "enigma2-plugin-extensions-executeonpowerevent_1.01-20130106_mips32el.ipk"
      die Ultimo4K hat wie alle VU-4K-Boxen eine ARM-CPU, kein Mipsel, du musst also ein ****arm oder ****all .ipk finden oder in das mipsel-paket reinschauen und nachsehen, ob da tatsächlich mipsel-binaries drin sind. Wenn nur Skripte und oder configs enthalten sind klappt es eventuell mit schlichtem entpacken der ipk
      ACHTUNG!!!! Hier folgt eine Signatur:


      Die Benutzung der Suche ist NICHT verboten! D:

      "Hilfe!!!" ist kein sinnvoller Titel für einen neuen Thread, ebensowenig "VU+Zero" oder vergleichbares.

      Keine Hilfe ohne ausgefülltes Profil!
      Kein Netzwerksupport bei manueller IP-Adress-Vergabe :-)
      Kein Support bei portforwardings/ Portfreigaben

      Profil extra angepasst für die arme Emma, die sonst nichts im Leben hat :happy1:
    • Geht auf alle Fälle, habe ich hier glaube ich auch schon mal irgendwo gepostet; wieviel Python kannst du? Das angehängte Plugin ist nicht fertig, sondern nur ein Skelett, welches bei Standby/Startup aufgerufen wird. Den Aufruf eines Shell-Scriptes müsstest du noch in die Funktion "standbyCounterChanged" einbauen.
      Dateien
      • onstandby.zip

        (1,59 kB, 91 mal heruntergeladen, zuletzt: )
      Diskutiere nie mit einem Idioten. Er zieht dich auf sein Niveau runter und schlägt dich mit seiner Erfahrung.
    • Hallo zusammen,

      Herzlichen Dank für eure Feedbacks. Werde mich morgen mal dahinter klemmen und versuchen wie weit ich komme. Werde mich wieder melden.
      Bisher noch keinerlei Python Erfahrung. Bei FHEM habe ich ich in erster Linie nur Perl genutzt.

      Grüsse Philipp
    • Hallo rdamas,

      Ich habe versucht das im OnStandby enthaltene ipk zu installieren. Es wird mir auch zurück gemeldet das 1 Paket ohne Fehler installiert wurde. Ich kann aber weder unter den Diensten, Erweiterungen noch sonstwo etwas sehen wo ich dann einstellungen vornehemn kann.

      Was würde das Paket bewirken und wo müsste das auftauchen?

      Grüsse

      Philipp
    • Es taucht nirgendwo in den Menus auf und du kannst auch nichts konfigurieren (hab ja gesagt, es ist ein Skelett). Aber es wird aufgerufen, wenn die Box in den Standby geht oder du die Box einschaltest. Das siehst du, wenn du das Debugging im VTi->Einstellungen System->letzter Bildschirm aktivierst.

      Du musst das Plugin noch nach deinen Anforderungen ergänzen, z.B. indem du ein Script aufrufst. Kann z.B. so aussehen:


      Quellcode

      1. # ganz oben gehört folgendes hin:
      2. import os
      3. import subprocess
      4. # ersetzen:
      5. def standbyCounterChanged(configElement):
      6. print "[OnStandy] going to standby..."
      7. from Screens.Standby import inStandby
      8. inStandby.onClose.append(leaveStandby)
      9. cmd = "/usr/lib/enigma2/python/Plugins/Extensions/OnStandby/onstandby.sh"
      10. if os.path.isfile(cmd) and os.access(cmd, os.X_OK):
      11. pid = subprocess.Popen([ cmd ]).pid
      12. # dann muss das Script "onstandby.sh" noch angelegt werden
      Alles anzeigen
      Das Plugin selber wurde nach /usr/lib/enigma2/python/Plugins/Extensions/OnStandby/ installiert; bei Python musst du tunlichst auf die richtige Einrückung achten.
      Diskutiere nie mit einem Idioten. Er zieht dich auf sein Niveau runter und schlägt dich mit seiner Erfahrung.
    • Hallo rdamas,

      Danke für die Anschubhilfe. Habe nun mit deinen Infos und dem von hajeku123 geposteten Link mal versucht das entsprechend anzupassen. Habe das Script vom Linke genommen da es sowohl ein shell script startet wenn die VU aus dem Standby kommt und ein anderes wenn es in Standdby geht.
      Habe fürs Debugging sowohl Konsole wie Datei eingestellt und er meldet nach dem Booten auch dass die Protokollierung eingeschalten sei.

      Ich habe bisher aber auf der Konsole keine Messages erhalten wenn ich die VU in den Standby schicke und wieder hole. Sieht im Moment noch so aus als ob das plugin.py nicht aufgerufen würde.

      Was habe ich gemacht:
      - Folder /media/hdd/standby auf der HD angelegt
      - Die Shell Scripte vuplus_on.sh und vuplus_off.sh in diesen Folder kopiert
      - die beiden scripte aus diesem Folder heraus aufgerufen. Beide funktionieren und setzen den Dummy auf meinem
      FHEM abwechselnd on oder off.

      - Dann das Script aus dem Link kopiert, mit Ultraedit ne neue Datei "plugin.py" angelegt auf dem PC
      und wie untenstehend angepasst:

      Quellcode

      1. # -*- coding: utf-8 -*-
      2. import os
      3. import subprocess
      4. from Components.config import config
      5. from Plugins.Plugin import PluginDescriptor
      6. def leaveStandby():
      7. print "[Info-StandbyPlugin] leaving standby..."
      8. import os
      9. ShellCommand = /media/hdd/standby/vuplus_off.sh"
      10. os.system(ShellCommand)
      11. def standbyCounterChanged(configElement):
      12. print "[Info-StandbyPlugin] going to standby..."
      13. import os
      14. ShellCommand = "/media/hdd/standby/vuplus_on.sh"
      15. os.system(ShellCommand)
      16. from Screens.Standby import inStandby
      17. inStandby.onClose.append(leaveStandby)
      18. def autostart(reason, **kwargs):
      19. if kwargs.has_key("session") and reason == 0:
      20. print "[Info-StandbyPlugin] start...."
      21. config.misc.standbyCounter.addNotifier(standbyCounterChanged, initial_call = False)
      22. def Plugins(**kwargs):
      23. return PluginDescriptor(
      24. name="Info-StandbyPlugin",
      25. description="OnOff Plugin",
      26. where = [PluginDescriptor.WHERE_SESSIONSTART, PluginDescriptor.WHERE_AUTOSTART],
      27. fnc=autostart)
      Alles anzeigen
      habe dann dieses Script mit dem Namen plugin.py unter /usr/lib/enigma2/python/Plugins/SystemPlugins/Standby/
      kopiert und die VU gebooted. In diesem Ordner wird aktuell noch kein Plugin.pyo angelegt

      Vermute mal dass da noch was fehlt damit das plugin.py aufgerufen wird.

      In welche Datei wird das Debugging geschrieben?

      Hättest du noch nen Tipp wie das Problem weiter eingrenzen kann?

      Grüsse Philipp

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von happy3127 ()

    • Wenn du das so kopiert hast, fehlt in Zeile 9 ein Anführungszeichen.
      Übrigens reicht einmal "import os" am Anfang.

      Wegen Debugging: stell Debug-Ausgabe auf "Loggen in Datei" und Debug-Typ auf "e2-python", dann wird alles, was mit dem Plugin über "print" ausgegeben wird, in einer Datei "dvbapp_debug_*" unter /media/hdd geschrieben.
      Diskutiere nie mit einem Idioten. Er zieht dich auf sein Niveau runter und schlägt dich mit seiner Erfahrung.

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von rdamas ()

    • Hallo rdamas,

      Untenstehend der Debug:

      Quellcode

      1. 21:14:09.545 [e2-python] screen cleanup!
      2. 21:14:09.568 [e2-python] screen cleanup!
      3. 21:14:09.651 [e2-python] screen cleanup!
      4. 21:14:09.670 [e2-python] screen cleanup!
      5. 21:14:09.714 [e2-python] screen cleanup!
      6. 21:14:11.649 [e2-python] action -> MenuActions menu
      7. 21:14:24.498 [e2-python] action -> GlobalActions power_down
      8. 21:14:25.459 [e2-python] action -> GlobalActions power_long
      9. 21:14:25.459 [e2-python] Show shutdown Menu
      10. 21:14:25.461 [e2-python] SleepTimerEdit SleepTimerEdit
      11. 21:14:25.462 [e2-python] TimerEdit EnergyTimerEditList
      12. 21:14:25.462 [e2-python] Standby Standby
      13. 21:14:25.462 [e2-python] Standby TryQuitMainloop
      14. 21:14:25.462 [e2-python] Standby TryQuitMainloop
      15. 21:14:25.463 [e2-python] TaskList TaskListScreen
      16. 21:14:25.463 [e2-python] Standby TryQuitMainloop
      17. 21:14:25.471 [e2-python] warning, skin is missing element blue in <class 'Screens.Menu.MainMenu'>
      18. 21:14:25.472 [e2-python] warning, skin is missing element green in <class 'Screens.Menu.MainMenu'>
      19. 21:14:25.472 [e2-python] warning, skin is missing element yellow in <class 'Screens.Menu.MainMenu'>
      20. 21:14:26.545 [e2-python] action -> GlobalActions power_up
      21. 21:14:28.043 [e2-python] action -> WizardActions down
      22. 21:14:28.357 [e2-python] action -> WizardActions down
      23. 21:14:28.642 [e2-python] action -> WizardActions down
      24. 21:14:29.184 [e2-python] action -> WizardActions ok
      25. 21:14:29.184 [e2-python] unknown action WizardActions/ok! typo in keymap?
      26. 21:14:29.184 [e2-python] action -> OkCancelActions ok
      27. 21:14:29.187 [e2-python] Looking for embedded skin
      28. 21:14:29.203 [e2-python] connectionLost? [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionLost'>: Connection to the other side was lost in a non-clean fashion: Connection lost.
      29. ]21:14:29.203 [e2-python]
      30. 21:14:29.208 [e2-python] [93m[SerienRecorder] Deep-Standby WakeUp: AUS[0m
      31. 21:14:29.208 [e2-python] stopService
      32. 21:14:30.509 [e2-python] [BT] current status : 0
      33. 21:14:30.612 [e2-python] [EPGRefresh] Stopping Timer
      34. 21:14:30.613 [e2-python] [MultiQuickButton] checking keymap.xml...
      Alles anzeigen

      Das Plugin scheint zwar aufgerufen zu werden, aber es scheint noch was faul zu sein.
      Da bin ich mit meinem Python Latein am Ende. Müsste da noch ne Exit Condition rein irgendwo?

      Gruss Philipp

      Nachtrag zu obiger Antwort

      Liegt es allenfalls gar am sh script? (folgend das vuplus_on.sh script)

      Shell-Script

      1. #!/bin/sh
      2. echo "set dm_VUPlusStatus on" | nc Heimnetz-IP Port
      3. exit 0

      Grüsse Philipp

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von NaseDC () aus folgendem Grund: Auf Wunsch des Users angepasst

    • Ich kann im Debug-Log von dir keine Ausgaben vom Plugin sehen? Da sollte irgendwo schon mal "Info-StandbyPlugin" stehen.
      Hast du mal versucht, die Box neu zu starten? Das Plugin von oben sieht eigentlich ok aus (bis auf das fehlende Anführungszeichen halt).

      Das Shell-Script funktioniert ja, wie du sagst!? Daran wird es eher nicht liegen.
      Diskutiere nie mit einem Idioten. Er zieht dich auf sein Niveau runter und schlägt dich mit seiner Erfahrung.

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von rdamas ()

    • Hoi rdamas,

      Danke für den Feedback.

      Habe die Box mehrfach gebooted gehabt. Das Anführungszeichen hatte ich bereits vor dem erstellen der Debugs angepasst gehabt. Zum Zeitpunkt der Debugs war das Anführungszeichen also schon drin. Das sollte also nicht mehr das Problem sein.

      Aktuell werden keine Debugs mehr erstellt. Werde Morgen dann wieder mal alles rausräumen und von Vorne beginnen.

      Grüsse Philipp

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von happy3127 ()

    • happy3127 schrieb:

      habe dann dieses Script mit dem Namen plugin.py unter /usr/lib/enigma2/python/Plugins/SystemPlugins/Standby/
      kopiert und die VU gebooted. In diesem Ordner wird aktuell noch kein Plugin.pyo angelegt

      Vermute mal dass da noch was fehlt damit das plugin.py aufgerufen wird.
      in dem Ordner steht eine leere Datei __init__.py ?
      Warum nicht unter Extensions statt SystemPlugin?
      Rechtschreibfehler sind beabsichtigt, sie fördern ein genaueres Lesen
      Debug Log aktivieren Putty Telnet Screenshots erstellen
    • Hallo zusammen,

      Inzwischen habe ich es zum laufen gekriegt

      hajeku123 schrieb:

      Warum nicht unter Extensions statt SystemPlugin?
      Schlichte Unkenntnisse der Materie. Habe es jetzt nach Extensions verschoben.

      Was habe ich noch gemacht das es letztlich dann funktioniert hat.
      - mein "plugin.py" im Folder Standby war mit 755-Rechten angelegt. Keine Ahnung ob das letztendlich
      Teil des Problems war. Habe die Rechte dann so geändert wie bei allen anderen Scripts auch.

      - Beim durchlesen des oben referenzierten Threads hatte ich noch gemerkt das ich noch ne
      Datei __init__.py anlegen sollte mit dem Text "# -*- coding: utf-8 -*-"
      (siehe auch Message oben von hajeku123)


      - Im python Debug wurde nach einem Boot Vorgang noch von blacklisted blocks auf der HD
      gemeckert. Daher habe ich dann die Scripts nach /usr/script/ gemoved um allfälligen Zugriffsprobleme
      auszuweichen und die Pfade im plugin.py entsprechend angepasst.

      Seither läufts. Nehme mal an die fehlende Datei __init__.py war das ursächliche Problem.

      Herzlichen Dank an euch Beide. Ohne eure Unterstützung hätt ichs nicht hingekriegt.

      Grüsse Philipp
    • Vielen Dank für die Vorlage.
      So funktioniert es bei mir:

      Neuer Ordner "Standby" unter "/usr/lib/enigma2/python/Plugins/Extensions/"

      Hier vier Dateien anlegen:

      Python-Quellcode: __init__.py

      1. # -*- coding: utf-8 -*-




      Python-Quellcode: plugin.py

      1. # -*- coding: utf-8 -*-
      2. import os
      3. import subprocess
      4. from Components.config import config
      5. from Plugins.Plugin import PluginDescriptor
      6. def leaveStandby():
      7. print "[Info-StandbyPlugin] leaving standby..."
      8. ShellCommand = "/usr/lib/enigma2/python/Plugins/Extensions/Standby/enigma_leave_standby.sh"
      9. os.system(ShellCommand)
      10. def standbyCounterChanged(configElement):
      11. print "[Info-StandbyPlugin] going to standby..."
      12. ShellCommand = "/usr/lib/enigma2/python/Plugins/Extensions/Standby/enigma_enter_standby.sh"
      13. os.system(ShellCommand)
      14. from Screens.Standby import inStandby
      15. inStandby.onClose.append(leaveStandby)
      16. def autostart(reason, **kwargs):
      17. if kwargs.has_key("session") and reason == 0:
      18. print "[Info-StandbyPlugin] start...."
      19. config.misc.standbyCounter.addNotifier(standbyCounterChanged, initial_call = False)
      20. def Plugins(**kwargs):
      21. return PluginDescriptor(
      22. name="Info-StandbyPlugin",
      23. description="OnOff Plugin",
      24. where = [PluginDescriptor.WHERE_SESSIONSTART, PluginDescriptor.WHERE_AUTOSTART],
      25. fnc=autostart)
      Alles anzeigen


      Zusätzlich die Scripts die Ausgeführt werden sollen (Bei mir ein Api Call mit CURL)


      Shell-Script: enigma_enter_standby.sh

      1. #!/bin/sh
      2. curl --silent -X PATCH --header "Content-Type:application/json" --data '{"type": "value", "valueOrExpression": "Aus"}' --user "username:password" http://192.168.0.11/api/variables/vusolostatus



      Shell-Script: enigma_leave_standby.sh

      1. #!/bin/sh
      2. curl --silent -X PATCH --header "Content-Type:application/json" --data '{"type": "value", "valueOrExpression": "Ein"}' --user "username:password" http://192.168.0.11/api/variables/vusolostatus



      Alle Dateien dann Ausführbar machen

      chmod +x /usr/lib/enigma2/python/Plugins/Extensions/Standby/*

      Anschließend Box neu booten. Im Verzeichnis sollten nun eine plugin.pyo und __init__.pyo vorhanden sein
    • Guten Morgen zusammen.

      Ich möchte den Thread hier gerne wieder ausgraben, weil ich in etwa das selbe realisieren möchte wie der TE.
      Bei mir funktioniert aber leider auch etwas nicht richtig.

      Um was es geht:

      Ich habe an meinem TV Ambilight mittels Raspberry nachgerüstet und möchte jetzt gern jedesmal wenn die Vu in Standby geht und aus dem Standby kommt den entsprechenden Befehl an den Pi schicken, damit dieser Ambilight an- und aus schaltet.
      Im Log funktioniert das Script von rdamas auch, sprich es gibt das Echo beim ein- und ausschalten aus

      Nur funktioniert der execute von dem Script anscheinend nicht richtig.
      Wenn ich in der Befehlszeile der Vu das Script manuell aktiviere funktioniert alles. Realisiert wird das ganze über ssh. Passwortlosen ssh login über keys ist bereits eingerichtet und funktioniert auch.
      Die Scripts auf dem Pi haben 755er Rechte und sind im Home Verzeichnis.

      Ich schicke euch mal die python.py und das .sh Script (Es sind eigentlich logischerweise 2 aber die unterscheiden sich nur im Befehl ). Wäre super falls jemand mal drüber schauen könnte.

      Achso, ich sollte noch erwähnen, dass ich nur sehr rudimentäre Kenntnisse von Python habe.

      Spoiler anzeigen

      Quellcode

      1. # -*- coding: utf-8 -*-
      2. from Components.config import config
      3. from Plugins.Plugin import PluginDescriptor
      4. import os
      5. import subprocess
      6. def leaveStandby():
      7. print "[OnStandy] leaving standby..."
      8. os.system("/usr/script/ambilighton.sh &")
      9. def standbyCounterChanged(configElement):
      10. print "[OnStandy] going to standby..."
      11. from Screens.Standby import inStandby
      12. inStandby.onClose.append(leaveStandby)
      13. os.system("/usr/script/ambilightoff.sh &")
      14. def autostart(reason, **kwargs):
      15. if kwargs.has_key("session") and reason == 0:
      16. print "[OnStandy] start...."
      17. config.misc.standbyCounter.addNotifier(standbyCounterChanged, initial_call = False)
      18. def Plugins(**kwargs):
      19. return PluginDescriptor(
      20. name="OnStandy",
      21. description="Aktion bei Betreten und Verlassen des Standby",
      22. where = [PluginDescriptor.WHERE_SESSIONSTART, PluginDescriptor.WHERE_AUTOSTART],
      23. fnc=autostart)
      Alles anzeigen


      Spoiler anzeigen


      Shell-Script

      1. #!/bin/sh
      2. ssh -i /home/root/.ssh/mykey -y root@192.168.2.140 './ambilightoff.sh'
      3. exit 0


      Danke im voraus.
    • Prinzipiell sollte es das auch mit "&" machen.

      Da wirst du nicht drum rum kommen, Debug-Ausgaben in die Scripten einzubauen. Vielleicht am einfachsten:

      - als Interpreter /bin/bash benutzen und nicht /bin/sh
      - im Script Debugging Ausgabe erzeugen (weit oben eintragen)

      Quellcode

      1. set -x
      2. exec 2>/tmp/script.log

      Ausgabe findest du dann in /tmp/script.log. Damit weisst du dann schon mal, ob das Script aufgerufen wird und was es macht.

      Ich benutze im OnStandy.py inzwischen subprocess.Popen um das Script zu starten, sollte aber keinen Unterschied machen.
      Diskutiere nie mit einem Idioten. Er zieht dich auf sein Niveau runter und schlägt dich mit seiner Erfahrung.

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von rdamas ()

    • Danke, ich werde es mal probieren.

      Ich überlege gerade, werden im Telnet und in Python unterschiedliche Benutzer verwendet um Dinge auszuführen? Ich sehe nämlich gerade, dass meine keyfile zur ssh Authentifizierung nur Rechte 600 hat, brauch ich da vielleicht andere Rechte? Also das Python quasi mit nem anderen Benutzer versucht die keyfile zu benutzen und scheitert?
      Wie gesagt nur ne Idee, ich kenn mich damit zu wenig aus

      Edit:

      wenn ich, wie von dir vorgeschlagen, den Quellcode zu meinem Script hinzufüge bekomm ich keine script.log in /tmp.. anscheinend wird das Script garnicht erst aufgerufen

      Da ich nicht mehr editieren kann:

      Wenn ich

      os.system()

      mit

      subprocess.Popen()

      tausche hängt sich Enigma2 auf

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Minority2k ()