XBMC-Kodi.cz

Úplná verze: Zobrazení stavových infomací Kodi a addon
Prohlížíte si holou variantu vašeho obsahu. Prohlédněte si plnou verzi s příslušným formátováním.
Úvod

Zobrazení stavových infomací Kodi a addon je téma, které se mnou celá řada uživatelů, kterým spravuji Kodi nebo jim poskytuji neformální podporu, často řeší. Já sám se jím zabývám už delší dobu, a tak mě čas od času někdo požádá, zda bych mu ve stavové liště jeho skinu nezobrazil nějakou (pro něj důležitu) informaci. Naposledy například informaci o tom, na kolik dní má ještě ve službě Webshare zaplacený VIP přístup. Ale vezmu to poněkud ze široka.

Celé toto téma se rozpadá na několik částí:
  1. Kde a jak se dá informace, kterou potřebujeme zobrazit, získat
  2. Kam získanou informaci, kterou potřebujeme zobrazit, uložit
  3. Jak získanou a uloženou informaci zobrazit
Kde a jak se dá informace, kterou potřebujeme zobrazit, získat

Toto je (či může být) z celé problematiky nejsložitější. V podstatě existují tři základní typy infomací a metod jejich získání.

Nejjednodušší je, pokud je zdrojem informací samo Kodi a ta informace je uložena přímo v proměnné, která je přístupná ve skinu. Seznam takových proměnných můžete nalézt v List of boolean conditions a InfoLabels. Samozřejmě, že v případě logických proměnných nezobrazujeme jejich hodnotu (True, False), to Kodi neumí, ale použijeme je k modifikaci nějakého jiného zobrazení (obsahu textu, barvy textu, zobrazení ikony, obrázku apod.) přímo v definičních souborech ve skinu, prostřednictvím "dopočtů" nebo kombinací obojího.

Druhou typickou možností je využité uložené hodnoty z nastavení nějakého addon. Pro získání této hodnoty je třeba  si "sáhnout" do souboru nastavení, settings.xml. V *ELEC systémech pro to dokonce existuje aplikace (oe_setup_addon), která si dokáže tento soubor načíst a pro všechny proměnné v něm vytvořit analogické proměnné v shell-u obsahující odpovídající hodnotu. Příklad použití této možnosti je vidět na níže uvedeném screenshot-u, kdy je použit právě pro získání informace o počtu dní, pro které je ve službě Webshare zaplacený VIP přístup (VIP: 80). Tím addon, do které settings.xml se sahá, je samozřejmě SCC.

Poslední způsob je pak ten, že pro příslušnou informaci použijme addon. A to jako nějaký explicitně vytvořený, tzn. určený pouze pro získání dané infomace, tak jakýkoliv, ve kterém existuje nějaká proměnná, jejíž honotu či stav chceme zobrazit (tuto metodu používá např. addon SC od ). Já používám řadu jednoduchých addon typu service, které mi sbírají a zpracovávají nějaké informace, které pak použiji pro zobrazení. Typicky např. měření rychlosti komunikace down/up-load-u na síťovém rozhraní, získání doplňujících datumových informací - kdo má v daný den jmeniny, zda je státní svátek, zda mají dnes a budou mít zítra zavřeno ve "velkých obchodech". Příklad obou těchto řešení (i těch uvedených výše) je vidět na následujícím screenshot-u.

[attachment=8229]

Kam získanou informaci, kterou potřebujeme zobrazit, uložit

Tady máme v podstatě tři základní možnosti. První se týká výše uvedených zdrojů infomací, které poskytuje samo Kodi. Tam nic nemusíme nikam ukládat, prostě příslušné proměnné použijeme v definičních souborech rovnou. Jejich obsah aktualizuje Kodi. Druhou možností je použití proměnných skinu a třetí pak, použití tzv. properties. 

