#:########################################################################################:#
# Open-Meteo Rain Chance Package                                                          #
#:########################################################################################:#
#
# TITLE:
#   Open-Meteo Rain Chance
#
# FILE:
#   open_meteo_rain_chance.yaml
#
# VERSION:
#   V1.2 2026-07-19
#     - Changed today's forecast period to use remaining daylight hours.
#     - Before sunrise, today's forecast covers sunrise through sunset.
#     - During daylight, today's forecast covers now through sunset.
#     - At sunset or later, today's forecast covers now through midnight.
#     - Tomorrow continues to cover daylight hours only.
#
#   V1.1 2026-07-19
#     - Changed today's prediction to use only the remaining forecast hours
#       from the current local hour until midnight.
#     - Changed tomorrow's prediction to cover daylight hours only.
#     - Added hourly precipitation probability data.
#     - Added today's and tomorrow's sunrise and sunset data.
#
#   V1.0 2026-07-18
#     - Initial version.
#     - Used the full-day maximum precipitation probability for today and
#       tomorrow.
#
# PURPOSE:
#   Creates dedicated Home Assistant sensors for the maximum hourly
#   probability of precipitation during useful forecast periods today and
#   tomorrow.
#
# SOURCE:
#   Open-Meteo Forecast API
#
# LOCATION:
#   Uses the latitude and longitude attributes of zone.home.
#
# OUTPUT ENTITIES:
#   sensor.open_meteo_rain_chance_today
#   sensor.open_meteo_rain_chance_tomorrow
#
# FORECAST PERIODS:
#   Today before sunrise:
#     Sunrise through sunset.
#
#   Today during daylight:
#     Current time through sunset.
#
#   Today at or after sunset:
#     Current time through midnight.
#
#   Tomorrow:
#     Sunrise through sunset.
#
# UPDATE RATE:
#   Every 30 minutes.
#
# NOTES:
#   - No API key is required.
#   - timezone=auto makes Open-Meteo return forecast times in the local
#     timezone determined from the zone.home coordinates.
#   - Each Open-Meteo hourly precipitation probability applies to the
#     preceding hour.
#   - Hourly forecast periods that partly overlap sunrise or sunset are
#     included.
#   - The displayed result is the highest hourly probability within the
#     applicable period.
#   - The result is not a separately calculated probability of receiving
#     rain at any point across the whole selected period.
#   - Sensor values and forecast-period changes are recalculated whenever
#     the REST request updates.
#
#:########################################################################################:#

rest:
  - resource_template: >-
      https://api.open-meteo.com/v1/forecast?latitude={{ state_attr('zone.home', 'latitude') }}&longitude={{ state_attr('zone.home', 'longitude') }}&hourly=precipitation_probability&daily=sunrise,sunset&timezone=auto&forecast_days=2

    method: GET
    scan_interval: 1800
    timeout: 20

    sensor:
      #:###################################################################################:#
      # Rain Chance Today                                                                  #
      #:###################################################################################:#
      #
      # Before sunrise:
      #   Uses today's sunrise through sunset.
      #
      # During daylight:
      #   Uses the current time through today's sunset.
      #
      # At or after sunset:
      #   Uses the current time through midnight.
      #

      - name: "Open Meteo Rain Chance Today"
        unique_id: open_meteo_rain_chance_today
        unit_of_measurement: "%"
        state_class: measurement
        icon: mdi:weather-rainy

        value_template: >-
          {% set current_timestamp =
            as_timestamp(now())
          %}

          {% set sunrise_timestamp =
            as_timestamp(
              value_json.daily.sunrise[0],
              0
            )
          %}

          {% set sunset_timestamp =
            as_timestamp(
              value_json.daily.sunset[0],
              0
            )
          %}

          {% set tomorrow_midnight_timestamp =
            as_timestamp(
              value_json.daily.time[1] ~ 'T00:00',
              0
            )
          %}

          {% if current_timestamp < sunrise_timestamp %}

            {% set period_start_timestamp =
              sunrise_timestamp
            %}

            {% set period_end_timestamp =
              sunset_timestamp
            %}

          {% elif current_timestamp < sunset_timestamp %}

            {% set period_start_timestamp =
              current_timestamp
            %}

            {% set period_end_timestamp =
              sunset_timestamp
            %}

          {% else %}

            {% set period_start_timestamp =
              current_timestamp
            %}

            {% set period_end_timestamp =
              tomorrow_midnight_timestamp
            %}

          {% endif %}

          {% set ns = namespace(
            maximum=0,
            found=false
          ) %}

          {% for index in range(
            value_json.hourly.time | count
          ) %}

            {% set forecast_end_timestamp =
              as_timestamp(
                value_json.hourly.time[index],
                0
              )
            %}

            {% set probability =
              value_json.hourly.precipitation_probability[index]
            %}

            {% if
              forecast_end_timestamp > period_start_timestamp
              and forecast_end_timestamp < period_end_timestamp + 3600
              and probability is not none
            %}

              {% set ns.found = true %}

              {% if probability | int(0) > ns.maximum %}

                {% set ns.maximum =
                  probability | int(0)
                %}

              {% endif %}

            {% endif %}

          {% endfor %}

          {{ ns.maximum if ns.found else 0 }}

      #:###################################################################################:#
      # Rain Chance Tomorrow — Daylight                                                    #
      #:###################################################################################:#
      #
      # Uses hourly forecast periods that overlap tomorrow's daylight
      # period between sunrise and sunset.
      #

      - name: "Open Meteo Rain Chance Tomorrow"
        unique_id: open_meteo_rain_chance_tomorrow
        unit_of_measurement: "%"
        state_class: measurement
        icon: mdi:weather-sunset-up

        value_template: >-
          {% set sunrise_timestamp =
            as_timestamp(
              value_json.daily.sunrise[1],
              0
            )
          %}

          {% set sunset_timestamp =
            as_timestamp(
              value_json.daily.sunset[1],
              0
            )
          %}

          {% set ns = namespace(
            maximum=0,
            found=false
          ) %}

          {% for index in range(
            value_json.hourly.time | count
          ) %}

            {% set forecast_end_timestamp =
              as_timestamp(
                value_json.hourly.time[index],
                0
              )
            %}

            {% set probability =
              value_json.hourly.precipitation_probability[index]
            %}

            {% if
              forecast_end_timestamp > sunrise_timestamp
              and forecast_end_timestamp < sunset_timestamp + 3600
              and probability is not none
            %}

              {% set ns.found = true %}

              {% if probability | int(0) > ns.maximum %}

                {% set ns.maximum =
                  probability | int(0)
                %}

              {% endif %}

            {% endif %}

          {% endfor %}

          {{ ns.maximum if ns.found else 0 }}
