天天看點

基于阿裡雲物聯網平台實作的簡易出入監控

本文通過一個簡單執行個體,主要介紹了如何使用樹莓派快速接入阿裡雲iot platform,并實作了一個簡易的監控人員出入并拍照上送釘釘群的場景

場景

在公司大門入口處布點樹莓派和紅外感應,實作出入口人員出入時,自動拍照并上送釘釘群機器人

準備

物料準備

  • 樹莓派
  • HC-SR501 人體紅外感應器
  • 樹莓派攝像頭
  • 母對母杜邦線三根

阿裡雲環境準備

  • 物聯網平台
  • 對象存儲OSS
  • 函數計算
  • 日志服務(可選)

操作步驟

1 雲端開發

1.1 物聯網平台

登入阿裡雲控制台,進入物聯網平台控制台

1.1.1 建立産品

進入裝置管理,建立産品,選擇基礎版或進階版都可以,本執行個體使用基礎版就可以滿足基本要求。

系統會自動建立3個Topic,我們需要使用 /ProductName/${deviceName}/update,作為裝置告警消息的上送的Topic。

1.1.2 裝置管理

在産品中新增裝置,并獲得裝置的3元組,在2.3節的裝置代碼的編寫時需要使用此3元組。裝置三元組是裝置的唯一标示

1.1.3 建立規則引擎

設定規則引擎的意義在于,可以将裝置上送的消息資料,通過配置轉發規則将處理後的資料轉發到阿裡雲其他服務,例如RDS、TBS和函數計算等等。我們需要注意的是從裝置端到規則引擎處理後的JSON資料格式的變化,下圖中是基礎版的演變過程:

基于阿裡雲物聯網平台實作的簡易出入監控

我們在裝置端消息上送定義的JSON的格式是:

{
    'photo': 'xxxxxxx.jpg'
}           

新建立一個規則,資料格式選擇JSON。編寫處理資料的SQL

SELECT deviceName() deviceName, photo FROM "/a1O4b4XcICc/+/update"           

配置完成後,我們可以模拟調試一下,檢查規則是否正确:

接着,配置資料轉發,把資料轉發到FC函數計算中。分别選擇在1.3步驟中建立好的服務和函數。

1.2 對象存儲

由于裝置端拍攝的照片需要在釘釘中展示,是以把照片存儲在OSS上是一個解決方案。

1.2.1 建立bucket

建立一個bucket用于儲存設備上送的照片。讀寫權限選擇公共讀

然後在bucket中建立photo目錄。

1.3 函數計算

經過物聯網平台規則引擎轉發過來的JSON資料,我們通過建立函數,把它轉發到釘釘機器人接口上,實作釘釘群中的消息通知

1.3.1 建立服務

新建立服務,如果需要記錄和回溯函數執行的日志,則需要開通日志服務,配置日志倉庫。

1.3.2 建立函數

使用空白模版建立函數,不需要觸發器,運作環境選擇python2.7

1.3.3 函數代碼
# -*- coding: utf-8 -*-

import logging
import json
import requests

# 釘釘消息發送實作
def post(data):
    webhook_url='https://oapi.dingtalk.com/robot/send?access_token=${Token}' #釘釘群機器人的webhook的URL
    headers = {'Content-Type': 'application/json; charset=utf-8'}
    post_data = json.dumps(data)
    try:
        response = requests.post(webhook_url, headers=headers, data=post_data)
        logging.info('Send success')
    except requests.exceptions.HTTPError as exc:
        logging.error("Send Error,HTTP error: %d, reason: %s" % (exc.response.status_code, exc.response.reason))
        raise
    except requests.exceptions.ConnectionError:
        logging.error("Send Error,HTTP connection error!")
        raise
    else:
        result = response.json()
        logging.info('Send Error:%s' % result)
        if result['errcode']:
            error_data = {"msgtype": "text", "text": {"content": "Send Error, reason:%s" % result['errmsg']}, "at": {"isAtAll": True}}
            logging.error("Send Error:%s" % error_data)
            requests.post(webhook_url, headers=headers, data=json.dumps(error_data))
        return result

# 發送釘釘markdown消息
def post_markdown(title,text):
    data = {
        "msgtype": "markdown",
        "markdown": {
            "title": title,
            "text": text
        },
        "at": {
            "atMobiles": [],
            "isAtAll": False
        }
    }
    post(data)

# 函數計算入口
def handler(event, context):
    logger = logging.getLogger()
    evt = json.loads(event)
    #OSS endpoint url
    post_markdown('告警','![screenshot](https://${bucket}.oss-cn-hangzhou.aliyuncs.com/photo/%s)' % evt.get('photo',''))
    logger.info('photo name is %s', evt.get('photo',''))
    return 'OK'           

