示例#1
0
def file_(value):
    import json
    from esphome.py_compat import safe_input
    value = string(value)
    path = CORE.relative_config_path(value)

    if CORE.vscode and (not CORE.ace or os.path.abspath(path)
                        == os.path.abspath(CORE.config_path)):
        print(json.dumps({
            'type': 'check_file_exists',
            'path': path,
        }))
        data = json.loads(safe_input())
        assert data['type'] == 'file_exists_response'
        if data['content']:
            return value
        raise Invalid(
            u"Could not find file '{}'. Please make sure it exists (full path: {})."
            u"".format(path, os.path.abspath(path)))

    if not os.path.exists(path):
        raise Invalid(
            u"Could not find file '{}'. Please make sure it exists (full path: {})."
            u"".format(path, os.path.abspath(path)))
    if not os.path.isfile(path):
        raise Invalid(u"Path '{}' is not a file (full path: {})."
                      u"".format(path, os.path.abspath(path)))
    return value
示例#2
0
def read_config(args):
    while True:
        CORE.reset()
        data = json.loads(safe_input())
        assert data['type'] == 'validate'
        CORE.vscode = True
        CORE.ace = args.ace
        f = data['file']
        if CORE.ace:
            CORE.config_path = os.path.join(args.configuration[0], f)
        else:
            CORE.config_path = data['file']
        vs = VSCodeResult()
        try:
            res = load_config()
        except Exception as err:  # pylint: disable=broad-except
            vs.add_yaml_error(text_type(err))
        else:
            for err in res.errors:
                try:
                    range_ = _get_invalid_range(res, err)
                    vs.add_validation_error(range_,
                                            _format_vol_invalid(err, res))
                except Exception:  # pylint: disable=broad-except
                    continue
        print(vs.dump())
示例#3
0
def choose_prompt(options):
    if not options:
        raise EsphomeError(
            "Found no valid options for upload/logging, please make sure relevant "
            "sections (ota, mqtt, ...) are in your configuration and/or the device "
            "is plugged in.")

    if len(options) == 1:
        return options[0][1]

    safe_print(u"Found multiple options, please choose one:")
    for i, (desc, _) in enumerate(options):
        safe_print(u"  [{}] {}".format(i + 1, desc))

    while True:
        opt = safe_input('(number): ')
        if opt in options:
            opt = options.index(opt)
            break
        try:
            opt = int(opt)
            if opt < 1 or opt > len(options):
                raise ValueError
            break
        except ValueError:
            safe_print(color('red', u"Invalid option: '{}'".format(opt)))
    return options[opt - 1][1]
示例#4
0
def read_config_file(path):
    # type: (basestring) -> unicode
    if CORE.vscode and (not CORE.ace or os.path.abspath(path)
                        == os.path.abspath(CORE.config_path)):
        print(json.dumps({
            'type': 'read_file',
            'path': path,
        }))
        data = json.loads(safe_input())
        assert data['type'] == 'file_response'
        return data['content']

    return read_file(path)
示例#5
0
def read_config_file(path):
    # type: (basestring) -> unicode
    if CORE.vscode and (not CORE.ace or os.path.abspath(path)
                        == os.path.abspath(CORE.config_path)):
        print(json.dumps({
            'type': 'read_file',
            'path': path,
        }))
        data = json.loads(safe_input())
        assert data['type'] == 'file_response'
        return data['content']

    try:
        with codecs.open(path, encoding='utf-8') as handle:
            return handle.read()
    except IOError as exc:
        raise EsphomeError(u"Error accessing file {}: {}".format(path, exc))
    except UnicodeDecodeError as exc:
        raise EsphomeError(u"Unable to read file {}: {}".format(path, exc))
