RetroPie forum home
    • Recent
    • Tags
    • Popular
    • Home
    • Docs
    • Register
    • Login
    Please do not post a support request without first reading and following the advice in https://retropie.org.uk/forum/topic/3/read-this-first

    ensuring ES gracefully finish and save metadata in every system shutdown

    Scheduled Pinned Locked Moved Help and Support
    shutdown scriptemulationstatiofavoriteslast playedmetadata issues
    96 Posts 26 Posters 39.8k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • meleuM
      meleu
      last edited by

      Hey bro. I appreciate your effort and I'm sure you're enjoying to learn all this stuff while working on your solution. Sadly I'm currently I'm away from my pi to test this stuff.

      But let's just try to put very clear what problem we are trying to solve. As far as I understood we want to detect if the system is going to actually poweroff or just reboot. Is it right?

      • Useful topics
      • joystick-selection tool
      • rpie-art tool
      • achievements I made
      cyperghostC 1 Reply Last reply Reply Quote 1
      • cyperghostC
        cyperghost @meleu
        last edited by cyperghost

        @meleu Yes...
        Then we can set a trigger to this transistor GPIO

        But what happens then? Will be a "second" shutdown performed? Because the triggered transistor will act as button press and call the regular shutdown script. Therefore I made a difference between software and hardware based actions ;) What's your opinion about?

        What happens if you press shutdown button in ES? Then also a es-shutdown will be generated and the killes script will be triggered ;)

        So you see it's a challenging game ;) And you see why the script from yesterday is so endless long. So yes, we need a to differ between shutdown and reboot and what initiated it? software or hardware.

        The easiest solution seems to just to edit the emulationstation.sh and set the calls here but that's far away from generic solution.

        But as final note:

        Personally it's not my responsibility to offer scripts here and 
        to satisfy someones setup. It's an encouragement to learn something 
        new and to share this knowledge for free as volunteer.
        
        Furthermore:
        I see this as interaction between enthusiasts to make a great development even
        better.
        
        caver01C 1 Reply Last reply Reply Quote 0
        • caver01C
          caver01 @cyperghost
          last edited by

          @cyperghost @meleu You guys are amazing! I really appreciate the work you put into this.

          You guys have already vastly improved the button-triggered shutdown by re-writing the script to ensureES saves metadata. That alone is a very nice improvement. However, there has always been an unrelated problem with the Mausberry circuit: it simply ignores software shutdowns/reboots. In order for it to cut power it requires a physical button press. The fact that it ignores a reboot is fine--might even be designed that way. But software shutdown puts the circuit into a locked state and does not cut power.

          For me, the goal was to fix a locking Mausberry circuit on soft shutdown. @meleu's service idea not only simplified the Mausberry script allowing us to revert back to the original version, but it also fixed the ES metadata problem for EVERY CIRCUIT OR SHUTDOWN SOLUTION. I love this because it takes the solution public, so to speak. It works no matter how you are triggering your shutdown.

          Of course, it also gave me a place to insert something specific--a GPIO call to trigger my transistor. Doing so, now eliminates the Mausberry lockup problem. It does it at the expense of rebooting (make all reboots lead to poweroff), but this is a good compromise in my opinion.

          If I could wrap that call inside a conditional to some system-level indicator to detect a shutdown (and ignore a reboot) my transistor trigger would be perfect.

          @cyperghost's idea goes a long way toward detecting reboots from ES, but what about a reboot from the RetroPie config menus? What about SSH and a sudo reboot issued from commandline?

          I love the ideas here. This puzzle has been a real challenge to enjoy! Thanks for all of the input.

          My 4-player cocktail style cabinet built as a custom "roadcase"

          cyperghostC 1 Reply Last reply Reply Quote 2
          • cyperghostC
            cyperghost @caver01
            last edited by cyperghost

            OUTDATED: Take a look to this code piece

            @caver01

            but what about a reboot from the RetroPie config menus? What about SSH and a sudo reboot issued from commandline?

            That's the issue I was working on. As long as you set a GPIO command in the killes.sh script as long it is triggered on every reboot and shutdown. A reboot is important... Just to test scripts and to test interaction.

            So my bad workaround I would suggest is. Edit the /opt/retropie/supplementary/emulationstation/emulationstation.shand add something like

            rm -f /tmp/es-shutdown && touch /dev/shm/es-shutdown
            

            and then in killes.sh

            [[ -f /dev/shm/es-shutdown ]] && trigger GPIO
            

            That's the easiest way without installing additional services, but will work only for ES or you need to remember to add file es-sysrestart to location that needs to be detected and then perform a reboot.

            Of course, it also gave me a place to insert something specific--a GPIO call to trigger my transistor. Doing so, now eliminates the Mausberry lockup problem. It does it at the expense of rebooting (make all reboots lead to poweroff), but this is a good compromise in my opinion.

            Yes this solution is so far the best one - indeed!

            If I could wrap that call inside a conditional to some system-level indicator to detect a shutdown (and ignore a reboot) my transistor trigger would be perfect.

            That's my hope... Afaik reboot and poweroff use different runlevels to terminate programs. If there is a chance to detect runlevel for poweroff (0) or to detect runlevel for reboot (6) then there is a generel solution available.

            1 Reply Last reply Reply Quote 0
            • meleuM
              meleu
              last edited by

              The runcommand.sh script changed a bit 3 days ago and users that are uptodate maybe are facing those issues with metadata not being saved when powering off while there's an emulator running.

              I'm already taking a look at it. Wait a little. ;-)

              • Useful topics
              • joystick-selection tool
              • rpie-art tool
              • achievements I made
              1 Reply Last reply Reply Quote 1
              • meleuM
                meleu
                last edited by

                UPDATE

                I've updated the killes.sh script in the OP. The issue I talked about in the post above seems to be fixed.

                Let me know if you guys find some problem.

                Cheers!

                • Useful topics
                • joystick-selection tool
                • rpie-art tool
                • achievements I made
                S 1 Reply Last reply Reply Quote 0
                • S
                  snarc @meleu
                  last edited by snarc

                  @meleu

                  Thanks for your awesome shutdown script. It works fantastic! :D

                  I only have 2 minor suggestions for improvement:

                  #1 I think it would be better if you add a "sudo" to "chmod a+x /etc/killes.sh" because some people will encouter a "permission denied error" without the sudo command.

                  #2 In the commented code in your 2nd post is a tiny error: "ExecStop=/home/pi/bin/killes.sh" hast to be replaced by "ExecStop=/etc/killes.sh" ;)

                  Regards!

                  1 Reply Last reply Reply Quote 0
                  • M
                    Mafu
                    last edited by Mafu

                    I'm using a Nespi Case with a mosfet switch mod and this works excellent for shutting down the system or using the reset button to do a full reset of the system. Currently however I am trying to get the reset button to just go back to the emulation station from a game but it is not saving the data. Is there any way to cannablize part of your method to save the game data and patch it into the code the maker of the mod I'm using provided? My current solution is to have retroarch save the game every few seconds which can't be very healthy for my sd card.

                    Sorry if the answer is obvious, I am a complete noob at python. (code below)

                    #!/usr/bin/python
                    import RPi.GPIO as GPIO
                    import os, time

                    GPIO.setmode(GPIO.BCM)
                    GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP) #Reset switch
                    GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_UP) #Power switch
                    GPIO.setup(25, GPIO.OUT) #ON control
                    GPIO.output(25, GPIO.HIGH)

                    def exitEmulator(channel):
                    print('exitEmulator')
                    pids = [pid for pid in os.listdir('/proc') if pid.isdigit()]

                    for pid in pids:
                        try:
                            commandpath = open(os.path.join('/proc', pid, 'cmdline'), 'rb').read()
                            if commandpath[0:24] == '/opt/retropie/emulators/':
                                os.system('kill -QUIT %s' % pid)
                                print('kill -QUIT %s' % pid)
                        except IOError:
                            continue
                    

                    GPIO.add_event_detect(23, GPIO.FALLING, callback=exitEmulator, bouncetime=500)

                    while True:
                    if (GPIO.input(24)):
                    time.sleep(0.25)
                    else:
                    print ("Shutting down...")
                    os.system("sudo shutdown -h now")
                    break

                    1 Reply Last reply Reply Quote 0
                    • SanoS
                      Sano
                      last edited by Sano

                      I would suggest to use Network Control Interface to take a savestate and properly quit Retroarch.
                      See here : https://buildbot.libretro.com/.docs/tech/network-control-interface/
                      Edit : yes I'm fond of this feature since I discovered it :)

                      1 Reply Last reply Reply Quote 0
                      • M
                        Mafu
                        last edited by

                        The reset button I have on my case is currently being controlled by the script I posted. How would I integrate the Network Control Interface with it?

                        caver01C 1 Reply Last reply Reply Quote 0
                        • caver01C
                          caver01 @Mafu
                          last edited by

                          @mafu it looks like, you would need to enable the option in retroarch.cfg, then insert a command such as echo -n "SAVE_STATE" | nc -u -w1 127.0.0.1 55355 before your kill command which would tell retroarch to save the game. Of course, this is limited to retroarch emulators only. If you were, for example, running AdvanceMAME, it would probably generate an error.

                          My 4-player cocktail style cabinet built as a custom "roadcase"

                          1 Reply Last reply Reply Quote 1
                          • M
                            Mafu
                            last edited by

                            I think we're talking past one another, I can't find any information on echo in python. I gave it a shot and put it in the script anyway but it just crashed the console instead of safe shutdown of the power button and did nothing when using the reset.

                            caver01C 1 Reply Last reply Reply Quote 0
                            • caver01C
                              caver01 @Mafu
                              last edited by

                              @mafu Sorry, I am not a python expert either, but what about borrowing the example from the script's working shutdown command and doing this:
                              os.system("echo -n "SAVE_STATE" | nc -u -w1 127.0.0.1 55355")

                              My 4-player cocktail style cabinet built as a custom "roadcase"

                              1 Reply Last reply Reply Quote 0
                              • M
                                Mafu
                                last edited by Mafu

                                That was an excellent idea carver01 (I facepalmed a little when I saw it for not thinking of it myself). It works partially but only on save states, not ingame save data (games that have their own dedicated save feature).

                                Whats frustrating is when using the OP's solution and just shutting the system down with the power button it will

                                1. Exit the game.
                                2. pause at the game selection screen (I assume this is where the "sleep 5" comes into play).
                                3. And then shut down.

                                What I need is a way to get it to stop at step 2 and still save the game's data(save files, save states, etc) when pressing the reset button. As it is now it goes back to the game selection screen but does not save any data.

                                SanoS caver01C 2 Replies Last reply Reply Quote 0
                                • Z
                                  zobilla
                                  last edited by

                                  Hey guys

                                  Anyone having problems with systemd refusing to load with no ExecStart line in the service?

                                  --
                                  pi@retropie:~ $ dmesg | grep killes
                                  [ 2.660196] systemd[1]: killes.service lacks ExecStart setting. Refusing.
                                  [ 2.679020] systemd[1]: Cannot add dependency job for unit killes.service, ignoring: Unit killes.service failed to load: Invalid argument. See system logs and 'systemctl status killes.service' for details.

                                  I pulled the logs from systemctl status killes.service but it just says invalid args.

                                  meleuM 1 Reply Last reply Reply Quote 0
                                  • SanoS
                                    Sano @Mafu
                                    last edited by Sano

                                    @mafu Could you precise what you mean by "save the game data" ?
                                    Is it that .srm files are not correctly written to the sd when retroarch is exited with the script ?

                                    It seems to me very difficult to script game saves beyond the savestates as explained above, because each game is quite specific about it's own saves (different menu, number of save slots, use of savepoints...)

                                    1 Reply Last reply Reply Quote 0
                                    • caver01C
                                      caver01 @Mafu
                                      last edited by

                                      @mafu said in ensuring ES gracefully finish and save metadata in every system shutdown:

                                      That was an excellent idea carver01

                                      Glad I can help, marfu.

                                      If your script is still shutting down, why not remove the line from the script that does the shutdown? Seems easy enough.

                                      My 4-player cocktail style cabinet built as a custom "roadcase"

                                      1 Reply Last reply Reply Quote 0
                                      • T
                                        TazgodX
                                        last edited by

                                        I am having the same issue as Zobilla

                                        dmesg | grep killes
                                        [ 1.936038] systemd[1]: killes.service lacks ExecStart setting. Refusing.
                                        [ 1.962910] systemd[1]: Cannot add dependency job for unit killes.service, ignoring: Unit killes.service failed to load: Invalid argument. See system logs and 'systemctl status killes.service' for details.

                                        systemctl status killes.service
                                        Ă¢ killes.service - Kill EmulationStation
                                        Loaded: error (Reason: Invalid argument)
                                        Active: inactive (dead)

                                        won't run for me.

                                        1 Reply Last reply Reply Quote 0
                                        • meleuM
                                          meleu @zobilla
                                          last edited by

                                          @zobilla @TazgodX could you guys paste here the output of systemd --version?

                                          • Useful topics
                                          • joystick-selection tool
                                          • rpie-art tool
                                          • achievements I made
                                          1 Reply Last reply Reply Quote 0
                                          • T
                                            TazgodX
                                            last edited by

                                            systemd --version
                                            systemd 215
                                            +PAM +AUDIT +SELINUX +IMA +SYSVINIT +LIBCRYPTSETUP +GCRYPT +ACL +XZ -SECCOMP -APPARMOR

                                            1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post

                                            Contributions to the project are always appreciated, so if you would like to support us with a donation you can do so here.

                                            Hosting provided by Mythic-Beasts. See the Hosting Information page for more information.