Friday, December 28, 2012

My first attempt to build a home monitoring/control system

I've been playing with XBees for a while now and about two weeks ago I hit the wall - transparent UART mode has stopped being enough for my hobby. Sensors, devices to control, clocks to sync all aroung house. I had to move on - API mode, explicit addressing, frames parsing...

I, however, also spent some time recently studying some courses (mostly programming) on edx.org (this eats a lot of my time by the way). So I couldn't just get away with simple functional programming approach. I created many classes, I subclassed subclasses and have a pretty sofisticated class structure now in about 10 different python modules. Trying to get through all of this makes my head ake. However if you just look from a 'Main' program stand point, the whole thing is relatively easy and natural. Here how a blinking led example looks like:

def main():

    ## Create a coordinator. This is an XBee, connected to PC via comport
    ## 'COM4' is a comport to where XBee is connected
    ## 57600 is the comport speed
    ## "\x00\x13\xA2\x00\x40\x78\xFD\x76" is 64-bit address of the coordinator module
    ## 'coord' is a human-readable name
    coordinator = XBee24ZBCoordinator('COM4', 57600,
        "\x00\x13\xA2\x00\x40\x78\xFD\x76", 'coord')


    ##print "Hi, I'm Coordinator, my is hw #", coordinator.get_hwuid(),
    ##print 'and name is', coordinator.getName()

    ## Create a remote module. This is an XBee, hanging out somewhere in my house
    ## "\x00\x13\xA2\x00\x40\x78\xFD\x76" is 64-bit address of the module
    ## 'spalnya' is a human-readable name
    remote = XBee24ZBRemote('\x00\x13\xA2\x00\x40\x79\xB2\x71', 'spalnya')


    ##print "Hi, I'm a remote, my is hw #", remote.get_hwuid(),
    ##print 'and name is', remote.getName(), 'and address is', remote.getLongAddress()

    ## Now we are building the network topology
    ## We tell remote to connect to coordinator
    ## This tells remote where to send information and this
    ## also registers this remote with coordinator
    remote.connectToCoordinator(coordinator)

    ## Create a led
    led = LED()
    ## Connect led to remote, tell to which pin and in which mode
    ## remote.getPin('DO4') <- this is a pin on remote with name 'DO4'
    ## 'DO' is pin operation mode. Can be DO (digital out), DI (digital in),
    ## 'ADC' - analog input
    led.connectTo(remote.getPin('DO4'), 'DO')

    ## Tell led to turn on. Notice, after network topology is set (remote
    ## is connected to coordinator and the led is connected to a specific
    ## pin of the remote, we do not have to care about connections any more
    ## we just tell our led to switch on
    led.on()

    ## Digital input sensor (sempling LOW/HIGH level on an XBee pin)
    ## 'test' is a human readable name
    io = DI('test')

    ## connect this sensor to an XBee pin
    io.connectTo(remote.getPin('DI3'), 'DI')
    
    while True:
        ## Read pin
        io.read()
        try:
            ## switch on led
            led.on()
            sleep(2)
            ## switch off led
            led.off()
            sleep(2)
        except KeyboardInterrupt:
            break

    ## Halt XBee and close comport
    coordinator.halt()

Note, that we have to define topology first (like connectTo(coordinator)), but than I simply don't care HOW my led is connected to main server - via XBee, WiFi, TCP/IP, UART or else. I don't have to. I just tell the led to shine and it magically goes on. That's what I wanted to get and it seems I'll get that.

What I have now is a working prototype. I wouldn't been able to do even this without this great XBee library: http://code.google.com/p/python-xbee/


No comments: