class _Regions: def __init__(self): self._regions = {} self.spine = Spine() self.spine.register_query_handler("getRegionsOfInterest", self._get_region_list) def __getitem__(self, region_id): return self._regions[region_id] def _get_region_list(self, stream_id): result = [] for region in self._regions: result.append(region) return result def add(self, region): self._regions[region.region_id] = region def clear(self, region_group=None, stream_id=None): for region_id in list(self._regions): region = self._regions[region_id] invalidate = False if not region_group and not stream_id: invalidate = True elif region_group and region.region_group == region_group: invalidate = True elif stream_id and region.stream_id == stream_id: invalidate = True if invalidate: region.invalidate() def remove(self, region): del self._regions[region.region_id]
def __init__(self, query, protocol): self.protocol = protocol self.query = query spine = Spine() #print("rq:", query) spine.register_query_handler(query, self.on_query, injected="socketSpine")
class _LinkedAction(object): def __init__(self, action_id): self._action_id = action_id self.spine = Spine() self.spine.register_event_handler("actionDone", self._action_done, action_id) self.spine.register_event_handler("actionStarted", self._action_started, action_id) self.spine.register_query_handler("getComponentRoutes", self._get_component_bus_routes) self._state = ACTION_STOPPED self._action_event = None self._action_lock = threading.Lock() self._process_locked = False self._is_running = False self._last_result = None self._observers = [] self._spine_observers = {} def _get_component_bus_routes(self): return { "id": None, "routes": [{ "id": self._action_id, "direction": "in", "topic_type": "event", "topic": "actionStarted" }, { "id": self._action_id, "direction": "in", "topic_type": "event", "topic": "actionDone" }, { "id": self._action_id, "direction": "out", "topic_type": "command", "topic": "kervi_action_" + self._action_id }], } def _action_done(self, id, state, result): if self._state == ACTION_RUNNING: self._state = state self._last_result = result if self._action_event: self._action_event.set() if self._process_locked: self._process_locked = False self._action_lock.release() self._is_running = False def _action_started(self, id): self._state = ACTION_RUNNING self._last_result = None self._is_running = True if self._action_lock.acquire(False): self._process_locked = True def run_every(self, interval=1): """ Schedule an action to run periodically. :param interval: A quantity of a certain time unit """ job = ActionJob(interval, default_scheduler, self) return job @property def is_running(self): return self._is_running @property def state(self): """Returns the running state of the action.""" return self._state def interrupt(self, *args, **kwargs): self.spine.send_command("kervi_action_interrupt_" + self._action_id, *args, **kwargs) def execute(self, *args, **kwargs): """Executes the action.""" timeout = kwargs.pop("timeout", -1) run_async = kwargs.pop("run_async", False) self._is_running = True result = None if self._action_lock.acquire(False): self._state = ACTION_PENDING self._action_event = threading.Event() self.spine.send_command("kervi_action_" + self._action_id, *args, **kwargs) if not run_async: if self._action_event.wait(timeout): self._state = ACTION_FAILED raise TimeoutError("Timeout in call to action: " + self._action_id) self._action_event = None result = self._last_result else: self._action_lock.release() else: if not self._action_lock.acquire(True, timeout): return None self._action_lock.release() return result def __call__(self, *args, **kwargs): self.execute(*args, **kwargs) def link_to(self, source, **kwargs): from kervi.values.kervi_value import KerviValue if isinstance(source, KerviValue): source.add_observer(self) self._spine_observers[source.value_id] = kwargs elif isinstance(source, str): self.spine.register_event_handler("valueChanged", self._link_changed_event, source) self._spine_observers[source] = kwargs def kervi_value_changed(self, source, value): self._link_changed_event(source.value_id, { "id": source.value_id, "value": source.value }, value) def _link_changed_event(self, id, source, old_value): if source["id"] in self._spine_observers.keys(): kwargs = self._spine_observers[source["id"]] value = source["value"] self._handle_link_event(value, **kwargs) def _handle_link_event(self, value, **kwargs): pass_value = kwargs.pop("pass_value", False) trigger_value = kwargs.pop("trigger_value", True) trigger_interrupt_value = kwargs.pop("trigger_interrupt_value", False) action_parameters = kwargs.pop("action_parameters", []) interrupt_parameters = kwargs.pop("interrupt_parameters", []) if pass_value: action_parameters = [value] + action_parameters if isinstance(trigger_value, types.LambdaType) and trigger_value( value) and not self.is_running: self.execute(*action_parameters, run_async=True) if isinstance(trigger_interrupt_value, types.LambdaType ) and trigger_interrupt_value(value) and self.is_running: self.interrupt(*interrupt_parameters) elif trigger_value == value and not self.is_running: self.execute(*action_parameters, run_async=True) elif trigger_interrupt_value == value and self.is_running: self.interrupt(*interrupt_parameters)
class StorageManager(Controller): def __init__(self, log_queue): Controller.__init__(self, "storage_manager", "Storage manager") self._spine = Spine() self._spine.register_event_handler("valueChanged", self._store_value) self._spine.register_query_handler("getValueData", self._get_value_data) self._spine.register_command_handler("storeSetting", self._store_setting) self._spine.register_query_handler("retrieveSetting", self._retrieve_setting) self._spine.register_query_handler("getMessageItems", self._get_messages) self._spine.register_event_handler("newMessage", self._store_message) #SPINE.register_command_handler("createCronJob", create_cron_job) #SPINE.register_command_handler("deleteCronJob", delete_cron_job) #SPINE.register_query_handler("queryCronJob", query_cron_job) self._plugin_manager = None self._plugin_manager = PluginManager(Configuration, "storage", [StoragePlugin], log_queue=log_queue) self._plugin_manager.load_managed_plugins() def _store_value(self, value_id, value, persist=False): for plugin in self._plugin_manager.plugins: try: if persist and plugin.storage_type == "persisted": plugin.store_value(value_id, value, persist) elif not persist and not plugin.storage_type == "persisted": plugin.store_value(value_id, value, persist) except NotImplementedError: pass def _get_value_data(self, value, date_from=None, date_to=None, limit=60): for plugin in self._plugin_manager.plugins: try: plugin.get_value_data(value, date_from, date_to, limit) except NotImplementedError: pass def _store_setting(self, group, name, value): for plugin in self._plugin_manager.plugins: try: if plugin.storage_type == "persisted": plugin.store_setting(group, name, value) except NotImplementedError: pass def _retrieve_setting(self, group, name): for plugin in self._plugin_manager.plugins: try: if plugin.storage_type == "persisted": return plugin.retrieve_setting(group, name) except NotImplementedError: pass def _store_message(self, source_id, item): for plugin in self._plugin_manager.plugins: try: plugin.store_message(source_id, item) except NotImplementedError: pass def _get_messages(self, page, page_size, filters=None): for plugin in self._plugin_manager.plugins: try: plugin.get_messages(self, page, page_size, filters) except NotImplementedError: pass