Remote Power Management Demo

From Digi Developer

Jump to: navigation, search



This page is to introduce you in the Demo of the Remote Power Management Interface using a python generated web page on a Connect Port X.


  • Connect Port X (CPX)
  • Digi RPM device (RPM 8 and 10 supported)
  • SMTP server
  • Wall Router
  • Watchport Camera


The Demo configuration is shown as below:

Remote Power Management Demo Setup

The standard python is compatible with CPX devices with the exception of one function call 'getfqdn()'. In the Digi compliant version, this call is replaced by a custom function call 'get_host()'. The 'get_host()' call returns the hostname of the device using the digicli [link needed] library.


We are using a couple of techniques in this demo, so it´s clear that we need a couple of source. You have to add the following Python files using the ConnectPort X web interface:

  • config.xml

Getting started

  1. At first you have to adjust the config file settings according to your needs.
    1. WALL_ROUTER_ENABLED: Set to 1 if the website should check sensor data from a wall router (specified in WallRouterAddress)
    2. PAGE_REFRESH: Adjust the period of the web site auto refresh (in seconds)
    3. ALERT_EMAIL_FROM: Set the "from" field of the alert email
    4. ALERT_EMAIL_TO: Set the destination email address
    5. SMTP_SERVER: Set the SMTP server host name
    6. TEMPERATURE_THRESHOLD_HIGH: An alert email is sent if the wall router temperature sensor value is above this threshold
    7. TEMPERATURE_THRESHOLD_LOW: An alert email is sent if the wall router temperature sensor value is below this threshold
    8. LIGHT_THRESHOLD_HIGH: An alert email is sent if the wall router light sensor value is above this threshold
    9. LIGHT_THRESHOLD_LOW: An alert email is sent if the wall router light sensor value is below this threshold
    10. DiagnosticsPagePort: Set the port on which the web page is accessible
    11. WallRouterAddress: Set the 64 bit destination address of the wall router (format: [XX:XX:XX:XX:XX:XX:XX:XX]!)
    12. User: Set the username for access to the web page
    13. Password: Set the password
  2. The Wall Router destination address is the same as its serial number. You can find that value on the device´s cover.
  3. Check if your CPX device can connect to the Wall Router. Using the web interface, "Configuration"->"XBee Network" should contain an according entry. If not, press the reset button of the wall router quickly 4 times. It then should re-associate with the CPX.
  4. Then, upload all files specified above on the CPX device.
  5. Add an auto-start slot at the CPX configuration page (Applications->Python->Auto-start Settings) for "".
  6. Reboot the device.
  7. If you whish to name your RPM outlets, open a serial connection from the CPX to the RPM device by typing "connect 1" on the command line interface. If everything worked fine, you will see the prompt "RPM>:". Type "name 0 X,Y" where X is the outlet id and Y is the name you whish to specify.
  8. If you are experiencing problems on connecting to the RPM, type "set term state=off" and reboot the CPX.
  9. Telnet and run "py" to start the web server manually.
  10. If the web server should start up automatically, please use a second auto-start slot (Applications->Python->Auto-start Settings). But be aware: You get no debug information from the console.
  11. Wait about a minute and type in your browser "http://<CPX-IP>:8080"
  12. To authenticate, add "?user=admin&password=secret" to the URL and enter (e.g. http://<CPX-IP>:8080/?user=admin&password=secret)
  13. To logout, add "?logout=." to the URL and hit enter

Please note: There is no session timeout, so don´t forget to logout!

How it works / How it looks serves a web page that gives you the opportunity to manage the connected RPM. You are able to

  • monitor the state of each outlet
  • set on/off a specific outlet
  • reboot a specific outlet (automatically reset the outlet within 10 seconds)
  • set on/off all outlets
  • reboot all outlets
  • monitor the Wall Router sensor values
  • have a look at the camera video
  • use basic authentication to limit access to the web page (see hints on the "Getting started" section).

As a big feature, you are getting an alert E-Mail if the Wall Router sensor values are out of the range specified in the config file.

Here is a screenshot of the Remote Power Management Interface:

RPM Interface Screenshot

Interesting Code

Below, we will give a short introduction in the key source code.

Sending an E-Mail is quite simple. Here is a snippet from

def sendEmail(fromaddr, toaddrs, subject, msg):
    ## Definde Header
    header = ("From: %s\r\nTo: %s\r\nSubject: %s\r\n"
       % (fromaddr, toaddrs, subject))
    msg = header + msg
    server = smtplib_digi.SMTP(smtp_server)
    server.sendmail(fromaddr, toaddrs, msg)

Hint: You can get a simple SMTP Server for Win32 that is free for non-commercial use at [1].

Retrieving the Wall Router sensor values is easy, too. Have a look at

def getDataSample():
    ## Create a sensor object
    wallrouter = xbeewr.XBeeWRN(DESTINATION)
    ## Retrieve a sample reading from the wallrouter
    sample = wallrouter.sample()
    return (sample['temperature'], sample['light'])

Communicating with the RPM is gained using the serial port. Here is an example from

def getStatus(rpmId):
    serialfd = openConsole()
    os.write(serialfd, "status %d\x0D" % rpmId)
    data =, 2048)
    return data
