# -*- coding: utf-8 -*- # !/usr/bin/env python import copy import getopt import time import uuid import requests import sys import os PROJECT_ROOT = os.path.join(os.path.abspath(os.path.split(os.path.realpath(__file__))[0] + "/.."), '..') sys.path.insert(0, PROJECT_ROOT) def translate_driver_code(driver_code): if driver_code == '100205': return '100210' return driver_code def map_code(driver_code): if driver_code == '100205' or driver_code == '100210': return ['100205', '100210'] else: return [driver_code] def valid_code(driver_code, registerd_code): code_map = map_code(driver_code) return registerd_code in code_map try: options, args = getopt.getopt(sys.argv[1:], 'd:v:s:e:m:r:p:b:c:', [ 'driver=', 'version=', 'server=', 'env=', 'max-count=', 'platform-version=', 'platform=', 'parallel=', 'change=' ]) except getopt.GetoptError as e: print(str(e)) sys.exit() upgrade_version = '' system_env = 'testing' max_count = 10 platform_version = '' platform = '' parallel = 5 server = '' driver_code = '' change = False for name, value in options: if name in ('-v', '--version'): upgrade_version = value if name in ('-e', '--env'): system_env = value if name in ('-m', '--max-count'): max_count = int(value) if name in ('-r', '--platform-version'): platform_version = value if name in ('-p', '--platform'): platform = value if name in ('-b', '--parallel'): parallel = int(value) if name in ('-s', '--server'): server = value if name in ('-d', '--driver'): driver_code = value if name in ('-c', '--change'): change = True if value == 'yes' else False if not server: print 'server is null.' sys.exit(2) if not platform_version or not platform: print 'not assign platform info.' sys.exit(2) if platform not in ('8955', 'ASR1802'): print 'incorrect platform type.' sys.exit(2) if not upgrade_version: print 'error version = {version}'.format(version = upgrade_version) sys.exit(2) master, major, minor = upgrade_version.split('.') if not master or not major or not minor: print 'error version = {version}'.format(version = upgrade_version) sys.exit(2) if not system_env: print 'error system env = {env}'.format(env = system_env) sys.exit(2) import os os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'configs.{env}'.format(env = system_env)) from django.conf import settings from script.base import init_env import simplejson as json from script.device_upgrade import DeviceUpgradeLog init_env(interactive = False) from apps.web.core.networking import MessageSender from apps.web.device.models import Device from apps.web.constant import Const, DeviceOnlineStatus from apps.web.core.mqtt_client import MqttClient version_regex = 'v{master}\.{major}\.'.format(master = master, major = major) version_check = 'v{master}.{major}.'.format(master = master, major = major) upgrade_soft_ver = 'v{version}'.format(version = upgrade_version) if platform == 'ASR1802': upgrade_core_ver = 'Luat_V{platform_version}_{platform}_720D'.format( platform_version = '{0:0>4}'.format(platform_version), platform = platform) else: upgrade_core_ver = 'Luat_V{platform_version}_{platform}_SSL'.format( platform_version = '{0:0>4}'.format(platform_version), platform = platform) update_key = DeviceUpgradeLog.make_update_key(upgrade_core_ver, upgrade_soft_ver) print 'version regex is: {}'.format(version_regex) print 'version check is: {}'.format(version_check) print 'upgrade soft version is: {}'.format(upgrade_soft_ver) print 'update key is: {}'.format(update_key) mqttc1883 = None mqttc1884 = None doing_dict = {} exists_version_path = set() no_exists_version_path = set() try: def on_connect(client, userdata, flags, rc): pass def on_message(mqttc, obj, msg): # type: (MqttClient, object, json)->None msgDict = json.loads(bytes.decode(msg.payload)) imei = msgDict['IMEI'] print 'msg dict is: {}'.format(msgDict) log = DeviceUpgradeLog.objects( updateKey = update_key, devNo = imei ).first() # type: DeviceUpgradeLog if not log: print 'not has log record' if msgDict['cmd'] == 209: print('209 has received. msg = %s' % str(msgDict)) if msgDict['result']: if log: log.set_stauts(DeviceUpgradeLog.Status.UPGRADED) else: if log: log.set_stauts(DeviceUpgradeLog.Status.FAILURE) mqttc.unsubscribe('server/%s/209' % imei) doing_dict.pop(imei, None) elif msgDict['cmd'] == 200: if msgDict['soft_ver'] == upgrade_soft_ver: log.status = DeviceUpgradeLog.Status.SUCCESS log.reboot = True log.save() else: log.set_stauts(DeviceUpgradeLog.Status.FAILURE) mqttc.unsubscribe('server/%s/200' % imei) def on_disconnect(client, userdata, self): print('exit. client = %s' % str(client)) mqttc1883 = MqttClient(client_id = 'webapp_' + str(uuid.uuid1())) try: mqttc1883.on_message = on_message mqttc1883.on_connect = on_connect mqttc1883.on_disconnect = on_disconnect mqttc1883.username_pw_set(settings.MQTT_USER, settings.MQTT_PSWD) mqttc1883.connect(settings.MQTT_HOSTNAME, 1883, 60) mqttc1883.loop_start() except Exception as e: print(e) mqttc1884 = MqttClient(client_id = 'webapp_' + str(uuid.uuid1())) try: mqttc1884.on_message = on_message mqttc1884.on_connect = on_connect mqttc1884.on_disconnect = on_disconnect mqttc1884.username_pw_set(settings.MQTT_USER, settings.MQTT_PSWD) mqttc1884.connect(settings.MQTT_HOSTNAME, 1884, 60) mqttc1884.loop_start() except Exception as e: print(e) if driver_code: items = [item for item in DeviceUpgradeLog.objects(updateKey = update_key, status = DeviceUpgradeLog.Status.INIT, beforeDriverCode__in = map_code(driver_code))] else: items = [item for item in DeviceUpgradeLog.objects(updateKey = update_key, status = DeviceUpgradeLog.Status.INIT)] count = 0 for item in items: try: devNo = item.devNo dev = Device.get_dev(devNo) if dev.softVer == upgrade_soft_ver: print '{} is newest.'.format(devNo) item.status = DeviceUpgradeLog.Status.SUCCESS item.reboot = True item.save() continue if version_check != 'v5.100.' and dev.online != DeviceOnlineStatus.DEV_STATUS_ONLINE: print '{} is offline.'.format(devNo) continue if version_check == 'v5.100.': mqttc1883.subscribe('server/%s/209' % devNo, Const.MQTT_QOS) mqttc1883.subscribe('server/%s/200' % devNo, Const.MQTT_QOS) else: if ':1884' in dev['server']: mqttc1884.subscribe('server/%s/209' % devNo, Const.MQTT_QOS) mqttc1884.subscribe('server/%s/200' % devNo, Const.MQTT_QOS) elif ':1883' in dev['server']: mqttc1883.subscribe('server/%s/209' % devNo, Const.MQTT_QOS) mqttc1883.subscribe('server/%s/200' % devNo, Const.MQTT_QOS) else: print('%s %s %s\n' % (str(dev['devNo']), str(dev['logicalCode']), str(dev['softVer']))) continue version_path = item.updatePara['ota_set']['fw_url'] if change: version_path = version_path.replace(item.afterCoreVer, item.beforeCoreVer) if version_path not in exists_version_path: r = requests.get(version_path, timeout = 15) if r.status_code == 404: print '{} is not exist'.format(version_path) no_exists_version_path.add(version_path) continue else: exists_version_path.add(version_path) cmdPara = copy.deepcopy(item.updatePara) cmdPara['ota_set']['fw_url'] = version_path print cmdPara if version_check == 'v5.100.': dev['server'] = '120.27.251.159:1883' result = MessageSender.send(device = dev, cmd = cmdPara['cmd'], payload = dict(cmdPara), timeout = 15) if result['rst'] != 0: item.set_stauts(DeviceUpgradeLog.Status.FAILURE) continue else: count = count + 1 item.set_stauts(DeviceUpgradeLog.Status.RUNNING) doing_dict[devNo] = int(time.time()) while True: if len(doing_dict) > parallel: print('queue is full.') for imei in list(doing_dict.keys()): start_time = doing_dict[imei] if (int(time.time()) - start_time) > 5 * 60: doing_dict.pop(imei, None) time.sleep(5) else: print('queue is not full') break if max_count != -1 and count >= max_count: print 'max count reach.' break except Exception, e: print 'some exception =%s' % e finally: while len(doing_dict) > 0: for imei in list(doing_dict.keys()): start_time = doing_dict[imei] if (int(time.time()) - start_time) > 5 * 60: doing_dict.pop(imei, None) time.sleep(1) if mqttc1883: mqttc1883.loop_stop() mqttc1883.disconnect() mqttc1883.close() if mqttc1884: mqttc1884.loop_stop() mqttc1884.disconnect() mqttc1884.close() print('finished')