Knx.send with a calculated value

Hi there, I have an existing KNX setup and just now want to switch from a different visualization to home assistant. So far, great. I am using lovelace and floorplan.
Here, I have an element which, when clicked, should increase the desired temperature by 0.5. The current status of the desired temperature can be obtained from the KNX bus, so in knx.yaml I have

sensor:
    - name: "Solltemp Status"
      state_address: "7/0/193"
      type: "temperature"

and this is the rule in the lovelace-floorplan-dashboard:

            - element: Incr_Solltemp
              tap_action:
                action: call-service
                service: knx.send
                service_data:
                  address: "7/0/190"
                  payload: '{{ states("sensor.solltemp_status") + 0.5 }}'
                  type: "temperature"

This results in an error when I click on the element: “Could not serialize DPTTemperature” with my formula. Just for checking, if I enter a literal number under payload, everything works fine. What can I do? Thanks in advance for any hint/help.

It would help if you also provided the error from the logs.
My best guess: states("sensor.solltemp_status") returns a string, so you’d have to states("sensor.solltemp_status") | float(0) it before you can add a number.

farmio, thanks for your reply!

Unfortunately, the home-assistant.log does not give more information:

2023-03-02 12:49:57.183 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection] [140132296614784] <ConversionError description="Could not serialize DPTTemperature" value="{{ (sensor.schlafzimmer_solltemp_status.state + 0.5) }}"/>
    raise ConversionError(f"Could not serialize {cls.__name__}", value=value)
xknx.exceptions.exception.ConversionError: <ConversionError description="Could not serialize DPTTemperature" value="{{ (sensor.schlafzimmer_solltemp_status.state + 0.5) }}"/>
2023-03-02 12:49:57.193 DEBUG (MainThread) [homeassistant.components.websocket_api.http.connection] [140132296614784] Sending {"id":45,"type":"result","success":false,"error":{"code":"unknown_error","message":"<ConversionError description=\"Could not serialize DPTTemperature\" value=\"{{ (sensor.schlafzimmer_solltemp_status.state + 0.5) }}\"/>"}}

I have tried your suggestion. Same error.
Am I trying to do this in the wrong way?

Even a simple formula ‘{{ 15.5 + 1.5 }}’ works, just the above one does not. Is something broken in the states() function, or am I using it in a way I should not?

Edit: I found the error changes when I use ‘${…}’ instead of ‘{{…}}’ Now I get the error

2023-03-02 13:18:52.518 DEBUG (MainThread) [homeassistant.components.websocket_api.http.connection] [139671613550560] Sending {"id":53,"type":"result","success":false,"error":{"code":"invalid_format","message":"required key not provided @ data['payload']"}}

and a simple formula such as ‘${ Math.round(15.5+1.5) }’ works! So it seems there is something wrong with my use of the states() function.

It acutally does, when you know what to look for.

<ConversionError description="Could not serialize DPTTemperature" value="{{ (sensor.schlafzimmer_solltemp_status.state + 0.5) }}"/>

This means it can’t make a number from the string "{{ (sensor.schlafzimmer_solltemp_status.state + 0.5) }}"
I have no idea where “sensor.schlafzimmer_solltemp_status.state” comes from and why it is not evaluated correctly. Try to test it beforehand in “Developer Tools → Templates”.

Thanks farmio. I have looked further: the template editor accepts and computes the correct result for the template

{{ ( (states("sensor.solltemp_status")|float) - 0.5) }}

(I have shortened the name of the sensor a little bit).

But when I put EXACTLY this template into the payload line, what I get upon a click in the log is:

2023-03-02 15:55:45.492 DEBUG (MainThread) [homeassistant.components.websocket_api.http.connection] [139713828619120] Received {'type': 'call_service', 'domain': 'knx', 'service': 'send', 'service_data': {'address': '7/0/190', 'payload': '{{ ( (states("sensor.solltemp_status")|float) - 0.5) }}', 'type': '9.001'}, 'id': 73}
2023-03-02 15:55:45.498 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection] [139713828619120] <ConversionError description="Could not serialize DPTTemperature" value="{{ ( (states("sensor.solltemp_status")|float) - 0.5) }}"/>
2023-03-02 15:55:45.512 DEBUG (MainThread) [homeassistant.components.websocket_api.http.connection] [139713828619120] Sending {"id":73,"type":"result","success":false,"error":{"code":"unknown_error","message":"<ConversionError description=\"Could not serialize DPTTemperature\" value=\"{{ ( (states(\"sensor.solltemp_status\")|float) - 0.5) }}\"/>"}}

To me this looks as if payload does not accept the states() function.
Any idea what I could try?

This looks like the template isn’t evaluated at all. It is passed as whole as string.
Afaik it works that way in automations. You seem to use it somewhere else, so maybe templates aren’t supposed to work there?

You are probably right. Although it does work if I write a simple expression involving constants, like 15+3.5.

Sorry, I am new to Home Assistant. What should I try next?

It is not possible to use templates for actions. But calling a script is a good alternative :wink: .

Ok, just for reference, I have resolved the issue using an automation. (Not very elegant but the best I could do).
So basically this is like my template idea above, only because Lovelace does not support templates, the template is pushed into an automation.
So in the Lovelace dashboard, under view, there is a YAML snippet like

            - element: MySVGelement
              tap_action:
                action: call-service
                service: automation.trigger
                service_data:
                  entity_id: automation.increase_target_temp

and in the automation.yaml, there is

- alias: "Increase Target Temp"
  trigger: []
  mode: single
  action:
  - service: knx.send
    data:
      address: '7/0/205'
      payload: '{{ ((states("sensor.target_temp_status") | float / 0.5 ) | round(0)) * 0.5 + 0.5 }}'
      type: '9.001'

Not beautiful, but works.