【问题标题】:Using telnetlib. How to make use of a response after writing a command使用 telnetlib。编写命令后如何使用响应
【发布时间】:2013-05-26 04:48:29
【问题描述】:

我对 Python 非常陌生,经过几周的学习和实践编程,我已经开始了我的家庭自动化项目。

我的目标是与在我的 Windows 机器上运行的名为 C-Gate 的基于 Java 的服务进行交互。然后,它会解释并与我的 Clipsal C-Bus 自动化系统发送和接收的更复杂的命令进行通信。

到目前为止,我已经成功地使用 telnelib 和写入/读取命令创建了与 C-Gate 的连接。

我现在一直试图弄清楚的是如何使用 C-Gate 给出的响应,并提取一个特定的值,例如光的级别,并将其转换为我可以使用的变量。

从那里我应该能够扩展我的理解并开始构建一个界面来使用/监控这些值。

到目前为止,这是我的代码:

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')

然后打印以下响应:

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

【问题讨论】:

    标签: telnetlib


    【解决方案1】:

    您可以通过几种方式执行此任务,但我建议使用正则表达式。首先要稍微修改一下telnet代码:

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

    提取“级别”值的示例代码:

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

    重新库文档:http://docs.python.org/2/library/re.html.

    更新: 回答更详细的 whittie83 的问题,有很多方法可以编写这个程序。它仍然是关于 Python 基础的,所以我建议至少从一些教程中学习,例如:http://docs.python.org/2/tutorial/

    无论如何,我会将正则表达式代码放入这样的函数中:

    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)
    

    这只是一个建议。您可以将 3 个函数合并为 1 个,将变量和函数嵌入到一个类中等等。它是由你决定。

    【讨论】:

    • 谢谢马尔辛。实际上,我刚刚开始使用 re 模块作为解决方案。
    • 我现在最大的问题是如何分解这些功能?所以他们 a) 按顺序完成,就像我需要运行前四个 tn_write 命令并在我询问级别之前初始化服务器。然后 b) 以不同的方式处理响应,因为我很高兴仅测试并查看前四个的整个响应,但正如您的代码所证明的那样,我需要从下一批命令中提取级别。
    • 我已经更新了我的答案并添加了更多代码。我希望它能回答你的问题。
    • 谢谢马尔辛。这是一个巨大的帮助。就像你说的那样,我确实需要学习一些东西才能让我真正理解它,但它给了我在这门语言中进步的基石。感谢您的时间和耐心。我还有很多东西要学。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-06
    • 2015-11-26
    • 1970-01-01
    • 2014-07-16
    • 2011-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多