UI Widget: Weather

Me too :crazy_face:.
I didn’t make any changes in the programming-logic, as this stuff is too hard for me. But I made some changes in the “suffix’s-naming”. I.e. your code was “ForecastToday_Iconid” or better said “Iconid”, I made “IconId” from it, a.s.o.
As Prefix I use “OC_WaF_”, as my naming convention looks like “OC_WaF_ForecastToday_TimeStamp”.

The YAML-Code for my Onecall-Thing is

UID: openweathermap:onecall:api:local
label: One Call API weather and forecast
thingTypeUID: openweathermap:onecall
configuration:
  location: 42.887211,3.4209123
  forecastHours: 0
  forecastDays: 6
  forecastMinutes: 0
bridgeUID: openweathermap:weather-api:api

I do not use any subdivisions into “hours” or “minutes”. So I’m surprised as you, as you, that I’m getting those warnings, even if the items are in my Item-Setup except for the “OC_WaF_ForecastDay1_IconId”-Naming, what a pity :sleepy:.
Thx for your answer. I will have a look on your scheme, if you have no other idea.

Cheers
Peter

Hi,

thx for the fast help. I didnt choose “advanced options” when adding the items via MainUI (since there are so many I didnt notice some where missing).

Works now as intended, thanks a lot!

1 Like

Hi Rainer,
me again, sorry!!!
Now I used your ItemSet and your Original-Widget. The only Difference is in the Thing-Description, as mine use another UID.
Onecall-Thing:

UID: openweathermap:onecall:api:local
label: One Call API weather and forecast
thingTypeUID: openweathermap:onecall
configuration:
  location: xxxx,yyyy
  forecastHours: 13
  forecastDays: 6
  forecastMinutes: 0
bridgeUID: openweathermap:weather-api:api

OWM-Thing:

UID: openweathermap:weather-and-forecast:api:local
label: Lokales Wetter und Wettervorhersage
thingTypeUID: openweathermap:weather-and-forecast
configuration:
  forecastDays: 0
  location: xxxx,yyyy
  forecastHours: 24
bridgeUID: openweathermap:weather-api:api

Bridge:

UID: openweathermap:weather-api:api
label: OpenWeatherMap Konto
thingTypeUID: openweathermap:weather-api
configuration:
  apikey: my key
  refreshInterval: 60
  language: de

Widget-Settings:
grafik
grafik

Widget-Result:
grafik

As you see all looks amazing include the correct location, but still the same boring warnings:

2021-02-02 17:03:03.642 [WARN ] [e.internal.SseItemStatesEventBuilder] - Attempting to send a state update of an item which doesn't exist: ForecastTomorrow_Iconid
2021-02-02 17:03:03.654 [WARN ] [e.internal.SseItemStatesEventBuilder] - Attempting to send a state update of an item which doesn't exist: OneCallAPIweatherandforecast_ForecastDay1_Iconid
2021-02-02 17:03:03.659 [WARN ] [e.internal.SseItemStatesEventBuilder] - Attempting to send a state update of an item which doesn't exist: ForecastDay2_Iconid
2021-02-02 17:03:03.670 [WARN ] [e.internal.SseItemStatesEventBuilder] - Attempting to send a state update of an item which doesn't exist: ForecastDay3_Iconid
2021-02-02 17:03:03.680 [WARN ] [e.internal.SseItemStatesEventBuilder] - Attempting to send a state update of an item which doesn't exist: ForecastDay4_Iconid
2021-02-02 17:03:03.690 [WARN ] [e.internal.SseItemStatesEventBuilder] - Attempting to send a state update of an item which doesn't exist: ForecastDay5_Iconid

Here once again the item-scheme and the YAML-Code:
weatherPopupRG.txt (29.5 KB) oncallRG.items.txt (44.1 KB)

Is it possible that the code was changed ? I used it from here

Cheers,
Peter

Today I renamed all my items according to the name schema suggested by Rainer. It took some time, as I had to change the tables and views in my Postgresl database and some Grafana panels as well, but I guess it will spare me some headache in the long run.

At it was worth the effort, on the first glance the widget now works as expected, great! I will do some more testing tomorrow. I still can not figure out why there was a problem with my first try, even when comparing it to the original version. Must be some subtle difference.

Thanks again for sharing this great widget!

This looks pretty cool - can you share the yaml file?

how do you impliment these into habpanel? ive got the top example working in OH3 under the developer setting to add widgets and added it to a page but cant work out how to get working in habpanel?

Those widgets cannot be used in habpanel.

Dear all

Based on thermostat widget by Nico_R I create widgets for personal weather station

Here

Any suggestion are welcome

These widgets look very nice.
I’ve never done this before, but I guess the items and things are created using with Developer Tools/Add Items from textual definition. I copied the text there, but it didn’t work:


Could you give me a tip what needs to be done?
Let’s suppose I get this running, do I create the OWM-weather ITEMS the same way or is this only for THING-creation?

@Ursusprimus did you check OP. There is a guide on how to add owm things and items.

This guide worked for me very well.

1 Like

Hey @Ursusprimus

you can add the things / items either via the UI or with textfiles. It seems you try to add the *.things definition as item (which won’t work).

I would advise you using the UI, if you’re new to openHAB. Have a look here for a more detailed explanation of how to set-up.

1 Like

@RGroll
Thank you for the link which helped me understand what to do.
I seem to have made a mistake though and am not sure which and where. Looks like my items have the wrong name; at least they aren’t found by the widget.
Is there a simple way to either change it in the widget or the item-names? If not and I should create the items again: Any idea where I might have gone wrong and what the name structure should be like?

Another thing: In the description it says that the widget is supposed to be part of a popup. I didn’t find a popup widget in the page-library. Where should I look?

Sorry for such simple questions but OH is a little overwhelming for a beginner …

Hey @Ursusprimus

everything seems fine with the item naming. You have to add the itemPrefix in the widget configuration like described in the first post of this thread:

:exclamation: Info: If you used the above item-naming pattern you’ve to assign OneCallAPIweatherandforecast_ as itemPrefix (and Localweatherandforecast_ as additional itemPrefix if you want to show the Location automatically) within the widget-configuration.

1 Like

Thank you! With your help even I got it running :wink:

Hi @RGroll

Thanks for the great work and the effort you have been putting in.

I really like your "Weather popup #2 (extended), which I have managed to get working nicely. But then wanted to add to it…

I managed to add the UV Index without too much hassle. As you will see below.

Next I want to add the Daily Min and Max temperatures next to the Daily Temp, Something like:

From looking at your other examples and trying to work out how it all works it looks like I need to use an f7-row for the Current Temp and Min and Max as "labels inside that.

I am however stuck at just putting the Current Temp in its won row - it throws most of the rest of the layout off completely and I just cannot work out what I have done to break it.

Any pointers to references for the F5-block, row etc would be appreciated. I tried looking at the docs referenced in “Building Pages: Components & Widgets” but I do not get how they tie back to the blocks, rows and columns in OpenHab. Maybe because I have zero CSS knowledge.

So this is what I get right now:

Any guidance on what I have done wrong to “lose” the Current Temp and mess up the alignment of the rest?. Would love to move one step forward and try and get the rest working myself - or even just have the MIN and MAX words there and can try figure the rest out.

How do you work on your layout? Do you use the Widget Builder directly or some other tools?

My Current YAML Code follows

uid: weatherPopup_extended_uv_feel_min_max
tags:
  - weather
  - popup
  - daily forecast
  - OpenWeatherMap
  - extended
