LDC - Daikin tarveohjaus Faikout avulla

Luukku

Vakionaama
Laitetaan nyt tänne tämä omakin kötöstys.
Tämän laskennan mukaan säädetään tarveohjausta.
ottaa huomioon sisälämpötilan, 0,5h ja 1h derivaatat, ulkolämpötilan.
Seuraava steppi säädölle sallitaan vasta 15min kuluttua tai heti, jos on riittävän suuri eli vähintään 10%.
Kylmäkerroin on. Tämän lisäksi pitää olla automaatioita muutama ja pari input.numberia.
Tarkkaillaan toimintaa ja parannellaan.

v.01.01.2026.1
Koodi:
v.01.01.2026.1
{% set T = states('sensor.sisälämpötila') | float(0) %}
{% set Tset = states('input_number.tavoitelampo') | float(0) %}
{% set d1 = states('sensor.1h_derivaatta') | float(0) %}
{% set d05 = states('sensor.0,5h_derivaatta') | float(0) %}
{% set prev = states('input_number.demand_locked') | float(0) %}
{% set T_out = states('sensor.ulkolampotila') | float(0) %}

{# --- 0) Kylmäkerroin ulkolämpötilasta --- #}
{% set gain_base =
     2.0 if T_out < -5 else
     1.5 if T_out < 2 else
     1.0 %}

{# --- 0b) Ennakointikerroin lisätekijäksi --- #}
{% set preheat = states('sensor.lammityksen_ennakointi_kerroin') | float(1.0) %}
{% set preheat_gain = [1.9, [0.3, preheat] | max] | min %}

{# --- Lopullinen gain --- #}
{% set gain = gain_base * preheat_gain %}

{# --- 1) Perustarve sisälämpötilavirheestä --- #}
{% set e = T - Tset %}
{% if e | abs < 0.05 %}
  {% set e = 0 %}
{% endif %}

{% set N_base = 50 + (-e * 50 * gain) %}
{% set N_base = [100, [40, N_base] | max] | min %}

{# --- 2) Ennusteen mukainen bias --- #}
{% set T_future = states('sensor.lampotila_ennuste_1h') | float(0) %}
{% set e_future = T_future - Tset %}

{% if e_future < -0.2 %}
  {% set offset_1h = 5 %}
{% elif e_future > 0.2 %}
  {% set offset_1h = -5 %}
{% else %}
  {% set offset_1h = 0 %}
{% endif %}

{# --- 2b) Trendikorjattu ohjaus --- #}
{% set N_trend = N_base + offset_1h %}
{% set N_trend = [100, [40, N_trend] | max] | min %}

{# --- 3) Sulatuksen jälkeinen rajoitus kytkimellä --- #}
{% if is_state('input_boolean.sulatusrajoitus', 'on') %}
  {# Sulatuksen aikana: demand lukitaan 95 %:iin #}
  {% set N_scaled = 95 %}
{% else %}
  {# Normaalitilanne: skaalaus + clamp #}
  {% set scale = 1.20 %}
  {% set N_scaled = N_trend * scale %}
  {% set N_scaled = [100, [40, N_scaled] | max] | min %}
{% endif %}

{# --- 4) Deadband + aikahystereesi (10 min) --- #}
{% set diff = (N_scaled - prev) | abs %}
{% set age = (now() - states.input_number.demand_locked.last_changed).total_seconds() %}

{# --- Eri rajat ylös- ja alaspäin --- #}
{% if N_scaled > prev %}
  {% set threshold = 5 %}
{% else %}
  {% set threshold = 10 %}
{% endif %}

{% if diff >= threshold or age > 600 %}
  {{ N_scaled | round(0) | int }}
{% else %}
  {{ prev | round(0) | int }}
{% endif %}


Sulatussensori:
Koodi:
 - name: "Sulatussensori"
        unique_id: sulatussensori_liquid
        state: >
          {% set liquid = states('sensor.faikout_liquid')|float(99)  %}
          {{ liquid < 0 }}
Tällä siis ohjataan Daikinin ilpin tarveohjausta Faikout lisäosan kautta. Template sensori laskee tarveohjauksen tarpeen huomioiden erillisen sensorin laskeman kertoimen ( T-out, T-in, tuuli ja sen suunta) sekä omassa sensorissaan olevien kertoimien perusteella tarveohjauksen määrän. Sensori sisältää myös hystereesit ettei säätö pumppaa kokoajan. Uusimpaan versioon tuli myös sulatuksen jälkeinen rajoitus tarveohjaukselle ettei pumppu ryntää, kun tuo Faikoutin DC100% näköjään antaa tosiaan täyden kompressoritehon tarvittaessa. Ryntäyksen jälkeen nämä Daikinit heittää herkästi katkolle.
Periaatteena tehdä "yksinkertainen" muutaman sensorin systeemi, mutta noita apusensoreita vaan tuntuu tulevan lisää. Pääohjaus kuitenkin yhdellä sensorilla.

Ennuste 1h sensori eli ennustaa mikä lämpötila on 1h päästä.
Koodi:
{% set T_in = states('sensor.sisälämpö') | float %}
{% set dT_in = states('sensor.sisälämpö_derivaatta') | float %}
{% set dT_out = states('sensor.ulkolampo_derivaatta') | float %}

{# Suodatetaan äkilliset piikit: rajataan derivaatan vaikutus -0.5…0.5 °C/h #}
{% set dT_in_filtered = [dT_in, 0.5] | min %}
{% set dT_in_filtered = [dT_in_filtered, -0.5] | max %}

{% set dT_out_filtered = [dT_out, 1] | min %}
{% set dT_out_filtered = [dT_out_filtered, -1] | max %}

{# Painokertoimet: sisälämpötilan muutos tärkeämpi kuin ulko #}
{% set k_in = 0.9 %}
{% set k_out = 0.1 %}

{# Ennuste 1h eteenpäin #}
{{ (T_in + k_in * dT_in_filtered + k_out * dT_out_filtered) | round(2) }}
 
Viimeksi muokattu:

Luukku

Vakionaama
  • Keskustelun aloittaja
  • #2
Nyt ohjautuu samalla metodilla yläkerran Stylish ilman Faikoutia HA:n Rest Command käskyillä (B-mallin wifi moduuli).
Semmonen huomio, että Perferalla Faikoutin tekemä DC muutos ei päivity Onectaan, mutta tuo Stylihksen Rest Command päivittää Onectankin tarveohjaus %.
 

Luukku

Vakionaama
  • Keskustelun aloittaja
  • #3
Lisäsin tuohon omaan systeemiin osavaikutuskertoimeksi aikaisemmin tekemäni "olosuhde pisteytyksen". Laskee kerrointa ottaen huomioon tuulen suunnan ja nopeuden (kylmin suunta= suurin kerroin) , ilmanpainemuutoksen, ulkolämpötilan ja sisälämpötilan.
 

Luukku

Vakionaama
  • Keskustelun aloittaja
  • #4
Aika tasaisesti puksuttavat.
 

Liitteet

  • IMG_6791.jpeg
    IMG_6791.jpeg
    63,1 KB · Katsottu: 20
  • IMG_6790.jpeg
    IMG_6790.jpeg
    55,3 KB · Katsottu: 21

Luukku

Vakionaama
  • Keskustelun aloittaja
  • #5
Eilis illasta pakkanen lauhtunut niin ei havaittavaa ylilämmitystä.
Lämpösensoreissa lukee keskiarvo, koska useampi mittauspiste. Tavoite 22.
 

Liitteet

  • IMG_6793.jpeg
    IMG_6793.jpeg
    65 KB · Katsottu: 23

Kaimo Ärräpää

Pumppauksen suomenmestari v. 2041
No tässä olisi tekoälyn osin söhläämää koodia. Miltä näyttää? En itse tosiaan voi toistaiseksi testailla, kun ei ole laitteita.

Tässä on kolme osaa, tuo kontrolleri, konfiguraatio (ilmeisesti GUI:ta ja viikkoaikataulua varten) ja lisäksi tuo viikkoaikataulun kopiointiskripti. Voi olla joku helpompikin tapa tuohon viikkoaikataulun toteutukseen päiväkopiointeineen, mutta ei tähän hätään ole niin tarkkaa tietoa, mitä siellä on jo saatavilla.

Eli lisäyksiä: ulkolämpötilan valinnaisuus, puhallustilaan siirtyminen, jos alin DC ylilämmittää (onko edes tarpeellinen, "jaksaako" pienimmällä DC:llä edes lämmittää?), ja viikkoaikataulun lisäys.

Ei todellakaan ole varmuutta, että edes toimii. Voi olla, että toimisi, mutta voi olla ettei. Nimittäin on kokemusta tekoälyn kanssa koodin vääntämisestä. Lähinnä kylläkin vain C-puolelta (Arduino), jossa helpotti, kun suunnilleen alkoi ymmärtää, mitä missäkin kohdassa edes tehdään. :)

EDIT: Ainakaan viikkoaikataulun osalta tuskin toimii, koska tuo viikonpäivien kaikki paikat kirjoittaa tuohon...
EDIT2: Muokattu, mutta ei välttämättä parempaan suuntaan noin toimivuuden(kaan) kannalta. 🫣

Python:
{#
  Advanced Daikin AC Controller with Weekly Schedule
  Features:
  1. Weekly schedule with up to 6 temperature points per day
  2. GUI adjustable parameters
  3. Automatic fan-only mode when overheating
  4. Outside temperature compensation (optional)
  5. Global enable/disable switch
#}

{# ============================================================================
   SECTION 1: INPUT VARIABLES
   ============================================================================ #}

{# Core temperature sensors #}
{% set T = states('sensor.sisälämpötila') | float(0) %}
{% set Tset = states('input_number.tavoitelampo') | float(0) %}
{% set d1 = states('sensor.1h_derivaatta') | float(0) %}
{% set d05 = states('sensor.0,5h_derivaatta') | float(0) %}
{% set prev_demand = states('input_number.demand_locked') | float(0) %}
{% set T_out = states('sensor.ulkolampotila') | float(0) %}

{# Control system switches #}
{% set system_enabled = is_state('input_boolean.ac_control_enabled', 'on') %}
{% set outside_comp_enabled = is_state('input_boolean.outside_temp_compensation', 'on') %}

{# Daikin AC mode and fan settings from GUI #}
{% set scheduled_mode = states('input_select.ac_mode') %}
{% set scheduled_fan = states('input_select.fan_power') %}

{# Current AC state #}
{% set current_ac_mode = states('climate.daikin_ac') | default('off') %}

{# ============================================================================
   SECTION 2: WEEKLY SCHEDULE HANDLING
   ============================================================================ #}

{#
  Weekly schedule structure:
  - Each day has up to 6 time slots (input_datetime)
  - Each slot has a corresponding temperature (input_number)
  - Format: day_slotX_time, day_slotX_temp (e.g., monday_slot1_time)
#}

{# Get current day and time #}
{% set now_time = now().time() %}
{% set weekday = now().weekday() %} {# 0=Monday, 6=Sunday #}

{# Map weekday number to day name #}
{% set day_names = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'] %}
{% set current_day = day_names[weekday] %}

{# Function to find current temperature from schedule #}
{% macro get_scheduled_temp(day) %}
  {% set slots = range(1, 7) %}
  {% set last_temp = states('input_number.' ~ day ~ '_slot6_temp') | float(21) %}
  {% set scheduled_temp = last_temp %}
 
  {% for slot in slots %}
    {% set slot_time = states('input_datetime.' ~ day ~ '_slot' ~ slot ~ '_time') %}
    {% if slot_time != 'unknown' and slot_time != 'unavailable' %}
      {% set slot_time_obj = strptime(slot_time, '%H:%M:%S').time() %}
      {% if now_time >= slot_time_obj %}
        {% set scheduled_temp = states('input_number.' ~ day ~ '_slot' ~ slot ~ '_temp') | float(21) %}
      {% endif %}
    {% endif %}
  {% endfor %}
 
  {{ scheduled_temp }}
{% endmacro %}

{# Get target temperature from schedule #}
{% set scheduled_Tset = get_scheduled_temp(current_day) %}

{# Apply scheduled temperature if schedule is enabled #}
{% if is_state('input_boolean.schedule_enabled', 'on') %}
  {% set Tset = scheduled_Tset %}
{% endif %}

{# ============================================================================
   SECTION 3: OUTSIDE TEMPERATURE COMPENSATION
   ============================================================================ #}

{% if outside_comp_enabled %}
  {#
    Outside temperature compensation gain:
    - Above +5°C: 1.0 (normal)
    - 0°C to -5°C: 1.2 (increased heating)
    - Below -5°C: 1.4 (maximum heating)
  #}
  {% set gain = 1.4 if T_out < -5 else 1.2 if T_out < 0 else 1.0 %}
{% else %}
  {% set gain = 1.0 %}
{% endif %}

{# ============================================================================
   SECTION 4: CORE CONTROL LOGIC
   ============================================================================ #}

{# Only proceed if system is enabled #}
{% if system_enabled %}
  {# --- 1) Base demand from temperature error --- #}
  {% set e = T - Tset %}
  {% set N_base = 40 + (-e * 50 * gain) %}
  {% set N_base = [100, [40, N_base] | max] | min %}
 
  {# --- 2) 1-hour derivative bias --- #}
  {% set offset_1h = 5 if d1 < -0.05 else -5 if d1 > 0.05 else 0 %}
  {% set N_trend = N_base + offset_1h %}
  {% set N_trend = [100, [40, N_trend] | max] | min %}
 
  {# --- 3) Round to 5% increments --- #}
  {% set N_step = ((N_trend / 5) | round(0, 'ceil') * 5) %}
  {% set N_step = [100, [40, N_step] | max] | min %}
 
  {# --- 4) Deadband and time hysteresis --- #}
  {% set diff = (N_step - prev_demand) | abs %}
  {% set age = (now() - states.input_number.demand_locked.last_changed).total_seconds() %}
 
  {% if diff >= 10 or age > 900 %}
    {% set output_demand = N_step %}
  {% else %}
    {% set output_demand = prev_demand %}
  {% endif %}
 
  {# ==========================================================================
     SECTION 5: AUTOMATIC FAN-ONLY MODE
     ========================================================================== #}
 
  {#
    Switch to fan-only mode when:
    1. Minimum demand (40%) is active
    2. Temperature is 0.5°C above target
    3. System is not already in fan-only mode
 
    Switch back to scheduled mode when:
    1. Temperature drops to target or below
  #}
 
  {% if output_demand <= 40 and (T - Tset) > 0.5 %}
    {# Overheating detected - switch to fan-only #}
    {% if current_ac_mode != 'fan_only' %}
      {# Store the scheduled mode before switching #}
      {% set stored_mode = scheduled_mode %}
      {% do state.set('input_text.last_ac_mode', stored_mode) %}
 
      {# Set AC to fan-only mode #}
      {% do service.call('climate', 'set_hvac_mode', {
        'entity_id': 'climate.daikin_ac',
        'hvac_mode': 'fan_only'
      }) %}
 
      {# Set fan to auto in fan-only mode #}
      {% do service.call('climate', 'set_fan_mode', {
        'entity_id': 'climate.daikin_ac',
        'fan_mode': 'auto'
      }) %}
    {% endif %}
 
    {# Set demand to 0% in fan-only mode #}
    {% set output_demand = 0 %}
 
  {% elif (T - Tset) <= 0 and is_state('input_text.last_ac_mode', 'heat') %}
    {# Temperature back to normal - restore heating mode #}
    {% if current_ac_mode != 'heat' %}
      {% do service.call('climate', 'set_hvac_mode', {
        'entity_id': 'climate.daikin_ac',
        'hvac_mode': 'heat'
      }) %}
 
      {# Restore scheduled fan power #}
      {% do service.call('climate', 'set_fan_mode', {
        'entity_id': 'climate.daikin_ac',
        'fan_mode': scheduled_fan
      }) %}
    {% endif %}
  {% endif %}
 
  {# ==========================================================================
     SECTION 6: APPLY DAIKIN SETTINGS
     ========================================================================== #}
 
  {# Apply scheduled mode if not in automatic fan-only mode #}
  {% if (T - Tset) <= 0.5 and current_ac_mode != 'fan_only' %}
    {% if current_ac_mode != scheduled_mode %}
      {% do service.call('climate', 'set_hvac_mode', {
        'entity_id': 'climate.daikin_ac',
        'hvac_mode': scheduled_mode
      }) %}
    {% endif %}
 
    {# Apply scheduled fan power #}
    {% set current_fan = state_attr('climate.daikin_ac', 'fan_mode') | default('auto') %}
    {% if current_fan != scheduled_fan %}
      {% do service.call('climate', 'set_fan_mode', {
        'entity_id': 'climate.daikin_ac',
        'fan_mode': scheduled_fan
      }) %}
    {% endif %}
  {% endif %}
 
  {# ==========================================================================
     SECTION 7: OUTPUT FINAL DEMAND
     ========================================================================== #}
 
  {{ output_demand }}
 
{% else %}
  {# System disabled - output 0% demand #}
  {{ 0 }}
{% endif %}

{# ============================================================================
   SECTION 8: GUI HELPER AUTOMATIONS (separate automations in YAML)
   ============================================================================ #}

{#
  The following automations should be created in automations.yaml:
 
  1. Copy day schedule button:
 
  automation:
    - alias: "Copy Day Schedule"
      trigger:
        platform: state
        entity_id: input_button.copy_schedule
      action:
        service: python_script.copy_schedule
        data:
          source_day: "{{ states('input_select.source_day') }}"
          target_days: "{{ states('input_select.target_days') }}"
 
  2. Update target temperature from schedule:
 
  automation:
    - alias: "Update Target Temperature from Schedule"
      trigger:
        platform: time
        minutes: '/10'  # Every 10 minutes
      action:
        service: input_number.set_value
        data_template:
          entity_id: input_number.tavoitelampo
          value: "{{ scheduled_Tset }}"
 
  3. Reset fan-only mode when system disabled:
 
  automation:
    - alias: "Reset AC Mode on System Disable"
      trigger:
        platform: state
        entity_id: input_boolean.ac_control_enabled
        to: 'off'
      action:
        service: climate.set_hvac_mode
        data:
          entity_id: climate.daikin_ac
          hvac_mode: "{{ scheduled_mode }}"
#}


Viikkoaikataulu (configuration.yaml):

Python:
# ============================================================================
# AC Controller - ALL Required Helpers
# Add this entire section to your configuration.yaml
# ============================================================================

input_boolean:
  # Core system controls
  ac_control_enabled:
    name: "AC Control Enabled"
    icon: mdi:power
  schedule_enabled:
    name: "Schedule Enabled"
    icon: mdi:calendar-clock
  outside_temp_compensation:
    name: "Outside Temperature Compensation"
    icon: mdi:thermometer

input_select:
  # AC mode and fan settings
  ac_mode:
    name: "AC Mode"
    options:
      - "heat"
      - "cool"
      - "fan_only"
      - "dry"
    icon: mdi:air-conditioner
  fan_power:
    name: "Fan Power"
    options:
      - "auto"
      - "low"
      - "medium"
      - "high"
    icon: mdi:fan
  # Schedule copy helpers
  source_day:
    name: "Copy From Day"
    options:
      - "Monday"
      - "Tuesday"
      - "Wednesday"
      - "Thursday"
      - "Friday"
      - "Saturday"
      - "Sunday"
    icon: mdi:calendar-arrow-right
  target_days:
    name: "Copy To Days"
    options:
      - "All Weekdays"
      - "All Days"
      - "Monday to Friday"
      - "Weekend"
    icon: mdi:calendar-multiple

input_number:
  # Core temperature and demand
  tavoitelampo:
    name: "Target Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    icon: mdi:thermometer
  demand_locked:
    name: "Demand Output"
    min: 0
    max: 100
    step: 5
    unit_of_measurement: "%"
    icon: mdi:gauge
 
  # ==================== MONDAY TEMPERATURES ====================
  monday_slot1_temp:
    name: "Monday Slot 1 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  monday_slot2_temp:
    name: "Monday Slot 2 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  monday_slot3_temp:
    name: "Monday Slot 3 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  monday_slot4_temp:
    name: "Monday Slot 4 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  monday_slot5_temp:
    name: "Monday Slot 5 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  monday_slot6_temp:
    name: "Monday Slot 6 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider

  # ==================== TUESDAY TEMPERATURES ====================
  tuesday_slot1_temp:
    name: "Tuesday Slot 1 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  tuesday_slot2_temp:
    name: "Tuesday Slot 2 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  tuesday_slot3_temp:
    name: "Tuesday Slot 3 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  tuesday_slot4_temp:
    name: "Tuesday Slot 4 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  tuesday_slot5_temp:
    name: "Tuesday Slot 5 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  tuesday_slot6_temp:
    name: "Tuesday Slot 6 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider

  # ==================== WEDNESDAY TEMPERATURES ====================
  wednesday_slot1_temp:
    name: "Wednesday Slot 1 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  wednesday_slot2_temp:
    name: "Wednesday Slot 2 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  wednesday_slot3_temp:
    name: "Wednesday Slot 3 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  wednesday_slot4_temp:
    name: "Wednesday Slot 4 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  wednesday_slot5_temp:
    name: "Wednesday Slot 5 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  wednesday_slot6_temp:
    name: "Wednesday Slot 6 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider

  # ==================== THURSDAY TEMPERATURES ====================
  thursday_slot1_temp:
    name: "Thursday Slot 1 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  thursday_slot2_temp:
    name: "Thursday Slot 2 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  thursday_slot3_temp:
    name: "Thursday Slot 3 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  thursday_slot4_temp:
    name: "Thursday Slot 4 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  thursday_slot5_temp:
    name: "Thursday Slot 5 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  thursday_slot6_temp:
    name: "Thursday Slot 6 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider

  # ==================== FRIDAY TEMPERATURES ====================
  friday_slot1_temp:
    name: "Friday Slot 1 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  friday_slot2_temp:
    name: "Friday Slot 2 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  friday_slot3_temp:
    name: "Friday Slot 3 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  friday_slot4_temp:
    name: "Friday Slot 4 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  friday_slot5_temp:
    name: "Friday Slot 5 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  friday_slot6_temp:
    name: "Friday Slot 6 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider

  # ==================== SATURDAY TEMPERATURES ====================
  saturday_slot1_temp:
    name: "Saturday Slot 1 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  saturday_slot2_temp:
    name: "Saturday Slot 2 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  saturday_slot3_temp:
    name: "Saturday Slot 3 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  saturday_slot4_temp:
    name: "Saturday Slot 4 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  saturday_slot5_temp:
    name: "Saturday Slot 5 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  saturday_slot6_temp:
    name: "Saturday Slot 6 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider

  # ==================== SUNDAY TEMPERATURES ====================
  sunday_slot1_temp:
    name: "Sunday Slot 1 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  sunday_slot2_temp:
    name: "Sunday Slot 2 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  sunday_slot3_temp:
    name: "Sunday Slot 3 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  sunday_slot4_temp:
    name: "Sunday Slot 4 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  sunday_slot5_temp:
    name: "Sunday Slot 5 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider
  sunday_slot6_temp:
    name: "Sunday Slot 6 Temperature"
    min: 15
    max: 30
    step: 0.5
    unit_of_measurement: "°C"
    mode: slider

input_text:
  last_ac_mode:
    name: "Last AC Mode"
    icon: mdi:information

input_button:
  copy_schedule:
    name: "Copy Schedule"
    icon: mdi:content-copy

input_datetime:
  # ==================== MONDAY TIMES ====================
  monday_slot1_time:
    name: "Monday Slot 1 Time"
    has_time: true
    has_date: false
  monday_slot2_time:
    name: "Monday Slot 2 Time"
    has_time: true
    has_date: false
  monday_slot3_time:
    name: "Monday Slot 3 Time"
    has_time: true
    has_date: false
  monday_slot4_time:
    name: "Monday Slot 4 Time"
    has_time: true
    has_date: false
  monday_slot5_time:
    name: "Monday Slot 5 Time"
    has_time: true
    has_date: false
  monday_slot6_time:
    name: "Monday Slot 6 Time"
    has_time: true
    has_date: false

  # ==================== TUESDAY TIMES ====================
  tuesday_slot1_time:
    name: "Tuesday Slot 1 Time"
    has_time: true
    has_date: false
  tuesday_slot2_time:
    name: "Tuesday Slot 2 Time"
    has_time: true
    has_date: false
  tuesday_slot3_time:
    name: "Tuesday Slot 3 Time"
    has_time: true
    has_date: false
  tuesday_slot4_time:
    name: "Tuesday Slot 4 Time"
    has_time: true
    has_date: false
  tuesday_slot5_time:
    name: "Tuesday Slot 5 Time"
    has_time: true
    has_date: false
  tuesday_slot6_time:
    name: "Tuesday Slot 6 Time"
    has_time: true
    has_date: false

  # ==================== WEDNESDAY TIMES ====================
  wednesday_slot1_time:
    name: "Wednesday Slot 1 Time"
    has_time: true
    has_date: false
  wednesday_slot2_time:
    name: "Wednesday Slot 2 Time"
    has_time: true
    has_date: false
  wednesday_slot3_time:
    name: "Wednesday Slot 3 Time"
    has_time: true
    has_date: false
  wednesday_slot4_time:
    name: "Wednesday Slot 4 Time"
    has_time: true
    has_date: false
  wednesday_slot5_time:
    name: "Wednesday Slot 5 Time"
    has_time: true
    has_date: false
  wednesday_slot6_time:
    name: "Wednesday Slot 6 Time"
    has_time: true
    has_date: false

  # ==================== THURSDAY TIMES ====================
  thursday_slot1_time:
    name: "Thursday Slot 1 Time"
    has_time: true
    has_date: false
  thursday_slot2_time:
    name: "Thursday Slot 2 Time"
    has_time: true
    has_date: false
  thursday_slot3_time:
    name: "Thursday Slot 3 Time"
    has_time: true
    has_date: false
  thursday_slot4_time:
    name: "Thursday Slot 4 Time"
    has_time: true
    has_date: false
  thursday_slot5_time:
    name: "Thursday Slot 5 Time"
    has_time: true
    has_date: false
  thursday_slot6_time:
    name: "Thursday Slot 6 Time"
    has_time: true
    has_date: false

  # ==================== FRIDAY TIMES ====================
  friday_slot1_time:
    name: "Friday Slot 1 Time"
    has_time: true
    has_date: false
  friday_slot2_time:
    name: "Friday Slot 2 Time"
    has_time: true
    has_date: false
  friday_slot3_time:
    name: "Friday Slot 3 Time"
    has_time: true
    has_date: false
  friday_slot4_time:
    name: "Friday Slot 4 Time"
    has_time: true
    has_date: false
  friday_slot5_time:
    name: "Friday Slot 5 Time"
    has_time: true
    has_date: false
  friday_slot6_time:
    name: "Friday Slot 6 Time"
    has_time: true
    has_date: false

  # ==================== SATURDAY TIMES ====================
  saturday_slot1_time:
    name: "Saturday Slot 1 Time"
    has_time: true
    has_date: false
  saturday_slot2_time:
    name: "Saturday Slot 2 Time"
    has_time: true
    has_date: false
  saturday_slot3_time:
    name: "Saturday Slot 3 Time"
    has_time: true
    has_date: false
  saturday_slot4_time:
    name: "Saturday Slot 4 Time"
    has_time: true
    has_date: false
  saturday_slot5_time:
    name: "Saturday Slot 5 Time"
    has_time: true
    has_date: false
  saturday_slot6_time:
    name: "Saturday Slot 6 Time"
    has_time: true
    has_date: false

  # ==================== SUNDAY TIMES ====================
  sunday_slot1_time:
    name: "Sunday Slot 1 Time"
    has_time: true
    has_date: false
  sunday_slot2_time:
    name: "Sunday Slot 2 Time"
    has_time: true
    has_date: false
  sunday_slot3_time:
    name: "Sunday Slot 3 Time"
    has_time: true
    has_date: false
  sunday_slot4_time:
    name: "Sunday Slot 4 Time"
    has_time: true
    has_date: false
  sunday_slot5_time:
    name: "Sunday Slot 5 Time"
    has_time: true
    has_date: false
  sunday_slot6_time:
    name: "Sunday Slot 6 Time"
    has_time: true
    has_date: false

Viikkoaikataulun kopiointi:

Python:
"""Copy schedule from one day to other days."""

"""copy_schedule.py in python_scripts folder!!!"""

def copy_schedule(source_day, target_days):
    # Map day names to lowercase
    source = source_day.lower()
 
    # Define target days based on selection
    days = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday']
 
    if target_days == "All Weekdays":
        targets = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday']
    elif target_days == "All Days":
        targets = days
    elif target_days == "Monday to Friday":
        targets = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday']
    elif target_days == "Weekend":
        targets = ['saturday', 'sunday']
    else:
        targets = []
 
    # Remove source day from targets if present
    if source in targets:
        targets.remove(source)
 
    # Copy time slots and temperatures
    for slot in range(1, 7):
        # Get source values
        time_entity = f"input_datetime.{source}_slot{slot}_time"
        temp_entity = f"input_number.{source}_slot{slot}_temp"
  
        source_time = hass.states.get(time_entity).state
        source_temp = hass.states.get(temp_entity).state
  
        # Copy to target days
        for target in targets:
            hass.services.call('input_datetime', 'set_datetime', {
                'entity_id': f"input_datetime.{target}_slot{slot}_time",
                'time': source_time
            })
      
            hass.services.call('input_number', 'set_value', {
                'entity_id': f"input_number.{target}_slot{slot}_temp",
                'value': float(source_temp)
            })
 
    # Notify user
    hass.services.call('persistent_notification', 'create', {
        'title': 'Schedule Copied',
        'message': f'Copied {source_day} schedule to {", ".join(targets).title()}'
    })

# Get parameters
source_day = data.get('source_day', 'Monday')
target_days = data.get('target_days', 'All Weekdays')

# Execute copy
copy_schedule(source_day, target_days)
 
Viimeksi muokattu:

Luukku

Vakionaama
  • Keskustelun aloittaja
  • #8
Onhan siinä koodia. HA:lla ylilämmityksen esto on aika simppeli tehdä automaatiolla, jossa only fans päälle, kun sensorin raja ylittyy jne. Myös automaatiot voi aikatauluttaa, että milloin ne on päällä, milloin pois. Mitä yksinkertaisempaa koodia niin sen parempi, lähtee helposti rönsyilemään. Tekojärkeäkin pitää välillä jarrutella, kun sillä lähtee lapasesta aika herkästi.
 

Luukku

Vakionaama
  • Keskustelun aloittaja
  • #9
12h lämpötilaheitto 0,71 astetta, vaikka keittiöstä tullut lämpökuormaa ajoittain.
Hyvin on Demand control pelittäny toistaiseksi.
 

Liitteet

  • IMG_6799.jpeg
    IMG_6799.jpeg
    19,4 KB · Katsottu: 23

Kaimo Ärräpää

Pumppauksen suomenmestari v. 2041
@Luukku , no niin, eli ainakaan tuota ylilämpöä ei kannata laittaa koodiin ollenkaan. Ei kai tuossa muuta tule äkkiseltään mieleen kuin tavoitelämmön ja puhaltimen nopeuden säädöt viikkoajastimessa.
 

Luukku

Vakionaama
Jos Home Assistantin valjastaa käyttöön niin sillä voi tehdä vaikka mitä ihan perusautomaatioilla, esim kaikki ajastushommat ja ilpin asetusten vaihtamiset. Jos ilpin ohjaus onnistuu vaikka Faikoutilla paikallisesti niin Home Assistantin ja laitteet voi laittaa omaan kotiverkkoon ja ulos nettiin voi yhteydet katkaista reitittimestä kokoajaksi tai vaikka yöksi, miten haluaa.
HA:n käyttö ns UI:llä eli visuaalisella editorilla on varsin helppoa, koodia ei tarvii osata ollenkaan.
 

Liitteet

  • IMG_6800.png
    IMG_6800.png
    201,4 KB · Katsottu: 19

Kaimo Ärräpää

Pumppauksen suomenmestari v. 2041
@Luukku , siihenhän voisi tehdä viikkoaikataulun ominaisuuksineen, jos on kerran avoin lähdekoodi. En osaa arvioida, kuinka vaikeaa sellaisen tekeminen olisi.

EDIT: Kyllähän tuo lähdekoodi varmaan löytyisi tuolta, mutta se on aika suuri paketti ja paljon eri juttuja. Ihan eri kuin jonkun 600 rivin Arduino-koodin nyhjääminen varmaan.

Lähtökohtaisesti ei sinänsä meillä olisi tarvetta HA:lle, jos ajastukset Daikin-säätöineen onnistuisi Faikoutissa.
 
Viimeksi muokattu:

Kaimo Ärräpää

Pumppauksen suomenmestari v. 2041
Joo katselin vähän sitä koodia, niin eihän sitä erkkikään jaksa alkaa selvittelemään. Pelkkä se "peruskoodi" oli jo melkein 5000 riviä pitkä. On siinä pojat tehneet hommia. Ei voi muuta kuin hattua nostaa, kaikille avoimen lähdekoodin nörteille myös. @Luukku :lle myös, koska tuo koodi saattaa täälläkin vielä joskus päätyä käyttöön.
 

Luukku

Vakionaama
Reagointi herkkyyteen täytyy olla jo tyytyväinen. Tavoite 22
 

Liitteet

  • IMG_6805.jpeg
    IMG_6805.jpeg
    71,3 KB · Katsottu: 23

Kaimo Ärräpää

Pumppauksen suomenmestari v. 2041
@Luukku , mites tuo kannattaisi muuten funtsia, jos kävisi niin, että ylilämpenisi vieläkin vaikka DC olisi alarajalla? Siirtyä puhallinmoodin HA:n automaatiolla? Tuo tilannehan tulee ainakin viikkoajastimessa vastaan joka päivä kun lämpötilaa pudotetaan yöksi . Hyvinkin saattaa tulla myös plussakeleillä kun uunia lämmitetään kuitenkin talvisin päivittäin.

Millä tavalla tuo pelittää eri pyynneillä eri vuorokauden aikoina?

Miten yhdistää viikkoajastimeen?

Sorry, voi olla tyhmiä kysymyksiä, mutta ei siis ole yhtään kokemusta HA:sta saati Faikoutista, niin kyselen nyt mahdollisesti pöljiä.
 
Viimeksi muokattu:

Luukku

Vakionaama
jos kävisi niin, että ylilämpenisi vieläkin vaikka DC olisi alarajalla? Siirtyä puhallinmoodin HA:n automaatiolla? Tuo tilannehan tulee ainakin viikkoajastimessa vastaan joka päivä kun lämpötilaa pudotetaan yöksi . Hyvinkin saattaa tulla myös plussakeleillä kun uunia lämmitetään kuitenkin talvisin päivittäin.
Puhallinmoodi tai sitten pyynti ihan alas. Ja voihan sen vaikka sammuttaa kokonaankin.
Millä tavalla tuo pelittää eri pyynneillä eri vuorokauden aikoina?
Tuossa koodissa otetaan huomioon asetettu tavoite lämpötila. Se laskee tarveohjauksen tarpeen sen ja muiden sensoriarvojen mukaan. Automaatioilla voi sitten säätää tavoitelämpöä eri aikojen mukaan miten haluaa.
Miten yhdistää viikkoajastimeen?
Automaatioilla ajastus.
 

Luukku

Vakionaama
Ylilämpenemisen eston saa kyllä sisällytettyä tuohon koodiinkin. Pitää alkaa työstämään.
Tein kuitenkin oman sensorin ylilämmitykselle, jos tavoitelämpö on +/- 0,3 astetta.
Tämä antaa arvon "pois" tai "päällä" ja sen mukaan sitten automaatio säätämään ilpin pyyntiä tai puhallusmoodia.
Koodi:
template:
  - binary_sensor:
      - name: "ILP ylilämmityksen esto"
        unique_id: ilp_override
        state: >
          {% set T = states('sensor.sisälämpötila') | float %}
          {% set Tset = states('input_number.tavoitelampo') | float %}
          {% set prev = states('binary_sensor.ilp_ylilammityksen_esto') %}
       
          {% set over = T > (Tset + 0.3) %}
          {% set under = T < (Tset - 0.3) %}

          {% if over %}
            päällä
          {% elif under %}
            pois
          {% else %}
            {{ prev }}
          {% endif %}

Automaatio:

Koodi:
alias: ILP only fan/heat
description: Only fan jos ylilämmitys päällä/pois
triggers:
  - trigger: state
    entity_id:
      - binary_sensor.ylilammityksen_esto
    to:
      - "on"
  - trigger: state
    entity_id:
      - binary_sensor.ylilammityksen_esto
    to:
      - "off"
conditions: []
actions:
  - choose:
      - conditions:
          - condition: state
            entity_id: binary_sensor.ylilammityksen_esto
            state:
              - "on"
        sequence:
          - device_id: oma laite id
            domain: climate
            entity_id: oma entity
            type: set_hvac_mode
            hvac_mode: fan_only
      - conditions:
          - condition: state
            entity_id: binary_sensor.ylilammityksen_esto
            state:
              - "off"
        sequence:
          - device_id: oma laite id
            domain: climate
            entity_id: oma entity
            type: set_hvac_mode
            hvac_mode: heat
mode: single
 
Viimeksi muokattu:

Kaimo Ärräpää

Pumppauksen suomenmestari v. 2041
Onkohan tuossa koodissa huomioitu äärimmäinen tehon tarve? Eli että DC pitäisi ilmeisesti ottaa pois päältä kun joskus tulisi sellainen tilanne, ettei DC == 100 % riitäkään?

Lisäksi, olikos jtn sellaista, että 95 --> 100 % välissä on iso pomppu? Siihen väliin kai pitäisi saada Econo ja Hiljainen ulkoyksikkö -portaat? Ehkä nuo voi sitten tehdä siellä HA:ssa, mutta mitenhän nuo sitten yhdistyisi tuon koodin kanssa? Eli jos en aivan hakoteillä nyt ole, niin ilmeisesti jos lämpötila pyrkisi laskemaan vaikka DC == 100 %, niin pitäisi kytkeä DC silloin pois? Ja millähän ehdolla nuo Econo ja Hiljainen ulkoyksikkö -tilat sitten kytkeytyisivät tuon 95 ja 100 %:n välissä?

Mitä muuten tapahtuu, jos DC == 0 %? Meneekö lämmitys pois päältä?
 
Viimeksi muokattu:

Luukku

Vakionaama
Onkohan tuossa koodissa huomioitu äärimmäinen tehon tarve? Eli että DC pitäisi ilmeisesti ottaa pois päältä kun joskus tulisi sellainen tilanne, ettei DC == 100 % riitäkään?

Lisäksi, olikos jtn sellaista, että 95 --> 100 % välissä on iso pomppu? Siihen väliin kai pitäisi saada Econo ja Hiljainen ulkoyksikkö -portaat? Ehkä nuo voi sitten tehdä siellä HA:ssa, mutta mitenhän nuo sitten yhdistyisi tuon koodin kanssa? Eli jos en aivan hakoteillä nyt ole, niin ilmeisesti jos lämpötila pyrkisi laskemaan vaikka DC == 100 %, niin pitäisi kytkeä DC silloin pois? Ja millähän ehdolla nuo Econo ja Hiljainen ulkoyksikkö -tilat sitten kytkeytyisivät tuon 95 ja 100 %:n välissä?

Mitä muuten tekee 0 % DC? Meneekö lämmitys pois päältä?
Faikoutista sitä DC:tä ei saa pois päältä. Tuo tehopomppu 95-->100 on oikeastaan hyvä, että saa tehoa tarvittaessa. Nuo aikaisemmat portaat sais olla lineaarisemmat. Mielestäni econo porras on aika tarpeeton, mutta en ole tutkinut niiden vaikutusta sen paremmin. DC:tä ei saa nollaan HA:n kautta, 30-100%. Faikoutista taitaa saada, mutta en ole testannut vielä. Äärimmäistä tehontarvetta ei ole vielä huomioitu, keskitytty DC:n säätöön. Itsellä tarkoitus, että puulämmitys tulee mukaan kovemmilla pakkasilla ja ilppiä ajetaan silti DC:n kautta vaikka 100%:lla, jos tarve on sellainen.
 

Luukku

Vakionaama
Päivitetty versio ketjun alussa, siinä on kylmäkerrointa kiristetty ja lämmityksen perustarve muuttuu ulkolämpötilan mukaan.
 

Kaimo Ärräpää

Pumppauksen suomenmestari v. 2041
@Luukku , ehkä hassu kysymys, mutta mihin ulkolämpötilaa tuossa ohjauksessa tarvitaan? Eikö sama säätötarkkuus olisi kuitenkin saavutettavissa pelkästään sisälämpötilaakin mittaamalla?

Ehkä se seikka, että ulkolämpötila alkaa laskemaan ennen kuin sisälämpötila, niin voidaan tavallaan ennakoida. Tuossa voinee käyttää ulkopömpelin mittamaa lämpötilaa eikä tartte erillistä ulkoanturia?
 

Kaimo Ärräpää

Pumppauksen suomenmestari v. 2041
@Luukku , siellä pojat korvanneet Daikinin höpöhöpöanturin sisäpömpelistä hienolla I2C-ratkaisulla. Saaneet kuulemma ±0,2 asteen säätötarkkuuden Daikinin omalla logiikalla. Eli kyllä se lämpötilasäädön ongelma taitaa puhtaasti siitä tyhmästi sijoitetusta lämpöanturista johtua. Toki tuossa aika paljon juottamista ja flashaamista ja koodaamista (kai) josta en tiedä juuri mitään, mutta Faikoutia tai HA:ta saati muuta ei käsittääkseni tarvittu.
 
Viimeksi muokattu:

Kaimo Ärräpää

Pumppauksen suomenmestari v. 2041
Kannattaisi ehkä muuten ketjun otsikkoa muokata kuvaavaksi , koska tuosta ei ehkä selviä yksinään , mitä tässä tarkoitetaan. 👍
 

Luukku

Vakionaama
ehkä hassu kysymys, mutta mihin ulkolämpötilaa tuossa ohjauksessa tarvitaan?
Siinä on niitä lämpötilakertoimia mitkä laskee sitä Gain arvoa ja vaikuttaa lopulliseen DC arvoon. Itsellä on lisäksi vielä erillinen olosuhdepisteytys sensori joka huomioi tuulen ja sen suunnan, ulkolämpötilan, sisälämpötilan ja ilmanpaineen. Ilmanpaineen nousu, kun ennustaa lämpötilan laskua talvella. Tästä pisteytyksestä tulee yksi osa Gain kertoimeen. Peruslämmön tarpeeseen lasketaan lisäksi nuo kertoimet. Tarkoituksena reagoida mahdollisimman nopeasti ja hieman ennakoivasti muuttuviin olosuhteisiin.
Nyt ei ainakaan sisällä lämpötila laskenut vaikka myrskytuuli alkaa tuivertaa nurkissa.
 

Kaimo Ärräpää

Pumppauksen suomenmestari v. 2041
@Luukku , oletko kokeillut, miten toimii pelkästään sisätilan mittauksella?

Saako systeemiin siis kuitenkin sen ulkolämpötilan Daikinin omalta anturilta? Se ainakin täällä näyttää ihan ok, kunhan laskisi siihen muutaman asteen offsetin, koska meillä se pumppu on sellaisessa koirankopissa, jossa nähtävästi on hieman lämpöisempää kuin ulkona.
 

Luukku

Vakionaama
@Luukku , oletko kokeillut, miten toimii pelkästään sisätilan mittauksella?

Saako systeemiin siis kuitenkin sen ulkolämpötilan Daikinin omalta anturilta? Se ainakin täällä näyttää ihan ok, kunhan laskisi siihen muutaman asteen offsetin, koska meillä se pumppu on sellaisessa koirankopissa, jossa nähtävästi on hieman lämpöisempää kuin ulkona.
Saa, itsellä on yhdistettynä sensorina ulkolämmölle molempien pumppujen ulkolämpötila arvo ja observatorion arvo, kun sellainen sattuu paikkakunnalla olemaan 7km päässä ja siellä aina vähän kylmempää niin kompensoi pumppujen mittaamaa.
En ole kokeillut ilman ulkolämpöä, mutta uskoisin, että toimii. Sisälämpötila ja derivaatta siitä kuitenkin ne tärkeimmät arvot. Kyllähän se sisälämpö reagoi ulkolämpöön ainakin viiveellä.
 

root

Aktiivinen jäsen
Itsellä vähän samantyyppistä viritystä, tosin ohjaan dc:tä ja pyyntiä ulkolämmön ja pörssihinnan mukaan. En ole vielä nähnyt tarpeelliseksi ottaa ennakointia (kuten sääennuste) mukaan, kun ilmalämmitys reagoi sen verran nopeasti esim. lattialämmitykseen verrattuna. Pitää vielä testata ottotehot eri dc-arvoilla, ehkä selviää sitten ainakin oman laitteen osalta miten dc 100 % eroaa (vai eroaako) siitä onko dc ollenkaan aktiivinen. En myöskään edes yritä ajaa alle 40 %:n dc:llä, kaippa siihen on syynsä ettei Onectakaan sitä mahdollista (ja täällä varoiteltiin että liian alhainen dc voisi vaarantaa kompuran voitelun)
 

Luukku

Vakionaama
Pitää vielä testata ottotehot eri dc-arvoilla, ehkä selviää sitten ainakin oman laitteen osalta miten dc 100 % eroaa (vai eroaako) siitä onko dc ollenkaan aktiivinen.
Faikoutin kehittäjä oli sitä mieltä, että DC100% = kokonaan pois eli pitäis antaa koko pumpun teho käyttöön. Econo, HUY yms pitää olla pois päältä. Kun Faikoutin extra valikosta laittaa "nodemand disable" niin DC mennee 100%:in. Kun kyselin, että mistä sen saa kokonaan pois, kun täällä välillä tarvitaan koko tehoalue käyttöön. Pakkasilla tuon pystyy sitten testaamaan. Itse en ole nähnyt nyt suurempaa tehoa kuin 1000W asetuksella DC 100%.
MQTT:llä pystyy testaamaan niitä portin S21 koodeja, mitä tapahtuu, mutta loputon suo.
 

Luukku

Vakionaama
7h sähkökatko hyvä testitilanne. Sähkökatkon aikaan DC juuri noussut 70%:in ja katkon jälkeen laskenta pyysi heti 100%. On tämä DC:n säätö automaattisesti ihan luxusta.
 

Liitteet

  • IMG_6827.jpeg
    IMG_6827.jpeg
    67,4 KB · Katsottu: 21

Luukku

Vakionaama
Tätähän tässä haetaan, ulkolämpötila laskee, mutta sisällä ei laske. Ja pumpun säätöihin ei tarvii itse koskea.
 

Liitteet

  • IMG_6829.jpeg
    IMG_6829.jpeg
    98 KB · Katsottu: 25

Luukku

Vakionaama
v.28.12.25
Trendikorjausta rajoitettu ylilämpötilanteessa ja ulkolämpötilasta riippuvaa minimiä lievennetty.
Uunin lämmitys aiheutti lievää ylilämpöä. Nosti DC:tä 5% turhaan, kun 40% riittää. Tuosta ennakointikertoimesta pitää laittaa koodi myös, sehän on osa tätä kokonaisuutta.
Koodi:
{% set T = states('sensor.sisälämpötila') | float(0) %}
{% set Tset = states('input_number.tavoitelampo') | float(0) %}
{% set d1 = states('sensor.1h_derivaatta') | float(0) %}
{% set d05 = states('sensor.0,5h_derivaatta') | float(0) %}
{% set prev = states('input_number.demand_locked') | float(0) %}
{% set T_out = states('sensor.ulkolampotila') | float(0) %}

{# --- 0) Kylmäkerroin ulkolämpötilasta --- #}
{% set gain_base =
     2.0 if T_out < -5 else
     1.5 if T_out < 2 else
     1.0 %}

{# --- 0b) Ennakointikerroin lisätekijäksi rivit --- #}
{% set preheat = states('sensor.lammityksen_ennakointi_kerroin') | float(1.0) %}
{% set preheat_gain = [1.9, [0.3, preheat] | max] | min %}

{# --- Lopullinen gain --- #}
{% set gain = gain_base * preheat_gain * 1.1 %}

{# --- 0) Ulkolämpötilasta riippuva minimi --- #}
{% set Tout = states('sensor.ulkolampotila_keskiarvo_daikin') | float(5) %}

{% if Tout >= 4 %}
  {% set N_min = 20 %}
{% elif Tout >= 2 %}
  {% set N_min = 25 %}
{% elif Tout >= 0 %}
  {% set N_min = 30 %}
{% elif Tout >= -5 %}
  {% set N_min = 40 %}
{% else %}
  {% set N_min = 50 %}
{% endif %}

{# --- 1) Perustarve sisälämpötilavirheestä --- #}
{% set e = T - Tset %}
{% if e | abs < 0.05 %}
  {% set e = 0 %}
{% endif %}

{% set N_base = 50 + (-e * 100 * gain) %}
{% set N_base = [100, [N_min, N_base] | max] | min %}

{# --- 2) 1h derivaatan bias --- #}
{% set offset_1h =
     5 if d1 < -0.05 else
    -5 if d1 >  0.1 else
     0 %}

{# --- 2.5) Trendin hillintä ylilämmössä --- #}
{% if e > 0 and d1 <= 0 %}
  {% set offset_1h = 0 %}
{% endif %}

{# --- 2b) Trendikorjattu ohjaus --- #}
{% set N_trend = N_base + offset_1h %}
{% set N_trend = [100, [40, N_trend] | max] | min %}

{# --- 3) Pyöristys 1 % portaisiin --- #}
{% set N_step = N_trend | round(0) %}
{% set N_step = [100, [40, N_step] | max] | min %}

{# --- 4) Deadband + aikahystereesi --- #}
{% set diff = (N_step - prev) | abs %}
{% set age = (now() - states.input_number.demand_locked.last_changed).total_seconds() %}

{% if diff >= 5 or age > 600 %}
  {{ N_step }}
{% else %}
  {{ prev }}
{% endif %}
 
Viimeksi muokattu:

Luukku

Vakionaama
Ennakointikerroin pisteytysjärjestelmä.
Koodi:
# Ennakointikerroin pisteytysjärjestelmä
template:
  sensor:

    # Ulkolämpötilan pisteytys
    - name: "Lampotilan pisteytys"
      state: >
        {% set dT = states('sensor.ulkolampo_derivaatta') | float(0) %}
        {# negatiivinen dT = lämpötila laskee → positiivinen piste #}
        {% set score = (0 - dT) %}
        {{ [score, 0] | max | round(3) }}

    # Ilmanpaine pisteytys
    - name: "Ilmanpaine pisteytys"
      state: >
        {% set dP = states('sensor.ilmanpaine_derivaatta') | float(0) %}
        {# positiivinen dP = paine nousee → kylmenee → pisteitä #}
        {{ [dP, 0] | max | round(3) }}

    # Sisälämpötila ja kalibrointi
    - name: "Sisalampotila pisteytys"
      state: >
        {% set Ti = states('sensor.alakerta_lampotila_keskiarvo') | float(0) %}
        {% set kerroin = states('input_number.sisalampo_kalibrointi') | float(1) %}
        {% set Ti_score = (22 - Ti) * 0.5 * kerroin %}
        {{ Ti_score | round(3) }}

    # Tuulen vaikutus suuntakertoimilla
    - name: "Tuuli fasadi pisteytys"
      state: >
        {% set s = states('sensor.wind_direction') %}
        {% set map = {
          'N': 0.95,
          'NE': 1.00,
          'E': 0.95,
          'NW': 0.6,
          'W': 0.5,
          'SE': 0.4,
          'SW': 0.3,
          'S': 0.3
        } %}
        {% set wfac = map.get(s, 0.5) %}
        {% set v = states('sensor.wind_speed') | float(0) %}
        {% set wnorm = [v / 10, 1] | min %}
        {{ (wfac * wnorm) | round(3) }}

    # Lopullinen ennakointikerroin LDC:lle
    - name: "Ennakointikerroin lopullinen"
      state: >
        {% set t = states('sensor.lampotilan_pisteytys') | float(0) %}
        {% set p = states('sensor.ilmanpaine_pisteytys') | float(0) %}
        {% set ti = states('sensor.sisalampotila_pisteytys') | float(0) %}
        {% set wfac = states('sensor.tuuli_fasadi_pisteytys') | float(0) %}
        {% set wmult = states('input_number.tuulikerroin') | float(1.0) %}
        {{ (t + p + ti * 1.2 + wfac * wmult) | round(3) }}
 

Luukku

Vakionaama
Tässä vähän käppyrää toiminnasta.
Eli tuossa ennen klo 10 alkanut preheat ( ennakointikertoimen pisteytys, ulkoiset tekijät) antaa nousevaa kerrointa laskentaan, koska ulkona kylmenee ja tuulee. Demand trendi lähtenyt laskemaan suurempaa pyyntiä demandille. Todellinen demand kuitenkin isompana annettu Faikoutille, koska muutos edelliseen demandiin riittävän iso >5% ja edellisestä muutoksesta >10 min.
Edit: tätä voi soveltaen käyttää vaikka ilman Faikoutia pyynnin muutokseen ilmojen kylmetessä ja toisinpäin.
 

Liitteet

  • Gain.jpg
    Gain.jpg
    33,6 KB · Katsottu: 14
Viimeksi muokattu:

Kaimo Ärräpää

Pumppauksen suomenmestari v. 2041
@Luukku , ehdottaisin ystävällisesti, että aloitusviestissä voisi kertoa hieman, mikä tämä LDC on. Toki kyllähän täällä kävijöistä moni jo sen saattaa tietääkin, mutta on niitä uusiakin aina välillä. Esimerkiksi minä. En olisi osannut arvata, jos en tiennyt jo ennalta, mitä tässä ketjussa tehdään. Voi olla, ettei aloitusviestiä välttämättä pysty enää muokkaamaankaan. :)
 

Luukku

Vakionaama
@Luukku , ehdottaisin ystävällisesti, että aloitusviestissä voisi kertoa hieman, mikä tämä LDC on. Toki kyllähän täällä kävijöistä moni jo sen saattaa tietääkin, mutta on niitä uusiakin aina välillä. Esimerkiksi minä. En olisi osannut arvata, jos en tiennyt jo ennalta, mitä tässä ketjussa tehdään. Voi olla, ettei aloitusviestiä välttämättä pysty enää muokkaamaankaan. :)
Tällä siis ohjataan Daikinin ilpin tarveohjausta Faikout lisäosan kautta. Template sensori laskee tarveohjauksen tarpeen huomioiden erillisen sensorin laskeman kertoimen ( T-out, T-in, tuuli ja sen suunta) sekä omassa sensorissaan olevien kertoimien perusteella tarveohjauksen määrän. Sensori sisältää myös hystereesit ettei säätö pumppaa kokoajan. Uusimpaan versioon tuli myös sulatuksen jälkeinen rajoitus tarveohjaukselle ettei pumppu ryntää, kun tuo Faikoutin DC100% näköjään antaa tosiaan täyden kompressoritehon tarvittaessa. Ryntäyksen jälkeen nämä Daikinit heittää herkästi katkolle.
Periaatteena tehdä "yksinkertainen" muutaman sensorin systeemi, mutta noita apusensoreita vaan tuntuu tulevan lisää. Pääohjaus kuitenkin yhdellä sensorilla.
"Nuubie" mä näissä olen ja osaavammat varmaan naureskelee partaansa, mutta kuhan värkkäilen.

Edit: Ylläpito voi siirtää tämän tonne ylös, kun alkuviestiä ei anna muokata.
 
Viimeksi muokattu:
Back
Ylös Bottom