Dynamic Webserver (variable processing)

Questions and comments specific to a particular plugin should go here.
kingtd
Plugin Developer
Posts: 78
Joined: Fri Jul 13, 2007 7:39 am

Dynamic Webserver (variable processing)

Post by kingtd » Wed May 20, 2009 4:06 am

This is a slight variation on the current Webserver plug-in that will look for {{eg.globals.<variable>}} and replace it with the value of that variable.

I've been using the Web Server with these tweaks for quite a while now. It allows you to use variables from eventghost as part of the webpage output with very little overhead. This is great for people building dashboards, web consoles, status pages, etc. To use it just put it in your eventghost (and disable the other webserver plug-in if you're using it currently). Edit your HTML to use {{eg.globals.<variable}} wherever you want the info displayed, and make sure that variable is getting set in eventghost.

For example I use {{eg.globals.VMCMediaName}} to show what's currently going on with my media center (along with my VMC Controller plug-in of course).

Notes:
- Nothing other than the eg.globals variables will display.
- Variables that don't process or convert easily to a string show up as "" (null).
- This can be dangerous if combined with external form input and weak input checking. You've been warned.

~K
Attachments
dynamicwebserver.zip
(4.7 KiB) Downloaded 1316 times

User avatar
Livin
Experienced User
Posts: 790
Joined: Wed Oct 08, 2008 4:56 am

Re: Dynamic Webserver (variable processing)

Post by Livin » Wed May 20, 2009 5:35 pm

I'd love to see a web interface that will "auto generate" a page based Macros in EG.

Is this possible?

Girder does this by 'device' and it is very cool!

Image
setup... XBMC, W7MC for DVR & Live OTA TV, JRMC for multi-zone audio, EG, MiCasaVerde Vera3, USB-UIRT IR receiver, Harmony remote, 5.2 home theater system

kingtd
Plugin Developer
Posts: 78
Joined: Fri Jul 13, 2007 7:39 am

Re: Dynamic Webserver (variable processing)

Post by kingtd » Wed May 20, 2009 7:34 pm

Well it's not automatic, but you can do it with the variables and actions in eventghost. I've done quite a bit of work on mine, and here's a screenshot of what the web interface currently looks like.

My Setup: Windows 7 Media Center - USB-UIRT - Insteon w/ ISY-26 - Harman Kardon AVR 645 - Networked PC's with Vista/OSX/W7 - Eventghost on everything

~K
Attachments
interface1.png

User avatar
Livin
Experienced User
Posts: 790
Joined: Wed Oct 08, 2008 4:56 am

Re: Dynamic Webserver (variable processing)

Post by Livin » Wed May 20, 2009 7:41 pm

can you share your code?
setup... XBMC, W7MC for DVR & Live OTA TV, JRMC for multi-zone audio, EG, MiCasaVerde Vera3, USB-UIRT IR receiver, Harmony remote, 5.2 home theater system

dberladyn
Posts: 3
Joined: Tue May 19, 2009 2:31 am
Location: Canada

Re: Dynamic Webserver (variable processing)

Post by dberladyn » Thu May 21, 2009 1:09 am

kingtd wrote:This is a slight variation on the current Webserver plug-in that will look for {{eg.globals.<variable>}} and replace it with the value of that variable.

I've been using the Web Server with these tweaks for quite a while now. It allows you to use variables from eventghost as part of the webpage output with very little overhead. This is great for people building dashboards, web consoles, status pages, etc. To use it just put it in your eventghost (and disable the other webserver plug-in if you're using it currently). Edit your HTML to use {{eg.globals.<variable}} wherever you want the info displayed, and make sure that variable is getting set in eventghost.

For example I use {{eg.globals.VMCMediaName}} to show what's currently going on with my media center (along with my VMC Controller plug-in of course).

Notes:
- Nothing other than the eg.globals variables will display.
- Variables that don't process or convert easily to a string show up as "" (null).
- This can be dangerous if combined with external form input and weak input checking. You've been warned.

~K
Hi I am new to EG. I wonder if you couldn't give me an example variable from a defaul Plugin. For example a variable from Winamp would help a lot. Once I get started I should be ok.

kingtd
Plugin Developer
Posts: 78
Joined: Fri Jul 13, 2007 7:39 am

Re: Dynamic Webserver (variable processing)

Post by kingtd » Sat May 23, 2009 9:41 pm

It's a little tricky because there really aren't any of the core plugins that generate events that have a payload, and this is really about displaying the information. The Winamp plugin even seems to be like this, or at least I couldn't get it to generate any usable output. I don't use Winamp, but I did install it to see if I could get an example for you.

Maybe the easiest way to see how this works would be to give you a quick Python Command example. Create a new action, choose python command, then enter this line:

Code: Select all

eg.globals.example="Hello World!"
Now create an HTML web page that eventghost will serve up:

Code: Select all

<HTML><HEAD><TITLE>Eventghost Dynamic Webserver Test</TITLE>
<BODY>
Here's an example value for eg.globals.example:  {{eg.globals.example}}
</BODY>
</HTML>
Now the way this works with some of the more active plugins (Broadcaster, HK, VMC Controller, ISY-26, etc) is that whenever something happens like song change or a light coming on, they generate actions in eventghost that look like this

VMC.MediaName,"Mr. Brightside"
VMC.ArtistName,"The Killers"
Insteon.A 26 35 1,"DOFF"

So I create simple python command actions for each of these to set the global variables like this:

Code: Select all

+VMC.MediaName
eg.globals.VMCMediaName=eg.event.payload

+VMC.ArtistName
eg.globals.VMCArtistName=eg.event.payload
Then I can reference these variables in a webpage to get the latest status of all my gear and media.

For the screenshot I posted before, I do some tricky stuff to find and copy the album art of the current song from Vista Media center. It's very specific to my configuration, but here's the code anyway. My media server is named PC008. This is a very advanced example and not something you'd normally need to do to just test out the Dynamic Webserver.

Code: Select all

#import win32com.client
from win32com.client import Dispatch
import time
import os
import shutil

#w=win32com.client.gencache.EnsureDispatch('WMPlayer.OCX',0)
w=Dispatch('WMPlayer.OCX')

if eg.globals.VMCMediaName=="":
    print "Probably a Playlist"
else:
    pl=w.mediaCollection.getByAlbum(eg.globals.VMCMediaName)
    s=pl
    print s.name, s.Item(0).getItemInfo("WM/WMCollectionID"), s.count

    t=s.Item(0)
    coverart=s.Item(0).getItemInfo("WM/WMCollectionID")
#coverart=s.Item(0).getItemInfo("WM/MediaClassPrimaryID")

#for i in range(1,t.attributeCount):
#    print t.getAttributeName(i),
#    print t.getItemInfo(t.getAttributeName(i))
    

    genericfile=r"e:\web\eventghost\images\generic_albumart.jpg"
    localfile=r"\\pc008\music\AlbumArt_"+coverart+"_large.jpg"
    serverfile=r"e:\web\eventghost\images\albumart.jpg"
    l5file="e:\web\eventghost\last5tracks.html"

    eg.globals.weblast5=""
    for Cover in eg.globals.l5Covers:
        eg.globals.weblast5="<div id='lastfivecover'><IMG class='l5cover' height='100' width='100' SRC='/images/Last5Tracks/"+Cover[3]+"'><div class='l5info'>"+Cover[1]+"</div></div>\n"+eg.globals.weblast5

    this5cover=[]
    this5cover.append(s.Item(0).getItemInfo("DisplayArtist"))
    print s.Item(0).getItemInfo("DisplayArtist")
    this5cover.append(s.Item(0).getItemInfo("Title"))
    this5cover.append(s.Item(0).getItemInfo("WM/AlbumTitle"))
    serverhistfile=r"e:\web\eventghost\images\Last5Tracks\albumart"+str(time.time())+".jpg"
    this5cover.append("albumart"+str(time.time())+".jpg")
    eg.globals.l5Covers.append(this5cover)
    this5cover=None

    if (len(eg.globals.l5Covers)>5):
        print "Popping: "+eg.globals.l5Covers[0][0]
        eg.globals.l5Covers.pop(0)


    if os.path.isfile(localfile):
        print "Local file exists"
        shutil.copy(localfile,serverfile)
        shutil.copy(localfile,serverhistfile)
    else:
    #   for i in range(1,t.attributeCount):
    #       print t.getAttributeName(i),
    #       print t.getItemInfo(t.getAttributeName(i))
        shutil.copy(genericfile,serverfile)
        shutil.copy(genericfile,serverhistfile)
        
Hope this helps, sorry I couldn't find a default plug-in that generates events that made sense for an example.

~K

dberladyn
Posts: 3
Joined: Tue May 19, 2009 2:31 am
Location: Canada

Re: Dynamic Webserver (variable processing)

Post by dberladyn » Sun May 24, 2009 5:33 pm

That's great, thank you!

I don't have time at the moment but I'll definitely be looking at this thread in depth when I have more time. Thanks again for taking the time to respond.

User avatar
Bitmonster
Site Admin
Posts: 2239
Joined: Mon Feb 06, 2006 10:28 pm

Re: Dynamic Webserver (variable processing)

Post by Bitmonster » Sun May 24, 2009 8:05 pm