2 裝置端開發

HC-SR501子產品感應到有人移動時,會輸出高電平,則觸發攝像頭拍照,并将照片檔案存儲到OSS,同時發送消息到IOT平台的/ProductName/${deviceName}/update消息隊列中

2.1 硬體安裝

  1. 連接配接好攝像頭
  2. 将HC-SR501 人體紅外感應器的vcc引腳接5v,也就是pin4,I/O引腳接pin18,GND引腳接地pin6

2.2 環境準備

我們在樹莓派上使用python2.7作為開發語言。

1. pip install aliyun-python-sdk-iot-client
2. pip install oss2
3. mkdir py-demo (項目程式檔案夾)
4. cd py-demo
5. mkdir photo (本地照片臨時目錄)
6. vim monitor.py           

2.3 代碼開發

monitor.py 内容如下:

# -*- coding: utf-8 -*-

import json
import uuid
import logging
from time import sleep
from picamera import PiCamera
import RPi.GPIO as GPIO
import oss2
import aliyunsdkiotclient.AliyunIotMqttClient as iot

# 參數定義
options = {
    'productKey': '${productKey}',  # 裝置辨別三元組
    'deviceName': '${deviceName}',  # 裝置辨別三元組
    'deviceSecret': '${deviceSecret}',  # 裝置辨別三元組
    'port': 1883,  # iot mqtt port
    'host': 'iot-as-mqtt.cn-shanghai.aliyuncs.com',  # iot mqtt endpoint
    'endpoint': 'http://oss-cn-hangzhou.aliyuncs.com',  # oss endpoint
    'ak': '${ak}',
    'sk': '${sk}',
    'bucket': '${bucket}',  # oss bucket
    'ir_pin': 24  # 人體紅外感應器設定讀取針腳标号
}

topic = '/' + options['productKey'] + '/' + options['deviceName'] + '/user/test'

# 拍照存oss,并發送通知
def takephoto2oss(client):

    #拍照
    photo_filename = str(uuid.uuid1()) + ".jpg"
    print('take photo :' + photo_filename)
    camera.capture('photo/' + photo_filename)

    #存OSS
    print('save photo to oss :' + photo_filename)
    bucket.put_object_from_file(
        'photo/' + photo_filename, 'photo/' + photo_filename)

    #消息上送
    payload_json = {
        'photo': photo_filename
    }
    print('send data to iot server: ' + str(payload_json))
    client.publish(topic, payload = str(payload_json))


def on_connect(client, userdata, flags_dict, rc):
    print("Connected with result code " + str(rc))


def on_disconnect(client, userdata, flags_dict, rc):
    print("Disconnected.")


if __name__ == '__main__':
    # GPIO 初始化
    GPIO.setmode(GPIO.BCM)
    GPIO.setwarnings(False)
    GPIO.setup(options['ir_pin'], GPIO.IN)

    # 攝像頭 初始化
    camera = PiCamera()
    camera.resolution = (640, 480)
    camera.vflip = True
    camera.hflip = True

    # OSS 初始化
    auth = oss2.Auth(options['ak'], options['sk'])
    bucket = oss2.Bucket(auth, options['endpoint'], options['bucket'])

    # IOT Mqtt 初始化
    client = iot.getAliyunIotMqttClient(options['productKey'], options['deviceName'], options['deviceSecret'], secure_mode = 3)
    client.on_connect = on_connect
    client.connect(host=options['productKey'] + '.' + options['host'], port=options['port'], keepalive = 60)

    while True:
        # 當高電平信号輸入時報警
        if GPIO.input(options['ir_pin']) == True:
            print " Someone is coming!"
            takephoto2oss(client)
        else:
            continue
        sleep(3)           

3 測試運作

3.1 裝置端運作

在py-demo檔案夾下運作

python monitor.py           

3.2 雲端檢視上送消息

進入裝置界面,觀察裝置狀态

在裝置的Topic清單中,也可以看到釋出的消息個數

進階版的産品,還提供了消息日志,而本例中的産品是基礎版,并無此功能。

3.3 釘釘群機器人結果

當有人出入門口的時候,釘釘群就可以收到機器人的消息推送

3.4 後續完善

如果大家有興趣,還可以進一步結合阿裡雲的人臉識别服務,再配合繼電器,實作人員考勤和出入門禁的功能

總結

通過阿裡雲物聯網平台,結合阿裡雲提供的其他産品和服務,使用者可以快速地建構一套基于雲邊端一體的IOT産品,開發者隻需關注業務層面的開發,而不用再花太多的精力在底層和通訊上,大大減少了開發周期,實作了産品的快速研發和疊代,節約了開發成本。