mirror of
https://github.com/home-assistant/core.git
synced 2025-07-24 21:57:51 +00:00
Change scene matching to use fuzzy logic for float values, if requested
This commit is contained in:
parent
6abaebb248
commit
61fb8271e5
@ -33,7 +33,7 @@ ATTR_ACTIVE_REQUESTED = "active_requested"
|
|||||||
|
|
||||||
CONF_ENTITIES = "entities"
|
CONF_ENTITIES = "entities"
|
||||||
|
|
||||||
SceneConfig = namedtuple('SceneConfig', ['name', 'states', 'read_after_set'])
|
SceneConfig = namedtuple('SceneConfig', ['name', 'states', 'fuzzy_match'])
|
||||||
|
|
||||||
|
|
||||||
def setup(hass, config):
|
def setup(hass, config):
|
||||||
@ -71,7 +71,15 @@ def setup(hass, config):
|
|||||||
def _process_config(scene_config):
|
def _process_config(scene_config):
|
||||||
""" Process passed in config into a format to work with. """
|
""" Process passed in config into a format to work with. """
|
||||||
name = scene_config.get('name')
|
name = scene_config.get('name')
|
||||||
read_after_set = scene_config.get('read_after_set')
|
|
||||||
|
fuzzy_match = scene_config.get('fuzzy_match')
|
||||||
|
if fuzzy_match:
|
||||||
|
# default to 1%
|
||||||
|
if isinstance(fuzzy_match, int):
|
||||||
|
fuzzy_match /= 100.0
|
||||||
|
else:
|
||||||
|
fuzzy_match = 0.01
|
||||||
|
|
||||||
states = {}
|
states = {}
|
||||||
c_entities = dict(scene_config.get(CONF_ENTITIES, {}))
|
c_entities = dict(scene_config.get(CONF_ENTITIES, {}))
|
||||||
|
|
||||||
@ -92,7 +100,7 @@ def _process_config(scene_config):
|
|||||||
|
|
||||||
states[entity_id.lower()] = State(entity_id, state, attributes)
|
states[entity_id.lower()] = State(entity_id, state, attributes)
|
||||||
|
|
||||||
return SceneConfig(name, states, read_after_set)
|
return SceneConfig(name, states, fuzzy_match)
|
||||||
|
|
||||||
|
|
||||||
class Scene(ToggleEntity):
|
class Scene(ToggleEntity):
|
||||||
@ -179,38 +187,30 @@ class Scene(ToggleEntity):
|
|||||||
""" Returns if given state is as requested. """
|
""" Returns if given state is as requested. """
|
||||||
state = self.scene_config.states.get(cur_state and cur_state.entity_id)
|
state = self.scene_config.states.get(cur_state and cur_state.entity_id)
|
||||||
|
|
||||||
ret = (cur_state is not None and state.state == cur_state.state and
|
return (cur_state is not None and state.state == cur_state.state and
|
||||||
all(value == cur_state.attributes.get(key)
|
all(self._compare_state_attribites(value, cur_state.attributes.get(key))
|
||||||
for key, value in state.attributes.items()))
|
for key, value in state.attributes.items()))
|
||||||
|
|
||||||
print('AS REQUESTED')
|
def _fuzzy_attribute_compare(self, a, b):
|
||||||
print(ret)
|
if not (isinstance(a, float) and isinstance(b, float)):
|
||||||
print(self.scene_config.states)
|
return False
|
||||||
return ret
|
diff = abs(a - b) / (abs(a) + abs(b))
|
||||||
|
return diff <= self.scene_config.fuzzy_match
|
||||||
|
|
||||||
def _state_read_after_set(self, states):
|
def _compare_state_attribites(self, attr1, attr2):
|
||||||
""" Reads back state after setting. """
|
if attr1 == attr2:
|
||||||
print('BEFORE')
|
return True
|
||||||
print(self.scene_config.states)
|
if not self.scene_config.fuzzy_match:
|
||||||
target_state = self.scene_config.states
|
return False
|
||||||
for key, value in target_state.items():
|
if isinstance(attr1, list):
|
||||||
actual = self.hass.states.get(key)
|
return all(self._fuzzy_attribute_compare(a, b) for a,b in zip(attr1,attr2))
|
||||||
print('ACTUAL')
|
return self._fuzzy_attribute_compare(attr1, attr2)
|
||||||
print(actual)
|
|
||||||
if actual and actual != value and actual.state == value.state:
|
|
||||||
print('CHANGING CONFIG')
|
|
||||||
for k in value.attributes.keys():
|
|
||||||
value.attributes[k] = actual.attributes[k]
|
|
||||||
print('AFTER')
|
|
||||||
print(self.scene_config.states)
|
|
||||||
|
|
||||||
def _reproduce_state(self, states):
|
def _reproduce_state(self, states):
|
||||||
""" Wraps reproduce state with Scence specific logic. """
|
""" Wraps reproduce state with Scence specific logic. """
|
||||||
print('REPRODUCE_STATE')
|
print('REPRODUCE_STATE')
|
||||||
self.ignore_updates = True
|
self.ignore_updates = True
|
||||||
reproduce_state(self.hass, states, True)
|
reproduce_state(self.hass, states, True)
|
||||||
if self.scene_config.read_after_set:
|
|
||||||
self._state_read_after_set(states)
|
|
||||||
self.ignore_updates = False
|
self.ignore_updates = False
|
||||||
|
|
||||||
self.update_ha_state(True)
|
self.update_ha_state(True)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user