props:
  parameters:
    - description: <b>Optional prefix</b> for item names.
      label: Item prefix
      name: itemPrefix
      required: false
      type: TEXT
      groupName: general
    - description: <b>Additional prefix</b> for item names that belongs to another Things channel (valid for 'StationName' as it might differ)
      label: Additional item prefix
      name: itemPrefix2
      required: false
      type: TEXT
      groupName: general
      advanced: true
    - description: The number of hours you want to forecast (<u>default:</u> <b>12</b>)
      label: Number of hours to forecast
      name: forecastHours
      required: false
      type: TEXT
      groupName: general
    - description: The number of days you want to forecast (<u>default:</u> <b>3</b>)
      label: Number of days to forecast
      name: forecastDays
      required: false
      type: TEXT
      groupName: general
    - description: Activate day & night Indication on hourly forecast (background color & sunrise / sunset indicator icon)
      label: Show sunrise & sunset
      name: sunIndicator
      required: false
      type: BOOLEAN
      groupName: general
    - description: Acitvate 24-hour clock-format (<u>default:</u> <b>12-hour clock-format</b>)
      label: 24h clock-format
      name: dateFormat
      required: false
      type: BOOLEAN
      groupName: general
    - description: Add suffix to the timestamp
      label: Custom timestamp suffix
      name: timestampSuffix
      required: false
      type: TEXT
      groupName: general
    - description: Overwrite the location header
      label: Location title
      name: locationTitle
      required: false
      type: TEXT
      groupName: general
    - description: Folder where you stored your weather-images (<u>default:</u> <b>/static/files/weather_img/</b>)
      label: Image folder
      name: imageFolder
      required: false
      type: TEXT
      groupName: images
    - description: Select a local sight as a centered image (preferably *.svg with the <b>image-content aligned at the bottom</b>)
      label: Local sight image-name
      name: localSightImg
      required: false
      type: TEXT
      groupName: images
    - description: Select a global background-image which will be visible on daytime
      label: Global background image (day-cycle)
      name: globalBackgroundDayImg
      required: true
      type: TEXT
      groupName: images
    - description: Select a global background-image which will be visible on nighttime
      label: Global background image (night-cycle)
      name: globalBackgroundNightImg
      required: true
      type: TEXT
      groupName: images
    - description: Disable background images (local sight & background-image)
      label: Disable local-sight image
      name: disableLocalSightBg
      required: false
      type: BOOLEAN
      groupName: images
      advanced: true
    - description: Alternative title for 'x-hour forecast' within the segmented control, where x gets replaced by the number of hours automatically. (<u>default:</u> <b>-hour forecast</b>)
      label: Translation 'x-hour forecast'
      name: wordingForecastHours
      required: false
      type: TEXT
      groupName: wording
    - description: Alternative title for 'x-day forecast' within the segmented control, where x gets replaced by the number of days automatically. (<u>default:</u> <b>-day forecast</b>)
      label: Translation 'x-day forecast'
      name: wordingForecastDays
      required: false
      type: TEXT
      groupName: wording
    - description: Alternative title for 'Now' in the 12-hour forecast tab
      label: Translation 'Now'
      name: wordingNow
      required: false
      type: TEXT
      groupName: wording
    - description: Alternative title for 'Today' in the 3-day-forecast tab
      label: Translation 'Today'
      name: wordingToday
      required: false
      type: TEXT
      groupName: wording
    - description: Alternative text for 'Sunrise at' in the icon-tooltip (only visible if you've activated the day & night indication)
      label: Translation 'Sunrise at'
      name: wordingSunrise
      required: false
      type: TEXT
      groupName: wording
    - description: Alternative text for 'Sunset at' in the icon-tooltip (only visible if you've activated the day & night indication)
      label: Translation 'Sunset at'
      name: wordingSunset
      required: false
      type: TEXT
      groupName: wording
  parameterGroups:
    - name: general
      label: General settings
      description: All settings which are related to the usage of this widget
    - name: images
      label: Image settings
    - name: wording
      label: Language settings
      description: Set alternative wordings
timestamp: Mar 3, 2021, 3:02:56 PM
component: f7-page
config:
  style:
    background: "=(dayjs().format() >= items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'ForecastToday_Sunrise'].state && dayjs().format() < items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'ForecastToday_Sunset'].state) ? 'linear-gradient(to bottom, #355b8e, #c0d4f0)' : 'repeat-x radial-gradient(white, rgba(255,255,255,.2) 2px, transparent 5px) 50px 0px/420px 420px, repeat-x radial-gradient(white, rgba(255,255,255,.2) 2px, transparent 5px) 10px 0px/650px 650px, repeat-x radial-gradient(white, rgba(255,255,255,.2) 2px, transparent 5px) 200px 0px/450px 450px, repeat-x radial-gradient(white, rgba(255,255,255,.2) 2px, transparent 5px) 200px 80px/350px 350px, repeat-x radial-gradient(white, rgba(255,255,255,.2) 2px, transparent 5px) 0px 0px/260px 260px, repeat-x radial-gradient(white, rgba(255,255,255,.15) 1px, transparent 3px) 50px 0px/200px 200px, repeat-x radial-gradient(white, rgba(255,255,255,.1) 2px, transparent 4px) 130px 0px/250px 100px, repeat-x radial-gradient(rgba(255,255,255,.4), rgba(255,255,255,.1) 2px, transparent 1px) 50px 0px/150px 50px, repeat-x radial-gradient(white, rgba(255,255,255,.2) 1px, transparent 2px) 50px 0px/280px 480px, repeat-x radial-gradient(white, rgba(255,255,255,.2) 1px, transparent 2px) 70px 0px/180px 350px, repeat-x radial-gradient(white, rgba(255,255,255,.1) 1px, transparent 1px) 80px 0px/200px 120px, repeat-x radial-gradient(white, rgba(255,255,255,.1) 2px, transparent 2px) 100px 0px/200px 180px, repeat-x radial-gradient(white, rgba(255,255,255,.1) 1px, transparent 5px) 100px 0px/350px 600px, linear-gradient(to bottom,#413D8F 0%,#CE9FC8 100%)'"
    background-repeat: repeat-x
    -ms-user-select: none
    -moz-user-select: none
    -webkit-user-select: none
    user-select: none
    overflow: hidden
    --f7-page-navbar-offset: none
    --f7-page-toolbar-top-offset: none
    --f7-page-subnavbar-offset: none
    --f7-page-searchbar-offset: none
    --f7-page-content-extra-padding-top: none
    --f7-page-toolbar-bottom-offset: none
    --f7-page-content-extra-padding-bottom: none
    --f7-theme-color: none
    --f7-bars-bg-color: none
    --f7-bars-border-color: none
    --f7-navbar-shadow-image: none
    --f7-navbar-text-color: white
    --f7-bars-text-color: white
    --f7-navbar-link-color: white
    --f7-navbar-bg-color-rgb: none
    --f7-bars-bg-color-rgb: none
    --f7-bars-translucent-opacity: none
    --f7-bars-translucent-blur: none
    backdrop-filter: none
    --f7-button-border-radius: 0
    --weather-condition-icon-size: 30px
    --weather-label-text-transform: normal
    --weather-font-size-xsmall: 14px
    --weather-font-size-small: 16px
    --weather-font-size-medium: 18px
    --weather-font-size-hero: 91px
    --weather-font-color-main: white
    --weather-forecast-location-font-color: rgba(255,255,255,.7)
    --weather-forecast-text-shadow-light: 2px 2px rgba(0,0,0,.15)
    --weather-forecast-text-shadow-strong: 2px 2px rgba(0,0,0,.35)
    --weather-forecast-font-color-light: rgba(0,0,0,.35)
    --weather-forecast-font-color: rgba(0,0,0,.7)
slots:
  default:
    - component: Label
      config:
        text: "=!props.locationTitle ? items[(!props.itemPrefix2 ? (!props.itemPrefix ? '' : props.itemPrefix) : props.itemPrefix2) + 'StationName'].state : props.locationTitle"
        class:
          - text-align-right
          - padding-right
        style:
          text-overflow: ellipsis
          overflow: hidden
          line-height: var(--f7-navbar-link-line-height,var(--f7-navbar-height))
          font-size: var(--weather-font-size-xsmall)
          color: var(--weather-forecast-location-font-color)
          text-shadow: var(--weather-forecast-text-shadow-light)
          text-transform: uppercase
    - component: f7-block
      config:
        text-align: center
        class:
          - no-margin
          - no-padding
      slots:
        default:
          - component: f7-row
            config:
              class: justify-content-center
              slots:
                default:
                  - component: Label
                    config:
                      text: "=(!props.itemPrefix) ? Math.round(items.Current_Temperature.state.split(' ')[0]) + '°' : Math.round(items[props.itemPrefix + 'Current_Temperature'].state.split(' ')[0]) + '°'"
                      style:
                        font-size: var(--weather-font-size-hero)
                        font-weight: lighter
                        line-height: var(--weather-font-size-hero)
                        color: var(--weather-font-color-main)
                        text-shadow: var(--weather-forecast-text-shadow-strong)
                        white-space: nowrap
                        overflow: hidden
                        text-overflow: ellipsis
          - component: f7-row
            slots: {}
          - component: Label
            config:
              text: "=(!props.itemPrefix) ? items.Current_Apparenttemperature.state : 'Feels Like: ' + items[props.itemPrefix + 'Current_Apparenttemperature'].state "
              class:
                - align-self-center
              style:
                font-size: var(--weather-font-size-medium)
                text-shadow: var(--weather-forecast-text-shadow-strong)
                color: var(--weather-font-color-main)
                text-overflow: ellipsis
                white-space: nowrap
                overflow: hidden
                z-index: 999
          - component: Label
            config:
              text: "=(!props.itemPrefix) ? items.Current_Condition.state : items[props.itemPrefix + 'Current_Condition'].state"
              style:
                font-size: var(--weather-font-size-medium)
                text-shadow: var(--weather-forecast-text-shadow-strong)
                color: var(--weather-font-color-main)
                text-overflow: ellipsis
                white-space: nowrap
                overflow: hidden
                z-index: 999
          - component: Label
            config:
              text: "=(!props.itemPrefix) ? items.UVIndex.state : 'UV Index: ' + items[props.itemPrefix + 'UVIndex'].state "
              style:
                font-size: var(--weather-font-size-medium)
                text-shadow: var(--weather-forecast-text-shadow-strong)
                color: var(--weather-font-color-main)
                text-overflow: ellipsis
                white-space: nowrap
                overflow: hidden
                z-index: 999
          - component: Label
    - component: f7-block
      config:
        class:
          - no-margin
          - no-padding
        style:
          background: "=(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '01d') ? '' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '01n') ? '' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '02d') ? 'no-repeat top center/750px url(' + ((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + '02.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '02n') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '02.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '03d') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '03.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '03n') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '03.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '04d') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '04.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '04n') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '04.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '09d') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '09.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '09n') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '09.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '10d') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '10.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '10n') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '10.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '11d') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '11.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '11n') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '11.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '13d') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '13.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '13n') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '13.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '50d') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '50.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '50n') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '50.svg)' : '?'"
          height: 100%
          width: 100%
          position: absolute
          top: 0
          left: 0
          right: 0
    - component: oh-image
      config:
        url: "=(dayjs().format() >= items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'ForecastToday_Sunrise'].state && dayjs().format() < items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'ForecastToday_Sunset'].state ) ? ((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + 'sun.svg' : ((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + 'moon.svg'"
        style:
          width: 100%
          max-width: 150px
          min-width: 70px
          position: absolute
          top: 5px
          left: -50px
          z-index: 999
    - component: f7-block
      config:
        style:
          overflow: hidden
          position: absolute
          bottom: 105px
          width: 100%
          height: 100%
          z-index: -1
      slots:
        default:
          - component: oh-image
            config:
              visible: =!props.disableLocalSightBg
              url: "=(dayjs().format() >= items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'ForecastToday_Sunrise'].state && dayjs().format() < items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'ForecastToday_Sunset'].state ) ? ((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + props.globalBackgroundDayImg : ((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + props.globalBackgroundNightImg"
              style:
                position: absolute
                bottom: 0
                right: 0
                left: 0
                margin-right: auto
                margin-left: auto
                width: 100%
                min-width: 800px
                max-width: 1200px
    - component: oh-image
      config:
        visible: =!props.disableLocalSightBg
        url: "=((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + props.localSightImg"
        style:
          position: absolute
          bottom: 138px
          right: 0
          left: 0
          margin-right: auto
          margin-left: auto
          width: 100%
          min-width: 150px
          max-width: 280px
          z-index: 1
    - component: f7-block
      config:
        class:
          - text-align-center
          - align-content-bottom
          - no-margin
        style:
          border-top: 60px solid white
          border-image-source: "='url(' + ((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + 'bottom_mask-white.svg' + ')'"
          -moz-border-image-source: "='url(' + ((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + 'bottom_mask-white.svg' + ')'"
          -webkit-border-image-source: "='url(' + ((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + 'bottom_mask-white.svg' + ')'"
          -o-border-image-source: "='url(' + ((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + 'bottom_mask-white.svg' + ')'"
          -webkit-appearance: none
          border-image-slice: 100% 0 0 0
          border-image-width: 1 0 0 0
          position: absolute
          bottom: 0
          left: 0
          width: 100%
      slots:
        default:
          - component: f7-block
            config:
              class:
                - no-margin
                - no-padding
              style:
                position: absolute
                left: 0
                bottom: 0
                height: calc(100% + 2px)
                width: 100%
                background: white
                -webkit-box-shadow: 10px 10px 10px 20px white
                -moz-box-shadow: 10px 10px 10px 20px white
                box-shadow: 10px 10px 10px 20px white
          - component: f7-segmented
            config:
              strong: true
              style:
                --f7-segmented-strong-button-active-box-shadow: 0 4px 0px -2px gray
                --f7-segmented-strong-button-font-color: gray
                --f7-segmented-strong-bg-color: white
                z-index: 999
            slots:
              default:
                - component: oh-button
                  config:
                    text: '=(!props.wordingForecastHours && !props.forecastHours) ? "12-hour forecast" : (props.wordingForecastHours && !props.forecastHours) ? 12 + props.wordingForecastHours : (!props.wordingForecastHours && props.forecastHours) ? props.forecastHours + "-hour forecast" : props.forecastHours + props.wordingForecastHours'
                    active: =!vars.tab || vars.tab === 'hourly_forecast'
                    action: variable
                    actionVariable: tab
                    actionVariableValue: hourly_forecast
                    style:
                      color: '=(vars.tab === "daily_forecast") ? "lightgray" : "black"'
                - component: oh-button
                  config:
                    text: '=(!props.wordingForecastDays && !props.forecastDays) ? "3-day forecast" : (props.wordingForecastDays && !props.forecastDays) ? 3 + props.wordingForecastDays : (!props.wordingForecastDays && props.forecastDays) ? props.forecastDays + "-day forecast" : props.forecastDays + props.wordingForecastDays'
                    active: =vars.tab === 'daily_forecast'
                    action: variable
                    actionVariable: tab
                    actionVariableValue: daily_forecast
                    style:
                      color: '=(!vars.tab || vars.tab === "hourly_forecast") ? "lightgray" : "black"'
          - component: f7-swiper
            config:
              visible: =!vars.tab || vars.tab === 'hourly_forecast'
              navigation: true
              class:
                - padding-top
                - padding-bottom
              params:
                initalSlide: 0
                runCallbacksOnInit: true
                grabCursor: true
                observer: true
                observeSlideChildren: true
                updateOnWindowResize: true
                spaceBetween: 5
                mousewheel: true
                keyboard: true
                watchOverflow: true
                breakpoints:
                  "0":
                    slidesPerView: 1
                  "240":
                    slidesPerView: "=(!props.forecastHours) ? 2 : ((props.forecastHours < 2) ? Math.round(Number(props.forecastHours) + 1) : 2)"
                  "320":
                    slidesPerView: "=(!props.forecastHours) ? 3 : ((props.forecastHours < 3) ? Math.round(Number(props.forecastHours) + 1) : 3)"
                  "480":
                    slidesPerView: "=(!props.forecastHours) ? 4 : ((props.forecastHours < 4) ? Math.round(Number(props.forecastHours) + 1) : 4)"
                  "640":
                    slidesPerView: "=(!props.forecastHours) ? 5 : ((props.forecastHours < 5) ? Math.round(Number(props.forecastHours) + 1) : 5)"
              style:
                --swiper-navigation-size: 20px
                --swiper-navigation-color: gray
            slots:
              default:
                - component: oh-repeater
                  config:
                    sourceType: range
                    for: hour
                    rangeStart: 0
                    rangeStop: "=(!props.forecastHours) ? 12 : Number(props.forecastHours)"
                    fragment: true
                  slots:
                    default:
                      - component: f7-swiper-slide
                        config:
                          style:
                            background: "=(props.sunIndicator === true) ? ((dayjs().add(loop.hour,'hour').format() >= items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunrise'].state && dayjs().add(loop.hour,'hour').format() <= items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunset'].state) ? 'rgba(44,130,201,.15)' : 'rgba(190,144,212,.15)') : 'none'"
                            border-radius: 5px
                        slots:
                          default:
                            - component: f7-icon
                              config:
                                visible: "=(dayjs().add(loop.hour,'hour').startOf('hour').format() === dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunrise'].state).startOf('hour').format() && props.sunIndicator === true)"
                                f7: sun_max_fill
                                color: black
                                size: 17px
                                tooltip: "=((!props.wordingSunrise) ? 'Sunrise at ' : props.wordingSunrise + ' ') + ((!props.dateFormat) ? dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunrise'].state).format('h:mm A') : dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunrise'].state).format('H:mm')+' h') + '<br><b>' + dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunrise'].state).fromNow() + '</b>'"
                                style:
                                  position: absolute
                                  right: 3px
                                  top: 3px
                                  cursor: pointer
                                  z-index: 9999
                            - component: f7-icon
                              config:
                                visible: "=(dayjs().add(loop.hour,'hour').startOf('hour').format() === dayjs(items['Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunset'].state).startOf('hour').format() && props.sunIndicator === true)"
                                f7: moon_fill
                                color: black
                                size: 17px
                                tooltip: "=((!props.wordingSunset) ? 'Sunset at ' : props.wordingSunset + ' ') + ((!props.dateFormat) ? dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunset'].state).format('h:mm A') : dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunset'].state).format('H:mm') + ' h') + '<br><b>' + dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunset'].state).fromNow() + '</b>'"
                                style:
                                  position: absolute
                                  right: 3px
                                  top: 3px
                                  cursor: pointer
                                  z-index: 9999
                            - component: f7-row
                              config:
                                class:
                                  - justify-content-center
                              slots:
                                default:
                                  - component: Label
                                    config:
                                      text: "=(loop.hour === 0) ? ((!props.wordingNow) ? 'Now' : props.wordingNow) : ((!props.dateFormat) ? dayjs().add(loop.hour,'hour').startOf('hour').format('h A') : dayjs().add(loop.hour,'hour').startOf('hour').format('H')) + (!props.timestampSuffix ? '' : ' ' + props.timestampSuffix)"
                                      style:
                                        font-weight: 400
                                        color: var(--weather-forecast-font-color)
                                        text-transform: var(--weather-label-text-transform)
                            - component: f7-row
                              config:
                                class:
                                  - justify-content-center
                                  - align-items-center
                              slots:
                                default:
                                  - component: f7-icon
                                    config:
                                      f7: "=(items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '01d') ? 'sun_max' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '01n') ? 'moon_stars' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '02d') ? 'cloud_sun' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '02n') ? 'cloud_moon' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '03d') ? 'cloud' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '03n') ? 'cloud' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '04d') ? 'cloud' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '04n') ? 'cloud' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '09d') ? 'cloud_heavyrain' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '09n') ? 'cloud_heavyrain' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '10d') ? 'cloud_sun_rain' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '10n') ? 'cloud_moon_rain' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '11d') ? 'cloud_sun_bolt' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '11n') ? 'cloud_moon_bolt' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '13d') ? 'cloud_snow' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '13n') ? 'cloud_snow' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '50d') ? 'cloud_fog' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '50n') ? 'cloud_fog' : ''"
                                      size: var(--weather-condition-icon-size)
                                      style:
                                        padding-right: 5px
                                        color: var(--weather-forecast-font-color)
                                  - component: Label
                                    config:
                                      text: "=Math.round(items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Temperature'].state.split(' ')[0]) + '°'"
                                      style:
                                        font-size: var(--weather-font-size-small)
                                        font-weight: 700
                                        color: var(--weather-forecast-font-color)
                            - component: f7-row
                              config:
                                class:
                                  - justify-content-center
                                  - align-items-center
                              slots:
                                default:
                                  - component: f7-icon
                                    config:
                                      f7: umbrella
                                      size: 15
                                      style:
                                        color: var(--weather-forecast-font-color-light)
                                        padding-right: 3px
                                  - component: Label
                                    config:
                                      text: "=Math.round(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1)) + '_Precipprobability'].state.split(' ')[0]) + '%'"
                                      style:
                                        font-size: var(--weather-font-size-small)
                                        font-weight: 400
                                        color: var(--weather-forecast-font-color-light)
          - component: f7-swiper
            config:
              visible: =vars.tab === 'daily_forecast'
              navigation: true
              class:
                - padding-top
                - padding-bottom
              params:
                initalSlide: 0
                grabCursor: true
                observer: true
                spaceBetween: 5
                observeSlideChildren: true
                updateOnWindowResize: true
                watchOverflow: true
                mousewheel: true
                keyboard: true
                breakpoints:
                  "0":
                    slidesPerView: 1
                  "210":
                    slidesPerView: "=(!props.forecastDays) ? 2 : ((props.forecastDays < 2) ? Math.round(Number(props.forecastDays) + 1) : 2)"
                  "480":
                    slidesPerView: "=(!props.forecastDays) ? 3 : ((props.forecastDays < 3) ? Math.round(Number(props.forecastDays) + 1) : 3)"
                  "640":
                    slidesPerView: "=(!props.forecastDays) ? 4 : ((props.forecastDays < 4) ? Math.round(Number(props.forecastDays) + 1) : 4)"
              style:
                --swiper-navigation-size: 20px
                --swiper-navigation-color: gray
            slots:
              default:
                - component: oh-repeater
                  config:
                    sourceType: range
                    for: day
                    rangeStart: 0
                    rangeStop: "=(!props.forecastDays) ? 3 : Number(props.forecastDays)"
                    fragment: true
                  slots:
                    default:
                      - component: f7-swiper-slide
                        config: {}
                        slots:
                          default:
                            - component: f7-row
                              config:
                                class:
                                  - justify-content-center
                                  - align-items-center
                              slots:
                                default:
                                  - component: Label
                                    config:
                                      text: "=(loop.day === 0) ? ((!props.wordingToday) ? 'Today' : props.wordingToday) : dayjs().add(loop.day,'day').startOf('day').format('dddd')"
                                      style:
                                        color: var(--weather-forecast-font-color)
                                        text-transform: var(--weather-label-text-transform)
                            - component: f7-icon
                              config:
                                f7: "=(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '01d') ? 'sun_max' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '01n') ? 'moon_stars' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '02d') ? 'cloud_sun' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '02n') ? 'cloud_moon' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '03d') ? 'cloud' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '03n') ? 'cloud' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '04d') ? 'cloud' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '04n') ? 'cloud' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '09d') ? 'cloud_heavyrain' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '09n') ? 'cloud_heavyrain' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '10d') ? 'cloud_sun_rain' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '10n') ? 'cloud_moon_rain' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '11d') ? 'cloud_sun_bolt' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '11n') ? 'cloud_moon_bolt' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '13d') ? 'cloud_snow' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '13n') ? 'cloud_snow' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '50d') ? 'cloud_fog' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '50n') ? 'cloud_fog' : '?'"
                                size: var(--weather-condition-icon-size)
                                style:
                                  color: var(--weather-forecast-font-color)
                            - component: f7-row
                              config:
                                class:
                                  - justify-content-center
                              slots:
                                default:
                                  - component: Label
                                    config:
                                      text: "=Math.round(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + ((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + (loop.day_idx))) + '_Maxtemperature'].state.split(' ')[0])+'°'"
                                      style:
                                        font-size: var(--weather-font-size-small)
                                        font-weight: 700
                                        color: var(--weather-forecast-font-color)
                                  - component: Label
                                    config:
                                      text: ""
                                      style:
                                        color: rgba(0,0,0,.2)
                                  - component: Label
                                    config:
                                      text: "=Math.round(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + ((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + (loop.day_idx))) + '_Mintemperature'].state.split(' ')[0])+'°'"
                                      style:
                                        font-size: var(--weather-font-size-small)
                                        font-weight: 700
                                        color: var(--weather-forecast-font-color-light)

Many Thanks for any suggestions or ideas?
Mark

Hey @Mark_VG

first of all, thank you!

One problem was, that the indentation is a bit off. The slot of your f7-row isn’t correctly aligned.
Further more you need to put 2 columns inside the f7 row, to align the contents (Current temp & Min/Max Temp) correctly.

See the f7-docs for more informations on the used components:
Framework7 grid (f7-row / f7-col)
f7-block (only used as a wrapper for the components)

Just a quick drawn explanation of whats happening here:

to give you a first dirty soloution, without optimizing stuff, it would work like:

uid: weatherPopup_extended_uv_feel_min_max
tags:
  - weather
  - popup
  - daily forecast
  - OpenWeatherMap
  - extended
props:
  parameters:
    - description: <b>Optional prefix</b> for item names.
      label: Item prefix
      name: itemPrefix
      required: false
      type: TEXT
      groupName: general
    - description: <b>Additional prefix</b> for item names that belongs to another Things channel (valid for 'StationName' as it might differ)
      label: Additional item prefix
      name: itemPrefix2
      required: false
      type: TEXT
      groupName: general
      advanced: true
    - description: The number of hours you want to forecast (<u>default:</u> <b>12</b>)
      label: Number of hours to forecast
      name: forecastHours
      required: false
      type: TEXT
      groupName: general
    - description: The number of days you want to forecast (<u>default:</u> <b>3</b>)
      label: Number of days to forecast
      name: forecastDays
      required: false
      type: TEXT
      groupName: general
    - description: Activate day & night Indication on hourly forecast (background color & sunrise / sunset indicator icon)
      label: Show sunrise & sunset
      name: sunIndicator
      required: false
      type: BOOLEAN
      groupName: general
    - description: Acitvate 24-hour clock-format (<u>default:</u> <b>12-hour clock-format</b>)
      label: 24h clock-format
      name: dateFormat
      required: false
      type: BOOLEAN
      groupName: general
    - description: Add suffix to the timestamp
      label: Custom timestamp suffix
      name: timestampSuffix
      required: false
      type: TEXT
      groupName: general
    - description: Overwrite the location header
      label: Location title
      name: locationTitle
      required: false
      type: TEXT
      groupName: general
    - description: Folder where you stored your weather-images (<u>default:</u> <b>/static/files/weather_img/</b>)
      label: Image folder
      name: imageFolder
      required: false
      type: TEXT
      groupName: images
    - description: Select a local sight as a centered image (preferably *.svg with the <b>image-content aligned at the bottom</b>)
      label: Local sight image-name
      name: localSightImg
      required: false
      type: TEXT
      groupName: images
    - description: Select a global background-image which will be visible on daytime
      label: Global background image (day-cycle)
      name: globalBackgroundDayImg
      required: true
      type: TEXT
      groupName: images
    - description: Select a global background-image which will be visible on nighttime
      label: Global background image (night-cycle)
      name: globalBackgroundNightImg
      required: true
      type: TEXT
      groupName: images
    - description: Disable background images (local sight & background-image)
      label: Disable local-sight image
      name: disableLocalSightBg
      required: false
      type: BOOLEAN
      groupName: images
      advanced: true
    - description: Alternative title for 'x-hour forecast' within the segmented control, where x gets replaced by the number of hours automatically. (<u>default:</u> <b>-hour forecast</b>)
      label: Translation 'x-hour forecast'
      name: wordingForecastHours
      required: false
      type: TEXT
      groupName: wording
    - description: Alternative title for 'x-day forecast' within the segmented control, where x gets replaced by the number of days automatically. (<u>default:</u> <b>-day forecast</b>)
      label: Translation 'x-day forecast'
      name: wordingForecastDays
      required: false
      type: TEXT
      groupName: wording
    - description: Alternative title for 'Now' in the 12-hour forecast tab
      label: Translation 'Now'
      name: wordingNow
      required: false
      type: TEXT
      groupName: wording
    - description: Alternative title for 'Today' in the 3-day-forecast tab
      label: Translation 'Today'
      name: wordingToday
      required: false
      type: TEXT
      groupName: wording
    - description: Alternative text for 'Sunrise at' in the icon-tooltip (only visible if you've activated the day & night indication)
      label: Translation 'Sunrise at'
      name: wordingSunrise
      required: false
      type: TEXT
      groupName: wording
    - description: Alternative text for 'Sunset at' in the icon-tooltip (only visible if you've activated the day & night indication)
      label: Translation 'Sunset at'
      name: wordingSunset
      required: false
      type: TEXT
      groupName: wording
  parameterGroups:
    - name: general
      label: General settings
      description: All settings which are related to the usage of this widget
    - name: images
      label: Image settings
    - name: wording
      label: Language settings
      description: Set alternative wordings
timestamp: Mar 4, 2021, 2:42:29 PM
component: f7-page
config:
  style:
    background: "=(dayjs().format() >= items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'ForecastToday_Sunrise'].state && dayjs().format() < items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'ForecastToday_Sunset'].state) ? 'linear-gradient(to bottom, #355b8e, #c0d4f0)' : 'repeat-x radial-gradient(white, rgba(255,255,255,.2) 2px, transparent 5px) 50px 0px/420px 420px, repeat-x radial-gradient(white, rgba(255,255,255,.2) 2px, transparent 5px) 10px 0px/650px 650px, repeat-x radial-gradient(white, rgba(255,255,255,.2) 2px, transparent 5px) 200px 0px/450px 450px, repeat-x radial-gradient(white, rgba(255,255,255,.2) 2px, transparent 5px) 200px 80px/350px 350px, repeat-x radial-gradient(white, rgba(255,255,255,.2) 2px, transparent 5px) 0px 0px/260px 260px, repeat-x radial-gradient(white, rgba(255,255,255,.15) 1px, transparent 3px) 50px 0px/200px 200px, repeat-x radial-gradient(white, rgba(255,255,255,.1) 2px, transparent 4px) 130px 0px/250px 100px, repeat-x radial-gradient(rgba(255,255,255,.4), rgba(255,255,255,.1) 2px, transparent 1px) 50px 0px/150px 50px, repeat-x radial-gradient(white, rgba(255,255,255,.2) 1px, transparent 2px) 50px 0px/280px 480px, repeat-x radial-gradient(white, rgba(255,255,255,.2) 1px, transparent 2px) 70px 0px/180px 350px, repeat-x radial-gradient(white, rgba(255,255,255,.1) 1px, transparent 1px) 80px 0px/200px 120px, repeat-x radial-gradient(white, rgba(255,255,255,.1) 2px, transparent 2px) 100px 0px/200px 180px, repeat-x radial-gradient(white, rgba(255,255,255,.1) 1px, transparent 5px) 100px 0px/350px 600px, linear-gradient(to bottom,#413D8F 0%,#CE9FC8 100%)'"
    background-repeat: repeat-x
    -ms-user-select: none
    -moz-user-select: none
    -webkit-user-select: none
    user-select: none
    overflow: hidden
    --f7-page-navbar-offset: none
    --f7-page-toolbar-top-offset: none
    --f7-page-subnavbar-offset: none
    --f7-page-searchbar-offset: none
    --f7-page-content-extra-padding-top: none
    --f7-page-toolbar-bottom-offset: none
    --f7-page-content-extra-padding-bottom: none
    --f7-theme-color: none
    --f7-bars-bg-color: none
    --f7-bars-border-color: none
    --f7-navbar-shadow-image: none
    --f7-navbar-text-color: white
    --f7-bars-text-color: white
    --f7-navbar-link-color: white
    --f7-navbar-bg-color-rgb: none
    --f7-bars-bg-color-rgb: none
    --f7-bars-translucent-opacity: none
    --f7-bars-translucent-blur: none
    backdrop-filter: none
    --f7-button-border-radius: 0
    --weather-condition-icon-size: 30px
    --weather-label-text-transform: normal
    --weather-font-size-xsmall: 14px
    --weather-font-size-small: 16px
    --weather-font-size-medium: 18px
    --weather-font-size-hero: 91px
    --weather-font-color-main: white
    --weather-forecast-location-font-color: rgba(255,255,255,.7)
    --weather-forecast-text-shadow-light: 2px 2px rgba(0,0,0,.15)
    --weather-forecast-text-shadow-strong: 2px 2px rgba(0,0,0,.35)
    --weather-forecast-font-color-light: rgba(0,0,0,.35)
    --weather-forecast-font-color: rgba(0,0,0,.7)
slots:
  default:
    - component: Label
      config:
        text: "=!props.locationTitle ? items[(!props.itemPrefix2 ? (!props.itemPrefix ? '' : props.itemPrefix) : props.itemPrefix2) + 'StationName'].state : props.locationTitle"
        class:
          - text-align-right
          - padding-right
        style:
          text-overflow: ellipsis
          overflow: hidden
          line-height: var(--f7-navbar-link-line-height,var(--f7-navbar-height))
          font-size: var(--weather-font-size-xsmall)
          color: var(--weather-forecast-location-font-color)
          text-shadow: var(--weather-forecast-text-shadow-light)
          text-transform: uppercase
    - component: f7-block
      config:
        text-align: center
        class:
          - no-margin
          - no-padding
          - text-align-center
      slots:
        default:
          - component: f7-row
            config:
              class:
                - display-flex
                - justify-content-space-between
            slots:
              default:
                - component: f7-col
                  config:
                    class:
                      - display-flex
                      - align-self-center
                      - align-items-flex-end
                      - flex-direction-column
                  slots:
                    default:
                      - component: Label
                        config:
                          text: "=(!props.itemPrefix) ? Math.round(items.Current_Temperature.state.split(' ')[0]) + '°' : Math.round(items[props.itemPrefix + 'Current_Temperature'].state.split(' ')[0]) + '°'"
                          style:
                            font-size: var(--weather-font-size-hero)
                            font-weight: lighter
                            line-height: var(--weather-font-size-hero)
                            color: var(--weather-font-color-main)
                            text-shadow: var(--weather-forecast-text-shadow-strong)
                            white-space: nowrap
                            overflow: hidden
                            text-overflow: ellipsis
                - component: f7-col
                  config:
                    class:
                      - display-flex
                      - align-self-center
                      - align-items-flex-start
                      - flex-direction-column
                    style:
                      font-size: var(--weather-font-size-medium)
                      font-weight: lighter
                      color: var(--weather-font-color-main)
                      text-shadow: var(--weather-forecast-text-shadow-strong)
                      z-index: 99
                  slots:
                    default:
                      - component: Label
                        config:
                          text: "Min: 21°C"
                      - component: Label
                        config:
                          text: "Max: 30°C"
          - component: Label
            config:
              text: "=(!props.itemPrefix) ? items.Current_Apparenttemperature.state : 'Feels Like: ' + items[props.itemPrefix + 'Current_Apparenttemperature'].state "
              style:
                font-size: var(--weather-font-size-medium)
                text-shadow: var(--weather-forecast-text-shadow-strong)
                color: var(--weather-font-color-main)
                text-overflow: ellipsis
                white-space: nowrap
                overflow: hidden
                z-index: 999
          - component: Label
            config:
              text: "=(!props.itemPrefix) ? items.Current_Condition.state : items[props.itemPrefix + 'Current_Condition'].state"
              style:
                font-size: var(--weather-font-size-medium)
                text-shadow: var(--weather-forecast-text-shadow-strong)
                color: var(--weather-font-color-main)
                text-overflow: ellipsis
                white-space: nowrap
                overflow: hidden
                z-index: 999
          - component: Label
            config:
              text: "=(!props.itemPrefix) ? items.UVIndex.state : 'UV Index: ' + items[props.itemPrefix + 'UVIndex'].state "
              style:
                font-size: var(--weather-font-size-medium)
                text-shadow: var(--weather-forecast-text-shadow-strong)
                color: var(--weather-font-color-main)
                text-overflow: ellipsis
                white-space: nowrap
                overflow: hidden
                z-index: 999
    - component: f7-block
      config:
        class:
          - no-margin
          - no-padding
        style:
          background: "=(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '01d') ? '' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '01n') ? '' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '02d') ? 'no-repeat top center/750px url(' + ((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + '02.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '02n') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '02.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '03d') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '03.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '03n') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '03.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '04d') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '04.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '04n') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '04.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '09d') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '09.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '09n') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '09.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '10d') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '10.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '10n') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '10.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '11d') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '11.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '11n') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '11.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '13d') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '13.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '13n') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '13.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '50d') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '50.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '50n') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '50.svg)' : '?'"
          height: 100%
          width: 100%
          position: absolute
          top: 0
          left: 0
          right: 0
    - component: oh-image
      config:
        url: "=(dayjs().format() >= items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'ForecastToday_Sunrise'].state && dayjs().format() < items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'ForecastToday_Sunset'].state ) ? ((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + 'sun.svg' : ((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + 'moon.svg'"
        style:
          width: 100%
          max-width: 150px
          min-width: 70px
          position: absolute
          top: 5px
          left: -50px
          z-index: 999
    - component: f7-block
      config:
        style:
          overflow: hidden
          position: absolute
          bottom: 105px
          width: 100%
          height: 100%
          z-index: -1
      slots:
        default:
          - component: oh-image
            config:
              visible: =!props.disableLocalSightBg
              url: "=(dayjs().format() >= items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'ForecastToday_Sunrise'].state && dayjs().format() < items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'ForecastToday_Sunset'].state ) ? ((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + props.globalBackgroundDayImg : ((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + props.globalBackgroundNightImg"
              style:
                position: absolute
                bottom: 0
                right: 0
                left: 0
                margin-right: auto
                margin-left: auto
                width: 100%
                min-width: 800px
                max-width: 1200px
    - component: oh-image
      config:
        visible: =!props.disableLocalSightBg
        url: "=((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + props.localSightImg"
        style:
          position: absolute
          bottom: 138px
          right: 0
          left: 0
          margin-right: auto
          margin-left: auto
          width: 100%
          min-width: 150px
          max-width: 280px
          z-index: 1
    - component: f7-block
      config:
        class:
          - text-align-center
          - align-content-bottom
          - no-margin
        style:
          border-top: 60px solid white
          border-image-source: "='url(' + ((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + 'bottom_mask-white.svg' + ')'"
          -moz-border-image-source: "='url(' + ((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + 'bottom_mask-white.svg' + ')'"
          -webkit-border-image-source: "='url(' + ((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + 'bottom_mask-white.svg' + ')'"
          -o-border-image-source: "='url(' + ((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + 'bottom_mask-white.svg' + ')'"
          -webkit-appearance: none
          border-image-slice: 100% 0 0 0
          border-image-width: 1 0 0 0
          position: absolute
          bottom: 0
          left: 0
          width: 100%
      slots:
        default:
          - component: f7-block
            config:
              class:
                - no-margin
                - no-padding
              style:
                position: absolute
                left: 0
                bottom: 0
                height: calc(100% + 2px)
                width: 100%
                background: white
                -webkit-box-shadow: 10px 10px 10px 20px white
                -moz-box-shadow: 10px 10px 10px 20px white
                box-shadow: 10px 10px 10px 20px white
          - component: f7-segmented
            config:
              strong: true
              style:
                --f7-segmented-strong-button-active-box-shadow: 0 4px 0px -2px gray
                --f7-segmented-strong-button-font-color: gray
                --f7-segmented-strong-bg-color: white
                z-index: 999
            slots:
              default:
                - component: oh-button
                  config:
                    text: '=(!props.wordingForecastHours && !props.forecastHours) ? "12-hour forecast" : (props.wordingForecastHours && !props.forecastHours) ? 12 + props.wordingForecastHours : (!props.wordingForecastHours && props.forecastHours) ? props.forecastHours + "-hour forecast" : props.forecastHours + props.wordingForecastHours'
                    active: =!vars.tab || vars.tab === 'hourly_forecast'
                    action: variable
                    actionVariable: tab
                    actionVariableValue: hourly_forecast
                    style:
                      color: '=(vars.tab === "daily_forecast") ? "lightgray" : "black"'
                - component: oh-button
                  config:
                    text: '=(!props.wordingForecastDays && !props.forecastDays) ? "3-day forecast" : (props.wordingForecastDays && !props.forecastDays) ? 3 + props.wordingForecastDays : (!props.wordingForecastDays && props.forecastDays) ? props.forecastDays + "-day forecast" : props.forecastDays + props.wordingForecastDays'
                    active: =vars.tab === 'daily_forecast'
                    action: variable
                    actionVariable: tab
                    actionVariableValue: daily_forecast
                    style:
                      color: '=(!vars.tab || vars.tab === "hourly_forecast") ? "lightgray" : "black"'
          - component: f7-swiper
            config:
              visible: =!vars.tab || vars.tab === 'hourly_forecast'
              navigation: true
              class:
                - padding-top
                - padding-bottom
              params:
                initalSlide: 0
                runCallbacksOnInit: true
                grabCursor: true
                observer: true
                observeSlideChildren: true
                updateOnWindowResize: true
                spaceBetween: 5
                mousewheel: true
                keyboard: true
                watchOverflow: true
                breakpoints:
                  "0":
                    slidesPerView: 1
                  "240":
                    slidesPerView: "=(!props.forecastHours) ? 2 : ((props.forecastHours < 2) ? Math.round(Number(props.forecastHours) + 1) : 2)"
                  "320":
                    slidesPerView: "=(!props.forecastHours) ? 3 : ((props.forecastHours < 3) ? Math.round(Number(props.forecastHours) + 1) : 3)"
                  "480":
                    slidesPerView: "=(!props.forecastHours) ? 4 : ((props.forecastHours < 4) ? Math.round(Number(props.forecastHours) + 1) : 4)"
                  "640":
                    slidesPerView: "=(!props.forecastHours) ? 5 : ((props.forecastHours < 5) ? Math.round(Number(props.forecastHours) + 1) : 5)"
              style:
                --swiper-navigation-size: 20px
                --swiper-navigation-color: gray
            slots:
              default:
                - component: oh-repeater
                  config:
                    sourceType: range
                    for: hour
                    rangeStart: 0
                    rangeStop: "=(!props.forecastHours) ? 12 : Number(props.forecastHours)"
                    fragment: true
                  slots:
                    default:
                      - component: f7-swiper-slide
                        config:
                          style:
                            background: "=(props.sunIndicator === true) ? ((dayjs().add(loop.hour,'hour').format() >= items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunrise'].state && dayjs().add(loop.hour,'hour').format() <= items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunset'].state) ? 'rgba(44,130,201,.15)' : 'rgba(190,144,212,.15)') : 'none'"
                            border-radius: 5px
                        slots:
                          default:
                            - component: f7-icon
                              config:
                                visible: "=(dayjs().add(loop.hour,'hour').startOf('hour').format() === dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunrise'].state).startOf('hour').format() && props.sunIndicator === true)"
                                f7: sun_max_fill
                                color: black
                                size: 17px
                                tooltip: "=((!props.wordingSunrise) ? 'Sunrise at ' : props.wordingSunrise + ' ') + ((!props.dateFormat) ? dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunrise'].state).format('h:mm A') : dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunrise'].state).format('H:mm')+' h') + '<br><b>' + dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunrise'].state).fromNow() + '</b>'"
                                style:
                                  position: absolute
                                  right: 3px
                                  top: 3px
                                  cursor: pointer
                                  z-index: 9999
                            - component: f7-icon
                              config:
                                visible: "=(dayjs().add(loop.hour,'hour').startOf('hour').format() === dayjs(items['Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunset'].state).startOf('hour').format() && props.sunIndicator === true)"
                                f7: moon_fill
                                color: black
                                size: 17px
                                tooltip: "=((!props.wordingSunset) ? 'Sunset at ' : props.wordingSunset + ' ') + ((!props.dateFormat) ? dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunset'].state).format('h:mm A') : dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunset'].state).format('H:mm') + ' h') + '<br><b>' + dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunset'].state).fromNow() + '</b>'"
                                style:
                                  position: absolute
                                  right: 3px
                                  top: 3px
                                  cursor: pointer
                                  z-index: 9999
                            - component: f7-row
                              config:
                                class:
                                  - justify-content-center
                              slots:
                                default:
                                  - component: Label
                                    config:
                                      text: "=(loop.hour === 0) ? ((!props.wordingNow) ? 'Now' : props.wordingNow) : ((!props.dateFormat) ? dayjs().add(loop.hour,'hour').startOf('hour').format('h A') : dayjs().add(loop.hour,'hour').startOf('hour').format('H')) + (!props.timestampSuffix ? '' : ' ' + props.timestampSuffix)"
                                      style:
                                        font-weight: 400
                                        color: var(--weather-forecast-font-color)
                                        text-transform: var(--weather-label-text-transform)
                            - component: f7-row
                              config:
                                class:
                                  - justify-content-center
                                  - align-items-center
                              slots:
                                default:
                                  - component: f7-icon
                                    config:
                                      f7: "=(items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '01d') ? 'sun_max' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '01n') ? 'moon_stars' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '02d') ? 'cloud_sun' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '02n') ? 'cloud_moon' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '03d') ? 'cloud' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '03n') ? 'cloud' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '04d') ? 'cloud' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '04n') ? 'cloud' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '09d') ? 'cloud_heavyrain' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '09n') ? 'cloud_heavyrain' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '10d') ? 'cloud_sun_rain' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '10n') ? 'cloud_moon_rain' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '11d') ? 'cloud_sun_bolt' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '11n') ? 'cloud_moon_bolt' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '13d') ? 'cloud_snow' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '13n') ? 'cloud_snow' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '50d') ? 'cloud_fog' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '50n') ? 'cloud_fog' : ''"
                                      size: var(--weather-condition-icon-size)
                                      style:
                                        padding-right: 5px
                                        color: var(--weather-forecast-font-color)
                                  - component: Label
                                    config:
                                      text: "=Math.round(items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Temperature'].state.split(' ')[0]) + '°'"
                                      style:
                                        font-size: var(--weather-font-size-small)
                                        font-weight: 700
                                        color: var(--weather-forecast-font-color)
                            - component: f7-row
                              config:
                                class:
                                  - justify-content-center
                                  - align-items-center
                              slots:
                                default:
                                  - component: f7-icon
                                    config:
                                      f7: umbrella
                                      size: 15
                                      style:
                                        color: var(--weather-forecast-font-color-light)
                                        padding-right: 3px
                                  - component: Label
                                    config:
                                      text: "=Math.round(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1)) + '_Precipprobability'].state.split(' ')[0]) + '%'"
                                      style:
                                        font-size: var(--weather-font-size-small)
                                        font-weight: 400
                                        color: var(--weather-forecast-font-color-light)
          - component: f7-swiper
            config:
              visible: =vars.tab === 'daily_forecast'
              navigation: true
              class:
                - padding-top
                - padding-bottom
              params:
                initalSlide: 0
                grabCursor: true
                observer: true
                spaceBetween: 5
                observeSlideChildren: true
                updateOnWindowResize: true
                watchOverflow: true
                mousewheel: true
                keyboard: true
                breakpoints:
                  "0":
                    slidesPerView: 1
                  "210":
                    slidesPerView: "=(!props.forecastDays) ? 2 : ((props.forecastDays < 2) ? Math.round(Number(props.forecastDays) + 1) : 2)"
                  "480":
                    slidesPerView: "=(!props.forecastDays) ? 3 : ((props.forecastDays < 3) ? Math.round(Number(props.forecastDays) + 1) : 3)"
                  "640":
                    slidesPerView: "=(!props.forecastDays) ? 4 : ((props.forecastDays < 4) ? Math.round(Number(props.forecastDays) + 1) : 4)"
              style:
                --swiper-navigation-size: 20px
                --swiper-navigation-color: gray
            slots:
              default:
                - component: oh-repeater
                  config:
                    sourceType: range
                    for: day
                    rangeStart: 0
                    rangeStop: "=(!props.forecastDays) ? 3 : Number(props.forecastDays)"
                    fragment: true
                  slots:
                    default:
                      - component: f7-swiper-slide
                        config: {}
                        slots:
                          default:
                            - component: f7-row
                              config:
                                class:
                                  - justify-content-center
                                  - align-items-center
                              slots:
                                default:
                                  - component: Label
                                    config:
                                      text: "=(loop.day === 0) ? ((!props.wordingToday) ? 'Today' : props.wordingToday) : dayjs().add(loop.day,'day').startOf('day').format('dddd')"
                                      style:
                                        color: var(--weather-forecast-font-color)
                                        text-transform: var(--weather-label-text-transform)
                            - component: f7-icon
                              config:
                                f7: "=(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '01d') ? 'sun_max' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '01n') ? 'moon_stars' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '02d') ? 'cloud_sun' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '02n') ? 'cloud_moon' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '03d') ? 'cloud' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '03n') ? 'cloud' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '04d') ? 'cloud' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '04n') ? 'cloud' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '09d') ? 'cloud_heavyrain' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '09n') ? 'cloud_heavyrain' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '10d') ? 'cloud_sun_rain' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '10n') ? 'cloud_moon_rain' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '11d') ? 'cloud_sun_bolt' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '11n') ? 'cloud_moon_bolt' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '13d') ? 'cloud_snow' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '13n') ? 'cloud_snow' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '50d') ? 'cloud_fog' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '50n') ? 'cloud_fog' : '?'"
                                size: var(--weather-condition-icon-size)
                                style:
                                  color: var(--weather-forecast-font-color)
                            - component: f7-row
                              config:
                                class:
                                  - justify-content-center
                              slots:
                                default:
                                  - component: Label
                                    config:
                                      text: "=Math.round(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + ((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + (loop.day_idx))) + '_Maxtemperature'].state.split(' ')[0])+'°'"
                                      style:
                                        font-size: var(--weather-font-size-small)
                                        font-weight: 700
                                        color: var(--weather-forecast-font-color)
                                  - component: Label
                                    config:
                                      text: ""
                                      style:
                                        color: rgba(0,0,0,.2)
                                  - component: Label
                                    config:
                                      text: "=Math.round(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + ((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + (loop.day_idx))) + '_Mintemperature'].state.split(' ')[0])+'°'"
                                      style:
                                        font-size: var(--weather-font-size-small)
                                        font-weight: 700
                                        color: var(--weather-forecast-font-color-light)

Hi @RGroll

Thank you. That is pretty much what I wanted. I managed to get a bit further during the day today after I took out all the variables and just had flat text to try and understand what was happening.

I see now that the indentation makes all the difference. Also had just realized that I needed the columns and was battling with that.

Will go through the suggested docs and see if I can understand better.

Always appreciate your work.

1 Like

Hi @RGroll

I think understand the rows, columns etc now. I would have battled forever without your help. The alignment was clearly my biggest issue.

Can you point me to a resource for the different style components etc?

For example: z-index: 999 etc.

I have an issue now that on my Android Mobile the Current Temp is “behind” the SUN? So not clearly visible. Trying to fix that.

Cheers
mark

Hey @Mark_VG

glad it helped you. There are tons and tons of ressources regarding css properties - this is nothing OH-specific.

Regarding the z-index, you can find some information here for example.
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/Adding_z-index

I personally like the explanation of css stuff from this site:

To fix the “Sun problem” you have to set the z-index of the image-component, to a lower value than the one from the Label component which shows the current temp - something like:

YAML with min/max values (and a lower z-index)
uid: weatherPopup_extended_uv_feel_min_max
tags:
  - weather
  - popup
  - daily forecast
  - OpenWeatherMap
  - extended
props:
  parameters:
    - description: <b>Optional prefix</b> for item names.
      label: Item prefix
      name: itemPrefix
      required: false
      type: TEXT
      groupName: general
    - description: <b>Additional prefix</b> for item names that belongs to another Things channel (valid for 'StationName' as it might differ)
      label: Additional item prefix
      name: itemPrefix2
      required: false
      type: TEXT
      groupName: general
      advanced: true
    - description: The number of hours you want to forecast (<u>default:</u> <b>12</b>)
      label: Number of hours to forecast
      name: forecastHours
      required: false
      type: TEXT
      groupName: general
    - description: The number of days you want to forecast (<u>default:</u> <b>3</b>)
      label: Number of days to forecast
      name: forecastDays
      required: false
      type: TEXT
      groupName: general
    - description: Activate day & night Indication on hourly forecast (background color & sunrise / sunset indicator icon)
      label: Show sunrise & sunset
      name: sunIndicator
      required: false
      type: BOOLEAN
      groupName: general
    - description: Acitvate 24-hour clock-format (<u>default:</u> <b>12-hour clock-format</b>)
      label: 24h clock-format
      name: dateFormat
      required: false
      type: BOOLEAN
      groupName: general
    - description: Add suffix to the timestamp
      label: Custom timestamp suffix
      name: timestampSuffix
      required: false
      type: TEXT
      groupName: general
    - description: Overwrite the location header
      label: Location title
      name: locationTitle
      required: false
      type: TEXT
      groupName: general
    - description: Folder where you stored your weather-images (<u>default:</u> <b>/static/files/weather_img/</b>)
      label: Image folder
      name: imageFolder
      required: false
      type: TEXT
      groupName: images
    - description: Select a local sight as a centered image (preferably *.svg with the <b>image-content aligned at the bottom</b>)
      label: Local sight image-name
      name: localSightImg
      required: false
      type: TEXT
      groupName: images
    - description: Select a global background-image which will be visible on daytime
      label: Global background image (day-cycle)
      name: globalBackgroundDayImg
      required: true
      type: TEXT
      groupName: images
    - description: Select a global background-image which will be visible on nighttime
      label: Global background image (night-cycle)
      name: globalBackgroundNightImg
      required: true
      type: TEXT
      groupName: images
    - description: Disable background images (local sight & background-image)
      label: Disable local-sight image
      name: disableLocalSightBg
      required: false
      type: BOOLEAN
      groupName: images
      advanced: true
    - description: Alternative title for 'x-hour forecast' within the segmented control, where x gets replaced by the number of hours automatically. (<u>default:</u> <b>-hour forecast</b>)
      label: Translation 'x-hour forecast'
      name: wordingForecastHours
      required: false
      type: TEXT
      groupName: wording
    - description: Alternative title for 'x-day forecast' within the segmented control, where x gets replaced by the number of days automatically. (<u>default:</u> <b>-day forecast</b>)
      label: Translation 'x-day forecast'
      name: wordingForecastDays
      required: false
      type: TEXT
      groupName: wording
    - description: Alternative title for 'Now' in the 12-hour forecast tab
      label: Translation 'Now'
      name: wordingNow
      required: false
      type: TEXT
      groupName: wording
    - description: Alternative title for 'Today' in the 3-day-forecast tab
      label: Translation 'Today'
      name: wordingToday
      required: false
      type: TEXT
      groupName: wording
    - description: Alternative text for 'Sunrise at' in the icon-tooltip (only visible if you've activated the day & night indication)
      label: Translation 'Sunrise at'
      name: wordingSunrise
      required: false
      type: TEXT
      groupName: wording
    - description: Alternative text for 'Sunset at' in the icon-tooltip (only visible if you've activated the day & night indication)
      label: Translation 'Sunset at'
      name: wordingSunset
      required: false
      type: TEXT
      groupName: wording
  parameterGroups:
    - name: general
      label: General settings
      description: All settings which are related to the usage of this widget
    - name: images
      label: Image settings
    - name: wording
      label: Language settings
      description: Set alternative wordings
timestamp: Mar 4, 2021, 2:42:29 PM
component: f7-page
config:
  style:
    background: "=(dayjs().format() >= items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'ForecastToday_Sunrise'].state && dayjs().format() < items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'ForecastToday_Sunset'].state) ? 'linear-gradient(to bottom, #355b8e, #c0d4f0)' : 'repeat-x radial-gradient(white, rgba(255,255,255,.2) 2px, transparent 5px) 50px 0px/420px 420px, repeat-x radial-gradient(white, rgba(255,255,255,.2) 2px, transparent 5px) 10px 0px/650px 650px, repeat-x radial-gradient(white, rgba(255,255,255,.2) 2px, transparent 5px) 200px 0px/450px 450px, repeat-x radial-gradient(white, rgba(255,255,255,.2) 2px, transparent 5px) 200px 80px/350px 350px, repeat-x radial-gradient(white, rgba(255,255,255,.2) 2px, transparent 5px) 0px 0px/260px 260px, repeat-x radial-gradient(white, rgba(255,255,255,.15) 1px, transparent 3px) 50px 0px/200px 200px, repeat-x radial-gradient(white, rgba(255,255,255,.1) 2px, transparent 4px) 130px 0px/250px 100px, repeat-x radial-gradient(rgba(255,255,255,.4), rgba(255,255,255,.1) 2px, transparent 1px) 50px 0px/150px 50px, repeat-x radial-gradient(white, rgba(255,255,255,.2) 1px, transparent 2px) 50px 0px/280px 480px, repeat-x radial-gradient(white, rgba(255,255,255,.2) 1px, transparent 2px) 70px 0px/180px 350px, repeat-x radial-gradient(white, rgba(255,255,255,.1) 1px, transparent 1px) 80px 0px/200px 120px, repeat-x radial-gradient(white, rgba(255,255,255,.1) 2px, transparent 2px) 100px 0px/200px 180px, repeat-x radial-gradient(white, rgba(255,255,255,.1) 1px, transparent 5px) 100px 0px/350px 600px, linear-gradient(to bottom,#413D8F 0%,#CE9FC8 100%)'"
    background-repeat: repeat-x
    -ms-user-select: none
    -moz-user-select: none
    -webkit-user-select: none
    user-select: none
    overflow: hidden
    --f7-page-navbar-offset: none
    --f7-page-toolbar-top-offset: none
    --f7-page-subnavbar-offset: none
    --f7-page-searchbar-offset: none
    --f7-page-content-extra-padding-top: none
    --f7-page-toolbar-bottom-offset: none
    --f7-page-content-extra-padding-bottom: none
    --f7-theme-color: none
    --f7-bars-bg-color: none
    --f7-bars-border-color: none
    --f7-navbar-shadow-image: none
    --f7-navbar-text-color: white
    --f7-bars-text-color: white
    --f7-navbar-link-color: white
    --f7-navbar-bg-color-rgb: none
    --f7-bars-bg-color-rgb: none
    --f7-bars-translucent-opacity: none
    --f7-bars-translucent-blur: none
    backdrop-filter: none
    --f7-button-border-radius: 0
    --weather-condition-icon-size: 30px
    --weather-label-text-transform: normal
    --weather-font-size-xsmall: 14px
    --weather-font-size-small: 16px
    --weather-font-size-medium: 18px
    --weather-font-size-hero: 91px
    --weather-font-color-main: white
    --weather-forecast-location-font-color: rgba(255,255,255,.7)
    --weather-forecast-text-shadow-light: 2px 2px rgba(0,0,0,.15)
    --weather-forecast-text-shadow-strong: 2px 2px rgba(0,0,0,.35)
    --weather-forecast-font-color-light: rgba(0,0,0,.35)
    --weather-forecast-font-color: rgba(0,0,0,.7)
slots:
  default:
    - component: Label
      config:
        text: "=!props.locationTitle ? items[(!props.itemPrefix2 ? (!props.itemPrefix ? '' : props.itemPrefix) : props.itemPrefix2) + 'StationName'].state : props.locationTitle"
        class:
          - text-align-right
          - padding-right
        style:
          text-overflow: ellipsis
          overflow: hidden
          line-height: var(--f7-navbar-link-line-height,var(--f7-navbar-height))
          font-size: var(--weather-font-size-xsmall)
          color: var(--weather-forecast-location-font-color)
          text-shadow: var(--weather-forecast-text-shadow-light)
          text-transform: uppercase
    - component: f7-block
      config:
        text-align: center
        class:
          - no-margin
          - no-padding
          - text-align-center
      slots:
        default:
          - component: f7-row
            config:
              class:
                - display-flex
                - justify-content-space-between
            slots:
              default:
                - component: f7-col
                  config:
                    class:
                      - display-flex
                      - align-self-center
                      - align-items-flex-end
                      - flex-direction-column
                  slots:
                    default:
                      - component: Label
                        config:
                          text: "=(!props.itemPrefix) ? Math.round(items.Current_Temperature.state.split(' ')[0]) + '°' : Math.round(items[props.itemPrefix + 'Current_Temperature'].state.split(' ')[0]) + '°'"
                          style:
                            font-size: var(--weather-font-size-hero)
                            font-weight: lighter
                            line-height: var(--weather-font-size-hero)
                            color: var(--weather-font-color-main)
                            text-shadow: var(--weather-forecast-text-shadow-strong)
                            white-space: nowrap
                            overflow: hidden
                            text-overflow: ellipsis
                            z-index: 99
                - component: f7-col
                  config:
                    class:
                      - display-flex
                      - align-self-center
                      - align-items-flex-start
                      - flex-direction-column
                    style:
                      font-size: var(--weather-font-size-medium)
                      font-weight: lighter
                      color: var(--weather-font-color-main)
                      text-shadow: var(--weather-forecast-text-shadow-strong)
                      z-index: 99
                  slots:
                    default:
                      - component: Label
                        config:
                          text: "Min: 21°C"
                      - component: Label
                        config:
                          text: "Max: 30°C"
          - component: Label
            config:
              text: "=(!props.itemPrefix) ? items.Current_Apparenttemperature.state : 'Feels Like: ' + items[props.itemPrefix + 'Current_Apparenttemperature'].state "
              style:
                font-size: var(--weather-font-size-medium)
                text-shadow: var(--weather-forecast-text-shadow-strong)
                color: var(--weather-font-color-main)
                text-overflow: ellipsis
                white-space: nowrap
                overflow: hidden
                z-index: 999
          - component: Label
            config:
              text: "=(!props.itemPrefix) ? items.Current_Condition.state : items[props.itemPrefix + 'Current_Condition'].state"
              style:
                font-size: var(--weather-font-size-medium)
                text-shadow: var(--weather-forecast-text-shadow-strong)
                color: var(--weather-font-color-main)
                text-overflow: ellipsis
                white-space: nowrap
                overflow: hidden
                z-index: 999
          - component: Label
            config:
              text: "=(!props.itemPrefix) ? items.UVIndex.state : 'UV Index: ' + items[props.itemPrefix + 'UVIndex'].state "
              style:
                font-size: var(--weather-font-size-medium)
                text-shadow: var(--weather-forecast-text-shadow-strong)
                color: var(--weather-font-color-main)
                text-overflow: ellipsis
                white-space: nowrap
                overflow: hidden
                z-index: 999
    - component: f7-block
      config:
        class:
          - no-margin
          - no-padding
        style:
          background: "=(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '01d') ? '' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '01n') ? '' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '02d') ? 'no-repeat top center/750px url(' + ((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + '02.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '02n') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '02.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '03d') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '03.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '03n') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '03.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '04d') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '04.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '04n') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '04.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '09d') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '09.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '09n') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '09.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '10d') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '10.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '10n') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '10.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '11d') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '11.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '11n') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '11.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '13d') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '13.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '13n') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '13.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '50d') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '50.svg)' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Iconid'].state === '50n') ? 'no-repeat top center/750px url(' + ((props.imageFolder === undefined) ? '/static/files/weather_img/' : props.imageFolder) + '50.svg)' : '?'"
          height: 100%
          width: 100%
          position: absolute
          top: 0
          left: 0
          right: 0
    - component: oh-image
      config:
        url: "=(dayjs().format() >= items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'ForecastToday_Sunrise'].state && dayjs().format() < items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'ForecastToday_Sunset'].state ) ? ((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + 'sun.svg' : ((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + 'moon.svg'"
        style:
          width: 100%
          max-width: 150px
          min-width: 70px
          position: absolute
          top: 5px
          left: -50px
          z-index: 91
    - component: f7-block
      config:
        style:
          overflow: hidden
          position: absolute
          bottom: 105px
          width: 100%
          height: 100%
          z-index: -1
      slots:
        default:
          - component: oh-image
            config:
              visible: =!props.disableLocalSightBg
              url: "=(dayjs().format() >= items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'ForecastToday_Sunrise'].state && dayjs().format() < items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'ForecastToday_Sunset'].state ) ? ((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + props.globalBackgroundDayImg : ((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + props.globalBackgroundNightImg"
              style:
                position: absolute
                bottom: 0
                right: 0
                left: 0
                margin-right: auto
                margin-left: auto
                width: 100%
                min-width: 800px
                max-width: 1200px
    - component: oh-image
      config:
        visible: =!props.disableLocalSightBg
        url: "=((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + props.localSightImg"
        style:
          position: absolute
          bottom: 138px
          right: 0
          left: 0
          margin-right: auto
          margin-left: auto
          width: 100%
          min-width: 150px
          max-width: 280px
          z-index: 1
    - component: f7-block
      config:
        class:
          - text-align-center
          - align-content-bottom
          - no-margin
        style:
          border-top: 60px solid white
          border-image-source: "='url(' + ((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + 'bottom_mask-white.svg' + ')'"
          -moz-border-image-source: "='url(' + ((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + 'bottom_mask-white.svg' + ')'"
          -webkit-border-image-source: "='url(' + ((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + 'bottom_mask-white.svg' + ')'"
          -o-border-image-source: "='url(' + ((!props.imageFolder) ? '/static/files/weather_img/' : props.imageFolder) + 'bottom_mask-white.svg' + ')'"
          -webkit-appearance: none
          border-image-slice: 100% 0 0 0
          border-image-width: 1 0 0 0
          position: absolute
          bottom: 0
          left: 0
          width: 100%
      slots:
        default:
          - component: f7-block
            config:
              class:
                - no-margin
                - no-padding
              style:
                position: absolute
                left: 0
                bottom: 0
                height: calc(100% + 2px)
                width: 100%
                background: white
                -webkit-box-shadow: 10px 10px 10px 20px white
                -moz-box-shadow: 10px 10px 10px 20px white
                box-shadow: 10px 10px 10px 20px white
          - component: f7-segmented
            config:
              strong: true
              style:
                --f7-segmented-strong-button-active-box-shadow: 0 4px 0px -2px gray
                --f7-segmented-strong-button-font-color: gray
                --f7-segmented-strong-bg-color: white
                z-index: 999
            slots:
              default:
                - component: oh-button
                  config:
                    text: '=(!props.wordingForecastHours && !props.forecastHours) ? "12-hour forecast" : (props.wordingForecastHours && !props.forecastHours) ? 12 + props.wordingForecastHours : (!props.wordingForecastHours && props.forecastHours) ? props.forecastHours + "-hour forecast" : props.forecastHours + props.wordingForecastHours'
                    active: =!vars.tab || vars.tab === 'hourly_forecast'
                    action: variable
                    actionVariable: tab
                    actionVariableValue: hourly_forecast
                    style:
                      color: '=(vars.tab === "daily_forecast") ? "lightgray" : "black"'
                - component: oh-button
                  config:
                    text: '=(!props.wordingForecastDays && !props.forecastDays) ? "3-day forecast" : (props.wordingForecastDays && !props.forecastDays) ? 3 + props.wordingForecastDays : (!props.wordingForecastDays && props.forecastDays) ? props.forecastDays + "-day forecast" : props.forecastDays + props.wordingForecastDays'
                    active: =vars.tab === 'daily_forecast'
                    action: variable
                    actionVariable: tab
                    actionVariableValue: daily_forecast
                    style:
                      color: '=(!vars.tab || vars.tab === "hourly_forecast") ? "lightgray" : "black"'
          - component: f7-swiper
            config:
              visible: =!vars.tab || vars.tab === 'hourly_forecast'
              navigation: true
              class:
                - padding-top
                - padding-bottom
              params:
                initalSlide: 0
                runCallbacksOnInit: true
                grabCursor: true
                observer: true
                observeSlideChildren: true
                updateOnWindowResize: true
                spaceBetween: 5
                mousewheel: true
                keyboard: true
                watchOverflow: true
                breakpoints:
                  "0":
                    slidesPerView: 1
                  "240":
                    slidesPerView: "=(!props.forecastHours) ? 2 : ((props.forecastHours < 2) ? Math.round(Number(props.forecastHours) + 1) : 2)"
                  "320":
                    slidesPerView: "=(!props.forecastHours) ? 3 : ((props.forecastHours < 3) ? Math.round(Number(props.forecastHours) + 1) : 3)"
                  "480":
                    slidesPerView: "=(!props.forecastHours) ? 4 : ((props.forecastHours < 4) ? Math.round(Number(props.forecastHours) + 1) : 4)"
                  "640":
                    slidesPerView: "=(!props.forecastHours) ? 5 : ((props.forecastHours < 5) ? Math.round(Number(props.forecastHours) + 1) : 5)"
              style:
                --swiper-navigation-size: 20px
                --swiper-navigation-color: gray
            slots:
              default:
                - component: oh-repeater
                  config:
                    sourceType: range
                    for: hour
                    rangeStart: 0
                    rangeStop: "=(!props.forecastHours) ? 12 : Number(props.forecastHours)"
                    fragment: true
                  slots:
                    default:
                      - component: f7-swiper-slide
                        config:
                          style:
                            background: "=(props.sunIndicator === true) ? ((dayjs().add(loop.hour,'hour').format() >= items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunrise'].state && dayjs().add(loop.hour,'hour').format() <= items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunset'].state) ? 'rgba(44,130,201,.15)' : 'rgba(190,144,212,.15)') : 'none'"
                            border-radius: 5px
                        slots:
                          default:
                            - component: f7-icon
                              config:
                                visible: "=(dayjs().add(loop.hour,'hour').startOf('hour').format() === dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunrise'].state).startOf('hour').format() && props.sunIndicator === true)"
                                f7: sun_max_fill
                                color: black
                                size: 17px
                                tooltip: "=((!props.wordingSunrise) ? 'Sunrise at ' : props.wordingSunrise + ' ') + ((!props.dateFormat) ? dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunrise'].state).format('h:mm A') : dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunrise'].state).format('H:mm')+' h') + '<br><b>' + dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunrise'].state).fromNow() + '</b>'"
                                style:
                                  position: absolute
                                  right: 3px
                                  top: 3px
                                  cursor: pointer
                                  z-index: 9999
                            - component: f7-icon
                              config:
                                visible: "=(dayjs().add(loop.hour,'hour').startOf('hour').format() === dayjs(items['Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunset'].state).startOf('hour').format() && props.sunIndicator === true)"
                                f7: moon_fill
                                color: black
                                size: 17px
                                tooltip: "=((!props.wordingSunset) ? 'Sunset at ' : props.wordingSunset + ' ') + ((!props.dateFormat) ? dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunset'].state).format('h:mm A') : dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunset'].state).format('H:mm') + ' h') + '<br><b>' + dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunset'].state).fromNow() + '</b>'"
                                style:
                                  position: absolute
                                  right: 3px
                                  top: 3px
                                  cursor: pointer
                                  z-index: 9999
                            - component: f7-row
                              config:
                                class:
                                  - justify-content-center
                              slots:
                                default:
                                  - component: Label
                                    config:
                                      text: "=(loop.hour === 0) ? ((!props.wordingNow) ? 'Now' : props.wordingNow) : ((!props.dateFormat) ? dayjs().add(loop.hour,'hour').startOf('hour').format('h A') : dayjs().add(loop.hour,'hour').startOf('hour').format('H')) + (!props.timestampSuffix ? '' : ' ' + props.timestampSuffix)"
                                      style:
                                        font-weight: 400
                                        color: var(--weather-forecast-font-color)
                                        text-transform: var(--weather-label-text-transform)
                            - component: f7-row
                              config:
                                class:
                                  - justify-content-center
                                  - align-items-center
                              slots:
                                default:
                                  - component: f7-icon
                                    config:
                                      f7: "=(items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '01d') ? 'sun_max' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '01n') ? 'moon_stars' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '02d') ? 'cloud_sun' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '02n') ? 'cloud_moon' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '03d') ? 'cloud' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '03n') ? 'cloud' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '04d') ? 'cloud' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '04n') ? 'cloud' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '09d') ? 'cloud_heavyrain' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '09n') ? 'cloud_heavyrain' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '10d') ? 'cloud_sun_rain' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '10n') ? 'cloud_moon_rain' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '11d') ? 'cloud_sun_bolt' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '11n') ? 'cloud_moon_bolt' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '13d') ? 'cloud_snow' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '13n') ? 'cloud_snow' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '50d') ? 'cloud_fog' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Iconid'].state === '50n') ? 'cloud_fog' : ''"
                                      size: var(--weather-condition-icon-size)
                                      style:
                                        padding-right: 5px
                                        color: var(--weather-forecast-font-color)
                                  - component: Label
                                    config:
                                      text: "=Math.round(items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1))) + '_Temperature'].state.split(' ')[0]) + '°'"
                                      style:
                                        font-size: var(--weather-font-size-small)
                                        font-weight: 700
                                        color: var(--weather-forecast-font-color)
                            - component: f7-row
                              config:
                                class:
                                  - justify-content-center
                                  - align-items-center
                              slots:
                                default:
                                  - component: f7-icon
                                    config:
                                      f7: umbrella
                                      size: 15
                                      style:
                                        color: var(--weather-forecast-font-color-light)
                                        padding-right: 3px
                                  - component: Label
                                    config:
                                      text: "=Math.round(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'ForecastHours' + ((loop.hour_idx+1 < 10 ? '0'+(loop.hour_idx+1) : loop.hour_idx+1)) + '_Precipprobability'].state.split(' ')[0]) + '%'"
                                      style:
                                        font-size: var(--weather-font-size-small)
                                        font-weight: 400
                                        color: var(--weather-forecast-font-color-light)
          - component: f7-swiper
            config:
              visible: =vars.tab === 'daily_forecast'
              navigation: true
              class:
                - padding-top
                - padding-bottom
              params:
                initalSlide: 0
                grabCursor: true
                observer: true
                spaceBetween: 5
                observeSlideChildren: true
                updateOnWindowResize: true
                watchOverflow: true
                mousewheel: true
                keyboard: true
                breakpoints:
                  "0":
                    slidesPerView: 1
                  "210":
                    slidesPerView: "=(!props.forecastDays) ? 2 : ((props.forecastDays < 2) ? Math.round(Number(props.forecastDays) + 1) : 2)"
                  "480":
                    slidesPerView: "=(!props.forecastDays) ? 3 : ((props.forecastDays < 3) ? Math.round(Number(props.forecastDays) + 1) : 3)"
                  "640":
                    slidesPerView: "=(!props.forecastDays) ? 4 : ((props.forecastDays < 4) ? Math.round(Number(props.forecastDays) + 1) : 4)"
              style:
                --swiper-navigation-size: 20px
                --swiper-navigation-color: gray
            slots:
              default:
                - component: oh-repeater
                  config:
                    sourceType: range
                    for: day
                    rangeStart: 0
                    rangeStop: "=(!props.forecastDays) ? 3 : Number(props.forecastDays)"
                    fragment: true
                  slots:
                    default:
                      - component: f7-swiper-slide
                        config: {}
                        slots:
                          default:
                            - component: f7-row
                              config:
                                class:
                                  - justify-content-center
                                  - align-items-center
                              slots:
                                default:
                                  - component: Label
                                    config:
                                      text: "=(loop.day === 0) ? ((!props.wordingToday) ? 'Today' : props.wordingToday) : dayjs().add(loop.day,'day').startOf('day').format('dddd')"
                                      style:
                                        color: var(--weather-forecast-font-color)
                                        text-transform: var(--weather-label-text-transform)
                            - component: f7-icon
                              config:
                                f7: "=(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '01d') ? 'sun_max' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '01n') ? 'moon_stars' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '02d') ? 'cloud_sun' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '02n') ? 'cloud_moon' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '03d') ? 'cloud' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '03n') ? 'cloud' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '04d') ? 'cloud' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '04n') ? 'cloud' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '09d') ? 'cloud_heavyrain' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '09n') ? 'cloud_heavyrain' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '10d') ? 'cloud_sun_rain' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '10n') ? 'cloud_moon_rain' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '11d') ? 'cloud_sun_bolt' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '11n') ? 'cloud_moon_bolt' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '13d') ? 'cloud_snow' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '13n') ? 'cloud_snow' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '50d') ? 'cloud_fog' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_Iconid'].state === '50n') ? 'cloud_fog' : '?'"
                                size: var(--weather-condition-icon-size)
                                style:
                                  color: var(--weather-forecast-font-color)
                            - component: f7-row
                              config:
                                class:
                                  - justify-content-center
                              slots:
                                default:
                                  - component: Label
                                    config:
                                      text: "=Math.round(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + ((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + (loop.day_idx))) + '_Maxtemperature'].state.split(' ')[0])+'°'"
                                      style:
                                        font-size: var(--weather-font-size-small)
                                        font-weight: 700
                                        color: var(--weather-forecast-font-color)
                                  - component: Label
                                    config:
                                      text: ""
                                      style:
                                        color: rgba(0,0,0,.2)
                                  - component: Label
                                    config:
                                      text: "=Math.round(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + ((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + (loop.day_idx))) + '_Mintemperature'].state.split(' ')[0])+'°'"
                                      style:
                                        font-size: var(--weather-font-size-small)
                                        font-weight: 700
                                        color: var(--weather-forecast-font-color-light)

Hi @RGroll

Once again , thanks for all the help. I am however clearly missing the basics with the F7 grids stuff.

Firstly battling to see how that ties in to the OH3 implementation… But also seem to have an issue with the alignments again.

I have been trying to add features to your PopupWidget#2 to get a grasp of the layout etc, and am now stuck with the following:

I have added the Sunrise and Sunset icons and times. This is done using columns (4 ), but then I saw your one suggestion that this may work better as just a row with the icon and text in a line?

So tried to implement that above the values shown - all I get however is a space created and nothing displays (so I think I must have messed up the alignment, but just can’t fix it.

Widget.txt (50.2 KB)

What I have "added is the following:

          - component: f7-block
            config:
              class:
                - padding
              slots:
                default:
                  - component: f7-row
                    config:
                      style:
                        flex-wrap: nowrap
                        z-index: 999
                    slots:
                      default:
                        - component: f7-icon
                          config:
                            f7: sunrise
                            size: 30
                            color: white
                            class:
                              - padding-right
                  - component: Label
                    config:
                      text: "Test Text"
                      style:
                        color: var(--weather-font-color-main)
                        font-size: 18px
                        line-height: 30px
                        text-align: left
                        white-space: nowrap
                        overflow: hidden
                        text-overflow: ellipsis

My end goal is to have two columns in two rows with Today and Tomorrow with eh Sunrise and Sunset for each day.

Can you see what I have done wrong?

Thanks
Mark