## -------------------------------------------------------------------------------------------------##
## EQ3-Heizthermostat
## -------------------------------------------------------------------------------------------------##
climate:
  - platform: eq3btsmart
    devices:
      kai:
        mac: '00:1A:22:0E:FB:32'


## -------------------------------------------------------------------------------------------------##
## Scripts: um einzelne Temperaturen zu setzen da Variable Fehler ausgibt (BUG)
## Ugly but working....
## -------------------------------------------------------------------------------------------------##
script:
  climate_set_15_0:
    sequence:
      - service: climate.turn_off
        entity_id: climate.kai
  climate_set_15_5:
    sequence:
      - service: climate.set_temperature
        entity_id: climate.kai
        data:
          temperature: "15.50"
          hvac_mode: "heat"
  climate_set_16_0:
    sequence:
      - service: climate.set_temperature
        entity_id: climate.kai
        data:
          temperature: "16.00"
          hvac_mode: "heat"
  climate_set_16_5:
    sequence:
      - service: climate.set_temperature
        entity_id: climate.kai
        data:
          temperature: "16.50"
          hvac_mode: "heat"
  climate_set_17_0:
    sequence:
      - service: climate.set_temperature
        entity_id: climate.kai
        data:
          temperature: "17.00"
          hvac_mode: "heat"
  climate_set_17_5:
    sequence:
      - service: climate.set_temperature
        entity_id: climate.kai
        data:
          temperature: "17.50"
          hvac_mode: "heat"
  climate_set_18_0:
    sequence:
      - service: climate.set_temperature
        entity_id: climate.kai
        data:
          temperature: "18.00"
          hvac_mode: "heat"
  climate_set_18_5:
    sequence:
      - service: climate.set_temperature
        entity_id: climate.kai
        data:
          temperature: "18.50"
          hvac_mode: "heat"
  climate_set_19_0:
    sequence:
      - service: climate.set_temperature
        entity_id: climate.kai
        data:
          temperature: "19.00"
          hvac_mode: "heat"
  climate_set_19_5:
    sequence:
      - service: climate.set_temperature
        entity_id: climate.kai
        data:
          temperature: "19.50"
          hvac_mode: "heat"
  climate_set_20_0:
    sequence:
      - service: climate.set_temperature
        entity_id: climate.kai
        data:
          temperature: "20.00"
          hvac_mode: "heat"
  climate_set_20_5:
    sequence:
      - service: climate.set_temperature
        entity_id: climate.kai
        data:
          temperature: "20.00"
          hvac_mode: "heat"
  climate_set_21_0:
    sequence:
      - service: climate.set_temperature
        entity_id: climate.kai
        data:
          temperature: "21.00"
          hvac_mode: "heat"
  climate_set_21_5:
    sequence:
      - service: climate.set_temperature
        entity_id: climate.kai
        data:
          temperature: "21.50"
          hvac_mode: "heat"
  climate_set_22_0:
    sequence:
      - service: climate.set_temperature
        entity_id: climate.kai
        data:
          temperature: "22.00"
          hvac_mode: "heat"
  climate_set_22_5:
    sequence:
      - service: climate.set_temperature
        entity_id: climate.kai
        data:
          temperature: "22.50"
          hvac_mode: "heat"
  climate_set_23_0:
    sequence:
      - service: climate.set_temperature
        entity_id: climate.kai
        data:
          temperature: "23.00"
          hvac_mode: "heat"
  climate_set_23_5:
    sequence:
      - service: climate.set_temperature
        entity_id: climate.kai
        data:
          temperature: "23.50"
          hvac_mode: "heat"
  climate_set_24_0:
    sequence:
      - service: climate.set_temperature
        entity_id: climate.kai
        data:
          temperature: "24.00"
          hvac_mode: "heat"
  climate_set_24_5:
    sequence:
      - service: climate.set_temperature
        entity_id: climate.kai
        data:
          temperature: "24.50"
          hvac_mode: "heat"
  climate_set_25_0:
    sequence:
      - service: climate.set_temperature
        entity_id: climate.kai
        data:
          temperature: "25.00"
          hvac_mode: "heat"
  climate_set_25_5:
    sequence:
      - service: climate.set_temperature
        entity_id: climate.kai
        data:
          temperature: "25.50"
          hvac_mode: "heat"
  climate_set_26_0:
    sequence:
      - service: climate.set_temperature
        entity_id: climate.kai
        data:
          temperature: "26.00"
          hvac_mode: "heat"
  climate_set_26_5:
    sequence:
      - service: climate.set_temperature
        entity_id: climate.kai
        data:
          temperature: "26.50"
          hvac_mode: "heat"
  climate_set_27_0:
    sequence:
      - service: climate.set_temperature
        entity_id: climate.kai
        data:
          temperature: "27.00"
          hvac_mode: "heat"
  climate_set_27_5:
    sequence:
      - service: climate.set_temperature
        entity_id: climate.kai
        data:
          temperature: "27.50"
          hvac_mode: "heat"
  climate_set_28_0:
    sequence:
      - service: climate.set_temperature
        entity_id: climate.kai
        data:
          temperature: "28.00"
          hvac_mode: "heat"
  climate_set_28_5:
    sequence:
      - service: climate.set_temperature
        entity_id: climate.kai
        data:
          temperature: "28.50"
          hvac_mode: "heat"
  climate_set_29_0:
    sequence:
      - service: climate.set_temperature
        entity_id: climate.kai
        data:
          temperature: "29.00"
          hvac_mode: "heat"
  climate_set_29_5:
    sequence:
      - service: climate.set_temperature
        entity_id: climate.kai
        data:
          temperature: "29.50"
          hvac_mode: "heat"
  climate_set_off:
    sequence:
      - service: climate.turn_off
        entity_id: climate.kai
  climate_set:
    alias: Setze Temperatur
    sequence:
      - service: script.turn_on
        data_template:
          entity_id: >
            {% set temp_set = ( states("sensor.climate_temp_set") | float ) %}
            {% if states("input_boolean.climate_power") == "off" %} script.climate_set_off
            {% elif temp_set == ( "00.00" | float ) %} script.climate_set_20_5
            {% elif temp_set <= ( "15.00" | float ) %} script.climate_set_15_0
            {% elif temp_set == ( "15.50" | float ) %} script.climate_set_15_5
            {% elif temp_set == ( "16.00" | float ) %} script.climate_set_16_0
            {% elif temp_set == ( "16.50" | float ) %} script.climate_set_16_5
            {% elif temp_set == ( "17.00" | float ) %} script.climate_set_17_0
            {% elif temp_set == ( "17.50" | float ) %} script.climate_set_17_5
            {% elif temp_set == ( "18.00" | float ) %} script.climate_set_18_0
            {% elif temp_set == ( "18.50" | float ) %} script.climate_set_18_5
            {% elif temp_set == ( "19.00" | float ) %} script.climate_set_19_0
            {% elif temp_set == ( "19.50" | float ) %} script.climate_set_19_5
            {% elif temp_set == ( "20.00" | float ) %} script.climate_set_20_0
            {% elif temp_set == ( "20.50" | float ) %} script.climate_set_20_5
            {% elif temp_set == ( "21.00" | float ) %} script.climate_set_21_0
            {% elif temp_set == ( "21.50" | float ) %} script.climate_set_21_5
            {% elif temp_set == ( "22.00" | float ) %} script.climate_set_22_0
            {% elif temp_set == ( "22.50" | float ) %} script.climate_set_22_5
            {% elif temp_set == ( "23.00" | float ) %} script.climate_set_23_0
            {% elif temp_set == ( "23.50" | float ) %} script.climate_set_23_5
            {% elif temp_set == ( "24.00" | float ) %} script.climate_set_24_0
            {% elif temp_set == ( "24.50" | float ) %} script.climate_set_24_5
            {% elif temp_set == ( "25.00" | float ) %} script.climate_set_25_0
            {% elif temp_set == ( "25.50" | float ) %} script.climate_set_25_5
            {% elif temp_set == ( "26.00" | float ) %} script.climate_set_26_0
            {% elif temp_set == ( "26.50" | float ) %} script.climate_set_26_5
            {% elif temp_set == ( "27.00" | float ) %} script.climate_set_27_0
            {% elif temp_set == ( "27.50" | float ) %} script.climate_set_27_5
            {% elif temp_set == ( "28.00" | float ) %} script.climate_set_28_0
            {% elif temp_set == ( "28.50" | float ) %} script.climate_set_28_5
            {% elif temp_set == ( "29.00" | float ) %} script.climate_set_29_0
            {% elif temp_set >= ( "29.50" | float ) %} script.climate_set_29_5
            {% else %} script.climate_set_20_5 {% endif %}