Proměnné skinu mají výhodu v tom, že jsou "nonvolatilní", jejich hodnoty se ukládají, tzn. po restartu Kodi jsou zachovány. To u properties neplatí, jejich obsah se při každém startu Kodi vymaže. Jak je používat najdete například v List of built-in functions.

Jak získanou a uloženou informaci zobrazit

To je už ona pověstná třešnička na dortu. Způsob zobrazení záleží (do jisté míry) na zdroji informací. Zatímco proměnné Kodi a skinu jsou v zásadě dvojího typu, řetězec a logická veličina, u properties je to vždy pouze řetězec. Skin engin Kodi ale nabízí celou řadu funkcí, metod a možností "dopočtů", které umožnují nadefinovat i poměrně složité funkce. Chce to jistou zkušenost, ale s podporou Skinning Manual nebo například Estuary Easy to jde celkem snadno.

Postupně tu budu přidávat jednoduché ukázky toho, jak uvedenou problematiku řeším já, a to hlavně v kombinaci se skinem Estuary. Případně se můžete přidat a svá řešení ukázat také.
Zobrazení počtu dní zaplaceného VIP přístupu Webshare

Řešení, které popíšu, je celkem triviální a nedokonalé a má jistá omezení. Ale pro začátek to myslím nevadí. Já to ostatně tak dělánm vždy, když něco potřebuji rychle, chci si to vyzkoušet a pak to, po nějaké době používání, realizovat nějakým dokonalejším způsobem.

Získání informace řeším načtením obsahu porměnné a parsováním hodnoty ze settings.xml doplňku SCC. Tady je to základní omezení. SCC hodnotu z WS načítá a ukládá do settings.xml pouze při přihlášení k WS, tedy typicky při startu addon, a pouze tehdy, pokud od posledního načtení uplynula nastavená doba (momentálně je to 1 den). Já si tedy ze settings.xml hodnotu načítám také jen při spuštění Kodi. Používám pro to service addon service.autoexec, ve které spuštím dále popsaný script. Znamená to, že ne vždy je zobrazená hodnota 100% aktuální (to je další daň jednoduchosti řešení), ale to se srovná vždy při dalším spuštění Kodi.

Načtení hodnot provádím pomocí sh scriptu. Za normálních okolností a v *ELEC systému bych pro to použil známý script oe_setup_addon, tomto případě to ale není možné. SCC bohužel používá v identifikátorech settings i znak "." (další drobný problém SCC) a s tím si tento script neumí poradit. Proto parsování provádím pomocí systémových příkazů grep a sed.
 
Kód:
#! /bin/sh
vip_check=$(grep "last_vip_check" /storage/.kodi/userdata/addon_data/plugin.video.stream-cinema-2-release/settings.xml | sed -re "s/.*>(.*)\..*<.*/\\1/")
kodi-send -a "SetProperty(vip_check,${vip_check},10000)"
vip_duration=$(grep "provider.vip_duration" /storage/.kodi/userdata/addon_data/plugin.video.stream-cinema-2-release/settings.xml | sed -re "s/.*>(.*)<.*/\\1/")
kodi-send -a "SetProperty(vip_duration,${vip_duration},10000)"
vip_days=$(echo ${vip_duration} | sed -re "s/.*\(Dny: ([0-9]*)\).*/\\1/")
if [ ${vip_days} -gt 14 ] ; then
    kodi-send -a "SetProperty(vip_days,[COLOR blue]${vip_days}[/COLOR],10000)"
elif [ ${vip_days} -gt 7 ] ; then
    kodi-send -a "SetProperty(vip_days,[COLOR yellow]${vip_days}[/COLOR],10000)"
else
    kodi-send -a "SetProperty(vip_days,[COLOR red]${vip_days}[/COLOR],10000)"
