前几天在朋友介绍下试用了阿里云的物联网平台,阿里云IOT平台使用MQTT协议通信,并且可以使用Web可视化开发将设备信息反映在网页上进行控制,绑定域名后就能随时随地进行查看和控制,但是阿里云IOT是收费的,虽然不是很贵,但是对于一个在读学生来说,非必要情况,还是不想花钱。。。有兴趣的可以去看看,附上朋友博客 树莓派上云 。我记的百度云的天工物接入平台是有免费政策的,每个月一百万条消息以内是免费的。而且也提供有Web物可视功能,就去研究了一下,写一个简单记录供大家参考,本人系在读学生,而且跨专业搞电子,可能有些地方有误,请大家指点。
附上用IOT物可视制作的页面
创建设备
开通服务
第一次使用百度云的朋友需要先注册账户并开通物接入服务。
1,登录百度智能云官网,点击右上角的“管理控制台”,快速进入控制台界面。
2,选择“产品服务 > 物联网服务 > 物接入IoT Hub”,进入服务页面。
3,点击“立即开通”,开通服务并同意按需计费,可进入“项目列表”,创建物接入项目。 附上计费规则
这里的消息条数是指,云平台每发送或接收一条消息,对我们学习使用来说,基本足够用了。
创建项目
进入物接入IoT Hub后在左侧项目列表中,创建一个新项目,输入项目名称,项目类型选择设备型。
这里注意百度云IOT只能创建一个设备型项目,而且创建后项目名称不可修改,项目不可删除。
设备接入
创建物模型
项目创建好后回到项目列表,点击项目名称进入物模型创建界面,这里的物模型对应的是现实中的设备属性模型,点击创建物模型,输入名称,并添加需要的属性,这里的属性是设备与云服务器上传的属性。设置好属性后保存。
创建物影子
在左侧选择物影子,进入物影子创建界面。物影子,指的是在物模型中创建的这一类设备存在云服务器上的反映,一个物模型可以对应多个物影子,设备的属性反映在物影子的属性上。点击新建物影子,输入设备名称,物模型选择刚创建的那个物模型。存储配置是收费项目,根据需要选择,这里存储配置是存储历史数据。 物影子创建成功后会弹出链接信息,尽量将其下载下来,如果找不到了,需要在物影子设备->物详情->连接配置中重新生成,此时密钥会发成变化,造成之前的密钥失效。创建完毕后的物影子就像这样,我新建的raspi4B,那个aliyun影子是我放在云服务器中的,正在运行,所以显示在线。
使用MQTT客户端测试,这里我使用的是MQTT.fx客户端。切记不可使用MQTT1.7.0版本,这个版本有bug。
测试连接
打开mqtt客户端,添加一个配置。
profile name | 配置文件名称,可随意填写 |
---|---|
Broker Address | 创建项目后返回的hostname,在刚才保存的文件中有。 |
Broker Port | 使用1883端口连接是非加密连接,使用1884端口需要配置SSL/TLS |
Client ID | 设备端需要填写物影子名称,其他客户端随意,使用物影子ID连接能够使物影子显示在线状态。 |
在User Credential中填写刚保存的用户名和密钥。 如果使用了1884端口,需要配置SSL/TLS安全认证,勾选 Enable SSL/TLS,选择CA signed server certificate认证。
配置完毕后点击apply应用。回到软件,选择刚才的配置,点击连接,此时右边的灯会亮绿灯,代表连接成功。
回到物影子界面,可见物影子上显示已连接
在物影子交互界面复制订阅主题,粘贴入MQTT客户端进行订阅,订阅成功后,在MQTT客户端显示一条订阅记录。
在物影子详情中点编辑,修改当前值及期望值,然后确定。随后可在mqtt客户端收到一条订阅消息。
在物影子交互中复制第一条订阅主题,粘贴入MQTT客户端的Publish窗口,在物影子详情中复制 原始数据 中的这一段,粘贴入MQTT客户端。
修改期望值为10和11,发布值为20和21,点击Publish发布,然后可见物影子属性界面随之发生改变。(需要手动刷新)
至此,MQTT协议的订阅与发布功能测试完成。
树莓派上云
环境搭建
树莓派上需要安装有Python3以上的版本,需要用到paho-mqtt模块。
paho-mqtt模块要使用1.2版,我之前用的1.5版发现无法连接到服务器。换成1.2版就可以。
代码编写
程序中主要使用paho-mqtt模块,这个模块的说明请参考Python paho-mqtt 模块使用和API分析代码的主要部分已进行注释。 代码开头加载python3解释器,然后将文件权限设为755,就可以直接进行执行。
运行后,树莓派就开始上报消息,同时如果修改物模型中的期望值,树莓派就可以收到期望值的改变,同时如果发布之出现改变,树莓派同样能收到改变的那一部分参数,这样就可以使用别的客户端控制设备。设备实例使用物影子ID连接,其他客户端使用别的ID连接。
代码只需要修改主机地址,用户名,密钥,还有ClientID即可。根据需要在 Sensor_dict字典和read_serverInfo()函数段添加相应字段即可。
#!/usr/bin/env python3
import paho.mqtt.client as mqtt
import json,time,os
host = '**************' #主机地址
port = 1883 #服务器端口
username = '********' #用户名
passwd = '!!!!!!!!!!!!!!!' #密钥
clientid = '!!!!' #客户端实例名称
topic = '$baidu/iot/shadow/raspi4B/update' #消息发布主题
desired = '$baidu/iot/shadow/raspi4B/delta' #订阅期望值发生变化的消息
reported = '$baidu/iot/shadow/raspi4B/update/documents' #订阅属性发生变化的消息
connect_flog = 0 #连接成功标志
Json_buf = {'reported':0} #上报消息用的字典
Sensor_dict= {'MemUsage':0,'freeMem':0,'usedMem':0,'loadavg_1':0,'loadavg_5':0,'loadavg_15':0,'cputemp':0} #采集的属性值
def on_connect(client, userdata, rc): #连接回调函数
global connect_flog
if rc == 0:
print('连接成功')
connect_flog = 1
client.subscribe(desired,0) #订阅消息
client.subscribe(reported,0) #订阅消息
else :
connect_flog = 0
print("连接失败,错误代码:%d"%rc)
def on_disconnect(client, userdata, rc): #断开连接回调
print("断开连接,代码%d"%rc)
def on_message(client, userdata, msg): #收到订阅的消息是回调此函数
buf = str(msg.payload,'utf-8') #将收到的消息转为JSON字符串格式
buf = json.loads(buf) #将JSON字符串转为字典
if msg.topic == desired : #判断消息类型
print ("领导发话了:",end='')
print (buf['desired'])
elif msg.topic == reported : #判断消息类型
print("情况有变: vsrsion = %s "%buf['profileVersion'],end='')
print ("当前值:%s "%buf['current'],end='')
print ("上次值:%s"%buf['previous'])
def on_subscribe(client, userdata, mid, granted_qos): #订阅成功回调
print("订阅成功")
def mqtt_connect(): #开始连接MQTT服务器
client.connect(host,port,60)
client.loop_start()
def MemInfo(): #获取系统内存信息
out_dict = {'FreeMem':0,'UsedMem':0,'MemUsage':0} #内存信息缓冲区
f = os.popen('free')
buf = f.readline()
buf = f.readline()
buf = buf.strip().split()
out_dict['FreeMem'] = int(buf[6])
out_dict['UsedMem'] = int(buf[2])
out_dict['MemUsage'] = int(buf[2]) * 100 / int(buf[1])
return out_dict
def LoadAvg(): #获取系统负载信息
out_dict = {'loadavg_1':0,'loadavg_5':0,'loadavg_15':0}
f = os.popen('uptime')
buf = f.readline()
buf = buf.replace(',','')
buf = buf.strip().split()
var = buf.index('average:')
out_dict['loadavg_1'] = float(buf[var + 1])*100 / 2
out_dict['loadavg_5'] = float(buf[var + 2])*100 / 2
out_dict['loadavg_15'] = float(buf[var + 3])*100 / 2
return out_dict
def CpuTemp(): #获取CPU温度
f = open('/sys/class/thermal/thermal_zone0/temp')
buf = f.read()
f.close()
buf = int(buf)
buf = buf / 1000
return buf
def read_serverInfo(): #读取服务器信息
meminfo = MemInfo()
loadavg = LoadAvg()
Sensor_dict['MemUsage'] = round(meminfo['MemUsage'],2) #将读取到的信息写入字典
Sensor_dict['freeMem'] = round(meminfo['FreeMem'] / 1024,2)
Sensor_dict['usedMem'] = round(meminfo['UsedMem'] / 1024,2)
Sensor_dict['loadavg_1'] = round(loadavg['loadavg_1'],2)
Sensor_dict['loadavg_5'] = round(loadavg['loadavg_5'],2)
Sensor_dict['loadavg_15'] = round(loadavg['loadavg_15'],2)
Sensor_dict['cputemp'] = round(CpuTemp(),2)
def Send_data(): #向MQTT服务器发布消息
read_serverInfo() #读取信息
Json_buf['reported'] = Sensor_dict #封装消息包
Rx_buf = str(json.dumps(Json_buf)) #将字典转为JSON字符串
client.publish(topic,Rx_buf) #上报消息
client = mqtt.Client(clientid) #使用构造函数构造一个客户端实例
client.on_connect = on_connect #连接回调函数
client.on_disconnect = on_disconnect
client.on_message = on_message
client.on_subscribe = on_subscribe
client.username_pw_set(username, passwd) #设置用户及密钥
if __name__ == '__main__':
print("开始连接MQTT服务器")
mqtt_connect()
while True:
if connect_flog == 1 :
Send_data()
time.sleep(10) #每隔10s上报一次消息
总结
小白第一次发帖,请多指教,有问题请留言,后面还有一些关于百度物可视的操作没有法,半夜了,后面有机会在发吧,简单说,就是在天工物联网总览打开物可视,先创建一个工作区,然后在工作区创建一个仪表盘,进入仪表盘,拖放控件,然后一些控件可以绑定数据,但是需要先在画布顶部进入数据栏创建数据表,数据表类型选择物影子。
简单总结一下,比较百度云和阿里云,两相比较 百度IOT 优点:有一部分免费政策,但是幅度不大,每月免费100万条消息。服务器的属性设置很自由,而且精度很高,可以达到小数点后七八位。 缺点:不能储存历史记录,当然这是对免费政策来说的,如果想储存数据需要购买他的时序数据库。Web项目不如阿里云的,虽然阿里云的也有一定的缺陷,比如不能显示字符串参数。