大家好,又见面了,我是你们的朋友全栈君。
大家好,我是机灵鹤。
最近研究开发了一个物联网 IoT
小项目——久坐提醒 / 喝水提醒小助手。
1. 项目介绍
本项目实现了一个久坐提醒和喝水提醒的小助手,在检测到连续工作较长时间之后,会打印纸条,提醒我们起身活动一下;在设定的喝水时间到了以后,也会打印纸条,提醒我们去喝水。
废话不多说,先上图。
项目用到的硬件设备有:
- 树莓派4B(作为网关设备来接入涂鸦 IoT 生态)
- 咕咕机G2(迷你热敏打印机)
- 人体红外传感器
- 无线智能 Zigbee 网关
事情是这样的,过几天就是跟女朋友的恋爱纪念日了,作为一名程序员,送什么礼物才能既有创意又有诚意,既实用又能让女朋友感受到我满满的爱呢?
我突然想到,前段时间女朋友公司年度体检,检查结果出来有好几项飘黄,医生给的建议是,多喝水!多运动!女朋友虽然不是程序员,但也是那种长期坐办公室的工作,有时候忙起来连水都会忘记喝。
于是我想,何不利用我的专业技能,开发一个 ”久坐提醒“ 和 ”喝水提醒“ 小助手送给女朋友呢。
2. 方案设计
为了完成这个项目,我翻箱倒柜找出来几个,若干年前买的压箱底的电子产品。
- 咕咕机G2:一台迷你的热敏打印机,之前做手帐时候买来打印图案的,后来发现时间长了会褪色,于是就用来打印便条来背单词,后来四六级过了以后,咕咕机就闲置了。
- 树莓派4B:之前买了用来搭个人网站服务器的,结果发现没有公网 IP ,外网访问贼麻烦,而且有时候家里停电断网什么的,服务器动不动就失联了。后来买了云服务器以后,树莓派就渐渐闲置了。
- 人体红外传感器:上学时候偷偷放教室门口,检测老师有没有来的,毕业以后不需要跟老师斗智斗勇了,就慢慢闲置了(PS:由于之前那个传感器闲置太久坏了,本项目开发时重新采购的涂鸦智能的传感器)。
我的设想是:
- 喝水提醒:创建几个喝水闹钟,喝水时间一到,咕咕机便会自动打印便条,提醒女朋友该去喝水了。
- 久坐提醒:将人体红外传感器放置在桌上正对座椅,当检测到女朋友坐着持续时间超过半小时,便触发久坐提醒,通知咕咕机打印便条,提醒女朋友该起来活动活动了。
硬件都备的差不多了,在开发时我遇到了一个比较棘手的问题,就是咕咕机跟人体传感器它也不是同一家的设备啊!
虽然两家都有各自的控制 APP,但是它们毕竟是两套系统,两个平台,没法儿联动啊!
这时候我发现一个很牛的东西,涂鸦的 Link SDK ,号称 适用于涂鸦现有产品方案外的设备接入
。
按它的说法,所有涂鸦 IoT 生态以外的智能设备,只要是支持二次开发,理论上都可以通过这套 Link SDK
接入到涂鸦的生态中。那这就厉害了!这就意味着,我可以通过 Link SDK
把咕咕机和传感器接入到同一套系统中,实现联动了。
经过一番研究,本项目的方案设计示意图如下:
在树莓派中运行涂鸦的 Link SDK,一方面,树莓派作为一个网关设备接入到涂鸦云中,与涂鸦云中的其他设备进行通信;另一方面,树莓派通过调用咕咕机的 memobird API
,与咕咕机进行通信。
3. 开发流程
开发过程大概分为 4 个阶段:
- 创建产品:在涂鸦云平台创建产品,包括配置功能点,开发操作面板,下载 SDK 及获取授权码,在线调试等环节。
- 硬件开发:下载 Link SDK,编写代码并运行在树莓派中,将树莓派作为一个 IoT 设备接入到涂鸦云上。
- 咕咕机开发:根据咕咕机开发文档,开发并封装好相关接口,在树莓派上可以调用接口实现咕咕机设备绑定和纸条打印等功能。
- 智能联动:通过设定智能场景和联动条件,完成咕咕机与人体红外传感器之间的智能联动。
接下来正式进入开发阶段。
3.1 创建产品
3.1.1 注册开发者账号
首先,需要在涂鸦智能平台(https://t.tuya.com/AY1D3R8rbM)注册开发者账号。
注册完成后,进入 IoT 平台主页
3.1.2 创建智能产品
点击 IoT 平台主页的 创建产品
按钮,开始创建我们的智能产品。
第一步,选择我们要创建的产品类型,由于我们要接入的硬件设备是树莓派 咕咕机,不在涂鸦现有产品品类之中,所以点击 找不到品类?
按钮。
第二步,填写产品信息,根据自己项目的实际情况填写产品信息,填写完成后,点击创建产品。
3.1.3 功能定义
创建好产品之后,我们需要为产品添加 功能定义
。
什么意思呢?说白了就是为云平台和设备之间制定通信协议的,约定好哪条协议对应哪个功能,数据格式如何如何之类的。
标准功能是为了涂鸦生态内的设备开发时提供的快捷模板,我们这里用不到,需要使用自定义功能。
点击新建自定义功能,创建我们的喝水提醒功能。
- DP_ID 时功能的编号,前 100 的编号被系统保留,我们的可以使用 101 往后的编号。
- 数据类型有六种,具体的区别参考文档:https://developer.tuya.com/cn/docs/iot/custom-functions?id=K937y38137c64
- 数据传输类型,上报是指设备向云平台发送消息,下发是指云平台发送指令。
3.1.4 面板开发
设置好功能定义后,进入设备面板界面,开发 APP 交互的面板。
编辑器左侧提供了很多组件,可以通过拖拽的方式来编辑面板布局,并在右侧属性页签中,通过添加交互,来为当前选中的组件添加交互动作。
详细使用方法参考:https://developer.tuya.com/cn/docs/iot/panel?id=K9hzyyk6g4p3m
如图,我们添加一个按钮,在按钮属性中,添加交互,触发 喝水提醒
功能 。这样我们点击按钮时,就会向设备发送一条 喝水提醒
的消息。
编辑好以后,点击右上角 预览
按钮,然后用 涂鸦智能
APP 扫描二维码,可以在手机上实时预览(预览模式下,编辑器中做的修改,手机APP中会同步变化)。
APP 可以在各大应用商店下载到,搜 涂鸦智能
即可。
预览测试没问题的话,可以点击发布。
经过一段时间的打包后,打包成功,我们直接点击 去发布
,然后选择 发布并应用
即可。
3.1.5 硬件开发
在硬件开发页面,云端接入方式选择 Link SDK
,云端接入硬件选择 通用CPU
。
我们将自己的设备接入涂鸦云的话,第一需要 Link SDK , 第二需要购买 授权码
。
Link SDK
在开发资料中可以下载,授权码需要购买(10元/个)。
不过平台给每个开发者提供了两个调试用的云端授权码,可以免费领取(领取按钮在 立即购买
按钮下方,我因为领取过了所以截图里没有显示)。
领取成功以后,点击 下载授权码清单
按钮即可下载。授权码清单中包含了 uuid 和 key,如下所示:
uuid | key |
---|---|
tuyaf5753924f3d94306 | 5TbgqpGXzbgrr8Plb8L93rBy38Liu7ok |
3.1.6 产品配置
产品配置中,可以为设备添加一些如多语言,消息推送,配网引导的功能,因为本项目中暂时用不到,可以跳过。
3.1.7 设备调试
然后是设备调试,由于我们的树莓派 Link SDK 还没有开发到位,所以先添加一个虚拟调试设备,来进行调试。
手机应用商店里,下载安装 涂鸦智能
APP,然后用 APP 扫描上面的二维码,可以添加一个虚拟设备,用于调试。
添加好虚拟设备后,点击调试按钮,进入调试界面。然后可以使用这里的虚拟设备跟手机 APP 端进行通信。
通过这个,我们可以看到上报数据和下发数据是否正确(主要用来验证 3.1.4 节
开发的面板功能是否正确)。
消息协议调试无误后,开始开发我们的设备
3.2 硬件开发
产品创建成功,且 APP 端调试无误后,我们正式请出我们的主角,树莓派,来进行基于 Link SDK 的硬件开发。
3.2.1 运行环境
树莓派上烧录好 Raspberry Pi OS
系统,并且安装好 Python3.6
环境。
烧录系统的过程略去不讲,大家没有树莓派的话,也可以用自己电脑,或者虚拟机来替代。
3.2.2 安装源码
首先下载 Link SDK ,平台上默认提供的是 c 语言版本。
下载地址:https://github.com/tuya/tuya-iot-link-sdk-embedded-c
我比较常用 Python,所以找的是 Python 版本(支持 Python 3.6 )。
下载地址:https://github.com/tuya/tuyaos-link-sdk-python
安装方法:
- 通过
Pypi
安装
python3 -m pip install tuyalinksdk
- 通过源码安装
git clone https://github.com/tuya/tuyaos-link-sdk-python.git
python3 -m pip install ./tuyaos-link-sdk-python
3.2.3 代码编写
在项目路径中,创建一个 demo.py
脚本,脚本内容如下:
#!/usr/bin/env python
import time
from tuyalinksdk.client import TuyaClient
from tuyalinksdk.console_qrcode import qrcode_generate
# 这里更换成自己的ID
PID = "jj9hhmjxsf8u2b94"
UUID = "tuyaf5753924f3d94306"
AUTHKEY = "5TbgqpGXzbgrr8Plb8L93rBy38Liu7ok"
client = TuyaClient(productid = PID, uuid = UUID, authkey = AUTHKEY)
def on_connected():
print('Connected.')
def on_qrcode(url):
qrcode_generate(url)
def on_reset(data):
print('Reset:', data)
def on_dps(dps):
print('DataPoints:', dps)
client.push_dps(dps)
client.on_connected = on_connected
client.on_qrcode = on_qrcode
client.on_reset = on_reset
client.on_dps = on_dps
client.connect()
client.loop_start()
while True:
time.sleep(1)
代码中第 7-9 行的 3 个参数,PID
,UUID
,AUTHKEY
需要替换成你自己的产品的值。
PID
,即 productid
产品 ID, 可以在 我的产品
列表里查看 产品ID
,如图所示。
UUID
和 AUTHKEY
为设备的授权码,在前面 3.1.5 硬件开发
部分,下载的免费授权码的文件中可以查看,分别对应 UUID
和 KEY
两列。
3.2.4 真机运行
代码写好以后,在树莓派中使用终端,执行 python3 demo.py
命令启动程序。
程序运行后,会弹出一个二维码,用 涂鸦智能 APP
扫码以后,即可添加设备。
在代码中, on_dps
函数负责接收和处理 APP 端下发的指令,我们只需要根据指令的值,触发不同的操作即可。
如,接收到 {"101": "True"}
时,执行 喝水提醒
的行为,示例代码如下:
DRINK_DP_ID = "101"
def on_dps(dps):
print('DataPoints:', dps)
client.push_dps(dps)
for key in dps:
if key == DRINK_DP_ID and dps[key] == True:
# TODO: 喝水提醒
pass
3.3 咕咕机接入
咕咕机是一款迷你的热敏打印机,可以方便的打印文字和图片,而且官网的开发者平台上开放了它的 API ,可玩性非常高。
3.3.1 注册开发者账号
首先需要在 Memobird
开放平台注册账号,并申请成为咕咕机开发者。
Memobird 开放平台线上地址:https://open.memobird.cn/
注册好账号,填写好自己的 咕咕号
,联系方式
,用途
等信息之后,提交审核就可以了。
一段时间,审核通过后,会向注册账号的邮箱发送一封邮件,包含申请到的 Access_Key
。
开发文档:https://open.memobird.cn/upload/webapi.pdf
3.3.2 绑定设备
示例代码:
代码语言:javascript复制import requests
import datetime
# 绑定设备的API
BIND_DEVICE_API = "http://open.memobird.cn/home/setuserbind"
# 开发者 Access_Key
Access_Key = "261ba***************9274a"
# 咕咕机设备编号,双击咕咕机吐出来的设备编号
MEMOBIRD_ID = "301*********fe69"
# 用户自定义字符串,与咕咕平台进行关联的用户唯一标识符
USER_IDENTIFYING = "smartcrane"
# 获取时间戳
def getTimeStamp():
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
return timestamp
# 绑定设备,获取用户ID
def getUserID():
params = {
"ak" : Access_Key,
"timestamp" : getTimeStamp(),
"memobirdID" : MEMOBIRD_ID,
"useridentifying" : USER_IDENTIFYING
}
try:
r = requests.get(BIND_DEVICE_API, params=params)
# 返回结果形如:
# {"showapi_res_code":1,"showapi_res_error":"ok","showapi_userid":8}
return r.json()["showapi_userid"]
except Exception as e:
print(e)
return ""
getUserID()
3.3.3 打印文字
示例代码:
代码语言:javascript复制import requests
import datetime
# 打印纸条的API
PRINT_PAPER_API = "http://open.memobird.cn/home/printpaper"
def printText(text, userId):
# 要打印的内容 T:文字的base64编码(gbk)
printContent = "T:" base64.b64encode(text.encode("gbk")).decode()
params = {
"ak" : Access_Key,
"timestamp" : getTimeStamp(),
"memobirdID" : MEMOBIRD_ID,
"printcontent" : printContent,
"userID" : userId,
}
r = requests.post(PRINT_PAPER_API, data=params)
print(r.text)
userId = getUserID()
printText("Hello World", userId)
运行后,咕咕机成功打印。
3.3.4 打印图片
示例代码:
代码语言:javascript复制import requests
import datetime
# 打印纸条的API
PRINT_PAPER_API = "http://open.memobird.cn/home/printpaper"
# JPG/PNG图片转单色点阵图base64编码的API
BASE64_PIC_API = "http://open.memobird.cn/home/getSignalBase64Pic"
# 获取图片转换后的base64编码
def getPictureBase64(path):
with open(path,"rb") as f:#转为二进制格式
base64_data = base64.b64encode(f.read())#使用base64进行加密
params = {
"ak" : Access_Key,
"imgBase64String" : base64_data,
}
r = requests.post(BASE64_PIC_API, data=params)
return r.json()["result"]
def printPicture(path, userId):
# 要打印的内容 P:单色点阵图的base64编码
printContent = "P:" getPictureBase64(path)
params = {
"ak" : Access_Key,
"timestamp" : getTimeStamp(),
"memobirdID" : MEMOBIRD_ID,
"printcontent" : printContent,
"userID" : userId,
}
r = requests.post(PRINT_PAPER_API, data=params)
print(r.text)
userId = getUserID()
printPicture("drink_0.jpeg", userId)
运行代码以后,咕咕机成功打印出来图片。
更多的功能,如获取打印状态,打印网页,打印HTML等,这里用不到,就不做示例了
大家感兴趣的话,可以去参考官网开发者文档。
3.3.5 咕咕机接入涂鸦云
接下来,我们通过树莓派来操控咕咕机,将咕咕机接入涂鸦生态。
首先我们将代码整理一下,保存为 memobird.py
脚本,如下:
import requests
import datetime
import random
import base64
class Memobird:
def __init__(self):
self.BIND_DEVICE_API = "http://open.memobird.cn/home/setuserbind"
self.PRINT_PAPER_API = "http://open.memobird.cn/home/printpaper"
self.AK = "填入你申请的开发者AK"
self.MEMOBIRD_ID = "填入你咕咕机的设备ID"
self.USER_IDENTIFYING = "smartcrane" #随便填一个字符串都可以
self.DRINK_REMINDER_TEXT = [
"机灵鹤,你好n我是“喝水提醒小助手”n希望此时此刻看到消息的你 n快去喝一杯水n成为一个一天八杯水的男人吧!"
]
self.userID = self.getUserID()
def getTimeStamp(self):
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
return timestamp
def getUserID(self):
params = {
"ak" : self.AK,
"timestamp" : self.getTimeStamp(),
"memobirdID" : self.MEMOBIRD_ID,
"useridentifying" : self.USER_IDENTIFYING
}
try:
r = requests.get(self.BIND_DEVICE_API, params=params)
return r.json()["showapi_userid"]
except Exception as e:
print(e)
return ""
def printText(self, text, userId):
printContent = "T:" base64.b64encode(text.encode("gbk")).decode()
params = {
"ak" : self.AK,
"timestamp" : self.getTimeStamp(),
"memobirdID" : self.MEMOBIRD_ID,
"printcontent" : printContent,
"userID" : self.userID,
}
r = requests.post(self.PRINT_PAPER_API, data=params)
print(r.text)
def drink_reminder(self):
printText = self.getTimeStamp() "n" random.choice(self.DRINK_REMINDER_TEXT)
self.printText(printText, self.userID)
这里封装了一个 Memobird
类,提供了一个 drink_reminder
函数,用来打印 喝水提醒
的文字。
我们只需要在树莓派中,接收到 APP 下发的 喝水提醒
指令时,调用 drink_reminder
函数即可。
相应的,我们将 demo.py
改造一下:
#!/usr/bin/env python
import time
from tuyalinksdk.client import TuyaClient
from tuyalinksdk.console_qrcode import qrcode_generate
from memobird import Memobird
# 这里更换成自己的ID
PID = "jj9hhmjxsf8u2b94"
UUID = "tuyaf5753924f3d94306"
AUTHKEY = "5TbgqpGXzbgrr8Plb8L93rBy38Liu7ok"
DRINK_DP_ID = "101"
memobird = Memobird()
client = TuyaClient(productid = PID, uuid = UUID, authkey = AUTHKEY)
def on_connected():
print('Connected.')
def on_qrcode(url):
qrcode_generate(url)
def on_reset(data):
print('Reset:', data)
def on_dps(dps):
print('DataPoints:', dps)
client.push_dps(dps)
for key in dps:
if key == DRINK_DP_ID and dps[key] == True:
# TODO: 喝水提醒
memobird.drink_reminder()
client.on_connected = on_connected
client.on_qrcode = on_qrcode
client.on_reset = on_reset
client.on_dps = on_dps
client.connect()
client.loop_start()
while True:
time.sleep(1)
重新启动代码,就到了最激动人心的时候了。
点击 喝水提醒
按钮,咕咕机成功打印出了提醒喝水的文字!!!
至此,通过 Tuya 的 Link SDK,我们借助树莓派作为网关,将咕咕机成功接入了涂鸦生态之中。
3.4 智能联动
接下来,我们只需要在涂鸦智能 APP 中创建智能场景,设定执行条件和执行任务,便可以实现简单的自动化,以及设备联动啦。
3.4.1 喝水提醒小助手
根据我们自己的作息时间,我们可以设定定时喝水提醒。
如:每天定时下午 2 点 10 分提醒喝水。
设定好以后,保存并启用,系统将会在每天下午 2 点 10 分打印纸条,提醒我们喝水。
3.4.2 久坐提醒小助手
如果说,喝水提醒小助手,只是相当于设定了一个闹钟,感觉用处没那么明显的话。那么我们接入其他各种传感器设备,进行设备间的联动,可以做的事情就很厉害了。
接下来,我们将与人体传感器联动,在 喝水提醒小助手
的基础上,实现一个 久坐提醒小助手
。
首先我们需要在涂鸦 IoT 平台,继续添加一条自定义功能 久坐提醒
,如图所示
然后,在 memobird.py
中设定好 久坐提醒
的文案,并提供一个 久坐提醒
的函数接口。
self.SEDENTARY_REMINDER_TEXT = [
"机灵鹤,你好n我是“久坐提醒小助手”n检测到您已经连续工作很久了n久坐对身体危害很大n快起来活动一下吧"
]
def sedentary_reminder(self):
printText(self.getTimeStamp() "n" random.choice(self.SEDENTARY_REMINDER_TEXT), self.userID)
最后,在 demo.py
中添加一条 久坐提醒
的消息定义,并完善该消息对应的处理函数。
DRINK_DP_ID = "101"
SEDENTARY_DP_ID = "102"
def on_dps(dps):
print('DataPoints:', dps)
client.push_dps(dps)
for key in dps:
if key == DRINK_DP_ID and dps[key] == True:
# TODO: 喝水提醒
memobird.drink_reminder()
if key == WELCOME_DP_ID and dps[key] == True:
# TODO: 久坐提醒
memobird.welcome_reminder()
保存代码,重新运行启动程序。
手机 APP 端,连接无线网关及人体传感器。
在传感器页面中,设定智能联动:检测到有人移动,持续 30 分钟时,触发久坐提醒。
然后将传感器固定到桌子旁边,正对座位的位置即可。
在连续坐着工作半个小时后,咕咕机成功打印出久坐提醒的纸条。
最后,只需要将久坐提醒和喝水提醒的文案修改一下,就可以送给女朋友啦!
我想女朋友收到礼物一定会感动哭了吧!
4. 写在后面的话
整个项目从构思到开发完成历时 9 天,期间踩了很多坑,绕了很多弯,不过好在最后成功完成,也收获了很多。同时借着这个机会,也算是入了 物联网/智能家居 的门。
在项目开发初期,我对物联网的这套逻辑其实是比较模糊的,我不清楚文档里每一个步骤的作用,不清楚设备之间通信的原理,我甚至搞不清每一个硬件设备在这套系统里需要扮演的角色。比如我会常常试图将树莓派作为系统的控制核心,用它来监听传感器状态,用它来控制咕咕机,以及用它来处理智能联动的逻辑。然而事实上,树莓派只需要完成一个任务——监听和处理涂鸦 APP 下发的指令就可以了,这也正是涂鸦 Link SDK 的核心能力。其他部分如监听传感器状态,设备间智能联动等等,都可以在 APP 中完成。
在逐步捋清楚整套逻辑之后,开发过程逐渐顺畅。我发现,在解决了设备接入和设备联动问题之后,物联网比拼的其实就是谁脑洞开的更大了,看谁能用一些奇怪的设备组合,通过一些莫名其妙的规则发生联动,最后产生奇妙的效果,给人们的生活带来出乎意料的方便。
本文较为详细的记录了这个项目开发的全过程,既是对我第一次开发物联网项目的全面复盘,也是希望大家在开发物联网入门项目时有所参考。如果有朋友因为本项目而对物联网产生了兴趣,我便更是荣幸之至。
如果文章中有哪里没有讲明白,或者讲解有误的地方,欢迎在评论区批评指正,大家一起学习交流,共同进步。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/186980.html原文链接:https://javaforall.cn