kodebach / hacs-idm-heatpump

HACS integration for IDM heat pumps
MIT License
20 stars 1 forks source link

Setup for writing values #40

Closed kodebach closed 8 months ago

kodebach commented 8 months ago

Adds a some basic setup for writing values back to the heat pump.

⚠️ CAUTION ⚠️ This code is mostly untested, but the currently supported values should be fairly safe experiment with. Use/extend at your own risk. Special consideration should be taken for extending this code to more sensors. IDM advises that certain values (not the ones n this PR), should be written as little as possible, since every write will cause a write to an EEPROM chip with limited write cycles. Writing those values to often may damage the heat pump.

Testing this PR

If you want to test this PR there are two options:

  1. Clone the PR branch, and use the devcontainer (e.g. via VSCode) to create a separate local testing instance of Home Assistant. In that instance you can configure the integration and test the new features.
  2. Clone the PR branch and copy the idm_heatpump directory into <config_dir>/custom_components/idm_heatpump of your existing Home Assistant instance (replacing existing files). Then restart Home Assistant to activate the new version.

I would recommend the first approach since it keeps your main Home Assistant instance in a clean and working state.

kodebach commented 8 months ago
idm_update_pv_values:
  alias: Update Photovoltaik values to IDM Headpump
  sequence:
  - service: idm_heatpump.set_power
    target:
      entity_id: [ID FOR Aktueller PV-Überschuss]
    data:
      value: {{ states("sensor.wp_aktueller_pv_uberschuss") }}
  - service: idm_heatpump.set_power
    target:
      entity_id: [ID FOR Aktueller PV-Produktion]
    data:
      value: {{ states("sensor.pv_aktuelle_produktion") }}
  mode: single

@geryyyyyy I think this is the replacement for the config from https://github.com/kodebach/hacs-idm-heatpump/issues/10#issuecomment-1782248156. You have to replace the [ID FOR ...] with the entity ids for the two sensors of this integration.

For testing you can also go to the "Developer Tools" page in Home Assistant and on the "Services" tab select the service from this integration (search for idm_heatpump). Then you can use the UI to configure the service call and switch to YAML mode to see what it looks like. You can also use it to figure out whether the service is working correctly, without setting up the entire automation script.

kodebach commented 8 months ago

From https://github.com/kodebach/hacs-idm-heatpump/issues/10#issuecomment-1783386110

template:
  - sensor:
      - name: "PV aktuelle Produktion"
        unique_id: "idm_aktuelle_pv_produktion"
        unit_of_measurement: "kW"
        state: >
          {% if states('sensor.pv_power') == 'unavailable' %}
            0.0
          {% else %}
            {{ '%.2f'%(states('sensor.pv_power')|float / 1000|float| float) }}
          {% endif %}
        state_class: measurement
        device_class: power
        icon: mdi:solar-power
      - name: "WP aktueller PV Überschuss"
        unique_id: "idm_aktueller_pv_ueberschuss"
        unit_of_measurement: "kW"
        state: >
          {% if states('sensor.pv_power')|float == 0|float %}
            0.0
          {% elif states('sensor.meter_active_power_total') == 'unavailable' %}
            0.0
          {% elif states('sensor.meter_active_power_total')|float < 0|float %}
            0.0
          {% else %}
            {{ '%.2f'%(states('sensor.meter_active_power_total')|float / 1000|float| float) }}
          {% endif %}
        state_class: measurement
        device_class: power
        icon: mdi:solar-power

The two values are prepared as float and rounded to two decimal places. It is working fine with the "modbus.write_register" script, but somehow I cannot use it in the "idm_heatpump.setpower" service.

service: idm_heatpump.set_power
data:
  target: sensor.idm_warmepumpe_aktueller_pv_produktion
  value: {{ states('sensor.pv_aktuelle_produktion') }}

Fehler beim Aufrufen des Diensts idm_heatpump.set_power. Unknown error

Does someone have an idea what I am doing wrong?

