智能家居系统利用大量的物联网设备(如温湿度传感器、安防系统、照明系统)实时监控家庭内部状态,完成智能调节、人机互动。随着物联网技术的发展,其应用范围、数据规模、市场份额将进一步扩大,智能家居设备之间的智能联动也将变的愈来愈困难,同时因为家庭数据的隐私性,用户数据上传至云端处理还有必定的安全问题。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 原创,转载请注明出处。