Scheduling in 1.8 – Always means Always!

Scheduling Always means just that… Always!

You want your displays to show content all the time such as a welcome message in your reception area?  Selecting Always in scheduling will do just that!
One of the many new and exciting features of 1.8 is Always Scheduling.  This will ensure that the Campaign or Layout selected will Always be scheduled.  Content will Always be shown on your displays.
Gone is the need to specify end dates as Always means Always!

The Always icon will show in your schedule…

And show Always until you decide to remove it!

Scheduling your regular content rotation as Always rather than scheduling the Default Layout will ensure that your Player has your real Default Layout to show when new content is being downloaded or if there’s ever a problem.  Useful for when you need to modify existing layouts!

With so many new features in 1.8  it’s hard to stop exploring!! 😀

 

What to expect in 1.8 “Tempel”

Back in October we let you know what to look forward to in 1.7 and beyond and since writing we have delivered 5 releases of 1.7, 6 Xibo for Android releases, moved to GitHub, opened the Xibo Community Forums and made many improvements to the Xibo Cloud.

Spring Signage are also pleased to be able to provide another full time Xibo resource, so please welcome Piotr Mis to the team (@peter in community). Peter will be assisting with the day-to-day Xibo support and helping to test our releases!

1.8 codename “Tempel”

We are now hard at work on the next Xibo release, which will be 1.8.0-alpha. In our October round-up we mentioned Playlists and Interactive Signage as targets for this release and we can now narrow this down and elaborate.

Playlists

Support for Playlists will be in the release. This is the idea that the contents of a region can be re-used across multiple layouts allowing content creators to have a set of layouts that differ slightly, but with the same main content. An example would be displays around a campus with an arrow showing the nearest exit in one region, but a common region for the other content. There are more details in the Feature Topic.

Interactive Signage

The full interactive signage implementation (as described in the Feature Topic) will be part of 1.9 Series, but we hope to include some basic features in 1.8.0-alpha2. In particular we hope to write a player API which allows 3rd parties to directly take certain actions on the Player (change layout).

Xibo API

The Xibo API has been in BETA for a long time, too long as far as we are concerned. 1.8 series will include a RESTful API with 100% coverage and a complete API document. We hope that this API functionality will greatly improve 3rd party interaction with Xibo and give developers a stable and reliable link into the Xibo CMS.

Changes for Developers

We recognise we have been on a journey with our Framework, Theme and Module Implementations and that this journey hasn’t always been a happy one! A lot of Xibo has been in existence since 2006 and doesn’t stick to modern day standards and ideals. We are happy to announce that this is going to change in 1.8 onwards.

We’ve decided to bite the bullet and strive for real code change – here are the highlights we’ve adopted:

  • PHP 5.4 or higher
  • The Slim PHP Framework
  • Twig
  • Composer
  • PSR-4 (yes, Xibo has a namespace!)
  • MVC (yes, we have models, controllers and Twig Views!)
  • RESTFul by design
  • A separate Web Folder for Security
  • PHPUnit

These changes have meant a lot of work, but have also meant that every bit of Xibo code has been revisited, scrutinized for improvements and had a test written to support it. We hope that adopting these standards means more contributors, more ideas and more Xibo!

Scripting Xibo Content Management – A brief tour of the API

One common use case people put forward is that they want to update a particular piece of content in a layout automatically on a schedule.

That could take the form of a video being updated on a daily basis, or an image.

Since Xibo 1.5 series, there has been a “work in progress” OAuth authenticated API for scripting actions in the Xibo CMS. As of Xibo 1.6.0-rc1, there are enough API methods implemented to do some basic layout and media management to script tasks such as these.

This article is a basic walk through showing you how to connect to the API, authorise an application to use the Xibo CMS on your behalf, a quick look at some basic API methods, and finally complete code to automatically replace a media item in a layout.

Firstly you must be running Xibo CMS 1.6.0-rc1 or later. Earlier versions may not have the API methods required for this guide.

This guide uses Python as the scripting language. Python is chosen because it’s cross platform, widely available, and it’s what the Xibo project uses to test the API with, so there are existing libraries (XiboAPI) that we can leverage. It’s perfectly possible to connect to the API from other languages. Indeed some example PHP code is provided in the main Xibo repository. The use of the API from other languages however falls outside this scope of this guide.

