Nieoficjalna integracja Home Assistant dla klientów cateringu Kuchnia Vikinga. Pokazuje, co przyjedzie w najbliższych dostawach, i pozwala zmieniać dania w zamówieniu prosto z dashboardu — bez wchodzenia do panelu klienta.
Unofficial Home Assistant integration for the Polish diet catering "Kuchnia Vikinga": delivery sensors, meal switching services and a Lovelace card. UI is bilingual (PL/EN), docs below are in Polish.
- Wiele diet na jednym koncie — każda dieta (zamówienie) to osobne urządzenie w HA z własnymi sensorami; liczba i kaloryczność diet wykrywane są automatycznie.
- Sensory dostaw — co przyjedzie jutro i dziś (lista dań, kalorie, alergeny), osobny sensor dla każdego posiłku jutrzejszej dostawy, data końca zamówienia, pełne menu na 10 nadchodzących dni.
- Zmiana dań — usługi HA i karta Lovelace do przeglądania alternatyw (z informacją, z której diety pochodzi danie) i podmiany posiłku.
- Oznaczanie alergenów — dania zawierające wskazane alergeny (domyślnie mleko) dostają plakietkę 🥛 w karcie i flagę w atrybutach sensorów.
- Bez chmur pośredniczących i bez AI — integracja rozmawia wyłącznie
z panelem
panel.kuchniavikinga.pl.
- HACS → menu ⋮ → Custom repositories → wklej adres tego repozytorium, kategoria Integration → Add.
- Wyszukaj „Kuchnia Vikinga" w HACS i zainstaluj.
- Zrestartuj Home Assistant.
- Skopiuj katalog
custom_components/viking_menudo kataloguconfig/custom_components/swojej instalacji HA. - Zrestartuj Home Assistant.
- Ustawienia → Urządzenia i usługi → Dodaj integrację → „Kuchnia Vikinga".
- Podaj e-mail i hasło z panelu klienta (te same co na
panel.kuchniavikinga.pl). Dane są przechowywane lokalnie w HA i używane wyłącznie do logowania do panelu. - Integracja sama znajdzie wszystkie aktywne zamówienia (diety) i utworzy urządzenia oraz encje.
| Opcja | Domyślnie | Opis |
|---|---|---|
| Interwał odświeżania | 30 min |
Jak często pobierać menu z panelu. |
| Oznaczane alergeny | mleko |
Lista po przecinku; dania z tymi alergenami dostają wyróżnienie (np. mleko,gluten). |
| Nazwy diet | (puste) | Przyjazne nazwy w formacie kaloryczność:nazwa, np. 2000:Mateusz,1500:Kasia. |
Wskazówka: nazwy diet najlepiej ustawić od razu po dodaniu integracji — nazwa urządzenia się zaktualizuje, ale identyfikatory encji (
entity_id) powstają przy pierwszym uruchomieniu i się nie zmieniają.
Dla każdej diety (np. „Wybór menu 2000 kcal") powstaje urządzenie z sensorami:
| Encja (przykład) | Stan | Atrybuty |
|---|---|---|
sensor.…_delivery_tomorrow |
liczba posiłków jutro | date, meals[] (posiłek, danie, kcal, alergeny), total_calories |
sensor.…_delivery_today |
liczba posiłków dziś | jak wyżej |
sensor.…_jutro_sniadanie, …_jutro_obiad, … |
nazwa dania | calories, allergens, contains_avoided, switchable |
sensor.…_order_end |
data końca zamówienia | days_left, order_id, status |
sensor.…_menu |
liczba dni z widocznym menu | days[] — pełne menu 10 nadchodzących dni (źródło danych karty) |
Sensory posiłków tworzone są dynamicznie z nazw używanych przez panel (np. Śniadanie, II śniadanie, Obiad, Podwieczorek, Kolacja — diety 3-posiłkowe dostaną trzy sensory).
automation:
- alias: "Kuchnia Vikinga — jutrzejsze menu"
triggers:
- trigger: time
at: "20:00:00"
actions:
- action: notify.mobile_app_twoj_telefon
data:
title: "🍽 Jutrzejsza dostawa"
message: >-
{% for m in state_attr('sensor.wybor_menu_2000_kcal_delivery_tomorrow', 'meals') -%}
{{ m.slot }}: {{ m.dish }}
{% endfor %}Zwraca dania, na które można wymienić wskazany posiłek (usługa z odpowiedzią — w Narzędziach deweloperskich zaznacz „zwróć odpowiedź").
action: viking_menu.get_meal_options
data:
diet: "2000" # kaloryczność lub nazwa z opcji (np. "Mateusz")
date: "2026-06-17"
slot: "Obiad"Odpowiedź zawiera options[] z polami: dish, diet_calories_meal_id,
calories, allergens, contains_avoided, source_diet (z której diety
pochodzi danie), can_be_changed, is_current.
Jeżeli panel nie pozwala już edytować dnia (zwykle ok. 3–4 dni przed
dostawą), odpowiedź ma locked: true i reason z komunikatem panelu —
to nie jest błąd.
action: viking_menu.choose_meal
data:
diet: "2000"
date: "2026-06-17"
slot: "Obiad"
diet_calories_meal_id: 3635 # z odpowiedzi get_meal_options
⚠️ Uwaga: zmiana od razu modyfikuje realne, opłacone zamówienie w panelu. Operacja jest odwracalna — dopóki dzień nie jest zablokowany, można wybrać z powrotem poprzednie danie.
Zasób karty rejestruje się automatycznie (dashboardy w trybie storage — domyślnym). Dodaj kartę:
type: custom:viking-menu-cardOpcjonalnie można ograniczyć widoczne diety:
type: custom:viking-menu-card
entities:
- sensor.wybor_menu_2000_kcal_menuKarta pokazuje zakładki diet, pasek nadchodzących dni i posiłki wybranego dnia. Kliknięcie posiłku rozwija dostępne alternatywy (z plakietką 🥛 i nazwą diety źródłowej); wybór dania wymaga potwierdzenia i od razu zapisuje zmianę w panelu. Dni zablokowane przez panel są oznaczone i tylko do odczytu.
Jeśli używasz dashboardów w trybie YAML, dodaj zasób ręcznie:
lovelace:
resources:
- url: /viking_menu/viking-menu-card.js
type: moduleSkąd integracja wie, która dieta jest która, skoro zamówienia wygasają co miesiąc? Dieta jest identyfikowana po kaloryczności (np. 2000 kcal), nie po numerze zamówienia — po opłaceniu kolejnego zamówienia encje płynnie przejmą nowe dane. W przerwie między zamówieniami sensory diety pokazują pusty stan, ale nie znikają.
Dlaczego nie mogę zmienić dania na jutro? Panel blokuje edycję dni na
ok. 3–4 dni przed dostawą. Integracja pokazuje wtedy locked: true
(usługa) / 🔒 (karta) z komunikatem panelu.
Zmieniłem hasło do panelu. HA pokaże prośbę o ponowną autoryzację (re-auth) — wystarczy podać nowe hasło.
Dwa zamówienia o tej samej kaloryczności? Integracja użyje nowszego (po dacie rozpoczęcia) i zapisze ostrzeżenie w logach.
Karta pisze „Nie znaleziono sensorów menu". Upewnij się, że integracja
jest skonfigurowana i sensor …_menu ma stan ≥ 0; przy trybie YAML sprawdź,
czy zasób karty został dodany ręcznie.
- Dane logowania trzymane są w szyfrowanym storage Home Assistant
i wysyłane wyłącznie do
panel.kuchniavikinga.pl(HTTPS). - Integracja nie korzysta z żadnych zewnętrznych usług ani telemetrii.
- Projekt nie jest powiązany z firmą Kuchnia Vikinga — korzysta z tego samego API co oficjalny panel klienta. API może się zmienić bez zapowiedzi.
Repozytorium zawiera też niezależną od HA lokalną aplikację FastAPI do przeglądania menu i zmiany dań (z eksperymentalnymi sugestiami AI) oraz skrypty analityczne. To narzędzia deweloperskie autora — integracja HA ich nie wymaga.
py -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
Copy-Item .env.example .env # uzupełnij KV_EMAIL i KV_PASSWORD
py scripts\probe_login.py # weryfikacja logowania (read-only)
uvicorn app.server:app --port 8732 # UI: http://127.0.0.1:8732Przydatne skrypty:
scripts/probe_async_client.py— read-only test klienta async integracji na żywym API (w tym zachowanie blokady dni, HTTP 490),scripts/tier_report.py [od] [do]— raport, z jakich diet źródłowych pochodzą wybrane dania i czy tańszy pakiet (BASIC/COMFORT/…) pokryłby dotychczasowe wybory.
Dane logowania trzymaj wyłącznie w .env (ignorowany przez git). Pliki HAR
z panelu zawierają hasło jawnym tekstem — *.har również jest ignorowane.
MIT