def setup_minimal_vpn_platform(message_client_name): # type: (str) -> None # IPC message_client = None if message_client_name is not None: message_client = MessageClient(message_client_name) Injectable.value(message_client=message_client)
] for plugin in plugins: shutil.rmtree(plugin_dir + plugin) config_files = constants.get_plugin_configfiles() for config_file in glob.glob(config_files): os.remove(config_file) if __name__ == '__main__': setup_logger() config = ConfigParser() config.read(constants.get_config_file()) Injectable.value(config_db_lock=Lock()) Injectable.value(config_db=constants.get_config_database_file()) Injectable.value(eeprom_db=constants.get_eeprom_extension_database_file()) controller_serial_port = config.get('OpenMotics', 'controller_serial') Injectable.value(controller_serial=Serial(controller_serial_port, 115200)) from gateway import config as config_controller _ = config_controller if Platform.get_platform() == Platform.Type.CORE_PLUS: from gateway.hal import master_controller_core # type: ignore from master_core import maintenance, core_communicator, ucan_communicator # type: ignore _ = master_controller_core, maintenance, core_communicator, ucan_communicator # type: ignore else: from gateway.hal import master_controller_classic # type: ignore from master import maintenance, master_communicator, eeprom_extension # type: ignore
System.import_libs() import sys import logging import constants from six.moves.configparser import ConfigParser from serial import Serial from ioc import Injectable from logs import Logs from master.core.core_updater import CoreUpdater logger = logging.getLogger("openmotics") if __name__ == '__main__': if len(sys.argv) != 2: print('Usage:') print('{0} firmware_filename'.format(sys.argv[0])) sys.exit(1) firmware_filename = sys.argv[1] config = ConfigParser() config.read(constants.get_config_file()) core_cli_serial_port = config.get('OpenMotics', 'cli_serial') Injectable.value(cli_serial=Serial(core_cli_serial_port, 115200)) Injectable.value(master_communicator=None) Injectable.value(maintenance_communicator=None) Logs.setup_logger() CoreUpdater.update(hex_filename=firmware_filename)
def setup_minimal_power_platform(): # type: () -> None config = ConfigParser() config.read(constants.get_config_file()) power_serial_port = config.get('OpenMotics', 'power_serial') if power_serial_port: Injectable.value(power_db=constants.get_power_database_file()) Injectable.value(power_store=PowerStore()) Injectable.value(power_serial=RS485( Serial(power_serial_port, 115200, timeout=None))) Injectable.value(power_communicator=PowerCommunicator()) Injectable.value(power_controller=PowerController()) Injectable.value(p1_controller=P1Controller()) else: Injectable.value(power_store=None) Injectable.value(power_communicator=None) Injectable.value(power_controller=None) Injectable.value(p1_controller=None) Injectable.value(power_serial=None)
def setup_minimal_master_platform(port): # type: (str) -> None config = ConfigParser() config.read(constants.get_config_file()) platform = Platform.get_platform() Injectable.value(controller_serial=Serial(port, 115200)) if platform == Platform.Type.DUMMY: Injectable.value(maintenance_communicator=None) Injectable.value(master_controller=MasterDummyController()) elif platform in Platform.CoreTypes: from master.core import ucan_communicator _ = ucan_communicator core_cli_serial_port = config.get('OpenMotics', 'cli_serial') Injectable.value(cli_serial=Serial(core_cli_serial_port, 115200)) Injectable.value(master_communicator=CoreCommunicator()) Injectable.value(maintenance_communicator=None) Injectable.value(memory_file=MemoryFile()) Injectable.value(master_controller=MasterCoreController()) elif platform in Platform.ClassicTypes: Injectable.value( eeprom_db=constants.get_eeprom_extension_database_file()) from master.classic import eeprom_extension _ = eeprom_extension Injectable.value(master_communicator=MasterCommunicator()) Injectable.value(maintenance_communicator=None) Injectable.value(master_controller=MasterClassicController()) else: logger.warning('Unhandled master implementation for %s', platform)
def main(): """ The main function. """ parser = argparse.ArgumentParser(description='Tool to control the master.') parser.add_argument('--port', dest='port', action='store_true', help='get the serial port device') parser.add_argument('--sync', dest='sync', action='store_true', help='sync the serial port') parser.add_argument('--reset', dest='reset', action='store_true', help='reset the master') parser.add_argument('--hard-reset', dest='hardreset', action='store_true', help='perform a hardware reset on the master') parser.add_argument('--version', dest='version', action='store_true', help='get the version of the master') parser.add_argument('--wipe', dest='wipe', action='store_true', help='wip the master eeprom') args = parser.parse_args() config = ConfigParser() config.read(constants.get_config_file()) port = config.get('OpenMotics', 'controller_serial') if args.port: print port elif args.hardreset: print 'Performing hard reset...' gpio_dir = open('/sys/class/gpio/gpio44/direction', 'w') gpio_dir.write('out') gpio_dir.close() def power(master_on): """ Set the power on the master. """ gpio_file = open('/sys/class/gpio/gpio44/value', 'w') gpio_file.write('1' if master_on else '0') gpio_file.close() power(False) time.sleep(5) power(True) print 'Done performing hard reset' elif args.sync or args.version or args.reset or args.wipe: master_serial = Serial(port, 115200) Injectable.value(controller_serial=master_serial) master_communicator = MasterCommunicator() master_communicator.start() if args.sync: print 'Sync...' try: master_communicator.do_command(master_api.status()) print 'Done sync' sys.exit(0) except CommunicationTimedOutException: print 'Failed sync' sys.exit(1) elif args.version: status = master_communicator.do_command(master_api.status()) print '{0}.{1}.{2} H{3}'.format(status['f1'], status['f2'], status['f3'], status['h']) elif args.reset: print 'Resetting...' try: master_communicator.do_command(master_api.reset()) print 'Done resetting' sys.exit(0) except CommunicationTimedOutException: print 'Failed resetting' sys.exit(1) elif args.wipe: (num_banks, bank_size, write_size) = (256, 256, 10) print 'Wiping the master...' for bank in range(0, num_banks): print '- Wiping bank {0}'.format(bank) for addr in range(0, bank_size, write_size): master_communicator.do_command(master_api.write_eeprom(), { 'bank': bank, 'address': addr, 'data': '\xff' * write_size }) master_communicator.do_command(master_api.activate_eeprom(), {'eep': 0}) print 'Done wiping the master' else: parser.print_help()
def setup_target_platform(target_platform, message_client_name): # type: (str, Optional[str]) -> None config = ConfigParser() config.read(constants.get_config_file()) config_lock = Lock() metrics_lock = Lock() config_database_file = constants.get_config_database_file() # Debugging options try: debug_logger = config.get('OpenMotics', 'debug_logger') if debug_logger: logging.getLogger(debug_logger).setLevel(logging.DEBUG) except NoOptionError: pass # Webserver / Presentation layer try: https_port = int(config.get('OpenMotics', 'https_port')) except NoOptionError: https_port = 443 try: http_port = int(config.get('OpenMotics', 'http_port')) except NoOptionError: http_port = 80 Injectable.value(https_port=https_port) Injectable.value(http_port=http_port) Injectable.value(ssl_private_key=constants.get_ssl_private_key_file()) Injectable.value(ssl_certificate=constants.get_ssl_certificate_file()) # TODO: Clean up dependencies more to reduce complexity # IOC announcements # When below modules are imported, the classes are registerd in the IOC graph. This is required for # instances that are used in @Inject decorated functions below, and is also needed to specify # abstract implementations depending on e.g. the platform (classic vs core) or certain settings (classic # thermostats vs gateway thermostats) from plugins import base from gateway import (metrics_controller, webservice, scheduling, observer, gateway_api, metrics_collector, maintenance_controller, user_controller, pulse_counter_controller, metrics_caching, watchdog, output_controller, room_controller, sensor_controller, shutter_controller, group_action_controller, module_controller, ventilation_controller) from cloud import events _ = (metrics_controller, webservice, scheduling, observer, gateway_api, metrics_collector, maintenance_controller, base, events, user_controller, pulse_counter_controller, metrics_caching, watchdog, output_controller, room_controller, sensor_controller, shutter_controller, group_action_controller, module_controller, ventilation_controller) # IPC message_client = None if message_client_name is not None: message_client = MessageClient(message_client_name) Injectable.value(message_client=message_client) # Cloud API Injectable.value(gateway_uuid=config.get('OpenMotics', 'uuid')) try: parsed_url = urlparse(config.get('OpenMotics', 'vpn_check_url')) except NoOptionError: parsed_url = urlparse('') Injectable.value(cloud_endpoint=parsed_url.hostname) Injectable.value(cloud_port=parsed_url.port) Injectable.value(cloud_ssl=parsed_url.scheme == 'https') Injectable.value(cloud_api_version=0) cloud_url = urlunparse( (parsed_url.scheme, parsed_url.netloc, '', '', '', '')) Injectable.value(cloud_url=cloud_url or None) try: firmware_url = config.get('OpenMotics', 'firmware_url') except NoOptionError: path = '/portal/firmware_metadata' firmware_url = urlunparse( (parsed_url.scheme, parsed_url.netloc, path, '', '', '')) Injectable.value(firmware_url=firmware_url or None) # User Controller Injectable.value(user_db=config_database_file) Injectable.value(user_db_lock=config_lock) Injectable.value(token_timeout=3600) Injectable.value( config={ 'username': config.get('OpenMotics', 'cloud_user'), 'password': config.get('OpenMotics', 'cloud_pass') }) # Metrics Controller Injectable.value(metrics_db=constants.get_metrics_database_file()) Injectable.value(metrics_db_lock=metrics_lock) # Energy Controller try: power_serial_port = config.get('OpenMotics', 'power_serial') except NoOptionError: power_serial_port = '' if power_serial_port: Injectable.value(power_db=constants.get_power_database_file()) Injectable.value(power_store=PowerStore()) # TODO: make non blocking? Injectable.value(power_serial=RS485( Serial(power_serial_port, 115200, timeout=None))) Injectable.value(power_communicator=PowerCommunicator()) Injectable.value(power_controller=PowerController()) Injectable.value(p1_controller=P1Controller()) else: Injectable.value(power_serial=None) Injectable.value(power_store=None) Injectable.value( power_communicator=None) # TODO: remove from gateway_api Injectable.value(power_controller=None) Injectable.value(p1_controller=None) # Pulse Controller Injectable.value(pulse_db=constants.get_pulse_counter_database_file()) # Master Controller try: controller_serial_port = config.get('OpenMotics', 'controller_serial') except NoOptionError: controller_serial_port = '' if controller_serial_port: Injectable.value(controller_serial=Serial( controller_serial_port, 115200, exclusive=True)) if target_platform in [Platform.Type.DUMMY, Platform.Type.ESAFE]: Injectable.value(maintenance_communicator=None) Injectable.value(passthrough_service=None) Injectable.value(master_controller=MasterDummyController()) Injectable.value(eeprom_db=None) from gateway.hal.master_controller_dummy import DummyEepromObject Injectable.value(eeprom_extension=DummyEepromObject()) elif target_platform in Platform.CoreTypes: # FIXME don't create singleton for optional controller? from master.core import ucan_communicator, slave_communicator _ = ucan_communicator, slave_communicator core_cli_serial_port = config.get('OpenMotics', 'cli_serial') Injectable.value(cli_serial=Serial(core_cli_serial_port, 115200)) Injectable.value(passthrough_service=None) # Mark as "not needed" # TODO: Remove; should not be needed for Core Injectable.value( eeprom_db=constants.get_eeprom_extension_database_file()) Injectable.value(master_communicator=CoreCommunicator()) Injectable.value( maintenance_communicator=MaintenanceCoreCommunicator()) Injectable.value(memory_file=MemoryFile()) Injectable.value(master_controller=MasterCoreController()) elif target_platform in Platform.ClassicTypes: # FIXME don't create singleton for optional controller? from master.classic import eeprom_extension _ = eeprom_extension leds_i2c_address = config.get('OpenMotics', 'leds_i2c_address') passthrough_serial_port = config.get('OpenMotics', 'passthrough_serial') Injectable.value( eeprom_db=constants.get_eeprom_extension_database_file()) Injectable.value(leds_i2c_address=int(leds_i2c_address, 16)) if passthrough_serial_port: Injectable.value( passthrough_serial=Serial(passthrough_serial_port, 115200)) from master.classic.passthrough import PassthroughService _ = PassthroughService # IOC announcement else: Injectable.value(passthrough_service=None) Injectable.value(master_communicator=MasterCommunicator()) Injectable.value( maintenance_communicator=MaintenanceClassicCommunicator()) Injectable.value(master_controller=MasterClassicController()) else: logger.warning('Unhandled master implementation for %s', target_platform) if target_platform in [Platform.Type.DUMMY, Platform.Type.ESAFE]: Injectable.value(frontpanel_controller=None) elif target_platform in Platform.CoreTypes: Injectable.value(frontpanel_controller=FrontpanelCoreController()) elif target_platform in Platform.ClassicTypes: Injectable.value(frontpanel_controller=FrontpanelClassicController()) else: logger.warning('Unhandled frontpanel implementation for %s', target_platform) # Thermostats thermostats_gateway_feature = Feature.get_or_none( name='thermostats_gateway') thermostats_gateway_enabled = thermostats_gateway_feature is not None and thermostats_gateway_feature.enabled if target_platform not in Platform.ClassicTypes or thermostats_gateway_enabled: Injectable.value(thermostat_controller=ThermostatControllerGateway()) else: Injectable.value(thermostat_controller=ThermostatControllerMaster())
def build_graph(): config = ConfigParser() config.read(constants.get_config_file()) config_lock = Lock() scheduling_lock = Lock() metrics_lock = Lock() config_database_file = constants.get_config_database_file() # TODO: Clean up dependencies more to reduce complexity # IOC announcements # When below modules are imported, the classes are registerd in the IOC graph. This is required for # instances that are used in @Inject decorated functions below, and is also needed to specify # abstract implementations depending on e.g. the platform (classic vs core) or certain settings (classic # thermostats vs gateway thermostats) from power import power_communicator, power_controller from plugins import base from gateway import (metrics_controller, webservice, scheduling, observer, gateway_api, metrics_collector, maintenance_controller, comm_led_controller, users, pulses, config as config_controller, metrics_caching, watchdog) from cloud import events _ = (metrics_controller, webservice, scheduling, observer, gateway_api, metrics_collector, maintenance_controller, base, events, power_communicator, comm_led_controller, users, power_controller, pulses, config_controller, metrics_caching, watchdog) if Platform.get_platform() == Platform.Type.CORE_PLUS: from gateway.hal import master_controller_core from master_core import maintenance, core_communicator, ucan_communicator from master import eeprom_extension # TODO: Obsolete, need to be removed _ = master_controller_core, maintenance, core_communicator, ucan_communicator else: from gateway.hal import master_controller_classic from master import maintenance, master_communicator, eeprom_extension _ = master_controller_classic, maintenance, master_communicator, eeprom_extension thermostats_gateway_feature = Feature.get_or_none( name='thermostats_gateway') thermostats_gateway_enabled = thermostats_gateway_feature is not None and thermostats_gateway_feature.enabled if Platform.get_platform( ) == Platform.Type.CORE_PLUS or thermostats_gateway_enabled: from gateway.thermostat.gateway import thermostat_controller_gateway _ = thermostat_controller_gateway else: from gateway.thermostat.master import thermostat_controller_master _ = thermostat_controller_master # IPC Injectable.value(message_client=MessageClient('openmotics_service')) # Cloud API parsed_url = urlparse(config.get('OpenMotics', 'vpn_check_url')) Injectable.value(gateway_uuid=config.get('OpenMotics', 'uuid')) Injectable.value(cloud_endpoint=parsed_url.hostname) Injectable.value(cloud_port=parsed_url.port) Injectable.value(cloud_ssl=parsed_url.scheme == 'https') Injectable.value(cloud_api_version=0) # User Controller Injectable.value(user_db=config_database_file) Injectable.value(user_db_lock=config_lock) Injectable.value(token_timeout=3600) Injectable.value( config={ 'username': config.get('OpenMotics', 'cloud_user'), 'password': config.get('OpenMotics', 'cloud_pass') }) # Configuration Controller Injectable.value(config_db=config_database_file) Injectable.value(config_db_lock=config_lock) # Energy Controller power_serial_port = config.get('OpenMotics', 'power_serial') Injectable.value(power_db=constants.get_power_database_file()) if power_serial_port: Injectable.value(power_serial=RS485( Serial(power_serial_port, 115200, timeout=None))) else: Injectable.value(power_serial=None) Injectable.value(power_communicator=None) Injectable.value(power_controller=None) # Pulse Controller Injectable.value(pulse_db=constants.get_pulse_counter_database_file()) # Scheduling Controller Injectable.value( scheduling_db=constants.get_scheduling_database_file()) Injectable.value(scheduling_db_lock=scheduling_lock) # Master Controller controller_serial_port = config.get('OpenMotics', 'controller_serial') Injectable.value( controller_serial=Serial(controller_serial_port, 115200)) if Platform.get_platform() == Platform.Type.CORE_PLUS: from master_core.memory_file import MemoryFile, MemoryTypes core_cli_serial_port = config.get('OpenMotics', 'cli_serial') Injectable.value(cli_serial=Serial(core_cli_serial_port, 115200)) Injectable.value(passthrough_service=None) # Mark as "not needed" Injectable.value( memory_files={ MemoryTypes.EEPROM: MemoryFile(MemoryTypes.EEPROM), MemoryTypes.FRAM: MemoryFile(MemoryTypes.FRAM) }) # TODO: Remove; should not be needed for Core Injectable.value( eeprom_db=constants.get_eeprom_extension_database_file()) else: passthrough_serial_port = config.get('OpenMotics', 'passthrough_serial') Injectable.value( eeprom_db=constants.get_eeprom_extension_database_file()) if passthrough_serial_port: Injectable.value( passthrough_serial=Serial(passthrough_serial_port, 115200)) from master.passthrough import PassthroughService _ = PassthroughService # IOC announcement else: Injectable.value(passthrough_service=None) # Metrics Controller Injectable.value(metrics_db=constants.get_metrics_database_file()) Injectable.value(metrics_db_lock=metrics_lock) # Webserver / Presentation layer Injectable.value(ssl_private_key=constants.get_ssl_private_key_file()) Injectable.value(ssl_certificate=constants.get_ssl_certificate_file())
def main(): """ The main function. """ parser = argparse.ArgumentParser( description= 'Tool to bootload the slave modules (output, dimmer, input and temperature).' ) parser.add_argument( '-t', '--type', dest='type', choices=['o', 'r', 'd', 'i', 't', 'c', 'O', 'R', 'D', 'I', 'T', 'C'], required=True, help='the type of module to bootload (choices: O, R, D, I, T, C)') parser.add_argument('-f', '--file', dest='file', required=True, help='the filename of the hex file to bootload') parser.add_argument('-l', '--log', dest='log', required=False) parser.add_argument('-V', '--verbose', dest='verbose', action='store_true', help='show the serial output') args = parser.parse_args() config = ConfigParser() config.read(constants.get_config_file()) port = config.get('OpenMotics', 'controller_serial') master_serial = Serial(port, 115200) Injectable.value(controller_serial=master_serial) log_file = None try: if args.log is not None: try: log_file = open(args.log, 'a') except IOError as ex: print 'Could not open the requested log file: {0}'.format(ex) return False logger = lambda msg: log_file.write('{0}\n'.format(msg)) else: logger = lambda msg: sys.stdout.write('{0}\n'.format(msg)) try: if os.path.getsize(args.file) <= 0: print 'Could not read hex or file is empty: {0}'.format( args.file) return False except OSError as ex: print 'Could not open hex: {0}'.format(ex) return False # The type argument is lowercase for backwards compatibility reasons. However, all subsequent calls need the correct type module_type = args.type.upper() update_success = bootload_modules(module_type, args.file, logger) finally: if log_file is not None: log_file.close() return update_success
def main(): """ The main function. """ logger.info('Bootloader for Energy/Power Modules and P1 Concentrator') logger.info('Command: {0}'.format(' '.join(sys.argv))) parser = argparse.ArgumentParser(description='Tool to bootload a module.') parser.add_argument('--address', dest='address', type=int, help='the address of the module to bootload') parser.add_argument('--all', dest='all', action='store_true', help='bootload all modules') parser.add_argument('--file', dest='file', help='the filename of the hex file to bootload') parser.add_argument('--8', dest='old', action='store_true', help='bootload for the 8-port power modules') parser.add_argument('--p1c', dest='p1c', action='store_true', help='bootload for the P1 concentrator modules') parser.add_argument('--verbose', dest='verbose', action='store_true', help='show the serial output') parser.add_argument('--scan', dest='scan', action='store_true', help='Scan the energy bus for modules') args = parser.parse_args() if not args.file and not args.scan: parser.print_help() return config = ConfigParser() config.read(constants.get_config_file()) port = config.get('OpenMotics', 'power_serial') power_serial = RS485(Serial(port, 115200)) Injectable.value(power_serial=power_serial) Injectable.value(power_db=constants.get_power_database_file()) power_controller = PowerController() power_communicator = PowerCommunicator(time_keeper_period=0, verbose=args.verbose) power_communicator.start() if args.scan: logger.info('Scanning addresses 0-255...') for address in xrange(256): for module_type, version in { 'E/P': power_api.ENERGY_MODULE, 'C': power_api.P1_CONCENTRATOR }.iteritems(): try: logger.info('{0}{1} - Version: {2}'.format( module_type, address, get_module_firmware_version(address, version, power_communicator))) except Exception: pass logger.info('Scan completed') return version = power_api.ENERGY_MODULE if args.old: version = power_api.POWER_MODULE elif args.p1c: version = power_api.P1_CONCENTRATOR def _bootload(_module, _module_address, filename): try: if version == _module['version'] == power_api.POWER_MODULE: bootload_power_module(_module_address, filename, power_communicator) elif version == _module['version'] == power_api.ENERGY_MODULE: bootload_energy_module(_module_address, filename, power_communicator) elif version == _module['version'] == power_api.P1_CONCENTRATOR: bootload_p1_concentrator(_module_address, filename, power_communicator) except CommunicationTimedOutException: logger.warning( 'E{0} - Module unavailable. Skipping...'.format(address)) except Exception: logger.exception( 'E{0} - Unexpected exception during bootload. Skipping...'. format(address)) if args.address or args.all: power_modules = power_controller.get_power_modules() if args.all: for module_id in power_modules: module = power_modules[module_id] address = module['address'] _bootload(module, address, args.file) else: address = args.address modules = [ module for module in power_modules.values() if module['address'] == address ] if len(modules) != 1: logger.info( 'ERROR: Cannot find a module with address {0}'.format( address)) sys.exit(0) module = modules[0] _bootload(module, address, args.file) else: parser.print_help()
def main(): """ The main function. """ logger.info('Energy/Power Module bootloader') logger.info('Command: {0}'.format(' '.join(sys.argv))) parser = argparse.ArgumentParser( description='Tool to bootload a power module.') parser.add_argument('--address', dest='address', type=int, help='the address of the power module to bootload') parser.add_argument('--all', dest='all', action='store_true', help='bootload all power modules') parser.add_argument('--file', dest='file', help='the filename of the hex file to bootload') parser.add_argument('--8', dest='old', action='store_true', help='bootload for the 8-port power modules') parser.add_argument('--verbose', dest='verbose', action='store_true', help='show the serial output') args = parser.parse_args() if not args.file: parser.print_help() return config = ConfigParser() config.read(constants.get_config_file()) port = config.get('OpenMotics', 'power_serial') power_serial = RS485(Serial(port, 115200)) Injectable.value(power_serial=power_serial) Injectable.value(power_db=constants.get_power_database_file()) power_controller = PowerController() power_communicator = PowerCommunicator(time_keeper_period=0, verbose=args.verbose) power_communicator.start() def _bootload(_module, _module_address, filename, is_power_module): try: if is_power_module and _module['version'] == POWER_API_8_PORTS: bootload_8(_module_address, filename, power_communicator) elif not is_power_module and _module[ 'version'] == POWER_API_12_PORTS: bootload_12(_module_address, filename, power_communicator) except CommunicationTimedOutException: logger.warning( 'E{0} - Module unavailable. Skipping...'.format(address)) except Exception: logger.exception( 'E{0} - Unexpected exception during bootload. Skipping...'. format(address)) if args.address or args.all: power_modules = power_controller.get_power_modules() if args.all: for module_id in power_modules: module = power_modules[module_id] address = module['address'] _bootload(module, address, args.file, is_power_module=args.old) else: address = args.address modules = [ module for module in power_modules.values() if module['address'] == address ] if len(modules) != 1: logger.info( 'ERROR: Cannot find a module with address {0}'.format( address)) sys.exit(0) module = modules[0] _bootload(module, address, args.file, is_power_module=args.old) else: parser.print_help()
# Try to figure out whether the network stack works as expected if not VPNService.has_connectivity(): reboot_gateway() self._iterations += 1 # Open or close the VPN self._set_vpn(feedback['open_vpn']) # Getting some sleep exec_time = time.time() - start_time if exec_time > 2: logger.warning('Heartbeat took more than 2s to complete: {0:.2f}s'.format(exec_time)) sleep_time = self._cloud.get_sleep_time() if self._previous_sleep_time != sleep_time: logger.info('Set sleep interval to {0}s'.format(sleep_time)) self._previous_sleep_time = sleep_time time.sleep(sleep_time) except Exception as ex: logger.error("Error during vpn check loop: {0}".format(ex)) time.sleep(1) if __name__ == '__main__': setup_logger() logger.info("Starting VPN service") Injectable.value(config_db=constants.get_config_database_file()) Injectable.value(config_db_lock=Lock()) vpn_service = VPNService() vpn_service.start()