Skocz do zawartości

Pisanie pluginów pod E2. Jak zacząć.


Gość czerwus

Rekomendowane odpowiedzi

Witam. To mój pierwszy post, do tej pory byłem tylko czytelnikiem. Na wstępie chciałbym pogratulować świetnej roboty, Tuxowi  i całemu devteam tworzącemu Graterlie2 jednocześnie dziękując za danie nam możliwości korzystania z ich dzieła.  Jako, że sam trochę programuje (niestety tylko win32) wpadłem na pomysł fajnego plugina, niestety nie mam pojęcia jak zacząć pracę nad pluginem. Czy wszystkie pluginy muszą być w pisane w pythonie czy też innym języku czy np. może to być odpowiednio zrobiony plik komend bash. Moje kolejne pytanie to czy z poziomu terminala logując się np. przez putty uzyskuje się dostęp do komend uruchomiających np. rozpoczęcie nagrywania czy też możliwość zmiany kanału na inny. Czy jest dostępne jakieś kompendium wiedzy o OpenPLI w którym mógłbym znaleźć te informacje? Z góry dziękuje za podpowiedź. Pozdrawiam.

Odnośnik do komentarza
Udostępnij na innych stronach

Trochę to stare, ale chyba ciągle użyteczne:

https://sites.google.com/site/allaboutdreambox/plugins/enigma2-plugin-tutorial

http://neverland.digsat.net/aadb/pdf/The%20enigma2-plugin%20Tutorial.pdf

 

Wtyczki pisane są w pythonie, ale mogą wywoływać komendy systemowe, czyli np. skrypty shella ... ale ostatnio zauważyłem, że niestety wywołuje to błędy "out of memory".

 

Nagrywanie i zmianę kanału można uruchomić z terminala na pewno drogą okrężną, czyli przez wget http://ip_tunera/adres_strony, to jest niejako przez OpenWebif. OpenWebif łączy się jako wtyczka z enigmą i robi co potrzebujemy. Pewnie dałoby się jeszcze przejąć kontrolę nad lircd i evremote2 i przesyłać komendy pilota bezpośrednio...

 

Kompendium wiedzy/dokumentacja. Z tego co wiem, to właśnie z tym jest największy problem. Kilka linków masz tutaj: http://forum.xunil.pl/index.php?topic=1043.msg13242#msg13242 i dwa posty niżej. I jak tam napisał @herpoi "Pozostaje samodzielne przeglądanie źródeł.".

 

No i pozostaje google...

Odnośnik do komentarza
Udostępnij na innych stronach

A jakiż to pomysł?

 

No pomysł dość banalny. A przyszedł mi do głowy wczoraj jak poszedłem na mecz koszykarski swojej ulubionej drużyny. (Stelmet Zielona Góra wczoraj wygrał z Valencia BC) i z pierwszym gwizdkiem przypomniało mi się, że zapomniałem nagrywania ustawić :/ Pomyślałem sobie, że szkoda, że nie mogę jakoś zdalnie kontrolować mojego nBoxa bo przecież mam podłączony do neta. Aplikacje na smartfona do obslugi E2 choć są (np. e2remote na iOs) to nie zdadzą egazaminu bo nBox stoi na firewallem a nie każdy ma VPNa :) Dlatego pomyślałem sobie, że fajnie by było napisać plugina który przez neta pobierał by treść np. pliku tekstowego albo rekord MySQL z serwera (który oczywiście trzeba by mieć, ja np. mam:) ) A ja ze smartfona wysyłałbym komendy zapisywane do tego pliku w postaci przykładowo:

record 118,toend,+3; czyli nagrywanie, kanał 118, do końca audycji, +3 minuty zapasu. Wiadomo, że to bida obsługa tekstowa, ale można by do tego dorobić jakiś interfejs graficzny już na smartfonie, albo chociażby interfejs www na serwerze :) To drugie rozwiązanie wydawało by się bardziej uniwersalne :) Wiadomo, że trzeba by do tego jakiś system autoryzacji zrobić, ale wydaje mi się że po stronie serwera by wystarczyło. :) Co wy na to? :) Jeśli ktoś podjął by się napisać to w pythonie na E2 to ja wtedy zrobię interfejs serwerowy tak, że będzie można sobie konta zakładać i byłby jeden serwer dla wszystkich :)

Odnośnik do komentarza
Udostępnij na innych stronach