Most modern Linux installations will come with Python ready-installed. Windows users can download and install Python here: http://www.python.org/getit This guide assumes you have Python 2.7 installed.

  • You also need the Python OAuth2 library installed.
    • On Linux, you’ll need to install the “python-oauth2” package (at least on Debian based systems such as Ubuntu).
    • On Windows, the process is slightly less straight forward
      • Download OAuth2 library from github: https://github.com/simplegeo/python-oauth2/archive/master.zip
      • Extract the downloaded file somewhere on your PC (remember where this is!)
      • Open a command promt (Start -> Run -> cmd)
      • Change directory to where you extracted OAuth2 to (eg cd c:\tmp\python-oauth2-master)
      • Then run: python setup.py install
      • The OAuth2 library will be installed to your Python installation
  • Make an empty folder somewhere to store your new script in.
  • Download the XiboAPI.py library and config file, and save a copy of both in your new folder.
  • Python is a white-space delimited language, which means that the amount each line of code is indented defines which code block a line belongs to. It’s therefore very important that you setup your text editor to follow the standard Python convention. Tab characters should not be used, but instead four space characters. On Linux, gedit is a suitable choice, and on Windows I’d recommend Notepad++.
  • This guide will give you the overview of how to communicate with the Xibo CMS via the API. It is not intended to be a guide on programming in the Python scripting language. There’s a plethora of resources out there aimed at that. I would recommend Dive into Python as a good primer before embarking on this is Python is your chosen language.
  • So lets make a start! We’ll create a new file called ReplaceVideo.py with the following contents:
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Script to upload a Video to the Xibo CMS and replace
# an old copy of it in a region

# Imports
import os
from xml.dom import minidom
import XiboAPI

api = XiboAPI.XiboAPI()
  • So there we’ve defined that the script is Python and that it’s UTF-8 encoded (so we don’t have issues with unicode characters down the line). We then import the os, minidom and XiboAPI libraries. Finally we create an instance of the XiboAPI to communicate with the CMS.
  • Next we need to register your application with the Xibo CMS. You’ll need an administrative login to your Xibo CMS.
    • Once logged in as an administrator (eg xibo_admin), go to Administration -> Applications
    • Click Add Application
    • Enter your name and email address. You can leave the third and fourth boxes (website and callback URL empty)
    • Click Register
    • Note the Key and Secret that have been generated. We’ll need those in the next step.
  • Next open defaults.cfg in your text editor. We need to point the XiboAPI library at your Xibo CMS.
  • Edit the file as follows, replacing the consumer_key and consumer_secrets with the values you got from your CMS, and the URL for your Xibo CMS:
[Main]
secret = NULL
token = NULL
url = http://yourXiboServer.com/path/xibo
consumer_key = 1b9e2c84fc747257375ae3eaaa01d49705303dac7
consumer_secret = 948989ef9eb9c17c26369a2265c35cea
  • Save defaults.cfg and close it
  • Save your ReplaceVideo,py script
  • Now lets run what we have:
alex@alex-laptop:~/scratch/xibo-release/ReplaceVideo$ python ReplaceVideo.py
Request Token:
 - oauth_token = 7dda5851bf99e09bdad1b27aebaa6fd005303dc3e
 - oauth_token_secret = a289a41cab324475c849283d553b113b

Go to the following link in your browser:
http://localhost/html/xibo-16/server/index.php?p=oauth&q=authorize&oauth_token=7dda5851bf99e09bdad1b27aebaa6fd005303dc3e

Have you authorized me? (y/n)
  • That’s the output from my script so far. So hopefully your script will attempt to connect to the Xibo CMS at the URL you configured, and will ask you to authorise it with the CMS. Now before you click the link, it’s important that you log on to the Xibo CMS as the user you want the script to impersonate. So if the script needs to appear to be the user “alex”, log off the Xibo CMS and log in as “alex”. Then follow the link.
  • You’ll be taken to a page “Xibo API – Authorization Requested”. Click the Allow button. Since we didn’t define a callback URL, the page will refresh lots now. That’s normal and can be ignored. Keep clicking the Allow button until you see a message ‘Request authorized. Please return to your application.’
  • Go back to your running script and enter “y” to indicate the API request has been authorised.
  • You will see that access has been authorised:
