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 37.7k 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 @BuZz
      last edited by

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

      @meleu It's an issue with 3rd party reboot scripts?

      Not only 3rd party reboot scripts, but any shutdown method different than ES quit menu (example: "Perform reboot" on retropie_setup while ES is running, or shutdown -h now or reboot via SSH).

      Looking briefly at op, I don't see why this is needed in RetroPie

      Before the "Favorites/Last Played" feature was implemented, the "save metadata on exit" wasn't so important. But now it is. It can be really frustrating to lose your favorites after spending some time curating the list...

      RetroPie doesn't actually need this, but it would avoid several topics here in the forum with people asking for help on how to not lose Favorites/Last played data when shutting down the pi with power buttons like Mausberry, Powerblock, etc.

      (it's not a RetroPie problem)

      Well, I have no intention to label it as a "RetroPie problem", but here is a 100% clean RetroPie use case (no custom configs/hacks involved):

      1. Boot you raspi.
      2. In ES add some games to Favorites.
      3. Launch and exit some games (just to add some entries in the Last Played).
      4. Launch retropie_setup via RetroPie Menu in ES.
      5. Perform a reboot via retropie_setup.
      6. After rebooting check that your Favorites/Last Played wasn't saved.

      IMHO adding that trick as an option in emulationstation.sh script module has more pros than cons.

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

        @meleu Well my advice would be to not reboot from retropie-setup and use ES. Maybe I should add a warning about rebooting when launched from ES. 3rd party reboot scripts can easily kill and wait for ES first. I'm not keen to invade the init system with ES to handle reboot scenarios outside of ES.

        To help us help you - please make sure you read the sticky topics before posting - https://retropie.org.uk/forum/topic/3/read-this-first

        meleuM cyperghostC 2 Replies Last reply Reply Quote 0
        • meleuM
          meleu @BuZz
          last edited by

          @buzz OK, I got it. Let's leave this as a tinker trick. I'm going to add this topic to the "Useful topics" post.

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

            @buzz Well you can add a file "es-sysrestart" to folder tmp and send SIGTERM to EmulationStation-binary PID only - then this script provided with ES will takeover the shutdown sequence. If no active ES-PID is available the usual system shutdown can be performed.

            Of course a warning hint within RetroPie-setup is also considerable and needs no maintainment - just a bit of user brain :)

            BuZzB 1 Reply Last reply Reply Quote 0
            • BuZzB
              BuZz administrators @cyperghost
              last edited by

              @cyperghost Thanks. I am aware of that btw, I wrote that script :-)

              To help us help you - please make sure you read the sticky topics before posting - https://retropie.org.uk/forum/topic/3/read-this-first

              1 Reply Last reply Reply Quote 0
              • AphexA
                Aphex
                last edited by Aphex

                Being a owner of a NESPi Case (and Pi 3 model B), can i follow OP's guide as it is right now? or is there something else i should do/know about to make it work?
                I've been trying to follow the whole thing but as a lesser-experienced linux user i still feel sorry to ask :s
                EDIT: So sorry, i meant a NESPi Case, not RasPi

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

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

                  Being a owner of a RasPi Case (and Pi 3 model B), can i follow OP's guide as it is right now?

                  Yes. Let me know if you face some problem.

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

                    @meleu After trying the guide with my NesPi case, i get the same initial result that @yahmez got. It's not saving changes and i also get the LED remains faintly lit (though i don't mind if it's fully off after 5 minutes).

                    @yahmez Have you performed extra modifications or anything to make it work? You posted this link ( https://pastebin.com/25GKw9xv ) but i am unsure of what to make of it.

                    YahmezY 1 Reply Last reply Reply Quote 0
                    • YahmezY
                      Yahmez @Aphex
                      last edited by Yahmez

                      @aphex The only thing I did was make the killes.service script executable. The code you linked is the shutdown script I am using. Although I am assuming you made the modifications to the NESPi as outlined in my PDF...

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

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

                        The only thing I did was make the killes.service script executable

                        The script is killes.sh, and, yes, it must be executable. There's nothing wrong with the .service file. ;-)

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

                          @meleu
                          Ha, sorry. My error.

                          1 Reply Last reply Reply Quote 0
                          • cyperghostC
                            cyperghost
                            last edited by cyperghost

                            @meleu As I mentioned in my latest script!
                            To trigger ES events we can use incron job.

                            you can set it up as I done in my github script and maybe you can add a new user (afaik you are not using user PI on your system)

                            Then there can be two ways! To locate in which status ES shutdown now we have to use a kind of logger as incron just writes events to syslog....

                            So just write echo $# in incronjob results in an entry of syslog...

                            So we would write this to icrontab... maybe sudo?? sudo /etc/log.sh $#

                            /tmp IN_CREATE /etc/log.sh $#
                            

                            log.shwill contain the redirection from incron

                            #!/bin/bash
                            # incron-logger to determine EmulationStation-quit-status
                                esstatus=("es-restart" "es-sysrestart" "es-shutdown")
                            
                                for status in "${esstatus[@]}"; do
                                           [[ "$status" == "$1" ]] && echo "$1" > /etc/esstatus.log
                                done
                            

                            Important! That needs a bit of fine tuning! Because every file written will be logged! Unix uses tons of temporary files ;)
                            FIXED!


                            EDIT:

                            /tmp IN_CREATE cp $@$# /dev/shm/
                            

                            would be much nicer ... then presence of ES status files have just to be tested ;) As these files are zero files, there is no chance to break copy process. And /dev/shm is "self cleaning" after shutdown ;)


                            Then we need to modify @meleu s script to determine the generated logfile and with this we can generate action based on ES-quit-status ;)

                            The solution I presnted yesterday lacks of speed, it works on a Raspberry 3 but maybe if the RPi 4 is available the shutdown is performed so fast my script will just terminated without action!

                            So I think systemd gots a more bright future.

                            @meleu
                            It's your turn now ;)
                            I hope that this gives you encourage to modify your script. Me and lot's of users will appreciate this. As I did not care about user rights managment, there maybe must be made sudo calls from time to time.

                            The king way would be to integrate the logger into the killes.sh and I vote for a rename of your script.... it sounds so destructive ;)

                            1 Reply Last reply Reply Quote 1
                            • 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
                                            • 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.