Python 物联网入门指南(五)(3)https://developer.aliyun.com/article/1507235
在新的浏览器窗口中打开前面截图中列出的 URL。它提供了POST
请求的 URL 以及如何进行 web 请求的解释(如下截图所示):
使用之前提到的 URL 进行 POST 请求(为了隐私而隐藏密钥)
- 在发出请求时(如 IFTTT 文档中所述),如果我们在请求的 JSON 主体中包括自行车的数量(使用
Value1
),它可以显示在移动通知上。 - 让我们重新查看 Python 示例,当自行车数量低于一定阈值时进行网络请求。将
IFTTT
URL 和您的 IFTTT 访问密钥(从您的 IFTTT 帐户中检索)保存到您的代码中,如下所示:
IFTTT_URL = "https://maker.ifttt.com/trigger/mobile_notify/ with/key/$KEY"
- 当自行车数量低于一定阈值时,我们需要使用 JSON 主体中编码的自行车信息进行
POST
请求:
for station in station_list: if station['id'] == 65 and station['availableBikes'] < 3: print("The available bikes is %d" % station['availableBikes']) payload = {"value1": station['availableBikes']} response = requests.post(IFTTT_URL, json=payload) if response.status_code == 200: print("Notification successfully triggered")
- 在上述代码片段中,如果自行车少于三辆,将使用
requests
模块进行POST
请求。可用自行车的数量使用键value1
进行编码:
payload = {"value1": station['availableBikes']}
- 将所有这些放在一起,我们有这个:
#!/usr/bin/python3 import requests import datetime BIKE_URL = "http://feeds.bayareabikeshare.com/stations/ stations.json" # find your key from ifttt IFTTT_URL = "https://maker.ifttt.com/trigger/mobile_notify/ with/key/$KEY" if __name__ == "__main__": # fetch the bike share information response = requests.get(BIKE_URL) parsed_data = response.json() station_list = parsed_data['stationBeanList'] for station in station_list: if station['id'] == 65 and station['availableBikes'] < 10: print("The available bikes is %d" % station ['availableBikes']) payload = {"value1": station['availableBikes']} response = requests.post(IFTTT_URL, json=payload) if response.status_code == 200: print("Notification successfully triggered")
上述代码示例可与本章一起下载,名称为bike_share.py
。在设置 IFTTT 上的配方后尝试执行它。如果需要,调整可用自行车数量的阈值。您应该会收到移动设备上的通知:
在您的移动设备上通知
读者的挑战
在此示例中,自行车信息被获取和解析,如果必要,将触发通知。您将如何修改此代码示例以确保它在一天中的特定时间执行?(提示:使用datetime
模块)。
您将如何构建一个作为视觉辅助的桌面显示?
项目挑战
尝试找出您所在地区的交通系统是否向其用户提供此类数据。您将如何利用数据帮助通勤者节省时间?例如,您将如何使用此类数据向您的朋友/同事提供交通系统建议?
完成书后,我们将发布一个类似的示例,使用旧金山湾区快速交通(BART)的数据。
提高你的词汇量
使用 Python 可以提高您的词汇量!想象一下设置一个大型显示屏,它显眼地安装在某个地方,并且每天更新。我们将使用wordnik
API(在www.wordnik.com/signup
注册 API 密钥)。
- 第一步是为 python3 安装
wordnik
API 客户端:
git clone https://github.com/wordnik/wordnik-python3.git cd wordnik-python3/ sudo python3 setup.py install
wordnik API 有使用限制。有关更多详细信息,请参阅 API 文档。
- 让我们回顾一下使用
wordnik
Python 客户端编写我们的第一个示例。为了获取当天的单词,我们需要初始化WordsApi
类。根据 API 文档,可以这样做:
# sign up for an API key API_KEY = 'API_KEY' apiUrl = 'http://api.wordnik.com/v4' client = swagger.ApiClient(API_KEY, apiUrl) wordsApi = WordsApi.WordsApi(client)
- 现在
WordsApi
类已初始化,让我们继续获取当天的单词:
example = wordsApi.getWordOfTheDay()
- 这将返回一个
WordOfTheDay
对象。根据wordnik
Python 客户端文档,该对象包括不同的参数,包括单词、其同义词、来源、用法等。当天的单词及其同义词可以打印如下:
print("The word of the day is %s" % example.word) print("The definition is %s" %example.definitions[0].text)
- 将所有这些放在一起,我们有这个:
#!/usr/bin/python3 from wordnik import * # sign up for an API key API_KEY = 'API_KEY' apiUrl = 'http://api.wordnik.com/v4' if __name__ == "__main__": client = swagger.ApiClient(API_KEY, apiUrl) wordsApi = WordsApi.WordsApi(client) example = wordsApi.getWordOfTheDay() print("The word of the day is %s" % example.word) print("The definition is %s" %example.definitions[0].text)
上述代码片段可与本章一起下载,名称为wordOfTheDay.py
。注册 API 密钥,您应该能够检索当天的单词:
The word of the day is transpare The definition is To be, or cause to be, transparent; to appear, or cause to appear, or be seen, through something.
读者的挑战
您将如何将此应用程序守护程序化,以便每天更新当天的单词?(提示:cronjob 或datetime
)。
项目挑战
可以使用wordnik
API 构建一个单词游戏。想想一个既有趣又有助于提高词汇量的单词游戏。您将如何构建一个提示玩家并接受答案输入的东西?
尝试在显示器上显示当天的单词。您将如何实现这一点?
日志记录
日志(docs.python.org/3/library/logging.html
)有助于解决问题。它通过跟踪应用程序记录的事件序列来确定问题的根本原因。让我们通过一个简单的应用程序来回顾日志。为了回顾日志,让我们通过发出一个POST
请求来回顾它:
- 日志的第一步是设置日志文件位置和日志级别:
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', filename='log_file.log', level=logging.INFO)
在初始化logging
类时,我们需要指定日志信息、错误等的格式到文件中。在这种情况下,格式如下:
format='%(asctime)s : %(levelname)s : %(message)s'
日志消息的格式如下:
2016-10-25 20:28:07,940 : INFO : Starting new HTTPS connection (1): maker.ifttt.com
日志消息保存在名为log_file.log
的文件中。
日志级别确定我们应用程序所需的日志级别。不同的日志级别包括DEBUG
、INFO
、WARN
和ERROR
。
在这个例子中,我们将日志级别设置为INFO
。因此,属于INFO
、WARNING
或ERROR
级别的任何日志消息都将保存到文件中。
如果日志级别设置为ERROR
,则只有这些日志消息会保存到文件中。
- 让我们根据
POST
请求的结果记录一条消息:
response = requests.post(IFTTT_URL, json=payload) if response.status_code == 200: logging.info("Notification successfully triggered") else: logging.error("POST request failed")
- 将所有这些放在一起,我们有:
#!/usr/bin/python3 import requests import logging # find your key from ifttt IFTTT_URL = "https://maker.ifttt.com/trigger/rf_trigger/ with/key/$key" if __name__ == "__main__": # fetch the bike share information logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', filename='log_file.log', level=logging.INFO) payload = {"value1": "Sample_1", "value2": "Sample_2"} response = requests.post(IFTTT_URL, json=payload) if response.status_code == 200: logging.info("Notification successfully triggered") else: logging.error("POST request failed")
前面的代码示例(logging_example.py
)可与本章一起下载。这是 Python 中日志概念的一个非常简单的介绍。
Python 中的线程
在本节中,我们将讨论 Python 中的线程概念。线程使得能够同时运行多个进程成为可能。例如,我们可以在监听传感器的同时运行电机。让我们通过一个例子来演示这一点。
我们将模拟一个情况,我们希望处理相同类型传感器的事件。在这个例子中,我们只是打印一些内容到屏幕上。我们需要定义一个函数来监听每个传感器的事件:
def sensor_processing(string): for num in range(5): time.sleep(5) print("%s: Iteration: %d" %(string, num))
我们可以利用前面的函数同时使用 Python 中的threading
模块监听三个不同传感器的事件:
thread_1 = threading.Thread(target=sensor_processing, args=("Sensor 1",)) thread_1.start() thread_2 = threading.Thread(target=sensor_processing, args=("Sensor 2",)) thread_2.start() thread_3 = threading.Thread(target=sensor_processing, args=("Sensor 3",)) thread_3.start()
将所有这些放在一起,我们有:
import threading import time def sensor_processing(string): for num in range(5): time.sleep(5) print("%s: Iteration: %d" %(string, num)) if __name__ == '__main__': thread_1 = threading.Thread(target=sensor_processing, args=("Sensor 1",)) thread_1.start() thread_2 = threading.Thread(target=sensor_processing, args=("Sensor 2",)) thread_2.start() thread_3 = threading.Thread(target=sensor_processing, args=("Sensor 3",)) thread_3.start()
前面的代码示例(可作为threading_example.py
下载)启动三个线程,同时监听来自三个传感器的事件。输出看起来像这样:
Thread 1: Iteration: 0 Thread 2: Iteration: 0 Thread 3: Iteration: 0 Thread 2: Iteration: 1 Thread 1: Iteration: 1 Thread 3: Iteration: 1 Thread 2: Iteration: 2 Thread 1: Iteration: 2 Thread 3: Iteration: 2 Thread 1: Iteration: 3 Thread 2: Iteration: 3 Thread 3: Iteration: 3 Thread 1: Iteration: 4 Thread 2: Iteration: 4 Thread 3: Iteration: 4
Python 的 PEP8 样式指南
PEP8是 Python 的样式指南,它帮助程序员编写可读的代码。遵循某些约定以使我们的代码可读是很重要的。一些编码约定的例子包括以下内容:
- 内联注释应以
#
开头,后面跟着一个空格。 - 变量应该遵循以下约定:
first_var
。 - 避免每行末尾的空格。例如,
if name == "test":
后面不应该有空格。
你可以在www.python.org/dev/peps/pep-0008/#block-comments
阅读完整的 PEP8 标准。
验证 PEP8 指南
有工具可以验证您的代码是否符合 PEP8 标准。编写代码示例后,请确保您的代码符合 PEP8 标准。可以使用pep8
包来实现。
pip3 install pep8
让我们检查我们的代码示例是否符合 PEP8 规范。可以按照以下步骤进行:
pep8 opencv_test.py
检查指出了以下错误:
opencv_test.py:5:50: E231 missing whitespace after ',' opencv_test.py:6:19: E231 missing whitespace after ','
根据输出结果,以下行缺少逗号后的空格,分别是第5
行和第6
行:
逗号后缺少尾随空格
让我们修复这个问题,并且我们的代码应该遵循 PEP8 规范。重新检查文件,错误将会消失。为了使你的代码可读,总是在将代码提交到公共存储库之前运行 PEP8 检查。
总结
在这一章中,我们讨论了 Python 中的高级主题。我们讨论了包括语音识别、构建通勤信息工具以及改善词汇量的 Python 客户端在内的主题。Python 中有许多在数据科学、人工智能等领域广泛使用的高级工具。我们希望本章讨论的主题是学习这些工具的第一步。