智能家居系統利用大量的物聯網設備(如溫溼度傳感器、安防系統、照明系統)實時監控家庭內部狀態,完成智能調節、人機互動。隨着物聯網技術的發展,其應用範圍、數據規模、市場份額將進一步擴大,智能家居設備之間的智能聯動也將變的愈來愈困難,同時因爲家庭數據的隱私性,用戶數據上傳至雲端處理還有必定的安全問題。python
爲此咱們將使用 Raspberry Pi + EMQ X Edge + EMQ X Kuiper 搭建智能家居網關,實現智能家居設備數據的邊緣計算處理,減小家庭私密數據外流。linux
本文中咱們將用 BH1750FVI 光照強度傳感器採集家庭光照強度數據,使用 EMQ X Kuiper 對光照強度數據進行分析和處理,並依據預先定義的數據規則對 LED 燈進行相應的控制。git
樹莓派3代B+ 型是一款基於 ARM 的微型計算機主板,以 SD/MicroSD卡進行存儲,該主板提供 USB 接口和以太網接口,能夠鏈接鍵盤、鼠標和網線,該主板具有 PC 的基本功能,同時樹莓派集成了 Wi-Fi,藍牙以及大量 GPIO,是智能家居網關的理想選擇。github
智能家居設備之間通訊協議有 MQTT,Wi-Fi,藍牙 等,其中 MQTT 協議 是基於發佈/訂閱模式的物聯網通訊協議,它簡單易實現、支持 QoS、報文小。在本文中咱們將使 MQTT 協議做爲智能家居設備之間的通訊協議。sql
因爲 Raspberry Pi 內存以及處理能力有限,咱們選擇由 EMQ 開源的 EMQ X Edge 做爲 MQTT broker,EMQ X Edge 是輕量級的物聯網邊緣計算消息中間件,支持部署在資源受限的物聯網邊緣硬件。編程
智能家居設備之間數據傳輸格式不一樣,而且數據存在波動性,咱們須要對設備上報的數據進行處理。在本文中咱們將使用由 EMQ 開源的 EMQ X Kuiper 對智能家居設備數據進行邊緣化處理,EMQ X Kuiper 是基於 SQL 的輕量級邊緣流式消息處理引擎,能夠運行在資源受限的邊緣設備上。json
經過實時分析智能家居設備的各種數據,能夠實現對設備的即時狀態管理與控制。安全
咱們選擇 raspbian 8 做爲樹莓派操做系統,並選擇 python 3 做爲項目編程語言bash
# 建立名爲 smart-home-hubs 的項目目錄 mkdir ~/smart-home-hubs
$ cd ~/smart-home-hubs # 下載軟件包 $ wget https://www.emqx.io/downloads/edge/v4.1.0/emqx-edge-raspbian8-v4.1.0.zip $ unzip emqx-edge-raspbian8-v4.1.0.zip $ cd ./emqx # 運行 EMQ X Edge $ ./bin/emqx start
$ cd ~/smart-home-hubs # 下載軟件包 $ wget https://github.com/emqx/kuiper/releases/download/0.4.2/kuiper-0.4.2-linux-armv7l.zip $ unzip kuiper-0.4.2-linux-armv7l.zip $ mv kuiper-0.4.2-linux-armv7l ./kuiper $ cd ./kuiper # 建立 rules 目錄,用來存放規則文件 $ mkdir ./rules # 運行 EMQ X Kuiper $ ./bin/server
編寫代碼讀取並計算 BH1750FVI 傳感器光照強度數據,並以 1次/秒 的頻率將光照強度數據經過 MQTT協議 發佈到 smartHomeHubs/light 主題上。tcp
# gy30.py import json import time import smbus from paho.mqtt import client as mqtt # BH1750FVI config DEVICE = 0x23 # Default device I2C address POWER_DOWN = 0x00 POWER_ON = 0x01 RESET = 0x07 CONTINUOUS_LOW_RES_MODE = 0x13 CONTINUOUS_HIGH_RES_MODE_1 = 0x10 CONTINUOUS_HIGH_RES_MODE_2 = 0x11 ONE_TIME_HIGH_RES_MODE_1 = 0x20 ONE_TIME_HIGH_RES_MODE_2 = 0x21 ONE_TIME_LOW_RES_MODE = 0x23 bus = smbus.SMBus(1) # MQTT broker config broker = '127.0.0.1' port = 1883 topic = 'smartHomeHubs/light' def read_light(): data = bus.read_i2c_block_data(DEVICE, ONE_TIME_HIGH_RES_MODE_1) light_level = round((data[1] + (256 * data[0])) / 1.2, 2) return light_level def connect_mqtt(): client = mqtt.Client(client_id='light_01') client.connect(host=broker, port=port) return client def run(): mqtt_client = connect_mqtt() while True: light_level = read_light() publish_msg = {'lightLevel': light_level} mqtt_client.publish( topic, payload=json.dumps(publish_msg) ) print(publish_msg) time.sleep(1) if __name__ == "__main__": run()
咱們將在 EMQ X Kuiper 上建立名爲 smartHomeHubs
的流,並配置規則對光照強度數據進行實時分析,以實現對 LED 燈的控制。
本文中咱們將計算光照強度平均值,當平均光照強度 持續 5 秒 小於 55 時開啓 LED(大於 55 時關閉 LED)。
建立流
$ cd ~/smart-home-hubs/kuiper $ ./bin/cli create stream smartHomeHubs '(lightLevel float) WITH (FORMAT="JSON", DATASOURCE="smartHomeHubs/light")'
編寫開啓 LED 規則(./rules/onLed.rule)
當持續 5 秒鐘平均光照強度小於 55 時,向 smartHomeHubs/led
主題發送 "{\"status\": \"on\"}"
消息打開 LED。
{ "sql":"SELECT avg(lightLevel) as avg_light from smartHomeHubs group by TUMBLINGWINDOW(ss, 5) having avg_light < 55;", "actions":[ { "mqtt":{ "server":"tcp://127.0.0.1:1883", "topic":"smartHomeHubs/led", "sendSingle":true, "dataTemplate": "{\"status\": \"on\"}" } } ] }
編寫關閉 LED 規則(./rules/offLed.rule)
當持續 5 秒鐘平均光照強度大於 55 時,向 smartHomeHubs/led
主題發送 "{\"status\": \"off\"}"
消息關閉 LED。
{ "sql":"SELECT avg(lightLevel) as avg_light from smartHomeHubs group by TUMBLINGWINDOW(ss, 5) having avg_light > 55;", "actions":[ { "mqtt":{ "server":"tcp://127.0.0.1:1883", "topic":"smartHomeHubs/led", "sendSingle":true, "dataTemplate": "{\"status\": \"off\"}" } } ] }
添加規則
$ ./bin/cli create rule onLed -f ./rules/onLed.rule $ ./bin/cli create rule onLed -f ./rules/offLed.rule
查看規則
$ ./bin/cli show rules
編寫代碼鏈接到 EMQ X Edge,並訂閱 smartHomeHubs/led 主題。監聽訂閱的 MQTT 消息內容,當 status 爲 on 時打開 LED,當 status 爲 off 時關閉 LED。
# led.py import paho.mqtt.client as mqtt import RPi.GPIO as GPIO import json # MQTT broker config broker = '127.0.0.1' port = 1883 topic = 'smartHomeHubs/led' def on_connect(client, userdata, flags, rc): print("Connecting to the MQTT broker...") if rc == 0: print("Connection success") else: print("Connected with result code "+str(rc)) client.subscribe(topic) def on_message(client, userdata, msg): payload = json.loads(msg.payload) led_status = payload.get('status') gpio_status = GPIO.input(4) if led_status == 'on' and gpio_status == 0: GPIO.output(4, True) print('LED on') elif led_status == 'off' and gpio_status == 1: GPIO.output(4, False) print('LED off') else: pass def run(): # connect MQTT broker client = mqtt.Client() client.on_connect = on_connect client.on_message = on_message client.connect(broker, 1883, 60) # set Raspberry Pi GPIO pin GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) GPIO.setup(4, GPIO.OUT) try: client.loop_forever() except KeyboardInterrupt: GPIO.cleanup() if __name__ == "__main__": run()
python gy30.py
獲取光照數據,並將數據上報到 smartHomeHubs/light 主題。python led.py
訂閱 smartHomeHubs/led 主題,監聽 LED 控制信息。至此,咱們已成功搭建基於 Raspberry Pi + EMQ X Edge + EMQ X Kuiper 的智能家居網關。
咱們使用 Raspberry Pi 爲網關提供豐富的外部通訊接口,使用 EMQ X Edge 爲網關提供設備之間的通訊功能,使用 EMQ X Kuiper 爲網關提供設備數據處理以及分析功能。
以後,咱們使用光照傳感器獲取光照強度,經過光照強度來控制 LED 的開和關。在整個過程當中全部數據都在本地處理和分析,下降了家庭私密數據泄漏的風險。
版權聲明: 本文爲 EMQ 原創,轉載請註明出處。