import os import sys from apps.web.constant import Const, DeviceOnlineStatus PROJECT_ROOT = os.path.join(os.path.abspath(os.path.split(os.path.realpath(__file__))[0] + "/..")) sys.path.insert(0, PROJECT_ROOT) from base import init_env init_env(interactive = True) import datetime import logging import daiquiri daiquiri.setup( level=logging.DEBUG, outputs=( daiquiri.output.File('automation_upgrade_log/automation_upgrade_error.log', level=logging.ERROR), daiquiri.output.TimedRotatingFile( 'automation_upgrade_log/automation_upgrade_out.log', level=logging.DEBUG, interval=datetime.timedelta(hours=1)) ) ) logger = daiquiri.getLogger(__name__) import re import json import traceback import ConfigParser from library.paho.mqtt import publish, MQTTException from apps.web.device.models import Device, DeviceDict from apps.web.dealer.models import Dealer from mongoengine import Q def get_device_online(): devices = Device.objects(Q(devType__ne = None) & Q(devType__ne = {}) & Q(ownerId__ne = '')) if devices.count() == 0: logger.info('devices are not found by database, num=%s' % devices.count()) return None devDict = {_.devNo: {'cycle': _.cycle, 'logicalCode': _.logicalCode} for _ in devices} devices_dict = Device.get_many_device_status_cache(devDict) online_devices_imei = [k for k, v in devices_dict.items() if DeviceDict(v).online == DeviceOnlineStatus.DEV_STATUS_ONLINE] online_devices = Device.objects(devNo__in = online_devices_imei) return online_devices def update_version(device): if re.compile(r'^v1.5.*$').match(device.softVer) is not None: url = 'http://121.41.38.172:18070/uploaded/SMARTBOX_1.8.1_Luat_V0016_8955_SSL.bin' host, port = device.server.split(':') update(device.devNo, url, host, int(port)) elif re.compile(r'^v1.6.*$').match(device.softVer) is not None: url = 'http://121.41.38.172:18070/uploaded/SMARTBOX_1.8.1_Luat_V0016_8955_SSL.bin' host, port = device.server.split(':') update(device.devNo, url, host, int(port)) elif re.compile(r'^v1.7.*$').match(device.softVer) is not None: url = 'http://121.41.38.172:18070/uploaded/SMARTBOX_1.8.1_Luat_V0016_8955_SSL.bin' host, port = device.server.split(':') update(device.devNo, url, host, int(port)) elif re.compile(r'^v1.8.*$').match(device.softVer) is not None: url = 'http://121.41.38.172:18070/uploaded/SMARTBOX_1.8.1_Luat_V0016_8955_SSL.bin' host, port = device.server.split(':') update(device.devNo, url, host, int(port)) elif re.compile(r'^v3.0.*$').match(device.softVer) is not None: if 'devType' in device and 'code' in device.devType: if device.devType['code'] in ['110300']: url = 'http://121.41.38.172:18070/uploaded/SMART_BOX_4.2.0_Luat_V0020_8955_SSL.bin' host, port = device.server.split(':') update(device.devNo, url, host, int(port)) elif device.devType['code'] in ['100500', '100208', '100600', '100205', '100203', '100200', '100308', '100901', '100400', '100209', '100207', '100309']: url = 'http://121.41.38.172:18070/uploaded/SMART_BOX_4.1.0_Luat_V0020_8955_SSL.bin' host, port = device.server.split(':') update(device.devNo, url, host, int(port)) else: url = 'http://121.41.38.172:18070/uploaded/SMART_BOX_4.0.0_Luat_V0020_8955_SSL.bin' host, port = device.server.split(':') update(device.devNo, url, host, int(port)) else: url = 'http://121.41.38.172:18070/uploaded/SMART_BOX_4.0.0_Luat_V0020_8955_SSL.bin' host, port = device.server.split(':') update(device.devNo, url, host, int(port)) elif re.compile(r'^v3.2.*$').match(device.softVer) is not None: url = 'http://121.41.38.172:18070/uploaded/SMART_BOX_4.2.0_Luat_V0020_8955_SSL.bin' host, port = device.server.split(':') update(device.devNo, url, host, int(port)) elif re.compile(r'^v3.1.*$').match(device.softVer) is not None: url = 'http://121.41.38.172:18070/uploaded/SMART_BOX_4.1.0_Luat_V0020_8955_SSL.bin' host, port = device.server.split(':') update(device.devNo, url, host, int(port)) elif re.compile(r'^v3.3.*$').match(device.softVer) is not None: url = 'http://121.41.38.172:18070/uploaded/SMART_BOX_4.3.0_Luat_V0020_8955_SSL.bin' host, port = device.server.split(':') update(device.devNo, url, host, int(port)) elif re.compile(r'^v3.4.*$').match(device.softVer) is not None: url = 'http://121.41.38.172:18070/uploaded/SMART_BOX_4.4.0_Luat_V0020_8955_SSL.bin' host, port = device.server.split(':') update(device.devNo, url, host, int(port)) elif re.compile(r'^v4.0.*$').match(device.softVer) is not None: url = 'http://121.41.38.172:18070/uploaded/SMART_BOX_4.4.0_Luat_V0020_8955_SSL.bin' host, port = device.server.split(':') update(device.devNo, url, host, int(port)) elif re.compile(r'^v4.1.*$').match(device.softVer) is not None: url = 'http://121.41.38.172:18070/uploaded/SMART_BOX_4.4.0_Luat_V0020_8955_SSL.bin' host, port = device.server.split(':') update(device.devNo, url, host, int(port)) elif re.compile(r'^v4.2.*$').match(device.softVer) is not None: url = 'http://121.41.38.172:18070/uploaded/SMART_BOX_4.4.0_Luat_V0020_8955_SSL.bin' host, port = device.server.split(':') update(device.devNo, url, host, int(port)) elif re.compile(r'^v4.3.*$').match(device.softVer) is not None: if 'devType' in device and 'code' in device.devType: if device.devType['code'] not in ['100710', '100711', '100712', '100713', '100714']: url = 'http://121.41.38.172:18070/uploaded/SMART_BOX_4.4.0_Luat_V0020_8955_SSL.bin' host, port = device.server.split(':') update(device.devNo, url, host, int(port)) elif re.compile(r'^v4.4.*$').match(device.softVer) is not None: url = 'http://121.41.38.172:18070/uploaded/SMART_BOX_4.4.0_Luat_V0020_8955_SSL.bin' host, port = device.server.split(':') update(device.devNo, url, host, int(port)) else: logger.error("version %s error" % device.softVer) def update(imei, url, host, port): for val in range(3): message = { 'cmd': 202, 'IMEI': imei, 'ota_set': { 'fw_url': url } } try: publish.single("smart_box/%s/202" % imei, json.dumps(message), hostname=host, port=port, auth={'username': "20160528@vivestone", 'password': "j429QXqI5CTv"}) logger.info('Upgrade package sent successfully! imei=%s' % imei) break except MQTTException, e: logger.error(traceback.format_exc()) logger.error("imei: %s, capture a mqtt exception: %s" % (imei, e)) except Exception, e: logger.error("imei: %s, capture a exception: %s" % (imei, e)) def imei_update(imei=None, targetVersion=None): device = Device.objects(devNo=imei).first() if not device: logger.info('device is not found, imei=%s' % imei) return None message = { 'cmd': 202, 'IMEI': imei, 'ota_set': { 'fw_url': 'http://121.41.38.172:18070/uploaded/' + targetVersion } } host, port = device.server.split(':') send_update(imei=imei, message=message, host=host, port=port, targetVersion=targetVersion, device=device) def logicalCode_update(logicalCode=None, targetVersion=None): device = Device.objects(logicalCode=logicalCode).first() if not device: logger.info('device is not found, logicalCode=%s' % logicalCode) return None imei = device.devNo message = { 'cmd': 202, 'IMEI': imei, 'ota_set': { 'fw_url': 'http://121.41.38.172:18070/uploaded/' + targetVersion } } host, port = device.server.split(':') send_update(imei=imei, message=message, host=host, port=port, targetVersion=targetVersion, device=device) def dealerId_update(dealerId=None, targetVersion=None): dealer = Dealer.objects(id=dealerId).first() if not dealer: logger.info('dealer is not found, dealerId=%s' % dealerId) return None devices = Device.objects(ownerId=dealerId).all() if len(devices) == 0: logger.info('devices are not found, dealerId=%s' % dealerId) return None def f(devNo): _ = Device.get_dev(devNo) # type: DeviceDict if _: return _.online else: return False online_devices = [_ for _ in devices if f(_.devNo)] logger.info('DealerId update: %s devices are ready to update, dealerId=%s' % (len(online_devices), dealerId)) if len(online_devices) == 0: logger.info('online_devices are not found, dealerId=%s' % dealerId) return None for device in online_devices: imei = device.devNo message = { 'cmd': 202, 'IMEI': imei, 'ota_set': { 'fw_url': 'http://121.41.38.172:18070/uploaded/' + targetVersion } } host, port = device.server.split(':') send_update(imei=imei, message=message, host=host, port=port, targetVersion=targetVersion, device=device) def agentId_update(agentId=None, targetVersion=None): dealers = Dealer.objects(agentId=agentId).all() if len(dealers) == 0: logger.info('dealers are not found, agentId=%s' % agentId) return None for dealer in dealers: devices = Device.objects(ownerId=str(dealer.id)).all() if len(devices) == 0: logger.info('devices are not found, dealerId=%s' % dealer.id) return None def f(devNo): _ = Device.get_dev(devNo) # type: DeviceDict if _: return _.online else: return False online_devices = [_ for _ in devices if f(_.devNo)] logger.info('AgentId update: %s devices are ready to update, dealerId=%s' %(len(online_devices), dealer.id)) if len(online_devices) == 0: logger.info('online_devices are not found, dealerId=%s' % dealer.id) return None for device in online_devices: imei = device.devNo message = { 'cmd': 202, 'IMEI': imei, 'ota_set': { 'fw_url': 'http://121.41.38.172:18070/uploaded/' + targetVersion } } host, port = device.server.split(':') send_update(imei=imei, message=message, host=host, port=port, targetVersion=targetVersion, device=device) def driverCode_update(driverCode=None, targetVersion=None): devices = get_device_online() logger.info('DriverCode update: %s devices online' % len(devices)) if len(devices) == 0: logger.info('online_devices are not found, driverCode=%s' % driverCode) return None devices = [_ for _ in devices if _.devType['code'] == driverCode] logger.info('DriverCode update: %s devices are ready to update, driverCode=%s' % (len(devices), driverCode)) for device in devices: imei = device.devNo message = { 'cmd': 202, 'IMEI': imei, 'ota_set': { 'fw_url': 'http://121.41.38.172:18070/uploaded/' + targetVersion } } host, port = device.server.split(':') send_update(imei=imei, message=message, host=host, port=port, targetVersion=targetVersion, device=device) def version_update(version=None, targetVersion=None): devices = get_device_online() logger.info('Version update: %s devices online' % len(devices)) if len(devices) == 0: logger.info('online_devices are not found, version=%s' % version) return None for device in devices: if re.compile(r'^'+ version +'$').match(device.softVer) is not None: imei = device.devNo message = { 'cmd': 202, 'IMEI': imei, 'ota_set': { 'fw_url': 'http://121.41.38.172:18070/uploaded/' + targetVersion } } host, port = device.server.split(':') send_update(imei=imei, message=message, host=host, port=port, targetVersion=targetVersion, device=device) def send_update(imei=None, message=None, host=None, port=None, targetVersion=None, device=None): if device.softVer[1:] in targetVersion: logger.info('one of the device version %s was already updated, imei=%s' % (targetVersion, imei)) return None for val in range(3): try: publish.single("smart_box/%s/202" % imei, json.dumps(message), hostname=host, port=int(port), auth={'username': "20160528@vivestone", 'password': "j429QXqI5CTv"}) logger.info('Upgrade package sent successfully! imei=%s, targetVersion=%s' % (imei, targetVersion)) break except MQTTException, e: logger.error(traceback.format_exc()) logger.error("imei: %s, capture a mqtt exception: %s" % (imei, e)) except Exception, e: logger.error("imei: %s, capture a exception: %s" % (imei, e)) def upgrade_all(): devices = get_device_online() logger.info('All update: %s devices are ready to update' % len(devices)) if len(devices) == 0: logger.info('online_devices are not found, num=%s' % len(devices)) return None for device in devices: update_version(device) def upgrade_custom(): if targetVersion != '': if driverCode != '': driverCode_update(driverCode=driverCode, targetVersion=targetVersion) if imei != '': imei_update(imei=imei, targetVersion=targetVersion) if logicalCode != '': logicalCode_update(logicalCode=logicalCode, targetVersion=targetVersion) if dealerId != '': dealerId_update(dealerId=dealerId, targetVersion=targetVersion) if agentId != '': agentId_update(agentId=agentId, targetVersion=targetVersion) if version != '': version_update(version=version, targetVersion=targetVersion) else: logger.info('targetVersion is not defined') def main(): if upgradeAll is True: upgrade_all() else: upgrade_custom() if __name__ == '__main__': cf = ConfigParser.ConfigParser() cf.read('automation_upgrade.ini') upgradeAll = eval(cf.get('upgrade', 'upgradeAll')) if upgradeAll is False: targetVersion = cf.get('upgrade', 'targetVersion') driverCode = cf.get('upgrade', 'driverCode') imei = cf.get('upgrade', 'imei') logicalCode = cf.get('upgrade', 'logicalCode') dealerId = cf.get('upgrade', 'dealerId') agentId = cf.get('upgrade', 'agentId') version = cf.get('upgrade', 'version') main()