Ben Dodson

Freelance iOS, macOS, Apple Watch, and Apple TV Developer

How to control a Mac Mini from your iPhone including waking, sleeping, and audio / video

I was recently cleaning through the "technology cupboard" in my flat (every geek has one - it's a place where all the useless electronics we've collected over the years live) when I came across an idea for creating a home entertainment system for my bedroom. The main driver for this was a forgotten Mac Mini (512MB of RAM and an old G4 processor) which I realised could hold all of my music on its 40GB hard drive and send it wirelessly to all of my other equipment.

The problem I have is that at present I have 3 computers at home and 1 at work (plus my iPhone 3G) which all have a complete copy of all of my music files (around 20GB - obviously the iPhone doesn't have all of that as it doesn't fit but that's a separate issue) - the downside to this is that when I update one machine the others are then out of sync. My original plan was to have the mac mini hold everything and then the other computers would use it's hard drive over my network as the master copy. That way if I added music to the mac mini, the others would all be in sync. I have since completely given up on this idea as I needed to a) access music on my laptop all the time and b) access music on my work iMac without having to leave everything on at home and broadcast through a static IP (which would also have been a little slow especially when I skip through lots of tracks - I'm very picky at what I listen to).

However, since I started writing this article there have been rumours flying around about the 9th September "Lets Rock" event being staged by Apple. Several sources are touting that iTunes 8 is going to be released and will have an option to stream your music wirelessly to other machines (or an iPhone) through the internet. Let's hope this is true!

With the initial problem left alone for now, I decided to think on another problem I have. If I want to listen to music in my bedroom, then I have to bring my laptop in and listen to it from there. This isn't a huge difficulty but the sound quality isn't great and I don't like using my laptop in my bedroom (mainly because I try to keep some separation between work / computer based activities from other things I enjoy like reading and writing - the ideal separation is a physical one so I don't use my computer in my bedroom at all). I could buy a cheap hi-fi system but then it wouldn't be connected to my iTunes library. Alternatively I could get an iPhone dock but they are quite expensive (due to the magnetic shielding) and also I can't fit all my music on there so it wasn't really an option. At this point I'd like to point out that yes I could have used AirTunes (plugging a hi-fi unit into the 3mm audio jack on an Airport Express in order to pick up a shared iTunes library) but that would require me leaving the laptop on in the other room. Not a great hardship but I'd have to get out of bed to turn it off (which would be a hardship).

After a bit of thought and a look at the components I had, I worked out that I could put the mac mini under my bed with a wireless card and some speakers and then play music through it using the Apple Remote application available from the App Store for iPhone. I could also install a VNC client so that I could control the mac mini remotely if necessary (in the case of copying music onto it, installing updates, etc). Perfect.