@geryyyyyy Are there any errors with more information in the Home Assistant logs? (under Settings -> System -> Logs)

Just guessing from the config above, I'd say both "PV aktuelle Produktion" and "WP aktueller PV Überschuss" are formatted as text, but the service expects a number. I think this config may work:

template:
  - sensor:
      - name: "PV aktuelle Produktion"
        unique_id: "idm_aktuelle_pv_produktion"
        unit_of_measurement: "kW"
        state: >
          {{ states('sensor.pv_power')|float / 1000 if has_value('sensor.pv_power') else 0.0 }}
        state_class: measurement
        device_class: power
        icon: mdi:solar-power
      - name: "WP aktueller PV Überschuss"
        unique_id: "idm_aktueller_pv_ueberschuss"
        unit_of_measurement: "kW"
        state: >
          {{ [0, states('sensor.meter_active_power_total')|float / 1000] | max  if has_value('sensor.pv_power') and has_value('sensor.meter_active_power_total') else 0.0 }}
        state_class: measurement
        device_class: power
        icon: mdi:solar-power

Note: This doesn't round to two decimals, but I don't think that's necessary, you can just give the exact value to the heat pump. If you want to round anyway, use (states(...)|float / 1000) | round(2) instead of states(...)|float / 1000.

geryyyyyy commented 8 months ago

Thank you for the modified yaml. Unfortunately the service is still not working with the sensor data.

@geryyyyyy Are there any errors with more information in the Home Assistant logs? (under Settings -> System -> Logs)

Sorry for not checking this earlier. There are indeed errors, which seem to root all to the same source: sensor_addresses.py line 142

Dieser Fehler wurde von einer benutzerdefinierten Integration verursacht

Logger: custom_components.idm_heatpump
Source: custom_components/idm_heatpump/coordinator.py:43
Integration: IDM heat pump (documentation, issues)
First occurred: 17:28:09 (1 occurrences)
Last logged: 17:28:09

error
Traceback (most recent call last):
  File "/config/custom_components/idm_heatpump/coordinator.py", line 43, in async_write_value
    return await self.heatpump.async_write_value(address, value)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/idm_heatpump/idm_heatpump.py", line 177, in async_write_value
    address.encode(builder, value)
  File "/config/custom_components/idm_heatpump/sensor_addresses.py", line 142, in encode
    assert value >= self.min_value and value <= self.max_value
           ^^^^^^^^^^^^^^^^^^^^^^^
TypeError: '>=' not supported between instances of 'dict' and 'int'
Logger: homeassistant.helpers.script.websocket_api_script
Source: helpers/script.py:468
First occurred: 17:28:09 (1 occurrences)
Last logged: 17:28:09

