Lysshow: SpotifyPlus+Hue automationer, input_booleans og knapper på Andreas/Daniel/soveværelse/stue views
This commit is contained in:
+1
-1
@@ -1 +1 @@
|
|||||||
2026.7.4
|
2026.9.1
|
||||||
+1
-8
@@ -22,14 +22,7 @@ homeassistant:
|
|||||||
media_dirs:
|
media_dirs:
|
||||||
local: /config/www/media
|
local: /config/www/media
|
||||||
|
|
||||||
http:
|
# http:-blok fjernet 15/8 2026 — migreret til UI (Indstillinger > System > Netværk) af HA 2026.8
|
||||||
use_x_forwarded_for: true
|
|
||||||
ip_ban_enabled: true
|
|
||||||
login_attempts_threshold: 5
|
|
||||||
trusted_proxies:
|
|
||||||
- 127.0.0.1
|
|
||||||
- 10.0.0.142
|
|
||||||
- 172.17.0.0/16 # Docker bridge (NPM)
|
|
||||||
|
|
||||||
# Undtager loopback (127.0.0.1/::1) fra HTTP-ban, så lokale værktøjer
|
# Undtager loopback (127.0.0.1/::1) fra HTTP-ban, så lokale værktøjer
|
||||||
# (fx en VS Code-session der rammer /api/config uden token) ikke banlyser localhost
|
# (fx en VS Code-session der rammer /api/config uden token) ikke banlyser localhost
|
||||||
|
|||||||
@@ -13,6 +13,31 @@ sections:
|
|||||||
entity: media_player.andreas
|
entity: media_player.andreas
|
||||||
name: Sonos Andreas
|
name: Sonos Andreas
|
||||||
|
|
||||||
|
- type: custom:button-card
|
||||||
|
entity: input_boolean.lightshow_andreas
|
||||||
|
name: Lysshow
|
||||||
|
icon: mdi:party-popper
|
||||||
|
tap_action:
|
||||||
|
action: toggle
|
||||||
|
state:
|
||||||
|
- value: "on"
|
||||||
|
styles:
|
||||||
|
card:
|
||||||
|
- background-color: "#3d2c5e"
|
||||||
|
- color: "#e0b0ff"
|
||||||
|
icon:
|
||||||
|
- color: "#e0b0ff"
|
||||||
|
name:
|
||||||
|
- color: "#e0b0ff"
|
||||||
|
styles:
|
||||||
|
card:
|
||||||
|
- height: 52px
|
||||||
|
- padding: 6px 8px
|
||||||
|
icon:
|
||||||
|
- width: 18px
|
||||||
|
name:
|
||||||
|
- font-size: 11px
|
||||||
|
|
||||||
- type: grid
|
- type: grid
|
||||||
columns: 2
|
columns: 2
|
||||||
square: false
|
square: false
|
||||||
|
|||||||
@@ -13,6 +13,31 @@ sections:
|
|||||||
entity: media_player.daniel
|
entity: media_player.daniel
|
||||||
name: Sonos Daniel
|
name: Sonos Daniel
|
||||||
|
|
||||||
|
- type: custom:button-card
|
||||||
|
entity: input_boolean.lightshow_daniel
|
||||||
|
name: Lysshow
|
||||||
|
icon: mdi:party-popper
|
||||||
|
tap_action:
|
||||||
|
action: toggle
|
||||||
|
state:
|
||||||
|
- value: "on"
|
||||||
|
styles:
|
||||||
|
card:
|
||||||
|
- background-color: "#3d2c5e"
|
||||||
|
- color: "#e0b0ff"
|
||||||
|
icon:
|
||||||
|
- color: "#e0b0ff"
|
||||||
|
name:
|
||||||
|
- color: "#e0b0ff"
|
||||||
|
styles:
|
||||||
|
card:
|
||||||
|
- height: 52px
|
||||||
|
- padding: 6px 8px
|
||||||
|
icon:
|
||||||
|
- width: 18px
|
||||||
|
name:
|
||||||
|
- font-size: 11px
|
||||||
|
|
||||||
- type: grid
|
- type: grid
|
||||||
columns: 2
|
columns: 2
|
||||||
square: false
|
square: false
|
||||||
|
|||||||
@@ -38,6 +38,31 @@ sections:
|
|||||||
entity: media_player.sovevaerelse
|
entity: media_player.sovevaerelse
|
||||||
name: Sonos Sovevaerelse
|
name: Sonos Sovevaerelse
|
||||||
|
|
||||||
|
- type: custom:button-card
|
||||||
|
entity: input_boolean.lightshow_sovevaerelse
|
||||||
|
name: Lysshow
|
||||||
|
icon: mdi:party-popper
|
||||||
|
tap_action:
|
||||||
|
action: toggle
|
||||||
|
state:
|
||||||
|
- value: "on"
|
||||||
|
styles:
|
||||||
|
card:
|
||||||
|
- background-color: "#3d2c5e"
|
||||||
|
- color: "#e0b0ff"
|
||||||
|
icon:
|
||||||
|
- color: "#e0b0ff"
|
||||||
|
name:
|
||||||
|
- color: "#e0b0ff"
|
||||||
|
styles:
|
||||||
|
card:
|
||||||
|
- height: 52px
|
||||||
|
- padding: 6px 8px
|
||||||
|
icon:
|
||||||
|
- width: 18px
|
||||||
|
name:
|
||||||
|
- font-size: 11px
|
||||||
|
|
||||||
- type: grid
|
- type: grid
|
||||||
columns: 2
|
columns: 2
|
||||||
square: false
|
square: false
|
||||||
|
|||||||
@@ -23,6 +23,31 @@ sections:
|
|||||||
entity: media_player.denon_avr_x2300w
|
entity: media_player.denon_avr_x2300w
|
||||||
name: Denon AVR
|
name: Denon AVR
|
||||||
|
|
||||||
|
- type: custom:button-card
|
||||||
|
entity: input_boolean.lightshow_stue
|
||||||
|
name: Lysshow
|
||||||
|
icon: mdi:party-popper
|
||||||
|
tap_action:
|
||||||
|
action: toggle
|
||||||
|
state:
|
||||||
|
- value: "on"
|
||||||
|
styles:
|
||||||
|
card:
|
||||||
|
- background-color: "#3d2c5e"
|
||||||
|
- color: "#e0b0ff"
|
||||||
|
icon:
|
||||||
|
- color: "#e0b0ff"
|
||||||
|
name:
|
||||||
|
- color: "#e0b0ff"
|
||||||
|
styles:
|
||||||
|
card:
|
||||||
|
- height: 52px
|
||||||
|
- padding: 6px 8px
|
||||||
|
icon:
|
||||||
|
- width: 18px
|
||||||
|
name:
|
||||||
|
- font-size: 11px
|
||||||
|
|
||||||
|
|
||||||
# 💡 Lys (kompakt + alle lys)
|
# 💡 Lys (kompakt + alle lys)
|
||||||
- type: grid
|
- type: grid
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ panel: true
|
|||||||
|
|
||||||
cards:
|
cards:
|
||||||
- type: iframe
|
- type: iframe
|
||||||
url: /local/snapshots/indkorsel_loader.html?v=20260808105147
|
url: /local/snapshots/indkorsel_loader.html?v=20260910174711
|
||||||
aspect_ratio: 100%
|
aspect_ratio: 100%
|
||||||
|
|||||||
@@ -0,0 +1,269 @@
|
|||||||
|
# SpotifyPlus + Hue lysshow pr. værelse.
|
||||||
|
# Baseret på thlucas1's "SpotifyPlus Hue Lightshow"-blueprint:
|
||||||
|
# https://github.com/thlucas1/homeassistant_blueprints/blob/master/spotifyplus/spotifyplus_hue_lightshow.md
|
||||||
|
#
|
||||||
|
# OBS: Kræver at SpotifyPlus-integrationen er sat op (Spotify Premium + OAuth).
|
||||||
|
# Ret media_player.spotifyplus til den faktiske entity efter opsætning.
|
||||||
|
|
||||||
|
- id: lightshow_andreas
|
||||||
|
alias: "Lysshow: Andreas"
|
||||||
|
description: Synkroniserer Hue-lys med Spotify-albumcover (SpotifyPlus)
|
||||||
|
mode: restart
|
||||||
|
max_exceeded: silent
|
||||||
|
triggers:
|
||||||
|
- trigger: state
|
||||||
|
entity_id: input_boolean.lightshow_andreas
|
||||||
|
to: "on"
|
||||||
|
- trigger: state
|
||||||
|
entity_id: media_player.spotifyplus
|
||||||
|
attribute: media_content_id
|
||||||
|
- trigger: state
|
||||||
|
entity_id: media_player.spotifyplus
|
||||||
|
to: playing
|
||||||
|
conditions:
|
||||||
|
- condition: state
|
||||||
|
entity_id: input_boolean.lightshow_andreas
|
||||||
|
state: "on"
|
||||||
|
- condition: state
|
||||||
|
entity_id: media_player.spotifyplus
|
||||||
|
state: playing
|
||||||
|
actions:
|
||||||
|
- variables:
|
||||||
|
media_player_entity: media_player.spotifyplus
|
||||||
|
lights:
|
||||||
|
- light.andreas_lysstrip
|
||||||
|
- light.andreas_stol
|
||||||
|
spotify_image_url: "{{ state_attr(media_player_entity, 'sp_nowplaying_image_url') }}"
|
||||||
|
- action: spotifyplus.get_image_palette_colors
|
||||||
|
data:
|
||||||
|
entity_id: media_player.spotifyplus
|
||||||
|
image_source: "{{ spotify_image_url }}"
|
||||||
|
color_count: 10
|
||||||
|
color_quality: 1
|
||||||
|
brightness_filter_low: 100
|
||||||
|
brightness_filter_high: 600
|
||||||
|
hue_distance_filter: 10
|
||||||
|
response_variable: palette_response
|
||||||
|
- variables:
|
||||||
|
colors_rgb: "{{ palette_response['result']['items'][:6] | map(attribute='rgb') | list }}"
|
||||||
|
- repeat:
|
||||||
|
while:
|
||||||
|
- condition: state
|
||||||
|
entity_id: input_boolean.lightshow_andreas
|
||||||
|
state: "on"
|
||||||
|
- condition: state
|
||||||
|
entity_id: media_player.spotifyplus
|
||||||
|
state: playing
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ spotify_image_url == state_attr(media_player_entity, 'sp_nowplaying_image_url') }}"
|
||||||
|
sequence:
|
||||||
|
- repeat:
|
||||||
|
count: "{{ colors_rgb | count }}"
|
||||||
|
sequence:
|
||||||
|
- action: light.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: "{{ lights }}"
|
||||||
|
data:
|
||||||
|
rgb_color: "{{ colors_rgb[repeat.index - 1] }}"
|
||||||
|
brightness_pct: 100
|
||||||
|
transition: 2
|
||||||
|
- delay: "00:00:02"
|
||||||
|
|
||||||
|
- id: lightshow_daniel
|
||||||
|
alias: "Lysshow: Daniel"
|
||||||
|
description: Synkroniserer Hue-lys med Spotify-albumcover (SpotifyPlus)
|
||||||
|
mode: restart
|
||||||
|
max_exceeded: silent
|
||||||
|
triggers:
|
||||||
|
- trigger: state
|
||||||
|
entity_id: input_boolean.lightshow_daniel
|
||||||
|
to: "on"
|
||||||
|
- trigger: state
|
||||||
|
entity_id: media_player.spotifyplus
|
||||||
|
attribute: media_content_id
|
||||||
|
- trigger: state
|
||||||
|
entity_id: media_player.spotifyplus
|
||||||
|
to: playing
|
||||||
|
conditions:
|
||||||
|
- condition: state
|
||||||
|
entity_id: input_boolean.lightshow_daniel
|
||||||
|
state: "on"
|
||||||
|
- condition: state
|
||||||
|
entity_id: media_player.spotifyplus
|
||||||
|
state: playing
|
||||||
|
actions:
|
||||||
|
- variables:
|
||||||
|
media_player_entity: media_player.spotifyplus
|
||||||
|
lights:
|
||||||
|
- light.daniel_lysstrip
|
||||||
|
- light.bamse
|
||||||
|
spotify_image_url: "{{ state_attr(media_player_entity, 'sp_nowplaying_image_url') }}"
|
||||||
|
- action: spotifyplus.get_image_palette_colors
|
||||||
|
data:
|
||||||
|
entity_id: media_player.spotifyplus
|
||||||
|
image_source: "{{ spotify_image_url }}"
|
||||||
|
color_count: 10
|
||||||
|
color_quality: 1
|
||||||
|
brightness_filter_low: 100
|
||||||
|
brightness_filter_high: 600
|
||||||
|
hue_distance_filter: 10
|
||||||
|
response_variable: palette_response
|
||||||
|
- variables:
|
||||||
|
colors_rgb: "{{ palette_response['result']['items'][:6] | map(attribute='rgb') | list }}"
|
||||||
|
- repeat:
|
||||||
|
while:
|
||||||
|
- condition: state
|
||||||
|
entity_id: input_boolean.lightshow_daniel
|
||||||
|
state: "on"
|
||||||
|
- condition: state
|
||||||
|
entity_id: media_player.spotifyplus
|
||||||
|
state: playing
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ spotify_image_url == state_attr(media_player_entity, 'sp_nowplaying_image_url') }}"
|
||||||
|
sequence:
|
||||||
|
- repeat:
|
||||||
|
count: "{{ colors_rgb | count }}"
|
||||||
|
sequence:
|
||||||
|
- action: light.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: "{{ lights }}"
|
||||||
|
data:
|
||||||
|
rgb_color: "{{ colors_rgb[repeat.index - 1] }}"
|
||||||
|
brightness_pct: 100
|
||||||
|
transition: 2
|
||||||
|
- delay: "00:00:02"
|
||||||
|
|
||||||
|
- id: lightshow_sovevaerelse
|
||||||
|
alias: "Lysshow: Soveværelse"
|
||||||
|
description: Synkroniserer Hue-lys med Spotify-albumcover (SpotifyPlus)
|
||||||
|
mode: restart
|
||||||
|
max_exceeded: silent
|
||||||
|
triggers:
|
||||||
|
- trigger: state
|
||||||
|
entity_id: input_boolean.lightshow_sovevaerelse
|
||||||
|
to: "on"
|
||||||
|
- trigger: state
|
||||||
|
entity_id: media_player.spotifyplus
|
||||||
|
attribute: media_content_id
|
||||||
|
- trigger: state
|
||||||
|
entity_id: media_player.spotifyplus
|
||||||
|
to: playing
|
||||||
|
conditions:
|
||||||
|
- condition: state
|
||||||
|
entity_id: input_boolean.lightshow_sovevaerelse
|
||||||
|
state: "on"
|
||||||
|
- condition: state
|
||||||
|
entity_id: media_player.spotifyplus
|
||||||
|
state: playing
|
||||||
|
actions:
|
||||||
|
- variables:
|
||||||
|
media_player_entity: media_player.spotifyplus
|
||||||
|
lights:
|
||||||
|
- light.sov_midt
|
||||||
|
- light.sov_vindue
|
||||||
|
- light.sov_dor
|
||||||
|
- light.anne
|
||||||
|
- light.claus
|
||||||
|
spotify_image_url: "{{ state_attr(media_player_entity, 'sp_nowplaying_image_url') }}"
|
||||||
|
- action: spotifyplus.get_image_palette_colors
|
||||||
|
data:
|
||||||
|
entity_id: media_player.spotifyplus
|
||||||
|
image_source: "{{ spotify_image_url }}"
|
||||||
|
color_count: 10
|
||||||
|
color_quality: 1
|
||||||
|
brightness_filter_low: 100
|
||||||
|
brightness_filter_high: 600
|
||||||
|
hue_distance_filter: 10
|
||||||
|
response_variable: palette_response
|
||||||
|
- variables:
|
||||||
|
colors_rgb: "{{ palette_response['result']['items'][:6] | map(attribute='rgb') | list }}"
|
||||||
|
- repeat:
|
||||||
|
while:
|
||||||
|
- condition: state
|
||||||
|
entity_id: input_boolean.lightshow_sovevaerelse
|
||||||
|
state: "on"
|
||||||
|
- condition: state
|
||||||
|
entity_id: media_player.spotifyplus
|
||||||
|
state: playing
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ spotify_image_url == state_attr(media_player_entity, 'sp_nowplaying_image_url') }}"
|
||||||
|
sequence:
|
||||||
|
- repeat:
|
||||||
|
count: "{{ colors_rgb | count }}"
|
||||||
|
sequence:
|
||||||
|
- action: light.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: "{{ lights }}"
|
||||||
|
data:
|
||||||
|
rgb_color: "{{ colors_rgb[repeat.index - 1] }}"
|
||||||
|
brightness_pct: 100
|
||||||
|
transition: 2
|
||||||
|
- delay: "00:00:02"
|
||||||
|
|
||||||
|
- id: lightshow_stue
|
||||||
|
alias: "Lysshow: Stue"
|
||||||
|
description: Synkroniserer Hue-lys med Spotify-albumcover (SpotifyPlus)
|
||||||
|
mode: restart
|
||||||
|
max_exceeded: silent
|
||||||
|
triggers:
|
||||||
|
- trigger: state
|
||||||
|
entity_id: input_boolean.lightshow_stue
|
||||||
|
to: "on"
|
||||||
|
- trigger: state
|
||||||
|
entity_id: media_player.spotifyplus
|
||||||
|
attribute: media_content_id
|
||||||
|
- trigger: state
|
||||||
|
entity_id: media_player.spotifyplus
|
||||||
|
to: playing
|
||||||
|
conditions:
|
||||||
|
- condition: state
|
||||||
|
entity_id: input_boolean.lightshow_stue
|
||||||
|
state: "on"
|
||||||
|
- condition: state
|
||||||
|
entity_id: media_player.spotifyplus
|
||||||
|
state: playing
|
||||||
|
actions:
|
||||||
|
- variables:
|
||||||
|
media_player_entity: media_player.spotifyplus
|
||||||
|
lights:
|
||||||
|
- light.pendle1
|
||||||
|
- light.pendle2
|
||||||
|
- light.syd
|
||||||
|
- light.raket
|
||||||
|
- light.spisebord
|
||||||
|
- light.panton
|
||||||
|
spotify_image_url: "{{ state_attr(media_player_entity, 'sp_nowplaying_image_url') }}"
|
||||||
|
- action: spotifyplus.get_image_palette_colors
|
||||||
|
data:
|
||||||
|
entity_id: media_player.spotifyplus
|
||||||
|
image_source: "{{ spotify_image_url }}"
|
||||||
|
color_count: 10
|
||||||
|
color_quality: 1
|
||||||
|
brightness_filter_low: 100
|
||||||
|
brightness_filter_high: 600
|
||||||
|
hue_distance_filter: 10
|
||||||
|
response_variable: palette_response
|
||||||
|
- variables:
|
||||||
|
colors_rgb: "{{ palette_response['result']['items'][:6] | map(attribute='rgb') | list }}"
|
||||||
|
- repeat:
|
||||||
|
while:
|
||||||
|
- condition: state
|
||||||
|
entity_id: input_boolean.lightshow_stue
|
||||||
|
state: "on"
|
||||||
|
- condition: state
|
||||||
|
entity_id: media_player.spotifyplus
|
||||||
|
state: playing
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ spotify_image_url == state_attr(media_player_entity, 'sp_nowplaying_image_url') }}"
|
||||||
|
sequence:
|
||||||
|
- repeat:
|
||||||
|
count: "{{ colors_rgb | count }}"
|
||||||
|
sequence:
|
||||||
|
- action: light.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: "{{ lights }}"
|
||||||
|
data:
|
||||||
|
rgb_color: "{{ colors_rgb[repeat.index - 1] }}"
|
||||||
|
brightness_pct: 100
|
||||||
|
transition: 2
|
||||||
|
- delay: "00:00:02"
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
lightshow_andreas:
|
||||||
|
name: Lysshow Andreas
|
||||||
|
icon: mdi:party-popper
|
||||||
|
|
||||||
|
lightshow_daniel:
|
||||||
|
name: Lysshow Daniel
|
||||||
|
icon: mdi:party-popper
|
||||||
|
|
||||||
|
lightshow_sovevaerelse:
|
||||||
|
name: Lysshow Soveværelse
|
||||||
|
icon: mdi:party-popper
|
||||||
|
|
||||||
|
lightshow_stue:
|
||||||
|
name: Lysshow Stue
|
||||||
|
icon: mdi:party-popper
|
||||||
@@ -50,7 +50,7 @@ varme_komfort_forgang:
|
|||||||
max: 28
|
max: 28
|
||||||
step: 0.5
|
step: 0.5
|
||||||
unit_of_measurement: "°C"
|
unit_of_measurement: "°C"
|
||||||
initial: 22
|
initial: 24
|
||||||
icon: mdi:thermometer
|
icon: mdi:thermometer
|
||||||
|
|
||||||
varme_komfort_lille_bad:
|
varme_komfort_lille_bad:
|
||||||
@@ -59,7 +59,7 @@ varme_komfort_lille_bad:
|
|||||||
max: 28
|
max: 28
|
||||||
step: 0.5
|
step: 0.5
|
||||||
unit_of_measurement: "°C"
|
unit_of_measurement: "°C"
|
||||||
initial: 22
|
initial: 24
|
||||||
icon: mdi:thermometer
|
icon: mdi:thermometer
|
||||||
|
|
||||||
varme_komfort_badevarelse:
|
varme_komfort_badevarelse:
|
||||||
@@ -77,7 +77,7 @@ varme_komfort_stue:
|
|||||||
max: 28
|
max: 28
|
||||||
step: 0.5
|
step: 0.5
|
||||||
unit_of_measurement: "°C"
|
unit_of_measurement: "°C"
|
||||||
initial: 21
|
initial: 23
|
||||||
icon: mdi:thermometer
|
icon: mdi:thermometer
|
||||||
|
|
||||||
# Globale sænkninger
|
# Globale sænkninger
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
{"count": 7, "items": [{"date": "2026-08-14", "recipe": {"name": "Salat med and og mango", "slug": "salat-med-and-og-mango"}}, {"date": "2026-08-13", "recipe": {"name": "Ovnbagt \u00e6ggekage med gr\u00f8nt", "slug": "ovnbagt-aeggekage-med-gront"}}, {"date": "2026-08-12", "recipe": {"name": "Nem k\u00f8dsauce med gr\u00f8ntsager", "slug": "nem-kodsauce-med-grontsager"}}, {"date": "2026-08-11", "recipe": {"name": "Tortillas med krydret oksek\u00f8d", "slug": "tortillas-med-krydret-oksekod"}}, {"date": "2026-08-10", "recipe": {"name": "Nem k\u00f8dsauce med gr\u00f8ntsager", "slug": "nem-kodsauce-med-grontsager"}}, {"date": "2026-08-09", "recipe": {"name": "Tortillas med krydret oksek\u00f8d", "slug": "tortillas-med-krydret-oksekod"}}, {"date": "2026-08-08", "recipe": {"name": "Pasta med laks og fl\u00f8de", "slug": "pasta-med-laks-og-flode"}}]}
|
{"count": 8, "items": [{"date": "2026-09-11", "recipe": {"name": "Coleslaw", "slug": "coleslaw"}}, {"date": "2026-09-11", "recipe": {"name": "SPARERIBS SOUS VIDE, 36 timers tilberedning", "slug": "spareribs-sous-vide-36-timers-tilberedning"}}, {"date": "2026-09-16", "recipe": {"name": "Rester \u2014 kylling i sennepssauce", "slug": ""}}, {"date": "2026-09-15", "recipe": {"name": "Rester \u2014 bolognese", "slug": ""}}, {"date": "2026-09-14", "recipe": {"name": "Kylling i cremet sennepssauce", "slug": "kylling-i-cremet-sennepssauce"}}, {"date": "2026-09-13", "recipe": {"name": "Spaghetti Bolognese - pasta med k\u00f8dsovs", "slug": "spaghetti-bolognese-pasta-med-kodsovs"}}, {"date": "2026-09-10", "recipe": {"name": "Burger med crispy kylling og avocado", "slug": "burger-med-crispy-kylling-og-avocado"}}, {"date": "2026-09-16", "recipe": {"name": "Pastasalat med kylling", "slug": "pastasalat-med-kylling"}}]}
|
||||||
Reference in New Issue
Block a user