How do you modify the value of a sensor attribute

I have an automation/script that keeps my living room light at a measured light level. I’m trying to clean it up by making a single sensor that has several attributes instead of several helper sensors. This is my new sensor:

- platform: template
  sensors:
    pid_loop_living_room_light:
      friendly_name: "Living Room PID"
      unique_id: 12345-67893
      value_template: "{{states('sensor.livingroom_light_and_motion_illuminance') | int}}"
      attribute_templates:
        P: 0.015
        I: 0.0
        D: 0.01
        Set_point: 800
        last_error: 3
        last_input: 803
        lux_sensor: "sensor.livingroom_light_and_motion_illuminance"

currently the attribute values I want to store are in separate helper sesnors

  - service: script.1717184105053
    data: {}
    response_variable: pid_vars
  - service: input_number.set_value
    metadata: {}
    data:
      value: '{{pid_vars.last_input|float}}'
    target:
      entity_id: input_number.lux_last_input
  - service: input_number.set_value
    metadata: {}
    data:
      value: '{{pid_vars.last_time|float}}'
    target:
      entity_id: input_number.lux_last_error
  - service: input_number.set_value
    metadata: {}
    data:
      value: '{{pid_vars.....

How do I modify input_number.lux_last_input to write to sensor.pid_loop_living_room_light.last_input ?

Thanks!

Take a look at the documentation on how to create attributes for your sensors. You are using the old method of template sensors, the new method wouldn’t have a value_template or attribute_template.

Thanks for the insight of where my issue is, but I can not get that to work at all. I even copy from the Template → YAML configuration example to replace my sensors.yaml file and all I get is:

Invalid config for ‘sensors’ in configuration.yaml line 18
where line 18 is ‘sensors: !include sensors.yaml’
guess I’ll just leave it alone - it works.

That is because it’s broken out now:

configuration.yaml

sensor: !include_dir_list ../entities/sensors (old style sensors)
template: !include_dir_list ../entities/templates/sensors (new style)

So if you want to use the new style then you add template: to point to your folder/file/etc (above mine is for files in a folder).

Once there, assuming each template sensor is it’s own file, they would look like this:

sensor:
  - name: Living Room PID
    unique_id: 12345-67893
    state: "{{states('sensor.livingroom_light_and_motion_illuminance') | int}}"
    icon: mdi:head-lightbulb-outline

    attributes:
      P: "{{states('input_number.whatever')}}"

      ... and so forth

Alright - trying to do this.
I want to make sure I understand this:

my new sensor will be located and called

[from the configuration.yaml file location]/entities/templates/sensors/my_1st_sensor.yaml
and
[from the configuration.yaml file location]/entities/templates/sensors/my_2nd_sensor.yaml

the things that are currently in my template.yaml will be
[from the configuration.yaml file location]/entities/templates/sensors/old.yaml

at least until I get around to cleaning them up.
Is this the right idea?

That seems about right, your old stuff uses the old config entry and the new stuff the new config entry. They can co-exist.

Unless I’m missing something, the path you’re headed down will result in a template sensor whose attributes are just copies of a bunch of input_number helpers’ states. If you want to skip the middleman and delete all those input number helpers, and have your automation put values directly into those attributes, you’re going to need a trigger-based template sensor that uses a custom event as a trigger.

You’ll want the new format, so that effort wasn’t all for naught, but you’ll have to change it a bit further. The documentation for the trigger-based template variants is just a little further down on the same template page linked earlier in this thread.

But you’ll also need to understand the event trigger and the data available in the trigger.event variable

Here’s a nice example of it implemented on a binary sensor:

Thank you. That is what the original question was actually looking for. As for the sensor move from old to new format - it is a fight. Still working that.

Making progress - need a little more assistants
my sensor is now:

