diff --git a/dashboards/views/12_madplan.yaml b/dashboards/views/12_madplan.yaml
new file mode 100644
index 0000000..0f41751
--- /dev/null
+++ b/dashboards/views/12_madplan.yaml
@@ -0,0 +1,148 @@
+title: Madplan
+path: madplan
+icon: mdi:chef-hat
+
+cards:
+
+ # 🍽️ Dagens ret - stort fremhævet kort med link til Mealie
+ - type: custom:button-card
+ entity: sensor.dagens_aftensmad
+ show_icon: true
+ show_name: true
+ show_state: true
+ icon: mdi:food-variant
+ name: I dag
+ tap_action:
+ action: url
+ url_path: >
+ [[[
+ var slug = states['sensor.dagens_aftensmad_slug'].state;
+ if (slug && slug !== '' && slug !== 'unknown') {
+ return 'http://10.0.0.142:9925/g/home/r/' + slug;
+ }
+ return 'http://10.0.0.142:9925';
+ ]]]
+ styles:
+ card:
+ - padding: 16px
+ - background: var(--primary-color)
+ - border-radius: 12px
+ icon:
+ - color: white
+ - width: 40px
+ name:
+ - font-size: 13px
+ - color: "rgba(255,255,255,0.7)"
+ - text-transform: uppercase
+ - letter-spacing: 1px
+ state:
+ - font-size: 22px
+ - font-weight: bold
+ - color: white
+ - padding-top: 4px
+
+ # 🎵 Musik i køkken + Der er mad
+ - type: grid
+ columns: 2
+ square: false
+ cards:
+ - type: button
+ name: Musik i køkken
+ icon: mdi:music-note-outline
+ tap_action:
+ action: call-service
+ service: media_player.select_source
+ target:
+ entity_id: media_player.kokken
+ data:
+ source: "1 Family Mix"
+
+ - type: button
+ name: Der er mad!
+ icon: mdi:silverware-fork-knife
+ tap_action:
+ action: call-service
+ service: script.mad_announcement
+
+ # 📅 Ugens madplan
+ - type: entities
+ title: Ugens madplan
+ show_header_toggle: false
+ entities:
+ - type: custom:button-card
+ entity: sensor.mealie_madplan_ugen
+ show_icon: false
+ show_name: false
+ show_state: false
+ styles:
+ card:
+ - padding: 0
+ - background: none
+ - box-shadow: none
+ custom_fields:
+ week: >
+ [[[
+ const items = entity.attributes.items || [];
+ const dayNames = ['Søndag','Mandag','Tirsdag','Onsdag','Torsdag','Fredag','Lørdag'];
+ const today = new Date().toISOString().slice(0,10);
+
+ // Build date->meal map
+ const meals = {};
+ items.forEach(item => {
+ if (item.recipe && item.recipe.name) {
+ meals[item.date] = {
+ name: item.recipe.name,
+ slug: item.recipe.slug || ''
+ };
+ }
+ });
+
+ // Generate 7 days starting from Monday of current week
+ const now = new Date();
+ const dayOfWeek = now.getDay();
+ const monday = new Date(now);
+ monday.setDate(now.getDate() - (dayOfWeek === 0 ? 6 : dayOfWeek - 1));
+
+ let html = '
';
+ for (let i = 0; i < 7; i++) {
+ const d = new Date(monday);
+ d.setDate(monday.getDate() + i);
+ const dateStr = d.toISOString().slice(0,10);
+ const dayName = dayNames[d.getDay()];
+ const meal = meals[dateStr];
+ const isToday = dateStr === today;
+
+ const bg = isToday ? 'var(--primary-color)' : 'transparent';
+ const textColor = isToday ? 'white' : 'var(--primary-text-color)';
+ const dayColor = isToday ? 'rgba(255,255,255,0.7)' : 'var(--secondary-text-color)';
+ const weight = isToday ? 'bold' : 'normal';
+ const radius = isToday ? '8px' : '0';
+ const border = isToday ? 'none' : '1px solid var(--divider-color)';
+
+ const mealName = meal ? meal.name : '—';
+ const slug = meal ? meal.slug : '';
+ const link = slug ? 'http://10.0.0.142:9925/g/home/r/' + slug : '';
+ const cursor = slug ? 'pointer' : 'default';
+
+ html += `
+
+
+ ${dayName}
+
+
+ ${mealName}
+
+
`;
+ }
+ html += '
';
+ return html;
+ ]]]
+ extra_styles: |
+ #week {
+ width: 100%;
+ }
diff --git a/include/scripts/home_actions.yaml b/include/scripts/home_actions.yaml
index 597bdde..2ab19a0 100644
--- a/include/scripts/home_actions.yaml
+++ b/include/scripts/home_actions.yaml
@@ -38,7 +38,13 @@ mad_announcement:
sequence:
- service: notify.mobile_app_claus_iphone_15pro
data:
- message: Der er mad
+ message: >-
+ {% set meal = states('sensor.dagens_aftensmad') %}
+ {% if meal and meal not in ['unknown','unavailable','Ingen planlagt'] %}
+ Der er mad! I dag: {{ meal }}
+ {% else %}
+ Der er mad!
+ {% endif %}
- choose:
- conditions:
- condition: state
@@ -47,7 +53,13 @@ mad_announcement:
sequence:
- service: notify.mobile_app_annes_iphone_14_pro
data:
- message: Der er mad
+ message: >-
+ {% set meal = states('sensor.dagens_aftensmad') %}
+ {% if meal and meal not in ['unknown','unavailable','Ingen planlagt'] %}
+ Der er mad! I dag: {{ meal }}
+ {% else %}
+ Der er mad!
+ {% endif %}
- choose:
- conditions:
- condition: state
@@ -56,7 +68,13 @@ mad_announcement:
sequence:
- service: notify.mobile_app_andreas_iphone_12
data:
- message: Der er mad
+ message: >-
+ {% set meal = states('sensor.dagens_aftensmad') %}
+ {% if meal and meal not in ['unknown','unavailable','Ingen planlagt'] %}
+ Der er mad! I dag: {{ meal }}
+ {% else %}
+ Der er mad!
+ {% endif %}
- choose:
- conditions:
- condition: state
@@ -65,7 +83,13 @@ mad_announcement:
sequence:
- service: notify.mobile_app_daniels_iphone_13_mini
data:
- message: Der er mad
+ message: >-
+ {% set meal = states('sensor.dagens_aftensmad') %}
+ {% if meal and meal not in ['unknown','unavailable','Ingen planlagt'] %}
+ Der er mad! I dag: {{ meal }}
+ {% else %}
+ Der er mad!
+ {% endif %}
- service: media_player.volume_set
target:
entity_id:
@@ -88,7 +112,13 @@ mad_announcement:
- media_player.daniel
- media_player.sovevaerelse
- media_player.badevaerelse
- message: Der er mad
+ message: >-
+ {% set meal = states('sensor.dagens_aftensmad') %}
+ {% if meal and meal not in ['unknown','unavailable','Ingen planlagt'] %}
+ Der er mad! I dag spiser vi {{ meal }}
+ {% else %}
+ Der er mad!
+ {% endif %}
- delay: "00:00:10"
- service: sonos.restore
data:
diff --git a/include/sensors/mealie.yaml b/include/sensors/mealie.yaml
index e69de29..40d2a55 100644
--- a/include/sensors/mealie.yaml
+++ b/include/sensors/mealie.yaml
@@ -0,0 +1,13 @@
+- platform: rest
+ name: mealie_madplan_ugen
+ resource_template: >-
+ http://10.0.0.142:9925/api/households/mealplans?start_date={{ now().strftime('%Y-%m-%d') }}&end_date={{ (now() + timedelta(days=6)).strftime('%Y-%m-%d') }}
+ headers:
+ Authorization: !secret mealie_bearer_token
+ Content-Type: application/json
+ method: GET
+ scan_interval: 1800
+ value_template: "{{ value_json.items | length }}"
+ json_attributes_path: "$"
+ json_attributes:
+ - items
diff --git a/include/templates/mealie.yaml b/include/templates/mealie.yaml
new file mode 100644
index 0000000..9af6c37
--- /dev/null
+++ b/include/templates/mealie.yaml
@@ -0,0 +1,34 @@
+- sensor:
+ - name: "Dagens aftensmad"
+ unique_id: mealie_dagens_aftensmad
+ icon: mdi:silverware-fork-knife
+ state: >
+ {% set today = now().strftime('%Y-%m-%d') %}
+ {% set items = state_attr('sensor.mealie_madplan_ugen', 'items') %}
+ {% if items %}
+ {% set ns = namespace(meal='Ingen planlagt') %}
+ {% for item in items %}
+ {% if item.date == today and item.recipe %}
+ {% set ns.meal = item.recipe.name %}
+ {% endif %}
+ {% endfor %}
+ {{ ns.meal }}
+ {% else %}
+ Ingen planlagt
+ {% endif %}
+
+ - name: "Dagens aftensmad slug"
+ unique_id: mealie_dagens_aftensmad_slug
+ state: >
+ {% set today = now().strftime('%Y-%m-%d') %}
+ {% set items = state_attr('sensor.mealie_madplan_ugen', 'items') %}
+ {% if items %}
+ {% set ns = namespace(slug='') %}
+ {% for item in items %}
+ {% if item.date == today and item.recipe %}
+ {% set ns.slug = item.recipe.slug %}
+ {% endif %}
+ {% endfor %}
+ {{ ns.slug }}
+ {% else %}
+ {% endif %}
diff --git a/secrets.yaml b/secrets.yaml
index aba5f30..46e1306 100644
--- a/secrets.yaml
+++ b/secrets.yaml
@@ -133,6 +133,7 @@ powerview_ip: 10.0.0.100
mealie_api_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb25nX3Rva2VuIjp0cnVlLCJpZCI6MSwiZXhwIjoxODMxOTY5MzcyfQ.WiTG7KQeJHvEsTFGNwnMKlB_EpTWGbX5qkOoPxjt7oo
mealie_api_URL_mealplan: http://10.0.0.142:9777/api/groups/mealplans
+mealie_bearer_token: "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb25nX3Rva2VuIjp0cnVlLCJpZCI6IjAwZDYwNThkLTkxNjQtNGU2ZS1hZjE4LWQyNmQxMTdmNDJiNSIsIm5hbWUiOiJIb21lQXNzaXN0YW50MiIsImludGVncmF0aW9uX2lkIjoiZ2VuZXJpYyIsImV4cCI6MTkzNDAzNjM5Mn0.ZQkyuE0sCFJVQIYq1lnNTyTVbPO7psUC-zaCVqMsrDs"
# ########################################