Skip to content

Commit

Permalink
Merge pull request #948 from onkelandy/stateengine
Browse files Browse the repository at this point in the history
Stateengine Plugin: multiple fixes
  • Loading branch information
onkelandy authored Jul 5, 2024
2 parents ec1d820 + b27753f commit d71e1f7
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 17 deletions.
10 changes: 8 additions & 2 deletions stateengine/StateEngineAction.py
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,7 @@ class SeActionSetItem(SeActionBase):
def __init__(self, abitem, name: str):
super().__init__(abitem, name)
self.__item = None
self.__eval_item = None
self.__status = None
self.__delta = 0
self.__value = StateEngineValue.SeValue(self._abitem, "value")
Expand All @@ -606,6 +607,7 @@ def __repr__(self):
def _getitem_fromeval(self):
if self.__item is None:
return
self.__eval_item = self.__item
self.__item, self.__value, self.__mindelta, _issue = self.check_getitem_fromeval(self.__item, self.__value,
self.__mindelta)
if self.__item is None:
Expand Down Expand Up @@ -643,8 +645,6 @@ def write_to_logger(self):
self._log_debug("item: {0}", self.__item.property.path)
else:
self._log_debug("item is not defined! Check log file.")
if self.__status is not None:
self._log_debug("status: {0}", self.__status.property.path)
self.__mindelta.write_to_logger()
self.__value.write_to_logger()

