跳转到主要内容

使用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 (8.9 kB 查看哈希)

上传时间

由以下赞助

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面