- alias: Solcast - Raport poranny
  description: Dzienny raport o 7:00
  trigger:
  - platform: time
    at: 07:00:00
  action:
  - service: notify.persistent_notification
    data:
      title: ☀️ Prognoza PV
      message: 'Dziś: {{ states(''sensor.solcast_pv_forecast_prognoza_na_dzisiaj'') }} kWh

        Jutro: {{ states(''sensor.solcast_pv_forecast_prognoza_na_jutro'') }} kWh

        Bateria: {{ states(''sensor.inverter_deye_battery'') }}%

        '
  mode: single

- alias: Solcast G12W - Ustaw ładowanie nocne
  id: g12w_ustaw_ladowanie_nocne
  description: >
    20:30 Pn-Czw: Solcast-based target SOC dla nocnego ładowania 22:00-06:00.
    target_soc = min(100, max(40, (zużycie_16h - pv_jutro) / 143.36 + 10)).
    Jeśli prognoza < 3 kWh: włącza też Program 4 (13:00-15:00 ładowanie dzienne).
    Brak warunku SOC - zawsze konfiguruje programy falownika.
    Pojemność: 14336 Wh (280Ah * 51.2V LFP).
  trigger:
  - platform: time
    at: '20:30:00'
  condition:
  - condition: time
    weekday:
    - mon
    - tue
    - wed
    - thu
  action:
  - service: switch.turn_on
    target:
      entity_id: switch.inverter_deye_battery_grid_charging
  - service: select.select_option
    target:
      entity_id: select.inverter_deye_energy_pattern
    data:
      option: Load First
  - service: number.set_value
    target:
      entity_id: number.inverter_deye_battery_grid_charging_current
    data:
      value: 80
  # Program 1: 22:00 - start nocnego ładowania
  - service: time.set_value
    target:
      entity_id: time.inverter_deye_program_1_time
    data:
      time: '22:00:00'
  - service: select.select_option
    target:
      entity_id: select.inverter_deye_program_1_charging
    data:
      option: Grid
  - service: number.set_value
    target:
      entity_id: number.inverter_deye_program_1_soc
    data:
      value: >
        {%- set pv_wh = states('sensor.solcast_pv_forecast_prognoza_na_jutro') | float(0) * 1000 -%}
        {%- set today_kwh = states('sensor.inverter_deye_today_load_consumption') | float(0) -%}
        {%- set elapsed_h = [now().hour + now().minute / 60.0, 2.0] | max -%}
        {%- set load_w = [(today_kwh * 1000 / elapsed_h) | int, 800] | max -%}
        {%- set net_wh = [load_w * 16 - pv_wh, 0] | max -%}
        {{ [[net_wh / 143.36 + 10, 40] | max, 100] | min | int }}
  # Program 2: 00:00 - kontynuacja
  - service: time.set_value
    target:
      entity_id: time.inverter_deye_program_2_time
    data:
      time: '00:00:00'
  - service: select.select_option
    target:
      entity_id: select.inverter_deye_program_2_charging
    data:
      option: Grid
  - service: number.set_value
    target:
      entity_id: number.inverter_deye_program_2_soc
    data:
      value: >
        {%- set pv_wh = states('sensor.solcast_pv_forecast_prognoza_na_jutro') | float(0) * 1000 -%}
        {%- set today_kwh = states('sensor.inverter_deye_today_load_consumption') | float(0) -%}
        {%- set elapsed_h = [now().hour + now().minute / 60.0, 2.0] | max -%}
        {%- set load_w = [(today_kwh * 1000 / elapsed_h) | int, 800] | max -%}
        {%- set net_wh = [load_w * 16 - pv_wh, 0] | max -%}
        {{ [[net_wh / 143.36 + 10, 40] | max, 100] | min | int }}
  # Program 3: 06:00 - koniec nocnego ładowania
  - service: time.set_value
    target:
      entity_id: time.inverter_deye_program_3_time
    data:
      time: '06:00:00'
  - service: select.select_option
    target:
      entity_id: select.inverter_deye_program_3_charging
    data:
      option: Disabled
  - service: number.set_value
    target:
      entity_id: number.inverter_deye_program_3_soc
    data:
      value: 15
  # Program 4: Grid jeśli bardzo pochmurnie (<3 kWh), Disabled jeśli jest PV
  - choose:
      - conditions:
          - condition: numeric_state
            entity_id: sensor.solcast_pv_forecast_prognoza_na_jutro
            below: 3
        sequence:
          - service: time.set_value
            target:
              entity_id: time.inverter_deye_program_4_time
            data:
              time: '13:00:00'
          - service: select.select_option
            target:
              entity_id: select.inverter_deye_program_4_charging
            data:
              option: Grid
          - service: number.set_value
            target:
              entity_id: number.inverter_deye_program_4_soc
            data:
              value: 100
    default:
      - service: time.set_value
        target:
          entity_id: time.inverter_deye_program_4_time
        data:
          time: '13:00:00'
      - service: select.select_option
        target:
          entity_id: select.inverter_deye_program_4_charging
        data:
          option: Disabled
      - service: number.set_value
        target:
          entity_id: number.inverter_deye_program_4_soc
        data:
          value: 15
  # Program 5: 15:00 - zawsze Disabled
  - service: time.set_value
    target:
      entity_id: time.inverter_deye_program_5_time
    data:
      time: '15:00:00'
  - service: select.select_option
    target:
      entity_id: select.inverter_deye_program_5_charging
    data:
      option: Disabled
  - service: number.set_value
    target:
      entity_id: number.inverter_deye_program_5_soc
    data:
      value: 15
  # Program 6: 22:00 - duplikat Programu 1 (zabezpieczenie)
  - service: time.set_value
    target:
      entity_id: time.inverter_deye_program_6_time
    data:
      time: '22:00:00'
  - service: select.select_option
    target:
      entity_id: select.inverter_deye_program_6_charging
    data:
      option: Grid
  - service: number.set_value
    target:
      entity_id: number.inverter_deye_program_6_soc
    data:
      value: >
        {%- set pv_wh = states('sensor.solcast_pv_forecast_prognoza_na_jutro') | float(0) * 1000 -%}
        {%- set today_kwh = states('sensor.inverter_deye_today_load_consumption') | float(0) -%}
        {%- set elapsed_h = [now().hour + now().minute / 60.0, 2.0] | max -%}
        {%- set load_w = [(today_kwh * 1000 / elapsed_h) | int, 800] | max -%}
        {%- set net_wh = [load_w * 16 - pv_wh, 0] | max -%}
        {{ [[net_wh / 143.36 + 10, 40] | max, 100] | min | int }}
  - service: notify.persistent_notification
    data:
      title: '🌙 G12W: Nocne ładowanie ustawione'
      message: >
        {%- set pv_kwh = states('sensor.solcast_pv_forecast_prognoza_na_jutro') | float(0) -%}
        {%- set pv_wh = pv_kwh * 1000 -%}
        {%- set today_kwh = states('sensor.inverter_deye_today_load_consumption') | float(0) -%}
        {%- set elapsed_h = [now().hour + now().minute / 60.0, 2.0] | max -%}
        {%- set load_w = [(today_kwh * 1000 / elapsed_h) | int, 800] | max -%}
        {%- set net_wh = [load_w * 16 - pv_wh, 0] | max -%}
        {%- set target = [[net_wh / 143.36 + 10, 40] | max, 100] | min | int -%}
        {%- set soc = states('sensor.inverter_deye_battery') | int(0) -%}
        Jutro: {{ pv_kwh }} kWh PV, zużycie ~{{ (load_w * 16 / 1000) | round(1) }} kWh.
        Target SOC: {{ target }}% (SOC teraz: {{ soc }}%).
        {{ '⛈️ Dzienne ładowanie 13-15h WŁĄCZONE' if pv_kwh < 3 else '☀️ Dzienne ładowanie z PV (bez sieci)' }}
  mode: single

