- iDigi Dia Home
- User
  - Getting Started
  - Dia Concepts
  - Devices
  - Loggers
  - Presentations
  - Services
  - Tracing
- Developer
  - Overview
  - Drivers
  - Loggers
  - Presentations
  - Services
  - Integrating Application
  - Tracing Manager
  - Debugging
  - Specific Considerations
  - API Reference

- Email
- Phone
- Contact us:

### Navigation

- index
- next |
- previous |
- iDigi Dia |
- Developer Documentation »

# Presentations

## I. Introduction to Dia Presentations

A presentation is an iDigi Dia module which is responsible for gathering sample data from channels and re-presenting the data in another format. The newly formatted data is usually sent over a network or written to a storage device.

Presentations gather sample data from the `Channel Database`. They do so either by polling–for example, checking on a time interval if a channel of interest has changed, or by interrupt–receiving an indication by means of a call back function by subscribing to one or more channels.

All presentations in the Dia must meet the following requirements:

> - They must inherit from `PresentationBase`.

> - They must have zero or more settings.

> - They must implement the following `PresentationBase` interface methods:

>   > - apply_settings(): called when new settings are applied.
>   > - start(): called when the presentation is started.
>   > - stop(): called when the presentation is stopped.

There are many types of presentations which can be implemented with the Dia. Here are a few examples, some of which have already been implemented and included with the Dia distribution:

> - A command line interface for browsing channels, system settings, and historical logs.
> - A single web page listing the current status of channels in the system.
> - A module which creates a new XML document on a time interval and uploads this document to a remote server using HTTP.
> - A module which uploads channel data automatically to the iDigi platform.
> - A module which presents data as a set of Modbus registers.
> - A module which watches a single channel and when this channel is True, it will send an e-mail containing the state of the system to a configured destination.

In order to illustrate how one may go about creating their own Dia Presentation we will walk through an example of what is needed to create the last presentation in the above list: the SMTP e-mail presentation.

## II. Implementing a Presentation

### A. Where are the Existing Presentation Modules Located?

Existing presentation modules for the Dia are located in the “src/presentations” directory of the distribution. Each individual presentation is located in its own directory. For example, the console presentation is stored in the “src/presentations/console” directory.

### B. The SMTP E-Mail Presentation Illustrated

The SMTP presentation is located in the file “src/presentations/smtp/smtp.py”. It is implemented to monitor a single channel for a sample value of “True” and when that value is found to send an e-mail to a configured destination containing the current state of all the channels on the system. If we open the source file in a text editor we may begin to examine the implementation of the presentation.

Below the copyright statement and triple-quoted documentation string we will find the import statement. All presentations must, at a minimum, import the following items:

    from settings.settings_base import SettingsBase, Setting
    from presentations.presentation_base import PresentationBase

All presentation modules are implemented by defining a class which is derived from `PresentationBase`. A `PresentationBase` class will contain Settings objects (accessed via methods defined in `SettingsBase`).

This presentation will need to validate e-mail addresses. It does this by means of a regular expression. The SMTP presentation module will therefore import the re module.

The presentation module will also need to asynchronously manage its outbox. That is to say, if the upstream SMTP server is busy the system needs to continue running without pausing until the server responds. This is done by running the potentially slow SMTP functions in their own thread. Messages are sent from the system thread context to the SMTP thread context by way of a Queue object.

The total import list is thus given as:

    import threading
    import re
    import digi_smtplib as smtplib
    import socket

    from Queue import Queue
    from settings.settings_base import SettingsBase, Setting
    from presentations.presentation_base import PresentationBase
    from channels.channel_publisher import ChannelDoesNotExist
    from common.helpers.format_channels import dump_channel_db_as_text

For more information on standard Python library functions, please see:

> http://docs.python.org/library/

Below the imports section of the SMTP presentation module our presentation class, SMTPHandler, is created. It derives from `Thread` as all presentation modules do:

    class SMTPHandler(PresentationBase):

