Tuesday 1 September 2009

IMAP PUSH GMail Python Script (for Mac, but easily changable)


So, you need a python script to do something when you get an email (from GMail, for example, but other services that support IMAP4 will work as well). I came across this post when finding out how to do this. It pointed me in the right direction; I didn't have to do much initial thinking/goggling.

A quick explanation as to how the script works:
  1. Connect using IMAP to imap.gmail.com
  2. Send login credentials (encrypted with SSL, don't worry)
  3. Select 'INBOX'
  4. Send IDLE command and wait for mail...
  5. When a message gets to Google's servers, they terminate the IDLE connection. This then signals to our script that a message has been received (or we've timed out)
  6. The script then checks to see if there is new, unseen mail, and, if so, uses growlnotify to let us know the sender and the subject. (This is the bit that can be replaced to do whatever you want it to do. You can get the message body if you want, times, dates, etc... and do whatever with it)
  7. IDLE command is sent again (i.e. back to 4.)
Instead of a growl notification, you could use pySerial to send something to an Arduino and light something, spin something, etc... Feel free to change the code and do whatever to it.

There are two bits of code you'll need: imaplib2.py and my IMAPPush.py

I hosted my IMAPPush.py on Google Sites because I couldn't host it here. All you need to do is put the files in the same directory, cd to said directory and execute:

python IMAPPush.py USERNAME [PASSWORD]

The PASSWORD is not required -- you'll be prompted for it if it is omitted.

To find out more about IMAP IDLE, see it's RFC (RFC 2177) here.

There's no point me explaining how the code works here; if you want to understand how the code works, I've put a lot of comments in the code. That's the best place for explaining the code, after all.

Here are the links to the code again:
  1. http://sites.google.com/site/hmmtheresanidea/files/IMAPPush.py?attredirects=0
  2. http://www.cs.usyd.edu.au/%7Epiers/python/imaplib.html
Any comments, suggestions, etc... please let me know below. Thanks for reading!

UPDATE: links fixed, and code is now licensed.

Thursday 30 October 2008

Start Media Center on a Particular Channel

I was wandering the other day: how is it possible to start Windows Media Center, in fullscreen mode, on a particular channel (BBC News 24), instead of having to go through the menu system, say, in the morning when my light turns on? (except this time it'll be my computer that switches it on, not the alarm clock)

I started googling for command line Media Center (ehshell.exe) operators/switches and quickly came across this page.

This bit of script (in a batch file) will start Media Center, maximised, on the last channel that was being watched:

start /MAX %systemroot%\ehome\ehshell.exe /homepage:VideoFullscreen.xml
(all one line)

There were no parameters that could be passed to the .exe that would specify what channel was going to be displayed. The fact that Media Center remembered the last channel suggested it had to be stored somewhere. I had a look in the ehome directory to see if there was anything in any files there that changed when the channel changed, all to no avail. The next stop was the registry.

Under HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\ the key Media Center can be found, and within that, Settings, within that, VideoSettings. Now, in this key you'll find a string (REG_SZ) called _tvChannel, this string contains the last/current channel you were/are on (_tvChannelPrev contains the one before that); change it, then when Media Center starts, and you navigate to Live TV, it starts on that channel.

Channel 80, in the UK (freeview), is BBC News 24. Just change the 80 to whatever channel you want. There are two ways I've combined the above to make it easier; the first involves a batch script and a .reg file:

tvChannel.reg ...

Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Media Center\Settings\VideoSettings]
"_tvChannel"="80"


startNews.bat ...

@echo off
echo Ammending entry in registry...
regedit /s tvChannel.reg
echo Starting Media Center at channel set in .reg file...
start /MAX %systemroot%\ehome\ehshell.exe /homepage:VideoFullscreen.xml
exit


Running startNews.bat will start Media Center at the channel specified in tvChannel.reg. This, however, isn't very flexible; files need to be manually edited if a different channel is required. A python script would be better, one which outputed the channel, passed as a command line argument, to a .reg file. which was then called. Please keep in mind this is a quick script, i'm sure it could be quite heavily optimised, but it does what it needs to do. Here is is:


Sorry about the image, blogger/blogspot strips out the tabs (as well as, disgusting as they are, spaces instead of tabs). The same could be achieved with a more advanced batch script, but, to me, a python script seemed much easier. I saved this python script as channelLaunch.py so when I use it, the command is:

python channelLaunch.py 80

That's it! Hope it can be of some use to someone.

Thanks

Chris

Friday 19 September 2008

Wake Up Light - Alarm Clock Triggered Light Bulb

I was thinking to myself the other day how much easier I find getting up in the mornings when it's light outside. I continued to contemplate how similar the light level from a low-power light bulb was. My mental conclusion was: 'meh, fairly'. Now, how do I make a light bulb turn on when I want to wake up? Here's where my previous post, Triac Mains Switching, comes into play. Here is the schematic again:


When I want myself to wake up, I make my alarm clock turn it's radio on. So, after taking my alarm clock apart and probing numerous soldered contacts, which looked like they could provide low-voltage DC power to the radio circuit, I found one (relative to ground) which was at approximately 6V when the radio was on, and 0.5V when it was off. This was great news, 6V is just slightly larger than the logic 'high' for the Arduino Decimilla. With a simple voltage divider, and the equation Vout = (Vin * Rb) / (Ra + Rb),it would be trivial to bring that voltage down to a suitable logic-triggering level; I probably don't even need to.



I have used fairly high-valued resistors to ensure very little current is drawn from the clock's circuitry; that way there's little chance of damaging the clock.

Now I have a low-current, 5V(ish) supply, capable of triggering an Arduino digital pin. I also have a circuit which allows the Arduino to turn 240V mains devices on and off.

Can you see where this is going?

With the two circuits joined together, it is possible to turn the light bulb on when the radio turns on. Mission Completed!

Simple set-up (without voltage divider)

Arduino Code Listing:

byte bulbPin = 12;
byte radioPin = 8;

void setup(){
pinMode(bulbPin, OUTPUT);
pinMode(radioPin, INPUT);
}
void loop(){
if (digitalRead(radioPin)){
digitalWrite(bulbPin, HIGH);
for (int i=0; i<5; i++){
delay(60000);
}
digitalWrite(bulbPin, LOW);
}
}

This code will leave the light on for 5 minutes after the alarm has been turned off. If the delay wasn't required, neither would be the Arduino.

A video of it in action:



Admittedly, this light bulb is quite bright; I'm going to get a 20W pearl bulb soon.

Possible additions:

- Serial communication for triggering, eg:
- e-mail received
- Web based (switch on a website) (with serial-to-Ethernet module possibly)

- Light level (LDR triggering)

- Triggered by a break in laser beam across the entrance to the room, hmm...

Words of warning: Mains electricity is very dangerous; do not do anything like this if you're not sure what your doing. I did a fair amount of research before building my circuit. The components in this circuit can become damaged from transient voltage spikes so I'd advise against using inductive loads with this circuit - the triacs may fuse open (or worse!). Stick with resistive loads!

Have fun,

Comments/Suggestions greatly appreciated...

Chris