a nie łatwiej zrobić tunel po ssh i potem po prostu wbić się przez przeglądarkę na webif'a?

Ale to rozwiązanie dla Ciebie łatwiejsze w ogóle nie jest "user friendly" :) A skoro miałby to być plugin dla mas, to trzeba czegoś takiego, co w konfiguracji wymagało by tylko podania loginu, hasla i adresu serwera :) Albo nawet prościej, przy pierwszym uruchomieniu generowało by na nboxie token, który trzeba by przepisać w interfejsie klienta żeby mieć do niego dostęp bez zbędnej konfiguracji po stronie nboxa :)

Odnośnik do komentarza
Udostępnij na innych stronach

  • 3 tygodnie później...

Witam. 

 

Panowie ja też bym chciał zrobić plugina który łączy się z piecem CO w domu i wyświetli dane na ekranie.

 

Chciałem wykorzystać  plugin HelloWord , ale widzę że jestem za słaby w te klocki , nie wiem gdzie i jak wstawić mój kod który działa do pluginu helloword. Może ktoś pomoże

 

kod helloword



from Screens.Screen import Screen
from Components.Label import Label
from Components.ActionMap import ActionMap
from Plugins.Plugin import PluginDescriptor


###########################################################################


class HalloWorldScreen(Screen):
    skin = """
        <screen position="130,150" size="460,150" title="Ihad.tv e2-tutorial lesson 1" >
            <widget name="myLabel" position="10,60" size="200,40" font="Regular;20"/>
        </screen>"""


    def __init__(self, session, args = None):
        self.session = session
        
        Screen.__init__(self, session)
        self["myLabel"] = Label(_("Hello World ;-)"))


        self["myActionMap"] = ActionMap(["SetupActions"],
        {
            "cancel": self.close # add the RC Command "cancel" to close your Screen
        }, -1)




###########################################################################


def main(session, **kwargs):
    print "\n[Hallo World] start\n"
    
    session.open(HalloWorldScreen)


###########################################################################


def Plugins(**kwargs):
    return PluginDescriptor(
            name="01 Hallo World",
            description="lesson 1 - Ihad.tv e2-tutorial",
            where = PluginDescriptor.WHERE_PLUGINMENU,
            icon="../ihad_tut.png",
            fnc=main)


 

 

 

 

a to moj kod który chce osadzić w helloword

 



#!/usr/bin/env python
import urllib
from array import *




class myURLOpener(urllib.FancyURLopener):
    # read an URL, with automatic HTTP authentication


    def setpasswd(self, user, passwd):
        self.__user = user
        self.__passwd = passwd


    def prompt_user_passwd(self, host, realm):
        return self.__user, self.__passwd


urlopener = myURLOpener()
urlopener.setpasswd("admin", "admin")


fp = urlopener.open("http://192.168.1.5/?com=02010006000000006103")
data = fp.read()


# tutaj obróbka danych


print data

Odnośnik do komentarza
Udostępnij na innych stronach

Ok udało się odpalić plugin  ;) , ale czy da się to zapętlić zęby odświeżał np: co 1sek

 

 


from Plugins.Plugin import PluginDescriptor
from Screens.Console import Console
import time


cmd = "python mat.py"


def main(session, **kwargs):


    	session.open(Console,_("E-sterownik parametry pieca CO"),[cmd])
   	
def Plugins(**kwargs):
    	return [PluginDescriptor(name="E-sterownik", description=_("Parametry pieca on-line"), where = PluginDescriptor.WHERE_PLUGINMENU, fnc=main),
            	PluginDescriptor(name="Execute My Script", description=_("execute /usr/script/ExcuteMyScript.sh"), where = PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=main)]


Odnośnik do komentarza
Udostępnij na innych stronach

Poddaje się,  chyba nie dam rady za wysokie progi, chyba wystarczy to co mam :-). marzenia miałem większe , chciałem po odpaleniu plugina zęby było statyczne zdjęcie  z piecem, bojlerem grzejnikami i w chmurkach temperatury które by się odświeżały. Ale tego w notatniku chyba nie zrobię :-)  Dzięki wszystkim za pomoc.

Odnośnik do komentarza
Udostępnij na innych stronach

Z tym notatnikiem żartowałem oczywiście mam notepad++

 

 

oto mój kod  wyciągnięcia danych z pieca

 

 



import urllib
import json


