That’s the source of your issues. That’s a poorly written script in regards to maintaining attribute types. It keeps everything a string which is the root cause of your issue.
I guess, for some of us, we need to take the long way round to get at the best solution.
It has been a very circuitous path for these blinds involving RF transmitters, rolling codes and complicated supply of power. They finally work and the GUI was the last bit.
Thank you so much for the simple solution for the icing on the cake
@ rodpayne the set_state.py is a great help thankyou.
However, I have a small issue when running mine, giving a no attribute lower() error.
Here is my log:
2020-02-06 20:35:08 INFO (SyncWorker_5) [homeassistant.components.python_script] Executing set_state.py: {'state': '0.105.1', 'entity_id': ['sensor.last_known_version']}
2020-02-06 20:35:08 ERROR (SyncWorker_5) [homeassistant.components.python_script.set_state.py] Error executing script: 'list' object has no attribute 'lower'
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/homeassistant/components/python_script/__init__.py", line 196, in execute
exec(compiled.code, restricted_globals)
File "set_state.py", line 13, in <module>
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/homeassistant/core.py", line 876, in get
return self._states.get(entity_id.lower())
AttributeError: 'list' object has no attribute 'lower'
If so, that would make it a list. Which would propagate error in question all the way down in the hass.states.get() in line 13.
change the code to this and it should always work.
inputEntity = data.get('entity_id')
if inputEntity is None:
logger.warning("===== entity_id is required if you want to set something.")
else:
if isinstance(inputEntity, list) and len(inputEntity) >= 1:
inputEntity = inputEntity[0]
if isinstance(inputEntity, str) and inputEntity:
inputStateObject = hass.states.get(inputEntity)
inputState = inputStateObject.state
inputAttributesObject = inputStateObject.attributes.copy()
for item in data:
newAttribute = data.get(item)
logger.debug("===== item = {0}; value = {1}".format(item,newAttribute))
if item == 'entity_id':
continue # already handled
elif item == 'state':
inputState = newAttribute
else:
inputAttributesObject[item] = newAttribute
hass.states.set(inputEntity, inputState, inputAttributesObject)
else:
logger.warning("===== entity_id is required if you want to set something.")
So yaml is pretty smart. It takes your configuration and converts it on load into python objects.
If you have this as a configuration in yaml:
foo:
- a
python recieves {'foo':['a']}
So if you were to get foo, you’d get ['a'] which is a list.
Same goes for a mapping object with a dict
foo:
bar: a
python gets {'foo':{'bar':'a'}}
or if you were to just use a single value:
foo: a
python gets {'foo':'a'}
So with that knowledge, and the flow of the program, you could deduce where this list would be coming from in get() because it’s only accepting what the user puts inside ‘entity_id’)
Well, I use a little bit modified script(which apparently does not do any list->str conversions) in my setup and there is at least one place where I call in from automation.yaml
Yeah, but the script should probably have some added safety. Never underestimate users. I didn’t test the changes I made but it should work for all non-string cases. It still doesn’t verify the entity_id is correct but that can always be added.