基於阿里雲物聯網平臺開發終端設備的通用方法(python語言實現)

萬物互聯,物聯網是未來的發展趨勢。如何將設備接入物聯網平臺,實現設備之間的通信呢?本文以阿里雲物聯網平臺爲例,使用python開發語言,介紹設備終端接入平臺的通用方法。閱讀本文需要了解MQTT協議、python等相關知識。

阿里雲物理網平臺

阿里雲物理網平臺是近幾年阿里推出的一項功能服務,提供了一站式的設備接入、設備管理、監控運維、數據流轉、數據存儲等服務,數據按照實例維度隔離,可根據業務規模靈活提升規格,具備高可用性、高併發、高性價比的特性,是設備上雲的首選。以上是官方介紹,本文不對其具體功能體驗分析,主要是介紹設備接入方法。

8小時Python零基礎輕鬆入門

雲端設置

首先在物理網平臺添加產品和設備,一個產品可對應多個設備,每個產品和設備都有唯一的編號。我們需要知道這些編號,用於終端設備註冊認證使用,設備有兩種認證方式,本文以一機一密認證方式爲例,即使用設備三元組product_keydevice_namedevice_secret.
在這裏插入圖片描述

設備接入

有了三元組數據之後,我們就可以在終端設備上開發了。
首先下載安裝阿里雲基於python第三方庫paho-mqtt開發的SDK

pip install aliyun-iot-linkkit

然後編寫自己的類或函數調用SDK,下面是通用代碼案例。

# -*- coding: utf-8 -*-
__author__ = "kaspar.s"
__date__ = '2020/6/13 17:02'
#  與 阿里雲iot平臺進行連接
#  MQTT協議

import os,sys,configparser
from linkkit import linkkit
from med.logging import *

logger = logging.getLogger(__name__)

# 讀取配置文件
# 注:我是將三元組數據存放在數據庫中,配置文件是要訂閱的話題
cfg = configparser.ConfigParser()
cfg.read('config.ini')
topic_pick = cfg.get('TOPIC','pick')
topic_control  = cfg.get('TOPIC','control')

# 連接回調返回
CALLBACK_ON_CONNECT ={
    0 : 'Connection successful',
    1 : 'Connection refused - incorrect protocol version',
    2 : 'Connection refused - invalid client identifier',
    3 : 'Connection refused - server unavailable',
    4 : 'Connection refused - bad username or password',
    5 : 'Connection refused - not authorised',
    6 : 'SSL wrong - ca file/data wrong',
    7 : 'MQTT parameter wrong',
    8 : 'Connect Timeout',
    9 : 'network error'
}