- alias: Solcast G12W - Piątek wyłącz (sobota tania)
  description: Piątek wieczór - wyłącz ładowanie bo sobota jest tania cała doba
  trigger:
  - platform: time
    at: '21:30:00'
  condition:
  - condition: time
    weekday:
    - fri
  action:
  - service: switch.turn_off
    target:
      entity_id: switch.inverter_deye_battery_grid_charging
  - service: select.select_option
    target:
      entity_id: select.inverter_deye_energy_pattern
    data:
      option: Battery First
  - service: notify.persistent_notification
    data:
      title: '🎉 G12W: Weekend startuje!'
      message: Sobota i niedziela = tania energia całą dobę.
  mode: single

- alias: Solcast G12W - Sobota bez zmian
  description: Sobota - niedziela też jest tania
  trigger:
  - platform: time
    at: '21:30:00'
  condition:
  - condition: time
    weekday:
    - sat
  action:
  - service: notify.persistent_notification
    data:
      title: '🎉 G12W: Niedziela też tania!'
      message: Niedziela = tania energia całą dobę.
  mode: single

- alias: Solcast G12W - Niedziela ładowanie na poniedziałek
  id: g12w_niedziela_ladowanie
  description: >
    Niedziela 20:30 - Solcast-based target SOC dla nocnego ładowania na poniedziałek.
    Używa tej samej formuły co Pn-Czw: target = min(100, max(40, (zużycie_16h - pv_jutro)/143.36 + 10)).
  trigger:
  - platform: time
    at: '20:30:00'
  condition:
  - condition: time
    weekday:
    - sun
  action:
  - service: switch.turn_on
    target:
      entity_id: switch.inverter_deye_battery_grid_charging
  - service: select.select_option
    target:
      entity_id: select.inverter_deye_energy_pattern
    data:
      option: Load First
  - service: number.set_value
    target:
      entity_id: number.inverter_deye_battery_grid_charging_current
    data:
      value: 80
  # Program 1: 22:00
  - service: time.set_value
    target:
      entity_id: time.inverter_deye_program_1_time
    data:
      time: '22:00:00'
  - service: select.select_option
    target:
      entity_id: select.inverter_deye_program_1_charging
    data:
      option: Grid
  - service: number.set_value
    target:
      entity_id: number.inverter_deye_program_1_soc
    data:
      value: >
        {%- set pv_wh = states('sensor.solcast_pv_forecast_prognoza_na_jutro') | float(0) * 1000 -%}
        {%- set today_kwh = states('sensor.inverter_deye_today_load_consumption') | float(0) -%}
        {%- set elapsed_h = [now().hour + now().minute / 60.0, 2.0] | max -%}
        {%- set load_w = [(today_kwh * 1000 / elapsed_h) | int, 800] | max -%}
        {%- set net_wh = [load_w * 16 - pv_wh, 0] | max -%}
        {{ [[net_wh / 143.36 + 10, 40] | max, 100] | min | int }}
  # Program 2: 00:00
  - service: time.set_value
    target:
      entity_id: time.inverter_deye_program_2_time
    data:
      time: '00:00:00'
  - service: select.select_option
    target:
      entity_id: select.inverter_deye_program_2_charging
    data:
      option: Grid
  - service: number.set_value
    target:
      entity_id: number.inverter_deye_program_2_soc
    data:
      value: >
        {%- set pv_wh = states('sensor.solcast_pv_forecast_prognoza_na_jutro') | float(0) * 1000 -%}
        {%- set today_kwh = states('sensor.inverter_deye_today_load_consumption') | float(0) -%}
        {%- set elapsed_h = [now().hour + now().minute / 60.0, 2.0] | max -%}
        {%- set load_w = [(today_kwh * 1000 / elapsed_h) | int, 800] | max -%}
        {%- set net_wh = [load_w * 16 - pv_wh, 0] | max -%}
        {{ [[net_wh / 143.36 + 10, 40] | max, 100] | min | int }}
  # Program 3: 06:00 - koniec nocnego
  - service: time.set_value
    target:
      entity_id: time.inverter_deye_program_3_time
    data:
      time: '06:00:00'
  - service: select.select_option
    target:
      entity_id: select.inverter_deye_program_3_charging
    data:
      option: Disabled
  - service: number.set_value
    target:
      entity_id: number.inverter_deye_program_3_soc
    data:
      value: 15
  # Program 4: Grid jeśli bardzo pochmurnie, Disabled jeśli jest PV
  - choose:
      - conditions:
          - condition: numeric_state
            entity_id: sensor.solcast_pv_forecast_prognoza_na_jutro
            below: 3
        sequence:
          - service: time.set_value
            target:
              entity_id: time.inverter_deye_program_4_time
            data:
              time: '13:00:00'
          - service: select.select_option
            target:
              entity_id: select.inverter_deye_program_4_charging
            data:
              option: Grid
          - service: number.set_value
            target:
              entity_id: number.inverter_deye_program_4_soc
            data:
              value: 100
    default:
      - service: time.set_value
        target:
          entity_id: time.inverter_deye_program_4_time
        data:
          time: '13:00:00'
      - service: select.select_option
        target:
          entity_id: select.inverter_deye_program_4_charging
        data:
          option: Disabled
      - service: number.set_value
        target:
          entity_id: number.inverter_deye_program_4_soc
        data:
          value: 15
  # Program 5: 15:00 Disabled
  - service: time.set_value
    target:
      entity_id: time.inverter_deye_program_5_time
    data:
      time: '15:00:00'
  - service: select.select_option
    target:
      entity_id: select.inverter_deye_program_5_charging
    data:
      option: Disabled
  - service: number.set_value
    target:
      entity_id: number.inverter_deye_program_5_soc
    data:
      value: 15
  # Program 6: 22:00 - duplikat Programu 1
  - service: time.set_value
    target:
      entity_id: time.inverter_deye_program_6_time
    data:
      time: '22:00:00'
  - service: select.select_option
    target:
      entity_id: select.inverter_deye_program_6_charging
    data:
      option: Grid
  - service: number.set_value
    target:
      entity_id: number.inverter_deye_program_6_soc
    data:
      value: >
        {%- set pv_wh = states('sensor.solcast_pv_forecast_prognoza_na_jutro') | float(0) * 1000 -%}
        {%- set today_kwh = states('sensor.inverter_deye_today_load_consumption') | float(0) -%}
        {%- set elapsed_h = [now().hour + now().minute / 60.0, 2.0] | max -%}
        {%- set load_w = [(today_kwh * 1000 / elapsed_h) | int, 800] | max -%}
        {%- set net_wh = [load_w * 16 - pv_wh, 0] | max -%}
        {{ [[net_wh / 143.36 + 10, 40] | max, 100] | min | int }}
  - service: notify.persistent_notification
    data:
      title: '🌙 G12W: Ładowanie na poniedziałek'
      message: >
        {%- set pv_kwh = states('sensor.solcast_pv_forecast_prognoza_na_jutro') | float(0) -%}
        {%- set today_kwh = states('sensor.inverter_deye_today_load_consumption') | float(0) -%}
        {%- set elapsed_h = [now().hour + now().minute / 60.0, 2.0] | max -%}
        {%- set load_w = [(today_kwh * 1000 / elapsed_h) | int, 800] | max -%}
        {%- set net_wh = [load_w * 16 - pv_kwh * 1000, 0] | max -%}
        {%- set target = [[net_wh / 143.36 + 10, 40] | max, 100] | min | int -%}
        {%- set soc = states('sensor.inverter_deye_battery') | int(0) -%}
        Jutro: {{ pv_kwh }} kWh PV. Target SOC: {{ target }}% (teraz: {{ soc }}%).
  mode: single

