How to manually set state/value of sensor?

I see now (was focusing on the state attribute for some reason). Looking at his code it sounds reasonable

    - service: python_script.set_state
      entity_id:
      - sensor.last_known_version

So actually there is no need to change the script code, he just have to remove that dash and this should work

    - service: python_script.set_state
      entity_id: sensor.last_known_version
      data_template:
        state: "{{states('sensor.current_version')}}"

The only trouble is he says it doesn’t… 8()

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.

Yeah I saw that, but you can never be sure. Always good to point out things they could have done to cause the issue.

This is (and always has been) the automation action. :smile:

    - service: python_script.set_state
      entity_id: sensor.last_known_version
      data_template:
        state: "{{states('sensor.current_version')}}"

Moreover, your amendment to detect a list doesn’t work, perhaps theres a missing import? Error is

name ‘list’ is not defined

It’s ok because this is the only place this script is used so for now I have just commented the check and assume it is always a list. :smile:

Sorry my python is not very good. :expressionless:

nope. this works for me:

if type(inputEntity) is list and len(inputEntity) >= 1:

list is a type in python, it’s impossible for it to not exist.

Try putting entity_id inside data_template

    - service: python_script.set_state
      data_template:
        entity_id: sensor.last_known_version
        state: "{{states('sensor.current_version')}}"

neither list not type are recognised in python_script because it’s RestrictedPython.
Here’s what’s available - list is a wrapper and I can see no isinstance.

1 Like

I think I can explain what’s wrong with the OP’s code.
First of all, it is not related to HA version (at least it behaves the same in 0.104.2).
It is also not related to the set_state.py script - I was able to get the error in question by changing the automation only.

Apparently the reason behind the error is the way data was passed to the service call and this suggestion should solve the issue. (I do remember at least one topic discussing different integrations allowing entity_id only outside/inside data)
Here is how it should be - basically, everything that you want to pass to your service must be inside data{_template} or you may get any types of errors.

I’m not a HA developer but the fact is that we get a string if entity_id is inside data_template and a list that contains the very same string if it’s outside. Maybe that’s because result of every template is a string, it cannot be an object?
I can only say that everything that we consider a string (like {{states('sensor.current_version')}}) is actually a list because that’s the way strings are represented in python - basically they are all lists of characters.

The bottom line is read the docs!

2 Likes

Psh, who does that!

1 Like

I just want to thank you for this amazing solution, it just made my day!

My use case as a new comer to H-A is a little different to most of what is posted here.
I have a python script that returns a numeric value from sqliteDB. I want to pass that numeric value to an entity state to update the state value and do this on a pattern or cron job every couple of hours. The idea is just to display the entity state value in a lovelace card.
Can this set_state.py script be used to achieve this?

You can use a command line sensor.

Thx, went with this option.
Used following in the configuration.yaml :

rest_command:
  update_sensor:
    url: 'http://localhost:8123/api/states/{{entity_id}}'
    method: POST
    headers:
      authorization: !secret longlivedtoken_curl_update_sensor
      accept: 'application/json, text/html'
      user-agent: 'Mozilla/5.0 {{ useragent }}'
    payload: '{"state":"button_pressed"}'
    content_type:  'application/json'

First create a livelong token (see Restful Command documentation)
From NodeRed or from within YAML call the service :
rest_command.update_sensor with data template { "entity_id": "sensor.your_sensor_here" }

1 Like

I’m using this python script to track the last few button pushes on a Hue dimmer switch. I store them as attributes under the sensor that is created for the dimmer switch. Staqrting with the python script in an automation, I have:

  - service: python_script.py_script_history_attributes
    data_template:
      entity_id: sensor.master_bedroom_switch
      state: unknown
      last_0: "{{states(trigger.entity_id) }}"
      last_1: "{{state_attr(trigger.entity_id,'last_0') }}"
      last_2: "{{state_attr(trigger.entity_id,'last_1') }}"

The idea is that the attribute last_0 takes on the actual state value, whatever was in last_0 cascades to last_1, and whatever was in last_1 cascades to last_2. The issue is that nothing gets passed to the script when I use state_attr - the logs show that it has the value of None in the script. The only attribute that gets updated is last_0, which does not use state_attr.

As an experiment, I changed the last_0 line to:

      last_0: "{{state_attr(trigger.entity_id,'state') }}"

It, too, then passes a value of None to the script, even though I know from the log there’s a state value that is not None.

Anyone see what I’m doing wrong here? As a second thought, maybe I shouldn’t be messing with an existing sensor by adding attributes… Thoughts on that?

I think you just answered the problem I was running in to. It seems the custom attributes dissapear once the sensor state changes - I love your word “clobbers!” So now I need to figure out how to set up a dummy sensor with the attributes I need, and then go with that…

Thanks, @ktownsend-personal!

Thank you, @xannor - that update to the python script did the trick for me! I was trying to figure out how to create a sensor on the fly - had no idea it was as simple as adding inputAttributesObject = {} to the script (along with the other nice checking features).

Again, thanks for the effort!!

I am a bit puzzled about what’s happening. Below, the first sensor is updated using the script. It sets it to ‘True’ and not ‘on’. The sensor below that is an example if a normally functioning sensor.

It seems that the entire object is fine, except the state property.

{'attributes': {'device_class': 'motion', 'friendly_name': 'Wyze Living Room Camera Motion Event'},
 'context': {'id': '913630937f0844a69f8c268b2a166bb3', 'parent_id': None, 'user_id': None},
 'entity_id': 'binary_sensor.wyze_living_room_camera_motion_event',
 'last_changed': '2020-07-23T05:19:44.025211+00:00',
 'last_updated': '2020-07-23T05:19:44.025211+00:00',
 'state': 'False'}

{'attributes': {'device_class': 'door', 'friendly_name': 'Laundry Room door sensor contact'},
 'context': {'id': '9ed47906ce1c4324a7bb6e13d3d241c3', 'parent_id': None, 'user_id': None},
 'entity_id': 'binary_sensor.laundry_room_door_sensor_contact',
 'last_changed': '2020-07-23T05:18:51.684317+00:00',
 'last_updated': '2020-07-23T05:18:51.684317+00:00',
 'state': 'on'}

yaml converts ‘on’, ‘off’ to True/False. The script would need to be updated to reflect that.

Gents,
I’m using the script (slightly modified for my purposes) to persist timestamp when template binary_sensor value changes (binary_sensor checks that value of other sensor is above threshold).

But attribute value doesn’t survive HA restart.

I was trying to create a new binary_sensor (in python code) and set attribute value on it - this new sensor disappears after reboot together with attributes.

How to force it to be persistent?

I have sensor.energy_kwh made by platform:integration from sensor.energy

When I am trying to set sensor.energy_kwh state to value eg. 100.00 (when the previous value was eg. 10.00) it is done… for a short while (seconds). Most probably to the next increasing of sensor.energy. After that it is again back to 10.00

It behaves for me this same way for python_script.set_state and SET STATE in Developer Tools > STATES.

Does it do not works for platform:integration or am I doing something wrong?

You can’t set states on existing sensors… period. The integration that updates the existing sensor will always take precedence over any state you set. When the sensor updates, your set value will be overwritten. Why are you doing this anyways?