Friday, November 1, 2013

Raspberry magic

Long time since I've written last time on my English blog page. Time to switch a bit from Polish piczkowskipl.blogspot.com to this one.

Some time ago I met Raspberry Pi for the first time. I had a chance to play with it and went as far as setting it in headless mode.

Today I got it back from dust and gave it next chance.
My aim was to set it up as small home server and media center.

At home I have a dynamic IP which updates more-less every 24 hours. I know solutions like DynDNS. I even used it but it was not perfect. Very often the IP stored in cloud service was not refreshed with new IP of my rooter at home.

My idea was to create a daemon program that would run in background periodically and check if external IP of the router changed. Then it should send me an email with new IP.
As genial as simple :) I could then easily use this IP to connect with remote desktop to my home server.
Surely it would not be useful if I want to setup web page and release it in the Internet to public because still the IP will change but this is not my purpose. My aim is to connect with home server by IP and use it for many purposes like monitoring what's going on at home (smart house) or working on my home machine (upload/download/program/watch a movie?? whatever comes to my mind).

Raspberry Pi seems to be interesting in this context.

Today I will explain how I set up virtual desktop connection with TightVNC.

1. Install TightVNC Server on Raspberry Pi

sudo apt-get install xrdp

2. Start remote desktop server


/usr/bin/tightvncserver
you will be asked for password, type password and do not ser view-only password when you will be asked for this.

3. Check ports on which xtightvncserver is running

sudo netstat -tulpn
Then you will have to setup your router to forward ports, e.g:


192.168.1.107 is the IP of Raspberry Pi in home network behind the router.

On your machine from where you want to connect to Raspberry Pi install TightVNC Viewer, on Ubuntu you can do this with command:

sudo apt-get install xtightvncviewer
Then connect to Raspberry Pi

xtightvncviewer 83.29.84.77:5901

83.29.84.77 is my router external IP, the one that I would like to email myself from PI whenever it changes.

How to email anything from Raspberry Pi?
Very easy with Python:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import smtplib
 
# Specifying the from and to addresses
 
fromaddr = 'fromuser@gmail.com'
toaddrs  = 'touser@gmail.com'
 
# Writing the message (this message will appear in the email)
 
msg = 'Enter you message here'
 
# Gmail Login
 
username = 'username'
password = 'password'
 
# Sending the mail 
 
server = smtplib.SMTP('smtp.gmail.com:587')
server.starttls()
server.login(username,password)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()

How to check your external IP address?
Very easy with service like http://ifconfig.me/


curl -s http://ifconfig.me
Putting it all together. Python script below gets IP address and compares it with address saved in local file. If for any reason IP is empty or same as the IP in local file then no email is sent. Otherwise an email is sent with new IP and the IP is saved in local file (dyndns.txt)

#!/usr/bin/env python

import smtplib
import subprocess
import sys

def send(ip):    # send mail
 # Specifying the from and to addresses
 fromaddr = 'change_me'
 toaddrs  = 'change_me'
  
 # Writing the message (this message will appear in the email)
  
 msg = "Your IP is  "+ip 
  
  
 # Sending the mail  
  
 server = smtplib.SMTP('smtp.gmail.com:587')
 server.starttls()
 server.login('marcin.piczkowski','mypassword')
 server.sendmail(fromaddr, toaddrs, msg)
 server.quit()

proc = subprocess.Popen(["curl","-s","http://ifconfig.me"], stdout=subprocess.PIPE)
(out,err)=proc.communicate()
ip = out.strip()
print "IP is " + ip

if ip == "": 
 raise SystemExit
else:
 txtf = open("dyndns.txt","rw")
 lines = txtf.readlines()
 oldip = lines[0].strip()
 txtf.close()
 
 if oldip != ip:
  print "Sending ip " + ip
  txtf = open("dyndns.txt","w")
  txtf.write(ip)
  send(ip)
  txtf.close()
 else:
  print "IPs are the same"
  txtf.close()
  raise SystemExit
The script must be given execution rights and dyndns.txt file read/write access

sudo chmod +x myscript.py
sudo chmod 666 dyndns.txt
Then you can schedule with cron to execute this script every 15 minutes:
sudo crontab -e
Add this line at the end of the file

*/15 * * * * python /etc/init.d/myscript.py >> /var/log/dyndns.log 2>&1 &
Above line is correct when you have your script placed in /etc/init.d/
It will store logs in /var/logs/dyndns.log but first you need to create such file and give it read/write access:
sudo touch /var/log/dyndns.log
sudo chmod 666 /var/log/dyndns.log

You can check your cron logs with

grep CRON /var/log/syslog

Now you should get mail with IP in 15 minutes. Let's verify quickly that you really can connect to Raspberry Pi on this IP.
We will start HTTP server on Pi with python, type this in console:

python -m SimpleHTTPServer
Server would listen on port 8000 so you need to forward this port in rooter configuration.
Then type in browser: http://<IP from email>:8000
Server should response with content of folder in which you started SimpleHTTPServer.

In future post we will have a look at how we can run Node.js on Raspberry Pi. Stay tuned!!

Used resources:
[1] http://programmaticponderings.wordpress.com/2012/12/26/installing-tightvnc-on-the-raspberry-pi/
[2] http://www.pythonforbeginners.com/systems-programming/sending-emails-using-google/
[3] http://www.linuxjournal.com/content/tech-tip-really-simple-http-server-python

No comments:

Post a Comment