- alias: Solcast G12W - Wyłącz ładowanie 06:00
  description: Wyłącza ładowanie po taniej strefie nocnej
  trigger:
  - platform: time
    at: '06:00:00'
  condition: []
  action:
  - service: switch.turn_off
    target:
      entity_id: switch.inverter_deye_battery_grid_charging
  - service: select.select_option
    target:
      entity_id: select.inverter_deye_energy_pattern
    data:
      option: Battery First
  - service: number.set_value
    target:
      entity_id: number.inverter_deye_battery_max_charging_current
    data:
      value: 100
  - service: notify.persistent_notification
    data:
      title: '🌅 G12W: Koniec ładowania nocnego'
      message: 'SOC: {{ states(''sensor.inverter_deye_battery'') }}%. Max charging current przywrócony: 100A.'
  mode: single

- alias: Solcast G12W - Włącz ładowanie dzienne 13:00
  id: g12w_wlacz_ladowanie_dzienne
  description: >
    12:55: Solcast-based decision. Oblicza ile energii potrzeba z baterii od 15:00 do 22:00
    (droga taryfa) uwzględniając prognozę PV. Cel: target_soc_at_15 = pokrycie 15-22h.
    Jeśli PV z okna 13-15h wystarczy → Battery First. Jeśli nie → Grid charging
    tylko na brakującą ilość energii (nie zawsze 100A).
    Pojemność baterii: 14336 Wh (280Ah * 51.2V LFP).
  trigger:
  - platform: time
    at: '12:55:00'
  condition:
  - condition: time
    weekday:
    - mon
    - tue
    - wed
    - thu
    - fri
  - condition: numeric_state
    entity_id: sensor.inverter_deye_battery
    below: 100
  action:
  - choose:
      # Solcast prognoza: PV w oknie 13-15h wystarczy na target SOC → Battery First
      - conditions:
          - condition: template
            value_template: >
              {%- set pv_next_wh = states('sensor.solcast_pv_forecast_prognoza_na_nastepna_godzine') | int(0) -%}
              {%- set remaining_kwh = states('sensor.solcast_pv_forecast_pozostala_prognoza_na_dzis') | float(0) -%}
              {%- set today_kwh = states('sensor.inverter_deye_today_load_consumption') | float(0) -%}
              {%- set elapsed_h = [now().hour + now().minute / 60.0, 2.0] | max -%}
              {%- set load_w = [(today_kwh * 1000 / elapsed_h) | int, 800] | max -%}
              {%- set soc = states('sensor.inverter_deye_battery') | int(0) -%}
              {%- set pv_13_15_wh = pv_next_wh * 1.8 -%}
              {%- set bat_surplus_wh = [pv_13_15_wh * 0.94 - load_w * 2, 0] | max -%}
              {%- set pv_after_15_wh = [remaining_kwh * 1000 - pv_13_15_wh, 0] | max -%}
              {%- set needed_from_bat_wh = [load_w * 7 - pv_after_15_wh, 0] | max -%}
              {%- set target_soc = [[needed_from_bat_wh / 143.36 + 15, 20] | max, 100] | min | int -%}
              {%- set soc_at_15 = soc + bat_surplus_wh / 143.36 -%}
              {{ soc_at_15 >= target_soc }}
        sequence:
          - service: select.select_option
            target:
              entity_id: select.inverter_deye_energy_pattern
            data:
              option: Battery First
          - service: select.select_option
            target:
              entity_id: select.inverter_deye_program_4_charging
            data:
              option: Disabled
          - service: switch.turn_off
            target:
              entity_id: switch.inverter_deye_battery_grid_charging
          - service: number.set_value
            target:
              entity_id: number.inverter_deye_battery_max_charging_current
            data:
              value: >
                {%- set pv_w = states('sensor.inverter_deye_pv_power') | int(0) -%}
                {%- set today_kwh = states('sensor.inverter_deye_today_load_consumption') | float(0) -%}
                {%- set elapsed_h = [now().hour + now().minute / 60.0, 2.0] | max -%}
                {%- set load_w = [(today_kwh * 1000 / elapsed_h) | int, 800] | max -%}
                {%- set vbat = states('sensor.inverter_deye_battery_voltage') | float(51.2) -%}
                {%- set surplus_a = ((pv_w * 0.94 - load_w) / vbat) | int -%}
                {{ [5, [surplus_a, 100] | min] | max }}
          - service: notify.persistent_notification
            data:
              title: '☀️ G12W: PV (Solcast) wystarczy - Battery First'
              message: >
                {%- set pv_next_wh = states('sensor.solcast_pv_forecast_prognoza_na_nastepna_godzine') | int(0) -%}
                {%- set remaining_kwh = states('sensor.solcast_pv_forecast_pozostala_prognoza_na_dzis') | float(0) -%}
                {%- set today_kwh = states('sensor.inverter_deye_today_load_consumption') | float(0) -%}
                {%- set elapsed_h = [now().hour + now().minute / 60.0, 2.0] | max -%}
                {%- set load_w = [(today_kwh * 1000 / elapsed_h) | int, 800] | max -%}
                {%- set soc = states('sensor.inverter_deye_battery') | int(0) -%}
                {%- set pv_13_15_wh = pv_next_wh * 1.8 -%}
                {%- set bat_surplus_wh = [pv_13_15_wh * 0.94 - load_w * 2, 0] | max -%}
                {%- set pv_after_15_wh = [remaining_kwh * 1000 - pv_13_15_wh, 0] | max -%}
                {%- set needed_from_bat_wh = [load_w * 7 - pv_after_15_wh, 0] | max -%}
                {%- set target_soc = [[needed_from_bat_wh / 143.36 + 15, 20] | max, 100] | min | int -%}
                {%- set soc_at_15 = (soc + bat_surplus_wh / 143.36) | round(1) -%}
                SOC: {{ soc }}% → ~{{ soc_at_15 }}% o 15:00 (target: {{ target_soc }}%).
                PV 13-15h: {{ pv_13_15_wh | round(0) }} Wh, po 15:00: {{ pv_after_15_wh | round(0) }} Wh.
                Zużycie 15-22h: {{ (load_w * 7) | round(0) }} Wh. Potrzeba z bat: {{ needed_from_bat_wh | round(0) }} Wh.
    # Solcast: PV nie wystarczy → ładuj z sieci tylko brakującą ilość
    default:
      - service: switch.turn_on
        target:
          entity_id: switch.inverter_deye_battery_grid_charging
      - service: select.select_option
        target:
          entity_id: select.inverter_deye_energy_pattern
        data:
          option: Load First
      - service: number.set_value
        target:
          entity_id: number.inverter_deye_battery_max_charging_current
        data:
          value: 100
      - service: number.set_value
        target:
          entity_id: number.inverter_deye_battery_grid_charging_current
        data:
          value: >
            {%- set pv_next_wh = states('sensor.solcast_pv_forecast_prognoza_na_nastepna_godzine') | int(0) -%}
            {%- set remaining_kwh = states('sensor.solcast_pv_forecast_pozostala_prognoza_na_dzis') | float(0) -%}
            {%- set today_kwh = states('sensor.inverter_deye_today_load_consumption') | float(0) -%}
            {%- set elapsed_h = [now().hour + now().minute / 60.0, 2.0] | max -%}
            {%- set load_w = [(today_kwh * 1000 / elapsed_h) | int, 800] | max -%}
            {%- set soc = states('sensor.inverter_deye_battery') | int(0) -%}
            {%- set vbat = states('sensor.inverter_deye_battery_voltage') | float(51.2) -%}
            {%- set pv_13_15_wh = pv_next_wh * 1.8 -%}
            {%- set bat_surplus_wh = [pv_13_15_wh * 0.94 - load_w * 2, 0] | max -%}
            {%- set pv_after_15_wh = [remaining_kwh * 1000 - pv_13_15_wh, 0] | max -%}
            {%- set needed_from_bat_wh = [load_w * 7 - pv_after_15_wh, 0] | max -%}
            {%- set target_soc = [[needed_from_bat_wh / 143.36 + 15, 20] | max, 100] | min | int -%}
            {%- set soc_at_15_no_grid = soc + bat_surplus_wh / 143.36 -%}
            {%- set missing_wh = [(target_soc - soc_at_15_no_grid) * 143.36, 0] | max -%}
            {%- set grid_a = [missing_wh / 2 / vbat, 100] | min | int -%}
            {{ [grid_a, 5] | max }}
      - service: select.select_option
        target:
          entity_id: select.inverter_deye_program_4_charging
        data:
          option: Grid
      - service: number.set_value
        target:
          entity_id: number.inverter_deye_program_4_soc
        data:
          value: >
            {%- set pv_next_wh = states('sensor.solcast_pv_forecast_prognoza_na_nastepna_godzine') | int(0) -%}
            {%- set remaining_kwh = states('sensor.solcast_pv_forecast_pozostala_prognoza_na_dzis') | float(0) -%}
            {%- set today_kwh = states('sensor.inverter_deye_today_load_consumption') | float(0) -%}
            {%- set elapsed_h = [now().hour + now().minute / 60.0, 2.0] | max -%}
            {%- set load_w = [(today_kwh * 1000 / elapsed_h) | int, 800] | max -%}
            {%- set needed_from_bat_wh = [load_w * 7 - [remaining_kwh * 1000 - pv_next_wh * 1.8, 0] | max, 0] | max -%}
            {{ [[needed_from_bat_wh / 143.36 + 15, 20] | max, 100] | min | int }}
      - service: notify.persistent_notification
        data:
          title: '⚡ G12W: Solcast - ładowanie z sieci do target SOC'
          message: >
            {%- set pv_next_wh = states('sensor.solcast_pv_forecast_prognoza_na_nastepna_godzine') | int(0) -%}
            {%- set remaining_kwh = states('sensor.solcast_pv_forecast_pozostala_prognoza_na_dzis') | float(0) -%}
            {%- set today_kwh = states('sensor.inverter_deye_today_load_consumption') | float(0) -%}
            {%- set elapsed_h = [now().hour + now().minute / 60.0, 2.0] | max -%}
            {%- set load_w = [(today_kwh * 1000 / elapsed_h) | int, 800] | max -%}
            {%- set soc = states('sensor.inverter_deye_battery') | int(0) -%}
            {%- set vbat = states('sensor.inverter_deye_battery_voltage') | float(51.2) -%}
            {%- set pv_13_15_wh = pv_next_wh * 1.8 -%}
            {%- set bat_surplus_wh = [pv_13_15_wh * 0.94 - load_w * 2, 0] | max -%}
            {%- set pv_after_15_wh = [remaining_kwh * 1000 - pv_13_15_wh, 0] | max -%}
            {%- set needed_from_bat_wh = [load_w * 7 - pv_after_15_wh, 0] | max -%}
            {%- set target_soc = [[needed_from_bat_wh / 143.36 + 15, 20] | max, 100] | min | int -%}
            {%- set soc_at_15_no_grid = soc + bat_surplus_wh / 143.36 -%}
            {%- set missing_wh = [(target_soc - soc_at_15_no_grid) * 143.36, 0] | max -%}
            {%- set grid_a = [[missing_wh / 2 / vbat, 100] | min | int, 5] | max -%}
            SOC: {{ soc }}%, target na 15:00: {{ target_soc }}%.
            PV 13-15h: {{ pv_13_15_wh | round(0) }} Wh, po 15:00: {{ pv_after_15_wh | round(0) }} Wh.
            Zużycie 15-22h: {{ (load_w * 7) | round(0) }} Wh. Brakuje: {{ missing_wh | round(0) }} Wh → {{ grid_a }}A z sieci.
  mode: single

