Integrated Raspberry Pi Camera with CUCM

I have finally decided to pickup Python, looks like that’s the prefer scripting language for Cisco. To do this i needed a project, a sort of “hello world” that would let me kick the tires. As a project I come up with making the Raspberry Pi Camera accessible to Cisco IP Phones as a service.

This blog post is just giving an overview of how I put this together, a good place for me to keep some notes for future and for others to use as a reference if they find anything useful. It’s not meant as a tutorial on Python or setting up Raspberry Pi, there is extremely good tutorials on both thous subjects already published on the internet.

Components used

1. I purchased my Raspberry Pi from RS Components
2. And also the Camera
3. I got Raspberry Pi up and running using this quick start guide
4. To update it, O/S, packages and Python up and running i used the following blog post. Note I skip steps 8 and 9. Lighttpd is a great and light web server but i needed something lighter while at the same time allowing me great flexibility. I also skip the static IP address part as the environment I developed this would have to work with DHCP. The blog post includes all the steps needed to setup Python as well as the easy_install utility.
5. The web server I use is the web.py framework and use these 2 short tutorials to get my head around it: web.py tutorial and blog post on 101
6. The Camera itself is controlled using the PiCamera package
7. And finally the reference guide when it comes to Cisco Unified IP Phone Services Application Development. The section mainly used for this project is “CiscoIPPhoneImageFile”

Overview

Click on the image to get a depiction of how the components interact.

PI with Cisco CUCM

PI with Cisco CUCM

Configurations Tasks

Assumtions made at this point is that the Raspberry Pi is up and working and Python is installed.
1. First task is to configure the service on CUCM and subscribe a few test phones to it. This is what the the service url will look like http://192.168.1.10:8080/getImg?phModel=7945

192.168.1.10 : IP address of the Raspberry Pi
8080 : Port the web server on Raspberry Pi is lisening to.
phModel=7945 : This is to tell the web server the request is coming from a 7945 Cisco IP Phone. Each phone model support diffrent image size and color depth (Refer to the link for Cisco Unified IP Phone Services Application Development) so the web server will need to know the phone model making the request to generate an image that will meet the requirements.

2. Create a user in CUCM (UserName:”Pi” UserPwd:”PiPwd”) and assign to the user the phones that will be using the service created in step 1.

3. Below is the Python code to get things up and running. The code is not great, I see 2 issues with it. Firstly allot of the code should be in functions/classes/package to make it more scalable. The code below only works with one phone model. Secondly the code below will not cope with multithreading (the camera been hit by multiple requests concurrently). Both these issues can be resolve. At this stage i just want to see if the concept will work.

Note use the easy_install utility to import the following packages ‘time‘, ‘socket‘, ‘requests‘, ‘picamera‘, ‘netifaces‘ and ‘ConfigParser‘. Also note that the folder ‘static/pic/7945/‘ needs to be created in the current directory the script is been run in.

import web
import time
import socket
import requests
import picamera
import netifaces
import ConfigParser

#Read setup first
config = ConfigParser.ConfigParser()
config.read("setup.ini")

setup = {
'userName' : config.get('UserDetails','user'),
'userPass' : config.get('UserDetails','pass'),
'serverPort' : config.get('WebServerDetails','port'),
'imgTitle' : config.get('ImageDetails','title'),
'imgPrompt' : config.get('ImageDetails','prompt')
}

print "**** Setup from setup.ini filr ***"
print "User Name : ", setup['userName'];
print "User Pass : ", setup['userPass'];
print "WebServer Port: ", setup['serverPort'];
print "Img Title : ", setup['imgTitle'];
print "Img Prompt : ", setup['imgPrompt'];
print " *****************"

webServerIP = netifaces.ifaddresses('eth0')[netifaces.AF_INET][0]['addr']
print "WebServer IP:" + webServerIP

#http url /7945Req goes to class name 7945img
urls = (
'/(getImg)', 'img'
)

#define class 7945img
class img:
def __init__(self):
self.render = web.template.render('templates/')

def GET(self,url):
#get the phone model
getInput = web.input(phModel="Default")
pModel=str(getInput.phModel)
print "Phone model:"+pModel

ipPhoneIp = web.ctx.env.get('HTTP_X_FORWARDED_FOR',
web.ctx.get('ip', ''))
print "Receive Req From IP:" +ipPhoneIp

if pModel == '7945':
#below should be the code to take the Pic
with picamera.PiCamera() as camera:
#nornal mode. there is also wide mode
camera.rotation=180
camera.color_effect = (128,128)
camera.resolution = (320,156 )
camera.start_preview()
#Camera warm-up time
time.sleep(2)
camera.capture('static/pic/7945/7945.png', 'png')

#reply to the phone with the detail of where to get the pic
headersT = {'Content-Type': 'text/xml; charset=UTF-8'}
payload = 'XML='+setup['imgTitle']+''+setup['imgPrompt']+'http://'+webServerIP+':'+setup['serverPort']+'
/static/pic/7945/7945.png'
return requests.post('http://' + ipPhoneIp + '/CGI/Execute', data=payload, headers=headersT, auth=(setup['userName'], setup['userPass']))

#reply to the phone with the detail of where to get the pic
headersT = {'Content-Type': 'text/xml; charset=UTF-8'}
payload = 'XML='+setup['imgTitle']+''+setup['imgPrompt']+'http://'+webServerIP+':'+setup['serverPort']+'
/static/pic/7945/7945.png'
return requests.post('http://' + ipPhoneIp + '/CGI/Execute', data=payload, headers=headersT, auth=(setup['userName'], setup['userPass']))
else:
print "END"

#create an application specifying the urls
if __name__ == "__main__":
app = web.application(urls, globals())
app.run()

The Python script above will read setup.ini file to setup the parameters. Below is a copy of the setup.ini file.

[UserDetails]
user: Pi
pass: PiPwd
[WebServerDetails]
port: 8080
[ImageDetails]
title: Pi Pic
prompt: Desk Area

Anyway below is what the result looks like, One of the first pictures I took. You can play around with the camera setting and can get a much better quality picture then this been taken and displayed on the phone.

Pi and CUCM Integration

Pi and CUCM Integration

Hope this helps. Any feedback let me know.
Alexis

About Alexis Katsavras

Working as Freelance Cisco Unified Communications Consultant in the UK. www.NetPacket.co.uk