Expand Down Expand Up @@ -710,6 +710,7 @@ def _execute_set_add_remove(self, state, actionname, namevar, repeat_text, item,
self.update_webif_actionstatus(state, re.findall(pat, actionname)[0], 'True')
# noinspection PyCallingNonCallable
item(value, caller=self._caller, source=source)
self.__item = self.__eval_item

def get(self):
orig_item = self.__item
Expand All @@ -733,6 +734,7 @@ def get(self):
value = None
except Exception:
value = None
self.__item = orig_item
mindelta = self.__mindelta.get()
if mindelta is None:
result = {'function': str(self._function), 'item': item, 'item_from_eval': item_from_eval,
Expand Down Expand Up @@ -979,6 +981,7 @@ class SeActionForceItem(SeActionBase):
def __init__(self, abitem, name: str):
super().__init__(abitem, name)
self.__item = None
self.__eval_item = None
self.__status = None
self.__value = StateEngineValue.SeValue(self._abitem, "value")
self.__mindelta = StateEngineValue.SeValue(self._abitem, "mindelta")
Expand Down Expand Up @@ -1045,6 +1048,7 @@ def _can_execute(self, state):
def _getitem_fromeval(self):
if self.__item is None:
return
self.__eval_item = self.__item
self.__item, self.__value, self.__mindelta, _issue = self.check_getitem_fromeval(self.__item, self.__value,
self.__mindelta)
if self.__item is None:
Expand Down Expand Up @@ -1103,6 +1107,7 @@ def real_execute(self, state, actionname: str, namevar: str = "", repeat_text: s
self.update_webif_actionstatus(state, self._name, 'True')
# noinspection PyCallingNonCallable
self.__item(value, caller=self._caller, source=source)
self.__item = self.__eval_item

def get(self):
orig_item = self.__item
Expand All @@ -1126,6 +1131,7 @@ def get(self):
value = None
except Exception:
value = None
self.__item = orig_item
result = {'function': str(self._function), 'item': item, 'item_from_eval': item_from_eval, 'value': value,
'conditionset': str(self.conditionset.get()), 'previousconditionset': str(self.previousconditionset.get()),
'previousstate_conditionset': str(self.previousstate_conditionset.get()), 'actionstatus': {}}
Expand Down
35 changes: 21 additions & 14 deletions stateengine/StateEngineCondition.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,16 @@ def __repr__(self):
def check_items(self, check, value=None, item_state=None):
item_issue, status_issue, eval_issue, status_eval_issue = None, None, None, None
item_value, status_value, eval_value, status_eval_value = None, None, None, None
if check == "attribute":
_orig_value = value
else:
_orig_value = None
if check == "se_item" or (check == "attribute" and self.__item is None and self.__eval is None):
if value is None:
value = StateEngineTools.find_attribute(self._sh, item_state, "se_item_" + self.__name)
if value is not None:
if isinstance(value, str):
match = re.match(r'^(.*):', value)
if isinstance(value, str) and value.startswith("eval:"):
if value.startswith("eval:"):
_, _, value = value.partition(":")
self.__eval = value
self.__item = None
Expand All @@ -87,9 +91,11 @@ def check_items(self, check, value=None, item_state=None):
self.__item = value
item_value = value
if check == "se_status" or (check == "attribute" and self.__status is None and self.__status_eval is None):
if check == "attribute":
value = _orig_value
if value is None:
value = StateEngineTools.find_attribute(self._sh, item_state, "se_status_" + self.__name)
if value is not None:
if isinstance(value, str):
match = re.match(r'^(.*):', value)
if isinstance(value, str) and value.startswith("eval:"):
_, _, value = value.partition(":")
Expand All @@ -108,7 +114,7 @@ def check_items(self, check, value=None, item_state=None):
if check == "se_eval" or (check == "attribute" and self.__eval is None):
if value is None:
value = StateEngineTools.find_attribute(self._sh, item_state, "se_eval_" + self.__name)
if value is not None:
if isinstance(value, str):
match = re.match(r'^(.*):', value)
if value.startswith("eval:"):
_, _, value = value.partition("eval:")
Expand All @@ -120,9 +126,11 @@ def check_items(self, check, value=None, item_state=None):
self.__eval = value
eval_value = value
if check == "se_status_eval" or (check == "attribute" and self.__status_eval is None):
if check == "attribute":
value = _orig_value
if value is None:
value = StateEngineTools.find_attribute(self._sh, item_state, "se_status_eval_" + self.__name)
if value is not None:
if isinstance(value, str):
match = re.match(r'^(.*):', value)
if value.startswith("eval:"):
_, _, value = value.partition("eval:")
Expand Down Expand Up @@ -454,7 +462,7 @@ def __convert(convert_value, convert_current):
else:
self.__value.set_cast(StateEngineTools.cast_str)
convert_value = StateEngineTools.cast_str(convert_value)
convert_current = StateEngineTools.cast_str(convert_value)
convert_current = StateEngineTools.cast_str(convert_current)
if not type(_oldvalue) == type(convert_value):
self._log_debug("Value {} was type {} and therefore not the same"
" type as item value {}. It got converted to {}.",
Expand All @@ -469,7 +477,6 @@ def __convert(convert_value, convert_current):
self.__updatedbynegate if valuetype == "updatedby" else\
self.__triggeredbynegate if valuetype == "triggeredby" else\
self.__negate

if isinstance(value, list):
text = "Condition '{0}': {1}={2} negate={3} current={4}"
_key = ['{}'.format(state.id), 'conditionsets', '{}'.format(self._abitem.get_variable('current.conditionset_name')), '{}'.format(self.__name), 'current', '{}'.format(valuetype)]
Expand Down Expand Up @@ -850,26 +857,26 @@ def check_eval(eval_or_status_eval):

if self.__status is not None:
# noinspection PyUnusedLocal
self._log_debug("Trying to get {} of status item {}", eval_type, self.__status)
self._log_debug("Trying to get {} of status item {}", eval_type, self.__status.property.path)
return self.__status.property.last_change_age if eval_type == 'age' else\
self.__status.property.last_change_by if eval_type == 'changedby' else\
self.__status.property.last_update_by if eval_type == 'updatedby' else\
self.__status.property.last_trigger_by if eval_type == 'triggeredby' else\
self.__status.property.value
elif self.__status_eval is not None:
self._log_debug("Trying to get {} of statuseval {}", eval_type, self.__status_eval)
return_value = check_eval(self.__status_eval)
return return_value
elif self.__item is not None:
# noinspection PyUnusedLocal
self._log_debug("Trying to get {} of item {}", eval_type, self.__item)
self._log_debug("Trying to get {} of item {}", eval_type, self.__item.property.path)
return self.__item.property.last_change_age if eval_type == 'age' else\
self.__item.property.last_change_by if eval_type == 'changedby' else\
self.__item.property.last_update_by if eval_type == 'updatedby' else\
self.__item.property.last_trigger_by if eval_type == 'triggeredby' else\
self.__item.property.value
if self.__status_eval is not None:
self._log_debug("Trying to get {} of statuseval {}", eval_type, self.__status_eval)
return_value = check_eval(self.__status_eval)
return return_value
elif self.__eval is not None:
self._log_debug("Trying to get {} of statuseval {}", eval_type, self.__eval)
self._log_debug("Trying to get {} of eval {}", eval_type, self.__eval)
return_value = check_eval(self.__eval)
return return_value

Expand Down
7 changes: 7 additions & 0 deletions stateengine/StateEngineConditionSet.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ def update(self, item, grandparent_item):
if item is not None:
for attribute in item.conf:
func, name = StateEngineTools.partition_strip(attribute, "_")
if name.startswith("eval_"):
_, name = StateEngineTools.partition_strip(name, "_")
func = f"{func}_eval"
if name == "":
continue
try:
Expand All @@ -97,6 +100,7 @@ def update(self, item, grandparent_item):
self.__conditions[name] = StateEngineCondition.SeCondition(self._abitem, name)
issue = self.__conditions[name].set(func, item.conf[attribute])
self.__conditions.move_to_end(name, last=True)

if issue not in [[], None, [None]]:
self.__unused_attributes.update({name: {'attribute': attribute, 'issue': issue}})
elif name not in self.__used_attributes.keys():
Expand All @@ -110,6 +114,9 @@ def update(self, item, grandparent_item):
for attribute in grandparent_item.conf:
func, name = StateEngineTools.partition_strip(attribute, "_")

if name.startswith("eval_"):
_, name = StateEngineTools.partition_strip(name, "_")
func = f"{func}_eval"
if name == "":
continue
cond1 = name not in self.__used_attributes.keys()
Expand Down
5 changes: 4 additions & 1 deletion stateengine/StateEngineTools.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,10 @@ def cast_time(value):
# attribute: name of attribute to find
def find_attribute(smarthome, base_item, attribute, recursion_depth=0):
# 1: parent of given item could have attribute
parent_item = base_item.return_parent()
try:
parent_item = base_item.return_parent()
except Exception:
return None
try:
_parent_conf = parent_item.conf
if parent_item is not None and attribute in _parent_conf:
Expand Down

0 comments on commit d71e1f7

Please sign in to comment.