Access Token:
 - oauth_token = 93399a91be50497afd0e3f66521ddc4b05303de08
 - oauth_token_secret = 104e4911f5f0e1dc9a45978d2428cbfa

You may now access protected resources using the access tokens above.
  • Excellent, so now we have access to the XiboAPI as your intended user. I appreciate that’s alot of setup work but most of this only ever needs to be done once. You can reuse the same XiboAPI object in more than one project.
  • Your access tokens will automatically be written to disk in a file called site.cfg. Keep that file safe as the contents allow API access to your Xibo CMS.
  • Now let’s do something useful with the API! Lets get a list of layouts in the system. Add the following to your ReplaceVideo.py script:
# Call the LayoutList Method
response, status, code, message, content = api.callMethod('LayoutList')

# Parse the response XML
doc = minidom.parseString(content)

#List the layouts
nodes = doc.getElementsByTagName('layout')

for layout in nodes:
    layoutId = int(layout.attributes['layoutid'].value)
    layoutName = str(layout.attributes['layout'].value)
    layoutDescription = str(layout.attributes['description'].value)
    layoutTags = str(layout.attributes['tags'].value)

    print "Layout ID %d" % layoutId
    print "    Name: %s" % layoutName
    print "    Description: %s" % layoutDescription
    print "    Tags: %s\n" % layoutTags

print "Layout List Complete\n\n"
  • Save the file and run it again. Note this time since we already have API credentials, the access to the API is seemless and no user interaction is required. A list of layouts the user has access to view is shown:
alex@alex-laptop:~/scratch/xibo-release/ReplaceVideo$ python ReplaceVideo.py 
Layout ID 4
    Name: Default Layout
    Description: 
    Tags: 

Layout ID 5
    Name: My Video Layout
    Description: Daily Updated Video
    Tags: video 

Layout List Complete
  • So here the Layout we’re interested in is Layout ID 5. Lets add some code to see what regions are in Layout ID 5. Add the following to ReplaceVideo.py:
# We're interested in LayoutID 5
params = [('layoutid', '5')]

# Call the RegionList Method
response, status, code, message, content = api.callMethod('LayoutRegionList', params)

# Parse the response XML
doc = minidom.parseString(content)

# List the Regions
nodes = doc.getElementsByTagName('region')

for node in nodes:
    regionId = str(node.attributes['regionid'].value)
    regionWidth = int(node.attributes['width'].value)
    regionHeight = int(node.attributes['height'].value)
    regionTop = int(node.attributes['top'].value)
    regionLeft = int(node.attributes['left'].value)

    print "Region ID %s" % regionId
    print "    Width: %s" % regionWidth
    print "    Height: %s" % regionHeight
    print "    Top: %s" % regionTop
    print "    Left: %s\n" % regionLeft

print "Region List Complete\n\n"
  • Again save the file and run it again:
Region ID 47ff29524ce1b
    Width: 409
    Height: 450
    Top: 0
    Left: 0

Region ID 5303e4c0c0973
    Width: 227
    Height: 212
    Top: 40
    Left: 502

Region List Complete
  • So my example layout (id 5) has two regions on it. The right-most region is the one which will host our video and that’s the second one in the list (we know it’s that one as the Left value is highest putting it further away from the left hand edge of the layout). So we’ll make a note of the region ID (5303e4c0c0973)
  • Now let’s see what’s in that region already:
# We're interested in LayoutID 5
# RegionID 5303e4c0c0973
params = [('layoutid', '5'),
          ('regionid', '5303e4c0c0973')]

# Call the RegionList Method
response, status, code, message, content = api.callMethod('LayoutRegionTimelineList', params)

# Parse the response XML
doc = minidom.parseString(content)

# List the Regions
nodes = doc.getElementsByTagName('media')

