automation_upgrade.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. import os
  2. import sys
  3. from apps.web.constant import Const, DeviceOnlineStatus
  4. PROJECT_ROOT = os.path.join(os.path.abspath(os.path.split(os.path.realpath(__file__))[0] + "/.."))
  5. sys.path.insert(0, PROJECT_ROOT)
  6. from base import init_env
  7. init_env(interactive = True)
  8. import datetime
  9. import logging
  10. import daiquiri
  11. daiquiri.setup(
  12. level=logging.DEBUG,
  13. outputs=(
  14. daiquiri.output.File('automation_upgrade_log/automation_upgrade_error.log', level=logging.ERROR),
  15. daiquiri.output.TimedRotatingFile(
  16. 'automation_upgrade_log/automation_upgrade_out.log',
  17. level=logging.DEBUG,
  18. interval=datetime.timedelta(hours=1))
  19. )
  20. )
  21. logger = daiquiri.getLogger(__name__)
  22. import re
  23. import json
  24. import traceback
  25. import ConfigParser
  26. from library.paho.mqtt import publish, MQTTException
  27. from apps.web.device.models import Device, DeviceDict
  28. from apps.web.dealer.models import Dealer
  29. from mongoengine import Q
  30. def get_device_online():
  31. devices = Device.objects(Q(devType__ne = None) & Q(devType__ne = {}) & Q(ownerId__ne = ''))
  32. if devices.count() == 0:
  33. logger.info('devices are not found by database, num=%s' % devices.count())
  34. return None
  35. devDict = {_.devNo: {'cycle': _.cycle, 'logicalCode': _.logicalCode} for _ in devices}
  36. devices_dict = Device.get_many_device_status_cache(devDict)
  37. online_devices_imei = [k for k, v in devices_dict.items() if DeviceDict(v).online == DeviceOnlineStatus.DEV_STATUS_ONLINE]
  38. online_devices = Device.objects(devNo__in = online_devices_imei)
  39. return online_devices
  40. def update_version(device):
  41. if re.compile(r'^v1.5.*$').match(device.softVer) is not None:
  42. url = 'http://121.41.38.172:18070/uploaded/SMARTBOX_1.8.1_Luat_V0016_8955_SSL.bin'
  43. host, port = device.server.split(':')
  44. update(device.devNo, url, host, int(port))
  45. elif re.compile(r'^v1.6.*$').match(device.softVer) is not None:
  46. url = 'http://121.41.38.172:18070/uploaded/SMARTBOX_1.8.1_Luat_V0016_8955_SSL.bin'
  47. host, port = device.server.split(':')
  48. update(device.devNo, url, host, int(port))
  49. elif re.compile(r'^v1.7.*$').match(device.softVer) is not None:
  50. url = 'http://121.41.38.172:18070/uploaded/SMARTBOX_1.8.1_Luat_V0016_8955_SSL.bin'
  51. host, port = device.server.split(':')
  52. update(device.devNo, url, host, int(port))
  53. elif re.compile(r'^v1.8.*$').match(device.softVer) is not None:
  54. url = 'http://121.41.38.172:18070/uploaded/SMARTBOX_1.8.1_Luat_V0016_8955_SSL.bin'
  55. host, port = device.server.split(':')
  56. update(device.devNo, url, host, int(port))
  57. elif re.compile(r'^v3.0.*$').match(device.softVer) is not None:
  58. if 'devType' in device and 'code' in device.devType:
  59. if device.devType['code'] in ['110300']:
  60. url = 'http://121.41.38.172:18070/uploaded/SMART_BOX_4.2.0_Luat_V0020_8955_SSL.bin'
  61. host, port = device.server.split(':')
  62. update(device.devNo, url, host, int(port))
  63. elif device.devType['code'] in ['100500', '100208', '100600', '100205',
  64. '100203', '100200', '100308', '100901',
  65. '100400', '100209', '100207', '100309']:
  66. url = 'http://121.41.38.172:18070/uploaded/SMART_BOX_4.1.0_Luat_V0020_8955_SSL.bin'
  67. host, port = device.server.split(':')
  68. update(device.devNo, url, host, int(port))
  69. else:
  70. url = 'http://121.41.38.172:18070/uploaded/SMART_BOX_4.0.0_Luat_V0020_8955_SSL.bin'
  71. host, port = device.server.split(':')
  72. update(device.devNo, url, host, int(port))
  73. else:
  74. url = 'http://121.41.38.172:18070/uploaded/SMART_BOX_4.0.0_Luat_V0020_8955_SSL.bin'
  75. host, port = device.server.split(':')
  76. update(device.devNo, url, host, int(port))
  77. elif re.compile(r'^v3.2.*$').match(device.softVer) is not None:
  78. url = 'http://121.41.38.172:18070/uploaded/SMART_BOX_4.2.0_Luat_V0020_8955_SSL.bin'
  79. host, port = device.server.split(':')
  80. update(device.devNo, url, host, int(port))
  81. elif re.compile(r'^v3.1.*$').match(device.softVer) is not None:
  82. url = 'http://121.41.38.172:18070/uploaded/SMART_BOX_4.1.0_Luat_V0020_8955_SSL.bin'
  83. host, port = device.server.split(':')
  84. update(device.devNo, url, host, int(port))
  85. elif re.compile(r'^v3.3.*$').match(device.softVer) is not None:
  86. url = 'http://121.41.38.172:18070/uploaded/SMART_BOX_4.3.0_Luat_V0020_8955_SSL.bin'
  87. host, port = device.server.split(':')
  88. update(device.devNo, url, host, int(port))
  89. elif re.compile(r'^v3.4.*$').match(device.softVer) is not None:
  90. url = 'http://121.41.38.172:18070/uploaded/SMART_BOX_4.4.0_Luat_V0020_8955_SSL.bin'
  91. host, port = device.server.split(':')
  92. update(device.devNo, url, host, int(port))
  93. elif re.compile(r'^v4.0.*$').match(device.softVer) is not None:
  94. url = 'http://121.41.38.172:18070/uploaded/SMART_BOX_4.4.0_Luat_V0020_8955_SSL.bin'
  95. host, port = device.server.split(':')
  96. update(device.devNo, url, host, int(port))
  97. elif re.compile(r'^v4.1.*$').match(device.softVer) is not None:
  98. url = 'http://121.41.38.172:18070/uploaded/SMART_BOX_4.4.0_Luat_V0020_8955_SSL.bin'
  99. host, port = device.server.split(':')
  100. update(device.devNo, url, host, int(port))
  101. elif re.compile(r'^v4.2.*$').match(device.softVer) is not None:
  102. url = 'http://121.41.38.172:18070/uploaded/SMART_BOX_4.4.0_Luat_V0020_8955_SSL.bin'
  103. host, port = device.server.split(':')
  104. update(device.devNo, url, host, int(port))
  105. elif re.compile(r'^v4.3.*$').match(device.softVer) is not None:
  106. if 'devType' in device and 'code' in device.devType:
  107. if device.devType['code'] not in ['100710', '100711', '100712', '100713', '100714']:
  108. url = 'http://121.41.38.172:18070/uploaded/SMART_BOX_4.4.0_Luat_V0020_8955_SSL.bin'
  109. host, port = device.server.split(':')
  110. update(device.devNo, url, host, int(port))
  111. elif re.compile(r'^v4.4.*$').match(device.softVer) is not None:
  112. url = 'http://121.41.38.172:18070/uploaded/SMART_BOX_4.4.0_Luat_V0020_8955_SSL.bin'
  113. host, port = device.server.split(':')
  114. update(device.devNo, url, host, int(port))
  115. else:
  116. logger.error("version %s error" % device.softVer)
  117. def update(imei, url, host, port):
  118. for val in range(3):
  119. message = {
  120. 'cmd': 202,
  121. 'IMEI': imei,
  122. 'ota_set': {
  123. 'fw_url': url
  124. }
  125. }
  126. try:
  127. publish.single("smart_box/%s/202" % imei, json.dumps(message), hostname=host, port=port,
  128. auth={'username': "20160528@vivestone", 'password': "j429QXqI5CTv"})
  129. logger.info('Upgrade package sent successfully! imei=%s' % imei)
  130. break
  131. except MQTTException, e:
  132. logger.error(traceback.format_exc())
  133. logger.error("imei: %s, capture a mqtt exception: %s" % (imei, e))
  134. except Exception, e:
  135. logger.error("imei: %s, capture a exception: %s" % (imei, e))
  136. def imei_update(imei=None, targetVersion=None):
  137. device = Device.objects(devNo=imei).first()
  138. if not device:
  139. logger.info('device is not found, imei=%s' % imei)
  140. return None
  141. message = {
  142. 'cmd': 202,
  143. 'IMEI': imei,
  144. 'ota_set': {
  145. 'fw_url': 'http://121.41.38.172:18070/uploaded/' + targetVersion
  146. }
  147. }
  148. host, port = device.server.split(':')
  149. send_update(imei=imei, message=message, host=host, port=port, targetVersion=targetVersion, device=device)
  150. def logicalCode_update(logicalCode=None, targetVersion=None):
  151. device = Device.objects(logicalCode=logicalCode).first()
  152. if not device:
  153. logger.info('device is not found, logicalCode=%s' % logicalCode)
  154. return None
  155. imei = device.devNo
  156. message = {
  157. 'cmd': 202,
  158. 'IMEI': imei,
  159. 'ota_set': {
  160. 'fw_url': 'http://121.41.38.172:18070/uploaded/' + targetVersion
  161. }
  162. }
  163. host, port = device.server.split(':')
  164. send_update(imei=imei, message=message, host=host, port=port, targetVersion=targetVersion, device=device)
  165. def dealerId_update(dealerId=None, targetVersion=None):
  166. dealer = Dealer.objects(id=dealerId).first()
  167. if not dealer:
  168. logger.info('dealer is not found, dealerId=%s' % dealerId)
  169. return None
  170. devices = Device.objects(ownerId=dealerId).all()
  171. if len(devices) == 0:
  172. logger.info('devices are not found, dealerId=%s' % dealerId)
  173. return None
  174. def f(devNo):
  175. _ = Device.get_dev(devNo) # type: DeviceDict
  176. if _:
  177. return _.online
  178. else:
  179. return False
  180. online_devices = [_ for _ in devices if f(_.devNo)]
  181. logger.info('DealerId update: %s devices are ready to update, dealerId=%s' % (len(online_devices), dealerId))
  182. if len(online_devices) == 0:
  183. logger.info('online_devices are not found, dealerId=%s' % dealerId)
  184. return None
  185. for device in online_devices:
  186. imei = device.devNo
  187. message = {
  188. 'cmd': 202,
  189. 'IMEI': imei,
  190. 'ota_set': {
  191. 'fw_url': 'http://121.41.38.172:18070/uploaded/' + targetVersion
  192. }
  193. }
  194. host, port = device.server.split(':')
  195. send_update(imei=imei, message=message, host=host, port=port, targetVersion=targetVersion, device=device)
  196. def agentId_update(agentId=None, targetVersion=None):
  197. dealers = Dealer.objects(agentId=agentId).all()
  198. if len(dealers) == 0:
  199. logger.info('dealers are not found, agentId=%s' % agentId)
  200. return None
  201. for dealer in dealers:
  202. devices = Device.objects(ownerId=str(dealer.id)).all()
  203. if len(devices) == 0:
  204. logger.info('devices are not found, dealerId=%s' % dealer.id)
  205. return None
  206. def f(devNo):
  207. _ = Device.get_dev(devNo) # type: DeviceDict
  208. if _:
  209. return _.online
  210. else:
  211. return False
  212. online_devices = [_ for _ in devices if f(_.devNo)]
  213. logger.info('AgentId update: %s devices are ready to update, dealerId=%s' %(len(online_devices), dealer.id))
  214. if len(online_devices) == 0:
  215. logger.info('online_devices are not found, dealerId=%s' % dealer.id)
  216. return None
  217. for device in online_devices:
  218. imei = device.devNo
  219. message = {
  220. 'cmd': 202,
  221. 'IMEI': imei,
  222. 'ota_set': {
  223. 'fw_url': 'http://121.41.38.172:18070/uploaded/' + targetVersion
  224. }
  225. }
  226. host, port = device.server.split(':')
  227. send_update(imei=imei, message=message, host=host, port=port, targetVersion=targetVersion, device=device)
  228. def driverCode_update(driverCode=None, targetVersion=None):
  229. devices = get_device_online()
  230. logger.info('DriverCode update: %s devices online' % len(devices))
  231. if len(devices) == 0:
  232. logger.info('online_devices are not found, driverCode=%s' % driverCode)
  233. return None
  234. devices = [_ for _ in devices if _.devType['code'] == driverCode]
  235. logger.info('DriverCode update: %s devices are ready to update, driverCode=%s' % (len(devices), driverCode))
  236. for device in devices:
  237. imei = device.devNo
  238. message = {
  239. 'cmd': 202,
  240. 'IMEI': imei,
  241. 'ota_set': {
  242. 'fw_url': 'http://121.41.38.172:18070/uploaded/' + targetVersion
  243. }
  244. }
  245. host, port = device.server.split(':')
  246. send_update(imei=imei, message=message, host=host, port=port, targetVersion=targetVersion, device=device)
  247. def version_update(version=None, targetVersion=None):
  248. devices = get_device_online()
  249. logger.info('Version update: %s devices online' % len(devices))
  250. if len(devices) == 0:
  251. logger.info('online_devices are not found, version=%s' % version)
  252. return None
  253. for device in devices:
  254. if re.compile(r'^'+ version +'$').match(device.softVer) is not None:
  255. imei = device.devNo
  256. message = {
  257. 'cmd': 202,
  258. 'IMEI': imei,
  259. 'ota_set': {
  260. 'fw_url': 'http://121.41.38.172:18070/uploaded/' + targetVersion
  261. }
  262. }
  263. host, port = device.server.split(':')
  264. send_update(imei=imei, message=message, host=host, port=port, targetVersion=targetVersion, device=device)
  265. def send_update(imei=None, message=None, host=None, port=None, targetVersion=None, device=None):
  266. if device.softVer[1:] in targetVersion:
  267. logger.info('one of the device version %s was already updated, imei=%s' % (targetVersion, imei))
  268. return None
  269. for val in range(3):
  270. try:
  271. publish.single("smart_box/%s/202" % imei, json.dumps(message), hostname=host, port=int(port),
  272. auth={'username': "20160528@vivestone", 'password': "j429QXqI5CTv"})
  273. logger.info('Upgrade package sent successfully! imei=%s, targetVersion=%s' % (imei, targetVersion))
  274. break
  275. except MQTTException, e:
  276. logger.error(traceback.format_exc())
  277. logger.error("imei: %s, capture a mqtt exception: %s" % (imei, e))
  278. except Exception, e:
  279. logger.error("imei: %s, capture a exception: %s" % (imei, e))
  280. def upgrade_all():
  281. devices = get_device_online()
  282. logger.info('All update: %s devices are ready to update' % len(devices))
  283. if len(devices) == 0:
  284. logger.info('online_devices are not found, num=%s' % len(devices))
  285. return None
  286. for device in devices:
  287. update_version(device)
  288. def upgrade_custom():
  289. if targetVersion != '':
  290. if driverCode != '':
  291. driverCode_update(driverCode=driverCode, targetVersion=targetVersion)
  292. if imei != '':
  293. imei_update(imei=imei, targetVersion=targetVersion)
  294. if logicalCode != '':
  295. logicalCode_update(logicalCode=logicalCode, targetVersion=targetVersion)
  296. if dealerId != '':
  297. dealerId_update(dealerId=dealerId, targetVersion=targetVersion)
  298. if agentId != '':
  299. agentId_update(agentId=agentId, targetVersion=targetVersion)
  300. if version != '':
  301. version_update(version=version, targetVersion=targetVersion)
  302. else:
  303. logger.info('targetVersion is not defined')
  304. def main():
  305. if upgradeAll is True:
  306. upgrade_all()
  307. else:
  308. upgrade_custom()
  309. if __name__ == '__main__':
  310. cf = ConfigParser.ConfigParser()
  311. cf.read('automation_upgrade.ini')
  312. upgradeAll = eval(cf.get('upgrade', 'upgradeAll'))
  313. if upgradeAll is False:
  314. targetVersion = cf.get('upgrade', 'targetVersion')
  315. driverCode = cf.get('upgrade', 'driverCode')
  316. imei = cf.get('upgrade', 'imei')
  317. logicalCode = cf.get('upgrade', 'logicalCode')
  318. dealerId = cf.get('upgrade', 'dealerId')
  319. agentId = cf.get('upgrade', 'agentId')
  320. version = cf.get('upgrade', 'version')
  321. main()