# 連接阿里雲iot中心的類
class IOT_platform():

    def __init__(self):

        try:
            # 一機一密
            self.lk = linkkit.LinkKit(
                host_name=device_info.host_name,
                product_key=device_info.ProductKey,
                device_name=device_info.DeviceName,
                device_secret=device_info.DeviceSecret)

            self.lk.on_connect = self._on_connect
            self.lk.on_disconnect = self._on_disconnect
            # 訂閱結果通過on_subscribe_topic通知用戶
            self.lk.on_subscribe_topic = self._on_subscribe_topic
            self.lk.on_topic_message = self._on_topic_message
            self.lk.on_publish_topic = self._on_publish_topic
            self.lk.on_unsubscribe_topic = self._on_unsubscribe_topic
            self.lk.on_topic_rrpc_message = self._on_topic_rrpc_message

            self.lk.enable_logger(logging.INFO)  # 開啓日誌
        except:
            logger.error(sys._getframe().f_code.co_name + '無效設備')
            
    def _on_connect(self,session_flag, rc, userdata):
        logger.info("on_connect:%d,rc:%s" % (session_flag, CALLBACK_ON_CONNECT[rc] ))

        if rc != 0 : # 連接失敗
         
            # 進行一些操作
        else:
             # 連接成功,進行一些操作

    def _on_disconnect(self,rc, userdata):
        logger.info("on_disconnect:rc:%d" % rc)

    def start(self):
        # 啓動連接
        """
         注:調用該函數之後如果因爲網絡處於連接斷開狀態導致連接失敗,用戶無需再次調用connect_async()、
         SDK會再次嘗試連接雲端。
        """
        try:
            if self.lk.check_state() != self.lk.LinkKitState.CONNECTED:
                self.lk.connect_async()
            else:
                logger.info('Init, already connected to IOT center.')

        except Exception as e:
            logger.error(e)
           
    """
    從雲端接收消息
    """
    def _on_subscribe_topic(self,mid, granted_qos, userdata):
        logger.info("on_subscribe_topic mid:%d, granted_qos:%s" %(mid, str(','.join('%s' % it for it in granted_qos))))

    # 接收與處理來自雲端的消息
    def _on_topic_message(self,topic, payload, qos, userdata):
        logger.info("on_topic_message:" + topic + " payload:" + str(payload) + " qos:" + str(qos))
		# 這裏是重要的部分,處理來自平臺的消息,根據不同的topic,進行不同的處理
        # 處理消息
        if  topic_pick in topic:  
            pass
        elif topic_control in topic:   
            pass
        else:
            pass


    def subscribe_topic(self,topic):
        if self.lk.check_state() == self.lk.LinkKitState.CONNECTED:
            # 訂閱雲端消息
            rc, mid = self.lk.subscribe_topic(self.lk.to_full_topic(topic)) 

    """
    發送消息到雲端
    """
    def _on_publish_topic(self,mid, userdata):
        logger.info("on_publish_topic mid:%d" % mid)

    def publish_topic(self,topic,payload):
        if self.lk.check_state() == self.lk.LinkKitState.CONNECTED:
            rc, mid = self.lk.publish_topic(self.lk.to_full_topic(topic), payload)

    """
    取消消息訂閱
    """
    def _on_unsubscribe_topic(self,mid, userdata):
        logger.info("on_unsubscribe_topic mid:%d" % mid)
        pass

    def unsubscribe_topic(self,topic):
        if self.lk.check_state() != self.lk.LinkKitState.CONNECTED:
            rc, mid = self.lk.unsubscribe_topic(self.lk.to_full_topic(topic))

    """
    RRPC  
    """
    def subscribe_rrpc_topic(self,topic):
        if self.lk.check_state() == self.lk.LinkKitState.CONNECTED:
            # 訂閱雲端rrpc消息
            rc, mid = self.lk.subscribe_rrpc_topic(self.lk.to_full_topic(topic)) #  "user/test"

    def _on_topic_rrpc_message(self,id,topic,payload,qos,userdata):
        logger.info("on_topic_rrpc_message:" + topic + " payload:" + str(payload) + " qos:" + str(qos))

       pass

之後,我們實例化類並訂閱相關話題,編寫處理話題的函數。注意接收的是bytes類型,需要進行轉換。

g_clent_iot = IOT_platform()
g_clent_iot.start()
time.sleep(1)
g_clent_iot.subscribe_topic(topic_pick)
g_clent_iot.subscribe_topic(topic_control)
# 處理話題的函數
def dealpayload( payload):
	# 將bytes 轉換爲 dict
	str = str(payload, encoding="utf-8")
	payload = eval(str)

注:eval的作用是用來執行一個字符串表達式,並返回表達式的值。

以上,就是基於阿里雲物理網平臺開發終端設備的通用方法。如有不完善地方歡迎指正補充。

二賽君整理髮布,轉載請註明出處。謝謝。如果文章對您有所幫助,歡迎打賞鼓勵。
在這裏插入圖片描述

相關參考:

  1. https://www.aliyun.com/product/iot?spm=5176.12825654.eofdhaal5.21.e9392c4ajEUjR1
  2. https://help.aliyun.com/document_detail/30522.html?spm=5176.cniot.0.0.3a9211fauWK4P1
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章