- alias: Solcast G12W - Wyłącz ładowanie dzienne 15:00
  description: Wyłącza ładowanie po taniej strefie dziennej, przywraca max prąd ładowania
  trigger:
  - platform: time
    at: '15:00:00'
  condition:
  - condition: time
    weekday:
    - mon
    - tue
    - wed
    - thu
    - fri
  action:
  # Zawsze przywróć max prąd ładowania (mógł być ograniczony przez PV optymalizację)
  - service: number.set_value
    target:
      entity_id: number.inverter_deye_battery_max_charging_current
    data:
      value: 100
  - service: switch.turn_off
    target:
      entity_id: switch.inverter_deye_battery_grid_charging
  - service: select.select_option
    target:
      entity_id: select.inverter_deye_energy_pattern
    data:
      option: Battery First
  # Reset prądu do 80A i Program 4 do Disabled
  - service: number.set_value
    target:
      entity_id: number.inverter_deye_battery_grid_charging_current
    data:
      value: 80
  - service: select.select_option
    target:
      entity_id: select.inverter_deye_program_4_charging
    data:
      option: Disabled
  - service: notify.persistent_notification
    data:
      title: '🔋 G12W: Koniec ładowania dziennego'
      message: 'SOC: {{ states(''sensor.inverter_deye_battery'') }}%. Prąd max: 100A przywrócony.'
  mode: single