- sensor:
  - name: Office PID
    unique_id: koko_auto_0003
    state: >
      {% set feedback = states('sensor.office_lighting_illuminance') | int %}
      {% set kp = state_attr('sensor.living_room_pid','P' ) | float | default(2) %}
      {% set ki = state_attr('sensor.living_room_pid','I') | float | default(0.0) %}
      {% set kd = state_attr('sensor.living_room_pid','D') | float | default(0.0) %}
      {% set sp = state_attr('sensor.living_room_pid','Set_point') | int | default(800) %}
      {% set lst_input = state_attr('sensor.living_room_pid','last_input') | int | default(810) %}
      {% set lst_error = state_attr('sensor.living_room_pid','last_error') | int | default(10.0) %}
      {% set error = (sp - feedback) | int %}
      {% set delta_error = (error - lst_error) | float %}
      {% set nwtime = now().timestamp() %}
      {% set lsttime = as_timestamp(states.sensor.living_room_pid.last_changed) %}
      {% set delta_time = (nwtime-lsttime) %}
      {% set disp = ((kp*error)+(ki*error*delta_error)+(kd*delta_error/delta_time)) | float %}

      {{disp}}
    attributes:
      P: >
        {% set disp = 0.015 |float(3) %}
        {{ disp }}
      I: >
        {% set disp = 0.0 |float(3) %}
        {{ disp }}
      D: >
        {% set disp = 0.01 |float(3) %}
        {{ disp }}
      Set_point: >
        {% set disp = 800 |int %}
        {{ disp }}
      last_error: >
        {% set feedback = states('sensor.office_lighting_illuminance') | int %}
        {% set sp = state_attr('sensor.living_room_pid','Set_point') | int | default(800) %}
        {% set disp = (sp - feedback) | int %} 
        {{ disp }}
      last_input: >
        {% set disp = states('sensor.office_lighting_illuminance') | int %}
        {{ disp }}

I will be setting the P I and D by going into Developer tools - this is working since it has a unique_id.
I will be setting the set point by automation based on time and request.

Otherwise I would like it to reference itself for the information that is currently coming from ‘living_room_pdi’

How do I get this sensor located in the template: !include_dir_merge_list → [path]/office_pid.yaml to reference itself?
I’ve tried replacing
state_attr(‘sensor.living_room_pid’,‘P’ )
with
state_attr(‘sensor.office_pid’,‘P’ )
and
this.attribute.P
… (several other attempts)

I’m not exactly sure what you are asking on this. Are you saying you want to use the value of the P attribute within the same sensor P exists in? If so then. you set up a variable and let P and whatever you want reference that.

Well it is running and cleaned up:

What it is:
On a cloudy day it feels like I have to get up and turn the light on and off based on the clouds and adjust the light because of to much glare or need a little more general light. This is to stop me from having to get up and down for light purposes.

I already have it running (but will change to the new code) in the entertainment area (which is my living room) with movement lux setting, general tv setting and movie setting. The neat thing about it is I use to run the light around 60% - immediately by just maintaining a reasonable lux level I found the lights running about 30%. So it is energy efficient as well.

This is the operating code:
It took two new sensors to do it: (plus the light illuminance commercial sensor)

office_adjustment.yaml

- sensor:
  - name: Office Adjustment
    unique_id: koko_auto_0004
    state: >
      {% set feedback = states('sensor.office_lighting_illuminance') | int %}
      {% set kp = state_attr('sensor.office_pid','P' ) | float | default(2) %}
      {% set ki = state_attr('sensor.office_pid','I') | float | default(0.0) %}
      {% set kd = state_attr('sensor.office_pid','D') | float | default(0.0) %}
      {% set sp = states('sensor.office_pid') | int | default(800) %}
      {% set lst_input = state_attr('sensor.office_pid','last_input') | int | default(810) %}
      {% set lst_error = state_attr('sensor.office_pid','last_error') | int | default(10.0) %}
      {% set error = (sp - feedback) | int %}
      {% set delta_error = (error - lst_error) | float %}
      {% set nwtime = now().timestamp() %}
      {% set lsttime = as_timestamp(states.sensor.office_pid.last_changed) %}
      {% set delta_time = (nwtime-lsttime) %}
      {% set disp = ((kp*error)+(ki*error*delta_error)+(kd*delta_error/delta_time)) | float %}

      {{disp}}

and
office_pid.yaml

- sensor:
  - name: Office PID
    unique_id: koko_auto_0003
    state: >
        {{ states('input_number.office_lux_set_point') | int }}

    attributes:
      P: >
        {% set disp = 0.015 |float(3) %}
        {{ disp }}
      I: >
        {% set disp = 0.0 |float(3) %}
        {{ disp }}
      D: >
        {% set disp = 0.01 |float(3) %}
        {{ disp }}
      last_error: >
        {% set feedback = states('sensor.office_lighting_illuminance') | int %}
        {% set sp = state_attr('sensor.living_room_pid','Set_point') | int | default(800) %}
        {% set disp = (sp - feedback) | int %} 
        {{ disp }}
      last_input: >
        {% set disp = states('sensor.office_lighting_illuminance') | int %}
        {{ disp }}

