Add Logic Service

This section adds the basic files require for the plugin to run on the peek logic service. Create the following files and directories.

Note

Setting up skeleton files for the field, office, worker and agent services, is identical to the logic service, generally replace “logic” with the appropriate service name.

The platform loads the plugins python package, and then calls the appropriate peek{logic}EntryHook() method on it, if it exists.

The object returned must implement the right interfaces, the platform then calls methods on this object to load, start, stop, unload, etc the plugin.

Logic Service File Structure

Add Package _private/logic

This step creates the _private/logic python package.

This package will contain the majority of the plugins code that will run on the logic service. Files in this package can be imported with

# Example
# To import peek_plugin_tutorial/_private/logic/File.py
from peek_plugin_tutorial._private.logic import File

Create directory peek_plugin_tutorial/_private/logic

Create an empty package file in the logic directory, peek_plugin_tutorial/_private/logic/__init__.py

Commands:

mkdir peek_plugin_tutorial/_private/logic
touch peek_plugin_tutorial/_private/logic/__init__.py

Add File LogicEntryHook.py

This file/class is the entry point for the plugin on the peek logic service. When the peek logic service starts this plugin, it will call the load() then the start() methods.

Any initialisation and loading that the plugin needs to do to run should be placed in load() and start() methods.

Important

Ensure what ever is constructed and initialised in the load() and start() methods, should be deconstructed in the stop() and unload() methods.


Create the file peek_plugin_tutorial/_private/logic/LogicEntryHook.py and populate it with the following contents.

import logging

from peek_plugin_base.logic.PluginLogicEntryHookABC import PluginLogicEntryHookABC

logger = logging.getLogger(__name__)


class LogicEntryHook(PluginLogicEntryHookABC):
    def __init__(self, *args, **kwargs):
        """" Constructor """
        # Call the base classes constructor
        PluginLogicEntryHookABC.__init__(self, *args, **kwargs)

        #: Loaded Objects, This is a list of all objects created when we start
        self._loadedObjects = []

    def load(self) -> None:
        """ Load

        This will be called when the plugin is loaded, just after the db is migrated.
        Place any custom initialiastion steps here.

        """
        logger.debug("Loaded")

    def start(self):
        """ Start

        This will be called to start the plugin.
        Start, means what ever we choose to do here. This includes:

        -   Create Controllers

        -   Create payload, observable and tuple action handlers.

        """
        logger.debug("Started")

    def stop(self):
        """ Stop

        This method is called by the platform to tell the peek app to shutdown and stop
        everything it's doing
        """
        # Shutdown and dereference all objects we constructed when we started
        while self._loadedObjects:
            self._loadedObjects.pop().shutdown()

        logger.debug("Stopped")

    def unload(self):
        """Unload

        This method is called after stop is called, to unload any last resources
        before the PLUGIN is unlinked from the platform

        """
        logger.debug("Unloaded")

Edit peek_plugin_tutorial/__init__.py

When the peek logic service loads the plugin, it first calls the peekLogicEntryHook() method from the peek_plugin_tutorial package.

The peekLogicEntryHook() method returns the Class that the peek logic service should create to initialise and start the plugin.

As far as the Peek Platform is concerned, the plugin can be structured how ever it likes internally, as long as it defines these methods in its root python package.


Edit the file peek_plugin_tutorial/__init__.py, and add the following:

from peek_plugin_base.logic.PluginLogicEntryHookABC import PluginLogicEntryHookABC
from typing import Type


def peekLogicEntryHook() -> Type[PluginLogicEntryHookABC]:
    from ._private.logic.LogicEntryHook import LogicEntryHook
    return LogicEntryHook

Edit plugin_package.json

These updates to the plugin_package.json tell the Peek Platform that we require the “logic” service to run, and additional configuration options we have for that service.


Edit the file peek_plugin_tutorial/plugin_package.json :

  1. Add “logic” to the requiresServices section so it looks like

    "requiresServices": [
        "logic"
    ]
    
  2. Add the logic section after requiresServices section:

    "logic": {
    }
    
  3. Ensure your JSON is still valid (Your IDE may help here)

Here is an example

{
    "plugin": {
        ...
    },
    "requiresServices": [
        "logic"
    ],
    "logic": {
    },
    ...

}

The plugin should now be ready for the logic service to load.

Running on the Logic Service

File ~/peek-logic-service.home/config.json is the configuration file for the peek logic service.

Note

This file is created in Administration. Running the Logic Service will also create the file.


Edit ~/peek-logic-service.home/config.json:

  1. Ensure logging.level is set to “DEBUG”
  2. Add “peek_plugin_tutorial” to the plugin.enabled array

Note

It would be helpful if this is the only plugin enabled at this point.

It should something like this:

{
    ...
    "logging": {
        "level": "DEBUG"
    },
    ...
    "plugin": {
        "enabled": [
            "peek_plugin_tutorial"
        ],
        ...
    },
    ...
}

You can now run the peek logic service, you should see your plugin load.

peek@_peek:~$ run_peek_logic_service
...
DEBUG peek_plugin_tutorial._private.logic.LogicEntryHook:Loaded
DEBUG peek_plugin_tutorial._private.logic.LogicEntryHook:Started
...