阿里云IOT Python SDK

来源:互联网 发布:js自动计算日期时间差 编辑:程序博客网 时间:2024/05/17 12:20

前一段时间研究了一下阿里云IOT官网上的连接demo,有java和c版本的,但是暂时没有python版本,于是参考了java版本的设计思路,编写了一个python版本的客户端,代码如下

alidemo.py

import socketimport uuidimport timefrom util import SignUtilfrom hashlib import sha1import paho.mqtt.publish as publishimport paho.mqtt.client as mqttimport os,logging#定义一个列表data = [1,3,2,5,7,6]#定义一个元组作为字典索引seq = ('productKey', 'deviceName', 'clientId', 'timestamp')'''开启TLS时的认证文件目录'''trust = 'F:/workspace/aliiot_python/root.cer' #修改为自己文件实际路径即可'''日志格式配置'''logging.basicConfig(level=logging.DEBUG,                format='[%(filename)s]-(line:%(lineno)d)-[%(funcName)s]-%(message)s----%(asctime)s',                datefmt='%y-%b %d %a %H:%M:%S')class SimpleClient4IOT :    def __init__(self, clientid=None):        #这里是客户端需要的参数,改成自己生成的即可        self.deviceName = "test"        self.productKey = "3y7iXH9wQDt"        self.secret = "IoW7r1E8WcEN2ROXEvPrH7e5V9B4tFJp"        self.clientId = self.get_localhost_ip()        #用于测试的topic        self.subTopic = "/" + self.productKey + "/" + self.deviceName + "/get"        self.pubTopic = "/" + self.productKey + "/" + self.deviceName + "/update"        #MQTT服务器地址,TLS连接使用ssl开头,这里选择直连不加ssl        self.targetServer = "ssl://" + self.productKey + ".iot-as-mqtt.cn-shanghai.aliyuncs.com:1883"        self.targetServer1 =  self.productKey + ".iot-as-mqtt.cn-shanghai.aliyuncs.com"        self.targetServer2 =  "3y7iXH9wQDt.iot-as-mqtt.cn-shanghai.aliyuncs.com"        dit = dict.fromkeys(seq)        dit['productKey'] = self.productKey #这个是对应用户在控制台注册的 设备productkey        dit['deviceName'] = self.deviceName #这个是对应用户在控制台注册的 设备name        dit['clientId'] = self.clientId        t = int(round(time.time()*1000)) #获取系统当前时间        dit['timestamp'] = str(t)        #客户端ID格式,两个||之间的内容为设备端自定义的标记,字符范围[0-9][a-z][A-Z]        self.params = dit        self.mqttclientId = self.clientId + "|securemode=2,signmethod=hmacsha1,timestamp=" + str(t) + "|"        self.mqttUsername = self.deviceName + "&" + self.productKey #mqtt用户名格式        self.mqttPassword = SignUtil.SignUtil().sign(sha1, self.secret, **self.params)#签名,固定使用hamc加密        self.connec()        time.sleep(1)#这里要加延时,否则订阅不成功,原因未知        self.client.subscribe(subTopic)        time.sleep(1)#这里要加延时,否则发送不成功,原因未知        self.client.publish(pubTopic,message)        self.client.loop_forever()#         while True:#             self.client.loop()    def connec(self):        logging.info("进行连接-服务器地址: " + self.targetServer1);          self.client = mqtt.Client(client_id=self.mqttclientId, clean_session=True, userdata=None, protocol=mqtt.MQTTv31)        self.client.on_publish = self.on_publish        self.client.on_connect = self.on_connect         self.client.on_disconnect = self.on_disconnect         self.client.on_message = self.on_message        self.client.on_subscribe = self.on_subscribe          self.client.tls_insecure_set(True) #检查hostname的cert认证        self.client.tls_set(trust) #设置认证文件        self.setAutho() #设置用户名和密码        self.client.connect( self.targetServer1 ,port=1883, keepalive=65) #向服务器发起连接    def setAutho(self):        self.client.username_pw_set(self.mqttUsername, self.mqttPassword)       #获得主机IP地址    def get_localhost_ip(self):        self.local_ip = socket.gethostbyname(socket.gethostname())        return self.local_ip    #获得主机MAC地址    def get_localhost_mac(self):         mac=uuid.UUID(int = uuid.getnode()).hex[-12:]         return ":".join([mac[e:e+2] for e in range(0,11,2)])       #创建客户端标识    def SetClientId(self):        return self.get_localhost_ip()    '''回调函数'''    def on_connect(self, mqttc, obj, flags, rc):#         print("Connection returned " + str(rc))        if str(rc)=='0':            logging.info("连接已被服务端接受")        elif str(rc)=='1':            logging.info("连接已拒绝,不支持的协议版本")        elif str(rc)=='2':            logging.info("连接已拒绝, 不合格的客户端标识符")        elif str(rc)=='3':            logging.info("连接已拒绝, 服务端不可用")        elif str(rc)=='4':            logging.info("连接已拒绝,无效的用户名或密码")    def on_message(self, mqttc, obj, msg):        print(msg.topic+" "+str(msg.qos)+" "+str(msg.payload))#         self.client.disconnect()    def on_publish(self, mqttc, obj, mid):        print("mid: "+str(mid))    def on_subscribe(self, mqttc, obj, mid, granted_qos):        print("Subscribed: "+str(mid)+" "+str(granted_qos))    def on_log(self, mqttc, obj, level, string):        print(string)    def on_disconnect(self, client, userdata, rc):        if rc != 0:            print("连接断开,准备重新发起连接.")            self.client.reconnect()s = SimpleClient4IOT()

signutil.py 签名生成

    def sign(self, Method, key, **params):                """ 数字签名程序"""        #字典排序生成规范化请求字符串        sortedKey = sorted(params.iteritems(), key=lambda d:d[0] )        temp = sortedKey[0]+sortedKey[1]+sortedKey[2]+sortedKey[3]        list_str = ''.join(temp)        return self.encryptHMAC(list_str, key, Method)        """HMAC加密"""    def encryptHMAC(self, content, key, Method):            a = hmac.new(key, content, Method)        return a.digest().encode('hex').rstrip('')

跟java版本相比,python在选择服务器地址时用tcp直连加证书认证
server地址不加ssl,带上ssl地址解析失败,这点跟java客户端不一样。

运行结果:其中连接过程中有个重连动作,订阅了subtopic,云端发送一个消息,可以正常显示

这里写图片描述

完整项目地址:http://git.oschina.net/DSSDD/aliiot_python/tree/master

原创粉丝点击