========== Components ========== The Visionect Software Suite comprises of the :ref:`Graphics Engine and rendering backends `, :ref:`Network Manager ` and :ref:`Gateway `, each implemented as a separate process and connected together via an IPC service. Components can be run across different physical servers in multiple instances. The Data is stored in the storage backend. .. TODO: SCHEMATIC add a picture or schematic about relations of Okular, NM and Koala (VS) for better understanding. .. _what-is-nm: Network Manager --------------- The Network Manager is a service for the administration of other components and distributing the workload. It offers facilities to monitor performance and, if needed, upgrade client devices over the air. It is also the centralized point from where you are able to control the operation of the :ref:`HTML rendering backend ` servers and access the web administration interface (and the Software Suite management API). It is the only component that needs to be run as a single instance inside your Visionect Software Suite cluster, managing all instances of the :ref:`HTML rendering backend ` and :ref:`Gateway `. .. _graphics-engine: Graphics Engine and rendering backends -------------------------------------- The Graphics Engine is the key component that stores the frame buffer and the state of each connected device. The Engine includes all the features required for an RGB image to be displayed on a connected e-paper display as well as handle all the device feedback (interactions, input). The Graphics Engine takes the RGB image input and uses various methods of dithering to convert color into the required bit-depth, optimize it for e-paper displays, and compress it to save bandwidth. The actual content is fed into the Engine from various rendering backends. When a client connects to the Engine for the first time, it spawns a new session or attaches to an existing session if two or more devices share a common session. The session will then access the configured backend, as configured in the :ref:`Network Manager `. The session will persist as long as the Engine is running, regardless if the device has intermittent connectivity. The Graphics Engine supports multiple rendering backends which can be chosen according to your specific application requirements. Currently, we support an HTML rendering backend (formerly Okular), intended for interactive and dynamic applications built with HTML, and an HTTP rendering backend which exposes direct access to the device framebuffer over HTTP (direct image uploads). .. _what-is-engine: HTML rendering backend ~~~~~~~~~~~~~~~~~~~~~~ HTML rendering backend is the default backend, meant to be used for dynamic applications. It renders HTML(5), CSS, and Javascript into graphical data using the WebKit rendering engine (as used in Google Chrome and Apple Safari web browsers). The backend connects to the configured URL and loads the Web application into its WebKit session. It supports full interactivity and exposes access to the device (hardware) features through Javascript extensions. More information regarding the development can be found in :doc:`/AppDevelopment/index`. The WebKit session will restart in case of problematic web applications, which cause extensive memory leaks in the WebKit session. This is done to ensure the stability of the system. After the session is restarted, it opens the default URL as configured. Developers are advised to take the possibility of the session restart into account, and not count on the browser session to exist forever. For protection against memory leaks, it is possible to set the WebKit session memory limit after which the Visionect Software Suite will restart the problematic session. Users can do it by changing the Web session memory limit setting [MB] in the Visionect Software Suite (Settings -> Rendering backend). The default setting is 120 MB. If you wish to force a restart of WebKit sessions due to issues with your application, you can do that by killing it with the ``Restart session`` button in the Visionect Software Suite (Devices sub-menu). .. figure:: images/NM-web-session-memory-limit1.png :align: center *Web session memory limit setting* .. TODO: Move HTTP backend example to seprate document - examples/developing HTTP push backend ~~~~~~~~~~~~~~~~~ The HTTP backend takes whatever graphical data you provide to the backend and pushes it directly into the frame buffer. You can use the provided RESTful API to upload images (PNG, JPG) with a simple PUT or POST command to a target URL. .. note:: The image needs to be in the PNG, JPG, or GIF format and it will not be resized in any way to conform to the target screen size. The palette should be RGB, with the alpha channel (or transparency) disabled. The HTTP backend is not especially suited for dynamic or interactive content (you can only push image data), but it does require a lot less resources compared to the HTML rendering backend as it does not process on its own. HTTP backend-based sessions will use up to ten times less RAM (20-40MB for 800x600 display). **Examples of how to send an image to a Visionect e-paper device:** - **Python** .. code-block:: python from requests import Request, Session import base64, hmac, hashlib, time, wsgiref.handlers host = 'localhost' uuid = '3a003c00-0d47-3130-3830-333200000000' apiKey = '8cdec34cb9249164' apiSecret = 'EU/X/CHo7895FGAXvsNieU1en4UtYIaP2o9R0b6hsuQ' headers = { 'Date': wsgiref.handlers.format_date_time(time.time()), } req = Request('PUT', 'http://%s:8081/backend/%s' % (host, uuid), files=[('image', ('local_image.png', open('local_image.png', 'rb'), 'image/png'))], headers=headers ) prepped = req.prepare() h = hmac.new(apiSecret, 'PUT\n\n%s\n%s\n/backend/%s' % (prepped.headers['Content-Type'], prepped.headers['Date'], uuid), hashlib.sha256) prepped.headers['Authorization'] = '%s:%s' % (apiKey, base64.encodestring(h.digest()).strip()) s = Session() resp = s.send(prepped) if resp.status_code != 200: print 'Error: ' + resp.text | | - **Node.js** .. code-block:: javascript var crypto = require('crypto'), FormData = require('form-data'), fs = require('fs'), http = require('http'), util = require('util'); var uuid = "3f003c12-0d47-3130-3830-3f3100000000", host = "localhost", apiKey = "036a8483ad55932131ba3", apiSecret = "EDQvVRsg5thvuHlfYVdfdsafvzKfK1Pak8FEP2KiodWezQY8"; var form = new FormData(); form.append('image', fs.createReadStream('image.png')); var headers = form.getHeaders(), date = Date(), path = util.format('/backend/%s', uuid); auth = crypto.createHmac('sha256', apiSecret) .update(util.format('%s\n%s\n%s\n%s\n%s', 'PUT', '', headers['content-type'], date, path)) .digest('base64') headers.Date = date; headers.Authorization = util.format('%s:%s', apiKey, auth) var request = http.request({ method: 'put', host: host, port: 8081, path: path, headers: headers }); form.pipe(request); request.on('response', function(res) { if (res.statusCode != 200) { console.log('Error: ' + res.statusCode) } res.on('data', function (chunk) { console.log(chunk); }); }); | | - **PHP** .. code-block:: php array( 'header' => "Content-type: ".$contentType."\r\n" . "Date: ".$date."\r\n" . "Authorization: ".$key.":".$hash_b64."\r\n", 'method' => $method, ) ); $context = stream_context_create($options); $result = file_get_contents($url, false, $context); if ($result === FALSE) { print("http fail\n"); } For more information on implementation, please consult the `server API documentation `_. .. TODO: Additional topics: Multiple Okular servers ~~~~~~~~~~~~~~~~~~~~~~~ Visionect Software Suite platform allows users to run multiple Okular services, connected to the same network. NetworkManager, which distributes the request for a new session when a device connects, will therefore select the Okular service with least hosted sessions. .. _what-is-gateway: Gateway ------- The Gateway is a virtual bridge between client devices and the Visionect Software Suite. It is possible to deploy multiple instances, providing connectivity to devices from multiple networks. .. _database-backends: Database (storage) backends --------------------------- The Storage component provides the Software Suite with data storage functionality and abstracts the underlying database. This is where the Visionect Software Suite stores all the settings and device events. Currently, the Visionect Software Suite supports PostgreSQL as the database backend. The database settings are configured in the ``config.json`` file. The valid settings are: :: "Storage": { "Backend": "postgresql", "Database": "name_of_your_database", "Host": "hostname", // if not configured defaults to localhost "Port": your_db_port, // if not configured defaults to default database port "Username": "your_username", "Password": "your_pass" }, .. note:: In the past, both the PostgreSQL and CouchDB databases were supported. Due to the much better performance of PostgreSQL support for CouchDB was discontinued. If you are using an old version of the Visionect Software Suite (with CouchDB) and you want to upgrade it, you are required to migrate your database first. Restarting The Services ----------------------- The components of the Visionect Software Suite (``engine``, ``networkmanager``, ``gateway``, ``storage``, ``admin``) are run as a system daemon via the ``supervisord`` facility. You can restart the components through the Software Suite command prompt with ``sudo supervisorctl restart all``. You can list the services (and view their status) by typing ``sudo supervisorctl status``. All Visionect Software Suite configuration files reside in ``/etc/supervisord/conf.d/``.