class myURLOpener(urllib.FancyURLopener):


    def setpasswd(self, user, passwd):
        self.__user = user
        self.__passwd = passwd


    def prompt_user_passwd(self, host, realm):
        return self.__user, self.__passwd


urlopener = myURLOpener()
urlopener.setpasswd("admin", "admin")


fp = urlopener.open("http://192.168.1.5/?com=02010006000000006103")
data = fp.read()
data =json.loads(data)


temp2 = (int(data[18])+(int(data[19])*256))*0.1
temp3 = (int(data[20])+(int(data[21])*256))*0.1
temp4 = (int(data[22])+(int(data[23])*256))*0.1
temp5 = (int(data[24])+(int(data[25])*256))*0.1
temp6 = (int(data[26])+(int(data[27])*256))*0.1
temp7 = (int(data[28])+(int(data[29])*256))*0.1
temp8 = (int(data[30])+(int(data[31])*256))*0.1


print "Temperatura wewnetrzna:",temp2
print "Temperatura zewnetrzna:",temp3
print "Temperatura CO:        ",temp7
print "Temperatura CWU:       ",temp4
print "Temperatura powrotu:   ",temp5
print "Temperatura podajnika: ",temp6
print "Temperatura spalin:    ",temp8




 

 

 

 

 

 

Odnośnik do komentarza
Udostępnij na innych stronach

 

Mam nadzieje ze robię jakieś postępy na podstawie innych pluginów ;)

 

 

moje zmiany są po ##

 

 

nie wiem czy dobrze definicja klawisza "OK"

 

 

jak do tego miejsca to działa :)

 

 

from Screens.Screen import Screen
from Components.Label import Label
from Components.ActionMap import ActionMap
from Plugins.Plugin import PluginDescriptor
import urllib
import json




class myURLOpener(urllib.FancyURLopener):




    def setpasswd(self, user, passwd):
        self.__user = user
        self.__passwd = passwd




    def prompt_user_passwd(self, host, realm):
        return self.__user, self.__passwd


class HalloWorldScreen(Screen):
    skin = """
        <screen position="130,150" size="700,500" title="Dane z pieca" >
##       <ePixmap position="50,0" zPosition="4" size="666,500" pixmap="/piec.png" transparent="1" alphatest="on" /> 
##           <widget name="myLabel1" position="10,60" size="200,40" font="Regular;20"/>
##            <widget name="myLabel2" position="10,100" size="200,40" font="Regular;20"/>
##            <widget name="myLabel3" position="10,140" size="200,40" font="Regular;20"/>
##            <widget name="myLabel4" position="10,180" size="200,40" font="Regular;20"/>
        </screen>"""




    def __init__(self, session, args = None):
        self.session = session
        
        Screen.__init__(self, session)
##      self["myLabel1"] = Label(_("?"))
##   self["myLabel2"] = Label(_("?"))
##   self["myLabel3"] = Label(_("?"))
   


        self["myActionMap"] = ActionMap(["SetupActions"],
        {
##       "ok": self.myMsg,
            "cancel": self.close # add the RC Command "cancel" to close your Screen
        }, -1)


##    def myMsg(self):
##   print "\n[myPiec] start\n"
##   self.session.open(HalloWorldScreen)






###########################################################################




def main(session, **kwargs):
    print "\n[myPiec] start\n"
    
    session.open(HalloWorldScreen)




###########################################################################




def Plugins(**kwargs):
    return PluginDescriptor(
            name="Monitor pieca",
            description="lesson 1 - monitor pieca",
            where = PluginDescriptor.WHERE_PLUGINMENU,
            icon="../ihad_tut.png",
            fnc=main)

Odnośnik do komentarza
Udostępnij na innych stronach

No i coś poszło nie tak wywala GS  , albo coś złe obsadziłem

 

 

 

 

jak dam

 

#self["myLabel2"].setText("%i" % (int(data[18])+(int(data[19])*256))*0.1) 

[/size]

[/size]to jest ok

 

 

zauważyłem ze jak  dam

 

 

[/size]self["myLabel2"] = Label(_("Test xxx"))

[/size]

[/size]to tez się[/size] nic nie wyświetla

 

 

 

crashlog

[/size]


[myPiec] myMsg


