构建Flask和Python物联网服务器五部曲:设置、Web API、验证和时间戳记、添加数据库、代码上传
介绍
物联网(IoT)是由相互连接的计算机,电话,平板电脑和诸如恒温器,车库门开启器,灯泡,门铃摄像头,气象站之类的物理设备组成的网络。 当我们谈论Internet时,通常是指与网页,程序和应用程序通信的计算机,平板电脑,电话和服务器。 物联网通过包含除计算机,电话,平板电脑和服务器以外的设备在Internet上的构建。
物联网设备
我有两个基于ESP8266的WiFi气象站。 这些小设备是物联网的一部分。 小型的WiFi气象站每个花费约20美元,并且运行时电力很少。 气象站由ESP8266微控制器和通过跨接线和面包板连接的温度传感器组成。 基于ESP8266的WiFi气象站将温度测量结果传输到云中的服务器。 这些WiFi气象站是物联网设备。
物联网服务器
与物联网设备交互的服务器(如基于ESP8266的WiFi气象站)称为物联网服务器或IoT服务器。 物联网服务器与物联网设备通信。 在该项目开始时,基于ESP8266的WiFi气象站与ThingSpeak.com物联网服务器进行通信。 WiFi气象站将温度测量结果发送到保存数据的ThingSpeak.com IoT服务器。
物联网服务器需求
IoT服务器需要实现两个主要功能:
- 从两个基于ESP8266的WiFi气象站接收并存储温度测量值
- 将两个基于ESP8266的WiFi气象站测得的温度发布到网页中
项目步骤
使用flask和Python构建IoT服务器是一个多部分的问题。我们可以将问题分解为以下步骤:
- 设置
- 构建在云中运行的基于Flask的服务器(Digital Ocean)
- 组装WiFi气象站的硬件
- 使用flask和Python构造一个Web API,以接受来自Web浏览器的请求并保存数据点
- 将数据库添加到服务器以保存来自WiFi气象站的数据点
- 在基于ESP8266的WiFi气象站上上传代码,以使用服务器的Web API发送温度测量值
设置
在本文中,我们将描述项目中使用的服务器设置和微控制器硬件。
前提
服务器
- Digital Ocean云服务器(从现在开始仅称为服务器)
- 连接到服务器的域名
- PuTTY或可以SSH进入服务器的终端
- 服务器上的非root用户sudo用户
- 在服务器上安装了flask和uwsgi pip的Python 3.6虚拟环境
- uWSGI和NGINX安装在服务器上的配置上
- Flask应用程序作为系统服务运行
- 附加到域名和NGINX实例的SSL
硬件
以下是用于构建基于ESP8266的WiFi气象站的硬件列表。
起点
我构建的flask应用程序是相对基本的,主要包含2个文件:flaskapp.py和index.html。 Digital Ocean服务器上的文件结构如下所示:
生成的网页如下所示:
Web API
我们已经在Digital Ocean上托管了一个工作Flask应用程序。现在,我们需要将Web API添加到flask应用程序的功能中。
什么是web API
Web API是基于Web的应用程序编程接口。这是一种幻想的说法,即服务器根据服务器从Web浏览器接收的URL保存输入或生成输出。
Web API的一个示例是ThingSpeak.com Web API。当网络浏览器(例如chrome)定向到以下URL时:
https://api.thingspeak.com/channels/266256/fields/2/last.txt
响应是存储在ThingSpeak.com上的数据条目,其对应于:
- channel 266256
- field 2
- last entry
- .txt format
如果粘贴到Web浏览器中的URL不同,则ThingSpeak.com的响应也将不同。
https://api.thingspeak.com/channels/9/fields/1/last.json
对上述URL的响应是存储在ThingSpeak.com上的数据条目,其对应于:
- channel 9
- field 1
- last entry
- .json format
大多数Web API允许您从其服务器中提取数据,但是许多Web API也使您能够在其服务器上放置数据。
如果粘贴到Web浏览器中的URL的格式如下,ThingSpeak.com将存储一个新的数据点。
https://api.thingspeak.com/update?api_key=THECLASSAPIKEY&field1=87
ThingSpeak.com收到GET请求时存储的数据点为:
- user with an API Key = THECLASSAPIKEY
- field = 1
- data = 87
我们将使用flask构建的Web API需要完全满足ThingSpeak.com Web API实现的两个基本功能:
- 根据Flask IoT服务器接收的特定URL输出数据点
- 根据Flask IoT服务器接收的特定URL存储数据点
Web API设计
我们将在Flask IoT服务器Web API中模仿ThingSpeak.com Web API的一部分。 为了基于服务器接收的URL存储数据点,我们需要指定URL的结构。 我们基于ESP8266的WiFi气象站需要知道URL格式,才能将数据点发布到Flask IoT服务器上。
数据将基于服务器从基于ESP8266的WiFi气象站接收的URL存储在我们的Flask IoT服务器上。
每个基于ESP8266的WiFi气象站都有几个独特的方面:
- 用户:每个WiFi气象站都有一个用户。在这种情况下,用户就是我。
- mac地址:mac地址是分配给每个硬件的唯一地址。每个基于ESP8266的WiFi气象站都有一个不同的mac地址。
- 字段:基于ESP8266的WiFi气象站具有输出温度和湿度的功能。 现在,我们将要处理温度,但是最好为同一设备的多个数据流(例如温度和湿度)提供一个额外的字段。
- 数据:每个基于ESP8266的WiFi气象站的温度测量值。
如果我们将这4个标识符作为Web API URL的一部分,我们的IoT服务器将提供WiFi气象站所需的功能。
我们的Web API URL的一般形式如下:
https://mydomain.com/update/API_key=ASCIISTR/mac=6c:rf:7f:2b:0e:g8/field=1/data=72.3
在上面的网址中,我们提供了:
- update(告诉IoT服务器保存数据点,而不仅仅是提供网页)
- API_key=ASCIISTR(识别用户)
- mac=6c:rf:7f:2b:0e:g8(识别基于ESP8255的WiFi气象站)
- field=1(指定数据是温度,而不是湿度)
- data=72.3(指定温度为72.3度)
现在,当出现类似于我们上面指定的URL时,我们需要使Flask IoT服务器保存数据点。
构造一个Flask Web API
由于flask可以选择在路由中包含变量,因此在flask中构建Web API非常容易。通用语法如下:
在上面的代码中,路由"/update/key=<route_var>"中包含变量<route_var>。 大于/小于符号<>告诉flask路径中有一个变量。 在第二行中,变量route_var(来自@ app.route()行)作为参数传递给update()函数。 最后,update()函数返回一个名为index.html的模板。
建立新路由
建立新模板
测试Web API
验证和时间戳记
现在我们有了Web API,我们可以使用Web浏览器发出GET请求,并参阅Flask返回的网页中的输出。添加到由我们的Web API指定的URL中的任何字符串都可以通过。 我们不希望任何WiFi气象站都上传数据。 我们需要的是一些数据验证。
什么是数据验证
Web API是基于Web的应用程序编程接口。这是说服务器保存输入或根据某人在Web浏览器中键入的URL生成输出的一种奇特的方式。我们的Flask IoT Web服务器接受的示例URL是:
https://mydomain.com/update/API_key=ASCIISTR/mac=6c:rf:7f:2b:0e:g8/field=1/data=72.3
在上面的网址中,我们提供了:
- update(告诉IoT服务器保存数据点,而不仅仅是提供网页)
- API_key = ASCIISTR(识别用户)
- mac = 6c:rf:7f:2b:0e:g8(确定基于ESP8255的WiFi气象站)
- field = 1(指定这是温度数据点,而不是湿度数据点)
- data = 72.3(指定温度为72.3度)
现在,可以将API_key =和mac =之后的任何字符串插入URL。 这允许具有Internet连接的任何人将数据上传到服务器,并可能将恶意代码上传到服务器。 由于可以将任意字符串作为API_key或mac插入,因此我们的flask IoT服务器将读取该任意字符串。
为了在我们的服务器中增加一点安全性,我们将使用一种数据验证形式。这意味着我们的Flask IoT服务器将仅接受某些API_key =和mac =字符串作为Web API URL的一部分。
验证传入的URL
进入我们的物联网服务器的数据仅来自基于ESP8266的WiFi气象站的两个特定数据。每个基于ESP8266的WiFi气象站都有几个独特的方面。
- 用户:每个WiFi气象站都有一个用户。在这种情况下,用户就是我。我可以设置一个只有我知道的唯一API密钥。
- Mac地址:Mac地址是分配给每个硬件的唯一地址。每个基于ESP8266的WiFi气象站都有一个不同的mac地址。
- 字段:基于ESP8266的WiFi气象站具有输出温度和湿度的功能。 现在,我们将要处理温度,但是很高兴有一个额外的字段可用于来自同一设备的多个数据输出。 一台设备可以发送的字段数将受到限制。 我们将字段限制为1-9
- 数据:每个基于ESP8266的WiFi气象站的温度数据。这是一个浮点数,但可以受长度限制。
添加时间戳
我们的Web API接受数据点,但是很高兴看到温度测量的时间戳。通过将时间戳记连接到每个数据点,我们可以显示带有温度和测量时间的网页。
重新启动flask应用程序并查看更改
现在,我们可以重新启动flask应用程序,并查看修改后的Web API是否有效。 我们想测试一下,当输入无效的URL时是否呈现403.html模板。 我们还希望看到使用有效URL时showrecent.html呈现的时间戳。
添加数据库
我们可以通过以下两种方式存储来自基于ESP8266的WiFi气象站的温度数据:
- 将数据保存在文本文件中。为每个新数据点在文本文件中添加一行。
- 将数据保存在.csv文件中。为每个数据点添加新行,并在每行上用逗号或制表符分隔字段。
- 将数据保存在pandas数据框中。将每个数据点存储为数据框中的一行。
- 使用数据库存储数据。每个数据点均作为记录保存在数据库中。
在上述四个选项中,我决定使用sqlite3数据库存储来自Flask IoT服务器Web API的数据。
数据库设计
将代码上传到基于ESP8266的WiFi气象站
详情参阅 - 亚图跨际