mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 15:12:06 +00:00 
			
		
		
		
	Add logger.log action (#198)
* Add logger.log Action * Simple schema * Validate printf * Improve error message * Undo unfix tests :)
This commit is contained in:
		| @@ -86,9 +86,12 @@ def validate_automation(extra_schema=None, extra_validators=None, single=False): | ||||
|             try: | ||||
|                 # First try as a sequence of actions | ||||
|                 return [schema({CONF_THEN: value})] | ||||
|             except vol.Invalid: | ||||
|             except vol.Invalid as err: | ||||
|                 # Next try as a sequence of automations | ||||
|                 return vol.Schema([schema])(value) | ||||
|                 try: | ||||
|                     return vol.Schema([schema])(value) | ||||
|                 except vol.Invalid as err2: | ||||
|                     raise vol.MultipleInvalid([err, err2]) | ||||
|         elif isinstance(value, dict): | ||||
|             if CONF_THEN in value: | ||||
|                 return [schema(value)] | ||||
|   | ||||
| @@ -1,10 +1,14 @@ | ||||
| import re | ||||
|  | ||||
| import voluptuous as vol | ||||
|  | ||||
| from esphomeyaml.automation import ACTION_REGISTRY, LambdaAction | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml.const import CONF_BAUD_RATE, CONF_ID, CONF_LEVEL, CONF_LOGS, \ | ||||
|     CONF_TX_BUFFER_SIZE | ||||
| from esphomeyaml.core import ESPHomeYAMLError | ||||
| from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, global_ns | ||||
| from esphomeyaml.const import CONF_ARGS, CONF_BAUD_RATE, CONF_FORMAT, CONF_ID, CONF_LEVEL, \ | ||||
|     CONF_LOGS, CONF_TAG, CONF_TX_BUFFER_SIZE | ||||
| from esphomeyaml.core import ESPHomeYAMLError, Lambda | ||||
| from esphomeyaml.helpers import App, Pvariable, TemplateArguments, add, esphomelib_ns, global_ns, \ | ||||
|     process_lambda, RawExpression, statement | ||||
|  | ||||
| LOG_LEVELS = { | ||||
|     'NONE': global_ns.ESPHOMELIB_LOG_LEVEL_NONE, | ||||
| @@ -16,6 +20,15 @@ LOG_LEVELS = { | ||||
|     'VERY_VERBOSE': global_ns.ESPHOMELIB_LOG_LEVEL_VERY_VERBOSE, | ||||
| } | ||||
|  | ||||
| LOG_LEVEL_TO_ESP_LOG = { | ||||
|     'ERROR': global_ns.ESP_LOGE, | ||||
|     'WARN': global_ns.ESP_LOGW, | ||||
|     'INFO': global_ns.ESP_LOGI, | ||||
|     'DEBUG': global_ns.ESP_LOGD, | ||||
|     'VERBOSE': global_ns.ESP_LOGV, | ||||
|     'VERY_VERBOSE': global_ns.ESP_LOGVV, | ||||
| } | ||||
|  | ||||
| LOG_LEVEL_SEVERITY = ['NONE', 'ERROR', 'WARN', 'INFO', 'DEBUG', 'VERBOSE', 'VERY_VERBOSE'] | ||||
|  | ||||
| # pylint: disable=invalid-name | ||||
| @@ -59,3 +72,57 @@ def required_build_flags(config): | ||||
|     if CONF_LEVEL in config: | ||||
|         return u'-DESPHOMELIB_LOG_LEVEL={}'.format(str(LOG_LEVELS[config[CONF_LEVEL]])) | ||||
|     return None | ||||
|  | ||||
|  | ||||
| def maybe_simple_message(schema): | ||||
|     def validator(value): | ||||
|         if isinstance(value, dict): | ||||
|             return vol.Schema(schema)(value) | ||||
|         return vol.Schema(schema)({CONF_FORMAT: value}) | ||||
|     return validator | ||||
|  | ||||
|  | ||||
| def validate_printf(value): | ||||
|     # https://stackoverflow.com/questions/30011379/how-can-i-parse-a-c-format-string-in-python | ||||
|     # pylint: disable=anomalous-backslash-in-string | ||||
|     cfmt = u"""\ | ||||
|     (                                  # start of capture group 1 | ||||
|     %                                  # literal "%" | ||||
|     (?:                                # first option | ||||
|     (?:[-+0 #]{0,5})                   # optional flags | ||||
|     (?:\d+|\*)?                        # width | ||||
|     (?:\.(?:\d+|\*))?                  # precision | ||||
|     (?:h|l|ll|w|I|I32|I64)?            # size | ||||
|     [cCdiouxXeEfgGaAnpsSZ]             # type | ||||
|     ) |                                # OR | ||||
|     %%)                                # literal "%%" | ||||
|     """ | ||||
|     matches = re.findall(cfmt, value[CONF_FORMAT], flags=re.X) | ||||
|     if len(matches) != len(value[CONF_ARGS]): | ||||
|         raise vol.Invalid(u"Found {} printf-patterns ({}), but {} args were given!" | ||||
|                           u"".format(len(matches), u', '.join(matches), len(value[CONF_ARGS]))) | ||||
|     return value | ||||
|  | ||||
|  | ||||
| CONF_LOGGER_LOG = 'logger.log' | ||||
| LOGGER_LOG_ACTION_SCHEMA = vol.All(maybe_simple_message({ | ||||
|     vol.Required(CONF_FORMAT): cv.string, | ||||
|     vol.Optional(CONF_ARGS, default=list): vol.All(cv.ensure_list, [cv.lambda_]), | ||||
|     vol.Optional(CONF_LEVEL, default="DEBUG"): vol.All(vol.Upper, cv.one_of(*LOG_LEVEL_TO_ESP_LOG)), | ||||
|     vol.Optional(CONF_TAG, default="main"): cv.string, | ||||
| }), validate_printf) | ||||
|  | ||||
|  | ||||
| @ACTION_REGISTRY.register(CONF_LOGGER_LOG, LOGGER_LOG_ACTION_SCHEMA) | ||||
| def logger_log_action_to_code(config, action_id, arg_type): | ||||
|     template_arg = TemplateArguments(arg_type) | ||||
|     esp_log = LOG_LEVEL_TO_ESP_LOG[config[CONF_LEVEL]] | ||||
|     args = [RawExpression(unicode(x)) for x in config[CONF_ARGS]] | ||||
|  | ||||
|     text = unicode(statement(esp_log(config[CONF_TAG], config[CONF_FORMAT], *args))) | ||||
|  | ||||
|     for lambda_ in process_lambda(Lambda(text), [(arg_type, 'x')]): | ||||
|         yield None | ||||
|     rhs = LambdaAction.new(template_arg, lambda_) | ||||
|     type = LambdaAction.template(template_arg) | ||||
|     yield Pvariable(action_id, rhs, type=type) | ||||
|   | ||||
| @@ -346,6 +346,8 @@ CONF_PM_2_5 = 'pm_2_5' | ||||
| CONF_PM_10_0 = 'pm_10_0' | ||||
| CONF_FORMALDEHYDE = 'formaldehyde' | ||||
| CONF_ON_TAG = 'on_tag' | ||||
| CONF_ARGS = 'args' | ||||
| CONF_FORMAT = 'format' | ||||
| CONF_COLOR_CORRECT = 'color_correct' | ||||
| CONF_ON_JSON_MESSAGE = 'on_json_message' | ||||
|  | ||||
|   | ||||
| @@ -193,6 +193,11 @@ sensor: | ||||
|     on_raw_value: | ||||
|       - lambda: >- | ||||
|           ESP_LOGD("main", "Got raw value %f", x); | ||||
|       - logger.log: | ||||
|           level: DEBUG | ||||
|           format: "Got raw value %f" | ||||
|           args: ['x'] | ||||
|       - logger.log: "Got raw value NAN" | ||||
|       - mqtt.publish: | ||||
|           topic: some/topic | ||||
|           payload: Hello | ||||
|   | ||||
		Reference in New Issue
	
	Block a user