Traceback (most recent call last):
  File "/usr/lib/enigma2/python/Components/ActionMap.py", line 46, in action
  File "/usr/lib/enigma2/python/Plugins/Extensions/demo1/plugin.py", line 51, in myMsg
    self["myLabel2"].setText("%i" % (int(data[18])+(int(data[19])*256))*0.1)
KeyError: 'myLabel2'
(PyObject_CallObject(<bound method ActionMap.action of <Components.ActionMap.ActionMap instance at 0x23ce30c>>,('SetupActions', 'ok')) failed)
getResolvedKey config.plugins.crashlogautosubmit.sendAnonCrashlog failed !! (Typo??)
getResolvedKey config.plugins.crashlogautosubmit.addNetwork failed !! (Typo??)
getResolvedKey config.plugins.crashlogautosubmit.addWlan failed !! (Typo??)
]]>

from Screens.Screen import Screen
from Components.Label import Label
from Components.ActionMap import ActionMap
from Plugins.Plugin import PluginDescriptor
import urllib
import json




class myURLOpener(urllib.FancyURLopener):




    def setpasswd(self, user, passwd):
        self.__user = user
        self.__passwd = passwd




    def prompt_user_passwd(self, host, realm):
        return self.__user, self.__passwd


class HalloWorldScreen(Screen):
    skin = """
        <screen position="130,150" size="460,150" title="Dane z pieca" >
            <widget name="myLabel1" position="10,60" size="200,40" font="Regular;20"/>
    <widget name="myLabel2" position="10,100" size="200,40" font="Regular;20"/>
        </screen>"""




    def __init__(self, session, args = None):
        self.session = session
        
        Screen.__init__(self, session)
        self["myLabel1"] = Label(_("Test"))


self["myActionMap"] = ActionMap(["SetupActions"],
        {
    "ok": self.myMsg,
            "cancel": self.close # add the RC Command "cancel" to close your Screen
        }, -1)


    def myMsg(self):
print "\n[myPiec] myMsg\n"


data = ""
        
        urlopener = myURLOpener()
        urlopener.setpasswd("admin", "admin")
        fp = urlopener.open("http://192.168.1.5/?com=02010006000000006103")
        data = fp.read()
        data =json.loads(data)


self["myLabel2"].setText("%i" % (int(data[18])+(int(data[19])*256))*0.1)


#self["myLabel2"] = Label(_("Test xxx"))









###########################################################################




def main(session, **kwargs):
    print "\n[myPiec] start\n"
    
    session.open(HalloWorldScreen)




###########################################################################




def Plugins(**kwargs):
    return PluginDescriptor(
            name="Monitor pieca",
            description="lesson 1 - monitor pieca",
            where = PluginDescriptor.WHERE_PLUGINMENU,
            icon="../ihad_tut.png",
            fnc=main)
Odnośnik do komentarza
Udostępnij na innych stronach

No działa  :)

 

 

nie wiem dlaczego ale musiałem zmienić

self["myLabel2"].setText("%i" % (int(data[18])+(int(data[19])*256))*0.1)  

[/size]na:

[/size]

tempX= (int(data[18])+(int(data[19])*256))*0.1)
self["myLabel2"].setText("%i" % tempX)

[/size]no i %i zmienić na %s 

 

 

 

Odnośnik do komentarza
Udostępnij na innych stronach

No idziemy dalej  ;) . Jak mam bata nad sobą to coś nawet wychodzi ;D

 

 

gdy piec nie odpowie wydaje mi się ze jest OK

 

 

co do temp mam wątpliwości ale sprawdzam czy wynik jest int    np:  tempX=int( obliczenia)

 

 


try:
    
    fp = urlopener.open("http://192.168.1.5/?com=02010006000000006103")


    data = fp.read()
    data =json.loads(data)


    print data


    try:
        #temp3 = int("fdsf") 
        temp2 = int((int(data[18])+(int(data[19])*256))*0.1)


    


        print "Temperatura wewnętrzna:",temp2
       




    except ValueError:


        print "Błąd w obliczeniach"
except:
    print "Brak polączenia z piecem" 
Odnośnik do komentarza
Udostępnij na innych stronach

Osobiście zamiast print-a użyłbym np. myLabel1, jako linii statusu i wtedy:

Oczywiście taki jest zamiar to były testy na pythonie pod windowsem.

 

 

natomiast mam problem  z automatycznym pobieraniem danych  przyglądałem się  podanym wtyczką ale nic nie przychodzi do głowy.

 

 