- alias: Solcast G12W - Raport poranny
  description: Status o 6:05
  trigger:
  - platform: time
    at: 06:05:00
  action:
  - service: notify.persistent_notification
    data:
      title: '🌅 G12W: Raport poranny'
      message: 'SOC: {{ states(''sensor.inverter_deye_battery'') }}%

        Naładowano: {{ states(''sensor.inverter_deye_today_battery_charge'') }} kWh

        Prognoza: {{ states(''sensor.solcast_pv_forecast_prognoza_na_dzisiaj'') }} kWh'

- id: heating_curve_auto_adjust
  alias: Ogrzewanie - Auto dostosowanie krzywej
  description: Automatycznie dostosowuje krzywą grzewczą
  trigger:
  - platform: state
    entity_id: sensor.temperatura_w_salonie
    for:
      minutes: 10
  - platform: time_pattern
    hours: /1
  condition:
  - condition: template
    value_template: '{% set diff = states(''sensor.roznica_temperatury_2'') | float(0) %} {{ diff | abs > 0.3 }}'
  action:
  - service: shell_command.set_heating_t1s
    data:
      value: '{% set current_t1s = states(''sensor.sterownik_1_rs0_id1_setting_t1s'') | int(7215) %} {% set diff = states(''sensor.roznica_temperatury_2'') | float(0) %} {% set adjustment = (diff * 350) | int %} {% set new_t1s = current_t1s - adjustment %} {% if new_t1s < 5000 %}5000{% elif new_t1s > 7000 %}7000{% else %}{{ new_t1s }}{% endif %}'
  mode: single

