智能家居——阿里雲物聯網套件體驗


背景

本文主要記錄使用阿里雲物聯網套件的方法。
以STM32驅動DHT11讀取溫度、濕度為例,將數據以MQTT方式推送到阿里雲物聯網平台上。
STM32驅動DHT11從串口獲取數據請參考文章《STM32獲取DHT11溫度傳感器數據

雲平台配置

1. 登陸管理控制台

<1> 登陸阿里雲官網
<2> 產品 -> 物聯網套件 -> 開通服務 or 管理控制台

2. 新建產品、設備

如圖,創建了名為home_automation的產品,以及產品下面兩個設備temperature_sensorsubscribe_test

以MQTT方式發布數據

官方文檔:https://help.aliyun.com/document_detail/30539.html?spm=5176.doc30530.6.574.43QEvm

本示例采用方式二:使用HTTPS認證再連接模式;
按照官網文檔說明,實現HTTPS認證並獲取授權,再通過MQTT通信。

HTTPS認證

HTTPS認證方式參考代碼如下:

#!/usr/bin/python                                                                                                                               
# -*- coding: utf-8 -*-

import json
import time
import hmac
import hashlib
import requests
import traceback


class AliyunIot():
CONF_FILE = 'config.json'

def __init__(self, config_file = None):
if not config_file:
config_file = self.CONF_FILE
self.__s = requests.Session()
self.__config = self.__load_config(config_file)

def __load_config(self, filename):
with open(filename) as f:
return json.load(f, encoding='utf-8')

def __del__(self):
self.__s.close()

def GetSign(self, secret, param):
black_key_list = ['version', 'sign', 'resources', 'signmethod']
p = filter(lambda x:x[0] not in black_key_list, param.items())
c = ''.join([''.join(str(j) for j in i) for i in sorted(p, key=lambda x:x[0])])
return hmac.new(str(secret), c, hashlib.md5).hexdigest()

def DeviceAuthentication(self, client_id, resources = 'mqtt'):
timestamp = int(time.time())

param = {'productKey': self.__config['productKey'],
'deviceName': self.__config['deviceName'],
'sign': None,
'signmethod': 'hmacmd5',
'clientId': client_id,
'timestamp': timestamp,
'resources': resources}

param['sign'] = self.GetSign(self.__config['deviceSecret'], param)

pre = requests.Request('POST', url=self.__config['url'], data=param).prepare()
res = self.__s.send(pre, cert=self.__config['cert'], timeout=3)
if res.text:
try:
resp = json.loads(res.text)
if resp['code'] == 200:
return resp['data']
except:
print res.text
print 'Http request failed.'
print traceback.print_exc()
return None,None

if __name__ == '__main__':
a = AliyunIot()
print a.DeviceAuthentication('01')

新建config.json配置如下:

{
"productKey": "xx",
"deviceName": "xx",
"deviceSecret": "xx",
"url": "https://iot-auth.cn-shanghai.aliyuncs.com/auth/devicename",
"cert": "aliyun_iot.crt"
}

參數說明:

  • productKey:官網產品管理獲取
  • deviceName:設備頁面獲取
  • deviceSecret:設備頁面 -> 設備證書
  • cert:請下載官網文檔中給的,也可選擇不使用證書,但要將python的Requests的verify置為false,方法可網上查閱資料。

執行腳本即可得到響應:

pi@raspberrypi:~/IoT/raspberrypi $ ./aliyun_iot.py
{u'iotId': u'xxxxx', u'resources': {u'mqtt': {u'host': u'public.iot-as-mqtt.cn-shanghai.aliyuncs.com', u'port': 1883}}, u'iotToken': u'xxxxxxx'}

MQTT發布消息

從串口讀取數據解析出json

編輯文件iot_serial.py

#!/usr/bin/python
# -*- coding: utf-8 -*-

import serial
import json
import time

class Serial:
def __init__(self, port, baudrate = 9600):
self.__ser = serial.Serial(port, baudrate, timeout=0.5)

def __del__(self):
self.__ser.close()

def GetData(self):
self.FlushInput()

while True:
time.sleep(0.1)

text = self.__ser.read(1)

