Raspberry Pi Shutdown Switch – Safely Turning off the Pi

We use a model B rev 2.0 Raspberry Pi as one of our Samba and DLNA media servers, and normally turn it off through a Webmin control panel to ensure nothing untoward happens with any of the attached hard drives. This solution is less than ideal however, as it requires a second powered-on device and a couple of clicks to get to the shutdown page in the control panel.

The Raspberry Pi forum has am excellent thread about a simple & safe shutdown button, from which I copied to produce my shutdown switch. It’s something you can put together in less than 20 minutes if you have the parts.

All you need is to install the RPi.GPIO Python class on the Pi (use SSH to grab it, “wget http://pypi.python.org/packages/source/R/RPi.GPIO/RPi.GPIO-0.4.1a.tar.gz”; unzip it; and install it, “sudo python setup.py install”; then remove the files to tidy it all up), and you can start accessing the pins via Python scripts.

Just connect pin 1 to a momentary open switch, and the switch to a 1K and a 10K resistor. Then connect the 10K resistor to the ground on pin 9 and the 1K to pin 11 (GPIO17). If you’re wondering where these are then this page has some nice illustrations; and more info on these pins can be found here. It’s worth covering the 5V line with some insulation just to minimise the risk of shorting out your Pi with it (see images below), as everything else on the GPIO header is 3.3V.

Breadboard setup, minus switch which would cross lanes 12 & 13.
Breadboard setup, minus switch which would cross lanes 12 & 13.
Raspberry Pi Shutdown Switch
In the case, soldered directly onto the pins with a momentary switch screwed into the case above the pi logo (hence minimising risk of contact)

All that’s left is to monitor pin 11 (GPIO17) for activity, for which I used the code on the Raspberry Pi forum.

Placed in /home/pi/bin/button/shutdown.py

import RPi.GPIO as GPIO
import time
import os
GPIO.setup(17, GPIO.IN)
while True:
os.system("sudo shutdown -h now")

Placed in /etc/rc.local on the line before “exit 0”

python /home/pi/bin/button/shutdown.py

Then the Pi will shutdown when the button is pressed for about 1 second – only the Power light will remain on (red) when it’s shut down. It’s worth noting that this won’t work if the Pi has crashed but that’s not an issue we often see.

Updated 22/01/15 – Thanks to “Joost” for clarification on pins, specifically that GPIO17 is pin 11 on the board.

SEATT Updated to 1.2.7

I’ve updated Simple Event Attendance (SEATT WordPress plugin) to version 1.2.7. This brings bug fixes, and updates in line with the release of WordPress 3.5.

  • Fixed problems with apostrophes being escaped with numerous backspaces in admin panel and in the comment box
  • Removed first+last name from page template as this is rarely used, with list users no longer in a table format, but now in an ordered list
  • Admins can now sign up registered users simply by supplying a username in the admin panel
  • Fixed problems with wp_prepare() causing errors in wordpress 3.5
  • Deleting the plugin now removes all database tables as well as files to provide clean removal. This means uninstalling will now remove all events


Live at http://wordpress.org/extend/plugins/simple-event-attendance/

SEATT Updated to 1.2.6

Simple Event Attendance has been updated to 1.2.6:

  1. Addition of extra table columns in admin view.
  2. Updated screenshots to reflect recent changes.
  3. Corrected use of date() function to current_time() to use timezone specified in WordPress rather than the server one.
  4. Added list of user emails signed up to an event.
  5. Some other small cosmetic changes, including register & login links on the event signup form.

The plugin is live at http://wordpress.org/extend/plugins/simple-event-attendance/


Facebook Like Buttons, &fb_xd_fragment=, Blank pages and SEO

This is a software development problem that’s been around for months now and yet still bugs thousands of users.

Any of your pages with facebook widgets on can result in URL’s like


This has several implications. Firstly – it can cause blank pages through unwanted interactions with div areas on the page. We can solve this by adding the following fix just before the </body> tag. This came from http://forum.developers.facebook.net/viewtopic.php?id=60571&p=1 (temporary solutions)

<!-- Correct fb_xd_fragment Bug Start -->
<!-- Correct fb_xd_fragment Bug End -->

The second, more long term issue is that this page will appear in search results alongside the normal page…resulting in duplicate content. Obviously you could just remove the like button but that’s not an ideal solution. So you can do a couple of things.

Head to webmastertools (https://www.google.com/webmasters/tools/home?hl=en) and add the fb_xd_fragment= as something that should be ignored on your site.

Filtering out fb_xd_fragment in Google Webmaster Tools
Filtering out fb_xd_fragment in Google Webmaster Tools

Another option is to use .htaccess and 301 redirects to clip out the &fb_xd_fragment=, which is a pain but very easily do-able and removes the requirement to put the display fix on every page. So try this (modified per your site) in your .htaccess.

RewriteCond %{QUERY_STRING} fb_xd_fragment=
RewriteRule ^(.*) http://www.example.com/$1? [R=301]

You could also ignore it and just hope facebook fixes it soon…yeahh bad choices right?

phpBB 3 Script Integration – New Threads and Replies from an External Script

This is the third article I’ve written for pulling functions in phpBB3 for external use. This one allows you to either create new posts in a forum or reply to a thread. This was created for use with a text system, where users could text in comments which would be added to a thread.

Article on phpBB3 Integration
Article on sending PM’s

I’ve put everything needed into one file as I don’t want to go through and break it up. The previous two posts (linked above) used a seperate phpbb.php file with part of the code in but this just includes everything.

// All queries --> support@3cc.org
// This is not setup for new thread posting, and has been config'd to not increment post count as this is for a bot.
// Further changes will be needed to clean up code as this is using external functions instead of clear documentation. --dc
define('IN_PHPBB', true);
$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './phpBB3/';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
include($phpbb_root_path . 'common.' . $phpEx);

// Start session management

// post send controller
function sendphpbbpost($pmmessage,$userid,$pmsubject) {

$my_subject = utf8_normalize_nfc(request_var('$pmsubject', '', true));
$message = utf8_normalize_nfc($pmmessage, '', true);
$uid = $bitfield = $options = '';
$allow_bbcode = $allow_smilies = true;
$allow_urls = true;
generate_text_for_storage($message, $uid, $bitfield, $options, $allow_bbcode, $allow_urls, $allow_smilies);
$data = array(
// General Posting Settings
'forum_id'          => 7,    // The forum ID in which the post will be placed. (int)
'topic_id'          => 5,    // Post a new topic or in an existing one? Set to 0 to create a new one, if not, specify your topic ID here instead.
'icon_id'           => false,    // The Icon ID in which the post will be displayed with on the viewforum, set to false for icon_id. (int)

// Defining Post Options
'enable_bbcode' => false, // Enable BBcode in this post. (bool)
'enable_smilies'    => true, // Enabe smilies in this post. (bool)
'enable_urls'       => false, // Enable self-parsing URL links in this post. (bool)
'enable_sig'        => true, // Enable the signature of the poster to be displayed in the post. (bool)

// Message Body
'message'           => $message,     // Your text you wish to have submitted. It should pass through generate_text_for_storage() before this. (string)
'message_md5'   => md5($message),    // The md5 hash of your message

// Values from generate_text_for_storage()
'bbcode_bitfield'   => $bitfield,    // Value created from the generate_text_for_storage() function.
'bbcode_uid'        => $uid,     // Value created from the generate_text_for_storage() function.

// Other Options
'post_edit_locked'  => 0,
'topic_title'       => $subject, // Subject/Title of the topic. (string). This is needed for new posts but for our purposes isn't.

// Email Notification Settings
'notify_set'        => false,        // (bool)
'notify'            => false,        // (bool)
'post_time'         => 0,        // Set a specific time, use 0 to let submit_post() take care of getting the proper time (int)
'forum_name'        => '',       // For identifying the name of the forum in a notification email. (string)

// Indexing
'enable_indexing'   => true,
'force_approved_state' => true, // Only runs on 6 onwards...check SUCC

//Now send that post...
submit_post('reply', '', '', POST_NORMAL, &$poll, &$data, $update_message = true);


$user->data['user_id'] = 2;    // User id of poster.
$auth->acl($user->data); // Re-initiate user after recall
$userid = $user->data['user_id'];
$pmmessage = 'This is a new reply, change this to whatever you want.';


Looking through the code above you will see several points that need changing. It’s currently set to ‘reply’ (change this to ‘post’ for a new post). Change all details to suit really – it’s easy to customise.