I'm quite pedantic however and so the above solution wasn't yet 100% perfect. The main problem I had was that the mac mini would need to be on 24 hours a day when I'd only be using it for around an hour a day at most. This doesn't bother me from an environmental perspective (I'm not into "green") but did bother me from the point of view that I'd be paying for electricity I wasn't using (around 45-50W an hour I believe which would be around 16p a day - that works out at nearly £60 a year for nothing!) and that the components would be wearing down from overuse. It would probably become a little unstable as well and I'd worry it would burst into flames or something! So, the mac mini needed to be put to sleep and needed to be woken up. I could do this by pressing the power button but it's under my bed and I can't be bothered with the movement involved. Thus a solution had to be created that would let me wake it and put it to sleep remotely with my iPhone being the obvious candidate for this as it was already choosing the songs being played.

Challenge One - Make the mac go to sleep remotely

Waking up a machine is easy with Wake-on-LAN (as we'll see shortly) but there seems to be no easy way to put one to sleep. My initial ideas of having an inactivity timer were quickly discarded as I realised that either the machine wouldn't go to sleep if music was left playing or it might go to sleep too quickly. A better solution was needed and I eventually came across a terminal command which will make your mac sleep:

osascript -e 'tell application "System Events" to sleep';

You can try the above in Terminal and watch in awe as your mac succumbs to tiredness. So this is all well and good but can only be run on the machine which you want to put to sleep; it can't be done remotely.

A solution to the problem comes in the form of the Apache2 web server that comes installed by default on all OS X Leopard installations. If I could set the mac mini up as a server, knock up a bit of PHP to pass the sleep command directly to the machine, and then broadcast the IP so that the command could be run via Safari on the iPhone, then I would be on to a winner! This is exactly what I ended up doing and the instructions are below for your delectation.

First of all we need to activate the Apache2 web server in Leopard. To do this, go to "System Preferences" and then to the "Sharing" icon. If you tick the "Web Sharing" checkbox, then the server will come to life and will be enabled whenever you start the machine. You can check this has worked by going to http://localhost/ on the machine and checking you get an apache default installation message. Now this is done, we need to set our Computer Name for easy access to this page from anywhere on our home network. The setting for this is also in the "Sharing" control panel and so I set mine to mini. This allows the web server to be reached by any computer on the network by going to http://mini.local/ - try it yourself by changing it to whatever name you want (the URL to access your computer will be shown on the same screen).

Now that we can connect to the web server, we need to get PHP up and running and write our script. PHP 5 doesn't come enabled by default so we have to do this by opening up terminal and typing the code below. I am assuming at this point that you have the excellent TextMate installed which is accessed from the 'mate' command in Terminal. If you don't have it, either install it or substitute 'mate' for some other text editor command like 'pico' or 'vi'.

sudo mate /etc/apache2/httpd.conf

You may need to type in your administrative password if prompted. Now you have the Apache2 configuration file open, scroll down to somewhere around line 114 where you will find the line:

# LoadModule php5_module libexec/apache2/libphp5.so

You'll need to uncomment this (by removing the proceeding hash) and then save the file. Once this is done, you'll need to restart Apache in order for your changes to be made available. You do this with the command:

sudo apachectl graceful

You can use 'restart' in place of 'graceful' to do a full restart, but a graceful restart won't kick off anyone that is currently using your server. This isn't going to matter here but it's a good habit to get into in case you ever need to restart an apache server in the future.

You now have PHP5 installed and ready to go so lets write the PHP script that is going to power our sleep command. You'll need to go to your Apache DocumentRoot (which by default is in a folder called Sites in your home folder) and delete any files that are in there. Now create a new file called "index.php" with the following code in it:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
    <title>Mac Mini Sleeping App</title>
</head>
<body>
    <h1>Goodnight...</h1>
</body>
</html>
<?php
exec('./sleep.scpt');
exit;
?>

All this code is doing is outputting a message that says "goodnight" and then executes an applescript file (in this case sleep.scpt) which contains the code from earlier:

osascript -e 'tell application "System Events" to sleep'

I find it's easier to include a file in this way rather than typing the command into a function such as passthru() as it allows for easier control over quotes, etc. The exec() command used in the above is pretty much telling PHP to type the command we used earlier into Terminal. Unfortunately this won't actually do anything at present (at least it shouldn't do) as the Apache webserver is not authorised by default to perform such important system commands as are available through exec(). To do this we need to go back to the Apache2 config file and set the user and group of the web server to be the same as that of the user of the machine. Now this is a calculated security risk as it means any scripts on the server can have full access to your machine and thus compromise it. However, this is for personal home use and no-one will be able to access it unless they are on your network let alone run scripts on it so I think it's ok. Let's set the permissions by opening up the config file:

sudo mate /etc/apache2/httpd.conf

Now go to around line 126 and amend the User to your own username and Group to 'staff'. In my case this was:

User ben
Group staff

Yours will differ (unless you're called ben) but you can find out what yours is by going to your home folder - the name of the folder is the name of your user.

Now restart the apache server (remember our graceful command from earlier?) and try out your site. You should find that your mac goes fast to sleep. Success! Simply go to the URL with safari on your iPhone, tap the '+' icon, and then choose "save to home screen" in order to set it up as a web app. If you want a fancy icon, then stick a square PNG named "apple-touch-icon.png" in the same folder as the index.php file and you'll notice that it appears on your home screen when you bookmark the page.

Challenge Two - Wake the mac up

Ok, you now have a sleeping mac that you want to wake up. Most computers have a little feature built in to them called Wake-on-LAN. The idea is that when the computer is asleep, the ethernet port is actually still active and listening for data. If a certain command is sent (referred to as a "magic packet") then the ethernet card will tell the rest of the computer to wake up. This is exactly what we need but unfortunately will not work over a wireless connection (as a wireless card doesn't stay awake when the computer is asleep). If you have connected your mac to an ethernet connection then you can ignore the next few steps, but for me a long cable wasn't really an option. I therefore came across a solution that would allow me to pretend I was on ethernet; wireless bridging.

The idea behind wireless bridging is fairly simple. Rather than having an ethernet cable from your router to your computer, you instead have 2 wireless routers that are connected via ethernet to each machine (or modem) which then act like an ethernet link between the two. Now I already had an Airport Extreme which was broadcasting my network / internet wirelessly and so all I needed was another router on the other end. After a bit of headscratching with a BT router that was lying around, I decided the best way to proceed was to pop to the Apple Store and buy an Airport Express. The Airport Express is plugged into a standard power socket and then broadcasts a wireless signal. On it's base it has 3 inputs; ethernet, USB, and 3mm Audio. Usually the Airport Express is connected to a wired modem via ethernet so it can quickly and easily broadcast internet to the rest of your house however you can also plug in a printer to share that to wireless devices or plug in a standard hi-fi unit in order to utilise the AirTunes feature I mentioned earlier.

I instead used it's network bridging service in order to connect it to the mac mini via ethernet and then extend the wireless network created by my Airport Extreme. This is fairly easy to do from the Airport Utility - I won't go into the exact process here as it is mimicked in several other places, but the end result that the Airport Express connects to the wireless network created by the Airport Extreme and sends this to the mac mini via ethernet. This means that we can now send a Wake-on-LAN command as both the Airport Extreme and Airport Express are "always on" allowing the packet to go through the bridge, down the ethernet cable, and straight into the ethernet port. Simple!

Now we just need to find a way to send the magic packet from the iPhone. The application iWOL allows us to do this easily and has a very quick setup. Simply type in a name to reference the machine and the MAC address of the ethernet card (this can be found by going to "System Preferences"->"Network" and selecting your ethernet card. Now click on "advanced" and then on the "Ethernet" tab. Your MAC Address is the "Ethernet ID"). Now enable "LAN Broadcast" mode and you should be good to go. Once your computer is asleep, open up iWol and you should be able to wake it up at the press of a button.

Further Enhancements

At present, my setup is working in the same way as detailed in the steps above. I am in the process of making the sleeping web app slightly tidier with a fancy interface and icon, etc, and this will be available for download from my site shortly - the working title is "Rohypnol"…

In addition to the above steps, I have installed a freeware application called Alarm Clock 2 on the mac mini which allows me to use it as an alarm clock. Various options are available including a "wake from sleep" mode which is perfect for this project. I now have a special playlist on my mac mini which starts off quietly and over 5 minutes gently increases in volume. Nothing says wake up in the morning like Rick Rollin' music…

In order to control the mac mini better, I also installed a freeware VNC server called Vine Server that allows me to control the machine remotely. I won't go into the finer details of VNC setup as this has also been covered in detail elsewhere on the net. I will however mention the excellent VNC Lite app for iPhone which allows you to access VNC controlled machines. It's easy to use and very intuitive - it's also free!

In the future I plan to make some improvements to this system by plugging in a monitor which can then sit on the end of the bed allowing me to watch movies and tv shows downloaded through iTunes as well as DVDs etc but this is an upgrade for another day. For now I'm quite happy with the setup which was achieved relatively easily and cheaply as I had all the components to hand. I probably wouldn't recommend it if you were going to buy all the parts as the whole system would cost about £500 but as a small project it's worked very well. Now I just have to wait to see what iTunes 8 will add to this setup…

If you have any questions or comments, then please use the comments box below or contact me!

iPhone 2.1 Firmware Update Released - Fast? Stable? Fixed? » « Twitter stops sending SMS to UK / Europe / Australia

Want to keep up to date? Sign up to my free newsletter which will give you exclusive updates on all of my projects along with early access to future apps.