IDM Heatpump Modbus integration
I like to share my integration of the IDM AERO 12 Heatpump. The concepts shared here, should also work with other IDM heatpumps.
General thoughts
A lot of terms used here are in German, hope this is OK, as long as I expect that IDM-Heatpumps are mainly sold in Austria, Switzerland and Germany.
Warranty
This is a hobby project, so there is no gurantee, support or warranty at all. You are responsible if you use parts of this project.
Prepare IDM Heatpump to eanble Modbus
You need to enter the IDM settings and switch to âFachmann Ebeneâ by entering the expert code (first level is OK, if you donât know the code, look in the internet or ask your supplier).
Go to âGebäudeleittechnikâ, enter the setting âModbus TCPâ and enable it.
If you canât manage this, consider to not continue with this project or ask the IDM-Support, I had really good experiences.
There is also a page âGLT Monitorâ to see all the available numbers and monitor/debug the values. See also these documents:
- https://www.idm-energie.at/wp-content/uploads/2021/04/tu_de_812184_myiDMenergy-Navigator-2.0.pdf
- https://www.photovoltaikforum.com/core/attachment/113433-ma-de-812170-modbus-tcp-navigator-2-0-pdf/
Important Note:
Make sure to not write too often if the settings via modbus as some of them are stored in EEPROM, see on page 12 modbus description!
Homeassistant
Letâs assume that you have HA already running and you have some experiences with it.
I use Visual Studio code to connect to my HA config via SSH (not described here).
I personally donât like to put all stuff into âconfiguration.yamlâ, I also donât like to spread a project over multiple files like âautomation.yamlâ. Fortunately there is a solution to properly seperate your projects: packages
.
I created a subfolder âpackagesâ and placed my projects there. You can have the same items as in configuration.yaml in each subfile, this does a perfect job to separate the different projects. You can simply switch them on/off by just comenting one line.
This should also work with your current setup, to not mix up this new code with you existing one.
Integration
This integration uses only the standard HA configurations and integrations, there is no need to use HACS or sourcecode - just configurations, using standard HA components.
Modbus
This integration uses modbus to communicate with the IDM heatpump.
Unfortunately the IDM modbus interface uses a different Endian-Format (Big-Endian, Little-Endian). So you need to provide the option swap: word
when reading float values.
When writing back such float values, you need to convert the float value by swapping the bytes again. This look ugly (see in automation definitions), but works good. If someone knows a better method, please let me know.
! Make sure to use your IP-address of your IDM device (see modbus:
configuration) !
Integration
PV integration
This project needs to know the current surplus PV power. So this package needs some kind of external sensors. In my setup my converter is a solaredge system, so you might need to adapt/rename these sensors (see my configuration below).
Features
All the features described here are working great for me and my setup, you might have other ideas/preferences, so just disable or modify these parts. Only use all the features if you really understand how they work.
Iâm not a heating expert, I did not found more documentation on how the heating works, so these assumptions mentioned here might be incomplete/incorrect.
The overall idea is to have a better overview on what the heatpump is doing and better understand how it works. Whenever there is enough PV power I want to use this to store energy in my buffer (850 l).
Typically the heatpump runs if there is need to do so. This means if the warm-water is below 48° (depending on the settings in IDM heatpump) it starts preparing water till appr. 53°. And if the heating is on, it will start if the heating water is no more sufficient to provide the needed temperature (Vorlauf). This is working without any integration - this is what the heatpump does itself.
If you want to âstoreâ the remaining PV power, we need to tell the heatpump to prepare warm water (more than currently needed) and store it for later use. Fortunately there is a parameter that IDM designed for that: 74. In short: if you signal that there is remaining power, the heating will use it.
In detail: the IDM will only start if there is enough energy. For my device this is about 2.1 to 2.8 kW, see the page âPhotovoltaik/PV Leistungâ Value âLeistung Vorrangâ. This value depends on several parameters (not sure) but for sure on the current temperature outside - 2.1 in summer, 2.8 in winter. Typically the heating starts using PV if the provided value is 500W higher than what is expected (to be sure there is enough energy). Then it will run at least 10 minutes - no matter if there is enough energy or not. It will also not start again prior a 10 minutes delay to have not too much toggles (bad for lifetime).
Happy Path:
The happy (naive) path is just provide the PV power and the heatpump uses it. It does adjust the used power, so the more you provide the more it uses - for my model 1.5-4 KW. If the water is warm enough, see settings on page âPhotovoltaikâ (please discuss these values with your supplier/expert to not damage the device), the heatpump will stop. It will also stop âmost timesâ if the power is too low. Sometimes it keeps on running even if there is no more power reported !?
Unhappy Path:
Letâs assume there are 3000W available, the heatpump starts⌠If you now want to make a coffee, the available power will drop to e.g. 800W - heatpump will probably stop. Even if this is only for 2 minutes, as described above it will not start again for 10 minutes. Wouldnât it be great if it keeps running? Coffee is just an example for any consumer like oven, washing machine, dryer, dish washer etcâŚ
I have a battery, on rainy days sometimes I have constantly 2000W, Battery is full, but heatpump does not start, because will start when e.g. 2,4 kW + 500W at 2,9kW. But it would be fine to let it run and use the battery that can be relaoded later.
So I introduced a buffer value âPuffer fĂźr WP Ăberschussâ. If this value is 0W you have the happy path, the heatpump will just see what PV is delivering. If it is +1000W, the heatpump will leave a 1000W unused so this can be used for other things. If it is negative, like -2000, the system reports more power than available (might use the battery if available) but will let the hetpump run (or not stop if there is some shadow).
There is also a maximum value âMaximal WP Ăberschussâ that limit the power usable by heatpump. The remaining power reported will include also the power the heatpump really uses, so even if providing âartificialâ values, the heatpump sees a response if it changes the used power.
I know, quite complex, letâs look at some examples (I add a 700W if HP is off to make it start):
| Use case | PV Power | Buffer | Max | HP Usage | PV to HP|
-----------------------------------------------------------------------------
| HP is off (+700 to start) | 2800 | 0 | 5000 | 0 | 3500 |
| HP starts | 2800 | 0 | 5000 | 1100 | 1700 |
| HP is running | 2800 | 0 | 5000 | 2300 | 500 |
| high PV | 5500 | 0 | 5000 | 2300 | 2700 |
| dawning | 2350 | 0 | 5000 | 2300 | 50 |
| WP adjust usage | 2300 | 0 | 5000 | 2150 | 150 |
| dawning | 2000 | 0 | 5000 | 2050 | 0 |
| WP stops | 1800 | 0 | 5000 | 0 | 2500 |
| high PV limited | 5000 | 0 | 3000 | 2800 | 200 |
| high PV positive buffer | 5000 | 2100 | 3000 | 2800 | 100 |
| Force run | 2000 | -4000 | 3000 | 0 | 3700 |
| HP is running | 2000 | -4000 | 3000 | 2200 | 800 |
| Coffee 3100W | -1100 | -4000 | 3000 | 2200 | 700 |
| simple case HP is running | 2800 | 0 | 0 | 2300 | 500 |
Call me crazy, but it works for my needs. To have kind of a normal behaviour, just set buffer to 0 and max to 4000. Then you will have the plain PV control as designed by IDM.
To make it even worse you can use a dummy value âDummy Value 2 Ăberschussâ (this is not tied to real PV power at all), they are used if the switch âĂbertrage reale PV Werte zu WPâ is off. Typicall set it to 0.
Additional
âWärmepumpe ein/aus automatischâ:
shall start the heatpump once a day (after 10am) if the battery is already 70+% loaded, no matter if there is currently enough power. There should be some power, because it was enough to load the battery.
This works perfectly for summer time to avoid having the heatpump starting between 8pm and 8am in the night (without PV). So typically the HP runs around 1pm fills up warm-water to 63° which is enough till the next day .
This does not really work for winter time when the heating is on . However even when heating is needed, it makes sense to let the HP run when it is warmer and high chance of PV.
âAnforderung Heizen/Warmwasserâ is experimental.
Letâs discuss how to do it better, or which kind of drugs might be helpful for this crazy guy.
======================================================
Code
content of packages\idm.yaml
:
input_boolean:
use_pv_values:
name: Ăbertrage reale PV Werte zu WP
initial: false
use_prefer_wp_before_battery:
name: Bevorzuge Wärmepumpe vor Batterie
initial: true
wp_on_off_automatically:
name: Wärmepumpe ein/aus automatisch
initial: true
wp_did_run_today:
name: Wärmepumpe lief heute schon
initial: true
input_number:
dummy_value_1:
name: "Dummy Value 1 Power"
initial: 0
min: -10000
max: 10000
step: 100
mode: box
unit_of_measurement: "W"
icon: mdi:lightning-bolt
dummy_value_2:
name: "Dummy Value 2 Ăberschuss"
initial: 0
min: -10000
max: 10000
step: 100
mode: box
unit_of_measurement: "W"
icon: mdi:lightning-bolt
wp_buffer:
name: "Puffer fĂźr WP Ăberschuss"
initial: 0
min: -10000
max: 10000
step: 100
mode: box
unit_of_measurement: "W"
icon: mdi:lightning-bolt
wp_max_power:
name: "Maximal WP Ăberschuss"
initial: 2700
min: -10000
max: 10000
step: 100
mode: box
unit_of_measurement: "W"
icon: mdi:lightning-bolt
idm_stopanforderungheizen:
name: "Stop Anforderung Heizen"
initial: 60
min: 25
max: 65
step: 1
mode: slider
unit_of_measurement: "C"
icon: mdi:thermometer-alert
idm_stopanforderungwarmwasser:
name: "Stop Anforderung Warmwasser"
initial: 60
min: 25
max: 65
step: 1
mode: slider
unit_of_measurement: "C"
icon: mdi:thermometer-alert
switch:
- platform: template
switches:
idm_anforderungheizen:
unique_id: "idm_anforderungheizen"
value_template: "{{ is_state('sensor.idm_AnforderungHeizen', '1') }}"
turn_on:
- service: modbus.write_register
data:
hub: idm_wp
unit: 1
address: 1710
value: 1
turn_off:
- service: modbus.write_register
data:
hub: idm_wp
unit: 1
address: 1710
value: 0
- platform: template
switches:
idm_anforderungwarmwasser:
unique_id: "idm_anforderungwarmwasser"
value_template: "{{ is_state('sensor.idm_AnforderungWarmWasser', '1') }}"
turn_on:
- service: modbus.write_register
data:
hub: idm_wp
unit: 1
address: 1712
value: 1
turn_off:
- service: modbus.write_register
data:
hub: idm_wp
unit: 1
address: 1712
value: 0
# NEEDS RESTART !!!
modbus:
- name: "idm_wp"
type: tcp
# use your own IP-Address
host: 192.168.1.54
port: 502
delay: 1 # after reconnect
# deprecated -> retries: 5
# retry_on_empty: true
# message_wait_milliseconds: 500
# timeout: 10
sensors:
- name: "idm_gemittelteAussentemperatur"
unique_id: "idm_gemittelteaussentemperatur"
slave: 1
scale: 1
offset: 0
unit_of_measurement: °C
address: 1002
data_type: float32
scan_interval: 30
precision: 1
swap: word
- name: "idm_Aussentemperatur"
unique_id: "idm_aussentemperatur"
slave: 1
scale: 1
offset: 0
unit_of_measurement: °C
address: 1000
data_type: float32
scan_interval: 30
precision: 1
swap: word
- name: "idm_Leistungsaufnahme"
unique_id: idm_Leistungsaufnahme
slave: 1
scale: 1
offset: 0
address: 4122
data_type: float32
scan_interval: 5
precision: 3
swap: word
unit_of_measurement: kW
device_class: power
- name: "idm_AktuellerPhotovoltaikUeberschuss"
unique_id: idm_AktuellerPhotovoltaikUeberschuss
slave: 1
scale: 1
offset: 0
address: 74
data_type: float32
scan_interval: 5
precision: 3
swap: word
unit_of_measurement: kW
device_class: power
- name: "idm_AktuellePhotovoltaikProduktion"
unique_id: idm_AktuellePhotovoltaikProduktion
slave: 1
scale: 1
offset: 0
unit_of_measurement: kW
address: 78
data_type: float32
scan_interval: 30
precision: 3
swap: word
- name: "idm_Vorlauftemperatur"
unique_id: "idm_vorlauftemperatur"
slave: 1
scale: 1
offset: 0
unit_of_measurement: °C
address: 1350
data_type: float32
scan_interval: 30
precision: 1
swap: word
- name: "idm_Waermespeichertemperatur"
unique_id: "idm_waermespeichertemperatur"
slave: 1
scale: 1
offset: 0
unit_of_measurement: °C
address: 1008
data_type: float32
scan_interval: 30
precision: 1
swap: word
- name: "idm_TrinkwassertemperaturUnten"
unique_id: "idm_trinkwassertemperaturunten"
slave: 1
scale: 1
offset: 0
unit_of_measurement: °C
address: 1012
data_type: float32
scan_interval: 30
precision: 1
swap: word
- name: "idm_AnforderungHeizen"
unique_id: idm_anforderungsheizen
slave: 1
address: 1710
data_type: uint16
scan_interval: 5
- name: "idm_AnforderungWarmWasser"
unique_id: idm_anforderungwarmwasser
slave: 1
address: 1712
data_type: uint16
scan_interval: 5
automation:
- id: solaredge_to_idm
alias: SolarEdge to IDM
description: Update von PV Ăberschuss
trigger:
- platform: state
entity_id:
- sensor.pv_uberschuss_fur_wp
- input_boolean.use_pv_values
# - sensor.pv_leistung_fur_wp
from:
condition:
# Check if input values are defined
- condition: template
value_template: "{{ is_number(states('sensor.pv_uberschuss_fur_wp')) }}"
action:
- service: modbus.write_register
data:
hub: idm_wp
unit: 1
address: 74
value: '[ {{ unpack(pack(states(''sensor.pv_uberschuss_fur_wp'')|float, ">f"), ">H", offset=2) }},
{{ unpack(pack(states(''sensor.pv_uberschuss_fur_wp'')|float, ">f"), ">H") }} ]'
# This is not needed, because WP dows not use this value !?
# - service: modbus.write_register
# data:
# hub: idm_wp
# unit: 1
# address: 78
# value: >
# [ {{ unpack(pack(states("sensor.pv_leistung_fur_wp")|float, ">f"), ">H", offset=2) }},
# {{ unpack(pack(states("sensor.pv_leistung_fur_wp")|float, ">f"), ">H") }} ]
mode: queued
### Automatische Wärmepumpensteuerung ###
# setzt das Flag, welches angibt, ob die WP schon lief zurĂźck, d.h. vor 10:00 Uhr soll die WP ohenhin nicht laufen
- id: reset_did_wp_run_totay_automation
alias: reset did wp run totay
description: 'Resets the WP did run flag once daily'
trigger:
- platform: time
at: '10:00:00'
condition: []
action:
- service: input_boolean.turn_off
target:
entity_id: input_boolean.wp_did_run_today
mode: queued
# wenn WP mind. 1000W zieht, läuft sie, und das Flag WP ist gelaufen wird schon mal gesetzt
- id: update_did_wp_run_totay_automation
alias: update did wp run totay
description: 'Updates the WP did run flag when WP is running'
trigger:
- platform: state
entity_id:
- sensor.idm_leistungsaufnahme
condition:
#alias: "WP did not run today (Flag is off) AND WP is running"
and:
- condition: state
entity_id: input_boolean.wp_did_run_today
state: "off"
- condition: numeric_state
entity_id: sensor.idm_leistungsaufnahme
value_template: "{{ state.state|float * 1000 }}"
above: 1000
action:
- service: input_boolean.turn_on
target:
entity_id: input_boolean.wp_did_run_today
mode: queued
# Wenn WP noch nicht gelaufen, und Speicher mind. 70% voll ist, kann die WP laufen
- id: start_wp_automation
alias: Start WP
condition:
and:
- condition: state
entity_id: input_boolean.wp_on_off_automatically
state: "on"
- condition: state
entity_id: input_boolean.wp_did_run_today
state: "off"
- condition: state
entity_id: input_boolean.use_pv_values
state: "off"
- condition: numeric_state
entity_id: sensor.solaredge_battery1_state_of_charge
above: 70
trigger:
- platform: state
entity_id:
- sensor.solaredge_battery1_state_of_charge
action:
- service: input_boolean.turn_on
target:
entity_id: input_boolean.use_pv_values
mode: queued
# 'WP ist gelaufen' ausschalten, wenn start_wp kommt, um nicht gleich wieder auszuschalten
- id: start_wp_auto_switchoff_wp_did_run_today
condition:
- condition: template
value_template: "{{ trigger.from_state.state == 'off' and trigger.to_state.state == 'on' }}"
trigger:
- platform: state
entity_id:
- input_boolean.use_pv_values
action:
- service: input_boolean.turn_off
target:
entity_id: input_boolean.wp_did_run_today
mode: queued
# wenn die WP schon lief und sie fertig ist (nicht mehr läuft), soll sie nicht mehr laufen
- id: stop_wp_automation
alias: Stop WP
condition:
and:
- condition: state
entity_id: input_boolean.wp_on_off_automatically
state: "on"
- condition: state
entity_id: input_boolean.wp_did_run_today
state: "on"
- condition: numeric_state
entity_id: sensor.idm_leistungsaufnahme
value_template: "{{ state.state|float(0) * 1000 }}"
below: 100
trigger:
- platform: state
entity_id:
- sensor.idm_leistungsaufnahme
- input_boolean.wp_did_run_today
action:
- service: input_boolean.turn_off
target:
entity_id: input_boolean.use_pv_values
mode: queued
# ausschalten der Heizanforderung bei erreichen der Zieltemperatur
- id: stop_wp_heizanforderung
alias: Stop WP HeizAnforderung
condition:
- condition: state
entity_id: sensor.idm_AnforderungHeizen
state: "1"
- condition: template
value_template: "{{ states('sensor.idm_Waermespeichertemperatur')|float >= states('input_number.idm_stopanforderungheizen')|float }}"
trigger:
- platform: state
entity_id:
- sensor.idm_Waermespeichertemperatur
- sensor.idm_AnforderungHeizen
action:
- service: modbus.write_register
data:
hub: idm_wp
unit: 1
address: 1710
value: 0
mode: queued
# ausschalten der WarmWasserAnforderung bei erreichen der Zieltemperatur
- id: stop_wp_warmwasseranforderung
alias: Stop WP WarmwasserAnforderung
condition:
- condition: state
entity_id: sensor.idm_AnforderungWarmWasser
state: "1"
- condition: template
value_template: "{{ states('sensor.idm_trinkwassertemperaturunten')|float >= states('input_number.idm_stopanforderungwarmwasser')|float }}"
trigger:
- platform: state
entity_id:
- sensor.idm_trinkwassertemperaturunten
- sensor.idm_AnforderungWarmWasser
action:
- service: modbus.write_register
data:
hub: idm_wp
unit: 1
address: 1712
value: 0
mode: queued
The UI: (see .storage\lovelace.dashboard_warmepumpe)
{
"version": 1,
"minor_version": 1,
"key": "lovelace.dashboard_warmepumpe",
"data": {
"config": {
"views": [
{
"title": "Home",
"cards": [
{
"type": "entities",
"entities": [
{
"entity": "input_number.dummy_value_1"
},
{
"entity": "input_number.dummy_value_2"
},
{
"entity": "input_boolean.wp_on_off_automatically"
},
{
"entity": "input_boolean.wp_did_run_today"
},
{
"entity": "input_boolean.use_pv_values"
},
{
"entity": "input_boolean.use_prefer_wp_before_battery"
},
{
"entity": "sensor.aktuelle_erzeugung"
},
{
"entity": "sensor.aktueller_verbrauch"
},
{
"entity": "sensor.aktueller_uberschuss"
},
{
"entity": "input_number.wp_max_power"
},
{
"entity": "input_number.wp_buffer"
},
{
"entity": "sensor.pv_uberschuss_fur_wp"
},
{
"entity": "sensor.idm_aktuellerphotovoltaikueberschuss"
},
{
"entity": "sensor.idm_leistungsaufnahme"
},
{
"entity": "sensor.idm_trinkwassertemperaturunten"
},
{
"entity": "sensor.idm_waermespeichertemperatur"
},
{
"entity": "sensor.idm_aussentemperatur"
},
{
"entity": "switch.idm_anforderungheizen"
},
{
"entity": "input_number.idm_stopanforderungheizen"
},
{
"entity": "switch.idm_anforderungwarmwasser"
},
{
"entity": "input_number.idm_stopanforderungwarmwasser"
}
]
},
{
"type": "grid",
"cards": [
{
"type": "gauge",
"entity": "sensor.aktuelle_erzeugung",
"max": 10000,
"needle": true,
"name": "Erzeugung",
"min": 0,
"severity": {
"green": 5000,
"yellow": 2000,
"red": 0
}
},
{
"type": "gauge",
"entity": "sensor.solaredge_battery1_power",
"needle": true,
"severity": {
"green": 100,
"yellow": -100,
"red": -5000
},
"min": -5000,
"max": 5000,
"name": "Power"
},
{
"type": "gauge",
"entity": "sensor.solaredge_battery1_state_of_charge",
"needle": true,
"severity": {
"green": 70,
"yellow": 20,
"red": 0
},
"name": "State of Charge"
},
{
"type": "gauge",
"entity": "sensor.solaredge_m1_ac_power",
"name": "Einspeisung",
"needle": true,
"severity": {
"green": 200,
"yellow": -200,
"red": -8000
},
"min": -8000,
"max": 8000
},
{
"type": "gauge",
"entity": "sensor.aktueller_verbrauch",
"name": "Verbrauch",
"needle": true,
"severity": {
"green": 0,
"yellow": 300,
"red": 1000
},
"max": 6000
},
{
"type": "gauge",
"entity": "sensor.idm_leistungsaufnahme",
"unit": "KW",
"name": "Wärmepumpe",
"max": 4,
"needle": true,
"severity": {
"green": 0,
"yellow": 2,
"red": 3
},
"min": 0
}
]
},
{
"type": "history-graph",
"entities": [
{
"entity": "sensor.idm_aktuellerphotovoltaikueberschuss"
},
{
"entity": "sensor.idm_leistungsaufnahme"
},
{
"entity": "sensor.idm_trinkwassertemperaturunten"
},
{
"entity": "sensor.idm_waermespeichertemperatur"
}
],
"hours_to_show": 5,
"title": "WP FĂźllen"
},
{
"type": "markdown",
"content": "[WP history](/history?entity_id=sensor.idm_aktuellerphotovoltaikueberschuss%2Csensor.idm_leistungsaufnahme%2Csensor.idm_trinkwassertemperaturunten%2Csensor.idm_waermespeichertemperatur&start_date={{ as_timestamp(now() - timedelta(hours=6)) | timestamp_custom('%Y-%m-%dT%H:%M:%SZ') }}) "
}
]
},
{
"title": "Power",
"path": "power",
"icon": "mdi:air-filter",
"badges": [],
"cards": []
},
{
"badges": [
{
"entity": "sensor.solaredge_ac_power"
},
{
"entity": "sensor.solaredge_battery1_power"
},
{
"entity": "sensor.solaredge_m1_ac_power"
},
{
"entity": "sensor.solaredge_battery1_state_of_charge"
}
],
"cards": []
}
]
}
}
}
Calculation of pv_uberschuss_fur_wp (kW)
This is really specific to my setup, just to give you an idea where/how I calculate this value, this is added here. You probably need to create you own calculation!
template:
- sensor:
- name: "aktueller Verbrauch"
unique_id: "aktueller_verbrauch"
unit_of_measurement: "W"
state: >
{% if states('sensor.solaredge_ac_power')|is_number and
states('sensor.solaredge_m1_ac_power')|is_number
%}
{{ states('sensor.solaredge_ac_power')|float - states('sensor.solaredge_m1_ac_power')|float }}
{%- else -%}
{{ -1.0 }}
{%- endif %}
icon: mdi:home-import-outline
state_class: measurement
device_class: power
- name: "aktuelle Erzeugung"
unique_id: "aktuelle_erzeugung"
unit_of_measurement: "W"
# state: "{{ ( states('sensor.solaredge_ac_power')|float + states('sensor.solaredge_battery1_power')|float ) }}"
state: >
{% if states('sensor.solaredge_ac_power')|is_number and
states('sensor.solaredge_battery1_power')|is_number
%}
{{ ( states('sensor.solaredge_ac_power')|float + states('sensor.solaredge_battery1_power')|float ) }}
{%- else -%}
{{ -1.0 }}
{%- endif %}
icon: mdi:lightning-bolt
state_class: measurement
device_class: power
- name: "aktueller Ăberschuss"
unique_id: "aktueller_uberschuss"
unit_of_measurement: "W"
state: >
{% if states('sensor.solaredge_m1_ac_power')|is_number and
states('sensor.solaredge_battery1_power')|is_number
%}
{% if is_state("sensor.solaredge_battery1_status", "Discharging") -%}
{{ ( states('sensor.solaredge_m1_ac_power')|float + states('sensor.solaredge_battery1_power')|float ) }}
{%- else -%}
{{ states('sensor.solaredge_m1_ac_power') }}
{%- endif %}
{%- else -%}
{{ -1.0 }}
{%- endif %}
icon: mdi:lightning-bolt
state_class: measurement
device_class: power
- name: "PV Leistung fĂźr WP"
unique_id: "pv_leistung_fur_wp"
unit_of_measurement: "kW"
state: >
{% if is_state("input_boolean.use_pv_values", "on") %}
{{ ( max(states('sensor.aktuelle_erzeugung')|float - states('input_number.wp_buffer')|float, 0) / 1000 ) }}
{%- else -%}
{{ ( states('input_number.dummy_value_1')|float / 1000 ) }}
{%- endif %}
icon: mdi:lightning-bolt
state_class: measurement
device_class: power
- name: "PV Ăberschuss fĂźr WP"
unique_id: "pv_uberschuss_fur_wp"
unit_of_measurement: "kW"
# ggf. wird während die Batterie geladen wird dennoch die Batterie-Power der WP zur Verfßgung gestellt (abzßglich eines Puffers von 100)
# x = available power for WP
# maxpower = limit power for WP, might include a 700 extra to trigger start
# aktpower = current power that the WP uses
# y = the power that we want to give to WP (the current usage is subtracted)
# z = the power that we can give to WP (respecting the available power)
state: >
{% if is_state("input_boolean.use_pv_values", "on") %}
{% set x = (states('sensor.aktueller_uberschuss')|float(0) - states('input_number.wp_buffer')|float)|float %}
{% if is_state("input_boolean.use_prefer_wp_before_battery", "on") %}
{% set batchargepower = states('sensor.solaredge_battery1_power')|float(0) - 100 %}
{% if batchargepower > 0 %}
{% set x = x + batchargepower %}
{% endif %}
{% endif %}
{% set x = max(x,0) %}
{% set maxpower = states('input_number.wp_max_power')|float %}
{% set aktpower = states('sensor.idm_leistungsaufnahme')|float(0) * 1000 %}
{% if aktpower <= 0 %}
{% set maxpower = maxpower + 700 %}
{% endif %}
{% set y = maxpower - aktpower %}
{% set y = max(y,0) %}
{% set z = min(x, y) %}
{{ z / 1000 }}
{% else %}
{{ ( states('input_number.dummy_value_2')|float / 1000 ) }}
{% endif %}
icon: mdi:lightning-bolt
state_class: measurement
device_class: power