本文主要是介绍IOTOS物联中台开发驱动支持精华隆周界子系统设备,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
本文章为原创,转载请注明出处!
登录平台:IOTOS®爱投斯物联中台
账号:iotos_test 密码:iotos123
代码地址:IOTOSDK-Python: IOTOS Python版本SDK,自带原生接口和采集引擎 (gitee.com)
目录
前言
驱动目的
适用范围
使用示例
驱动代码
驱动解析
-
前言
精华隆周界可以连接多个设备并进行监控,作为主机,可以通过TCP/IP将数据包转发出来。
-
驱动目的
驱动将精华隆周界的数据解析并上传至中台以便于更好的进行可视化展示
-
适用范围
精华隆周界
-
使用示例
- 首先,连接好精华隆周界主机,在其下绑定相应的设备:
- 进入爱投斯中台,账号为iotos_test,密码为iotos123,创建网关
- 填好网关名称后点击确认
- 依次点击【系统设备】->【模板驱动】->【我的模板】,点击右上角创建模板。 填写模板名称和相关的参数,其中tcp为中台需要打开的端口,与精华隆主机的配置保持一致
- 创建设备实例,点击【系统设备】 -> 【通信网关】 -> 【设备实例】->【创建设备】
- 填写设备名称,选择刚才创建的网关和模板即可(检查一下驱动根配置的“driver”参数,若在创建模板时已按要求配置,则现在无需修改,否则则需要在此进行配置,配置标准见创建模板)。
- 创建数据点,点击【我的设备】 -> 【通信网关】 -> 【设备实例】 -> 【数据点】,并在【设备实例】下拉列表选择刚刚创建的设备实例
- 删除系统自带的四个数据点,然后点击右边的创建数据点,填写名称,名称为周界主机下面的设备的ID
- 开启云网关,密码为账号密码
- 在精华隆主机的操作界面配置数据转发的端口并且打开对外协议,url为中台的地址,端口号与中台tcp参数的值保持一致
- 点击 【我的设备】 -> 【通信网关】 -> 【设备实例】->【数据点】,选择刚才创建的设备实例
- 即可查看数据已经上报成功
在报警主机中进行布撤防,中台的数据也会发生相应的变化,报警状态也可以进行同步,放置物联组态上还可以做到报警提示或者其他联动效果
-
驱动代码
#!coding:utf8
import sysimport json
import base64
from Crypto.Cipher import AESsys.path.append("..")
reload(sys)
sys.setdefaultencoding('gbk')
from driver import *
from jcomm import *
import threading#打印日志
import logginglogger = logging.getLogger()
logging.basicConfig(level=logging.ERROR,format='%(asctime)s %(threadName)s %(levelname)s %(filename)s:%(lineno)d %(funcName)s %(message)s')
logger.setLevel(logging.ERROR & logging.INFO)#except,防止socket报error: [Errno 104] Connection reset by peer
from socket import error as SocketError
import errno#AES的加解密类
class EncryptDate:def __init__(self, rec_data):self.key = self.create_key(rec_data) # 初始化密钥self.length = AES.block_size # 初始化数据块大小self.aes = AES.new(self.key, AES.MODE_ECB) # 初始化AES,ECB模式的实例# 截断函数,去除填充的字符self.unpad = lambda rec_data: rec_data[0:-ord(rec_data[-1])]#根据传过来的数据 取出hostid 产生用于AES加密的密钥key@staticmethoddef create_key(res):newkey = ''# print len(str(res['hostId']))if len(str(res['hostId'])) != 12:for i in range(0, (12 - len(str(res['hostId'])))):newkey = newkey + '0'newkey = newkey + str(res['hostId'])else:newkey = str(res['hostId'])newkey = newkey + str(res['hostId'] + 12345)[-4:]#logging.info (newkey)return newkeydef pad(self, text):"""#填充函数,使被加密数据的字节码长度是block_size的整数倍"""count = len(text.encode('utf-8'))add = self.length - (count % self.length)entext = text + (chr(add) * add)return entextdef encrypt(self, encrData): # 加密函数res = self.aes.encrypt(self.pad(encrData).encode("utf8"))msg = str(base64.b64encode(res))return msgdef decrypt(self, decrData): # 解密函数res = base64.decodestring(decrData.encode("utf8"))msg = self.aes.decrypt(res).decode("utf8")return self.unpad(msg)"""定义线程,防止在collecting里面两组数据上传时数据过慢
"""
#8023第一次的数据
class Set8023firstDataThreading(threading.Thread,JLib):def __init__(self, driver):threading.Thread.__init__(self)JLib.__init__(self)self.driver = driverdef run(self):logging.info(u'8023 first data setvalue')# logging.info(getattr(self.driver, __8023firstData))# logging.info(self.driver._Alarm__8023firstData)self.driver.__8023firstdataDict = eval(self.driver._Alarm__8023firstData)data8023SetList = self.driver.__8023firstdataDict['deviceList']for i in data8023SetList:# 排除温湿度的设备if str(i["deviceId"]).find('10007') != -1 or str(i["deviceId"]).find('10025') != -1:continueelse:try:# logger.info(i["deviceName"].decode('utf-8'))self.driver.setValue(unicode(str(i["deviceId"]), "utf-8"), (i["deviceName"] + ',' + self.driver._Alarm__deviceStatus[i["deviceStatus"]] + ',' +self.driver._Alarm__alarmStatus[i["armingStatus"]]))except Exception as e:if "deviceName" not in i:self.driver.setValue(unicode(str(i["deviceId"]), "utf-8"), ('未知' + ',' + self.driver._Alarm__deviceStatus[i["deviceStatus"]] + ',' +self.driver._Alarm__alarmStatus[i["armingStatus"]]))logging.info(str(i["deviceId"]))continue#8023第二次的数据
class Set8023DataThreading(threading.Thread,JLib):def __init__(self, driver):threading.Thread.__init__(self)JLib.__init__(self)self.driver = driverdef run(self):logging.info(u'8023 data setvalue')self.driver.__8023dataDict = eval(self.driver._Alarm__8023data)data8023SetList = self.driver.__8023dataDict['deviceList']for i in data8023SetList:# 排除温湿度的设备if str(i["deviceId"]).find('10007') != -1 or str(i["deviceId"]).find('10025') != -1:continueelse:try:# logger.info(i["deviceName"].decode('utf-8'))self.driver.setValue(unicode(str(i["deviceId"]), "utf-8"), (i["deviceName"] + ',' + self.driver._Alarm__deviceStatus[i["deviceStatus"]] + ',' +self.driver._Alarm__alarmStatus[i["armingStatus"]]))except Exception as e:if "deviceName" not in i:self.driver.setValue(unicode(str(i["deviceId"]), "utf-8"), ('未知' + ',' + self.driver._Alarm__deviceStatus[i["deviceStatus"]] + ',' +self.driver._Alarm__alarmStatus[i["armingStatus"]]))logging.info(str(i["deviceId"]))continue#8130的数据上传线程
class Set8130DataThreading(threading.Thread,JLib):def __init__(self, driver):threading.Thread.__init__(self)JLib.__init__(self)self.driver = driverdef run(self):logging.info(u'8130 data setvalue')self.driver.__8130dataDict = eval(self.driver._Alarm__8130data.replace('null', '""'))data8130SetList = self.driver.__8130dataDict['data']for i in data8130SetList:# logging.info(unicode(str(i["deviceId"]), "utf-8"))# logging.info(type(i["param"]["temperature"]))try:self.driver.setValue(unicode(str(i["deviceId"]), "utf-8"),((i["deviceName"] + ',' + i["param"]["humidity"] + ',' + str(int(i["param"]["temperature"]) * 0.01)) + ',' + self.driver._Alarm__deviceStatus[i['deviceStatus']]))except Exception as e:#一些温湿度没有上线,没有param参数。if i["param"]== "":self.driver.setValue(unicode(str(i["deviceId"]), "utf-8"),(i["deviceName"] + ',' + '' + ',' + '' + ',' +self.driver._Alarm__deviceStatus[i['deviceStatus']]))else:logging.info(e.message)logging.info(str(i["deviceId"]))continue# 没有用到过
class Set8026dataThreading(threading.Thread,JLib):def __init__(self, driver):threading.Thread.__init__(self)JLib.__init__(self)self.driver = driverdef run(self):logging.info(u'8026 data setvalue')self.driver.__8026dataDict = eval(self.driver._Alarm__8026data.replace('null', '""'))#判断8026是否有报警情况for i in self.driver.__8026dataDict['zoneList']:if i['zoneStatus']==1:logging.info(33333333333333333333333333)if self.driver._Alarm__8023firstData!='' and self.driver._Alarm__8023data=='':self.driver.__8023firstdataDict = eval(self.driver._Alarm__8023firstData)# data8023SetList = self.driver.__8023firstdataDict['deviceList']for _8023i in self.driver.__8023firstdataDict['deviceList']:if _8023i['deviceId'] == self.driver.__8026dataDict['deviceId']:logging.info('99999999999999999999999999999999999999999')_8023i['deviceStatus'] = 3else:passlogging.info(self.driver.__8023firstdataDict['deviceList'])elif self.driver._Alarm__8023firstData!='' and self.driver._Alarm__8023data!='':self.driver.__8023dataDict = eval(self.driver._Alarm__8023data)# data8023SetList = self.driver.__8023dataDict['deviceList']for _8023i in self.driver.__8023dataDict['deviceList']:if _8023i['deviceId'] == self.driver.__8026dataDict['deviceId']:logging.info('99999999999999999999999999999999999999999')_8023i['deviceStatus'] = 3else:passelse:passelse:continueif self.driver.__8023dataDict:return self.driver.__8023firstdataDict , self.driver.__8023dataDictelse:return self.driver.__8023firstdataDict, ''#驱动运行的类
class Alarm(IOTOSDriverI):#初始化,获取设备实例中的tcp参数,开启中台的tcp端口def InitComm(self, attrs=None):self.__port = self.sysAttrs['config']['param']['tcp']logging.info(str(self.__port))self.__tcpServer = TcpServerThread(self, self.__port)self.__tcpServer.setDaemon(True)self.__tcpServer.start()# self.__data='' #8026存储数据self.__flat=0 #拼接的标识变量self.__sumdata='' #第一种情况分包后拼接后的字符串self.__sumdata2='' #第二种情况分包后拼接后的字符串self.__8023flat = 1 #用于判断是否为第一次接收到8023self.__8023firstData = '' #用于接收第一次收到的8023self.__8023data = '' #保存8023的数据self.__8030senddata = '' #保存从机发过来的一个命令用于8030发送数据的修改self.__8130data='' #保存温湿度的数据# self.__8016sendData_json = {} #保存主动询问设备的防区状态id和typeself.__deviceStatus = {0:"未知状态",1:"在线状态",2:"离线状态",3:"报警状态",4:"故障状态"} #设备状态self.__alarmStatus = {0:"未知状态",1:"外出布防",2:"在家布防",3:"撤防状态",4:"布防延时"} #布防状态logging.info(self.sysAttrs['name'] + u' TCP端口' + str(self.__port) + u"已启动监听!")#设置tcp回调函数,接收主机传过来的数据def tcpCallback(self,data):# logging.info(data)#一条cmd单独分包:判断是否分包,没有\n则分包了,进行合并,由于合并的最后一个包有\n,则通过判断__sumdata是否为空判断是否是需要合并的包,若此时的__sumdata不为空,说明正在合并,把最后一个包加上即可if data.find('\n')==-1:self.__sumdata = self.__sumdata+data# logging.info(self.__sumdata)else:if self.__sumdata !='':self.__sumdata = self.__sumdata+datadata = self.__sumdata# logging.info(data)self.__sumdata=''dataList = data.split('\n')# logging.info(dataList)for i in dataList:dataList_i = iif dataList_i=='':continue#多条cmd,最后一个分包elif dataList_i.find("{") == -1 or dataList_i.find("}") == -1:# logging.info(dataList_i)self.__sumdata2 = self.__sumdata2+dataList_iself.__flat = self.__flat +1# logging.info(self.__flat)if self.__flat == 2:self.__flat =0dataList_i = self.__sumdata2# logging.info(dataList_i)self.__sumdata2=''else:continuenewdata = eval(dataList_i)#报警主机发来请求登录信息if newdata['cmd']==8001:self.__8030senddata = newdata# self.__8016senddata = newdata"""进行加解密"""obj_endata=EncryptDate(rec_data=newdata)#响应登录请求send_data = json.dumps({"code":0,"platformName":"aiotos"})send_data = obj_endata.encrypt(send_data)newdata["data"]=send_datanewdata["cmd"]=8101data = json.dumps(newdata)time.sleep(0.5)self.__tcpServer.send(data + "\n")time.sleep(0.5)# #心跳包,直接跳过# elif data["cmd"]==8000:# logging.info(u"8000 rec , 心跳包")#设备列表数据包elif newdata['cmd']==8023:time.sleep(1)#拿去数据包并解密传至collectingobj_endata = EncryptDate(rec_data=newdata)if self.__8023flat == 1:self.__8023firstData = obj_endata.decrypt(newdata["data"])self.__8023flat = 0logging.info(u'8023 : first data received is ' + str(self.__8023firstData))else:self.__8023data = obj_endata.decrypt(newdata["data"])logging.info(u'8023 : data received is ' + str(self.__8023data))#中台响应8123,加密send_data = json.dumps({"code": 0})send_data = obj_endata.encrypt(send_data)# logging.info(send_data)newdata["data"]=send_datanewdata["cmd"]=8123data = json.dumps(newdata)time.sleep(0.5)self.__tcpServer.send(data + "\n")# logging.info(u'8123 !deta send is' +str(data))elif newdata['cmd']==8026:pass#中台响应8126# obj_endata = EncryptDate(rec_data=newdata)# self.__8026data = obj_endata.decrypt(newdata["data"])## logging.info(u'8026 : data received is ' + str(self.__8026data))# # if self.__8026data!='' and (self.__8023firstData!='' or self.__8023data!=''):# # try:# # self.__8023firstdataDict,self.__8023dataDict = Set8026dataThreading(self).start()# # except Exception as e:# # pass# # else:# # pass# send_data = json.dumps({"code": 0})# send_data = obj_endata.encrypt(send_data)# # logging.info(send_data)# newdata["data"] = send_data# newdata["cmd"] = 8126# data = json.dumps(newdata)# time.sleep(0.5)# self.__tcpServer.send(data + "\n")# logging.info(u'8126 !deta send is' + str(data))#8024为布撤防状态改变时发送,发送到来时将原有的8023数据修改掉elif newdata['cmd']==8024:obj_endata = EncryptDate(rec_data=newdata)self.__8024data = obj_endata.decrypt(newdata["data"])logging.info(u'8024 : data received is ' + str(self.__8024data))self.__8024dataDict = eval(self.__8024data)if self.__8023firstData != '':__8023MidFirstData = eval(self.__8023firstData)for i in self.__8024dataDict['deviceList']:for j in __8023MidFirstData['deviceList']:if i['deviceId'] == j['deviceId']:# __8023MidFirstData['deviceList'].remove(j)if 'armingStatus' in i:j['armingStatus'] = i['armingStatus']if 'deviceStatus' in i:j['deviceStatus'] = i['deviceStatus']logging.info(__8023MidFirstData)# logging.info(j)# __8023MidFirstData['deviceList'].append(j)# logging.info(__8023MidFirstData)self.__8023firstData = json.dumps(__8023MidFirstData,ensure_ascii=False,encoding="utf-8")logging.info(self.__8023firstData)else:continueif self.__8023data != '':__8023MidData = eval(self.__8023data)for i in self.__8024dataDict['deviceList']:for j in __8023MidData['deviceList']:if i['deviceId'] == j['deviceId']:# __8023MidData['deviceList'].remove(j)if 'armingStatus' in i:j['armingStatus'] = i['armingStatus']if 'deviceStatus' in i:j['deviceStatus'] = i['deviceStatus']logging.info(__8023MidFirstData)self.__8023data = json.dumps(__8023MidData,ensure_ascii=False,encoding="utf-8")else:continue# 报警事件传递过来,根据报警的id去8023数据中查找,若有则将deviceStatus改为3即可elif newdata['cmd'] == 8011:obj_endata = EncryptDate(rec_data=newdata)self.__8011data = obj_endata.decrypt(newdata["data"])logging.info(u'8011 : data received is ' + str(self.__8011data))self.__8011dataDic = eval(self.__8011data.replace('null',''))if self.__8023firstData != '':__8023MidFirstData = eval(self.__8023firstData)for i in __8023MidFirstData['deviceList']:if i['deviceId'] == self.__8011dataDic['deviceId']:i['deviceStatus'] = 3logging.info(__8023MidFirstData)self.__8023firstData = json.dumps(__8023MidFirstData, ensure_ascii=False, encoding="utf-8")if self.__8023data != '':__8023MidData = eval(self.__8023data)for i in __8023MidData['deviceList']:if i['deviceId'] == self.__8011dataDic['deviceId']:i['deviceStatus'] = 3logging.info(__8023MidData)self.__8023data = json.dumps(__8023MidData, ensure_ascii=False, encoding="utf-8")# 中台响应8111,加密send_data = json.dumps({"code": 0})send_data = obj_endata.encrypt(send_data)# logging.info(send_data)newdata["data"] = send_datanewdata["cmd"] = 8111data = json.dumps(newdata)time.sleep(0.5)self.__tcpServer.send(data + "\n")elif newdata['cmd']==8130:# 拿去数据包并解密传至collectingobj_endata = EncryptDate(rec_data=newdata)self.__8130data = obj_endata.decrypt(newdata["data"])logging.info(u'8130 : data received is ' + str(self.__8130data))elif newdata['cmd']==8000:logging.info(u'cmd' + str(newdata['cmd']))logging.info(newdata["data"])obj_endata = EncryptDate(rec_data=newdata)send_data = json.dumps({"code": 0})send_data = obj_endata.encrypt(send_data)newdata["data"] = send_datanewdata["cmd"] = 8100data = json.dumps(newdata)time.sleep(1)self.__tcpServer.send(data + "\n")# 8023设备状态的数据上传成功后再发送8030请求温湿度的值# logging.info('start')if self.__8030senddata:try:obj_endata = EncryptDate(rec_data=self.__8030senddata)send_data = json.dumps({"deviceType": 85})send_data = obj_endata.encrypt(send_data)self.__8030senddata["data"] = send_dataself.__8030senddata["cmd"] = 8030data = json.dumps(self.__8030senddata)# time.sleep(0.5)self.__tcpServer.send(data + "\n")# logging.info(u'8030 data send is' + str(data))except SocketError as e:logging.info(self.__8030senddata)"""断掉后再次开启端口进行重启"""self.__tcpServer = TcpServerThread(self, self.__port)self.__tcpServer.setDaemon(True)self.__tcpServer.start()if e.errno != errno.ECONNRESET:raise # Not error we are looking forpass # Handle error here.else:logging.info(u'其他cmd' + str(newdata['cmd']))logging.info(newdata["data"])# 8023设备状态的数据上传成功后再发送8030请求温湿度的值#logging.info('start')if self.__8030senddata:try:obj_endata = EncryptDate(rec_data=self.__8030senddata)send_data = json.dumps({"deviceType": 85})send_data = obj_endata.encrypt(send_data)self.__8030senddata["data"] = send_dataself.__8030senddata["cmd"] = 8030data = json.dumps(self.__8030senddata)time.sleep(0.5)self.__tcpServer.send(data + "\n")# logging.info(u'8030 data send is' + str(data))except SocketError as e:logging.info(self.__8030senddata)"""断掉后再次开启端口进行重启"""self.__tcpServer = TcpServerThread(self, self.__port)self.__tcpServer.setDaemon(True)self.__tcpServer.start()if e.errno != errno.ECONNRESET:raise # Not error we are looking forpass # Handle error here.# 连接状态回调def connectEvent(self, state):self.online(state)try:if state == True:self.pauseCollect = Falseelse:self.pauseCollect = Trueexcept Exception, e:logging.info(u'硬件心跳错误, ' + e.message)def Collecting(self, dataId):if self.__8023firstData !='' and self.__8023firstData != self.__8023data:# logging.info(1234567890)Set8023firstDataThreading(self).start()else:passif self.__8023data:Set8023DataThreading(self).start()time.sleep(1)else:passif self.__8130data:Set8130DataThreading(self).start()time.sleep(1)else:pass# time.sleep(2)return ()
-
驱动解析
- 编写环境为python2(python3也可以),首先需要导入加解密所需要的base64、AES包和中台通讯用的driver包以及其他数据解析所用的包
#!coding:utf8
import sysimport json
import base64
from Crypto.Cipher import AESsys.path.append("..")
reload(sys)
sys.setdefaultencoding('gbk')
from driver import *
from jcomm import *
import threading#打印日志
import logginglogger = logging.getLogger()
logging.basicConfig(level=logging.ERROR,format='%(asctime)s %(threadName)s %(levelname)s %(filename)s:%(lineno)d %(funcName)s %(message)s')
logger.setLevel(logging.ERROR & logging.INFO)#except,防止socket报error: [Errno 104] Connection reset by peer
from socket import error as SocketError
import errno
- 定义AES加解密的类
#AES的加解密类
class EncryptDate:def __init__(self, rec_data):self.key = self.create_key(rec_data) # 初始化密钥self.length = AES.block_size # 初始化数据块大小self.aes = AES.new(self.key, AES.MODE_ECB) # 初始化AES,ECB模式的实例# 截断函数,去除填充的字符self.unpad = lambda rec_data: rec_data[0:-ord(rec_data[-1])]#根据传过来的数据 取出hostid 产生用于AES加密的密钥key@staticmethoddef create_key(res):newkey = ''# print len(str(res['hostId']))if len(str(res['hostId'])) != 12:for i in range(0, (12 - len(str(res['hostId'])))):newkey = newkey + '0'newkey = newkey + str(res['hostId'])else:newkey = str(res['hostId'])newkey = newkey + str(res['hostId'] + 12345)[-4:]#logging.info (newkey)return newkeydef pad(self, text):"""#填充函数,使被加密数据的字节码长度是block_size的整数倍"""count = len(text.encode('utf-8'))add = self.length - (count % self.length)entext = text + (chr(add) * add)return entextdef encrypt(self, encrData): # 加密函数res = self.aes.encrypt(self.pad(encrData).encode("utf8"))msg = str(base64.b64encode(res))return msgdef decrypt(self, decrData): # 解密函数res = base64.decodestring(decrData.encode("utf8"))msg = self.aes.decrypt(res).decode("utf8")return self.unpad(msg)
- 定义数据上传的线程,防止全部留在collecting里面会出现延迟上传
#8023第一次的数据
class Set8023firstDataThreading(threading.Thread,JLib):def __init__(self, driver):threading.Thread.__init__(self)JLib.__init__(self)self.driver = driverdef run(self):logging.info(u'8023 first data setvalue')# logging.info(getattr(self.driver, __8023firstData))# logging.info(self.driver._Alarm__8023firstData)self.driver.__8023firstdataDict = eval(self.driver._Alarm__8023firstData)data8023SetList = self.driver.__8023firstdataDict['deviceList']for i in data8023SetList:# 排除温湿度的设备if str(i["deviceId"]).find('10007') != -1 or str(i["deviceId"]).find('10025') != -1:continueelse:try:# logger.info(i["deviceName"].decode('utf-8'))self.driver.setValue(unicode(str(i["deviceId"]), "utf-8"), (i["deviceName"] + ',' + self.driver._Alarm__deviceStatus[i["deviceStatus"]] + ',' +self.driver._Alarm__alarmStatus[i["armingStatus"]]))except Exception as e:if "deviceName" not in i:self.driver.setValue(unicode(str(i["deviceId"]), "utf-8"), ('未知' + ',' + self.driver._Alarm__deviceStatus[i["deviceStatus"]] + ',' +self.driver._Alarm__alarmStatus[i["armingStatus"]]))logging.info(str(i["deviceId"]))continue#8023第二次的数据
class Set8023DataThreading(threading.Thread,JLib):def __init__(self, driver):threading.Thread.__init__(self)JLib.__init__(self)self.driver = driverdef run(self):logging.info(u'8023 data setvalue')self.driver.__8023dataDict = eval(self.driver._Alarm__8023data)data8023SetList = self.driver.__8023dataDict['deviceList']for i in data8023SetList:# 排除温湿度的设备if str(i["deviceId"]).find('10007') != -1 or str(i["deviceId"]).find('10025') != -1:continueelse:try:# logger.info(i["deviceName"].decode('utf-8'))self.driver.setValue(unicode(str(i["deviceId"]), "utf-8"), (i["deviceName"] + ',' + self.driver._Alarm__deviceStatus[i["deviceStatus"]] + ',' +self.driver._Alarm__alarmStatus[i["armingStatus"]]))except Exception as e:if "deviceName" not in i:self.driver.setValue(unicode(str(i["deviceId"]), "utf-8"), ('未知' + ',' + self.driver._Alarm__deviceStatus[i["deviceStatus"]] + ',' +self.driver._Alarm__alarmStatus[i["armingStatus"]]))logging.info(str(i["deviceId"]))continue#8130的数据上传线程
class Set8130DataThreading(threading.Thread,JLib):def __init__(self, driver):threading.Thread.__init__(self)JLib.__init__(self)self.driver = driverdef run(self):logging.info(u'8130 data setvalue')self.driver.__8130dataDict = eval(self.driver._Alarm__8130data.replace('null', '""'))data8130SetList = self.driver.__8130dataDict['data']for i in data8130SetList:# logging.info(unicode(str(i["deviceId"]), "utf-8"))# logging.info(type(i["param"]["temperature"]))try:self.driver.setValue(unicode(str(i["deviceId"]), "utf-8"),((i["deviceName"] + ',' + i["param"]["humidity"] + ',' + str(int(i["param"]["temperature"]) * 0.01)) + ',' + self.driver._Alarm__deviceStatus[i['deviceStatus']]))except Exception as e:#一些温湿度没有上线,没有param参数。if i["param"]== "":self.driver.setValue(unicode(str(i["deviceId"]), "utf-8"),(i["deviceName"] + ',' + '' + ',' + '' + ',' +self.driver._Alarm__deviceStatus[i['deviceStatus']]))else:logging.info(e.message)logging.info(str(i["deviceId"]))continue
- 定义驱动运行的类,进行初始化和参数的获取,开启tcp监听的端口
#驱动运行的类
class Alarm(IOTOSDriverI):#初始化,获取设备实例中的tcp参数,开启中台的tcp端口def InitComm(self, attrs=None):self.__port = self.sysAttrs['config']['param']['tcp']logging.info(str(self.__port))self.__tcpServer = TcpServerThread(self, self.__port)self.__tcpServer.setDaemon(True)self.__tcpServer.start()# self.__data='' #8026存储数据self.__flat=0 #拼接的标识变量self.__sumdata='' #第一种情况分包后拼接后的字符串self.__sumdata2='' #第二种情况分包后拼接后的字符串self.__8023flat = 1 #用于判断是否为第一次接收到8023self.__8023firstData = '' #用于接收第一次收到的8023self.__8023data = '' #保存8023的数据self.__8030senddata = '' #保存从机发过来的一个命令用于8030发送数据的修改self.__8130data='' #保存温湿度的数据# self.__8016sendData_json = {} #保存主动询问设备的防区状态id和typeself.__deviceStatus = {0:"未知状态",1:"在线状态",2:"离线状态",3:"报警状态",4:"故障状态"} #设备状态self.__alarmStatus = {0:"未知状态",1:"外出布防",2:"在家布防",3:"撤防状态",4:"布防延时"} #布防状态logging.info(self.sysAttrs['name'] + u' TCP端口' + str(self.__port) + u"已启动监听!")
- 定义回调函数,接收传过来的数据并进行相应的加解密处理和回应操作
#设置tcp回调函数,接收主机传过来的数据def tcpCallback(self,data):# logging.info(data)#一条cmd单独分包:判断是否分包,没有\n则分包了,进行合并,由于合并的最后一个包有\n,则通过判断__sumdata是否为空判断是否是需要合并的包,若此时的__sumdata不为空,说明正在合并,把最后一个包加上即可if data.find('\n')==-1:self.__sumdata = self.__sumdata+data# logging.info(self.__sumdata)else:if self.__sumdata !='':self.__sumdata = self.__sumdata+datadata = self.__sumdata# logging.info(data)self.__sumdata=''dataList = data.split('\n')# logging.info(dataList)for i in dataList:dataList_i = iif dataList_i=='':continue#多条cmd,最后一个分包elif dataList_i.find("{") == -1 or dataList_i.find("}") == -1:# logging.info(dataList_i)self.__sumdata2 = self.__sumdata2+dataList_iself.__flat = self.__flat +1# logging.info(self.__flat)if self.__flat == 2:self.__flat =0dataList_i = self.__sumdata2# logging.info(dataList_i)self.__sumdata2=''else:continuenewdata = eval(dataList_i)#报警主机发来请求登录信息if newdata['cmd']==8001:self.__8030senddata = newdata# self.__8016senddata = newdata"""进行加解密"""obj_endata=EncryptDate(rec_data=newdata)#响应登录请求send_data = json.dumps({"code":0,"platformName":"aiotos"})send_data = obj_endata.encrypt(send_data)newdata["data"]=send_datanewdata["cmd"]=8101data = json.dumps(newdata)time.sleep(0.5)self.__tcpServer.send(data + "\n")time.sleep(0.5)# #心跳包,直接跳过# elif data["cmd"]==8000:# logging.info(u"8000 rec , 心跳包")#设备列表数据包elif newdata['cmd']==8023:time.sleep(1)#拿去数据包并解密传至collectingobj_endata = EncryptDate(rec_data=newdata)if self.__8023flat == 1:self.__8023firstData = obj_endata.decrypt(newdata["data"])self.__8023flat = 0logging.info(u'8023 : first data received is ' + str(self.__8023firstData))else:self.__8023data = obj_endata.decrypt(newdata["data"])logging.info(u'8023 : data received is ' + str(self.__8023data))#中台响应8123,加密send_data = json.dumps({"code": 0})send_data = obj_endata.encrypt(send_data)# logging.info(send_data)newdata["data"]=send_datanewdata["cmd"]=8123data = json.dumps(newdata)time.sleep(0.5)self.__tcpServer.send(data + "\n")# logging.info(u'8123 !deta send is' +str(data))elif newdata['cmd']==8026:pass#8024为布撤防状态改变时发送,发送到来时将原有的8023数据修改掉elif newdata['cmd']==8024:obj_endata = EncryptDate(rec_data=newdata)self.__8024data = obj_endata.decrypt(newdata["data"])logging.info(u'8024 : data received is ' + str(self.__8024data))self.__8024dataDict = eval(self.__8024data)if self.__8023firstData != '':__8023MidFirstData = eval(self.__8023firstData)for i in self.__8024dataDict['deviceList']:for j in __8023MidFirstData['deviceList']:if i['deviceId'] == j['deviceId']:# __8023MidFirstData['deviceList'].remove(j)if 'armingStatus' in i:j['armingStatus'] = i['armingStatus']if 'deviceStatus' in i:j['deviceStatus'] = i['deviceStatus']logging.info(__8023MidFirstData)# logging.info(j)# __8023MidFirstData['deviceList'].append(j)# logging.info(__8023MidFirstData)self.__8023firstData = json.dumps(__8023MidFirstData,ensure_ascii=False,encoding="utf-8")logging.info(self.__8023firstData)else:continueif self.__8023data != '':__8023MidData = eval(self.__8023data)for i in self.__8024dataDict['deviceList']:for j in __8023MidData['deviceList']:if i['deviceId'] == j['deviceId']:# __8023MidData['deviceList'].remove(j)if 'armingStatus' in i:j['armingStatus'] = i['armingStatus']if 'deviceStatus' in i:j['deviceStatus'] = i['deviceStatus']logging.info(__8023MidFirstData)self.__8023data = json.dumps(__8023MidData,ensure_ascii=False,encoding="utf-8")else:continue# 报警事件传递过来,根据报警的id去8023数据中查找,若有则将deviceStatus改为3即可elif newdata['cmd'] == 8011:obj_endata = EncryptDate(rec_data=newdata)self.__8011data = obj_endata.decrypt(newdata["data"])logging.info(u'8011 : data received is ' + str(self.__8011data))self.__8011dataDic = eval(self.__8011data.replace('null',''))if self.__8023firstData != '':__8023MidFirstData = eval(self.__8023firstData)for i in __8023MidFirstData['deviceList']:if i['deviceId'] == self.__8011dataDic['deviceId']:i['deviceStatus'] = 3logging.info(__8023MidFirstData)self.__8023firstData = json.dumps(__8023MidFirstData, ensure_ascii=False, encoding="utf-8")if self.__8023data != '':__8023MidData = eval(self.__8023data)for i in __8023MidData['deviceList']:if i['deviceId'] == self.__8011dataDic['deviceId']:i['deviceStatus'] = 3logging.info(__8023MidData)self.__8023data = json.dumps(__8023MidData, ensure_ascii=False, encoding="utf-8")# 中台响应8111,加密send_data = json.dumps({"code": 0})send_data = obj_endata.encrypt(send_data)# logging.info(send_data)newdata["data"] = send_datanewdata["cmd"] = 8111data = json.dumps(newdata)time.sleep(0.5)self.__tcpServer.send(data + "\n")elif newdata['cmd']==8130:# 拿去数据包并解密传至collectingobj_endata = EncryptDate(rec_data=newdata)self.__8130data = obj_endata.decrypt(newdata["data"])logging.info(u'8130 : data received is ' + str(self.__8130data))elif newdata['cmd']==8000:logging.info(u'cmd' + str(newdata['cmd']))logging.info(newdata["data"])obj_endata = EncryptDate(rec_data=newdata)send_data = json.dumps({"code": 0})send_data = obj_endata.encrypt(send_data)newdata["data"] = send_datanewdata["cmd"] = 8100data = json.dumps(newdata)time.sleep(1)self.__tcpServer.send(data + "\n")# 8023设备状态的数据上传成功后再发送8030请求温湿度的值# logging.info('start')if self.__8030senddata:try:obj_endata = EncryptDate(rec_data=self.__8030senddata)send_data = json.dumps({"deviceType": 85})send_data = obj_endata.encrypt(send_data)self.__8030senddata["data"] = send_dataself.__8030senddata["cmd"] = 8030data = json.dumps(self.__8030senddata)# time.sleep(0.5)self.__tcpServer.send(data + "\n")# logging.info(u'8030 data send is' + str(data))except SocketError as e:logging.info(self.__8030senddata)"""断掉后再次开启端口进行重启"""self.__tcpServer = TcpServerThread(self, self.__port)self.__tcpServer.setDaemon(True)self.__tcpServer.start()if e.errno != errno.ECONNRESET:raise # Not error we are looking forpass # Handle error here.else:logging.info(u'其他cmd' + str(newdata['cmd']))logging.info(newdata["data"])# 8023设备状态的数据上传成功后再发送8030请求温湿度的值#logging.info('start')if self.__8030senddata:try:obj_endata = EncryptDate(rec_data=self.__8030senddata)send_data = json.dumps({"deviceType": 85})send_data = obj_endata.encrypt(send_data)self.__8030senddata["data"] = send_dataself.__8030senddata["cmd"] = 8030data = json.dumps(self.__8030senddata)time.sleep(0.5)self.__tcpServer.send(data + "\n")# logging.info(u'8030 data send is' + str(data))except SocketError as e:logging.info(self.__8030senddata)"""断掉后再次开启端口进行重启"""self.__tcpServer = TcpServerThread(self, self.__port)self.__tcpServer.setDaemon(True)self.__tcpServer.start()if e.errno != errno.ECONNRESET:raise # Not error we are looking forpass # Handle error here.
- 连接状态回调
# 连接状态回调def connectEvent(self, state):self.online(state)try:if state == True:self.pauseCollect = Falseelse:self.pauseCollect = Trueexcept Exception, e:logging.info(u'硬件心跳错误, ' + e.message)
- 循环采集函数,开启线程,将数据上传至中台
def Collecting(self, dataId):if self.__8023firstData !='' and self.__8023firstData != self.__8023data:# logging.info(1234567890)Set8023firstDataThreading(self).start()else:passif self.__8023data:Set8023DataThreading(self).start()time.sleep(1)else:passif self.__8130data:Set8130DataThreading(self).start()time.sleep(1)else:pass# time.sleep(2)return ()
至此,精华隆周界的设备已经对接完成
这篇关于IOTOS物联中台开发驱动支持精华隆周界子系统设备的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!