Actually I was working on a similar enhancement of the webserver. It wasn't and isn't fully tested, therefore I haven't committed the changes, but here is something you can experiment with. The differences to the approach of kingtd are:

1. It uses jinja2 as a full featured template language for the web pages.
2. Therefore templates can evaluate every object in EG and also call functions, etc.
3. The evaluation of the webpage is delayed till the event (if there is any generated by the request) is processed completely. Therefore macros can modify some variables in reaction of the event and these modifications can be shown to the web browser immediately .

You need 0.3.7.r1016 or greater to get it working. Then replace plugins\Webserver\__init__.py with the attached version.

Ok, a little example. Imagine you want to build a webbpage to control some light. To keep track of the state of the light, we use a simple variable named 'lightState'. So firstly we define this variable and some macros to handle turning it on/off and also toggling its state and set "lightState" to the current state of the light every time.

Code: Select all

<?xml version="1.0" encoding="UTF-8" ?>
<EventGhost Version="1014">
    <Folder Name="Light Control" Expanded="True">
        <Macro Name="Set initial value" Expanded="True">
            <Event Name="Main.OnInit" />
            <Action>
                EventGhost.PythonCommand(u'lightState = False')
            </Action>
        </Macro>
        <Macro Name="Light Off" Expanded="True">
            <Event Name="Webserver.LightOff" />
            <Action>
                EventGhost.PythonCommand(u'lightState = False')
            </Action>
        </Macro>
        <Macro Name="Light On" Expanded="True">
            <Event Name="Webserver.LightOn" />
            <Action>
                EventGhost.PythonCommand(u'lightState = True')
            </Action>
        </Macro>
        <Macro Name="Light Toggle" Expanded="True">
            <Event Name="Webserver.LightToggle" />
            <Action>
                EventGhost.PythonCommand(u'lightState = not lightState')
            </Action>
        </Macro>
    </Folder>
</EventGhost>
Paste it to a configuration tree and restart EG, so the initial value can be set.

Now we create a simple web page:

Code: Select all

<html>
    <head></head>
    <body>
        <p>
            <a href="?LightOn">Turn Light On</a>
        </p>
        <p>
            <a href="?LightOff">Turn Light Off </a>
        </p>
        <p>
            <a href="?LightToggle">Toggle Light</a>
        </p>
        <p>
            Light is {{"on" if lightState else "off"}}
        </p>
    </body>
</html>
Save this as "light.html" in the HTML document root of the webserver plugin. Now open http://localhost/light.html in your web browser and see what happens. Every time you change the state of the light through one of the links, it will show the new state on the page.
Attachments
__init__.py
(12.19 KiB) Downloaded 797 times
Please post software-related questions in the forum - PMs will only be answered, if really private, thanks!

krambriw
Plugin Developer
Posts: 2570
Joined: Sat Jun 30, 2007 2:51 pm
Location: Stockholm, Sweden
Contact:

Re: Dynamic Webserver (variable processing)

Post by krambriw » Sun May 24, 2009 9:09 pm

This is perfect, thank you very much!!!

BestR Walter

User avatar
Livin
Experienced User
Posts: 790
Joined: Wed Oct 08, 2008 4:56 am

Re: Dynamic Webserver (variable processing)

Post by Livin » Mon May 25, 2009 5:25 pm

Bit,
Interested to hear your thoughts on this idea.

Create a set of properties for each Macro and Action, then have the web code auto-generate the web pages based on the properties.

Example...

Macro 'Media Center - on'
Type: trigger
States: <last triggered date/time>
Web Visible: yes
Web Page: 'Main'
Tab Order: 1
Label: "Media Center"
Images: TriggerOn.gif/TriggerOff.gif

Device 'Kitchen Lights'
Type: slider
States: off/10/20/30/40/50/60/70/80/90/100
Web Visible: yes
Web Page: 'Main'
Tab Order: 2
Label: "Kitchen Lights"
Image base: SliderVertible.jpg
Image movable: SliderThumbVerticle.jpg

Device 'Ceiling Fan'
Type: toggle
States: on/off
Web Visible: yes
Web Page: 'Master Bedroom'
Tab Order: 2
Label: "Ceiling Fan"
Image on: ToggleHighOn.gif/ToggleLowOn.gif
Image off ToggleHighOff.gif/ToggleLowOff.gif
setup... XBMC, W7MC for DVR & Live OTA TV, JRMC for multi-zone audio, EG, MiCasaVerde Vera3, USB-UIRT IR receiver, Harmony remote, 5.2 home theater system

sjolof
Posts: 27
Joined: Tue Aug 21, 2007 11:22 am

Re: Dynamic Webserver (variable processing)

