Skip to main content

使用 enfora gsm 调制解调器发送和接收 SMS

项目描述

sms 包为 enfora gsm 调制解调器和可能的其他调制解调器提供了 sms 功能。

sms 包提供了 Modem 和 Message 类,用于发送和接收 sms 消息。

sms.server 模块提供了两个服务器,允许您发送传入的短信。sms.echo 模块是与 sms.server.subprocess_server 一起工作的示例。

用法

创建一个调制解调器对象,将串行设备 ID 传递给它。在 Windows 上,这类似于“COM1”。以下示例适用于 mac 和 linux:

>>> import sms
>>> m = sms.Modem('/dev/ttyS0')

如果您有多个调制解调器连接到不同的串行端口,您可以同时使用多个调制解调器对象。

出于本次测试的目的,我们将用一个虚拟的串行连接替换调制解调器上的真实串行连接,这样测试实际上不会发送 sms 消息。

>>> 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 终止的 sms 消息。

让我们通过硬编码连接以返回错误字符串来模拟发送错误。

>>> m.conn.response = ['ERROR']

现在让我们尝试发送消息。

>>> m.send('14161234567', 'This is a message')
回溯(最近一次通话最后):
...
调制解调器错误:['错误']

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()
>>> 长度(信息)
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'
>>> 消息[2].number
'+14161234567'
>>> 消息[2].date
datetime.datetime(2008, 7, 11, 13, 2, 11)
>>> 消息[2].text
'测试消息'

收到消息后,您需要将其从 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 方法采用可选的 timeout 参数。

出于此测试的目的,而不是实际阻塞,连接将打印它将阻塞多少秒。

>>> m.wait(1)
reading with 1 timeout
>>> m.wait()
reading with no timeout

等待消息不返回任何内容。您应该在 messages() 返回后调用该方法以接收消息。请注意,在等待方法返回后,实际上可能没有可用的消息。

消息解码

大多数情况下,您可以将 SMS 消息视为 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 函数将尽其所能将这些消息解码为 un​​icode。

>>> 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 的非重音脚本。

>>> sms.encoding.to_ascii(u'Montr\xe9al')
'Montreal'

不容易转成ascii的字符改成?。

>>> sms.encoding.to_ascii(u'\ufffd')
'?'

项目详情


下载文件

下载适用于您平台的文件。如果您不确定要选择哪个,请了解有关安装包的更多信息。

源分布

sms-0.4.tar.gz (8.9 kB 查看哈希)

已上传 source