for node in nodes:
    mediaId = str(node.attributes['mediaid'].value)
    mediaType = str(node.attributes['mediatype'].value)
    mediaDuration = str(node.attributes['mediaduration'].value)

    print "Media ID %s" % mediaId
    print "    Type: %s" % mediaType
    print "    Duration: %s\n" % mediaDuration

print "Media List Complete\n\n"
  • Now save ReplaceMedia.py and run it:
Media ID 11
    Type: video
    Duration: 0

Media List Complete
  • See the video that’s already in the region listed.
  • Hopefully that’s given a basic overview of how to navigate the API, how to pass in parameters etc. Now we’ll remove most of the code we’ve written and get on with the job in hand of scripting the file upload and replacing that video in the region. We need to remember it’s Layout ID 5, region 5303e4c0c0973 (or the correct values from your CMS). That’s how we’ll identify where we want our video to end up being added, and the old video to delete.
  • So now your ReplaceVideo.py should look like this:
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Script to upload a Video to the Xibo CMS and replace
# an old copy of it in a region

# Imports
import os
from xml.dom import minidom
import XiboAPI

api = XiboAPI.XiboAPI()

layoutId = 5
regionId = '5303e4c0c0973'
fileToUpload = 'myVideo.mp4'
mediaName = 'Daily Video'
  • Clearly set layoutId and regionId to the correct values we obtained earlier. Change fileToUpload to be the filename of the video you want to upload. It could be in the same directory as your script (in which case just the name is sufficient), or it could be a full path to the file. It’s up to you.
  • I’ve included some library functions to do the heavy lifting for you. Add the following to the file and save:
#################################
# START LIBRARY FUNCTIONS
#################################

def uploadFile(api,path,chunksize=256000,fileid='0',offset=0,size=0):
    # Uploads file at path (full path)
    # Returns a file upload ID which can be used to add the media
    # to the library
    #
    # eg uploadFile(api,'/home/user/1.jpg')
    #
    # Optional Parameters:
    #  chunksize - Int: How many bytes to upload at each pass
    #  fileid - String: The fileUploadID to use. Useful if you're resuming an interupted upload.
    #  offset - Long: How many bytes to skip over before beginning upload. Useful for resuming an interupted upload.
    #  size - Long: How many bytes to upload. 0 = the whole file. Useful to break an upload part way through for testing.
    #              Must be smaller than the size of the file in bytes.

    # First check the test file exists
    if not os.path.isfile(path):
        print "Error: File does not exist %s " % path
        exit(1)

    checksum = ''
    data = ''
    if size == 0:
        size = os.path.getsize(path)
    chunkOK = False

    # If the file is smaller than the chunksize, send one chunk
    # of the correct size.
    if chunksize > size:
        chunksize = size
 
    # Open the file for binary read
    fh = open(path,'rb')

    while offset < size:
        attempts = 0
        chunkOK = False
        while attempts < 3 and not chunkOK:
            attempts += 1

            # Read chunksize bytes of the file
            fh.seek(offset)
            data = fh.read(chunksize)

            # Data needs to be base64 encoded to be sent
            data, checksum = api.b64encode(data)

            params = [('fileId',fileid),
                      ('offset',offset),
                      ('checksum',checksum),
                      ('payload',data)
                     ]

            response, status, code, message, content = api.callMethod('LibraryMediaFileUpload', params)

            # If the chunk went up OK then move to the next chunk
            if status == 'OK':
                chunkOK = True
            else:
                print 'Uploading chunk failed. Error %s: %s' % (code,message)

        if not chunkOK:
            # We did three tries and the chunk still failed.
            print 'Uploading chunk failed after three attempts. File: %s Id: %s Offset: %s Attempt: %s' % (path,fileid,offset,attempts)
            exit(1)

        # Store the fileID so we can reuse it
        fileid = api.parseID(content,'file','id')

        # Get the offset the server has already (to support resuming uploads)
        offset = api.parseID(content,'file','offset')

        # Make sure we don't upload past the end of the file!
        if offset + chunksize > size:
            chunksize = size - offset

    # All chunks uploaded
    # Close the file handle
    fh.close()

    return fileid