websocket_api script: Error executing script. Unexpected error for call_service at pos 1: '>=' not supported between instances of 'dict' and 'int'
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 468, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 704, in _async_call_service_step
    response_data = await self._async_run_long_action(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 666, in _async_run_long_action
    return long_task.result()
           ^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2012, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2049, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/idm_heatpump/sensor.py", line 44, in handle_set_power
    await entity.async_write_value(value)
  File "/config/custom_components/idm_heatpump/entity.py", line 87, in async_write_value
    return await self.coordinator.async_write_value(self.sensor_address, value)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/idm_heatpump/coordinator.py", line 46, in async_write_value
    raise exception
  File "/config/custom_components/idm_heatpump/coordinator.py", line 43, in async_write_value
    return await self.heatpump.async_write_value(address, value)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/idm_heatpump/idm_heatpump.py", line 177, in async_write_value
    address.encode(builder, value)
  File "/config/custom_components/idm_heatpump/sensor_addresses.py", line 142, in encode
    assert value >= self.min_value and value <= self.max_value
           ^^^^^^^^^^^^^^^^^^^^^^^
TypeError: '>=' not supported between instances of 'dict' and 'int'
Logger: homeassistant.components.websocket_api.http.connection
Source: custom_components/idm_heatpump/sensor_addresses.py:142
Integration: Home Assistant WebSocket API (documentation, issues)
First occurred: 17:28:09 (1 occurrences)
Last logged: 17:28:09

[139967890783296] Error handling message: Unknown error (unknown_error) DJ from 192.168.180.64 (Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36)
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/decorators.py", line 26, in _handle_async_response
    await func(hass, connection, msg)
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 727, in handle_execute_script
    script_result = await script_obj.async_run(msg.get("variables"), context=context)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1578, in async_run
    return await asyncio.shield(run.async_run())
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 420, in async_run
    await self._async_step(log_exceptions=False)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 470, in _async_step
    self._handle_exception(
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 493, in _handle_exception
    raise exception
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 468, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 704, in _async_call_service_step
    response_data = await self._async_run_long_action(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 666, in _async_run_long_action
    return long_task.result()
           ^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2012, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2049, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/idm_heatpump/sensor.py", line 44, in handle_set_power
    await entity.async_write_value(value)
  File "/config/custom_components/idm_heatpump/entity.py", line 87, in async_write_value
    return await self.coordinator.async_write_value(self.sensor_address, value)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/idm_heatpump/coordinator.py", line 46, in async_write_value
    raise exception
  File "/config/custom_components/idm_heatpump/coordinator.py", line 43, in async_write_value
    return await self.heatpump.async_write_value(address, value)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/idm_heatpump/idm_heatpump.py", line 177, in async_write_value
    address.encode(builder, value)
  File "/config/custom_components/idm_heatpump/sensor_addresses.py", line 142, in encode
    assert value >= self.min_value and value <= self.max_value
           ^^^^^^^^^^^^^^^^^^^^^^^
TypeError: '>=' not supported between instances of 'dict' and 'int'

It is failing in this assert check. assert value >= self.min_value and value <= self.max_value

I am not sure how the variable types 'dict' and 'int' are handled in HA, or how i can adapt it according to work with the service.

kodebach commented 8 months ago

I just updated the PR. Please download and try again. The service call will still fail, but I added some logging, so I can figure out where this dict comes from.

Once you updated, enable debug logging for the integration. Then wait until the error happens again, stop debug logging and post the logs as a file (or just post the new "Calling set_power with value ..." line from the logs).

geryyyyyy commented 8 months ago

Here is the log. home-assistant_idm_heatpump_2023-10-29T19-00-08.052Z.log DEBUG (MainThread) [custom_components.idm_heatpump] Calling set_power with value {'[object Object]': None} on sensor.idm_warmepumpe_aktueller_pv_produktion It seems like the value from the sensor will not be forwarded into the service.

In the service section I use this code in yaml view.

service: idm_heatpump.set_power
data:
  target: sensor.idm_warmepumpe_aktueller_pv_produktion
  value: {{ states('sensor.pv_aktuelle_produktion') }}

However, if i switch into UI and back into yaml view, it looks like this.

service: idm_heatpump.set_power
data:
  target: sensor.idm_warmepumpe_aktueller_pv_produktion
  value:
    "[object Object]": null
kodebach commented 8 months ago

Ah okay, I think you need quotes around the template:

service: idm_heatpump.set_power
data:
  target: sensor.idm_warmepumpe_aktueller_pv_produktion
  value: "{{ states('sensor.pv_aktuelle_produktion') }}"

Or do the multi-line string trick that many Home Assistant examples use:

service: idm_heatpump.set_power
data:
  target: sensor.idm_warmepumpe_aktueller_pv_produktion
  value: >
    {{ states('sensor.pv_aktuelle_produktion') }}

YAML is sometimes weird...

geryyyyyy commented 8 months ago
service: idm_heatpump.set_power
data:
  target: sensor.idm_warmepumpe_aktueller_pv_produktion
  value: >
    {{ states('sensor.pv_aktuelle_produktion') }}

Great, this is working now for the produktion.

Now i tried to do the same with uberschuss, but it seems there is a different problem here. Even without a sensor (using the UI service by simply sending a number) it is not working.

service: idm_heatpump.set_power
data:
  value: 1
  target: sensor.idm_warmepumpe_aktueller_pv_uberschuss

Error in same line, but stating 'NoneType'.

Dieser Fehler wurde von einer benutzerdefinierten Integration verursacht

Logger: custom_components.idm_heatpump
Source: custom_components/idm_heatpump/coordinator.py:43
Integration: IDM heat pump (documentation, issues)
First occurred: 20:56:49 (2 occurrences)
Last logged: 20:57:41

error
Traceback (most recent call last):
  File "/config/custom_components/idm_heatpump/coordinator.py", line 43, in async_write_value
    return await self.heatpump.async_write_value(address, value)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/idm_heatpump/idm_heatpump.py", line 177, in async_write_value
    address.encode(builder, value)
  File "/config/custom_components/idm_heatpump/sensor_addresses.py", line 148, in encode
    assert value >= self.min_value and value <= self.max_value
           ^^^^^^^^^^^^^^^^^^^^^^^
TypeError: '>=' not supported between instances of 'int' and 'NoneType'

Debug File here. home-assistant_idm_heatpump_2023-10-29T19-56-54.040Z.log

kodebach commented 8 months ago

Small error because I now allow negative values for the "Überschuss" in case the heat pump has some use for that. Should be fixed with the latest update of the PR.

geryyyyyy commented 8 months ago

Great, now I can execute it without any errors.

To summarize:

idm_update_pv_values:
  alias: Update Photovoltaik values to IDM Headpump
  sequence:
  - service: idm_heatpump.set_power
    data:
      target: sensor.idm_warmepumpe_aktueller_pv_uberschuss
      value: >
        {{ states("sensor.wp_aktueller_pv_uberschuss") }}
  - service: idm_heatpump.set_power
    data:
      target: sensor.idm_warmepumpe_aktueller_pv_produktion
      value: >
        {{ states("sensor.pv_aktuelle_produktion") }}
  mode: single

I will test and monitor the script tomorrow. Thanks a lot.

geryyyyyy commented 8 months ago

I will test and monitor the script tomorrow.

Unfortunately today was a cloudy and rainy day. However, the automation seems to be working. Here is an overview of the written and reaback data: image

As you can see the produktion seems to be working fine. The uberschuss sometimes has some peaks. The battery today was never at 100%, that means there should not have been any uberschuss. Those peaks come from the battery. The inverter tries to keep the grid consumption at 0. But it happens that it will climb above 0 for a short time when for example a high power consumption device has been switched off. To avoid this at least for some cases, I modified the configuration that the uberschuss will be 0 when the produktion is 0. In addition it will be 0 if the uberschuss should be higher than the produktion. New configuration looks like this:

template:
  - sensor:
      - name: "PV aktuelle Produktion"
        unique_id: "idm_aktuelle_pv_produktion"
        unit_of_measurement: "kW"
        state: >
          {% if has_value('sensor.pv_power') == False %}
            0.0
          {% else %}
            {{ (states('sensor.pv_power')|float / 1000) }}
          {% endif %}
        state_class: measurement
        device_class: power
        icon: mdi:solar-power
      - name: "WP aktueller PV Überschuss"
        unique_id: "idm_aktueller_pv_ueberschuss"
        unit_of_measurement: "kW"
        state: >
          {% if has_value('sensor.pv_power') == False or has_value('sensor.meter_active_power_total') == False %}
            0.0
          {% elif states('sensor.meter_active_power_total')|float < 0  or states('sensor.meter_active_power_total')|float > states('sensor.pv_power')|float %}
            0.0
          {% else %}
            {{ (states('sensor.meter_active_power_total')|float / 1000) }}
          {% endif %}
        state_class: measurement
        device_class: power
        icon: mdi:solar-power

Anyway, the heatpump is set to average the PV power of 2 minutes. Short peaks should not make any problems. image

Beside of this, some errors appeared in the log.

Dieser Fehler wurde von einer benutzerdefinierten Integration verursacht

Logger: custom_components.idm_heatpump
Source: custom_components/idm_heatpump/coordinator.py:43
Integration: IDM heat pump (documentation, issues)
First occurred: 18:08:21 (1 occurrences)
Last logged: 18:08:21

error
Traceback (most recent call last):
  File "/config/custom_components/idm_heatpump/coordinator.py", line 43, in async_write_value
    return await self.heatpump.async_write_value(address, value)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/idm_heatpump/idm_heatpump.py", line 177, in async_write_value
    address.encode(builder, value)
  File "/config/custom_components/idm_heatpump/sensor_addresses.py", line 149, in encode
    self.max_value is None or value <= self.max_value)
                              ^^^^^^^^^^^^^^^^^^^^^^^
TypeError: '<=' not supported between instances of 'str' and 'int'
Logger: homeassistant.components.script.idm_update_pv_values
Source: helpers/script.py:468
Integration: Skript (documentation, issues)
First occurred: 18:08:21 (1 occurrences)
Last logged: 18:08:21

Update Photovoltaik values to IDM Headpump: Error executing script. Unexpected error for call_service at pos 1: '<=' not supported between instances of 'str' and 'int'
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 468, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 704, in _async_call_service_step
    response_data = await self._async_run_long_action(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 666, in _async_run_long_action
    return long_task.result()
           ^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2012, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2049, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/idm_heatpump/sensor.py", line 48, in handle_set_power
    await entity.async_write_value(value)
  File "/config/custom_components/idm_heatpump/entity.py", line 87, in async_write_value
    return await self.coordinator.async_write_value(self.sensor_address, value)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/idm_heatpump/coordinator.py", line 46, in async_write_value
    raise exception
  File "/config/custom_components/idm_heatpump/coordinator.py", line 43, in async_write_value
    return await self.heatpump.async_write_value(address, value)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/idm_heatpump/idm_heatpump.py", line 177, in async_write_value
    address.encode(builder, value)
  File "/config/custom_components/idm_heatpump/sensor_addresses.py", line 149, in encode
    self.max_value is None or value <= self.max_value)
                              ^^^^^^^^^^^^^^^^^^^^^^^
TypeError: '<=' not supported between instances of 'str' and 'int'
Logger: homeassistant.components.automation.adaptierte_idm_update
Source: helpers/script.py:468
Integration: Automatisierung (documentation, issues)
First occurred: 18:08:21 (1 occurrences)
Last logged: 18:08:21

Adaptierte IDM Update: Error executing script. Unexpected error for call_service at pos 1: '<=' not supported between instances of 'str' and 'int'
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 468, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 704, in _async_call_service_step
    response_data = await self._async_run_long_action(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 666, in _async_run_long_action
    return long_task.result()
           ^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2012, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2049, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 605, in _service_handler
    response = await self._async_start_run(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 563, in _async_start_run
    script_result = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 594, in _async_run
    return await self.script.async_run(script_vars, context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1578, in async_run
    return await asyncio.shield(run.async_run())
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 420, in async_run
    await self._async_step(log_exceptions=False)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 470, in _async_step
    self._handle_exception(
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 493, in _handle_exception
    raise exception
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 468, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 704, in _async_call_service_step
    response_data = await self._async_run_long_action(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 666, in _async_run_long_action
    return long_task.result()
           ^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2012, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2049, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/idm_heatpump/sensor.py", line 48, in handle_set_power
    await entity.async_write_value(value)
  File "/config/custom_components/idm_heatpump/entity.py", line 87, in async_write_value
    return await self.coordinator.async_write_value(self.sensor_address, value)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/idm_heatpump/coordinator.py", line 46, in async_write_value
    raise exception
  File "/config/custom_components/idm_heatpump/coordinator.py", line 43, in async_write_value
    return await self.heatpump.async_write_value(address, value)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/idm_heatpump/idm_heatpump.py", line 177, in async_write_value
    address.encode(builder, value)
  File "/config/custom_components/idm_heatpump/sensor_addresses.py", line 149, in encode
    self.max_value is None or value <= self.max_value)
                              ^^^^^^^^^^^^^^^^^^^^^^^
TypeError: '<=' not supported between instances of 'str' and 'int'
Logger: homeassistant.components.automation.adaptierte_idm_update
Source: helpers/script.py:1783
Integration: Automatisierung (documentation, issues)
First occurred: 09:13:28 (227 occurrences)
Last logged: 18:08:21

Adaptierte IDM Update: Already running
Logger: homeassistant.components.automation.adaptierte_idm_update
Source: components/automation/__init__.py:655
Integration: Automatisierung (documentation, issues)
First occurred: 18:08:21 (1 occurrences)
Last logged: 18:08:21

While executing automation automation.adaptierte_idm_update
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/automation/__init__.py", line 655, in async_trigger
    await self.action_script.async_run(
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1578, in async_run
    return await asyncio.shield(run.async_run())
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 420, in async_run
    await self._async_step(log_exceptions=False)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 470, in _async_step
    self._handle_exception(
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 493, in _handle_exception
    raise exception
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 468, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 704, in _async_call_service_step
    response_data = await self._async_run_long_action(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 666, in _async_run_long_action
    return long_task.result()
           ^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2012, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2049, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 605, in _service_handler
    response = await self._async_start_run(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 563, in _async_start_run
    script_result = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 594, in _async_run
    return await self.script.async_run(script_vars, context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1578, in async_run
    return await asyncio.shield(run.async_run())
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 420, in async_run
    await self._async_step(log_exceptions=False)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 470, in _async_step
    self._handle_exception(
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 493, in _handle_exception
    raise exception
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 468, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 704, in _async_call_service_step
    response_data = await self._async_run_long_action(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 666, in _async_run_long_action
    return long_task.result()
           ^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2012, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2049, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/idm_heatpump/sensor.py", line 48, in handle_set_power
    await entity.async_write_value(value)
  File "/config/custom_components/idm_heatpump/entity.py", line 87, in async_write_value
    return await self.coordinator.async_write_value(self.sensor_address, value)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/idm_heatpump/coordinator.py", line 46, in async_write_value
    raise exception
  File "/config/custom_components/idm_heatpump/coordinator.py", line 43, in async_write_value
    return await self.heatpump.async_write_value(address, value)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/idm_heatpump/idm_heatpump.py", line 177, in async_write_value
    address.encode(builder, value)
  File "/config/custom_components/idm_heatpump/sensor_addresses.py", line 149, in encode
    self.max_value is None or value <= self.max_value)
                              ^^^^^^^^^^^^^^^^^^^^^^^
TypeError: '<=' not supported between instances of 'str' and 'int'

All of those errors appeared several times. Those errors might have to do something with my automation script. I trigger the script every time either the produktion or uberschuss value change. I guess that it could happen that one of those values change during the execution of the execution of the script. In that case the update idm service might get called twice at the same time. Not sure how I should configure the trigger in a proper way.

kodebach commented 8 months ago

'<=' not supported between instances of 'str' and 'int'

That means the left side of <= is a string (text-value). From the line above we know that the left side of <= is value, which in this case is the value we're trying to write to the heat pump.

I suspect the issue is the way you implemented the fallback to 0.0:

{% if has_value('sensor.pv_power') == False %}
  0.0
{% else %}
  {{ (states('sensor.pv_power')|float / 1000) }}
{% endif %}

I think, because the whole template is a string the 0.0 is also interpreted as text and not as a number. Doing this instead may work (and similarly for the other template):

{% if has_value('sensor.pv_power') == False %}
  {{ 0.0 }}
{% else %}
  {{ (states('sensor.pv_power')|float / 1000) }}
{% endif %}

The {{ }} turns 0.0 into a code fragment, where 0.0 is interpreted as a number. A shorter version of this whole thing would be:

{{ (states('sensor.pv_power')|float / 1000) if has_value('sensor.pv_power') else 0.0 }}
kodebach commented 8 months ago

@geryyyyyy If you have any further issues, please create a new issue.