Search code examples
telnetlib

Using telnetlib. How to make use of a response after writing a command


I am extremely new to Python and after several weeks of study and practice programming I have begun my home automation project.

My aim is to interact with a Java based service that runs on my Windows machine called C-Gate. This then interprets and communicates with the much more complicated commands sent & received by my Clipsal C-Bus automation system.

So far I have managed to create a connection to C-Gate using telnelib and write/read commands.

What I have been trying to figure out for some time now is how to use the responses given by C-Gate and extract a particular value such as the level of a light and turn it into a variable I can use.

From there I should be able to expand my understanding and begin building an interface to use/monitor these values.

Here is my code so far:

import telnetlib

HOST = "localhost"
PORT = "20023"


def read_until(cue, timeout=2):
    print tn.read_until(cue, timeout)


def tn_write(text):
    tn.write(text)


tn = telnetlib.Telnet(HOST, PORT)


tn_write('project load MYHOUSE\r\n')

read_until('200 OK.')

tn_write('project use MYHOUSE\r\n')

read_until('200 OK.')

tn_write('net open 254\r\n')

read_until('200 OK: //MYHOUSE/254')

tn_write('project start\r\n')

read_until('200 OK.')



tn_write('get 254/56/1 level\r\n')

tn_write('get 254/56/2 level\r\n')

tn_write('get 254/56/3 level\r\n')

tn_write('get 254/56/4 level\r\n')

tn_write('get 254/56/5 level\r\n')

tn_write('get 254/56/6 level\r\n')

tn_write('get 254/56/7 level\r\n')

tn_write('get 254/56/8 level\r\n')

read_until('300 //MYHOUSE/254/56/1: level=0\r\n')

This then prints the following responses:

201 Service ready: Clipsal C-Gate Version: v2.9.5 (build 2460) #cmd-syntax=1.0

200 OK.

200 OK.

200 OK: //MYHOUSE/254

200 OK.

300 //MYHOUSE/254/56/1: level=100

300 //MYHOUSE/254/56/2: level=0

300 //MYHOUSE/254/56/3: level=0

300 //MYHOUSE/254/56/4: level=0

300 //MYHOUSE/254/56/5: level=0

300 //MYHOUSE/254/56/6: level=0

300 //MYHOUSE/254/56/7: level=0

300 //MYHOUSE/254/56/8: level=0

Solution

  • You can perfirm this task in few ways but I would recommend using regular expression. First of all, telnet code should be modified a little bit:

    def read_until(cue, timeout=2):
        return tn.read_until(cue, timeout)
    
    telnetReturnedValue = read_until('200 OK: //MYHOUSE/254')
    

    Example code which would extract value of "level":

    import re
    rePattern = 'level=(\d+)'
    matchTuple = re.search(rePattern,telnetReturnedValue)
    if(matchTuple!=None):
        levelValue = matchTuple.groups()[0]
        print(levelValue)
    

    Re library documentation: http://docs.python.org/2/library/re.html .

    UPDATE: Answering more detailed whittie83's question, there are many ways to write this program. It is still about Python basics so I would recommend learning from at least some tutorial, for example: http://docs.python.org/2/tutorial/.

    Anyway, I would put regexp code into function like this:

    import re
    def parseTelnetOutput(output,rePattern='level=(\d+)'):
        print(output)
        matchTuple = re.search(rePattern,output)
        if(matchTuple!=None):
            someValue = matchTuple.groups()[0]
            return(someValue)
    
    #telnet functions definitions and telnet initiation 
    
    levelsList = []  #empty table for extracted levels
    
    #some telnet commands...
    tn_write('project load MYHOUSE\r\n')
    print(read_until('200 OK.'))#not parsing, only printing
    tn_write('net open 254\r\n')
    parseResult = parseTelnetOutput(read_until('200 OK: //MYHOUSE/254/56/1'))
    levelsList.append(parseResult)  # adding extracted level into a table
    tn_write('net open 254\r\n')
    parseResult = parseTelnetOutput(read_until('200 OK: //MYHOUSE/254/56/2'))
    levelsList.append(parseResult)  # adding extracted level into a table
    #etc...
    
    for pr in levelsList:  #iterating list of extracted levels
        print(pr)
    

    It is only a suggestion. You can merge 3 functions into 1, embed variables and functions into a class and so on. It is up to you.