使用enfora gsm调制解调器发送和接收短信
项目描述
sms包为enfora gsm调制解调器提供了短信功能,可能还有其他。
sms包提供了Modem和Message类,用于发送和接收短信消息。
sms.server模块提供了两个服务器,允许您调度传入的短信消息。sms.echo模块是与sms.server.subprocess_server一起工作的示例。
用法
通过传递串行设备ID创建调制解调器对象。在Windows上,这将是类似于‘COM1’的东西。下面的示例是针对mac和linux的
>>> import sms >>> m = sms.Modem('/dev/ttyS0')
如果您连接了多个串行端口的不同调制解调器,则可以同时使用多个调制解调器对象。
为了测试目的,我们将用模拟的串行连接替换调制解调器上的实际串行连接,以便测试实际上不会发送短信消息。
>>> m.conn = DummyConnection()
模拟连接将简单地保存发送的AT命令列表,而不是实际将它们发送到调制解调器。
要发送短信消息,请调用send方法,传递电话号码字符串和消息字符串。
>>> m.send('14161234567', 'This is a message')
让我们看看发送了哪些AT命令。
>>> m.conn.sent() 'AT+CMGS="14161234567"\r\nThis is a message\x1a'
发送了AT+CMGS命令,后面跟有以ctrl-z结尾的短信消息。
让我们通过将连接硬编码为返回错误字符串来模拟发送错误。
>>> m.conn.response = ['ERROR']
现在让我们尝试发送消息。
>>> m.send('14161234567', 'This is a message') Traceback (most recent call last): ... ModemError: ['ERROR']
抛出一个包含错误消息的ModemError。
让我们恢复正常的连接响应。
>>> m.conn.response = []
您可以使用messages()方法接收短信消息。它返回所有已接收消息的列表。
>>> m.messages() []
到目前为止,没有收到任何消息。让我们看看调制解调器如何请求消息。
>>> m.conn.reset() >>> m.messages() [] >>> m.conn.sent() 'AT+CMGL="ALL"\r\n'
AT+CMGL消息指示调制解调器列出存储的消息。让我们模拟对这一命令的典型响应。
>>> m.conn.response = ['\r\n', '+CMGL: 1,"REC UNREAD","+16476186676",,"08/07/11,11:02:11+00"\r\n', 'Activation code 63966 Go 2 www.ipipi.com and signin with your username and pwd, enter 63966 to activate your mobile/account\r\n', '\r\n', '\r\n', 'Welcome 2 ipipi.com\r\n', 'OK\r\n']
现在我们再试一次。
>>> msgs = m.messages() >>> msgs [<sms.Message object at 0x...>]
消息对象有几个属性:号码、日期和文本。
>>> msgs[0].number '+16476186676'>>> msgs[0].date datetime.datetime(2008, 7, 11, 11, 2, 11)>>> msgs[0].text 'Activation code 63966 Go 2 www.ipipi.com and signin with your username and pwd, enter 63966 to activate your mobile/account\n\nWelcome 2 ipipi.com'
让我们通过一个更复杂的例子来确保我们可以处理不同类型的消息。
>>> m.conn.response = ['\r\n', '+CMGL: 1,"REC READ","+16476186676",,"08/07/11,11:02:11+00"\r\n', 'Activation code 63966 Go 2 www.ipipi.com and signin with your username and pwd, enter 63966 to activate your mobile/account\r\n', '\r\n', '\r\n', 'Welcome 2 ipipi.com\r\n', '+CMGL: 2,"STO UNSENT","14166243508",,\r\n', 'Out over the fields,\r\n', '\n', 'attached to nothing,\r\n', '\n', 'a skylark sings\r\n', '\r\n', '+CMGL: 3,"REC READ","+14161234567","Example Name","08/07/11,13:02:11+00"\r\n', 'Test message\r\n','OK\r\n']>>> msgs = m.messages() >>> len(msgs) 3 >>> msgs[0].number '+16476186676' >>> msgs[0].date datetime.datetime(2008, 7, 11, 11, 2, 11) >>> msgs[0].text 'Activation code 63966 Go 2 www.ipipi.com and signin with your username and pwd, enter 63966 to activate your mobile/account\n\nWelcome 2 ipipi.com' >>> msgs[2].number '+14161234567' >>> msgs[2].date datetime.datetime(2008, 7, 11, 13, 2, 11) >>> msgs[2].text 'Test message'
收到消息后,您可能希望从SIM卡中删除它们。这是通过在消息上调用delete方法来完成的。
>>> msgs[0].delete()
让我们通过查看在删除消息时发送给调制解调器的AT命令来测试这一点。
>>> m.conn.reset() >>> msgs[0].delete() >>> m.conn.sent() 'AT+CMGD=1\r\n'>>> m.conn.reset() >>> msgs[1].delete() >>> m.conn.sent() 'AT+CMGD=2\r\n'
您可以通过调用wait()方法而不是轮询调制解调器来查找消息,该方法会阻塞,直到接收到消息。wait方法接受一个可选的超时参数。
为了本测试的目的,而不是真正阻塞,连接将打印出将阻塞多少秒。
>>> m.wait(1) reading with 1 timeout>>> m.wait() reading with no timeout
wait消息不返回任何内容。在它返回后,您应该调用messages()方法来接收消息。请注意,wait方法返回后可能实际上没有可用的消息。
消息解码
大多数时候,您可以将短信消息视为ASCII字符串。然而,它们应该在GMS 03.38 7位编码中。我在实践中从未见过这种情况。
我见过Unicode消息。它们被编码为一系列的十六进制数字,如下所示
>>> text = "004500200074006500730074002000E800E9002000C800C90020006100200074006500730074002000C000C1002000E000E1"
有一个函数可以解码这些消息。
>>> import sms.encoding >>> sms.encoding.decode_unicode(text) u'E test \xe8\xe9 \xc8\xc9 a test \xc0\xc1 \xe0\xe1'
如果您尝试向它提供看起来不是Unicode消息的文本,它将失败。
>>> sms.encoding.decode_unicode('not a unicode message') Traceback (most recent call last): ... ValueError: Message is not unicode
我还观察到带重音的字符与ASCII字符混合。带重音的字符是大于127的值。我不知道它们的编码方式是什么,但我已经反向工程了它,并且它对我有效。
以下是一个例子
>>> text = "Montr\x82al"
decode_accents函数将尽可能将这些消息解码为Unicode。
>>> sms.encoding.decode_accents(text) u'Montr\xe9al'
decode_accents函数不会因未知字符而失败。它只是用Unicode替换字符替换它们。
>>> sms.encoding.decode_accents('what is this \xff') u'what is this \ufffd'
还有一个方便的to_ascii函数,可以将Unicode转换为ASCII。它使用Fredrick Lundh的unaccent脚本。
>>> sms.encoding.to_ascii(u'Montr\xe9al') 'Montreal'
无法轻易转换为ASCII的字符将更改为?。
>>> sms.encoding.to_ascii(u'\ufffd') '?'
项目详情
sms-0.4.tar.gz的哈希
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 0da1a5e4cd673b58198f932685a5a1e2f330a22f91790ff0ee70c9b940f4cde7 |
|
MD5 | 074fba15815741579b8be4a47681c697 |
|
BLAKE2b-256 | 91eacadc987bb2e74df153349df84dac2ba34d2752fb943e6660430061dab2f9 |