## -------------------------------------------------------------------------------------------------##
## Inputs
## -------------------------------------------------------------------------------------------------##
input_number:
  climate_temp:
    name: Ziel Manuell
    #initial: 21.5
    min: 15
    max: 29
    step: 0.5
  climate_temp_morning:
    name: Ziel Morgen
    #initial: 20.5
    min: 15
    max: 29
    step: 0.5
  climate_temp_night:
    name: Ziel Nacht
    #initial: 17.0
    min: 15
    max: 29
    step: 0.5
  climate_temp_accuracy:
    name: Genauigkeit
    #initial: 1
    min: 0
    max: 5
    step: 0.5
  climate_temp_offset:
    name: Offset Heizung->Temp
    #initial: 1
    min: -2
    max: 2
    step: 0.5
  climate_temp_last:
    name: Letzte Temp
    min: 0
    max: 29
    step: 0.01
    mode: box

input_datetime:
  climate_morning:
    name: "Morgen"
    has_time: true
    has_date: false
    #initial: "10:00"
  climate_morning_weekend:
    name: "Morgen Sa"
    has_time: true
    has_date: false
    #initial: "15:30"
  climate_night:
    name: "Nacht"
    has_time: true
    has_date: false
    #initial: "23:59"

input_boolean:
  climate_auto:
    name: 'Automatisch'
    icon: mdi:power
    #initial: off
  climate_power:
    name: 'Power'
    icon: mdi:power
    #initial: off
  climate_weekday:
    name: 'Wochentag'
    #initial: on
  climate_away:
    name: 'Away'
    #initial: off