def layoutRegionMediaDelete(api,layoutid,regionid,mediaid,lkid):
    params = [('mediaId',mediaid),
              ('regionId',regionid),
              ('layoutId',int(layoutid)),
              ('lkId',int(lkid))
             ]
    
    response, status, code, message, content = api.callMethod('LayoutRegionMediaDelete', params)

def libraryMediaDelete(api,mediaid):
    params = [('mediaId',mediaid)]

    response, status, code, message, content = api.callMethod('LibraryMediaDelete', params)

#############################################
# END LIBRARY FUNCTIONS
#############################################
  • So first up we upload the new file to the CMS. Note here that by upload we mean copy it to the server ready to be added to the library. We add it to the library in a second stage later on. Add the following to upload:
# Upload our file to the CMS so it's ready to add
# Note this won't make it appear in the library
# We do that further down the script
uploadId = uploadFile(api,fileToUpload)
  • Next we need to find the ID of the old video file, remove it from the Region Timeline, and then delete it from the library. Add the following:
# Find out what the mediaID of the old video is, and remove it from the layout
oldMediaId = None

params = [('layoutid', layoutId),
          ('regionid', regionId)]

# Call the RegionList Method
response, status, code, message, content = api.callMethod('LayoutRegionTimelineList', params)

# Parse the response XML
doc = minidom.parseString(content)

# List the Regions
nodes = doc.getElementsByTagName('media')

for node in nodes:
    if str(node.attributes['mediatype'].value) == 'video':
        oldMediaId = str(node.attributes['mediaid'].value)
        lkid = str(node.attributes['lkid'].value)

if not oldMediaId is None:
    # We found an old video in the region
    # Lets delete it
    print "Removing old media with ID %s" % oldMediaId
    layoutRegionMediaDelete(api, layoutId, regionId, oldMediaId, lkid)
    libraryMediaDelete(api, oldMediaId)
  • Now the old video is gone from the layout timeline, and from the CMS Library, we can add our new video to the library and add it to the region. Add the following:
# Now the file is uploaded, and the old file is deleted,
# we need to add the newly uploaded file to the CMS Library
params = [('fileId', uploadId),
          ('type', 'video'),
          ('name', mediaName),
          ('duration', '0'),
          ('permissionId','1'),
          ('fileName',os.path.basename(fileToUpload))
         ]

response, status, code, message, content = api.callMethod('LibraryMediaAdd', params)

# Get the ID of the file we just added
mediaId = api.parseID(content,'media')

# Now mediaID contains the library media ID of our freshly uploaded video
print "Adding new media with ID %s" % mediaId

# Now add our new media item to the region
params = [('layoutId',layoutId),
          ('regionId',regionId),
          ('mediaList',mediaId),
         ]

response, status, code, message, content = api.callMethod('LayoutRegionLibraryAdd', params)
  • Finally check that the video was added correctly by listing the media items in the region. Add the following:
# Finally Check the layout now contains the new video
# by listing the contents of the region and checking for our new video
params = [('layoutId', layoutId),
          ('regionId', regionId)]

# Call the RegionList Method
response, status, code, message, content = api.callMethod('LayoutRegionTimelineList', params)

# Parse the response XML
doc = minidom.parseString(content)

# List the Regions
nodes = doc.getElementsByTagName('media')

for node in nodes:
    if str(node.attributes['mediatype'].value) == 'video':
        if str(node.attributes['mediaid'].value) == str(mediaId):
            print "Video Uploaded and Layout Modified Successfully"
            exit(0)

print "Error Uploading Video"
  • Now save and run your file. You should see output as follows:
alex@alex-laptop:~/scratch/xibo-release/ReplaceVideo$ python ReplaceVideo.py 
Removing old media with ID 15
Adding new media with ID 16
Video Uploaded and Layout Modified Successfully

You can download the completed ReplaceVideo.py file here.

Moving to PDO – Notice to server admins

We have recently taken the difficult decision of migrating the Xibo code base away from the PHP MySQL extension and over to PHP PDO. Despite this being a significant development effort the end user will not notice any changes.

This change will be rolled out over the next few releases with core functions/inserts/updates/deletes covered from 1.5 series, and all queries covered from 1.7 series.