fi
Načítám proměnné vip_check a vip_duration. Z vip_duration pak parsuji vlastní hodnotu počtu dní a ukládám ji do proměnné vip_days. Všechny tři proměnné pak ukládám do Kodi properties se shodnými jmény. Při ukládání hodnoty počtu dní ji ještě doplním metakódy barev podle zbývajícího počtu dní (>14 blue, >7 & <=14 yellow, <=7 red). Pro ukládání používám v *ELEC dostupný příkaz kodi-send. Tady je tedy další omezení, jednak to lze použít právě jen u tohoto typu instalací a jednak každé použití tohoto příkazu deaktivuje případně spuštěný screen saver. Ale i to je daň za jednoduchost řešení. Jistě by místo kodi-send šlo použít i json-rpc příkaz, pak by to bylo obecnější.

Vlastní zobrazení ve skinu Kodi je pak celkem jednoduché. Použijeme k tomu např. toto:
 
Kód:
        <control type="label" id="1">  <!-- EASY+ SCC VIP days remains -->
            <width>auto</width>
            <aligny>center</aligny>
            <font>font_flag</font>
            <label>$INFO[Window(Home).Property(vip_days),VIP: ]</label>
        </control>
Finální řešení a umístěné kódu samozřejmě závisí na použitém skinu. Ale znalí skineři budou určitě vědět, jak na to. V Estuary Easy to pak vypadá nějak takto:
[attachment=8242]
Abych měl přehled o tom, co se v settings.xml děje, tak jsem si ještě další dvě proměnné zobrazil v testovacím okně proměnných skinu. Testovací okno používám už dlouho, zobrazuji si tam vybrané veličiny pro potřeby ladění a testování a je to velmi produktivní a pomáhá mi to.
[attachment=8243]
VIP days podruhé, s pomocí Webshare api...

Jak jsem napsal, čato preferuji rychlé řešení k odzkoušení funkce. Nyní jsme tedy zkusil trochu jinou cestu, postrádající jedno z omezení, o kterém jsme psal v minulém postu. Východiskem je použití api rozhraní webshare a načtení obsahu user_data. To může vypadat následovně.

Nejdříve musíme získat aktuální provider_token:
Kód:
provider_token=$(grep 'id="provider.token"' /storage/.kodi/userdata/addon_data/plugin.video.stream-cinema-2-release/settings.xml | sed -re "s/.*>(.*)<.*/\\1/")
Pak s jeho pomocí vlastní obsahu user_data:
Kód:
user_data=$(wget -qO - --post-data "wst=${provider_token}" "https://webshare.cz/api/user_data")
Obsahem je celá řada zajímavých informací v xml formálu. Z nich pak už není problém vyparsovat hodnotu vip_days:
Kód:
vip_days=$(echo ${user_data} | sed -re "s/.*<vip_days>(.*)<\/vip_days>.*/\\1/")
Další porce informací

V tomo přípdě se vracím k tomu, co jsem už kdysi řešil v addon Monitor. Chystám se tento addon resuscitovat, ale zatím jsem si sadu nových infomací vyzkoušel jako tradičně s pomocí sh scriptu.

Zajímají mě stavy komunikace, informace o serveru a pak také stav Tvheadend serveru. To poslední proto, protože hlavní domácí server mi běží na hlavním obývákovém Kodi (Beelink GT King + CE) a já o něm chci mít přehled. Pojal jsme to opět co možná nejjednodušeji a nejrychleji. Script běží v nekonečné smyčce a spouští se se samotným spuštěním Kodi pomocí service.autoexec.
 
Kód:
#! /bin/sh

path=$(dirname $(realpath $0))/
. ${path}/monitor.ini

echo MONITOR Start

echo end=${end} delay=${delay}

nas_code=-1 ; kodi-send -a "ClearProperty(nas_code,10000)"
lan_code=-1 ; kodi-send -a "ClearProperty(lan_code,10000)"
wan_code=-1 ; kodi-send -a "ClearProperty(wan_code,10000)"
scc_code=-1 ; kodi-send -a "ClearProperty(scc_code,10000)"
cfl_code=-1 ; kodi-send -a "ClearProperty(cfl_code,10000)"
tvh_code=-1 ; kodi-send -a "ClearProperty(tvh_code,10000)"
cli_code=-1 ; kodi-send -a "ClearProperty(cli_code,10000)"
sub_code=-1 ; kodi-send -a "ClearProperty(sub_code,10000)"