if text:
recv = text + self.__ser.readline()
return recv.strip().strip('\n').strip('_')

def FlushInput(self):
self.__ser.flushInput()


if __name__ == '__main__':
s = Serial('/dev/ttyUSB0')
while True:

try:
j = json.loads(s.GetData())
print '%s\t%s' %(time.time(), j)
except:
continue

運行,測試串口數據讀取正常

pi@raspberrypi:~/IoT/raspberrypi $ ./iot_serial.py
1506334420.2 {u'temperature': 17.4, u'humidness': 35.6}
1506334444.57 {u'temperature': 20.4, u'humidness': 46.4}
1506334468.19 {u'temperature': 20.4, u'humidness': 43.6}

將串口讀取數據利用MQTT協議發送

python安裝mqtt模塊:

sudo pip install paho-mqtt

編輯文件mqtt.py

#!/usr/bin/python
# -*- coding: utf-8 -*-

import time
import json
import traceback
import paho.mqtt.client as mqtt


from util import GetMacAddr
from iot_serial import Serial
from aliyun_iot import AliyunIot

#此處TOPIC應該替換為自己的
TOPIC = '/xxxxx/temperature_sensor/m2m'

def ConnectCallback(client, userdata, flags, rc):
print 'Connected:' + str(rc)

dev_id = GetMacAddr()
print dev_id

a = AliyunIot()
conf = a.DeviceAuthentication(dev_id)
print conf

client = mqtt.Client(dev_id)
client.on_connect = ConnectCallback

client.tls_set('aliyun_iot.crt')
client.username_pw_set(conf['iotId'], conf['iotToken'])

m = conf['resources']['mqtt']
client.connect(m['host'], m['port'], 80)
client.loop_start()

s = Serial('/dev/ttyUSB0')
while True:
try:
msg = json.dumps(json.loads(s.GetData()))
rc, mid = client.publish(TOPIC, payload=msg)
if rc == 0:
print '[%s]publis success, %s' %(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), msg)
except:
traceback.print_exc()
time.sleep(1)

運行查看結果:

pi@raspberrypi:~/IoT/raspberrypi $ ./mqtt.py
Connected:0
[2017-09-25 10:18:36]publis success, {"temperature": 17.2, "humidness": 45.6}

也可以在雲平台管理頁面查看日志:

設備間通信M2M

官方文檔:https://help.aliyun.com/document_detail/59147.html?spm=5176.doc30539.6.668.bSNXB3

配置規則引擎

訂閱Topic

#!/usr/bin/python
# -*- coding: utf-8 -*-

from util import GetMacAddr
from iot_serial import Serial
from aliyun_iot import AliyunIot
import paho.mqtt.client as mqtt

TOPIC = '/JVMwetHXFGK/temperature_sensor/m2m'

def ConnectCallback(client, userdata, flags, rc):
print 'Connected:' + str(rc)
client.subscribe(TOPIC)

def MessageCallback(client, userdata, msg):
print '%s -> %s' %(msg.topic, str(msg.payload))

dev_id = GetMacAddr()
dev_id='test001'

a = AliyunIot('config_subscribe.json')
conf = a.DeviceAuthentication(dev_id)

client = mqtt.Client(dev_id)
client.on_connect = ConnectCallback
client.on_message = MessageCallback

client.tls_set('aliyun_iot.crt')
client.username_pw_set(conf['iotId'], conf['iotToken'])

m = conf['resources']['mqtt']
client.connect(m['host'], m['port'], 80)
client.loop_forever()

其中config_subscribe.json為配置文件拷貝一份,將里面的設備名和秘鑰改為另一個設備的。

運行發布消息和訂閱消息程序

數據存入表格存儲

創建規則

添加方法

沒有內容的可以按照提示連接創建

在OTS中查看數據

安裝表格存儲客戶端並登陸

總結

阿里雲Iot套件提供了方便的接入,便捷的數據導入其他雲服務,很適合大型、或海量應用高效接入。
對於智能家居方便,目前有比較好的開源平台Home Assistant可以自己搭建私有平台,且可以方便介入HomeKit等,效果非常贊。
下篇博客將簡單介紹Home Assistant相關內容。


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com