When an instance of this presentation class is created from the `Presentation Manager`, execution will begin at the __init__() method. In the __init__() method, the following tasks are completed:

> 1. A handle to the core_services object is stored in a local class-private variable. This handle will be used later to look up other system objects (e.g. the `Channel Database` and `Channel Publisher` objects).
> 2. A Queue object is created.
> 3. The settings “to_address”, “from_address”, “subject”, “server_address”, “port”, and “monitored_channel” are created.
> 4. The `PresentationBase` constructor is called and it is handed references to the current object, the name of the current instance, and a list of defined settings.

When __init__() returns, the `Presentation Manager` will attempt to apply driver settings. This occurs in the apply_settings() method.

Settings are applied in exactly the same manner as they are in Dia device driver abstraction. Please see the section, “Introduction to Dia Device Drivers”.

Aside from the standard set of operations to apply settings in the Dia system (`SettingsBase`.merge_settings(), `SettingsBase`.verify_settings(), `SettingsBase`.commit_settings()) below the settings validations there is a section which retrieves the “monitored_channel” name setting, fetches the `Channel Publisher` by way of the Channel Manager via the Core Services object, and asks the `Channel Publisher` to call the SMTPHandler’s queue_msg() function with the subscribed channel each and every time it changes:

    ## subscribe to monitored_channel
    cm = self.__core.get_service("channel_manager")
    cp = cm.channel_publisher_get()
    cp.subscribe(accepted['monitored_channel'], self.queue_msg)

After settings are applied, the presentation’s start() method will be called. The SMTP presentation’s start() method is very simple: it calls the threading.Thread.start(self) method which will start a class member function named run() in its own thread context.

When the presentation begins its execution loop in the run() method, it will immediately block execution on the queue object which had been created in the __init__() method. We will return to what happens when an item is available in the queue in a moment. Let us turn our attention to how items are queued in the first place.

Items are queued when the channel sample indicated by the “monitored_channel” setting changes. When the channel sample changes, it will call the queue_msg() method of the SMTPHandler instance. The instance will first check to see if the channel now contains a True value and then it will begin to construct an e-mail message containing the state of all channels by accessing the `Channel Database`. The last action this function will perform will be to place the e-mail message into the queue.

Queuing the message will cause the SMTPHandler’s thread to wake up in the run() method. The message will then be paired with the rest of the e-mail server, to, and from settings from the Dia settings and finally it will attempt to be queued using the Python SMTP library’s sendmail() function.

The final method to consider is the stop() method. The stop method is very simple. It checks to ensure that the driver is running, and if so, it will set the running flag to False and signal the Presentation’s thread via the queue to terminate by sending a dummy message. Queuing anything with the start_flag set to False in this driver will cause the mail outbox thread to terminate. Finally, the stop() method returns True to the `Presentation Manager`.

### C. Defining a Presention in the Configuration File

### D. A Summary of How Presentations Execute

> 1. A presentation is loaded and its __init__() method is called.
> 2. Settings are applied by calling the driver’s apply_settings() method.
>    1. First a call to `SettingsBase`.merge_settings() should be made to merge new settings from the pending registry and the running settings to the pending registry.
>    2. Second, a call to `SettingsBase`.verify_settings() will return three items: a dictionary of accepted setting, a dictionary of rejected settings, and a dictionary of required settings that where not found.
>    3. `SettingsBase`.commit_settings() should be called with a list of the settings that were successfully accepted and applied. This will adjust the device’s running settings registry.
>    4. Finally, the apply_settings method should return the list of settings accepted, rejected, and not_found.
> 3. The presentation’s start() method is called. The presentation is now available.
> 4. The presentation’s stop() method may be called. The presentation is expected to stop and the method should return True. Once the method has returned the Presentation Manager may restart the driver by calling the start() method once again.

### Navigation

- index
- next |
- previous |
- iDigi Dia |
- Developer Documentation »