while [ ${end} == 0 ] ; do
    # LAN
    ping -c 1 -W 1 -q 10.0.0.1
    if [ $? == 0 ] ; then
        if [ ${lan_code} != 1 ] ; then
            kodi-send -a "SetProperty(lan_code,1,10000)"
            lan_code=1
        fi
    else
        if [ ${lan_code} != 0 ] ; then
            kodi-send -a "SetProperty(lan_code,0,10000)"
            lan_code=0
        fi
    fi

    # NAS
    ping -c 1 -W 1 -q 10.0.0.10
    if [ $? == 0 ] ; then
        if [ ${nas_code} != 1 ] ; then
            kodi-send -a "SetProperty(nas_code,1,10000)"
            nas_code=1
        fi
    else
        if [ ${nas_code} != 0 ] ; then
            kodi-send -a "SetProperty(nas_code,0,10000)"
            nas_code=0
        fi
    fi

    # WAN
    ping -c 1 -W 2 -q www.google.com
    if [ $? == 0 ] ; then
        if [ ${wan_code} != 1 ] ; then
            kodi-send -a "SetProperty(wan_code,1,10000)"
            wan_code=1
        fi
    else
        if [ ${wan_code} != 0 ] ; then
            kodi-send -a "SetProperty(wan_code,0,10000)"
            wan_code=0
        fi
    fi

    # SCC
    ping -c 1 -W 2 -q plugin.sc2.zone
    if [ $? == 0 ] ; then
        if [ ${scc_code} != 1 ] ; then
            kodi-send -a "SetProperty(scc_code,1,10000)"
            scc_code=1
        fi
    else
        if [ ${scc_code} != 0 ] ; then
            kodi-send -a "SetProperty(scc_code,0,10000)"
            scc_code=0
        fi
    fi

    # Cloudflare
    if [ ${scc_code} == 1 ] ; then
        json=$(curl -s https://plugin.sc2.zone)
        error=$(echo ${json} | jq -r '.error')
        if [ "${error}" == "Not Found" ] ; then
            if [ ${cfl_code} != 1 ] ; then
                kodi-send -a "SetProperty(cfl_code,1,10000)"
                cfl_code=1
            fi
        else
            if [ ${cfl_code} != 0 ] ; then
                kodi-send -a "SetProperty(cfl_code,0,10000)"
                cfl_code=0
            fi
        fi
    else
        kodi-send -a "SetProperty(cfl_code,0,10000)"
        cfl_code=0
    fi

    # Tvheadend
    subscription=$(curl -s "http://localhost:9981/api/status/subscriptions" | jq '.totalCount')
    client=$(curl -s "http://localhost:9981/api/status/connections" | jq -r '.totalCount')
    if [ $? == 0 ] ; then
        if [ ${tvh_code} != 1 ] ; then
            kodi-send -a "SetProperty(tvh_code,1,10000)"
            tvh_code=1
        fi
    else
        if [ ${tvh_code} != 0 ] ; then
            kodi-send -a "SetProperty(tvh_code,0,10000)"
            tvh_code=0
        fi
    fi
    
    # Tvheadend client
    if [ ${tvh_code} == 1 ] ; then
        if [ "${cli_code}" != "${client}" ] ; then
            kodi-send -a "SetProperty(cli_code,${client},10000)"
            cli_code=${client}
        fi
    else
        if [ "${cli_code}" != "" ] ; then
            kodi-send -a "ClearProperty(cli_code,10000)"
            cli_code=
        fi
    fi
    # Tvheadend substription
    if [ ${tvh_code} == 1 ] ; then
        if [ "${sub_code}" != "${subscription}" ] ; then
            kodi-send -a "SetProperty(sub_code,${subscription},10000)"
            sub_code=${subscription}
        fi
    else
        if [ "${sub_code}" != "" ] ; then
            kodi-send -a "ClearProperty(sub_code,10000)"
            sub_code=
        fi
    fi

    . ${path}/monitor.ini
    sleep ${delay}
done

echo MONITOR End

exit 0
Je to hodně triviální a neoptimalizované, ale funkční.

Co sleduji a jak?
  • dostupnost LAN, pomocí ping na hlavní domácí router - LAN
  • dostupnost NAS serveru, pomocí ping - NAS
  • dostupnosr WAN, úpomocé ping na google.com  1 - WAN
  • dostupnost SCC serveru, ping na pligin.sc2.zone - SCC
    • následně i analýza response api rozhraní - tady to je ještě nevyřešené, zatím tedy jen jakési torzo
  •  dostupnost Tvheadend serveru, analýza response api rozhraní - ikona Tvheadend
    • zjištění počtu aktivních HTSP clientů - první číslo za ikonou Tvheadned a :
    • zjištění počtu aktivních subscriptions - číslo za /
Opět data zapisuji do Kodi properties, zápis probíhá změnově, tzn. že se zapisuje jen pokud od posledního zápisu došlo k nějaké změně (nuluje se to při startu scriptu).

Takhle nějak vypadá výsledek, vesměs je všechno v pravém horní rohu, počínaje ikonou Tvheadend, až do konce:
[attachment=8291]

Pro všechny ping mám nastavenou krátkou prodlevu čekání na odpověď, takže mi občas problikne výpadek (text  zčervená), ale mám to úmyslně, alespoň vidím jak je to citlivé v tu kterou denní dobu.

Ve skinu to vypadá takto:
 
Kód:
        <control type="image" id="1">  <!-- EASY+ TVH state -->
            <top>6</top>
            <width>16</width>
            <height>16</height>
            <fadetime>300</fadetime>
            <aspectratio aligny="center" align="center">keep</aspectratio>
            <texture>special://skin/extras/icons/tvh.png</texture>
            <visible>String.IsEqual(Window(Home).Property(tvh_code),1)</visible>
        </control>
        <control type="label" id="1"> <!-- EASY+ TVH subscription -->
            <left>-1</left>
            <width>auto</width>
            <aligny>center</aligny>
            <font>font_flag</font>
            <label>$INFO[Window(Home).Property(cli_code),:]$INFO[Window(Home).Property(sub_code),/]</label>
        </control>

        <control type="label" id="1"> <!-- EASY+ LAN state -->
            <width>auto</width>
            <aligny>center</aligny>
            <textcolor>$VAR[lan_state_color]</textcolor>
            <font>font_flag</font>
            <label>[B]LAN[/B]</label>
        </control>
        <control type="label" id="1"> <!-- EASY+ NAS state -->
            <width>auto</width>
            <aligny>center</aligny>
            <textcolor>$VAR[nas_state_color]</textcolor>
            <font>font_flag</font>
            <label>[B]NAS[/B]</label>
        </control>
        <control type="label" id="1"> <!-- EASY+ WAN state -->
            <width>auto</width>
            <aligny>center</aligny>
            <textcolor>$VAR[wan_state_color]</textcolor>
            <font>font_flag</font>
            <label>[B]WAN[/B]</label>
        </control>
        <control type="label" id="1"> <!-- EASY+ SCC state -->
            <width>auto</width>
            <aligny>center</aligny>
            <textcolor>$VAR[scc_state_color]</textcolor>
            <font>font_flag</font>
            <label>[B]SCC[/B]</label>
        </control>

Nutné dopočty jsou ve skinu pak tyto:
 
Kód:
    <variable name="lan_state_color">
        <value condition="String.IsEqual(Window(Home).Property(lan_code),1)">green</value>
        <value condition="String.IsEqual(Window(Home).Property(lan_code),0)">red</value>
        <value>grey</value>
    </variable>
    <variable name="nas_state_color">
        <value condition="String.IsEqual(Window(Home).Property(nas_code),1)">green</value>
        <value condition="String.IsEqual(Window(Home).Property(nas_code),0)">red</value>
        <value>grey</value>
    </variable>
    <variable name="wan_state_color">
        <value condition="String.IsEqual(Window(Home).Property(wan_code),1)">green</value>
        <value condition="String.IsEqual(Window(Home).Property(wan_code),0)">red</value>
        <value>grey</value>
    </variable>
    <variable name="scc_state_color">
        <value condition="String.IsEqual(Window(Home).Property(scc_code),1) + String.IsEqual(Window(Home).Property(cfl_code),1)">green</value>
        <value condition="String.IsEqual(Window(Home).Property(scc_code),1) + String.IsEqual(Window(Home).Property(cfl_code),0)">yellow</value>
        <value condition="String.IsEqual(Window(Home).Property(scc_code),0)">red</value>
        <value>grey</value>
    </variable>
: Kdysi mě nabudil : s Dashboard-Kodi, pak s dalšími nápady či postřehy ty, a tak jsem si vytvořil vlastní service pro dostupnost sítě. Určitě to není ideální a odpovídající všem zvyklostem tvorby service, ale funguje to.
Já vlastně addon monitor s podobnou service mám také, trochu rozsáhlejší, kde pro funkce dostupnosti ping používám také, a podobným způsobem, jen rozšířené tak, aby to fungovalu v linux i windows (parametry ping v linux a windows jsou jiné 10 ). Mám tam i jiné funkce, včetně dostupnosti některých zařízení na aplikační úrovni. Ono např. ping na SCC server nestačí, protože to, že je server dostupný, ještě neznamená, že funguje i api aplikace. Ale to je už jiné téma.

Náše původní service bylo obrovské, byla tam i možnost volby jak často některý test spouštět nebo spouštění v celou hodinu nebo na přechodu mezi dny apod. Časem byla jeho údržba komplikovaná a udržení všech funkcí pro linux i widnows dost složité. Proto z něj používám jenom něco, to co funguje, a když potřebuji něco přidat, řeším to přes ty scripty. Ale věřím, že časem se k tomu vrátím a addon monitor opráším.
: Díky za pochvalu. I já mám další. Mám to šité jen na box a mnou používaný upravený skin. Víceméně vše z tvých námětů a postřehů. VIP, datový tok, svátky, narozeniny. Jen to zatím neumím dát do rodin (ping + RX/TX, popř. Svátky + Narozeniny) tak, aby mi to fungovalo. To musím ještě nastudovat. Ale prioritou je dodělat korektní zavření všech mých service. Teď to Kodi shodí natvrdo. Funkčně to zřejmě ničemu nevadí, ale připisuji tomu abnormálně dlouhý restart boxu v případě potřeby. Normálně jen uspávám, tam se to neprojeví.
Jo jo, neshození service v předepsaném čase má na restart boxu vliv. S tímhle občas bojuje i SCC a jiné addon, které část service intenzivně používají (a některé dost brutálně, jako třeba právě SCC). Z tohoto ohledu je vlastně to řešení mimo Kodi, pomocí scriptů v systému, vhodnější, protože tam žádné takové problémy nehrozí. Ale nedá se samozřejmě použít vždy.

Co se týče základní struktury jednoduché service, kterou asi potřebuješ ty, je to jednoduché, podívej se do Service add-ons.
: O tom vím. Jen jde o to, že když to aplikuju např. na ten ping či ostatní mé výtvory tak, jak jsem to pochopil, stejně některý z nich občas Kodi shodí natvrdo. A nejčastěji právě ten ping. A téměř pokaždé na stejné řádce response_nas = os.system("ping -c 1 " + nas). Mám totiž verze, kde to je aplikované, ale to jsem schválně nevyvěsil. Právě kvůli nespolehlivosti. Kdybys, prosím, upravil ten můj addon tak, jak to má být správně, budu rád.