From d61a4fba63dd97ac7f6f12b0e5b54bc88909c8a7 Mon Sep 17 00:00:00 2001 From: Otto Winter Date: Mon, 12 Nov 2018 22:46:09 +0100 Subject: [PATCH] Global variables --- esphomeyaml/components/globals.py | 35 +++++++++++++++++++++++++++++++ esphomeyaml/const.py | 2 ++ esphomeyaml/helpers.py | 24 ++++++++++++++++++--- 3 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 esphomeyaml/components/globals.py diff --git a/esphomeyaml/components/globals.py b/esphomeyaml/components/globals.py new file mode 100644 index 0000000000..757822d749 --- /dev/null +++ b/esphomeyaml/components/globals.py @@ -0,0 +1,35 @@ +import voluptuous as vol + +from esphomeyaml import config_validation as cv +from esphomeyaml.const import CONF_ID, CONF_INITIAL_VALUE, CONF_RESTORE_VALUE, CONF_TYPE +from esphomeyaml.helpers import App, Component, Pvariable, RawExpression, TemplateArguments, add, \ + esphomelib_ns, setup_component + +GlobalVariableComponent = esphomelib_ns.class_('GlobalVariableComponent', Component) + +GLOBAL_VAR_SCHEMA = vol.Schema({ + vol.Required(CONF_ID): cv.declare_variable_id(GlobalVariableComponent), + vol.Required(CONF_TYPE): cv.string, + vol.Optional(CONF_INITIAL_VALUE): cv.string, + vol.Optional(CONF_RESTORE_VALUE): cv.boolean, +}).extend(cv.COMPONENT_SCHEMA.schema) + +CONFIG_SCHEMA = vol.All(cv.ensure_list, [GLOBAL_VAR_SCHEMA]) + + +def to_code(config): + for conf in config: + type_ = RawExpression(conf[CONF_TYPE]) + template_args = TemplateArguments(type_) + res_type = GlobalVariableComponent.template(template_args) + initial_value = None + if CONF_INITIAL_VALUE in conf: + initial_value = RawExpression(conf[CONF_INITIAL_VALUE]) + rhs = App.Pmake_global_variable(template_args, initial_value) + glob = Pvariable(conf[CONF_ID], rhs, type=res_type) + + if conf.get(CONF_RESTORE_VALUE, False): + hash_ = hash(conf[CONF_ID].id) % 2**32 + add(glob.set_restore_value(hash_)) + + setup_component(glob, conf) diff --git a/esphomeyaml/const.py b/esphomeyaml/const.py index abcce14696..0071b6c500 100644 --- a/esphomeyaml/const.py +++ b/esphomeyaml/const.py @@ -365,6 +365,8 @@ CONF_TIME_ID = 'time_id' CONF_RESTORE_STATE = 'restore_state' CONF_TIMING = 'timing' CONF_INVALID_COOLDOWN = 'invalid_cooldown' +CONF_INITIAL_VALUE = 'initial_value' +CONF_RESTORE_VALUE = 'restore_value' ALLOWED_NAME_CHARS = u'abcdefghijklmnopqrstuvwxyz0123456789_' diff --git a/esphomeyaml/helpers.py b/esphomeyaml/helpers.py index 036d680763..cbcaf54ede 100644 --- a/esphomeyaml/helpers.py +++ b/esphomeyaml/helpers.py @@ -407,15 +407,31 @@ def get_variable(id): yield None +def get_variable_with_full_id(id): + while True: + for k, v in _VARIABLES.iteritems(): + if k == id: + yield (k, v) + return + _LOGGER.debug("Waiting for variable %s", id) + yield None, None + + def process_lambda(value, parameters, capture='=', return_type=None): + from esphomeyaml.components.globals import GlobalVariableComponent + if value is None: yield return parts = value.parts[:] for i, id in enumerate(value.requires_ids): - var = None - for var in get_variable(id): + for full_id, var in get_variable_with_full_id(id): yield + if full_id is not None and isinstance(full_id.type, MockObjClass) and \ + full_id.type.inherits_from(GlobalVariableComponent): + parts[i * 3 + 1] = var.value() + continue + if parts[i * 3 + 2] == '.': parts[i * 3 + 1] = var._ else: @@ -592,7 +608,9 @@ class MockObjClass(MockObj): def template(self, args): if not isinstance(args, TemplateArguments): args = TemplateArguments(args) - obj = MockObjClass(u'{}{}'.format(self.base, args), parents=self._parents) + new_parents = self._parents[:] + new_parents.append(self) + obj = MockObjClass(u'{}{}'.format(self.base, args), parents=new_parents) obj.requires.append(self) obj.requires.append(args) return obj