edit: almost forgot, it also has slight animations built in gif is jagged but the animations are smooth and unobtrusive.
Moon
- Add moon integration and create sensor
1.1 - integrations/moon
1.2 - create template sensor for emoji and picture. Rename it to โsensor.moon_phaseโ
template:
- sensor:
- unique_id: moon_moon
name: >-
{{ state_attr('sensor.moon','friendly_name') }}
icon: >-
{{ state_attr('sensor.moon','icon') }}
state: >-
{{ states('sensor.moon') | replace('_',' ') | capitalize }}
attributes:
entity_picture: >-
{% set moon = states('sensor.moon') %}
{% set face = '_face' if moon in ['first_quarter','last_quarter','full_moon','new_moon'] else '' %}
/local/emoji/moon/{{moon}}{{face}}.svg
emoji: >-
{% set values = {'first_quarter':'๐','last_quarter':'๐','full_moon':'๐','new_moon':'๐','waxing_crescent':'๐','waning_gibbous':'๐','waxing_gibbous':'๐','waning_crescent':'๐'} %}
{% if moon in ['first_quarter','last_quarter','full_moon','new_moon'] %}
{% set values = {'first_quarter':'๐','last_quarter':'๐','full_moon':'๐','new_moon':'๐'}
%}
{% endif %}
{% set value = states('sensor.moon') %}
{{ values[value] if value in values.keys() else 'off' }}
Weather
Create a template sensor Weather. Rename your weather entity_id! Rename the sensor to โsensor.weatherโ
template:
- sensor:
- unique_id: weather_forecast
name: Weather Forecast
icon: >-
mdi:weather-{{ states('weather.hernes') }}
state: >-
{{ states('weather.hernes') | replace('_',' ') | capitalize }}
attributes:
forecast_high: >-
{{ state_attr('weather.hernes','forecast')[0].temperature | int(0) | default(0) }}
forecast_low: >-
{{ state_attr('weather.hernes','forecast')[0].templow | int(0) | default(0) }}
entity_picture: >-
{%- set elevation = state_attr('sun.sun', 'elevation') | int -%}
{%- set rising = state_attr('sun.sun', 'rising') -%}
{%- set azimuth = state_attr('sun.sun', 'azimuth') | int -%}
{% set weather = states('weather.hernes') %}
{% if weather == 'sunny' and elevation <= -12 %}
{{ state_attr('sensor.moon_phase','entity_picture') }}
{% else %}
{% if weather in ['unknown','unavailable'] %}
/local/emoji/weather/{{ ['unicorn','sparkles','rainbow'] | random }}.svg
{% else %}
/local/emoji/weather/{{weather}}.svg
{% endif %}
{% endif %}
emoji: >-
{%- set elevation = state_attr('sun.sun', 'elevation') | int -%}
{%- set rising = state_attr('sun.sun', 'rising') -%}
{%- set azimuth = state_attr('sun.sun', 'azimuth') | int -%}
{% set values = {'cloudy':'โ๏ธ','fog':'๐','lightning-rainy':'โ๏ธ','lightning':'๐ฉ๏ธ','partlycloudy':'โ
','rainy':'๐ง๏ธ','snowy':'โ๏ธ','snowy-rainy':'๐จ๏ธ','sunny':'โ๏ธ','windy':'๐ฌ๏ธ'} %}
{% set value = states('weather.hernes') %}
{% if values[value] == 'โ๏ธ' and elevation <= -12 %}
{{ state_attr('sensor.moon_phase','emoji') }}
{% else %}
{{ values[value] if value in values.keys() else '๐ฏ' }}
{% endif %}
Solar
Create sensor solar.
This get pictures based on states of weather, moon position, etc.
Rename it to โsensor.solarโ
template:
- sensor:
- unique_id: solar
name: >-
{%- set elevation = state_attr('sun.sun', 'elevation') | int -%}
{%- set rising = state_attr('sun.sun', 'rising') -%}
{%- set azimuth = state_attr('sun.sun', 'azimuth') | int -%}
{%- if elevation <= -12 -%}
{%- if (0 <= azimuth <= 10) or (350 <= azimuth <= 360) -%}
Midnight
{%- else -%}
Night
{%- endif -%}
{%- elif -6 < elevation <= 0 -%}
{{- 'Sunrise' if rising else 'Sunset' -}}
{%- elif -12 < elevation <= -6 -%}
{{- 'Dawn' if rising else 'Dusk' -}}
{%- else -%}
{%- if 160 <= azimuth <= 200 -%}
Noon
{%- else -%}
Day
{%- endif -%}
{%- endif -%}
icon: >-
{%- set elevation = state_attr('sun.sun', 'elevation') | int -%}
{%- set rising = state_attr('sun.sun', 'rising') -%}
{%- set azimuth = state_attr('sun.sun', 'azimuth') -%}
{%- if elevation <= -12 -%}
{%- if (0 <= azimuth <= 10) or (350 <= azimuth <= 360) -%}
mdi:moon-waning-crescent
{%- else -%}
mdi:weather-night
{%- endif -%}
{%- elif -6 < elevation <= 0 -%}
{{- 'mdi:theme-light-dark' if rising else 'mdi:weather-sunset' -}}
{%- elif -12 < elevation <= -6 -%}
{{- 'mdi:weather-sunset-up' if rising else 'mdi:weather-sunset-down' -}}
{%- else -%}
{%- if 160 <= azimuth <= 200 -%}
mdi:white-balance-sunny
{%- else -%}
mdi:weather-sunny
{%- endif -%}
{%- endif -%}
state: >-
{%- set elevation = state_attr('sun.sun', 'elevation') -%}
{%- set rising = state_attr('sun.sun', 'rising') -%}
{%- set azimuth = state_attr('sun.sun', 'azimuth') -%}
{%- if elevation <= -12 -%}
{%- if (0 <= azimuth <= 10) or (350 <= azimuth <= 360) -%}
๐
{%- else -%}
๐
{%- endif -%}
{%- elif -6 < elevation <= 0 -%}
{{- '๐
' if rising else '๐' -}}
{%- elif -12 < elevation <= -6 -%}
{{- '๐' if rising else '๐' -}}
{%- else -%}
{%- if 160 < azimuth < 200 -%}
๐
{%- else -%}
๐๏ธ
{%- endif -%}
{%- endif -%}
attributes:
entity_picture: >-
{% set weather = states('weather.hernes') %}
{% set solar = state_attr('sensor.solar','friendly_name') %}
{% if solar in ['Midnight','Night'] %}
{{ state_attr('sensor.moon_phase','entity_picture') }}
{% elif solar in ['Sunrise','Sunset','Dawn','Dusk'] %}
/local/emoji/solar/{{solar}}.svg
{% else %}
{% if weather == 'sunny' %}
{% if state_attr('weather.hernes','temperature') >= 0 %}
/local/emoji/weather/{{weather}}.svg
{%else%}
/local/emoji/weather/snowy.svg
{% endif %}
{% else %}
/local/emoji/weather/{{weather}}.svg
{% endif %}
{% endif %}
weather_picture: >-
{{ state_attr('sensor.weather','entity_picture') }}
weather_emoji: >-
{{ state_attr('sensor.weather','emoji') }}
solar_picture: >-
{% set solar = state_attr('sensor.solar','friendly_name') %}
/local/emoji/solar/{{solar}}.svg
solar_emoji: >-
{{ states('sensor.solar') }}
moon_picture: >-
{{ state_attr('sensor.moon_phase','entity_picture') }}
moon_emoji: >-
{{ state_attr('sensor.moon_phase','emoji') }}
solar_moon_picture: >-
{% set solar = state_attr('sensor.solar','friendly_name') %}
{% if solar in ['Midnight','Night'] %}
{{ state_attr('sensor.moon_phase','entity_picture') }}
{% else %}
/local/emoji/solar/{{solar}}.svg
{% endif %}
Icons
Download the icons:
Get Microsoft Fluent UI Emoji and add to your config/www folder
- [easier version] Export them from Figma, which style you like:
2.1 - 3D emoji
2.2 - Flat emoji
It now exports SVG icons with correct names, and puts them in appropriate folders, eg. /emoji/solar/noon.svg
Select the menu icon โ file โ export and all get saved with correct naming the sensor uses:
Layout
Create a new view, add this code and change sensor names:
type: custom:layout-card
layout_type: custom:grid-layout
cards:
- type: custom:layout-card
layout_type: custom:grid-layout
cards:
- type: markdown
content: >-
<img id="main_shadow" src="{{state_attr('sensor.solar','moon_picture') }}" height="48" width="48">
card_mod:
style: |
ha-card{
background: transparent;
display:flex;
align-items: center;
justify-content: center;
}
ha-card>ha-markdown{
border-radius: 100%;
background:transparent;
padding: 0 !important;
line-height:0;
display:flex;
align-items: center;
justify-content: center;
overflow:hidden;
{% set time = now().hour %}
{% set brightness = ((5 - ((time/24*10) | round(0) -5 ) | abs)/10 + 0.5) | float %}
opacity:{{brightness}};
{% set time = now().hour %}
{% set top = ( (time - 12)*1 ) %}
transform:scale(5) translateY({{top}}px) translateX(-48px);
{% set blur = ((((((time/24))-0.5)|abs)*5)|round(0)|int)+5 %}
filter:blur({{blur}}px);
}
view_layout:
grid-column: 1
grid-row: 1
- type: markdown
content: >-
<img id="main" src="{{ state_attr('sensor.solar','solar_moon_picture')}}" height="48" width="48">
card_mod:
style: |
ha-card{
background: transparent;
display:flex;
align-items: center;
justify-content: center;
overflow:hidden;
{% set time = now().hour %}
{% set sun = states.sensor.sun_elevation.state | int %}
{% set sunpos = ((((( -16 - (sun | int ) - 8)) / 32 * 100) | round(0) ) * 24 / 100) | round(0) %}
{% set left = ((5 - ((time/24*10) | round(0) -5 ) | abs) * 24 ) | int - 240 %}
{% set top = ( (time - 12)*2 ) %}
transform: scale(5) translateX(-48px) translateY({{top}}px);
}
ha-card>ha-markdown
background:transparent;
padding: 0 !important;
line-height:0;
display:flex;
align-items: center;
justify-content: center;
overflow:hidden;
}
view_layout:
grid-column: 1
grid-row: 1
- type: markdown
content: >-
<img id="weatherblur" src="{{ state_attr('sensor.solar','weather_picture') }}" height="48" width="48">
card_mod:
style: |
:host {
overflow:hidden;
}
ha-card{
background: transparent;
display:flex;
align-items: center;
justify-content: center;
{% set sun = states.sensor.sun_elevation.state %}
transform:scale(2.5) translateY({{ ((-((((( -16 - (sun | int ) - 8)) / 32 * 100) | round(0) ) *24 / 100) ) * 2) | round(0) }}px) translateX({{ ((-((((( -16 - (sun | int ) - 8)) / 32 * 100) | round(0) ) *24 / 100) ) * 2) | round(0) }}px);
{% set time = now().hour %}
{% set brightness = ((5 - ((time/24*10) | round(0) -5 ) | abs)/10 + 0.5) | float %}
}
ha-card>ha-markdown{
transform:scale(0.5) translateY(150%) translateX(-100%);
background:transparent;
padding: 0 !important;
line-height:0;
display:flex;
align-items: center;
justify-content: center;
overflow:hidden;
}
view_layout:
grid-column: 1
grid-row: 1
layout:
grid-gap: 0
margin: 0
padding: 0
height: 100%
width: 100%
card_mod:
style: |
ha-card{
height:100%;
background:red;
}
:root{
overflow:hidden;
height:100%;
}
layout-card, grid-layout{
overflow: hidden;
height:100%;
transform:scale(3);
}
view_layout:
grid-column: 1 / span 6
grid-row: 1 / span 6
- type: markdown
content: ' '
card_mod:
style: |
:host{
overflow:hidden;
width:100%;
height: 100%;
padding:0;
margin:0
}
ha-card{
box-sizing:border-box;
{% set time = now().hour %}
{% set hue = (time/24*360 | round(2) ) | int %}
{% set hue2 = ((time/24*360 | round(2) ) | int) - 45 %}
{% set hue3 = ((time/24*360 | round(2) ) | int) - 30 %}
background: radial-gradient( transparent, hsla({{hue3}},100%,50%,0.0), hsla({{hue2}},100%,50%,0.0), hsla({{hue}},100%,50%,0), hsla({{hue}},100%,50%,0));
background-size: 100% 100%;
background-repeat: no-repeat;
background-position: top center;
backdrop-filter: blur(10px);
display: flex;
align-items: end;
justify-content: left;
font:var(--h3-font);
color: var(--accent-text-color);
border-radius: 100%;
{% set time = now().hour %}
{% set left = ((5 - ((time/24*10) | round(0) -5 ) | abs) * 24 ) | int - 120 %}
{% set top = ((5 - ((time/24*10) | round(0) -5 ) ) * -24 ) | int + 240 %}
/*transform: translateX({{ left }}px) translateY({{top}}px);*/
transform: translateX(-50%) translateY(50%);
position:relative;
}
ha-card .card-header{
font-size:1rem;
}
ha-card > ha-markdown{
padding:0 !important;
}
view_layout:
grid-column: 1 / span 6
grid-row: 1 / span 6
- type: custom:layout-card
layout_type: custom:grid-layout
cards:
- type: markdown
content: >-
<img id="weather1" src="{{ state_attr('sensor.solar','weather_picture') }}" height="48" width="48">
card_mod:
style: |
:host {
overflow:hidden;
}
ha-card{
background: transparent;
display:flex;
align-items: center;
justify-content: center;
{% set sun = states.sensor.sun_elevation.state %}
transform:scale(1.5) translateY({{ ((-((((( -16 - (sun | int ) - 8)) / 32 * 100) | round(0) ) *24 / 100) ) * 2) | round(0) }}px) translateX({{ ((-((((( -16 - (sun | int ) - 8)) / 32 * 100) | round(0) ) *24 / 100) ) * 2) | round(0) }}px);
{% set time = now().hour %}
{% set brightness = ((5 - ((time/24*10) | round(0) -5 ) | abs)/10 + 0.5) | float %}
}
ha-card>ha-markdown{
transform:scale(0.5) translateX(-200%);
background:transparent;
padding: 0 !important;
line-height:0;
display:flex;
align-items: center;
justify-content: center;
overflow:hidden;
}
view_layout:
grid-column: 1
grid-row: 1
- type: markdown
content: >-
<img id="weather2" src="{{ state_attr('sensor.solar','weather_picture') }}" height="48" width="48">
card_mod:
style: |
:host {
overflow:hidden;
}
ha-card{
background: transparent;
display:flex;
align-items: center;
justify-content: center;
{% set sun = states.sensor.sun_elevation.state %}
transform:scale(2.5) translateY({{ ((-((((( -16 - (sun | int ) - 8)) / 32 * 100) | round(0) ) *24 / 100) ) * 2) | round(0) }}px) translateX({{ ((-((((( -16 - (sun | int ) - 8)) / 32 * 100) | round(0) ) *24 / 100) ) * 2) | round(0) }}px);
{% set time = now().hour %}
{% set brightness = ((5 - ((time/24*10) | round(0) -5 ) | abs)/10 + 0.5) | float %}
}
ha-card>ha-markdown{
transform:scale(0.5) translateY(150%) translateX(-100%);
background:transparent;
padding: 0 !important;
line-height:0;
display:flex;
align-items: center;
justify-content: center;
overflow:hidden;
}
view_layout:
grid-column: 1
grid-row: 1
- type: markdown
content: >-
<img id="weatherpic" src="{{ state_attr('sensor.solar','weather_picture') }}" height="48" width="48">
card_mod:
style: |
:host {
overflow:hidden;
}
@keyframes float{
0% {transform:translateY(-0.5em)}
50% {transform:translateY(0.5em)}
100% {transform:translateY(-0.5em)}
}
ha-card{
background: transparent;
display:flex;
align-items: center;
justify-content: center;
{% set sun = states.sensor.sun_elevation.state %}
transform:scale(2.5) translateY({{ ((-((((( -16 - (sun | int ) - 8)) / 32 * 100) | round(0) ) *24 / 100) ) * 2) | round(0) }}px) translateX({{ ((-((((( -16 - (sun | int ) - 8)) / 32 * 100) | round(0) ) *24 / 100) ) * 2) | round(0) }}px);
{% set time = now().hour %}
{% set brightness = ((5 - ((time/24*10) | round(0) -5 ) | abs)/10 + 0.5) | float %}
}
ha-card>ha-markdown{
animation: 5s ease-out infinite alternate float;
background:transparent;
padding: 0 !important;
line-height:0;
display:flex;
align-items: center;
justify-content: center;
overflow:hidden;
}
ha-markdown>ha-markdown-element{
}
view_layout:
grid-column: 1
grid-row: 1
layout:
grid-gap: 0
margin: 0
padding: 0
height: 100%
width: 100%
card_mod:
style: |
ha-card{
height:100%;
background:red;
}
:root{
overflow:hidden;
height:100%;
}
layout-card, grid-layout{
overflow: hidden;
height:100%;
transform:scale(3);
}
view_layout:
grid-column: 1 / span 6
grid-row: 1 / span 6
- type: markdown
content: >-
{% set clock = as_timestamp(now()) %} {{- clock | timestamp_custom("%H")
}}<span class="minutes">:{{ clock | timestamp_custom("%M") }}</span>
card_mod:
style: |
ha-markdown span{
color:green !important;
background:red;
}
ha-card > span {
border: 3px dotted magenta;
padding: 0px;
display: unset;
}
ha-card{
background:transparent;
display: flex;
align-items: center;
justify-content: right;
font: var(--h1-font);
font-weight: 500;
letter-spacing:-0.05em;
{% set time = now().hour %}
{% set int = ((5 - ((time/24*10) | round(0) -5 ) | abs)/10 + 0.5) | float %}
font-size: calc(var(--h1-font-size)*3*{{int}} );
transform: translateX({{ -((((( -16 - (states.sensor.sun_elevation.state | int ) - 8)) / 32 * 100) | round(0) ) * 24 / 100) | round(0)}}px);
mix-blend-mode:difference;
}
ha-card > ha-markdown{
padding:0 !important;
margin:0 !important;
{% set hue = (now().hour*15 + ((now().minute/60*100)/100) | round(2)*15 ) | int | abs %}
{% set hue2 = (((now().hour*15 + ((now().minute/60*100)/100) | round(2)*15 ) | int) - 45) | abs %}
{% set hue3 = ((now().hour*15 + ((now().minute/60*100)/100) | round(2)*15 ) | int) - 90 | abs %}
{% set time = now().hour %}
{% set br1 = ((5 - ((time/24*10) | round(0) -5 ) | abs)/10 + 0.5) | float %}
{% set br2 = ((5 - ((time/24*10) | round(0) -5 ) | abs)/10 ) | float %}
{% set brightness = ((5 - ((time/24*10) | round(0) -5 ) | abs) * 10 ) | int + 25 %}
background: linear-gradient(45deg, hsl({{hue}},100%,{{brightness}}%), hsl({{hue2}},100%,{{brightness}}%));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
/*mix-blend-mode:difference;*/
/*color:hsla({{hue}},100%,50%,{{brightness}});*/
/*text-shadow: 0 3px 3px hsla({{hue }},100%,50%,0.5), 0 3px 10px hsla({{hue }},100%,50%,1);*/
}
ha-card > .card-header, .card-header {
background-color: var(--background-color-off);
color: var(--text-color-off);
font-size:10px;
}
view_layout:
grid-column: 1 / span 5
grid-row: 2 / 4
- type: markdown
content: '{{ (( states(''sensor.calendar_event'') ) ) }}'
card_mod:
style: |
ha-card{
background: transparent;
display: flex;
align-items: flex-end;
justify-content: right;
text-align:right;
font: var(--{{ "h1" if state_attr('sensor.calendar_event','number_days') <= 1 else "card-title" }}-font);
line-height: 0.8em;
color: var(--primary-color);
mix-blend-mode:difference;
}
ha-card > ha-markdown{
padding:0 1rem !important;
}
view_layout:
grid-row: 4 / 5
grid-column: 4 / 7
- type: markdown
content: ' {{ (( states(''sensor.thermal_home_heatindex'') | float ) ) | round(0) }}ยฐC'
card_mod:
style: |
ha-card{
background: transparent;
display: flex;
align-items: center;
justify-content: right;
font:var(--h3-font);
color:var(--accent-text-color);
mix-blend-mode: lighten;
{% set hue = (25/(states.sensor.thermal_home_heatindex.state | int)*360) | int %}
{% set time = now().hour %}
{% set br1 = ((5 - ((time/24*10) | round(0) -5 ) | abs)/10 + 0.5) | float %}
{% set brightness = ((5 - ((time/24*10) | round(0) -5 ) | abs) * 10 ) | int + 25 %}
color: hsl({{hue}},100%,{{brightness}}%);
/*mix-blend-mode:difference;*/
/*color:hsla({{hue}},100%,50%,{{brightness}});*/
/*text-shadow: 0 3px 3px hsla({{hue }},100%,50%,0.5), 0 3px 10px hsla({{hue }},100%,50%,1);*/
}
ha-card > ha-markdown{
padding:0 1rem !important;
}
view_layout:
grid-row: 1
grid-column: 3 / 7
- type: markdown
content: >-
{%- macro suffix(d) %}
{%- set sfx = {1:'st',2:'nd',3:'rd'} %}
{{- 'th' if 11 <= d <= 13 else sfx.get(d%10, 'th') }}
{%- endmacro %}
{% set day = as_timestamp(now()) | timestamp_custom("%d") | int %}
{{ as_timestamp(now()) | timestamp_custom("%a") }} {{ day }}{{ suffix(day) }}
card_mod:
style: |
ha-card{
background:transparent;
display: flex;
align-items: center;
justify-content: left;
font: var(--h3-font);
color: var(--accent-color);
mix-blend-mode: difference;
}
ha-card > ha-markdown{
padding:0 1rem !important;
}
view_layout:
grid-column: 1 / span 4
grid-row: 1
- type: markdown
content: '{{ (( state_attr(''sensor.calendar_event'',''friendly_name'') ) ) }}'
card_mod:
style: |
ha-card{
background: transparent;
display: flex;
align-items: center;
justify-content: right;
text-align:right;
font: var(--body-font);
color: var(--accent-text-color);
mix-blend-mode: difference;
font-size: calc( 2*{{ "1" if state_attr('sensor.calendar_event','number_days') <= 1 else 1 }}rem);
}
ha-card > ha-markdown{
padding:0 1rem !important;
}
view_layout:
grid-row: 4
grid-column: 2 / 7
- type: markdown
content: >
{%- set weather = states('weather.hernes') -%}
{%- if weather in ['unknown','unavailable'] -%}
{{- ['idks','??'] | random -}}
{%- else -%}
{{- (( state_attr('weather.hernes','temperature') | float +
states('sensor.temperature_balcony') | float ) / 2) | round(0) }}ยฐC
{%- endif %}
card_mod:
style: |
ha-card{
box-sizing:border-box;
background: transparent;
display: flex;
align-items: center;
justify-content: left;
font:var(--h3-font);
color: var(--accent-text-color);
mix-blend-mode: screen;
{% set wefer = states('sensor.temperature_balcony') | int %}
{% set hue = 180-((((wefer)*10)) | int) %}
{% if hue <= 0 %}
{% set hue = 0 %}
{% elif hue >=360 %}
{% set hue = 360 - hue %}
{% else %}
{% endif %}
{% set time = now().hour %}
{% set br1 = ((5 - ((time/24*10) | round(0) -5 ) | abs)/10 + 0.5) | float %}
{% set brightness = ((5 - ((time/24*10) | round(0) -5 ) | abs) * 10 ) | int + 25 %}
color: hsl({{hue}},100%,{{brightness}}%);
}
ha-card > ha-markdown{
padding:0 1rem !important;
}
view_layout:
grid-column: 1 / span 3
grid-row: 6
- show_name: true
show_icon: true
type: button
entity: sensor.solar
tap_action:
action: navigate
navigation_path: /dashboard-nspanel/menu
hold_action:
action: navigate
navigation_path: /dashboard-nspanel/screensaver
view_layout:
grid-column: 1 / span 6
grid-row: 1 / span 6
card_mod:
style: ha-card{opacity:0}
layout:
grid-template-columns: repeat(6, minmax(60px, 1fr))
grid-template-rows: repeat(6, minmax(60px, 1fr))
grid-gap: 0.5em
margin: 0
padding: 0
height: 100vh
min-height: 480px
overflow: hidden
card_mod:
style: |
:host{
--card-header-font-size:1px;
}
:host > ha-card > .card-header{
display:none;
}
ha-card{
width:100%;
height:100vh;
}
:root{
overflow:hidden;
height:100vh;
}
layout-card{
overflow: hidden;
height:100vh;
}
Profit
Enjoy an always dynamic screensaver
- main image based on solar status (day, sunset, sunrise, etc)
1.1 if night, get actual moon phase
- weather conditions as illustrations
- time, date and temperature colored based on the state
- everything positioned based on time, state, etc, so you never get the same image