## -------------------------------------------------------------------------------------------------##
## Sensoren
## -------------------------------------------------------------------------------------------------##
sensor:
  ## -----------------------------------------------------------------------------------------------##
  ## Berechnung der Temperaturveränderung
  ## -----------------------------------------------------------------------------------------------##
  - platform: template
    sensors:
      climate_temp_change:
        friendly_name: Veränderung
        value_template: >
          {% set now = states("sensor.aqara_temperature_kai_temperature")|float %}
          {% set last = states("input_number.climate_temp_last")|float %}
          {% set change = (now | float - last) | float %}
          {% if now == ("0.0"|float) %} {% set change = ("0.0"|float) %} {% endif %}
          {{ change | round(2) }}
  ## -----------------------------------------------------------------------------------------------##
  ## Berechnung der aktuellen Zieltemperatur bzgl Morgen/Nacht, Automatik/Manuell
  ## -----------------------------------------------------------------------------------------------##
  - platform: template
    sensors:
      climate_temp:
        friendly_name: akt. Ziel
        unit_of_measurement: '°C'
        value_template: >
          {% set auto = states("input_boolean.climate_auto") %}
          {% set manual_temp = states("input_number.climate_temp") %}
          {% if auto == "off" %} {{ manual_temp }}
          {% else %}
            {% set time = states("sensor.time") %}
            {% set morning = states("sensor.climate_morning") %}
            {% set weekday = states("input_boolean.climate_weekday") %}
            {% if weekday == "on" %} {% set morning = states("input_datetime.climate_morning") %}
            {% else %} {% set morning = states("input_datetime.climate_morning_weekend") %} {% endif %}
            {% set night = states("input_datetime.climate_night") %}
            {% set morning_temp = states("input_number.climate_temp_morning")|float %}
            {% set night_temp = states("input_number.climate_temp_night")|float %}
            {% if night > morning %}
              {% if time > morning and time <= night %} {{ morning_temp|float }}
              {% else %} {{ night_temp|float }} {% endif %}
            {% else %}
              {% if time <= morning and time > night %} {{ morning_temp|float }}
              {% else %} {{ night_temp|float }} {% endif %}
            {% endif %}
          {% endif %}
  ## -----------------------------------------------------------------------------------------------##
  ## Berechnung von Unterschied zwischen Heizungstemperatur und realer Temperatur
  ## -----------------------------------------------------------------------------------------------##
  - platform: template
    sensors:
      climate_temp_difference:
        friendly_name: 'akt. Unterschied'
        value_template: >
          {% if states("sensor.aqara_temperature_kai_temperature") == "unknown" %}
          {{ 0 | float }}
          {% else %}
          {{ ( states("sensor.aqara_temperature_kai_temperature") | float - (states.sensor.climate_temp.state | float) ) | round(2) }}
          {% endif %}
        unit_of_measurement: '°C'
  ## -----------------------------------------------------------------------------------------------##
  ## Schrittgröße, mit der die Heizung verstellt werden soll, abhängig vom Unterschied zur realen
  ## Temperatur
  ## Variable Schrittgröße, bei positiv (zu warm) größer, bei negativ (zu kalt) geringer
  ## -----------------------------------------------------------------------------------------------##
  - platform: template
    sensors:
      climate_temp_steps:
        friendly_name: 'Schrittgröße'
        value_template: >
          {% set difference = (states("sensor.climate_temp_difference" ) | float) %}
          {% set zero = ("0.0" | float ) %}
          {% if difference > zero %}
            {% if difference >= ("2.00"|float) %} {% set steps = ( "3.00" | float ) %}
            {% elif difference >= ("1.50"|float) %} {% set steps = ( "1.50" | float ) %}
            {% elif difference >= ("1.00"|float) %} {% set steps = ( "1.00" | float ) %}
            {% elif difference >= ("0.50"|float) %} {% set steps = ( "0.50" | float ) %}
            {% elif difference >= ("0.00"|float) %} {% set steps = ( "0.00" | float ) %}
            {% endif %}
          {% else %}
            {% if difference <= ("-2.00"|float) %} {% set steps = ( "3.00" | float ) %}
            {% elif difference <= ("-1.50"|float) %} {% set steps = ( "1.50" | float ) %}
            {% elif difference <= ("-1.00"|float) %} {% set steps = ( "0.50" | float ) %}
            {% elif difference <= ("-0.50"|float) %} {% set steps = ( "0.50" | float ) %}
            {% elif difference <= ("-0.00"|float) %} {% set steps = ( "0.00" | float ) %}
            {% endif %}
          {% endif %}
          {{ steps }}
  ## -----------------------------------------------------------------------------------------------##
  ## Berechnung der Temperatur, auf die die Heizung gestellt werden soll, um Zieltemperatur zu
  ## erreichen. Berücksichtigung für Genauigkeit, variable Temperaturanpassung und Temperatur-
  ## anpassung aufgrund von Offset. Berechnung ob Anpassung Positiv oder Negativ
  ## -----------------------------------------------------------------------------------------------##
  - platform: template
    sensors:
      climate_temp_set:
        friendly_name: '-> Heizung'
        value_template: >
          {% set difference = (states("sensor.climate_temp_difference" ) | float) %}
          {% set change = (states("sensor.climate_temp_change" ) | float) %}
          {% set goal = (states("sensor.climate_temp" ) | float) %}
          {% set temp = (states("sensor.aqara_temperature_kai_temperature") | float ) %}
          {% set climate = (state_attr("climate.kai", "temperature") | float ) %}
          {% if climate < ("15.0" | float ) %} {% set climate = ("15.0" | float) %} {% endif %}
          {% set max = states("sensor.climate_temp") | float %}
          {% set min = states("sensor.climate_temp") | float - (states.input_number.climate_temp_accuracy.state | float) %}
          {% set zero = ("0.0" | float ) %}
          {% set difference_max = ("1.5" | float ) %}
          {% set difference_min = ("-2.0" | float ) %}
          {% set change_max = ("1.0" | float ) %}
          {% set offset = (states("input_number.climate_temp_offset") | float ) %}
          {% set climate_goal = (goal | float + ("2.0" | float) | float - offset) | float %}
          {% set steps = (states("sensor.climate_temp_steps") | float) %}
          {% if difference == zero %} {% set result = climate %}
          {% elif (difference > difference_max) %} {% set result = ("15.0"|float) %}
          {% elif (difference < difference_min) %} {% set result = goal - offset %}
          {% elif difference > zero %}
            {% if (climate_goal <= climate) or (change >= change_max) %} {% set result = goal - offset %}
            {% elif temp > max %} {% set result = (climate | float - steps) | float %}
            {% else %} {% set result = climate %} {% endif %}
          {% elif difference < zero %}
            {% if temp < min %} 
              {% set result = (climate | float + steps) | float %}
            {% else %} 
              {% if change >= change_max %}
                {% set result = goal - offset %}
              {% else %}
                {% set result = climate %} 
              {% endif %}
            {% endif %}
          {% endif %}
          {% if result < ("15.0"|float) %} {{ ("15.0"|float) }}
          {% elif result > ("29.5"|float) %} {{ ("29.5"|float) }}
          {% else %} {{ result }}
          {% endif %}
        unit_of_measurement: '°C'
  ## -----------------------------------------------------------------------------------------------##
  ## Time / Date
  ## -----------------------------------------------------------------------------------------------##
  - platform: time_date
    display_options:
      - 'time'
      - 'date'
      