The advantages to PDO are many – the key ones for us are:

  • Potential to support different RDBMS (e.g. SQL Server, Oracle, MySQL, etc).
  • Prepared SQL statements that protect against SQL injection.
  • Support for Transactions.

As a server admin, all that needs to happen on upgrade will be to check that the PHP PDO extension is enabled on your web server installation. PDO ships with PHP 5.1 which is already an Xibo requirement.

For more information on PDO please refer to the PHP manual.

Introducing a new region Timeline editing window

The next article in the run up to 1.4 looks at improvements to the region timeline editor and layout preview. Our intentions with these improvements are:

The vertical timeline is a sortable list

  • To make the region time line more consistent, easy to understand and allow it to support more media modules
  • Simplify re-ordering the items in the timeline
  • Make it easier to add new items from the library
  • To make the region preview reflect the client more closely

Region Timeline

The region timeline has been re-designed to use a vertical list of “media nodes” which are all the same fixed height. The module add buttons are repositioned to the left hand side, and a simple text preview is positioned on the right hand side, on hover.

In addition all of the media nodes in the timeline can be dragged and sorted like a list, they will not be saved in their new order until the “re-order” button is clicked, allowing the user to make more than one change at a time. Also the media nodes automatically flow around the one that is being re-ordered. Making the entire process more elegant.

Available media and media to assign are shown in two lists

The same is true when the user comes to assigning media from the library. The interface has been improved to used a 2-list style interface of available/assigned media. Items can be dragged and dropped from the available list to the assignment list and re-ordered before assignment.

Region Preview

Where possible the region preview has been updated to better reflect the options selected for each media item. This will allow greater accuracy between what is designed using the editor and what is seen on the actual display client.

 

These updates are a small set in the right direction for our layout designer – our hope is that they are well received, but as always we welcome any comments and discussion over on Launchpad Answers.

Introducing a threaded, more robust Windows Client with improved library management

The next article in the run up to 1.4 looks at improvements to the Windows client’s connection to the Xibo server and its library management.

These improvements can be categorised into the following areas:

  • Reduced “lag” and “display jitter” when the client is connecting to the Server
  • Concurrent file downloads
  • Clearing up old and unused files in the library
  • Information window showing client status, library status and log information
  • Replacing the splash screen

Reduced display jitter

The Windows client has always been “single threaded” which means that it processed instructions one after the other in sequence. This meant that when the client was doing something intensive that wasn’t displaying content (such as verifying the files that needed download) there was a chance of display “lag” or jitter while this other action was occurring. Prime examples of this were displaying scrolling text, or loading new media when it reached the end of its play time.

The has been greatly reduced in the new client by “threading”, meaning the client is separated into different part which all act independently of each other. There are now seperate threads for the following:

  • Checking the schedule on the server
  • Checking the files required on the server
  • Downloading files from the server
  • Calculating the valid schedule

Concurrent File Downloads

Another effect of the “single threaded” design of the old client was that it could only download one file at a time, in sequence. The new client has been improved to allow a user configurable number of concurrent downloads.

This allows files to be pulled into clients faster and more efficiently.

In addition to this the client will now resume interrupted downloads, especially useful for clients with intermittent or slow connections.

Client Info Screenshot
The Client Info window showing status of all communications, schedule, library info and recent logs.

Clearing up old and unused files

Anyone that has been running a client for a long time will have noticed that the local client library doesn’t automatically tidy itself up and will get larger and larger as time goes on.

The new client manages this library much more efficiently, clearing up files that are no longer needed (including temporary files).

This can be managed using the “required files look ahead” setting in the server – increasing this value causes the client to consider media to be required for longer.

Client status window

It has always been a challenge to see what is going in within the client, especially if it is not showing what you expect. The new client comes with an info screen which shows you the status of all communications with the server, the current schedule and the contents of the library (with progress indicators for current downloads).

Replacing the splash screen

Due to popular demand we have also included an option in the client to replace the Xibo splash screen with a file on the local PC. We have “resisted” this in the past because maintaining this website and the Xibo wiki does cost us some money – and de-branding the client has previously been a good method for funding this site.

However in the interests of being as “open” as we possibly can, we have chosen to make it easier to “de-brand” the client with this splash screen replacement feature. Apologies it has taken us so long to do this.

