mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	Add MQTT publish JSON action and subscribe JSON trigger (#193)
* Add MQTT publish JSON action and subscribe JSON trigger * Lint
This commit is contained in:
		| @@ -16,6 +16,7 @@ from esphomeyaml.core import ESPHomeYAMLError | ||||
| from esphomeyaml.helpers import AssignmentExpression, Expression, RawStatement, \ | ||||
|     _EXPRESSIONS, add, \ | ||||
|     add_job, color, flush_tasks, indent, quote, statement, relative_path | ||||
| from esphomeyaml.util import safe_print | ||||
|  | ||||
| _LOGGER = logging.getLogger(__name__) | ||||
|  | ||||
| @@ -39,11 +40,11 @@ def choose_serial_port(config): | ||||
|  | ||||
|     if not result: | ||||
|         return 'OTA' | ||||
|     print(u"Found multiple serial port options, please choose one:") | ||||
|     safe_print(u"Found multiple serial port options, please choose one:") | ||||
|     for i, (res, desc) in enumerate(result): | ||||
|         print(u"  [{}] {} ({})".format(i, res, desc)) | ||||
|     print(u"  [{}] Over The Air ({})".format(len(result), get_upload_host(config))) | ||||
|     print() | ||||
|         safe_print(u"  [{}] {} ({})".format(i, res, desc)) | ||||
|     safe_print(u"  [{}] Over The Air ({})".format(len(result), get_upload_host(config))) | ||||
|     safe_print() | ||||
|     while True: | ||||
|         opt = raw_input('(number): ') | ||||
|         if opt in result: | ||||
| @@ -55,7 +56,7 @@ def choose_serial_port(config): | ||||
|                 raise ValueError | ||||
|             break | ||||
|         except ValueError: | ||||
|             print(color('red', u"Invalid option: '{}'".format(opt))) | ||||
|             safe_print(color('red', u"Invalid option: '{}'".format(opt))) | ||||
|     if opt == len(result): | ||||
|         return 'OTA' | ||||
|     return result[opt][0] | ||||
| @@ -111,10 +112,7 @@ def run_miniterm(config, port, escape=False): | ||||
|             message = time + line | ||||
|             if escape: | ||||
|                 message = message.replace('\033', '\\033') | ||||
|             try: | ||||
|                 print(message) | ||||
|             except UnicodeEncodeError: | ||||
|                 print(message.encode('ascii', 'backslashreplace')) | ||||
|             safe_print(message) | ||||
|  | ||||
|  | ||||
| def write_cpp(config): | ||||
| @@ -295,7 +293,7 @@ def strip_default_ids(config): | ||||
| def command_config(args, config): | ||||
|     if not args.verbose: | ||||
|         config = strip_default_ids(config) | ||||
|     print(yaml_util.dump(config)) | ||||
|     safe_print(yaml_util.dump(config)) | ||||
|     return 0 | ||||
|  | ||||
|  | ||||
| @@ -354,7 +352,7 @@ def command_mqtt_fingerprint(args, config): | ||||
|  | ||||
|  | ||||
| def command_version(args): | ||||
|     print(u"Version: {}".format(const.__version__)) | ||||
|     safe_print(u"Version: {}".format(const.__version__)) | ||||
|     return 0 | ||||
|  | ||||
|  | ||||
| @@ -496,7 +494,7 @@ def run_esphomeyaml(argv): | ||||
|         except ESPHomeYAMLError as e: | ||||
|             _LOGGER.error(e) | ||||
|             return 1 | ||||
|     print(u"Unknown command {}".format(args.command)) | ||||
|     safe_print(u"Unknown command {}".format(args.command)) | ||||
|     return 1 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -10,10 +10,10 @@ from esphomeyaml.const import CONF_BIRTH_MESSAGE, CONF_BROKER, CONF_CLIENT_ID, C | ||||
|     CONF_DISCOVERY_PREFIX, CONF_DISCOVERY_RETAIN, CONF_ID, CONF_KEEPALIVE, CONF_LEVEL, \ | ||||
|     CONF_LOG_TOPIC, CONF_ON_MESSAGE, CONF_PASSWORD, CONF_PAYLOAD, CONF_PORT, CONF_QOS, \ | ||||
|     CONF_REBOOT_TIMEOUT, CONF_RETAIN, CONF_SHUTDOWN_MESSAGE, CONF_SSL_FINGERPRINTS, CONF_TOPIC, \ | ||||
|     CONF_TOPIC_PREFIX, CONF_TRIGGER_ID, CONF_USERNAME, CONF_WILL_MESSAGE | ||||
|     CONF_TOPIC_PREFIX, CONF_TRIGGER_ID, CONF_USERNAME, CONF_WILL_MESSAGE, CONF_ON_JSON_MESSAGE | ||||
| from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, RawExpression, \ | ||||
|     StructInitializer, TemplateArguments, add, esphomelib_ns, optional, std_string, templatable, \ | ||||
|     uint8, bool_ | ||||
|     uint8, bool_, JsonObjectRef, process_lambda, JsonObjectConstRef | ||||
|  | ||||
|  | ||||
| def validate_message_just_topic(value): | ||||
| @@ -37,7 +37,9 @@ mqtt_ns = esphomelib_ns.namespace('mqtt') | ||||
| MQTTMessage = mqtt_ns.MQTTMessage | ||||
| MQTTClientComponent = mqtt_ns.MQTTClientComponent | ||||
| MQTTPublishAction = mqtt_ns.MQTTPublishAction | ||||
| MQTTPublishJsonAction = mqtt_ns.MQTTPublishJsonAction | ||||
| MQTTMessageTrigger = mqtt_ns.MQTTMessageTrigger | ||||
| MQTTJsonMessageTrigger = mqtt_ns.MQTTJsonMessageTrigger | ||||
|  | ||||
|  | ||||
| def validate_broker(value): | ||||
| @@ -79,9 +81,14 @@ CONFIG_SCHEMA = vol.Schema({ | ||||
|     vol.Optional(CONF_REBOOT_TIMEOUT): cv.positive_time_period_milliseconds, | ||||
|     vol.Optional(CONF_ON_MESSAGE): vol.All(cv.ensure_list, [automation.validate_automation({ | ||||
|         cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(MQTTMessageTrigger), | ||||
|         vol.Required(CONF_TOPIC): cv.publish_topic, | ||||
|         vol.Required(CONF_TOPIC): cv.subscribe_topic, | ||||
|         vol.Optional(CONF_QOS, default=0): cv.mqtt_qos, | ||||
|     })]) | ||||
|     })]), | ||||
|     vol.Optional(CONF_ON_JSON_MESSAGE): vol.All(cv.ensure_list, [automation.validate_automation({ | ||||
|         cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(MQTTJsonMessageTrigger), | ||||
|         vol.Required(CONF_TOPIC): cv.subscribe_topic, | ||||
|         vol.Optional(CONF_QOS, default=0): cv.mqtt_qos, | ||||
|     })]), | ||||
| }) | ||||
|  | ||||
|  | ||||
| @@ -160,6 +167,11 @@ def to_code(config): | ||||
|         trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs) | ||||
|         automation.build_automation(trigger, std_string, conf) | ||||
|  | ||||
|     for conf in config.get(CONF_ON_JSON_MESSAGE, []): | ||||
|         rhs = mqtt.make_json_message_trigger(conf[CONF_TOPIC], conf[CONF_QOS]) | ||||
|         trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs) | ||||
|         automation.build_automation(trigger, JsonObjectConstRef, conf) | ||||
|  | ||||
|  | ||||
| CONF_MQTT_PUBLISH = 'mqtt.publish' | ||||
| MQTT_PUBLISH_ACTION_SCHEMA = vol.Schema({ | ||||
| @@ -194,6 +206,35 @@ def mqtt_publish_action_to_code(config, action_id, arg_type): | ||||
|     yield action | ||||
|  | ||||
|  | ||||
| CONF_MQTT_PUBLISH_JSON = 'mqtt.publish_json' | ||||
| MQTT_PUBLISH_JSON_ACTION_SCHEMA = vol.Schema({ | ||||
|     vol.Required(CONF_TOPIC): cv.templatable(cv.publish_topic), | ||||
|     vol.Required(CONF_PAYLOAD): cv.lambda_, | ||||
|     vol.Optional(CONF_QOS): cv.mqtt_qos, | ||||
|     vol.Optional(CONF_RETAIN): cv.boolean, | ||||
| }) | ||||
|  | ||||
|  | ||||
| @ACTION_REGISTRY.register(CONF_MQTT_PUBLISH_JSON, MQTT_PUBLISH_JSON_ACTION_SCHEMA) | ||||
| def mqtt_publish_json_action_to_code(config, action_id, arg_type): | ||||
|     template_arg = TemplateArguments(arg_type) | ||||
|     rhs = App.Pget_mqtt_client().Pmake_publish_json_action(template_arg) | ||||
|     type = MQTTPublishJsonAction.template(template_arg) | ||||
|     action = Pvariable(action_id, rhs, type=type) | ||||
|     for template_ in templatable(config[CONF_TOPIC], arg_type, std_string): | ||||
|         yield None | ||||
|     add(action.set_topic(template_)) | ||||
|  | ||||
|     for lambda_ in process_lambda(config[CONF_PAYLOAD], [(arg_type, 'x'), (JsonObjectRef, 'root')]): | ||||
|         yield None | ||||
|     add(action.set_payload(lambda_)) | ||||
|     if CONF_QOS in config: | ||||
|         add(action.set_qos(config[CONF_QOS])) | ||||
|     if CONF_RETAIN in config: | ||||
|         add(action.set_retain(config[CONF_RETAIN])) | ||||
|     yield action | ||||
|  | ||||
|  | ||||
| def required_build_flags(config): | ||||
|     if CONF_SSL_FINGERPRINTS in config: | ||||
|         return '-DASYNC_TCP_SSL_ENABLED=1' | ||||
|   | ||||
| @@ -11,6 +11,7 @@ from esphomeyaml import core, yaml_util, core_config | ||||
| from esphomeyaml.const import CONF_ESPHOMEYAML, CONF_PLATFORM, CONF_WIFI, ESP_PLATFORMS | ||||
| from esphomeyaml.core import ESPHomeYAMLError | ||||
| from esphomeyaml.helpers import color | ||||
| from esphomeyaml.util import safe_print | ||||
|  | ||||
| _LOGGER = logging.getLogger(__name__) | ||||
|  | ||||
| @@ -306,17 +307,17 @@ def dump_dict(layer, indent_count=3, listi=False, **kwargs): | ||||
|     if isinstance(layer, dict): | ||||
|         for key, value in sorted(layer.items(), key=sort_dict_key): | ||||
|             if isinstance(value, (dict, list)): | ||||
|                 print(indent_str, key + ':', line_info(value, **kwargs)) | ||||
|                 safe_print(u"{} {}: {}".format(indent_str, key, line_info(value, **kwargs))) | ||||
|                 dump_dict(value, indent_count + 2) | ||||
|             else: | ||||
|                 print(indent_str, key + ':', value) | ||||
|                 safe_print(u"{} {}: {}".format(indent_str, key, value)) | ||||
|             indent_str = indent_count * ' ' | ||||
|     if isinstance(layer, (list, tuple)): | ||||
|         for i in layer: | ||||
|             if isinstance(i, dict): | ||||
|                 dump_dict(i, indent_count + 2, True) | ||||
|             else: | ||||
|                 print(' ', indent_str, i) | ||||
|                 safe_print(u" {} {}".format(indent_str, i)) | ||||
|  | ||||
|  | ||||
| def read_config(path): | ||||
| @@ -334,10 +335,11 @@ def read_config(path): | ||||
|             excepts[domain].append(config) | ||||
|  | ||||
|     if excepts: | ||||
|         print(color('bold_white', u"Failed config")) | ||||
|         safe_print(color('bold_white', u"Failed config")) | ||||
|         for domain, config in excepts.iteritems(): | ||||
|             print(' ', color('bold_red', domain + ':'), color('red', '', reset='red')) | ||||
|             safe_print(u' {} {}'.format(color('bold_red', domain + u':'), | ||||
|                                         color('red', '', reset='red'))) | ||||
|             dump_dict(config, reset='red') | ||||
|             print(color('reset')) | ||||
|             safe_print(color('reset')) | ||||
|         return None | ||||
|     return OrderedDict(res) | ||||
|   | ||||
| @@ -342,6 +342,7 @@ CONF_CRON = 'cron' | ||||
| CONF_POWER_SAVE_MODE = 'power_save_mode' | ||||
| CONF_POWER_ON_VALUE = 'power_on_value' | ||||
| CONF_ON_TAG = 'on_tag' | ||||
| CONF_ON_JSON_MESSAGE = 'on_json_message' | ||||
|  | ||||
| ALLOWED_NAME_CHARS = u'abcdefghijklmnopqrstuvwxyz0123456789_' | ||||
| ARDUINO_VERSION_ESP32_DEV = 'https://github.com/platformio/platform-espressif32.git#feature/stage' | ||||
|   | ||||
| @@ -536,6 +536,10 @@ class MockObj(Expression): | ||||
|             obj = MockObj(u'{} &'.format(self.base), u'') | ||||
|             obj.requires.append(self) | ||||
|             return obj | ||||
|         if name == "const": | ||||
|             obj = MockObj(u'const {}'.format(self.base), u'') | ||||
|             obj.requires.append(self) | ||||
|             return obj | ||||
|         raise NotImplementedError() | ||||
|  | ||||
|     def has_side_effects(self): | ||||
| @@ -568,6 +572,10 @@ NoArg = esphomelib_ns.NoArg | ||||
| App = esphomelib_ns.App | ||||
| Application = esphomelib_ns.namespace('Application') | ||||
| optional = esphomelib_ns.optional | ||||
| arduino_json_ns = global_ns.namespace('ArduinoJson') | ||||
| JsonObject = arduino_json_ns.JsonObject | ||||
| JsonObjectRef = JsonObject.operator('ref') | ||||
| JsonObjectConstRef = JsonObjectRef.operator('const') | ||||
|  | ||||
| GPIOPin = esphomelib_ns.GPIOPin | ||||
| GPIOOutputPin = esphomelib_ns.GPIOOutputPin | ||||
|   | ||||
| @@ -14,6 +14,7 @@ from esphomeyaml.const import CONF_BROKER, CONF_DISCOVERY_PREFIX, CONF_ESPHOMEYA | ||||
|     CONF_MQTT, CONF_NAME, CONF_PASSWORD, CONF_PORT, CONF_TOPIC_PREFIX, \ | ||||
|     CONF_USERNAME, CONF_TOPIC, CONF_SSL_FINGERPRINTS | ||||
| from esphomeyaml.helpers import color | ||||
| from esphomeyaml.util import safe_print | ||||
|  | ||||
| _LOGGER = logging.getLogger(__name__) | ||||
|  | ||||
| @@ -70,10 +71,7 @@ def show_logs(config, topic=None, username=None, password=None, client_id=None, | ||||
|         message = time + msg.payload | ||||
|         if escape: | ||||
|             message = message.replace('\033', '\\033') | ||||
|         try: | ||||
|             print(message) | ||||
|         except UnicodeEncodeError: | ||||
|             print(message.encode('ascii', 'backslashreplace')) | ||||
|         safe_print(message) | ||||
|  | ||||
|     return initialize(config, [topic], on_message, username, password, client_id) | ||||
|  | ||||
| @@ -113,6 +111,7 @@ def get_fingerprint(config): | ||||
|  | ||||
|     sha1 = hashlib.sha1(cert_der).hexdigest() | ||||
|  | ||||
|     print(u"SHA1 Fingerprint: " + color('cyan', sha1)) | ||||
|     print(u"Copy above string into mqtt.ssl_fingerprints section of {}".format(core.CONFIG_PATH)) | ||||
|     safe_print(u"SHA1 Fingerprint: " + color('cyan', sha1)) | ||||
|     safe_print(u"Copy the string above into mqtt.ssl_fingerprints section of {}" | ||||
|                u"".format(core.CONFIG_PATH)) | ||||
|     return 0 | ||||
|   | ||||
| @@ -1,3 +1,6 @@ | ||||
| from __future__ import print_function | ||||
|  | ||||
|  | ||||
| class Registry(dict): | ||||
|     def register(self, name): | ||||
|         def decorator(fun): | ||||
| @@ -14,3 +17,16 @@ class ServiceRegistry(dict): | ||||
|             return fun | ||||
|  | ||||
|         return decorator | ||||
|  | ||||
|  | ||||
| def safe_print(message=""): | ||||
|     try: | ||||
|         print(message) | ||||
|         return | ||||
|     except UnicodeEncodeError: | ||||
|         pass | ||||
|  | ||||
|     try: | ||||
|         print(message.encode('ascii', 'backslashreplace')) | ||||
|     except UnicodeEncodeError: | ||||
|         print("Cannot print line because of invalid locale!") | ||||
|   | ||||
| @@ -6,14 +6,13 @@ import unicodedata | ||||
|  | ||||
| import voluptuous as vol | ||||
|  | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml.components import mqtt | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml.const import ESP_PLATFORMS, ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266 | ||||
| from esphomeyaml.helpers import color | ||||
|  | ||||
|  | ||||
| # pylint: disable=anomalous-backslash-in-string | ||||
| from esphomeyaml.pins import ESP32_BOARD_PINS, ESP8266_BOARD_PINS | ||||
| from esphomeyaml.util import safe_print | ||||
|  | ||||
| CORE_BIG = """    _____ ____  _____  ______ | ||||
|    / ____/ __ \|  __ \|  ____| | ||||
| @@ -52,7 +51,7 @@ OTA_BIG = """       ____ _______ | ||||
| """ | ||||
|  | ||||
| # TODO handle escaping | ||||
| BASE_CONFIG = """esphomeyaml: | ||||
| BASE_CONFIG = u"""esphomeyaml: | ||||
|   name: {name} | ||||
|   platform: {platform} | ||||
|   board: {board} | ||||
| @@ -76,9 +75,9 @@ def wizard_file(**kwargs): | ||||
|     config = BASE_CONFIG.format(**kwargs) | ||||
|  | ||||
|     if kwargs['ota_password']: | ||||
|         config += "ota:\n  password: '{}'\n".format(kwargs['ota_password']) | ||||
|         config += u"ota:\n  password: '{}'\n".format(kwargs['ota_password']) | ||||
|     else: | ||||
|         config += "ota:\n" | ||||
|         config += u"ota:\n" | ||||
|  | ||||
|     return config | ||||
|  | ||||
| @@ -90,18 +89,18 @@ else: | ||||
|     from time import sleep | ||||
|  | ||||
|  | ||||
| def print_step(step, big): | ||||
|     print() | ||||
|     print() | ||||
|     print("============= STEP {} =============".format(step)) | ||||
|     print(big) | ||||
|     print("===================================") | ||||
| def safe_print_step(step, big): | ||||
|     safe_print() | ||||
|     safe_print() | ||||
|     safe_print("============= STEP {} =============".format(step)) | ||||
|     safe_print(big) | ||||
|     safe_print("===================================") | ||||
|     sleep(0.25) | ||||
|  | ||||
|  | ||||
| def default_input(text, default): | ||||
|     print() | ||||
|     print("Press ENTER for default ({})".format(default)) | ||||
|     safe_print() | ||||
|     safe_print(u"Press ENTER for default ({})".format(default)) | ||||
|     return raw_input(text.format(default)) or default | ||||
|  | ||||
|  | ||||
| @@ -113,30 +112,30 @@ def strip_accents(string): | ||||
|  | ||||
| def wizard(path): | ||||
|     if not path.endswith('.yaml') and not path.endswith('.yml'): | ||||
|         print("Please make your configuration file {} have the extension .yaml or .yml".format( | ||||
|             color('cyan', path))) | ||||
|         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): | ||||
|         print("Uh oh, it seems like {} already exists, please delete that file first " | ||||
|               "or chose another configuration file.".format(color('cyan', 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 | ||||
|     print("Hi there!") | ||||
|     safe_print("Hi there!") | ||||
|     sleep(1.5) | ||||
|     print("I'm the wizard of esphomeyaml :)") | ||||
|     safe_print("I'm the wizard of esphomeyaml :)") | ||||
|     sleep(1.25) | ||||
|     print("And I'm here to help you get started with esphomeyaml.") | ||||
|     safe_print("And I'm here to help you get started with esphomeyaml.") | ||||
|     sleep(2.0) | ||||
|     print("In 5 steps I'm going to guide you through creating a basic " | ||||
|           "configuration file for your custom ESP8266/ESP32 firmware. Yay!") | ||||
|     safe_print("In 5 steps I'm going to guide you through creating a basic " | ||||
|                "configuration file for your custom ESP8266/ESP32 firmware. Yay!") | ||||
|     sleep(3.0) | ||||
|     print() | ||||
|     print_step(1, CORE_BIG) | ||||
|     print("First up, please choose a " + color('green', 'name') + " for your node.") | ||||
|     print("It should be a unique name that can be used to identify the device later.") | ||||
|     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) | ||||
|     print("For example, I like calling the node in my living room {}.".format( | ||||
|     safe_print("For example, I like calling the node in my living room {}.".format( | ||||
|         color('bold_white', "livingroom"))) | ||||
|     print() | ||||
|     safe_print() | ||||
|     sleep(1) | ||||
|     name = raw_input(color("bold_white", "(name): ")) | ||||
|     while True: | ||||
| @@ -144,34 +143,34 @@ def wizard(path): | ||||
|             name = cv.valid_name(name) | ||||
|             break | ||||
|         except vol.Invalid: | ||||
|             print(color("red", "Oh noes, \"{}\" isn't a valid name. Names can only include " | ||||
|                                "numbers, letters and underscores.".format(name))) | ||||
|             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) | ||||
|             print("Shall I use \"{}\" as the name instead?".format(color('cyan', name))) | ||||
|             safe_print(u"Shall I use \"{}\" as the name instead?".format(color('cyan', name))) | ||||
|             sleep(0.5) | ||||
|             name = default_input("(name [{}]): ", name) | ||||
|             name = default_input(u"(name [{}]): ", name) | ||||
|  | ||||
|     print("Great! Your node is now called \"{}\".".format(color('cyan', name))) | ||||
|     safe_print(u"Great! Your node is now called \"{}\".".format(color('cyan', name))) | ||||
|     sleep(1) | ||||
|     print_step(2, ESP_BIG) | ||||
|     print("Now I'd like to know what microcontroller you're using so that I can compile " | ||||
|           "firmwares for it.") | ||||
|     print("Are you using an " + color('green', 'ESP32') + " or " + | ||||
|           color('green', 'ESP8266') + " platform? (Choose ESP8266 for Sonoff devices)") | ||||
|     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) | ||||
|         print() | ||||
|         print("Please enter either ESP32 or ESP8266.") | ||||
|         safe_print() | ||||
|         safe_print("Please enter either ESP32 or ESP8266.") | ||||
|         platform = raw_input(color("bold_white", "(ESP32/ESP8266): ")) | ||||
|         try: | ||||
|             platform = vol.All(vol.Upper, vol.Any(*ESP_PLATFORMS))(platform) | ||||
|             break | ||||
|         except vol.Invalid: | ||||
|             print("Unfortunately, I can't find an espressif microcontroller called " | ||||
|                   "\"{}\". Please try again.".format(platform)) | ||||
|     print("Thanks! You've chosen {} as your platform.".format(color('cyan', platform))) | ||||
|     print() | ||||
|             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 == ESP_PLATFORM_ESP32: | ||||
| @@ -179,18 +178,18 @@ def wizard(path): | ||||
|     else: | ||||
|         board_link = 'http://docs.platformio.org/en/latest/platforms/espressif8266.html#boards' | ||||
|  | ||||
|     print("Next, I need to know what " + color('green', 'board') + " you're using.") | ||||
|     safe_print("Next, I need to know what " + color('green', 'board') + " you're using.") | ||||
|     sleep(0.5) | ||||
|     print("Please go to {} and choose a board.".format(color('green', board_link))) | ||||
|     safe_print("Please go to {} and choose a board.".format(color('green', board_link))) | ||||
|     if platform == ESP_PLATFORM_ESP8266: | ||||
|         print("(Type " + color('green', 'esp01_1m') + " for Sonoff devices)") | ||||
|     print() | ||||
|         safe_print("(Type " + color('green', 'esp01_1m') + " for Sonoff devices)") | ||||
|     safe_print() | ||||
|     # Don't sleep because user needs to copy link | ||||
|     if platform == ESP_PLATFORM_ESP32: | ||||
|         print("For example \"{}\".".format(color("bold_white", 'nodemcu-32s'))) | ||||
|         safe_print("For example \"{}\".".format(color("bold_white", 'nodemcu-32s'))) | ||||
|         boards = list(ESP32_BOARD_PINS.keys()) | ||||
|     else: | ||||
|         print("For example \"{}\".".format(color("bold_white", 'nodemcuv2'))) | ||||
|         safe_print("For example \"{}\".".format(color("bold_white", 'nodemcuv2'))) | ||||
|         boards = list(ESP8266_BOARD_PINS.keys()) | ||||
|     while True: | ||||
|         board = raw_input(color("bold_white", "(board): ")) | ||||
| @@ -198,71 +197,73 @@ def wizard(path): | ||||
|             board = vol.All(vol.Lower, vol.Any(*boards))(board) | ||||
|             break | ||||
|         except vol.Invalid: | ||||
|             print(color('red', "Sorry, I don't think the board \"{}\" exists.")) | ||||
|             print() | ||||
|             safe_print(color('red', "Sorry, I don't think the board \"{}\" exists.")) | ||||
|             safe_print() | ||||
|             sleep(0.25) | ||||
|             print("Possible options are {}".format(', '.join(boards))) | ||||
|             print() | ||||
|             safe_print("Possible options are {}".format(', '.join(boards))) | ||||
|             safe_print() | ||||
|  | ||||
|     print("Way to go! You've chosen {} as your board.".format(color('cyan', board))) | ||||
|     print() | ||||
|     safe_print(u"Way to go! You've chosen {} as your board.".format(color('cyan', board))) | ||||
|     safe_print() | ||||
|     sleep(1) | ||||
|  | ||||
|     print_step(3, WIFI_BIG) | ||||
|     print("In this step, I'm going to create the configuration for " | ||||
|           "WiFi.") | ||||
|     print() | ||||
|     safe_print_step(3, WIFI_BIG) | ||||
|     safe_print("In this step, I'm going to create the configuration for " | ||||
|                "WiFi.") | ||||
|     safe_print() | ||||
|     sleep(1) | ||||
|     print("First, what's the " + color('green', 'SSID') + " (the name) of the WiFi network {} " | ||||
|                                                           "I should connect to?".format(name)) | ||||
|     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) | ||||
|     print("For example \"{}\".".format(color('bold_white', "Abraham Linksys"))) | ||||
|     safe_print("For example \"{}\".".format(color('bold_white', "Abraham Linksys"))) | ||||
|     while True: | ||||
|         ssid = raw_input(color('bold_white', "(ssid): ")) | ||||
|         try: | ||||
|             ssid = cv.ssid(ssid) | ||||
|             break | ||||
|         except vol.Invalid: | ||||
|             print(color('red', "Unfortunately, \"{}\" doesn't seem to be a valid SSID. " | ||||
|                                "Please try again.".format(ssid))) | ||||
|             print() | ||||
|             safe_print(color('red', u"Unfortunately, \"{}\" doesn't seem to be a valid SSID. " | ||||
|                                     u"Please try again.".format(ssid))) | ||||
|             safe_print() | ||||
|             sleep(1) | ||||
|  | ||||
|     print("Thank you very much! You've just chosen \"{}\" as your SSID.".format( | ||||
|         color('cyan', ssid))) | ||||
|     print() | ||||
|     safe_print(u"Thank you very much! You've just chosen \"{}\" as your SSID." | ||||
|                u"".format(color('cyan', ssid))) | ||||
|     safe_print() | ||||
|     sleep(0.75) | ||||
|  | ||||
|     print("Now please state the " + color('green', 'password') + | ||||
|           " of the WiFi network so that I can connect to it (Leave empty for no password)") | ||||
|     print() | ||||
|     print("For example \"{}\"".format(color('bold_white', 'PASSWORD42'))) | ||||
|     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 = raw_input(color('bold_white', '(PSK): ')) | ||||
|     print("Perfect! WiFi is now set up (you can create static IPs and so on later).") | ||||
|     safe_print("Perfect! WiFi is now set up (you can create static IPs and so on later).") | ||||
|     sleep(1.5) | ||||
|  | ||||
|     print_step(4, MQTT_BIG) | ||||
|     print("Almost there! Now let's setup MQTT so that your node can connect to the outside world.") | ||||
|     print() | ||||
|     safe_print_step(4, MQTT_BIG) | ||||
|     safe_print("Almost there! Now let's setup MQTT so that your node can connect to the " | ||||
|                "outside world.") | ||||
|     safe_print() | ||||
|     sleep(1) | ||||
|     print("Please enter the " + color('green', 'address') + " of your MQTT broker.") | ||||
|     print() | ||||
|     print("For example \"{}\".".format(color('bold_white', '192.168.178.84'))) | ||||
|     safe_print("Please enter the " + color('green', 'address') + " of your MQTT broker.") | ||||
|     safe_print() | ||||
|     safe_print("For example \"{}\".".format(color('bold_white', '192.168.178.84'))) | ||||
|     while True: | ||||
|         broker = raw_input(color('bold_white', "(broker): ")) | ||||
|         try: | ||||
|             broker = mqtt.validate_broker(broker) | ||||
|             break | ||||
|         except vol.Invalid as err: | ||||
|             print(color('red', "The broker address \"{}\" seems to be invalid: {} :(".format( | ||||
|                 broker, err))) | ||||
|             print("Please try again.") | ||||
|             print() | ||||
|             safe_print(color('red', u"The broker address \"{}\" seems to be invalid: {} :(" | ||||
|                                     u"".format(broker, err))) | ||||
|             safe_print("Please try again.") | ||||
|             safe_print() | ||||
|             sleep(1) | ||||
|  | ||||
|     print("Thanks! Now enter the " + color('green', 'username') + " and " + | ||||
|           color('green', 'password') + " for the MQTT broker. Leave empty for no authentication.") | ||||
|     safe_print("Thanks! Now enter the " + color('green', 'username') + " and " + | ||||
|                color('green', 'password') + | ||||
|                " for the MQTT broker. Leave empty for no authentication.") | ||||
|     mqtt_username = raw_input(color('bold_white', '(username): ')) | ||||
|     mqtt_password = '' | ||||
|     if mqtt_username: | ||||
| @@ -271,19 +272,19 @@ def wizard(path): | ||||
|         show = '*' * len(mqtt_password) | ||||
|         if len(mqtt_password) >= 2: | ||||
|             show = mqtt_password[:2] + '*' * len(mqtt_password) | ||||
|         print("MQTT Username: \"{}\"; Password: \"{}\"".format( | ||||
|             color('cyan', mqtt_username), color('cyan', show))) | ||||
|         safe_print(u"MQTT Username: \"{}\"; Password: \"{}\"" | ||||
|                    u"".format(color('cyan', mqtt_username), color('cyan', show))) | ||||
|     else: | ||||
|         print("No authentication for MQTT") | ||||
|         safe_print("No authentication for MQTT") | ||||
|  | ||||
|     print_step(5, OTA_BIG) | ||||
|     print("Last step! esphomeyaml can automatically upload custom firmwares over WiFi " | ||||
|           "(over the air).") | ||||
|     print("This can be insecure if you do not trust the WiFi network. Do you want to set " | ||||
|           "an " + color('green', 'OTA password') + " for remote updates?") | ||||
|     print() | ||||
|     safe_print_step(5, OTA_BIG) | ||||
|     safe_print("Last step! esphomeyaml can automatically upload custom firmwares over WiFi " | ||||
|                "(over the air).") | ||||
|     safe_print("This can be insecure if you do not trust the WiFi network. Do you want to set " | ||||
|                "an " + color('green', 'OTA password') + " for remote updates?") | ||||
|     safe_print() | ||||
|     sleep(0.25) | ||||
|     print("Press ENTER for no password") | ||||
|     safe_print("Press ENTER for no password") | ||||
|     ota_password = raw_input(color('bold_white', '(password): ')) | ||||
|  | ||||
|     config = wizard_file(name=name, platform=platform, board=board, | ||||
| @@ -294,19 +295,19 @@ def wizard(path): | ||||
|     with codecs.open(path, 'w') as f_handle: | ||||
|         f_handle.write(config) | ||||
|  | ||||
|     print() | ||||
|     print(color('cyan', "DONE! I've now written a new configuration file to ") + | ||||
|           color('bold_cyan', path)) | ||||
|     print() | ||||
|     print("Next steps:") | ||||
|     print("  > If you haven't already, enable MQTT discovery in Home Assistant:") | ||||
|     print() | ||||
|     print(color('bold_white', "# In your configuration.yaml")) | ||||
|     print(color('bold_white', "mqtt:")) | ||||
|     print(color('bold_white', "  broker: {}".format(broker))) | ||||
|     print(color('bold_white', "  # ...")) | ||||
|     print(color('bold_white', "  discovery: True")) | ||||
|     print() | ||||
|     print("  > Then follow the rest of the getting started guide:") | ||||
|     print("  > https://esphomelib.com/esphomeyaml/guides/getting_started_command_line.html") | ||||
|     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("  > If you haven't already, enable MQTT discovery in Home Assistant:") | ||||
|     safe_print() | ||||
|     safe_print(color('bold_white', "# In your configuration.yaml")) | ||||
|     safe_print(color('bold_white', "mqtt:")) | ||||
|     safe_print(color('bold_white', u"  broker: {}".format(broker))) | ||||
|     safe_print(color('bold_white', "  # ...")) | ||||
|     safe_print(color('bold_white', "  discovery: True")) | ||||
|     safe_print() | ||||
|     safe_print("  > Then follow the rest of the getting started guide:") | ||||
|     safe_print("  > https://esphomelib.com/esphomeyaml/guides/getting_started_command_line.html") | ||||
|     return 0 | ||||
|   | ||||
| @@ -102,6 +102,7 @@ def get_ini_content(config, path): | ||||
|         build_flags |= get_build_flags(config, 'build_flags') | ||||
|         build_flags |= get_build_flags(config, 'BUILD_FLAGS') | ||||
|         build_flags.add(u"-DESPHOMEYAML_USE") | ||||
|         build_flags.add("-Wno-unused-variable") | ||||
|     build_flags |= get_build_flags(config, 'required_build_flags') | ||||
|     build_flags |= get_build_flags(config, 'REQUIRED_BUILD_FLAGS') | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user