def openConsole():
    # Open serial port
    serialfd =, os.O_RDWR)
    os.write(serialfd, "\x0D")
    data =, 1024)
    return serialfd

Starting the web server is a bit more difficult. Please look at this snippet of

WebServerThread = Thread(group=None, target=WebServerThreadFunction, name="Web Server Thread", args=(), kwargs={})
def WebServerThreadFunction():
    lastpage = "Error."
    server = SimpleHTTPServer.BaseHTTPServer.HTTPServer(
                ('', HTTP_PORT), MyHTTPRequestHandler)
    print "Serving HTTP Requests at port ", HTTP_PORT
class MyHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
    def do_GET(self):
        global lastpage                
        parameters = {}
            parameters = dict(
                [ map(lambda s: urllib.unquote(s), pair.split('=')) \
                        for pair in urlparse.urlparse(self.path)[4].split('&')])
        s = WEB_do_GET(parameters)
        if (s!="Error"):
            lastpage = s

WEB_do_GET is responsible for generating the HTML code and handling actions. At first it checks if some buttons have been pressed and according actions have to be done:

def WEB_do_GET(parameters):
    # Perform action
    if 'action' in parameters:
        if parameters['action'].startswith('setOn'):
            outletId = parameters['action'].split('setOn')[1]
            setOutlet(0, outletId, 'on')
        elif # and so on...

After that, the RPM status and Wall Router values are being retrieved using the modules described above.

Having that values in mind, we are able to generate a string template and fill it properly. The template is stored in

s = Template(ngg_main_webpage)
s = s.safe_substitute(REFRESH=PAGE_REFRESH,
                # [...]
return s

Monitoring the Wall Router sensor values periodically is done by the main loop:

while True:
	# [...]
	# check if th Wall Router is enabled (as defined in config.xml)
                # get Wall Router sensor data
                sample = getDataSample()
                print "Error getting data sample from Wall router."
                # check sensor data and send an Email if neccessary
                if (not temperature_alerted) and (not TEMPERATURE_THRESHOLD_LOW<=sample[0]<=TEMPERATURE_THRESHOLD_HIGH):
                    print "Temperature alert! "
                    alertcounter = alertcounter + 1
                    msg = "\r\n" + "Temperature is bad:\r\n\r\n" + str(sample[0]) + "(C)\r\n\r\n" \
                         "\r\n\r\n\r\n" + "This is alarm number " + str(alertcounter) + " since start of the monitoring script."
                    sendEmail(ALERT_EMAIL_FROM, ALERT_EMAIL_TO, "Digi Sensor Alert!", msg)
                    temperature_alerted = True
                    temperature_alerted = False
                # [...] doing the same for the light sensor value...
                print "Error sending alert E-Mail."

Future Versions

  • There are no recent changes scheduled so far.


In some installations it can occur, that the connection between the CPX and the RPM device cannot be established. In these cases, just remove the power plug of the RPM for some seconds and replug it. Maybe a reboot of the CPX should necessary, too.


There is no protocol for the communication between the CPX and the RPM device. This demo uses a parsing algorithm to retrieve the information in the RPM status message. However, if the status message syntax changes due to product/firmware updates in the future, the parsing algorithm has to be adapted acordingly.


The next archive contains some files that have to be uploaded unpacked on the ConnectPort X.

Personal tools
Wiki Editing