a helper:

and the automation

alias: Office Light Adjustment
description: ""
trigger:
  - platform: time_pattern
    minutes: /1
    seconds: "11"
    id: TOD
  - platform: device
    type: changed_states
    device_id: c2f53d2ac34d1e4e4a9b2db8610a8fab
    entity_id: 833869d699c4e3525ad1fe28b12e5fe7
    domain: light
    id: Manual
  - platform: state
    entity_id:
      - automation.laura_working_2
    to: "on"
    id: Office Occupied
  - platform: state
    entity_id:
      - binary_sensor.eric_s_working
    to: "on"
    id: Office Occupied
    for:
      hours: 0
      minutes: 0
      seconds: 15
condition: []
action:
  - choose:
      - conditions:
          - condition: trigger
            id:
              - TOD
        sequence:
          - if:
              - condition: numeric_state
                entity_id: light.office_main_lights
                above: 0
                below: 254
                attribute: brightness
            then:
              - service: input_number.set_value
                metadata: {}
                data:
                  value: 800
                target:
                  entity_id: input_number.office_lux_set_point
              - service: light.turn_on
                metadata: {}
                data:
                  transition: 15
                  brightness_step: |
                    {{states('sensor.office_adjustment')}}
                target:
                  entity_id: light.office_main_lights
              - if:
                  - condition: numeric_state
                    entity_id: light.office_main_lights
                    below: 5
                    attribute: brightness
                then:
                  - service: light.turn_off
                    metadata: {}
                    data:
                      transition: 30
                    target:
                      entity_id: light.office_main_lights
              - if:
                  - condition: numeric_state
                    entity_id: light.office_main_lights
                    above: 253
                    attribute: brightness
                then:
                  - service: light.turn_on
                    metadata: {}
                    data:
                      brightness: 252
                    target:
                      entity_id: light.office_main_lights
      - conditions:
          - condition: trigger
            id:
              - Manual
        sequence:
          - if:
              - condition: device
                type: is_off
                device_id: c2f53d2ac34d1e4e4a9b2db8610a8fab
                entity_id: 833869d699c4e3525ad1fe28b12e5fe7
                domain: light
            then:
              sequence:
                - service: light.turn_off
                  metadata: {}
                  data:
                    transition: 3
                  target:
                    entity_id: light.office_main_lights
                - service: input_number.set_value
                  metadata: {}
                  data:
                    value: 0
                  target:
                    entity_id: input_number.office_lux_set_point
            else:
              sequence:
                - service: light.turn_on
                  metadata: {}
                  data:
                    transition: 15
                  target:
                    entity_id: light.office_main_lights
                - service: input_number.set_value
                  metadata: {}
                  data:
                    value: 3500
                  target:
                    entity_id: input_number.office_lux_set_point
      - conditions:
          - condition: and
            conditions:
              - condition: device
                type: is_off
                device_id: c2f53d2ac34d1e4e4a9b2db8610a8fab
                entity_id: 833869d699c4e3525ad1fe28b12e5fe7
                domain: light
              - condition: trigger
                id:
                  - Office Occupied
              - condition: numeric_state
                entity_id: input_number.office_lux_set_point
                above: 0
              - condition: numeric_state
                entity_id: sensor.office_lighting_illuminance
                below: input_number.office_lux_set_point
        sequence:
          - service: light.turn_on
            metadata: {}
            data:
              transition: 15
              brightness_pct: 7
            target:
              entity_id: light.office_main_lights
        alias: Occupied Office
mode: single

As with all my stuff it will be upgraded again over time…
Any ideas on how I could have coded it better or even additions to put into it are welcome.

Future add will be to add lux control control by when the switch is manually dimmed or brighten it will use the new room lux level as the control set point.

1 Like

is the same as:

      P: >
        {{ 0.015 | float(3) }}
       

or even

      P: "{{ 0.015 | float(3) }}"
       

But it looks and sounds like a neat system!