Putting mythfrontend to sleep

From MythTV Official Wiki
Revision as of 19:39, 24 January 2013 by BigBoote66 (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Clean.png Cleanup: This article or section may require cleanup. Discuss the issue on the talk page

This "How To" article pulls together a number of different aspects of customizing MythTV, to accomplish what would seem to be a simple task: putting your MythTV system to sleep.

Introduction

One very common MythTV configuration is to have one machine running both mythfrontend and mythbackend on a custom-assembled, small, quiet machine sitting with the rest of the A/V equipment. I couldn't afford to buy a new computer for MythTV, but I have a lot of computers sitting around the house, so I set up MythTV on two computers. Mythbackend is running on a fairly powerful and very noisy rack-mount server that hangs out with the other noisemakers in the basement. Mythfrontend is running on a PC that I inherited that used to run Windows in an office.

The Problem

The main reason I didn't run all of MythTV on one machine is that our "TV room" is also our bedroom, and all the hardware I had on hand was unacceptably noisy for trying to sleep. Mythbackend needs stay on all the time (or turn itself on and off as needed, as per this excellent How To article on ACPI Wakeup), but we needed to be able to shut down the machine running mythfrontend in order to get to sleep at night.

I haven't yet bought a fancy IR remote control yet, either, so currently we use a regular keyboard at the end of three USB extension cords. We could shut the computer down just fine by selecting "Exit and Shutdown" from the pop-up menu on the main screen, but once it was off, we'd have to walk over to the tower computer itself to press the "On" button. I decided that what we really needed was a new option on the main MythTV menu: "Sleep." (If I ever get a remote control, I'll revise this article to explain how to use the "Power" button of the remote to sleep/wake the PC instead of having a menu option, I hope!)

I installed MythTV v0.22 on an existing Ubuntu system for the backend server, and installed Mythbuntu v0.22 off a CD from the .iso image for the front end machine, but this article should apply to many other configurations as well, although I'm sure some of the file locations will wander about depending on the version of MythTV and/or Linux that you're running. Also, I use the "MythCenter" theme and "DVR" menu theme, rather than the default "Terra" and "Default."

The Solution

If I could get the machine to just go to sleep, then it ought to be as good as shutting it off for when we were trying to go to sleep ourselves, but we'd be able to start it back up a lot faster than we could with a full boot-from-off sequence, and it should be possible to wake it up just by poking a key on the keyboard instead of having to walk over to the computer itself. If I just quit from mythfrontend on my tower PC, I would get dropped onto the default graphic UI for Mythbuntu, which I believe is Xfce. From here, choosing to log out brought up a fancy window that offered me the choices of logging out, restarting, shutting down, suspending, or hibernating the system. I wasn't even sure what the last two options actually did, although they definitely sounded like what I was looking for.

A bit of research revealed the difference. "Suspend" was what I generally thought of as "sleep," in that the computer would power down most of its systems but would keep a trickle of power to the RAM so that it could wake up and pick up where it left off when nudged. "Hibernate" is almost the same thing, except that the operating state is saved onto the drive. If I understand what I've read, this takes even less power, since the computer doesn't maintain the RAM state, and it means the machine can "wake up" even if the power is interrupted, but it takes longer to shut down and to wake up, since there's disk activity on both state changes. I didn't see any benefit to being able to wake up even after a power failure, and "Hibernate" was notably slower than "Suspend," so that's what I decided to shoot for.

Step One: Waking Up From the Keyboard

Unfortunately, the first problem showed up right away. I could certainly Suspend or Hibernate the system just fine, but once it was asleep, the only way to wake it back up was . . . to press the "Power" button on the case. The ACPI Wakeup article was very useful in giving me the clues I needed, and further research on the ACPI system explained how to tell the system to watch the USB bus for activity, and wake up when it saw some. The key was this command:
 echo "USB0" > /proc/acpi/wakeup

Although "wakeup" appears to be an ordinary file, this command does not simply overwrite the contents with "USB0" as I expected. Instead, it somehow toggles the "disabled" flag in that file to "enabled." My version of the file had both "USB0" and "USB1," and I figured I'd just enable both rather than trying to figure out which one the keyboard was in, and then having to worry about somebody moving the plug to the other bus and disabling the keyboard wakeup ability.

Alas, it's more complicated than that, since the flags switch back to "disabled" whenever the system reboots . . . or wakes from sleep. So a script that re-enables them every time the machine wakes up is required. This means getting involved with the "init.d" system. First, a script is needed to enable waking from USB activity.

Script.png wake.sh
#!/bin/bash

echo "USB0" > /proc/acpi/wakeup
echo "USB1" > /proc/acpi/wakeup
I think I could have stuck with the traditional "#!/bin/sh" at the top if I'd used "/bin/echo" instead of just "echo," but this worked, so I haven't bothered changing it. Then the script needs to be made executable, and put where the init.d system can find it. Finally, init.d is told to process the new script and do the mysterious things it does to cause the script to be run at the proper times:
chmod +x wake.sh
cp wake.sh /etc/init.d/
sudo update-rc.d wake.sh defaults

Now I could Suspend the system, and wake it back up by poking a key on the keyboard.

Step Two: Falling Asleep From the Command Line

At this point, I still was Suspending the system by selecting an option from the window that popped up in Xfce. In order to make "Sleep" be an option from within Mythfrontend, I needed a way of putting the machine to sleep from the command line. I eventually discovered three or four different ways that might have worked, but while I was digging around in MythTV itself, I accidentally discovered some very interesting-sounding scripts that were already part of MythTV: "myth-reboot.sh," "myth-halt.sh," and "myth-hibernate.sh." Myth-hibernate.sh in particular contained this:


Script.png myth-hibernate.sh
#!/bin/sh
# This script uses dbus to tell HAL to hibernate your computer
dbus-send --system --print-reply --dest=org.freedesktop.Hal /org/freedesktop/Hal/devices/computer org.freedesktop.Hal.Device.SystemPowerManagement.Hibernate

Swapping "Suspend" for "Hibernate" didn't work, although it turns out that it's almost that easy. A bit more digging, and I was ready to create "myth-suspend.sh":


Script.png myth-suspend.sh
#!/bin/sh
# This script uses dbus to tell HAL or UPower to suspend your computer
# Use one of the following lines; the UPower line worked for a Zotac ZBox running MythBuntu 12.04

# dbus-send --system --print-reply --dest="org.freedesktop.UPower" /org/freedesktop/UPower org.freedesktop.UPower.Suspend
dbus-send --system --print-reply --dest=org.freedesktop.Hal /org/freedesktop/Hal/devices/computer org.freedesktop.Hal.Device.SystemPowerManagement..Suspend int32:0

After setting the execute flag on the script and copying it into /usr/share/mythtv, I could put the machine to sleep from the command line. (Note: those scripts seem not to be available or work with 12.04 Mythbuntu --rasos; See my alternate dbus-send command - works with my ZBox in 12.04 --BigBoote66)

Step Three: Putting "Sleep" Into the Menu

I'd already done a fair amount of tinkering with the menus before I started this project, so this step might vary a bit from the default installation. MythTV has some clever, if sometimes confusing, ways of managing themes. In effect, it lays down a complete default user interface, then lays your selected theme changes over the top of that default scheme, then lays any changes you've personally made over the top of that. (Technically, I think it works from front to back, rather than back to front, but the result is the same.) I had already settled on one particular theme (well, one visual theme and one menu theme), so I made copies of both of those in order to make it (a little bit) easier to figure out how to make changes. For this sake of this article, I will proceed as if I had done this work on a stock install.

You'll need to figure out what your current menu theme is. In Mythfrontend, go to "Utilities/Setup" -> "Setup" -> "Appearance". On the first page, you should see "Menu theme: Default" or, in my case, "Menu theme: DVR". When I log into my MythTV front end machine, I start in the home directory for the user named "mrmyth." MythTV creates a ".mythtv" directory in the home folder. In order to install a revised main menu, I created a themes directory inside .mythtv, cloned the theme I wanted to change, then found and edited the specific menus I wanted to change .

cd .mythtv
mkdir -p  themes/defaultmenu
cp -r /usr/share/mythtv/themes/defaultmenu/ themes/defaultmenu/


Important.png Note: The official documentation is, not too surprisingly for open source, lagging behind. Various sources seem to think that you only need to copy the files you're going to actually edit into your .mythtv folder. For example, the Hulu Desktop Integration page says to copy just "mainmenu.xml" into your .mythtv directory, not even to a "themes" folder within it. This will work, in that Mythfrontend will let that mainmenu.xml file override the one inside .mythtv/themes/, which in turn overrides ones stored in /usr/share/mythtv/themes, but when I went to Setup, Appearances, the display malfunctioned rather badly. Creating a themes/defaultmenu directory and 'only' putting the files I wanted to edit also was a near miss: that menu works fine, but Mythfrontend then cannot find any of the unchanged .xml files. In all, I think I found a couple dozen ways to make this not work.

To change the main menu, I edited "mainmenu.xml." I do most of my work by connecting to the MythTV front end from other computers, so if I'm working through "ssh" I'll just use "pico" for editing, as in
pico mainmenu.xml
If it's going to be more work, then I mount the MythTV machine's drive onto my own laptop (which is a Macintosh), and use TextWrangler to do the work. Any way you do it, when you open the file, you'll find the menu structure represented as a bunch of stuff in between "<button>" tags. I decided to put the "Sleep" button at the bottom of the list, so I added this right near the end of the file: {{Code box|mainmenu.xml (insert)|
    <button>
        <type>SLEEP</type>
        <text>Sleep</text>
        <action>EXEC /usr/share/mythtv/myth-suspend.sh</action>
    </button>

Restart Mythfrontend, and Presto! now I could put it to sleep.

Step Four: Avoiding Re-Sleep

Waking it up, however, wasn't entirely problem-free. Sometimes, it would wake up, and then immediately go right back to sleep. I decided that this might be related to the fact that "Sleep" had (obviously) been highlighted when the machine had shut down, so "Sleep" was still highlighted when it woke back up, and if a spurious "Return" or "Enter" slipped through and looked to Mythfrontend like a Select event, then it would activate the option that was highlighted; i.e. "Sleep," and go right back to sleep. I needed a way to reset the highlight bar back to the top of the list.

I'll spare you the extended fight I had with the difference between running a script by hand and having a program (like Mythfrontend) execute it, and just cut to the chases. First, you need to enable the Network Remote Control Interface. That's found in "Utilities/Setup" -> "Setup" -> "General" then skip along to the "Remote Control" page and check off "Enable Network Remote Control Interface." This opens up a means to control Mythfrontend through a socket connection.

Now we need another script.


Script.png sleeper.sh
#!/bin/bash

/bin/echo "key pageup" >/dev/tcp/localhost/6546 
/usr/share/mythtv/myth-suspend.sh

The second line is, of course, the command to put the system to sleep. The first line tells Mythfrontend to act as if I'd pressed the "Page Up" key. This kicks the highlight bar to the first item on the menu.

All that remains is to change 'mainmenu.xml' to point to this script instead of directly at myth-suspend.sh...


Script.png mainmenu.xml (update)
        <button>
		<type>SLEEP</type>
		<text>Sleep</text>
		<action>EXEC ~/.mythtv/sleeper.sh</action>
	</button>


Important.png Note: OK, I lied. I won't entirely spare you the extended fight. Just be aware that the "key pageup" command will not work with /bin/sh. It has to be /bin/bash. As always with me and Linux, it remains a big fat mystery why.

Step Five: Beautification

The last touch was to do something about the icon. As I mentioned at the beginning, I prefer (so far) to use the MythCenter theme. It's got a bright, uncluttered, modern look to it. It seemed a shame to not have an appropriate watermark appear for Sleep like Watch Recordings or System Status had. So I made one.

Sleep.png

Now to get it installed. First, clone the entire MythCenter theme:

cd .mythtv
mkdir -p  themes/MythCenter-wide
cp -r /usr/share/mythtv/themes/MythCenter-wide themes/MythCenter-wide

Then, put Sleep.png in the "watermark" directory inside MythCenter.

cp Sleep.png .mythtv/themes/MythCenter/watermark

And lastly, connect this watermark image with buttons of type SLEEP. Edit the "menu-ui.xml" file, and stick these lines in with the other "<state...>" commands:


Script.png menu-ui.xml (insert)
           <state name="SLEEP" from="DEFAULT">
                <imagetype name="watermark">
                    <filename>watermark/sleep.png</filename>
                </imagetype>
            </state>

The only remaining regret is that adding one more item to the menu causes the menu to scroll. "Sleep" is hidden until you get to it. There's plenty of room remaining on the screen, so I decided to just make the list a smidge bigger. While still in 'menu-ui.xml,' search for buttonlist name="menu". Here's the bulk of that section, with the parts I changed marked in red


Script.png 'menu-ui.xml (update)'
...

 <buttonlist name="menu">
   <area>160,130,700,450</area>
   <layout>vertical</layout>
   <spacing>5</spacing>
   <wrapstyle>selection</wrapstyle>
   <buttonarea>0,0,580,450</buttonarea>
   <statetype name="buttonitem">
       <state name="active">
           <area>0,0,580,60</area>
           <imagetype name="background" />
           <textarea name="buttontext">
               <area>15,7,550,50</area>
               menufont
               <align>left,vcenter</align>
               <cutdown>no</cutdown>
           </textarea>
       </state>

Now it all fits neatly on the screen again.

Conclusion

This 'trivial' modification involved most of a day to run down all the various little secrets and what-nots required to get it to work. I doubt it's going to save me that much time that I would have otherwise wasted walking back and forth to the computer to turn it on. On the other hand, it's fun to have the system run a little more smoothly, so I'll chalk it up to keeping myself happy.

Hopefully, even people who don't really need (or can't use) a Sleep function will still find this helpful for modifying their own MythTV menus and invoking external applications.

Snarke 02:59, 28 January 2010 (UTC)