Post by sjolof » Tue May 26, 2009 12:00 pm

Bitmonster wrote: You need 0.3.7.r1016 or greater to get it working. Then replace plugins\Webserver\__init__.py with the attached version.
Bitmonster:
Best plugin-idéa ever!

Sorry to say I´m having trouble.
When replacing _init_.py to your version I´m getting:
Webserver socket error /?LightOn
<type 'exceptions.Exception'> ('utf8', '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN">\r\n<html>\r\n<head>\r\n<title>Huvudmeny</title>\r\n\r\n</head> \r\n\r\n<frameset rows="35,30,*,40" frameborder="0" framespacing="0" border="0">\r\n\r\n<frame src="top.html" name="top" scrolling="no" marginheight="5" marginwidth="5" noresize frameborder=0>\r\n\r\n<frame src="sida_start.html" name="sida" scrolling="no" marginheight="5" marginwidth="5" noresize frameborder=0>\r\n\r\n<frame src="stora_start.html" name="stora" scrolling="auto" marginheight="5" marginwidth="25" frameborder=0>\r\n\r\n<frame src="bottom.html" name="bottom" scrolling="no" marginheight="5" marginwidth="10" noresize frameborder=0>\r\n\r\n</frameset>\r\n\r\n<noframes>\r\n\r\n<body>\r\nV\xe4lkommen tillbaks med en browser som klarar frames. </body>\r\n</noframes>\r\n</frameset>\r\n</html>', 683, 686, 'invalid data')
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 2820)
Traceback (most recent call last):
File "SocketServer.pyc", line 558, in process_request_thread
File "SocketServer.pyc", line 320, in finish_request
File "SocketServer.pyc", line 615, in __init__
File "BaseHTTPServer.pyc", line 329, in handle
File "BaseHTTPServer.pyc", line 323, in handle_one_request
File "C:\Program\EventGhost\plugins\Webserver\__init__.py", line 194, in do_GET
File "C:\Program\EventGhost\plugins\Webserver\__init__.py", line 149, in SendContent
File "jinja2\environment.pyc", line 504, in get_template
File "jinja2\loaders.pyc", line 96, in load
File "C:\Program\EventGhost\plugins\Webserver\__init__.py", line 69, in get_source
File "encodings\utf_8.pyc", line 16, in decode
UnicodeDecodeError: 'utf8' codec can't decode bytes in position 683-685: invalid data
----------------------------------------

I´m using 0.3.7.r1016 - Windows XP SP3

When putting back the old _init_.py the old webserver works as alwas.

Any idéas?

/Magnus


*Update*:
I removed all my own html-code and only used your example above and then it works perfect.
So I guess I need a separate webserver for running my old code. (Wich I used old eg-webserver for...)
Or could it be possible to use 2 webserver-plugins, one old and one new (with different names and ports)?
Any idéas?
Last edited by sjolof on Tue May 26, 2009 12:11 pm, edited 2 times in total.

User avatar
Bitmonster
Site Admin
Posts: 2239
Joined: Mon Feb 06, 2006 10:28 pm

Re: Dynamic Webserver (variable processing)

Post by Bitmonster » Tue May 26, 2009 12:07 pm

Templates must be stored in UTF-8 if they use non-ASCII characters. So set you editor accordingly.
Please post software-related questions in the forum - PMs will only be answered, if really private, thanks!

sjolof
Posts: 27
Joined: Tue Aug 21, 2007 11:22 am

Re: Dynamic Webserver (variable processing)

Post by sjolof » Tue May 26, 2009 12:12 pm

Bitmonster wrote:Templates must be stored in UTF-8 if they use non-ASCII characters. So set you editor accordingly.
I will give it a try. Thanks!

sjolof
Posts: 27
Joined: Tue Aug 21, 2007 11:22 am

Re: Dynamic Webserver (variable processing)

Post by sjolof » Tue May 26, 2009 1:06 pm

Bitmonster wrote:Templates must be stored in UTF-8 if they use non-ASCII characters. So set you editor accordingly.
Seems that you are correct.
I just removed my extended ascii characters "ÅÄÖ åäö" and after that it seems to work.
Now I have to learn how to set my editor (Crimson). When I changed to UTF-8 it just removes my åäö...
Thank you for now!

User avatar
Pako
Plugin Developer
Posts: 2274
Joined: Sat Nov 11, 2006 1:31 pm
Location: Czech Republic
Contact:

Re: Dynamic Webserver (variable processing)

Post by Pako » Tue May 26, 2009 2:02 pm

You can try this great (and free) editor:
http://www.pspad.com/en/
Excuse me, if I am writing nonsense. I did not follow the whole topic.

Pako

Post Reply