import json import click from pathlib import Path import logging import re from iottb import definitions from iottb.models.device_metadata import DeviceMetadata from iottb.models.iottb_config import IottbConfig from iottb.definitions import CFG_FILE_PATH, TB_ECHO_STYLES logger = logging.getLogger(__name__) def add_device_guided(ctx, cn, db): click.echo('TODO: Implement') logger.info('Adding device interactively') #logger.debug(f'Parameters: {params}. value: {value}') @click.command('add-device', help='Add a device to a database') @click.option('--dev', '--device-name', type=str, required=True, help='The name of the device to be added. If this string contains spaces or other special characters \ normalization is performed to derive a canonical name') @click.option('--db', '--database', type=click.Path(exists=True, file_okay=False, dir_okay=True), envvar='IOTTB_DB', show_envvar=True, help='Database in which to add this device. If not specified use default from config.') @click.option('--guided', is_flag=True, default=False, show_default=True, envvar='IOTTB_GUIDED_ADD', show_envvar=True, help='Add device interactively') def add_device(dev, db, guided): """Add a new device to a database Device name must be supplied unless in an interactive setup. Database is taken from config by default. """ logger.info('add-device invoked') # Step 1: Load Config # Dependency: Config file must exist config = IottbConfig(Path(CFG_FILE_PATH)) logger.debug(f'Config loaded: {config}') # Step 2: Load database # dependency: Database folder must exist if db: database = db path = config.db_path_dict[database] logger.debug(f'Resolved (path, db) {path}, {database}') else: path = config.default_db_location database = config.default_database logger.debug(f'Default (path, db) {path}, {database}') click.secho(f'Using database {database}') full_db_path = Path(path) / database if not full_db_path.is_dir(): logger.warning(f'No database at {database}') click.echo(f'Could not find a database.') click.echo(f'You need to initialize the testbed before before you add devices!') click.echo(f'To initialize the testbed in the default location run "iottb init-db"') click.echo('Exiting...') exit() # Step 3: Check if device already exists in database # dependency: DeviceMetadata object device_metadata = DeviceMetadata(device_name=dev) device_dir = full_db_path / device_metadata.canonical_name # Check if device is already registered if device_dir.exists(): logger.warning(f'Device directory {device_dir} already exists.') click.echo(f'Device {dev} already exists in the database.') click.echo('Exiting...') exit() try: device_dir.mkdir() except OSError as e: logger.error(f'Error trying to create device {e}') click.echo('Exiting...') exit() # Step 4: Save metadata into device_dir metadata_path = device_dir / definitions.DEVICE_METADATA_FILE_NAME with metadata_path.open('w') as metadata_file: json.dump(device_metadata.__dict__, metadata_file, indent=4) click.echo(f'Successfully added device {dev} to database') logger.debug(f'Added device {dev} to database {database}. Full path of metadata {metadata_path}') logger.info(f'Metadata for {dev} {device_metadata.print_attributes()}')