Source code for papi.plugin.base_classes.base_ownProcess
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
Copyright (C) 2014 Technische Universität Berlin,
Fakultät IV - Elektrotechnik und Informatik,
Fachgebiet Regelungssysteme,
Einsteinufer 17, D-10587 Berlin, Germany
This file is part of PaPI.
PaPI is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
PaPI is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with PaPI. If not, see <http://www.gnu.org/licenses/>.
Contributors:
<Stefan Ruppin
"""
from papi.plugin.base_classes.base_plugin import base_plugin
import papi.event as Event
[docs]class base_ownProcess(base_plugin):
"""
This plugin base should be used by a plugin if should run in an own process.
It is not possible to create a widget which is displayed in the graphical interface of PaPI.
"""
def _work_process(self, CoreQueue, pluginQueue, id, defaultEventTriggered=False, config=None, autostart=True):
"""
This is the main working function of plugins running in their own process.
:param CoreQueue: multiprocessing queue of core for plugin to send data
:param pluginQueue: multiprocessing queue for plugin to receive data
:param id: Plugin id
:param defaultEventTriggered: event mode
:param config: Pluign intial cfg
:param autostart: Should plugin start immediately after call?
:return:
"""
# set queues and id and remember them
self._Core_event_queue__ = CoreQueue
self.__plugin_queue__ = pluginQueue
self.__id__ = id
self.__EventTriggered = defaultEventTriggered
self.__user_event_triggered = 'default'
self.__paused = False
# initialize the base class and all objects
self._papi_init()
# working should go at least one time/cycle
self.__goOn = 1
# plugin will start so it is not stopped yet
self.__plugin_stopped = False
# will check if plugin shall be started immediately after creation
if autostart is True:
# call _start_plugin_base function to use developers init
self._starting_sequence(config)
else:
self.__plugin_stopped = True
# main working loop
while self.__goOn:
# check event trigger mode
self._evaluate_event_trigger(defaultEventTriggered)
# Check for new event in plugin queue
event = None
try:
# do blocked checking of queue if:
# plugin is paused or
# plugin is stopped or
# plugin mode is event triggered
event = self.__plugin_queue__.get( self.__paused or self.__EventTriggered or self.__plugin_stopped)
except:
# no new event
event = None
# there is a new event
if event is not None:
op = event.get_event_operation()
# plugin shall stop operation
if op=='stop_plugin' :
self.cb_quit()
if event.delete is True:
# delete plugin, so work_progress will stop completely
self.__goOn = 0
event = Event.status.JoinRequest(self.__id__, 0, None)
self._Core_event_queue__.put(event)
else:
# plugin should stop but is not getting deleted
# response to core and rm_all_subs, blocks, paras
self.__plugin_stopped = True
event = Event.status.PluginStopped(self.__id__, 0, None)
self._Core_event_queue__.put(event)
# plugin should start again after it was stopped once
if op=='start_plugin' and self.__plugin_stopped is True:
# maybe new config?
self._starting_sequence(config)
self.__plugin_stopped = False
# pause this plugin
if op=='pause_plugin' and self.__paused is False and self.__plugin_stopped is False:
self.__paused = True
self.cb_pause()
# resume this plugin if it was paused
if op=='resume_plugin' and self.__paused is True and self.__plugin_stopped is False:
self.__paused = False
self.cb_resume()
# answer the check alive call from the core
if op=='check_alive_status':
alive_event = Event.status.Alive(self.__id__, 0, None)
self._Core_event_queue__.put(alive_event)
# there is new data routed from the core to this plugin, maybe this data is a parameter change
# check and process data according to type
# The parameter type will appear when another plugin sends parameter updates to this plugin through a
# parameter subscription
if op=='new_data' and self.__paused is False and self.__plugin_stopped is False:
opt = event.get_optional_parameter()
if opt.is_parameter is False:
data = self._demux(opt.data_source_id, opt.block_name, opt.data)
self.cb_execute(Data=data, block_name = opt.block_name, plugin_uname= event.source_plugin_uname)
if opt.is_parameter is True:
self._set_parameter_internal(opt.parameter_alias, opt.data)
# This case appears when a parameter gets changed through an api call e.g. in the overview menu
if op == 'set_parameter' and self.__plugin_stopped is False:
opt = event.get_optional_parameter()
self._set_parameter_internal(opt.parameter_alias, opt.data)
# process a update with meta information from the core
if op == 'update_meta' and self.__plugin_stopped is False:
opt = event.get_optional_parameter()
self._update_plugin_meta(opt.plugin_object)
else: # there was no new event
if self.__paused or self.__EventTriggered or self.__plugin_stopped:
pass
else:
# call the plugin cb_execute function if event mode allows it.
self.cb_execute()
def _starting_sequence(self, config):
"""
This is the starting point for the operation of a plugin.
This function will start the plugin. Therefore it will call the setup function and will report
the success of the start to the core by sending an event.
:param config:
:return:
"""
self._config = config
if self._start_plugin_base():
# report start successfull event
event = Event.status.StartSuccessfull(self.__id__, 0, None)
self._Core_event_queue__.put(event)
else:
# init failed, so report it to core
event = Event.status.StartFailed(self.__id__, 0, None)
self._Core_event_queue__.put(event)
# end plugin
self.__goOn = 0
# sent join request to core
event = Event.status.JoinRequest(self.__id__, 0, None)
self._Core_event_queue__.put(event)
def _start_plugin_base(self):
"""
Needs to be implemented by plugin base class
:return:
"""
raise NotImplementedError("Please Implement this method")
def _evaluate_event_trigger(self,default):
"""
Will evaluate the event trigger mode and set it to the needed value
:param default:
:return:
"""
if self.__user_event_triggered == 'default':
self.__EventTriggered = default
if self.__user_event_triggered is True:
self.__EventTriggered = True
if self.__user_event_triggered is False:
self.__EventTriggered = False
[docs] def pl_set_event_trigger_mode(self, mode):
"""
Enables the plugin developer to set the event_trigger_mode. This meas that when set to TRUE, the
plugin is set to be event triggered which means that the cb_execute function will only be called when
a new event (newData) arrives.
default will mean the default value for the specific plugin type.
:param mode: True, False, or 'default'
:return:
"""
if mode is True or mode is False or mode == 'default':
self.__user_event_triggered = mode