def update(version, md5_server): """ Execute the actual update: extract the archive and execute the bash update script. :param version: the new version (after the update). :param md5_server: the md5 sum provided by the server. """ update_file = get_update_file() md5_client = md5(update_file) if md5_server != md5_client: raise Exception('MD5 of client (' + str(md5_client) + ') and server (' + str(md5_server) + ') don\'t match') extract = subprocess.Popen('cd `dirname ' + update_file + '`; tar xzf ' + update_file, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True) ret = extract.wait() extract_output = extract.stdout.read() if ret != 0: raise Exception('Extraction failed: ' + extract_output) update_script = subprocess.Popen(get_update_script() + ' `dirname ' + update_file + '`', stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True) ret = update_script.wait() update_output = update_script.stdout.read() cleanup = subprocess.Popen('rm -Rf `dirname ' + update_file + '`/*', stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True) cleanup.wait() cleanup_output = update_script.stdout.read() if ret != 0: raise Exception('Error during update (ret=' + str(ret) + ') : ' + update_output) else: config = ConfigParser() config.read(get_config_file()) config.set('OpenMotics', 'version', version) with open(get_config_file(), 'wb') as configfile: config.write(configfile) return extract_output + '\n' + update_output + '\n' + cleanup_output
def main(): """ The main function runs a loop that waits for dbus calls, drives the leds and reads the switch. """ try: config = ConfigParser() config.read(constants.get_config_file()) dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) system_bus = dbus.SystemBus() _ = dbus.service.BusName("com.openmotics.status", system_bus) # Initializes the bus # The above `_ = dbus...` need to be there, or the bus won't be initialized i2c_device = Hardware.get_i2c_device() i2c_address = int(config.get('OpenMotics', 'leds_i2c_address'), 16) status = StatusObject(system_bus, '/com/openmotics/status', i2c_device, i2c_address, Hardware.get_gpio_input()) status.start() status.set_led(Hardware.Led.POWER, True) LOGGER.log("Running led service.") mainloop = gobject.MainLoop() gobject.timeout_add(250, status.drive_leds) gobject.timeout_add(250, status.check_button) mainloop.run() except Exception as exception: LOGGER.log('Error starting led service: {0}'.format(exception))
def __init__(self, configuration_controller=INJECTED): config = ConfigParser() config.read(constants.get_config_file()) self._message_client = MessageClient('vpn_service') self._message_client.add_event_handler(self._event_receiver) self._message_client.set_state_handler(self._check_state) self._iterations = 0 self._last_cycle = 0 self._cloud_enabled = True self._sleep_time = 0 self._previous_sleep_time = 0 self._vpn_open = False self._debug_data = {} self._eeprom_events = deque() self._gateway = Gateway() self._vpn_controller = VpnController() self._config_controller = configuration_controller self._cloud = Cloud(config.get('OpenMotics', 'vpn_check_url') % config.get('OpenMotics', 'uuid'), self._message_client, self._config_controller) self._collectors = {'thermostats': DataCollector(self._gateway.get_thermostats, 60), 'inputs': DataCollector(self._gateway.get_inputs_status), 'outputs': DataCollector(self._gateway.get_enabled_outputs), 'pulses': DataCollector(self._gateway.get_pulse_counter_diff, 60), 'power': DataCollector(self._gateway.get_real_time_power), 'errors': DataCollector(self._gateway.get_errors, 600), 'local_ip': DataCollector(self._gateway.get_local_ip_address, 1800)}
def __init__(self): config = ConfigParser() config.read(constants.get_config_file()) self._iterations = 0 self._last_cycle = 0 self._cloud_enabled = True self._sleep_time = 0 self._previous_sleep_time = 0 self._vpn_open = False self._debug_data = {} self._eeprom_events = deque() self._gateway = Gateway() self._vpn_controller = VpnController() self._config_controller = ConfigurationController(constants.get_config_database_file(), threading.Lock()) self._dbus_service = DBusService('vpn_service', event_receiver=self._event_receiver, get_state=self._check_state) self._cloud = Cloud(config.get('OpenMotics', 'vpn_check_url') % config.get('OpenMotics', 'uuid'), self._dbus_service, self._config_controller) self._collectors = {'thermostats': DataCollector(self._gateway.get_thermostats, 60), 'outputs': DataCollector(self._gateway.get_enabled_outputs), 'pulses': DataCollector(self._gateway.get_pulse_counter_diff, 60), 'power': DataCollector(self._gateway.get_real_time_power), 'errors': DataCollector(self._gateway.get_errors, 600), 'local_ip': DataCollector(self._gateway.get_local_ip_address, 1800)}
def __init__(self, url=None): self._url = url if self._url is None: config = ConfigParser() config.read(constants.get_config_file()) self._url = config.get('OpenMotics', 'vpn_check_url') % config.get( 'OpenMotics', 'uuid')
def main(): """ The main function runs a loop that waits for dbus calls, drives the leds and reads the switch. """ config = ConfigParser() config.read(constants.get_config_file()) dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) system_bus = dbus.SystemBus() _ = dbus.service.BusName("com.openmotics.status", system_bus) # Initializes the bus. i2c_device = I2C_DEVICE_BBB if is_beagle_bone_black() else I2C_DEVICE_BB i2c_address = int(config.get('OpenMotics', 'leds_i2c_address'), 16) gpio_input = detect_button(GPIO_INPUT_BUTTON_GW_M, GPIO_INPUT_BUTTON_GW) status = StatusObject(system_bus, '/com/openmotics/status', i2c_device, i2c_address, gpio_input) status.start() mainloop = gobject.MainLoop() gobject.timeout_add(100, status.network) gobject.timeout_add(100, status.serial) gobject.timeout_add(100, status.input) print "Running led service." mainloop.run()
def main(): """ The main function runs a loop that waits for dbus calls, drives the leds and reads the switch. """ try: config = ConfigParser() config.read(constants.get_config_file()) i2c_address = int(config.get('OpenMotics', 'leds_i2c_address'), 16) led_controller = LedController(Hardware.get_i2c_device(), i2c_address, Hardware.get_gpio_input()) led_controller.start() led_controller.set_led(Hardware.Led.POWER, True) DBusService('led_service', event_receiver=lambda *args, **kwargs: led_controller.event_receiver(*args, **kwargs), get_state=led_controller.get_state) LOGGER.log("Running led service.") mainloop = gobject.MainLoop() gobject.timeout_add(250, led_controller.drive_leds) gobject.timeout_add(250, led_controller.check_button) mainloop.run() except Exception as exception: LOGGER.log('Error starting led service: {0}'.format(exception))
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 runs a loop that waits for om bus calls, drives the leds and reads the switch. """ try: logger.info('Starting led service...') config = ConfigParser() config.read(constants.get_config_file()) i2c_address = int(config.get('OpenMotics', 'leds_i2c_address'), 16) led_controller = LedController(Hardware.get_i2c_device(), i2c_address, Hardware.get_gpio_input()) led_controller.start() led_controller.set_led(Hardware.Led.POWER, True) signal_request = {'stop': False} def stop(signum, frame): """ This function is called on SIGTERM. """ _ = signum, frame logger.info('Stopping led service...') led_controller.stop() logger.info('Stopping led service...Done') signal_request['stop'] = True signal(SIGTERM, stop) logger.info('Starting led service... Done') while not signal_request['stop']: time.sleep(1) except Exception as exception: logger.exception('Error starting led service: {0}'.format(exception))
def __init__(self, url=None, message_client=INJECTED): # type: (Optional[str], MessageClient) -> None config = ConfigParser() config.read(constants.get_config_file()) self._message_client = message_client if self._message_client is not None: self._message_client.set_state_handler(self._check_state) self._last_successful_heartbeat = None # type: Optional[float] self._last_cycle = 0.0 self._cloud_enabled = True self._sleep_time = 0.0 self._previous_sleep_time = 0.0 self._gateway = Gateway() self._cloud = Cloud(url=url) self._task_executor = TaskExecutor() # Obsolete keys (do not use them, as they are still processed for legacy gateways): # `outputs`, `update`, `energy`, `pulse_totals`, `'thermostats`, `inputs`, `shutters` self._collectors = { 'errors': DataCollector('errors', self._gateway.get_errors, 600), 'local_ip': DataCollector('ip address', System.get_ip_address, 1800) } self._debug_collector = DebugDumpDataCollector()
def __init__(self, host="127.0.0.1"): self._host = host config = ConfigParser() config.read(constants.get_config_file()) if config.has_option('OpenMotics', 'http_port'): self._port = config.get('OpenMotics', 'http_port') else: self._port = 80
def main(): """ The main function. """ 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('--version', dest='version', action='store_true', help='display the version of the power module(s)') parser.add_argument('--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', 'power_serial') power_serial = RS485(Serial(port, 115200)) power_communicator = PowerCommunicator(power_serial, None, time_keeper_period=0, verbose=args.verbose) power_communicator.start() if args.address or args.all: power_controller = PowerController(constants.get_power_database_file()) power_modules = power_controller.get_power_modules() if args.all: for module_id in power_modules: module = power_modules[module_id] addr = module['address'] if args.version: print "E%d - Version: %s" % (addr, version(addr, power_communicator)) if args.file: if args.old and module['version'] == POWER_API_8_PORTS: bootload_8(addr, args.file, power_communicator) elif not args.old and module['version'] == POWER_API_12_PORTS: bootload_12(addr, args.file, power_communicator) else: addr = args.address modules = [module for module in power_modules if module['address'] == addr] if len(modules) != 1: print 'ERROR: Could not determine energy module version. Aborting' sys.exit(1) if args.version: print "E%d - Version: %s" % (addr, version(addr, power_communicator)) if args.file: if args.old and module['version'] == POWER_API_8_PORTS: bootload_8(addr, args.file, power_communicator) elif not args.old and module['version'] == POWER_API_12_PORTS: bootload_12(addr, args.file, power_communicator) else: parser.print_help()
def get_platform(): config = ConfigParser() config.read(constants.get_config_file()) if config.has_option('OpenMotics', 'platform'): platform = config.get('OpenMotics', 'platform') if platform in Platform.Types: return platform return Platform.Type.CLASSIC
def get_platform(): # type: () -> str from six.moves.configparser import ConfigParser config = ConfigParser() config.read(constants.get_config_file()) if config.has_option('OpenMotics', 'platform'): platform = config.get('OpenMotics', 'platform') if platform in Platform.Types: return platform return Platform.Type.CLASSIC
def https_port(): # type: () -> int try: from six.moves.configparser import ConfigParser config = ConfigParser() config.read(constants.get_config_file()) https_port = int(config.get('OpenMotics', 'https_port')) if https_port is None: https_port = 433 # default https port return https_port except Exception: return 433
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 __init__(self, path): # type: (str) -> None self._stopped = False self._path = path.rstrip('/') self._decorated_methods = { 'input_status': [], 'output_status': [], 'shutter_status': [], 'thermostat_status': [], 'thermostat_group_status': [], 'ventilation_status': [], 'receive_events': [], 'background_task': [], 'on_remove': [] } # type: Dict[str,List[Any]] self._name = None self._version = None self._interfaces = [] # type: List[Any] self._exposes = [] # type: List[Any] self._metric_definitions = [] # type: List[Any] self._metric_collectors = [] # type: List[Any] self._metric_receivers = [] # type: List[Any] self._plugin = None self._writer = PluginIPCWriter(os.fdopen(sys.stdout.fileno(), 'wb', 0)) self._reader = PluginIPCReader(os.fdopen(sys.stdin.fileno(), 'rb', 0), self._writer.log_exception) config = ConfigParser() config.read(constants.get_config_file()) try: http_port = int(config.get('OpenMotics', 'http_port')) except (NoSectionError, NoOptionError): http_port = 80 self._webinterface = WebInterfaceDispatcher(self._writer.log, port=http_port)
def bootload_modules(type, filename, verbose, logger): """ Bootload all modules of the given type with the firmware in the given filename. :param type: Type of the modules (o, d, i, t, c) :type type: chr :param filename: The filename for the hex file to load :type filename: string :param verbose: If true the serial communication is printed. :param verbose: boolean """ config = ConfigParser() config.read(constants.get_config_file()) port = config.get('OpenMotics', 'controller_serial') master_serial = Serial(port, 115200) master_communicator = MasterCommunicator(master_serial, verbose=verbose) master_communicator.start() addresses = get_module_addresses(master_communicator, type) blocks = 922 if type == 'c' else 410 ihex = intelhex.IntelHex(filename) crc = calc_crc(ihex, blocks) success = True for address in addresses: logger("Bootloading module %s" % pretty_address(address)) try: bootload(master_communicator, address, ihex, crc, blocks, logger) except Exception as exception: success = False logger("Bootloading failed") traceback.print_exc() return success
def main(): """ The main function contains the loop that check if the vpn should be opened every 2 seconds. Status data is sent when the vpn is checked. """ led_service = LedService() # Get the configuration config = ConfigParser() config.read(constants.get_config_file()) check_url = config.get('OpenMotics', 'vpn_check_url') % config.get( 'OpenMotics', 'uuid') gateway = Gateway() cloud = Cloud(check_url, led_service, ActionExecutor(gateway)) collectors = { 'energy': BufferingDataCollector(gateway.get_total_energy, 300), 'thermostats': DataCollector(gateway.get_thermostats, 60), 'pulse_totals': BufferingDataCollector(gateway.get_pulse_counter_status, 300), 'pulses': DataCollector(gateway.get_pulse_counter_diff, 60), 'outputs': DataCollector(gateway.get_enabled_outputs, mode='rt'), 'power': DataCollector(gateway.get_real_time_power, mode='rt'), 'update': DataCollector(gateway.get_update_status), 'errors': DataCollector(gateway.get_errors, 600), 'local_ip': DataCollector(gateway.get_local_ip_address, 1800), 'modules': DataCollector(gateway.get_modules, mode='init'), 'module_log': DataCollector(gateway.get_module_log, mode='init'), 'last_inputs': DataCollector(gateway.get_last_inputs, mode='init'), 'sensor_tmp': DataCollector(gateway.get_sensor_temperature_status, 10, mode='init'), 'sensor_hum': DataCollector(gateway.get_sensor_humidity_status, 10, mode='init'), 'sensor_bri': DataCollector(gateway.get_sensor_brightness_status, 10, mode='init') } iterations = 0 # Loop: check vpn and open/close if needed while True: vpn_data = {} for collector_name in collectors: collector = collectors[collector_name] data = collector.collect(cloud.get_current_modes()) if data is not None: vpn_data[collector_name] = data (success, should_open) = cloud.should_open_vpn(vpn_data) for collector_name in vpn_data.keys(): collector = collectors[collector_name] if type(collector) == BufferingDataCollector: collector.data_sent_callback(success) if iterations > 20 and cloud.get_last_connect( ) < time.time() - REBOOT_TIMEOUT: # The cloud is not responding for a while, perhaps the BeagleBone network stack is # hanging, reboot the gateway to reset the BeagleBone. reboot_gateway() is_open = VpnController.check_vpn() led_service.set_led('vpn', is_open) if should_open and not is_open: print str(datetime.now()) + ": opening vpn" VpnController.start_vpn() elif not should_open and is_open: print str(datetime.now()) + ": closing vpn" VpnController.stop_vpn() print "Sleeping for %ds" % cloud.get_sleep_time() time.sleep(cloud.get_sleep_time()) iterations += 1
def update(version, expected_md5): """ Execute the actual update: extract the archive and execute the bash update script. :param version: the new version (after the update). :param expected_md5: the md5 sum provided by the server. """ version_mapping = {} has_master_hardware = Platform.has_master_hardware() try: config = ConfigParser() config.read(constants.get_config_file()) from_version = config.get('OpenMotics', 'version') logger.info('==================================') logger.info('Starting update {} -> {}'.format(from_version, version)) update_file = constants.get_update_file() update_dir = os.path.dirname(update_file) # Change to update directory. os.chdir(update_dir) if os.path.exists(update_file): logger.info(' -> Extracting update.tgz') extract_legacy_update(update_file, expected_md5) else: logger.info(' -> Fetching metadata') meta = fetch_metadata(config, version, expected_md5) logger.info(' -> Downloading firmware for update {}'.format(meta['version'])) for data in meta['firmwares']: download_firmware(data['type'], data['url'], data['sha256']) version_mapping[data['type']] = data['version'] except Exception: logger.exception('failed to preprepare update') raise SystemExit(EXIT_CODES['failed_preprepare_update']) errors = [] services_running = True try: date = datetime.now().strftime('%Y%m%d%H%M%S') # TODO: should update and re-execute itself before proceeding? logger.info(' -> Checking services') check_services() logger.info(' -> Stopping services') stop_services() services_running = False if has_master_hardware: gateway_os = FIRMWARE_FILES['gateway_os'] if os.path.exists(gateway_os): os_version = version_mapping.get('gateway_os') logger.info(' -> Updating Gateway OS to {0}'.format(os_version if os_version else 'unknown version')) error = update_gateway_os(gateway_os, os_version) if error: errors.append(error) gateway_service = FIRMWARE_FILES['gateway_service'] if os.path.exists(gateway_service): service_version = version_mapping.get('gateway_service') logger.info(' -> Updating Gateway service to {0}'.format(service_version if service_version else 'unknown version')) error = update_gateway_backend(gateway_service, date, service_version) if error: errors.append(error) if has_master_hardware: master_type = get_master_type() master_firmware = FIRMWARE_FILES[master_type] if os.path.exists(master_firmware): master_version = version_mapping.get(master_type) logger.info(' -> Updating Master firmware to {0}'.format(master_version if master_version else 'unknown version')) error = update_master_firmware(master_type, master_firmware, master_version) if error: errors.append(error) for module, filename, arguments in [('energy', FIRMWARE_FILES['energy'], []), ('power', FIRMWARE_FILES['power'], ['--8'])]: if os.path.exists(filename): energy_version = version_mapping.get(module) logger.info(' -> Updating {0} firmware to {1}'.format(module, energy_version if energy_version else 'unknown version')) error = update_energy_firmware(module, filename, energy_version, arguments) if error: errors.append(error) for module in MODULE_TYPES: module_firmware = FIRMWARE_FILES[module] module_version = version_mapping.get(module) if os.path.exists(module_firmware): logger.info(' -> Updating {0} firmware to {1}'.format(module, module_version if module_version else 'unknown version')) error = update_module_firmware(module, module_firmware, module_version) if error: errors.append(error) logger.info('Checking master communication') check_master_communication() gateway_frontend = FIRMWARE_FILES['gateway_frontend'] if os.path.exists(gateway_frontend): frontend_version = version_mapping.get('gateway_frontend') logger.info(' -> Updating Gateway frontend to {0}'.format(frontend_version if frontend_version else 'unknown version')) error = update_gateway_frontend(gateway_frontend, date, frontend_version) if error: errors.append(error) if os.path.exists(gateway_frontend) or os.path.exists(gateway_service): clean_update_backups() logger.info(' -> Starting services') start_services() services_running = True logger.info(' -> Waiting for health check') check_gateway_health() except Exception as exc: logger.exception('Unexpected exception updating') errors.append(exc) # TODO: rollback finally: if not services_running: logger.info(' -> Starting services') start_services() logger.info(' -> Running cleanup') cmd('rm -v -rf {}/*'.format(update_dir), shell=True) if errors: logger.error('Exceptions:') for error in errors: logger.error('- {0}'.format(error)) raise errors[0] config.set('OpenMotics', 'version', version) temp_file = constants.get_config_file() + '.update' with open(temp_file, 'w') as configfile: config.write(configfile) shutil.move(temp_file, constants.get_config_file()) cmd(['sync']) if os.path.exists('/tmp/post_update_reboot'): logger.info('Scheduling reboot in 5 minutes') subprocess.Popen('sleep 300 && reboot', close_fds=True, shell=True) logger.info('DONE') logger.info('exit 0')
def main(): # type: () -> None """ 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') parser.add_argument('--update', dest='update', action='store_true', help='update the master firmware') parser.add_argument('--master-firmware-classic', help='path to the hexfile with the classic firmware') parser.add_argument('--master-firmware-core', help='path to the hexfile with the core+ firmware') args = parser.parse_args() setup_logger() config = ConfigParser() config.read(constants.get_config_file()) port = config.get('OpenMotics', 'controller_serial') if args.port: print(port) return if not any([args.sync, args.version, args.reset, args.hardreset, args.wipe, args.update]): parser.print_help() setup_minimal_master_platform(port) platform = Platform.get_platform() if args.hardreset: master_cold_reset() return elif args.update: if platform in Platform.CoreTypes: firmware = args.master_firmware_core if not firmware: print('error: --master-firmware-core is required to update') sys.exit(1) else: firmware = args.master_firmware_classic if not firmware: print('error: --master-firmware-classic is required to update') sys.exit(1) master_update(firmware) return communicator = get_communicator() communicator.start() try: if args.sync: master_sync() elif args.version: master_version() elif args.reset: master_reset() elif args.wipe: master_factory_reset() finally: communicator.stop()
def main(): """ The main function contains the loop that check if the vpn should be opened every 2 seconds. Status data is sent when the vpn is checked. """ led_service = LedService() config_lock = threading.Lock() config_controller = ConfigurationController(constants.get_config_database_file(), config_lock) def set_vpn(_should_open): is_running = VpnController.check_vpn() if _should_open and not is_running: LOGGER.log(str(datetime.now()) + ": opening vpn") VpnController.start_vpn() elif not _should_open and is_running: LOGGER.log(str(datetime.now()) + ": closing vpn") VpnController.stop_vpn() is_running = VpnController.check_vpn() led_service.set_led(Hardware.Led.VPN, is_running and VpnController.vpn_connected()) # Get the configuration config = ConfigParser() config.read(constants.get_config_file()) check_url = config.get('OpenMotics', 'vpn_check_url') % config.get('OpenMotics', 'uuid') gateway = Gateway() cloud = Cloud(check_url, led_service, config_controller) collectors = {'thermostats': DataCollector(gateway.get_thermostats, 60), 'pulses': DataCollector(gateway.get_pulse_counter_diff, 60), 'outputs': DataCollector(gateway.get_enabled_outputs), 'power': DataCollector(gateway.get_real_time_power), 'update': DataCollector(gateway.get_update_status), 'errors': DataCollector(gateway.get_errors, 600), 'local_ip': DataCollector(gateway.get_local_ip_address, 1800)} iterations = 0 previous_sleep_time = 0 while True: try: # Check whether connection to the Cloud is enabled/disabled cloud_enabled = config_controller.get_setting('cloud_enabled') if cloud_enabled is False: set_vpn(False) led_service.set_led(Hardware.Led.CLOUD, False) led_service.set_led(Hardware.Led.VPN, False) time.sleep(30) continue vpn_data = {} # Collect data to be send to the Cloud for collector_name in collectors: collector = collectors[collector_name] data = collector.collect() if data is not None: vpn_data[collector_name] = data # Send data to the cloud and see if the VPN should be opened should_open = cloud.should_open_vpn(vpn_data) if iterations > 20 and cloud.get_last_connect() < time.time() - REBOOT_TIMEOUT: # The cloud is not responding for a while. if not ping('cloud.openmotics.com') and not ping('8.8.8.8') and not ping(get_gateway()): # Perhaps the BeagleBone network stack is hanging, reboot the gateway # to reset the BeagleBone. reboot_gateway() iterations += 1 # Open or close the VPN set_vpn(should_open) # Getting some cleep sleep_time = cloud.get_sleep_time() if previous_sleep_time != sleep_time: LOGGER.log('Sleep time set to {0}s'.format(sleep_time)) previous_sleep_time = sleep_time time.sleep(sleep_time) except Exception as ex: LOGGER.log("Error during vpn check loop: {0}".format(ex))
def main(): supported_modules = ['O', 'R', 'D', 'I', 'T', 'C'] supported_modules_gen3 = ['O3', 'R3', 'D3', 'I3', 'T3', 'C3'] supported_can_modules = ['UC'] all_supported_modules = supported_modules + supported_modules_gen3 + supported_can_modules parser = argparse.ArgumentParser( description='Tool to bootload the slave modules.') parser.add_argument( '-t', '--type', dest='type', choices=all_supported_modules + [m.lower() for m in all_supported_modules], required=True, help='The type of module to bootload (choices: {0})'.format( ', '.join(all_supported_modules))) parser.add_argument('-f', '--file', dest='file', required=True, help='The filename of the hex file to bootload') parser.add_argument('-v', '--version', dest='version', required=False, help='The version of the firmware to flash') parser.add_argument('--verbose', dest='verbose', action='store_true', help='Show the serial output') args = parser.parse_args() module_type = args.type.upper() filename = args.file version = args.version gen3_firmware = module_type.endswith('3') if gen3_firmware: module_type = module_type[0] config = ConfigParser() config.read(constants.get_config_file()) port = config.get('OpenMotics', 'controller_serial') setup_minimal_master_platform(port) communicator = get_communicator() communicator.start() try: if Platform.get_platform() in Platform.CoreTypes: from master.core.slave_updater import SlaveUpdater update_success = SlaveUpdater.update_all( module_type=module_type, hex_filename=filename, gen3_firmware=gen3_firmware, version=version) else: from master.classic.slave_updater import bootload_modules 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 if module_type == 'UC': print( 'Updating uCAN modules not supported on Classic platform') return True # Don't fail the update update_success = bootload_modules(module_type=module_type, filename=filename, gen3_firmware=gen3_firmware, version=version) finally: communicator.stop() time.sleep(3) return update_success
def main(): """ Main function. """ log('Starting service...') config = ConfigParser() config.read(constants.get_config_file()) defaults = {'username': config.get('OpenMotics', 'cloud_user'), 'password': config.get('OpenMotics', 'cloud_pass')} controller_serial_port = config.get('OpenMotics', 'controller_serial') passthrough_serial_port = config.get('OpenMotics', 'passthrough_serial') power_serial_port = config.get('OpenMotics', 'power_serial') gateway_uuid = config.get('OpenMotics', 'uuid') config_lock = threading.Lock() user_controller = UserController(constants.get_config_database_file(), config_lock, defaults, 3600) config_controller = ConfigurationController(constants.get_config_database_file(), config_lock) dbus_service = DBusService('openmotics_service') controller_serial = Serial(controller_serial_port, 115200) power_serial = RS485(Serial(power_serial_port, 115200, timeout=None)) master_communicator = MasterCommunicator(controller_serial) eeprom_controller = EepromController( EepromFile(master_communicator), EepromExtension(constants.get_eeprom_extension_database_file()) ) if passthrough_serial_port: passthrough_serial = Serial(passthrough_serial_port, 115200) passthrough_service = PassthroughService(master_communicator, passthrough_serial) passthrough_service.start() power_controller = PowerController(constants.get_power_database_file()) power_communicator = PowerCommunicator(power_serial, power_controller) pulse_controller = PulseCounterController( constants.get_pulse_counter_database_file(), master_communicator, eeprom_controller ) observer = Observer(master_communicator, dbus_service) gateway_api = GatewayApi(master_communicator, power_communicator, power_controller, eeprom_controller, pulse_controller, dbus_service, observer, config_controller) observer.set_gateway_api(gateway_api) scheduling_controller = SchedulingController(constants.get_scheduling_database_file(), config_lock, gateway_api) maintenance_service = MaintenanceService(gateway_api, constants.get_ssl_private_key_file(), constants.get_ssl_certificate_file()) web_interface = WebInterface(user_controller, gateway_api, maintenance_service, dbus_service, config_controller, scheduling_controller) scheduling_controller.set_webinterface(web_interface) # Plugins plugin_controller = PluginController(web_interface, config_controller) web_interface.set_plugin_controller(plugin_controller) gateway_api.set_plugin_controller(plugin_controller) # Metrics metrics_cache_controller = MetricsCacheController(constants.get_metrics_database_file(), threading.Lock()) metrics_collector = MetricsCollector(gateway_api, pulse_controller) metrics_controller = MetricsController(plugin_controller, metrics_collector, metrics_cache_controller, config_controller, gateway_uuid) metrics_collector.set_controllers(metrics_controller, plugin_controller) metrics_controller.add_receiver(metrics_controller.receiver) metrics_controller.add_receiver(web_interface.distribute_metric) plugin_controller.set_metrics_controller(metrics_controller) plugin_controller.set_metrics_collector(metrics_collector) web_interface.set_metrics_collector(metrics_collector) web_interface.set_metrics_controller(metrics_controller) web_service = WebService(web_interface, config_controller) plugin_controller.set_webservice(web_service) observer.subscribe_master(Observer.MasterEvents.INPUT_TRIGGER, metrics_collector.on_input) observer.subscribe_master(Observer.MasterEvents.INPUT_TRIGGER, plugin_controller.process_input_status) observer.subscribe_master(Observer.MasterEvents.ON_OUTPUTS, metrics_collector.on_output) observer.subscribe_master(Observer.MasterEvents.ON_OUTPUTS, plugin_controller.process_output_status) observer.subscribe_master(Observer.MasterEvents.ON_SHUTTER_UPDATE, plugin_controller.process_shutter_status) observer.subscribe_events(web_interface.process_observer_event) led_thread = threading.Thread(target=led_driver, args=(dbus_service, master_communicator, power_communicator)) led_thread.setName("Serial led driver thread") led_thread.daemon = True led_thread.start() master_communicator.start() observer.start() power_communicator.start() metrics_controller.start() scheduling_controller.start() metrics_collector.start() web_service.start() gateway_api.start() plugin_controller.start() signal_request = {'stop': False} def stop(signum, frame): """ This function is called on SIGTERM. """ _ = signum, frame log('Stopping service...') web_service.stop() metrics_collector.stop() metrics_controller.stop() plugin_controller.stop() log('Stopping service... Done') signal_request['stop'] = True signal(SIGTERM, stop) log('Starting service... Done') while not signal_request['stop']: time.sleep(1)
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 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) master_communicator = MasterCommunicator(master_serial) 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 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()
def main(): """ Main function. """ config = ConfigParser() config.read(constants.get_config_file()) defaults = { 'username': config.get('OpenMotics', 'cloud_user'), 'password': config.get('OpenMotics', 'cloud_pass') } controller_serial_port = config.get('OpenMotics', 'controller_serial') passthrough_serial_port = config.get('OpenMotics', 'passthrough_serial') power_serial_port = config.get('OpenMotics', 'power_serial') gateway_uuid = config.get('OpenMotics', 'uuid') config_lock = threading.Lock() user_controller = UserController(constants.get_config_database_file(), config_lock, defaults, 3600) config_controller = ConfigurationController( constants.get_config_database_file(), config_lock) led_service = LedService() controller_serial = Serial(controller_serial_port, 115200) power_serial = RS485(Serial(power_serial_port, 115200, timeout=None)) master_communicator = MasterCommunicator(controller_serial) if passthrough_serial_port: passthrough_serial = Serial(passthrough_serial_port, 115200) passthrough_service = PassthroughService(master_communicator, passthrough_serial) passthrough_service.start() master_communicator.start( ) # A running master_communicator is required for the startup of services below power_controller = PowerController(constants.get_power_database_file()) power_communicator = PowerCommunicator(power_serial, power_controller) gateway_api = GatewayApi(master_communicator, power_communicator, power_controller) scheduling_controller = SchedulingController( constants.get_scheduling_database_file(), config_lock, gateway_api) maintenance_service = MaintenanceService( gateway_api, constants.get_ssl_private_key_file(), constants.get_ssl_certificate_file()) web_interface = WebInterface(user_controller, gateway_api, maintenance_service, led_service.in_authorized_mode, config_controller, scheduling_controller) scheduling_controller.set_webinterface(web_interface) plugin_controller = PluginController(web_interface, config_controller) web_interface.set_plugin_controller(plugin_controller) gateway_api.set_plugin_controller(plugin_controller) # Metrics metrics_cache_controller = MetricsCacheController( constants.get_metrics_database_file(), threading.Lock()) metrics_collector = MetricsCollector(gateway_api) metrics_controller = MetricsController(plugin_controller, metrics_collector, metrics_cache_controller, config_controller, gateway_uuid) metrics_collector.set_controllers(metrics_controller, plugin_controller) metrics_collector.set_plugin_intervals(plugin_controller.metric_intervals) metrics_controller.add_receiver(metrics_controller.receiver) metrics_controller.add_receiver(web_interface.distribute_metric) plugin_controller.set_metrics_controller(metrics_controller) web_interface.set_metrics_collector(metrics_collector) web_interface.set_metrics_controller(metrics_controller) web_service = WebService(web_interface, config_controller) def _on_output(*args, **kwargs): metrics_collector.on_output(*args, **kwargs) gateway_api.on_outputs(*args, **kwargs) def _on_input(*args, **kwargs): metrics_collector.on_input(*args, **kwargs) gateway_api.on_inputs(*args, **kwargs) master_communicator.register_consumer( BackgroundConsumer(master_api.output_list(), 0, _on_output, True)) master_communicator.register_consumer( BackgroundConsumer(master_api.input_list(), 0, _on_input)) power_communicator.start() plugin_controller.start_plugins() metrics_controller.start() scheduling_controller.start() metrics_collector.start() web_service.start() led_thread = threading.Thread(target=led_driver, args=(led_service, master_communicator, power_communicator)) led_thread.setName("Serial led driver thread") led_thread.daemon = True led_thread.start() def stop(signum, frame): """ This function is called on SIGTERM. """ _ = signum, frame sys.stderr.write("Shutting down") web_service.stop() metrics_collector.stop() metrics_controller.stop() plugin_controller.stop() signal(SIGTERM, stop)
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" elif args.sync or args.version or args.reset or args.wipe: master_serial = Serial(port, 115200) master_communicator = MasterCommunicator(master_serial) master_communicator.start() if args.sync: try: master_communicator.do_command(master_api.status()) except CommunicationTimedOutException: print "Failed" sys.exit(1) else: print "Done" sys.exit(0) elif args.version: status = master_communicator.do_command(master_api.status()) print "%d.%d.%d H%d" % (status['f1'], status['f2'], status['f3'], status['h']) elif args.reset: master_communicator.do_command(master_api.reset()) print "Reset !" 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 %d" % 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 get_main_version(self): """ Gets reported main version """ _ = self config = ConfigParser() config.read(constants.get_config_file()) return str(config.get('OpenMotics', 'version'))
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. """ 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
name for name in os.listdir(plugin_dir) if os.path.isdir(os.path.join(plugin_dir, name)) ] 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:
def main(): """ Main function. """ config = ConfigParser() config.read(constants.get_config_file()) defaults = { 'username': config.get('OpenMotics', 'cloud_user'), 'password': config.get('OpenMotics', 'cloud_pass') } user_controller = UserController(constants.get_user_database_file(), defaults, 3600) led_service = LedService() controller_serial_port = config.get('OpenMotics', 'controller_serial') passthrough_serial_port = config.get('OpenMotics', 'passthrough_serial') power_serial_port = config.get('OpenMotics', 'power_serial') controller_serial = Serial(controller_serial_port, 115200) passthrough_serial = Serial(passthrough_serial_port, 115200) power_serial = RS485(Serial(power_serial_port, 115200, timeout=None)) master_communicator = MasterCommunicator(controller_serial) master_communicator.start() power_controller = PowerController(constants.get_power_database_file()) power_communicator = PowerCommunicator(power_serial, power_controller) power_communicator.start() gateway_api = GatewayApi(master_communicator, power_communicator, power_controller) maintenance_service = MaintenanceService( gateway_api, constants.get_ssl_private_key_file(), constants.get_ssl_certificate_file()) passthrough_service = PassthroughService(master_communicator, passthrough_serial) passthrough_service.start() web_interface = WebInterface(user_controller, gateway_api, constants.get_scheduling_database_file(), maintenance_service, led_service.in_authorized_mode) plugin_controller = PluginController(web_interface) plugin_controller.start_plugins() web_interface.set_plugin_controller(plugin_controller) gateway_api.set_plugin_controller(plugin_controller) web_service = WebService(web_interface) web_service.start() led_service.set_led('stat2', True) led_thread = threading.Thread(target=led_driver, args=(led_service, master_communicator, power_communicator)) led_thread.setName("Serial led driver thread") led_thread.daemon = True led_thread.start() def stop(signum, frame): """ This function is called on SIGTERM. """ sys.stderr.write("Shutting down") led_service.set_led('stat2', False) web_service.stop() signal(SIGTERM, stop)
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())