基于阿里云物联网平台开发终端设备的通用方法(python语言实现)

自古美人都是妖i 提交于 2020-08-13 06:47:05

万物互联,物联网是未来的发展趋势。如何将设备接入物联网平台,实现设备之间的通信呢?本文以阿里云物联网平台为例,使用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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!