示例#6
0
def choose_prompt(options):
    if not options:
        raise ValueError

    if len(options) == 1:
        return options[0][1]

    safe_print(u"Found multiple options, please choose one:")
    for i, (desc, _) in enumerate(options):
        safe_print(u"  [{}] {}".format(i + 1, desc))

    while True:
        opt = safe_input('(number): ')
        if opt in options:
            opt = options.index(opt)
            break
        try:
            opt = int(opt)
            if opt < 1 or opt > len(options):
                raise ValueError
            break
        except ValueError:
            safe_print(color('red', u"Invalid option: '{}'".format(opt)))
    return options[opt - 1][1]
示例#7
0
def wizard(path):
    if not path.endswith('.yaml') and not path.endswith('.yml'):
        safe_print(
            u"Please make your configuration file {} have the extension .yaml or .yml"
            u"".format(color('cyan', path)))
        return 1
    if os.path.exists(path):
        safe_print(
            u"Uh oh, it seems like {} already exists, please delete that file first "
            u"or chose another configuration file.".format(color('cyan',
                                                                 path)))
        return 1
    safe_print("Hi there!")
    sleep(1.5)
    safe_print("I'm the wizard of ESPHome :)")
    sleep(1.25)
    safe_print("And I'm here to help you get started with ESPHome.")
    sleep(2.0)
    safe_print(
        "In 4 steps I'm going to guide you through creating a basic "
        "configuration file for your custom ESP8266/ESP32 firmware. Yay!")
    sleep(3.0)
    safe_print()
    safe_print_step(1, CORE_BIG)
    safe_print("First up, please choose a " + color('green', 'name') +
               " for your node.")
    safe_print(
        "It should be a unique name that can be used to identify the device later."
    )
    sleep(1)
    safe_print(
        "For example, I like calling the node in my living room {}.".format(
            color('bold_white', "livingroom")))
    safe_print()
    sleep(1)
    name = safe_input(color("bold_white", "(name): "))
    while True:
        try:
            name = cv.valid_name(name)
            break
        except vol.Invalid:
            safe_print(
                color(
                    "red",
                    u"Oh noes, \"{}\" isn't a valid name. Names can only include "
                    u"numbers, letters and underscores.".format(name)))
            name = strip_accents(name).replace(' ', '_')
            name = u''.join(c for c in name if c in cv.ALLOWED_NAME_CHARS)
            safe_print(u"Shall I use \"{}\" as the name instead?".format(
                color('cyan', name)))
            sleep(0.5)
            name = default_input(u"(name [{}]): ", name)

    safe_print(u"Great! Your node is now called \"{}\".".format(
        color('cyan', name)))
    sleep(1)
    safe_print_step(2, ESP_BIG)
    safe_print(
        "Now I'd like to know what microcontroller you're using so that I can compile "
        "firmwares for it.")
    safe_print("Are you using an " + color('green', 'ESP32') + " or " +
               color('green', 'ESP8266') +
               " platform? (Choose ESP8266 for Sonoff devices)")
    while True:
        sleep(0.5)
        safe_print()
        safe_print("Please enter either ESP32 or ESP8266.")
        platform = safe_input(color("bold_white", "(ESP32/ESP8266): "))
        try:
            platform = vol.All(vol.Upper, vol.Any('ESP32',
                                                  'ESP8266'))(platform)
            break
        except vol.Invalid:
            safe_print(
                u"Unfortunately, I can't find an espressif microcontroller called "
                u"\"{}\". Please try again.".format(platform))
    safe_print(u"Thanks! You've chosen {} as your platform.".format(
        color('cyan', platform)))
    safe_print()
    sleep(1)

    if platform == 'ESP32':
        board_link = 'http://docs.platformio.org/en/latest/platforms/espressif32.html#boards'
    else:
        board_link = 'http://docs.platformio.org/en/latest/platforms/espressif8266.html#boards'

    safe_print("Next, I need to know what " + color('green', 'board') +
               " you're using.")
    sleep(0.5)
    safe_print("Please go to {} and choose a board.".format(
        color('green', board_link)))
    if platform == 'ESP32':
        safe_print("(Type " + color('green', 'esp01_1m') +
                   " for Sonoff devices)")
    safe_print()
    # Don't sleep because user needs to copy link
    if platform == 'ESP32':
        safe_print("For example \"{}\".".format(
            color("bold_white", 'nodemcu-32s')))
        boards = list(ESP32_BOARD_PINS.keys())
    else:
        safe_print("For example \"{}\".".format(
            color("bold_white", 'nodemcuv2')))
        boards = list(ESP8266_BOARD_PINS.keys())
    safe_print("Options: {}".format(', '.join(boards)))

    while True:
        board = safe_input(color("bold_white", "(board): "))
        try:
            board = vol.All(vol.Lower, vol.Any(*boards))(board)
            break
        except vol.Invalid:
            safe_print(
                color('red', "Sorry, I don't think the board \"{}\" exists."))
            safe_print()
            sleep(0.25)
            safe_print()

    safe_print(u"Way to go! You've chosen {} as your board.".format(
        color('cyan', board)))
    safe_print()
    sleep(1)

    safe_print_step(3, WIFI_BIG)
    safe_print("In this step, I'm going to create the configuration for "
               "WiFi.")
    safe_print()
    sleep(1)
    safe_print("First, what's the " + color('green', 'SSID') +
               u" (the name) of the WiFi network {} I should connect to?".
               format(name))
    sleep(1.5)
    safe_print("For example \"{}\".".format(
        color('bold_white', "Abraham Linksys")))
    while True:
        ssid = safe_input(color('bold_white', "(ssid): "))
        try:
            ssid = cv.ssid(ssid)
            break
        except vol.Invalid:
            safe_print(
                color(
                    'red',
                    u"Unfortunately, \"{}\" doesn't seem to be a valid SSID. "
                    u"Please try again.".format(ssid)))
            safe_print()
            sleep(1)

    safe_print(u"Thank you very much! You've just chosen \"{}\" as your SSID."
               u"".format(color('cyan', ssid)))
    safe_print()
    sleep(0.75)

    safe_print(
        "Now please state the " + color('green', 'password') +
        " of the WiFi network so that I can connect to it (Leave empty for no password)"
    )
    safe_print()
    safe_print("For example \"{}\"".format(color('bold_white', 'PASSWORD42')))
    sleep(0.5)
    psk = safe_input(color('bold_white', '(PSK): '))
    safe_print(
        "Perfect! WiFi is now set up (you can create static IPs and so on later)."
    )
    sleep(1.5)

    safe_print_step(4, OTA_BIG)
    safe_print(
        "Almost there! ESPHome can automatically upload custom firmwares over WiFi "
        "(over the air) and integrates into Home Assistant with a native API.")
    safe_print(
        "This can be insecure if you do not trust the WiFi network. Do you want to set "
        "a " + color('green', 'password') + " for connecting to this ESP?")
    safe_print()
    sleep(0.25)
    safe_print("Press ENTER for no password")
    password = safe_input(color('bold_white', '(password): '))

    wizard_write(path=path,
                 name=name,
                 platform=platform,
                 board=board,
                 ssid=ssid,
                 psk=psk,
                 password=password)

    safe_print()
    safe_print(
        color('cyan', "DONE! I've now written a new configuration file to ") +
        color('bold_cyan', path))
    safe_print()
    safe_print("Next steps:")
    safe_print(
        "  > Check your Home Assistant \"integrations\" screen. If all goes well, you "
        "should see your ESP being discovered automatically.")
    safe_print("  > Then follow the rest of the getting started guide:")
    safe_print(
        "  > https://esphome.io/guides/getting_started_command_line.html")
    return 0
示例#8
0
def default_input(text, default):
    safe_print()
    safe_print(u"Press ENTER for default ({})".format(default))
    return safe_input(text.format(default)) or default