update_4g_pulse.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. # -*- coding: utf-8 -*-
  2. # !/usr/bin/env python
  3. import getopt
  4. import time
  5. import uuid
  6. import sys
  7. import os
  8. PROJECT_ROOT = os.path.join(os.path.abspath(os.path.split(os.path.realpath(__file__))[0] + "/.."), '..')
  9. sys.path.insert(0, PROJECT_ROOT)
  10. try:
  11. options, args = getopt.getopt(sys.argv[1:], 'v:s:e:m:r:p:b:d:a:f:',
  12. ['version=', 'server=', 'env=', 'max-count=', 'platform-version=',
  13. 'parallel=', 'dealer=', 'agent=', 'postfix='])
  14. except getopt.GetoptError as e:
  15. print(str(e))
  16. sys.exit()
  17. upgrade_version = ''
  18. system_env = 'testing'
  19. max_count = 10
  20. platform_version = ''
  21. platform = 'ASR1802'
  22. parallel = 5
  23. server = ''
  24. dealer = None
  25. agent = None
  26. postfix = ''
  27. driver_code = '100000'
  28. for name, value in options:
  29. if name in ('-v', '--version'):
  30. upgrade_version = value
  31. if name in ('-e', '--env'):
  32. system_env = value
  33. if name in ('-m', '--max-count'):
  34. max_count = int(value)
  35. if name in ('-r', '--platform-version'):
  36. platform_version = value
  37. if name in ('-b', '--parallel'):
  38. parallel = int(value)
  39. if name in ('-s', '--server'):
  40. server = value
  41. if name in ('-d', '--dealer'):
  42. dealer = value
  43. if name in ('-a', '--agent'):
  44. agent = value
  45. if name in ('-f', '--postfix'):
  46. postfix = value
  47. if not server:
  48. print 'server is null.'
  49. sys.exit(2)
  50. if not platform_version:
  51. print 'not assign platform info.'
  52. sys.exit(2)
  53. if not upgrade_version:
  54. print 'error version = {version}'.format(version = upgrade_version)
  55. sys.exit(2)
  56. master, major, minor = upgrade_version.split('.')
  57. if not master or not major or not minor:
  58. print 'error version = {version}'.format(version = upgrade_version)
  59. sys.exit(2)
  60. if not system_env:
  61. print 'error system env = {env}'.format(env = system_env)
  62. sys.exit(2)
  63. import os
  64. os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'configs.{env}'.format(env = system_env))
  65. from django.conf import settings
  66. from script.base import init_env
  67. import simplejson as json
  68. init_env(interactive = False)
  69. from apps.web.dealer.models import Dealer
  70. from apps.web.device.models import Device, DeviceDict
  71. from apps.web.core.networking import MessageSender
  72. from apps.web.constant import Const, DeviceOnlineStatus
  73. from apps.web.core.mqtt_client import MqttClient
  74. from script.device_upgrade import DeviceUpgradeLog
  75. version_regex = 'v{master}\.{major}\.'.format(master = master, major = major)
  76. version_check = 'v{master}.{major}.'.format(master = master, major = major)
  77. print 'version regex is: {}'.format(version_regex)
  78. print 'version check is: {}'.format(version_check)
  79. upgrade_soft_ver = 'v{version}'.format(version = upgrade_version)
  80. upgrade_core_ver = 'Luat_V{platform_version}_{platform}_720D'.format(
  81. platform_version = '{0:0>4}'.format(platform_version),
  82. platform = platform)
  83. update_key = DeviceUpgradeLog.make_update_key(upgrade_core_ver, upgrade_soft_ver)
  84. print 'update key is: {}'.format(update_key)
  85. print 'upgrade soft ver is: {}'.format(upgrade_soft_ver)
  86. print 'upgrade core ver is: {}'.format(upgrade_core_ver)
  87. mqttc1883 = None
  88. mqttc1884 = None
  89. doing_dict = {}
  90. exists_code = set()
  91. no_exists_code = set()
  92. try:
  93. def on_connect(client, userdata, flags, rc):
  94. pass
  95. def on_message(mqttc, obj, msg):
  96. # type: (MqttClient, obj, json)->None
  97. msgDict = json.loads(bytes.decode(msg.payload))
  98. imei = msgDict['IMEI']
  99. print 'msg dict is: {}'.format(msgDict)
  100. print 'update key is: {}'.format(update_key)
  101. log = DeviceUpgradeLog.objects(
  102. updateKey = update_key,
  103. devNo = imei
  104. ).first() # type: DeviceUpgradeLog
  105. if not log:
  106. print 'not has log record'
  107. if msgDict['cmd'] == 209:
  108. print('209 has received. msg = %s' % str(msgDict))
  109. if msgDict['result']:
  110. if log:
  111. log.set_stauts(DeviceUpgradeLog.Status.UPGRADED)
  112. else:
  113. if log:
  114. log.set_stauts(DeviceUpgradeLog.Status.FAILURE)
  115. mqttc.unsubscribe('server/%s/209' % imei)
  116. doing_dict.pop(imei, None)
  117. elif msgDict['cmd'] == 200:
  118. if msgDict['soft_ver'] == upgrade_soft_ver and msgDict['core_ver'] == upgrade_core_ver:
  119. log.set_stauts(DeviceUpgradeLog.Status.SUCCESS)
  120. else:
  121. log.set_stauts(DeviceUpgradeLog.Status.FAILURE)
  122. mqttc.unsubscribe('server/%s/200' % imei)
  123. def on_disconnect(client, userdata, self):
  124. print('exit. client = %s' % str(client))
  125. mqttc1883 = MqttClient(client_id = 'webapp_' + str(uuid.uuid1()))
  126. try:
  127. mqttc1883.on_message = on_message
  128. mqttc1883.on_connect = on_connect
  129. mqttc1883.on_disconnect = on_disconnect
  130. mqttc1883.username_pw_set(settings.MQTT_USER, settings.MQTT_PSWD)
  131. mqttc1883.connect(settings.MQTT_HOSTNAME, 1883, 60)
  132. mqttc1883.loop_start()
  133. except Exception as e:
  134. print(e)
  135. mqttc1884 = MqttClient(client_id = 'webapp_' + str(uuid.uuid1()))
  136. try:
  137. mqttc1884.on_message = on_message
  138. mqttc1884.on_connect = on_connect
  139. mqttc1884.on_disconnect = on_disconnect
  140. mqttc1884.username_pw_set(settings.MQTT_USER, settings.MQTT_PSWD)
  141. mqttc1884.connect(settings.MQTT_HOSTNAME, 1884, 60)
  142. mqttc1884.loop_start()
  143. except Exception as e:
  144. print(e)
  145. if dealer:
  146. dealers = [dealer]
  147. elif agent:
  148. dealers = [dealer['_id'] for dealer in Dealer.get_collection().find({'agentId': agent})]
  149. else:
  150. dealers = None
  151. if dealers:
  152. objs = Device.get_collection().find(
  153. {'ownerId': {'$in': dealers},
  154. 'devType.code': {'$lt': '100100'},
  155. 'softVer': {'$regex': version_regex}})
  156. else:
  157. objs = Device.get_collection().find(
  158. {'ownerId': {'$nin': [None, '']},
  159. 'devType.code': {'$lt': '100100'},
  160. 'softVer': {'$regex': version_regex}})
  161. count = 0
  162. devNoList = []
  163. for obj in objs:
  164. now_soft_ver = str(obj['softVer'])
  165. now_core_ver = str(obj.get('coreVer',''))
  166. dev_no = str(obj['devNo'])
  167. exist_log = DeviceUpgradeLog.objects(
  168. updateKey = update_key,
  169. devNo = dev_no).first()
  170. if exist_log:
  171. print 'ignore this round for dev<{}>'.format(dev_no)
  172. continue
  173. need_upgrade = True
  174. try:
  175. common_flag = (now_soft_ver.startswith(version_check) and (
  176. now_soft_ver != upgrade_soft_ver or now_core_ver != upgrade_core_ver))
  177. if common_flag:
  178. devNoList.append(dev_no)
  179. continue
  180. need_upgrade = False
  181. finally:
  182. if not need_upgrade:
  183. print 'dev<devNo={},rCode={},code={}> version is: {}. no need to upgrade'.format(dev_no,
  184. obj['devType'].get(
  185. 'code', ''),
  186. obj.get('driverCode',
  187. ''),
  188. now_soft_ver)
  189. else:
  190. print 'dev<devNo={},rCode={},code={}> version is: {}. need to upgrade.'.format(dev_no,
  191. obj['devType'].get(
  192. 'code', None),
  193. obj.get('driverCode',
  194. ''),
  195. now_soft_ver)
  196. fw_url_tmpl = 'http://{server}/uploaded/version/4g/SmartBox4G_{version}_Luat_V{platform_version}_{platform}_720D_100000'.format(
  197. server = server,
  198. version = upgrade_version,
  199. platform_version = '{0:0>4}'.format(platform_version),
  200. platform = platform)
  201. if postfix:
  202. fw_url_tmpl = fw_url_tmpl + '_' + postfix
  203. fw_url_tmpl = fw_url_tmpl + '_{full}.bin'
  204. # r = requests.get(version_path, timeout = 15)
  205. # if r.status_code == 404:
  206. # print '{} version is not exist'.format(driver_code)
  207. for devNo in devNoList:
  208. try:
  209. if max_count != -1 and count >= max_count:
  210. print 'max count reach.'
  211. break
  212. dev = Device.get_dev(devNo) # type: DeviceDict
  213. if dev.online != DeviceOnlineStatus.DEV_STATUS_ONLINE:
  214. print '{imei} is offline.'.format(imei = devNo)
  215. continue
  216. if ':1884' in dev['server']:
  217. mqttc1884.subscribe('server/%s/209' % devNo, Const.MQTT_QOS)
  218. mqttc1884.subscribe('server/%s/200' % devNo, Const.MQTT_QOS)
  219. elif ':1883' in dev['server']:
  220. mqttc1883.subscribe('server/%s/209' % devNo, Const.MQTT_QOS)
  221. mqttc1883.subscribe('server/%s/200' % devNo, Const.MQTT_QOS)
  222. else:
  223. continue
  224. if upgrade_core_ver == dev['coreVer']:
  225. version_path = fw_url_tmpl.format(driver_code = driver_code, full = 'inc')
  226. else:
  227. version_path = fw_url_tmpl.format(driver_code = driver_code, full = 'full')
  228. cmdPara = {'cmd': Const.CMD_CODE_SET_DEVINFO, 'IMEI': devNo, 'ota_set': {'fw_url': version_path}}
  229. print cmdPara
  230. log = DeviceUpgradeLog.new_log(dev = dev,
  231. coreVer = upgrade_core_ver,
  232. softVer = upgrade_soft_ver,
  233. driverCode = driver_code,
  234. updatePara = cmdPara)
  235. result = MessageSender.send(device = dev, cmd = Const.CMD_CODE_SET_DEVINFO, payload = cmdPara, timeout = 15)
  236. if result['rst'] != 0:
  237. log.set_stauts(DeviceUpgradeLog.Status.FAILURE)
  238. continue
  239. else:
  240. log.set_stauts(DeviceUpgradeLog.Status.RUNNING)
  241. count = count + 1
  242. doing_dict[devNo] = int(time.time())
  243. while True:
  244. if len(doing_dict) > parallel:
  245. print('queue is full.')
  246. for imei in list(doing_dict.keys()):
  247. start_time = doing_dict[imei]
  248. if (int(time.time()) - start_time) > 5 * 60:
  249. doing_dict.pop(imei, None)
  250. time.sleep(1)
  251. else:
  252. print('queue is not full')
  253. break
  254. except Exception, e:
  255. print 'some exception =%s' % e
  256. finally:
  257. while len(doing_dict) > 0:
  258. for imei in list(doing_dict.keys()):
  259. start_time = doing_dict[imei]
  260. if (int(time.time()) - start_time) > 5 * 60:
  261. doing_dict.pop(imei, None)
  262. time.sleep(1)
  263. if mqttc1883:
  264. mqttc1883.loop_stop()
  265. mqttc1883.disconnect()
  266. mqttc1883.close()
  267. if mqttc1884:
  268. mqttc1884.loop_stop()
  269. mqttc1884.disconnect()
  270. mqttc1884.close()
  271. print('finished')