陕西网站建设优化建站,中国小康建设网官方网站,龙岩建设网站,asp网站时间代码源码将于最后一遍文章给出下载
监测数据采集物联网应用开发步骤(10)
程序自动更新开发
前面章节写了部分功能模块开发#xff1a;
日志或文本文件读写开发;Sqlite3数据库读写操作开发;定时器插件化开发;串口(COM)通讯开发;TCP/IP Client开发;TCP/IP Server 开发;modbus协议…源码将于最后一遍文章给出下载
监测数据采集物联网应用开发步骤(10)
程序自动更新开发
前面章节写了部分功能模块开发
日志或文本文件读写开发;Sqlite3数据库读写操作开发;定时器插件化开发;串口(COM)通讯开发;TCP/IP Client开发;TCP/IP Server 开发;modbus协议开发;
本章节啰嗦些该解决方案最终业务成品有些需要部署在不同工控机或设备上在实际应用过程中随时间推移有些需要升级迭代或修改bug一旦安装部署设备点位达到一定数量系统自动更新升级就是一个必要的步骤了。笔者开发的业务应用在相应的设备上安装已近千台设备鉴于此增加了程序自动更新功能模块。
在com.zxy.common.Com_Para.py中添加如下内容
#自动更新服务端文件夹地址
urlPath
#程序版本号
version
新建程序版本自动更新类com.zxy.autoUpdate.GetVersion.py
#! python3
# -*- coding: utf-8 -Created on 2017年05月10日
author: zxyong 13738196011
import urllib.request,datetime
from com.zxy.adminlog.UsAdmin_Log import UsAdmin_Log
from com.zxy.common import Com_Para
from com.zxy.common.Com_Fun import Com_Fun
from com.zxy.interfaceReflect.A01_A1B2C3 import A01_A1B2C3
from com.zxy.z_debug import z_debug
from urllib.parse import urlparse#监测数据采集物联网应用--程序版本自动更新类
class GetVersion(z_debug):def __init__(self):pass#下载文件def SaveRemoteFile(self,inputFileName,inputLocalFileName):try:temResult urllib.request.urlretrieve(Com_Para.urlPath/inputFileName,Com_Para.ApplicationPathCom_Para.zxyPathinputLocalFileName)except Exception as e:if str(type(self)) class type:self.debug_in(self,repr(e)str(e.__traceback__.tb_lineno))#打印异常信息else:self.debug_in(repr(e)str(e.__traceback__.tb_lineno))#打印异常信息return temResult#保存版本号文件def SaveVersionFile(self,version_no,inputLocalFileName):temStrTFileName Com_Para.ApplicationPathCom_Para.zxyPathinputLocalFileNametemFile Nonetry: temFile open(temStrTFileName, w,encodingCom_Para.U_CODE)temFile.write(version_no)temFile.close()except Exception as e:if str(type(self)) class type:self.debug_in(self,repr(e)str(e.__traceback__.tb_lineno))#打印异常信息else:self.debug_in(repr(e)str(e.__traceback__.tb_lineno))#打印异常信息finally:if temFile ! None:temFile.close()#检测最新版本def CheckVersion(self):try:print(check new version...Com_Fun.GetTimeDef())#读取服务器端version.txt信息temResult self.GetRequestWeb()if temResult :return 0temUL UsAdmin_Log(Com_Para.ApplicationPath,temResult,0)#文件形式版本号管理temVersion temUL.ReadFile(Com_Para.ApplicationPathCom_Para.zxyPath version.txt)Com_Para.version temVersion#数据库形式版本号管理temVersion Com_Para.versiontemAryTem []temVersion_No temLastFile #判断文件是否存在if temVersion and temResult ! :print(local version nonedownloading new version)temAryTem temResult.split(\n)for temLine in temAryTem:temLine temLine.replace(\r,).replace(\n,)temLastFile temLineif temLine.find(version) ! -1:temVersion_No temLineelif temLine ! :print(new version file download:temLine)self.SaveRemoteFile(temLine,back/temLine)self.CopyFile(temLine)if temVersion_No ! :#文件形式版本管理 self.SaveVersionFile(temVersion_No,version.txt)#数据库形式版本文件管理#将版本号insert入库 该处代码省略....Com_Para.version temVersion_No print(new version updated over:)#如果读到reboot.txt则需要重启设备if temLastFile.strip() reboot.txt:self.RebootProgram()return 0if temVersion_No ! :#文件形式版本管理 print(new version updated over:)self.SaveVersionFile(temVersion_No,version.txt)#数据库形式版本文件管理#将版本号insert入库 该处代码省略....Com_Para.version temVersion_Noelif temResult ! :#数据库形式版本号管理
# localVersion Com_Para.version#文件形式版本号管理temAryTem temVersion.split(\n)for temLine in temAryTem:temArySub temLine.split()if len(temArySub) 1 and temArySub[0] version:localVersion temArySub[1]break bFlag FalsetemAryTem temResult.split(\n)for temLine in temAryTem:temLine temLine.replace(\r,).replace(\n,)temLastFile temLinetemArySub temLine.split()if len(temArySub) 1 and temArySub[0] version:try:if localVersion.find() ! -1:iLV int(localVersion.split()[1])else:iLV int(localVersion)if localVersion ! and iLV int(temArySub[1]):bFlag Falseelse:temVersion_No temLinebFlag Trueexcept:bFlag Falsebreakelse:if bFlag:self.SaveRemoteFile(temLine,back/temLine)self.CopyFile(temLine)if temVersion_No ! :#文件形式版本管理 self.SaveVersionFile(temVersion_No,version.txt) #数据库形式版本文件管理 #将版本号insert入库 该处代码省略....Com_Para.version temVersion_Noprint(new version updated over:temVersion_No)if temLastFile.strip() reboot.txt:self.RebootProgram()return 0if (bFlag and temVersion_No ! ):#文件形式版本管理 self.SaveVersionFile(temVersion_No,version.txt)#数据库形式版本文件管理 #将版本号insert入库 该处代码省略....Com_Para.version temVersion_Noprint(new version updated over:)if bFlag and temLastFile.strip() reboot.txt:self.RebootProgram()return 0except Exception as e:if str(type(self)) class type:self.debug_in(self,repr(e)str(e.__traceback__.tb_lineno))#打印异常信息else:self.debug_in(repr(e)str(e.__traceback__.tb_lineno))#打印异常信息return 1#重启设备def RebootProgram(self): aa A01_A1B2C3()if Com_Para.devsys.lower() linux: aa.param_value2 reboot -faa.CmdExecLinux()else:aa.param_value2 shutdown -raa.CmdExecWin()#文件更新def CopyFile(self,inputWebFile):temAryTem inputWebFile.split(\n)for temLine in temAryTem:if temLine.find() -1:aa A01_A1B2C3()temFileName temLine[0:temLine.find(.)]temFileAtt temLine[temLine.find(.):len(temLine)].upper()if temFileAtt.upper() .ZIP:aa.param_value2 unzip -o Com_Para.ApplicationPathCom_Para.zxyPathbackCom_Para.zxyPathtemLine -d Com_Para.ApplicationPathCom_Para.zxyPathbackCom_Para.zxyPathtemFileNameCom_Para.zxyPathaa.param_value3 Com_Para.ApplicationPathCom_Para.zxyPathbackCom_Para.zxyPathtemLineaa.param_value4 Com_Para.ApplicationPathCom_Para.zxyPathbackCom_Para.zxyPathtemFileNameCom_Para.zxyPath#利用命令进行解压缩#aa.CmdExecLinux()#利用python自带解压缩模块aa.unzip_file() if Com_Para.devsys.lower() linux: aa.param_value2 cp -rf Com_Para.ApplicationPathCom_Para.zxyPathbackCom_Para.zxyPathtemFileNameCom_Para.zxyPath* Com_Para.ApplicationPathCom_Para.zxyPathelse:aa.param_value2 xcopy Com_Para.ApplicationPathCom_Para.zxyPathbackCom_Para.zxyPathtemFileNameCom_Para.zxyPath*.* Com_Para.ApplicationPath /E /Yaa.CmdExecLinux()#执行sql语句elif temFileAtt.upper() .SQL:aa.RunSqlFile(Com_Para.ApplicationPathCom_Para.zxyPathbackCom_Para.zxyPathtemLine)#执行更新数据接口elif temFileAtt.upper() .JSON:#JSON业务数据进行数据库结构更改或升级passelse:if Com_Para.devsys.lower() linux: aa.param_value2 cp -rf Com_Para.ApplicationPathCom_Para.zxyPathbackCom_Para.zxyPathtemLine Com_Para.ApplicationPathCom_Para.zxyPathelse:aa.param_value2 copy Com_Para.ApplicationPathCom_Para.zxyPathbackCom_Para.zxyPathtemLine Com_Para.ApplicationPathCom_Para.zxyPath /Yaa.CmdExecLinux()#inputFlag网络链接是否正常def set_dSockList(self,inputFlag):urlp urlparse(Com_Para.urlPath)if Com_Para.urlPath :return None key str(urlp.netloc.replace(:,|)) #存在if key not in list(Com_Para.dSockList.keys()):Com_Para.dSockList[key] [0,datetime.datetime.now()]if inputFlag False:objAry Com_Para.dSockList[key]if objAry[0] 10:objAry[0] objAry[0] 1objAry[1] datetime.datetime.now()Com_Para.dSockList[key] objAryelse:Com_Para.dSockList[key] [0,datetime.datetime.now()] #判断上次链接时间频率是否合规def judge_dSock(self):urlp urlparse(Com_Para.urlPath)if Com_Para.urlPath :return False key str(urlp.netloc.replace(:,|)) if key not in list(Com_Para.dSockList.keys()):Com_Para.dSockList[key] [0,datetime.datetime.now()]objAry Com_Para.dSockList[key]starttime datetime.datetime.now()if objAry[0] 3:return Trueelif objAry[0] 4 and starttime objAry[1] datetime.timedelta(hours12):return Trueelse:return Falsedef GetRequestWeb(self):temResult try:#判断上次链接时间频率是否合规if not self.judge_dSock():return resp urllib.request.urlopen(Com_Para.urlPath/version.txt,timeout5)temResult resp.read().decode(Com_Para.U_CODE) except Exception as e:temLog if str(type(self)) class type:temLog self.debug_info(self)repr(e)else:temLog self.debug_info()repr(e)uL UsAdmin_Log(Com_Para.ApplicationPath, temLogstr(e.__traceback__.tb_lineno))uL.WriteLog()temResult self.set_dSockList(False)return temResult新建操作系统执行指令接口类com.zxy.interfaceReflect.A01_A1B2C3.py
#! python3
# -*- coding: utf-8 -Created on 2017年05月10日
author: zxyong 13738196011
import os, sys,zipfile,subprocess,tempfile
from urllib.parse import unquote
from com.zxy.common import Com_Para
from com.zxy.common.Com_Fun import Com_Fun
from com.zxy.z_debug import z_debug#监测数据采集物联网应用--操作系统执行指令接口类
class A01_A1B2C3(z_debug):strResult session_id param_name param_value1 None #1:同步更新设备时间param_value2 None #当前时间param_value3 Noneparam_value4 Noneparam_value5 Noneparam_value6 Noneparam_value7 Noneparam_value8 Noneparam_value9 Noneparam_value10 None#是否继续执行 1:继续执行 0:中断执行strContinue 0strCmdValue def __init__(self):passdef init_start(self):
# /**************************************************/
# //示例: 此处写业务逻辑,最后给 param_name,param_value1....重新赋值
# // param_name Com_Fun.Get_New_GUID()
# // param_value1 Com_Fun.Get_New_GUID()
# // param_value2 Com_Fun.Get_New_GUID()
# // ......# /**************************************************/
# //示例:若业务逻辑判断失败,不发送数据库接口请求并返回失败信息#strContinue 0 表示拦截器判断接口执行结束,不需要入库操作,直接返回信息temValue self.strContinue 0if self.param_value1 100 and Com_Para.devsys linux:temValue self.CmdExecLinux(self)self.strResult 命令结果:\r\nfor temR in temValue:self.strResult self.strResulttemR.decode(Com_Para.U_CODE)\r\n#100执行命令elif self.param_value1 100 and Com_Para.devsys windows:temValue self.CmdExecWin(self)self.strResult {\self.param_name\:[{\s_result\:\1\,\error_desc\:\命令执行成功temValue\}]}#利用python自带解压缩def unzip_file(self):temzipfile zipfile.ZipFile(self.param_value3, r)temzipfile.extractall(self.param_value4) #重启程序def RestartPro(self):python sys.executableos.execl(python,python,* sys.argv)#执行命令(Linux)def CmdExecLinux(self):out_temp Nonetry: temCommand unquote(unquote(self.param_value2,Com_Para.U_CODE))out_temp tempfile.SpooledTemporaryFile(max_size10*1000)fileno out_temp.fileno()obj subprocess.Popen(temCommand,stdoutfileno,stderrfileno,shellTrue)obj.wait() out_temp.seek(0)temResult out_temp.readlines() except Exception as e:temResult repr(e)finally:if out_temp is not None:out_temp.close()return temResult#执行命令(Windows)def CmdExecWin(self):try:temCommand unquote(unquote(self.param_value2,Com_Para.U_CODE))temResult os.popen(temCommand).read()except Exception as e:temResult repr(e)return temResult#更新设备时间(Windows)def ChangeDateWin(self):try:temDate Com_Fun.GetDateInput(%Y-%m-%d, %Y-%m-%d %H:%M:%S, unquote(unquote(self.param_value2.replace(, ),Com_Para.U_CODE)))temTime Com_Fun.GetDateInput(%H:%M:%S, %Y-%m-%d %H:%M:%S, unquote(unquote(self.param_value2.replace(, ),Com_Para.U_CODE)))temResult os.system(date {} time {}.format(temDate,temTime))except:temResult -1return temResult#更新设备时间(Linux)def ChangeDateLinux(self):try: #将硬件时间写入到系统时间#hwclock -s#将系统时间写入到硬件时间#hwclock -wtemCommand unquote(unquote(date -s \self.param_value2.replace(, ).split( )[0]\,Com_Para.U_CODE))temCommand unquote(unquote(date -s \self.param_value2.replace(, ).split( )[1]\,Com_Para.U_CODE))out_temp tempfile.SpooledTemporaryFile(max_size10*1000)fileno out_temp.fileno()obj subprocess.Popen(temCommand,stdoutfileno,stderrfileno,shellTrue)obj.wait()temCommand unquote(unquote(hwclock -w,Com_Para.U_CODE))obj subprocess.Popen(temCommand,stdoutfileno,stderrfileno,shellTrue)obj.wait() out_temp.seek(0)temByt out_temp.readlines()temResult temByt[0].decode(Com_Para.U_CODE)if temResult :temResult 1except Exception as e:temResult -1 finally:if out_temp is not None:out_temp.close()return temResult
版本更新测试案例MonitorDataCmd.py主文件中编写
from com.zxy.autoUpdate.GetVersion import GetVersion
在 if __name__ __main__:下添加 #版本更新测试Com_Para.urlPath http://localhost:8080/testweb/updtest/gv GetVersion() gv.CheckVersion()print(版本更新完成) 程序文件新建back文件夹临时存放下载更新包的zip文件;
版本更新服务端文件信息
版本更新服务端版本号信息 运行结果设备端更新之后新增文件 更新文件已下载并自动解压缩成功。
print打印出的内容