- id: heating_temp_limit_enforcer
  alias: Ogrzewanie - Wymuszenie limitu temperatury
  description: Obniża T1S gdy temperatura przekracza 35°C
  trigger:
  - platform: numeric_state
    entity_id: sensor.aktualna_nastawa_temperatury_2
    above: 35
    for:
      minutes: 5
  action:
  - service: shell_command.set_heating_t1s
    data:
      value: '{% set current = states(''sensor.sterownik_1_rs0_id1_setting_t1s'') | int(7215) %} {{ current - 500 }}'
  - service: persistent_notification.create
    data:
      message: Temperatura przekroczyła limit 35°C. Obniżam T1S.
  mode: single

- id: defrost_counter
  alias: Licznik defrostów
  description: Zlicza ilość defrostów pompy
  trigger:
  - platform: state
    entity_id: binary_sensor.pompa_defrost
    from: 'off'
    to: 'on'
  action:
  - service: counter.increment
    target:
      entity_id: counter.defrost_count
  mode: single

- alias: Solcast G12W - Optymalizacja PV ładowania dziennego
  id: g12w_pv_charging_optimization
  description: >
    Co 15 min 13:00-15:00: Solcast-based re-evaluation. Oblicza target SOC na 15:00
    potrzebny do pokrycia zużycia 15-22h (droga taryfa). Używa Solcast prognoza_na_biezaca_godzine
    jako estymaty PV w pozostałym oknie.
    Pojemność baterii: 14336 Wh (280Ah LFP).
  trigger:
    - platform: time_pattern
      minutes: '/15'
  condition:
    - condition: time
      after: '13:00:00'
      before: '15:00:00'
      weekday:
        - mon
        - tue
        - wed
        - thu
        - fri
    - condition: numeric_state
      entity_id: sensor.inverter_deye_battery
      below: 100
  action:
    - choose:
        # Solcast: PV w pozostałym oknie wystarczy na target SOC → Battery First
        - conditions:
            - condition: template
              value_template: >
                {%- set pv_hour_wh = states('sensor.solcast_pv_forecast_prognoza_na_biezaca_godzine') | int(0) -%}
                {%- set remaining_kwh = states('sensor.solcast_pv_forecast_pozostala_prognoza_na_dzis') | float(0) -%}
                {%- set today_kwh = states('sensor.inverter_deye_today_load_consumption') | float(0) -%}
                {%- set elapsed_h = [now().hour + now().minute / 60.0, 2.0] | max -%}
                {%- set load_w = [(today_kwh * 1000 / elapsed_h) | int, 800] | max -%}
                {%- set soc = states('sensor.inverter_deye_battery') | int(0) -%}
                {%- set now_min = now().hour * 60 + now().minute -%}
                {%- set remaining_window_h = ([15 * 60 - now_min, 0] | max) / 60 -%}
                {%- set pv_remaining_window_wh = pv_hour_wh * remaining_window_h -%}
                {%- set bat_surplus_wh = [pv_remaining_window_wh * 0.94 - load_w * remaining_window_h, 0] | max -%}
                {%- set pv_after_15_wh = [remaining_kwh * 1000 - pv_remaining_window_wh, 0] | max -%}
                {%- set needed_from_bat_wh = [load_w * 7 - pv_after_15_wh, 0] | max -%}
                {%- set target_soc = [[needed_from_bat_wh / 143.36 + 15, 20] | max, 100] | min | int -%}
                {%- set soc_at_15 = soc + bat_surplus_wh / 143.36 -%}
                {{ soc_at_15 >= target_soc }}
          sequence:
            - service: switch.turn_off
              target:
                entity_id: switch.inverter_deye_battery_grid_charging
            - service: select.select_option
              target:
                entity_id: select.inverter_deye_energy_pattern
              data:
                option: Battery First
            - service: select.select_option
              target:
                entity_id: select.inverter_deye_program_4_charging
              data:
                option: Disabled
            - service: number.set_value
              target:
                entity_id: number.inverter_deye_battery_max_charging_current
              data:
                value: >
                  {%- set pv_w = states('sensor.inverter_deye_pv_power') | int(0) -%}
                  {%- set today_kwh = states('sensor.inverter_deye_today_load_consumption') | float(0) -%}
                  {%- set elapsed_h = [now().hour + now().minute / 60.0, 2.0] | max -%}
                  {%- set load_w = [(today_kwh * 1000 / elapsed_h) | int, 800] | max -%}
                  {%- set vbat = states('sensor.inverter_deye_battery_voltage') | float(51.2) -%}
                  {%- set surplus_a = ((pv_w * 0.94 - load_w) / vbat) | int -%}
                  {{ [5, [surplus_a, 100] | min] | max }}

        # Solcast: PV nie wystarczy → ładuj z sieci dokładnie brakującą ilość
        - conditions:
            - condition: template
              value_template: >
                {%- set pv_hour_wh = states('sensor.solcast_pv_forecast_prognoza_na_biezaca_godzine') | int(0) -%}
                {%- set remaining_kwh = states('sensor.solcast_pv_forecast_pozostala_prognoza_na_dzis') | float(0) -%}
                {%- set today_kwh = states('sensor.inverter_deye_today_load_consumption') | float(0) -%}
                {%- set elapsed_h = [now().hour + now().minute / 60.0, 2.0] | max -%}
                {%- set load_w = [(today_kwh * 1000 / elapsed_h) | int, 800] | max -%}
                {%- set soc = states('sensor.inverter_deye_battery') | int(0) -%}
                {%- set now_min = now().hour * 60 + now().minute -%}
                {%- set remaining_window_h = ([15 * 60 - now_min, 0] | max) / 60 -%}
                {%- set pv_remaining_window_wh = pv_hour_wh * remaining_window_h -%}
                {%- set bat_surplus_wh = [pv_remaining_window_wh * 0.94 - load_w * remaining_window_h, 0] | max -%}
                {%- set pv_after_15_wh = [remaining_kwh * 1000 - pv_remaining_window_wh, 0] | max -%}
                {%- set needed_from_bat_wh = [load_w * 7 - pv_after_15_wh, 0] | max -%}
                {%- set target_soc = [[needed_from_bat_wh / 143.36 + 15, 20] | max, 100] | min | int -%}
                {%- set soc_at_15 = soc + bat_surplus_wh / 143.36 -%}
                {{ soc_at_15 < target_soc and soc < target_soc }}
          sequence:
            - service: switch.turn_on
              target:
                entity_id: switch.inverter_deye_battery_grid_charging
            - service: select.select_option
              target:
                entity_id: select.inverter_deye_energy_pattern
              data:
                option: Load First
            - service: number.set_value
              target:
                entity_id: number.inverter_deye_battery_max_charging_current
              data:
                value: 100
            - service: number.set_value
              target:
                entity_id: number.inverter_deye_battery_grid_charging_current
              data:
                value: >
                  {%- set pv_hour_wh = states('sensor.solcast_pv_forecast_prognoza_na_biezaca_godzine') | int(0) -%}
                  {%- set remaining_kwh = states('sensor.solcast_pv_forecast_pozostala_prognoza_na_dzis') | float(0) -%}
                  {%- set today_kwh = states('sensor.inverter_deye_today_load_consumption') | float(0) -%}
                  {%- set elapsed_h = [now().hour + now().minute / 60.0, 2.0] | max -%}
                  {%- set load_w = [(today_kwh * 1000 / elapsed_h) | int, 800] | max -%}
                  {%- set soc = states('sensor.inverter_deye_battery') | int(0) -%}
                  {%- set vbat = states('sensor.inverter_deye_battery_voltage') | float(51.2) -%}
                  {%- set now_min = now().hour * 60 + now().minute -%}
                  {%- set remaining_window_h = ([15 * 60 - now_min, 0.01] | max) / 60 -%}
                  {%- set pv_remaining_window_wh = pv_hour_wh * remaining_window_h -%}
                  {%- set bat_surplus_wh = [pv_remaining_window_wh * 0.94 - load_w * remaining_window_h, 0] | max -%}
                  {%- set pv_after_15_wh = [remaining_kwh * 1000 - pv_remaining_window_wh, 0] | max -%}
                  {%- set needed_from_bat_wh = [load_w * 7 - pv_after_15_wh, 0] | max -%}
                  {%- set target_soc = [[needed_from_bat_wh / 143.36 + 15, 20] | max, 100] | min | int -%}
                  {%- set soc_at_15_no_grid = soc + bat_surplus_wh / 143.36 -%}
                  {%- set missing_wh = [(target_soc - soc_at_15_no_grid) * 143.36, 0] | max -%}
                  {%- set grid_a = [missing_wh / remaining_window_h / vbat, 100] | min | int -%}
                  {{ [grid_a, 5] | max }}
            - service: select.select_option
              target:
                entity_id: select.inverter_deye_program_4_charging
              data:
                option: Grid
            - service: number.set_value
              target:
                entity_id: number.inverter_deye_program_4_soc
              data:
                value: >
                  {%- set pv_hour_wh = states('sensor.solcast_pv_forecast_prognoza_na_biezaca_godzine') | int(0) -%}
                  {%- set remaining_kwh = states('sensor.solcast_pv_forecast_pozostala_prognoza_na_dzis') | float(0) -%}
                  {%- set today_kwh = states('sensor.inverter_deye_today_load_consumption') | float(0) -%}
                  {%- set elapsed_h = [now().hour + now().minute / 60.0, 2.0] | max -%}
                  {%- set load_w = [(today_kwh * 1000 / elapsed_h) | int, 800] | max -%}
                  {%- set now_min = now().hour * 60 + now().minute -%}
                  {%- set remaining_window_h = ([15 * 60 - now_min, 0] | max) / 60 -%}
                  {%- set pv_rem_wh = pv_hour_wh * remaining_window_h -%}
                  {%- set pv_after_15_wh = [remaining_kwh * 1000 - pv_rem_wh, 0] | max -%}
                  {%- set needed_from_bat_wh = [load_w * 7 - pv_after_15_wh, 0] | max -%}
                  {{ [[needed_from_bat_wh / 143.36 + 15, 20] | max, 100] | min | int }}
            - service: notify.persistent_notification
              data:
                title: '⚡ G12W Optymalizacja: Solcast → sieć potrzebna'
                message: >
                  {%- set pv_hour_wh = states('sensor.solcast_pv_forecast_prognoza_na_biezaca_godzine') | int(0) -%}
                  {%- set remaining_kwh = states('sensor.solcast_pv_forecast_pozostala_prognoza_na_dzis') | float(0) -%}
                  {%- set today_kwh = states('sensor.inverter_deye_today_load_consumption') | float(0) -%}
                  {%- set elapsed_h = [now().hour + now().minute / 60.0, 2.0] | max -%}
                  {%- set load_w = [(today_kwh * 1000 / elapsed_h) | int, 800] | max -%}
                  {%- set soc = states('sensor.inverter_deye_battery') | int(0) -%}
                  {%- set vbat = states('sensor.inverter_deye_battery_voltage') | float(51.2) -%}
                  {%- set now_min = now().hour * 60 + now().minute -%}
                  {%- set remaining_window_h = ([15 * 60 - now_min, 0.01] | max) / 60 -%}
                  {%- set pv_rem_wh = pv_hour_wh * remaining_window_h -%}
                  {%- set bat_surplus_wh = [pv_rem_wh * 0.94 - load_w * remaining_window_h, 0] | max -%}
                  {%- set pv_after_15_wh = [remaining_kwh * 1000 - pv_rem_wh, 0] | max -%}
                  {%- set needed_from_bat_wh = [load_w * 7 - pv_after_15_wh, 0] | max -%}
                  {%- set target_soc = [[needed_from_bat_wh / 143.36 + 15, 20] | max, 100] | min | int -%}
                  {%- set soc_at_15_no_grid = soc + bat_surplus_wh / 143.36 -%}
                  {%- set missing_wh = [(target_soc - soc_at_15_no_grid) * 143.36, 0] | max -%}
                  {%- set grid_a = [[missing_wh / remaining_window_h / vbat, 100] | min | int, 5] | max -%}
                  SOC: {{ soc }}%, target: {{ target_soc }}% ({{ remaining_window_h | round(2) }}h do końca).
                  Brakuje: {{ missing_wh | round(0) }} Wh → {{ grid_a }}A z sieci.
  mode: single