automation:
  ## -----------------------------------------------------------------------------------------------##
  ## Trigger alle 15min um Abfrage und Temperaturanpassung durchzuführen
  ## -----------------------------------------------------------------------------------------------##
  - alias: climate_set_auto
    initial_state: on
    trigger:
      - platform: time_pattern
        minutes: '/5'
      - platform: state
        entity_id: sensor.climate_temp
    condition:
      - condition: template
        value_template: '{{ states.climate.kai.state != "unavailable" }}'
    action:
      - service: script.turn_on
        entity_id: script.climate_set
      - delay: '00:20'
      - service: script.turn_on
        entity_id: script.climate_set
      - service: input_number.set_value
        data_template:
          entity_id: input_number.climate_temp_last
          value: '{{ states("sensor.aqara_temperature_kai_temperature")|float }}'
  - alias: climate_set_manual
    initial_state: on
    trigger:
      - platform: state
        entity_id: input_number.climate_temp
    condition:
      - condition: template
        value_template: '{{ states.climate.kai.state != "unavailable" }}'
    action:
      - service: input_boolean.turn_off
        entity_id: input_boolean.climate_auto
      - service: script.turn_on
        entity_id: script.climate_set
      - delay: '00:20'
      - service: script.turn_on
        entity_id: script.climate_set
  - alias: climate_set_power_off
    initial_state: on
    trigger:
      - platform: state
        entity_id: input_boolean.climate_power
        to: "off"
    action:
      - service: climate.turn_off
        entity_id: climate.kai
      - delay: '00:20'
      - service: climate.turn_off
        entity_id: climate.kai
  - alias: climate_set_power_on
    initial_state: on
    trigger:
      - platform: state
        entity_id: input_boolean.climate_power
        to: "on"
    action:
      - service: climate.turn_on
        entity_id: climate.kai
      - delay: '00:20'
      - service: climate.turn_on
        entity_id: climate.kai
  ## -----------------------------------------------------------------------------------------------##
  ## Trigger alle 5min, wenn Wochentag -> aktiviere Weekday-Boolean
  ## -----------------------------------------------------------------------------------------------##
  - alias: climate_weekday
    initial_state: on
    trigger:
      platform: time_pattern
      minutes: '/5'
    condition:
      - condition: time
        weekday:
          - mon
          - tue
          - wed
          - thu
          - fri
          - sun
    action:
      service: input_boolean.turn_on
      entity_id: input_boolean.climate_weekday
  ## -----------------------------------------------------------------------------------------------##
  ## Trigger alle 5min, wenn Wochenende -> deaktiviere Weekday-Boolean
  ## -----------------------------------------------------------------------------------------------##
  - alias: climate_weekend
    initial_state: on
    trigger:
      platform: time_pattern
      minutes: '/5'
    condition:
      - condition: time
        weekday:
          - sat
    action:
      service: input_boolean.turn_off
      entity_id: input_boolean.climate_weekday