fledge-iot / fledge

An open source platform for the Industrial Internet of Things, it acts as an edge gateway between sensor devices and cloud storage systems.
https://www.lfedge.org/projects/fledge/
Apache License 2.0
124 stars 44 forks source link

Custom python plugin error #1349

Closed stephenrichardson closed 5 months ago

stephenrichardson commented 5 months ago

I created a basic python plugin "myplugin.py" and saved it in "/usr/local/fledge/python/fledge/plugins/south/myplugin/". When I try to add it as a new south service I get the following log messages:

May 2 23:45:19 firefly Fledge[24754] ERROR: logger: fledge.common.plugin_discovery: KeyError: 'plugin' May 2 23:45:19 firefly Fledge[24754] ERROR: logger: fledge.common.plugin_discovery: File "/usr/local/fledge/python/fledge/common/plugin_discovery.py", line 186, in get_plugin_config#012 name = plugin_info['config']['plugin']['default'] May 2 23:45:19 firefly Fledge[24754] ERROR: logger: fledge.common.plugin_discovery: Traceback (most recent call last): May 2 23:45:19 firefly Fledge[24754] ERROR: logger: fledge.common.plugin_discovery: Failed to fetch config for /usr/local/fledge/python/fledge/plugins/south/myplugin plugin.

The http_south plugin loads fine. Am I missing something or is this a bug? This is on Ubuntu 18.04.

Plugin code:

# -*- coding: utf-8 -*-

# FLEDGE_BEGIN
# See: http://fledge-iot.readthedocs.io/
# FLEDGE_END

import requests
from datetime import datetime, timezone
import uuid

from fledge.common import logger
from fledge.services.south import exceptions

__author__ = "abcd"
__copyright__ = "Copyright (c) 2024 efgh"
__license__ = "Apache 2.0"
__version__ = "${VERSION}"

_CONFIG_CATEGORY_NAME = 'MYPLUGIN'
_CONFIG_CATEGORY_DESCRIPTION = 'South Plugin My Plugin'
_DEFAULT_CONFIG = {
    'plugin': {
        'description': 'My Plugin South Plugin',
        'type': 'string',
        'default': 'myplugin',
        'readonly': 'true'
    },
    'getCmd': {
        'description': 'The REST API Get Command to get the latest data from a sensor',
        'type': 'string',
        'default': '',
        'order': '1',
        'displayName': 'REST API Get Command'
    },
    'pollInterval': {
        'description': 'The interval between executing the REST API call expressed in milliseconds.',
        'type': 'integer',
        'default': '60000',
        'order': '2',
        'displayName': 'Poll Interval'
    }
}

_LOGGER = logger.setup(__name__)

def plugin_info():
    return {
        'name': 'myplugin',
        'version': '1.0',
        'mode': 'poll',
        'type': 'south',
        'interface': '1.0',
        'config': _DEFAULT_CONFIG
    }

def plugin_init(config):
    handle = copy.deepcopy(config)
    return handle

def plugin_poll(handle):
    try:
        response = requests.get(handle)
        if response.status_code == 200:
            time_stamp = str(datetime.now(tz=timezone.utc))
            wrapper = {
                    'asset':     'myasset',
                    'timestamp': time_stamp,
                    'key':       str(uuid.uuid4()),
                    'readings':  response.text
            }
            return wrapper
        else:
            _LOGGER.info("plugin_poll(): get={}, status_code={}".format(handle, response.status_code))
            return None

    except Exception as ex:
        raise exceptions.DataRetrievalError(ex)

    return None

def plugin_reconfigure(handle, new_config):
    new_handle = copy.deepcopy(new_config)
    return new_handle

def plugin_shutdown(handle):
    pass
ashish-jabble commented 5 months ago

Hi @stephenrichardson Thankyou for the interest in Fledge. Your python file looks good, assuming that you have saved the plugin under directory /usr/local/fledge/python/fledge/plugins/south/myplugin/" and having python filename myplugin.py. (Case sensitive myplugin)

myplugin/
└── myplugin.py

If you are still getting an errors with above structure, Would you mind to share /usr/local/fledge/python/fledge/plugins/south directory contents, also which Fledge version are you using?

stephenrichardson commented 5 months ago

Hey @ashish-jabble I am using Fledge 2.4.0. My custom plugin was identical to my above example except it was named "sensor_works" (in the directory, the filename, the plugin_info() and the config -> default property). When I changed the name to "myplugin" or "s_worx" or "abc_works" or "sensorworks" or "sensor_workss" it was fine. Is there something in the name "sensor_works" that is an issue?

ashish-jabble commented 5 months ago

(in the directory, the filename, the plugin_info() and the config -> default property)

To discover a python based plugin the contract be like having same name in following areas a) directory b) python filename c) config->plugin->default property d) in plugin_info def - It can have with different name, so optional for the case

Is there something in the name "sensor_works" that is an issue?

Not really!

I have just tried your example with sensor_works name and it is working fine. I would recommend to restart the fledge and check again.

stephenrichardson commented 5 months ago

It works fine after restarting fledge. Good to know! Thanks.

As you can see I'm knew to fledge and just started working with it this week. Is this the best place to ask questions or are there some forums or other somewhere else?

ashish-jabble commented 5 months ago

or are there some forums or other somewhere else?

You can ask queries over slack https://lfedge.slack.com and join channels like fledge-help and fledge.