If you do decide to replace the splash screen with one of your own, then it would be fantastic for the project if you made a small donation.

If the image you select is invalid or cannot be found, Xibo will default back to the current splash screen.

Summary

Our long term intention is still to replace the Windows client with a fully cross platform client – however this is taking us longer than expected due to a number of technical reasons. We hope that these improvements to the current Windows client will be a good “stop-gap” for a more professional, reliable solution while development on the cross platform client continues.

Introducing new features for Service Providers

Usage statistics in the Settings Window
Usage statistics can be found in the Settings Window under the Content tab

The next article in the run up to 1.4 looks at some small new features for people that use Xibo as service providers. It is difficult to tell how many use Xibo in this manner, as not many come forward – but those that do have mentioned that it would be nice to have a way to manage limits on the library file size and monthly bandwidth usage.

We have completed this work by virtue of two new settings in the settings table (LIBRARY_SIZE_LIMIT_KB & MONTHLY_XMDS_TRANSFER_LIMIT_KB) – these are not available through the user interface.

If no limits are entered, everything continues to work as before… however once a limit is entered Xibo will start validating against these limits, and when they are exceeded will prevent the upload of new media / updates to clients.

A visual queue is provided on the settings page. In the future we will extend this to also include a bandwidth chart, and some metrics on the dashboard.

Hope this is useful to service providers… both those we know about and those we don’t! As usual, comments and thoughts are appreciated over on Launchpad Answers.

Introducing Wake On Lan for Display Clients

The next article in the run up to releasing 1.4 will look at the new Wake On Lan (WOL) feature of Xibo.

Edit Display Form
WOL Settings on the Edit Display Form

There has been a lot of interest over the years Xibo has been running for a solution to be “green”, “save power” and generally not have the Xibo display screen solution on unnecessarily. The Xibo project has been very keen to put these things in place, and 1.4 will contain a number of measures to make these wishes a reality.

The WOL function is intended to be used for display clients that are addressable by the server, by this we mean that there has to be a clear addressable network route between the server and the client that needs to wake up. It is also required that WOL is turned on in any necessary settings on the client PC.

The WOL configuration happens on a display by display basis from the Edit Display form. Each display has new settings for:

  • Enable Wake On LAN – (Turn WOL on/off for the display)
  • Wake On LAN Time – (Specify a time for this display to wake, using the 24 hr clock)
  • BroadCast Address – (The BroadCast address of the client, if unknown use the IP address and fill in the CIDR field)
  • Wake On LAN Secure On – (The SecureOn password for the client, if supported)
  • Wake On LAN CIDR – (The CIDR subnet mask, if the BroadCast Address is unknown)

Once the display has these settings it can be woken up in 2 ways:

Wake On LAN Now

WOL Now Button
Wake On LAN button can be used to wake up the client immediately

Each display has the “Wake On LAN” button which can be used to send a wake on LAN command on demand. Clicking the button displays a form for confirmation, once this is pressed the command is send immediately to the client.

Wake On LAN Time – Maintenance Script

In addition to the WOL now function, the Xibo maintenance module has been altered to send a WOL packet to any display which has a “Wake On LAN Time” specified. It will only send the command once, as the time window is passed.

The maintenance script has to be running for this to work correctly. Maintenance instructions can be found on the wiki.

Putting the client to sleep

There are a few different options for putting the client to sleep – such as a scheduled task. However, the next article in this series will look at an option built into Xibo. The “Shell Command” module.

We hope you will find this new functionality useful! As always comments are always welcome over on Launchpad Answers.

Introducing the Layout Designer Jump List

Layout Jump Button
The Jump Button icon and form showing list of available layouts.

Its been a while since our last article looking at features of the upcoming 1.4 release. We have a small but useful enhancement to look at this time – Layout Designer Jump List.

This little feature allows navigation between layouts a user has permissions to design, without having to jump out to the list of layouts each and every time. Its accessible from a new icon on the layout designer, called “Jump to…”

Once clicked, it presents a list of accessible layouts with a “Design” button – selecting the button will load corresponding layout into the designer window.