jedynie to:  ale nie przetestowane bo dzieciaki  :)

 

 

 

 

self["myActionMap"] = ActionMap(["SetupActions"],
        {
    "ok": self.myMsg,
            "cancel": self.close # add the RC Command "cancel" to close your Screen
        }, -1)


    self.onClose.append(self.__onClose)


    def __onClose(self):

self.myMsg()

Odnośnik do komentarza
Udostępnij na innych stronach

no i coś nie tak  >:(

 

 

unindent does not match any outer indentation level  linia 65

 

 


   	self["myActionMap"] = ActionMap(["SetupActions"],
        {
    "ok": self.myMsg,
            "cancel": self.close # add the RC Command "cancel" to close your Screen
        }, -1)


self.onShown.append(self.onStart)




   
linia 65    def onStart(self):


 self.Timer = eTimer()
       	 self.Timer.callback.append(self.myMsg)
       	 self.Timer.start(1000*5, False)





    def myMsg(self):
print "\n[myPiec] myMsg\n"


data = ""
        
        urlopener = myURLOpener()
        urlopener.setpasswd("admin", "admin")
        fp = urlopener.open("http://192.168.1.5/?com=02010006000000006103")
        data = fp.read()
        data =json.loads(data)
temp2 = (int(data[18])+(int(data[19])*256))*0.1
        temp3 = (int(data[20])+(int(data[21])*256))*0.1
        temp4 = (int(data[22])+(int(data[23])*256))*0.1
        temp5 = (int(data[24])+(int(data[25])*256))*0.1
        temp6 = (int(data[26])+(int(data[27])*256))*0.1
        temp7 = (int(data[28])+(int(data[29])*256))*0.1
        temp8 = (int(data[30])+(int(data[31])*256))*0.1



self["myLabel1"].setText("%s" % temp2)
self["myLabel2"].setText("%s" % temp3)
self["myLabel3"].setText("%s" % temp4)
self["myLabel4"].setText("%s" % temp5)
self["myLabel5"].setText("%s" % temp6)
self["myLabel6"].setText("%s" % temp7)
self["myLabel7"].setText("%s" % temp8)


[/size]

Odnośnik do komentarza
Udostępnij na innych stronach

Wcięcia, wcięcia, wcięcia...

W Pythonie podstawą jest odpowiednie używanie wcięć. Jak używasz spacji to nie używaj tabulatorów i vice versa. Jeżeli przeklejasz fragment kodu z innego źródła to sprawdź czy stosuje ten sam format wcięć.

W edytorze włącz sobie wyświetlanie białych znaków to szybko zorientujesz się o co chodzi.

Odnośnik do komentarza
Udostępnij na innych stronach

Działa ;D

 

 

Chciałem Wszystkim podziękować za pomoc w szczególności jOOzkowi za motywacje i kod

mam nadzieję ze wskazówki kolegów pomogą choć trochę przy pisaniu pierwszego pluginu pod E2

 

 

Jeszcze raz wielki dzięki.

 

 

W załączniki plugin ze zdalnym dostępem do mojego pieca

 

 

 

 

Odnośnik do komentarza
Udostępnij na innych stronach

  • 1 miesiąc temu...

 

Witam ponownie

 

Panowie kontynuując rozbudowę  plugin'u napotkałem znów problem  :-[

Czy można zmienić kolor tła tekstu lub samego tekstu dynamicznie:

np:

if a==0:
<widget name="myLabel9" position="10,60" zPosition="1" size="300,25" font="Regular;20" foregroundColor="black" backgroundColor="white"/>
else:
<widget name="myLabel9" position="10,60" zPosition="1" size="300,25" font="Regular;20" foregroundColor="black" backgroundColor="black"/>
Odnośnik do komentarza
Udostępnij na innych stronach

Patrząc jak działa wtyczka FrontPanel, to coś dynamicznie da się robić. Wyświetlane tam opcje zależą od typu odbiornika a dodatkowo przełączanie niektórych opcji powoduje wyświetlanie lub usuwanie kolejnych ustawień. Ale czy to dokładnie to samo co próbujesz zrobić, to już nie wiem.

Odnośnik do komentarza
Udostępnij na innych stronach

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Gość
Dodaj odpowiedź do tematu...

×   Wklejono zawartość z formatowaniem.   Usuń formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

×
×
  • Dodaj nową pozycję...