class Settings(object): """ Class that persists settings to the Kervi database. :param group: To avoid name clash with other settings in the Kervi application enter name to group your settings under. :type group: ``str`` """ def __init__(self, settings_group=None): self.group = settings_group self.spine = Spine() def store_value(self, name, value): """Store a value to DB""" self.spine.send_command("storeSetting", self.group, name, value) def retrieve_value(self, name, default_value=None): """Retrieve a value from DB""" value = self.spine.send_query("retrieveSetting", self.group, name, processes=["kervi-main"]) if value is None: return default_value elif isinstance(value, list) and len(value) == 0: return default_value elif isinstance(default_value, int): return int(value) elif isinstance(default_value, float): return float(value) else: return value
def open_file(source, file_type, file_name, metadata=None): from kervi.spine import Spine spine = Spine() file_id = str(uuid.uuid4()) spine.send_command("files_open_file", file_id, source, file_type, file_name, metadata) return file_id
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()
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, region_group, stream_id, position_x, position_y, caption=None, width=0, height=0, focus_x=None, focus_y=None, text=None, region_id=None): if region_id: self.region_id = region_id else: self.region_id = uuid.uuid4().hex self.region_group = region_group self.stream_id = stream_id self.x = position_x self.y = position_y self.caption = caption self.width = width self.height = height self.focus_x = focus_x self.focus_y = focus_y self.text = text self.visible = True self.spine = Spine() Regions.add(self) self.spine.trigger_event( "visionRegionChange", self.stream_id, {"action":"add", "region":self._region_info()} )
def is_session_valid(headers): spine = Spine() json_header = {} for header in headers: json_header[header] = headers[header] res = spine.send_query("validSessionHeader", json_header) return res
class _ScheduleThread(threading.Thread): r""" """ def __init__(self, schedule, schedule_interval=1): threading.Thread.__init__(self, name="ScheduleThread") self.spine = None self.terminate = False self.schedule_interval = schedule_interval self.schedule = schedule self.daemon = True def run(self): while not self.terminate: if not self.spine: self.spine = Spine() if self.spine: self.spine.register_command_handler( "stopThreads", self._stop_command) else: self.schedule.run_pending() time.sleep(self.schedule_interval) def _stop_command(self): if not self.terminate: self.terminate = True
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")
def __init__(self, command, protocol): self.protocol = protocol self.command = command spine = Spine() #print("rc", command) spine.register_command_handler(command, self.on_command, injected="socketSpine")
def __init__(self): self.spine = Spine() WebSocketServerProtocol.__init__(self) self.handlers = {"command": [], "query": [], "event": []} self.authenticated = False self.session = None self.user = None self._authorization = Authorization()
def __init__(self, event, id_event, protocol): self.protocol = protocol self.event = event self.id_event = id_event self.spine = Spine() self.spine.register_event_handler(event, self.on_event, id_event, injected="socketSpine") self._eps_counter = 0 self._eps_start_time = time.time() self._eps = 0
def __init__(self, stream_id, stream_event, protocol): self.protocol = protocol self.stream_event = stream_event self.stream_id = stream_id self.spine = Spine() self.spine.register_stream_handler(stream_id, self.on_event, stream_event, injected="socketSpine") self._eps_counter = 0 self._eps_start_time = time.time() self._eps = 0
class _Messaging(object): def __init__(self): self.spine = Spine() pass def send_message(self, subject, **kwargs): #kwargs = dict(kwargs, run_async=True) #Actions["message_manager.send_message"](subject, **kwargs) self.spine.send_command("messageManagerSend", subject, **kwargs)
def __init__(self, event, id_event, protocol): self.protocol = protocol self.event = event self.id_event = id_event self.spine = Spine() #print("re", event, id_event) self.spine.register_event_handler(event, self.on_event, id_event, injected="socketSpine")
def run(self): while not self.terminate: if not self.spine: self.spine = Spine() if self.spine: self.spine.register_command_handler( "stopThreads", self._stop_command) else: self.schedule.run_pending() time.sleep(self.schedule_interval)
class _SensorThread(KerviThread): r""" SensorThread is the base class that polls sensors. Add one or more sensors and set polling interval. :param sensors: Id of the sensor. This id is used in other components to reference this sesnor. :type sensors: ``str`` :param reading_interval: Polling interval in seconds between :type reading_interval: ``float`` """ def __init__(self, sensors, reading_interval=1): KerviThread.__init__(self) self.spine = Spine() if self.spine: self.spine.register_command_handler("startThreads", self._start_command) self.spine.register_command_handler("stopThreads", self._stop_command) self.alive = False self.reading_interval = reading_interval if hasattr(sensors, "__len__"): self.sensors = sensors else: self.sensors = [sensors] def new_sensor_reading(self, value, sensor_idx=0): self.sensors[sensor_idx]._new_sensor_reading(value) def _step(self): for sensor in self.sensors: sensor._read_sensor() self.sensor_step() time.sleep(self.reading_interval) def sensor_step(self): pass def _start_command(self): if not self.alive: self.alive = True KerviThread.start(self) def _stop_command(self): if self.alive: self.alive = False self.stop()
def __init__(self, channel, device, callback, polling_time=.1): KerviThread.__init__(self) self._callback = callback self._channel = channel self._device = device self._value = None self._polling_time = polling_time self.alive = False self.spine = Spine() if self.spine: self.spine.register_command_handler("startThreads", self._start_command) self.spine.register_command_handler("stopThreads", self._stop_command)
def __init__(self, sensors, reading_interval=1): KerviThread.__init__(self) self.spine = Spine() if self.spine: self.spine.register_command_handler("startThreads", self._start_command) self.spine.register_command_handler("stopThreads", self._stop_command) self.alive = False self.reading_interval = reading_interval if hasattr(sensors, "__len__"): self.sensors = sensors else: self.sensors = [sensors]
class ModuleThread(KerviThread): def __init__(self): KerviThread.__init__(self) self.spine = Spine() self.spine.register_command_handler("startThreads", self._startCommand) def _step(self): self.moduleStep() def _startCommand(self): if not self.isAlive(): super(KerviThread, self).start() def _stopCommand(self): self.stop()
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 = {}
class _WebEventHandler(object): def __init__(self, event, id_event, protocol): self.protocol = protocol self.event = event self.id_event = id_event self.spine = Spine() #print("re", event, id_event) self.spine.register_event_handler(event, self.on_event, id_event, injected="socketSpine") def on_event(self, id_event, *args, **kwargs): injected = kwargs.get("injected", "") groups = kwargs.get("groups", None) process_id = kwargs.get("process_id", None) self.spine.log.debug("WS relay event:{0} injected:{1}", self.event, injected) authorized = True if self.protocol.user != None and self.protocol.user[ "groups"] != None and groups != None and len(groups) > 0: for group in groups: if group in self.protocol.user["groups"]: break else: authorized = False if authorized and self.protocol.authenticated and not injected == "socketSpine": cmd = { "messageType": "event", "event": self.event, "id": id_event, "args": args } jsonres = json.dumps(cmd, cls=_ObjectEncoder, ensure_ascii=False).encode('utf8') #if self.event=="userLogMessage": # print("wum", id_event, process_id, injected, jsonres) self.protocol.sendMessage(jsonres, False)
class _WebStreamHandler(object): def __init__(self, stream_id, stream_event, protocol): self.protocol = protocol self.stream_event = stream_event self.stream_id = stream_id self.spine = Spine() self.spine.register_stream_handler(stream_id, self.on_event, stream_event, injected="socketSpine") self._eps_counter = 0 self._eps_start_time = time.time() self._eps = 0 def close(self): self.spine.unregister_stream_handler(self.stream_id, self.on_event, self.stream_event) def on_event(self, stream_id, stream_event, data, *args, **kwargs): self._eps_counter += 1 now = time.time() seconds = now - self._eps_start_time if (seconds) > 1 : self._eps = self._eps_counter / seconds self._eps_counter = 0 self._eps_start_time = now #print("epc", self.stream_id, self.stream_event, epc) injected = kwargs.get("injected", "") groups = kwargs.get("groups", None) #process_id = kwargs.get("process_id", None) authorized = True if self.protocol.user != None and self.protocol.user["groups"] != None and groups != None and len(groups) > 0: for group in groups: if group in self.protocol.user["groups"]: break else: authorized = False if authorized and self.protocol.authenticated and not injected == "socketSpine": cmd = {"messageType":"stream", "streamId":self.stream_id, "streamEvent":self.stream_event, "args":args, "eps": self._eps, "ts": now} jsonres = json.dumps(cmd, cls=_ObjectEncoder, ensure_ascii=False).encode('utf8') jsonlen = len(jsonres) jsonres = jsonlen.to_bytes(4, byteorder='little') + jsonres + data #print(cmd) self.protocol.broadcast_message(self.protocol, jsonres, True)
class Authorization: def __init__(self): self._spine = Spine() self._active = None @property def active(self): if self._active == None: self._active = self._spine.send_query("authorizationActive") return self._active def authorize(self, user_name, password): user = self._spine.send_query("authorizationAuthorizeUser", user_name, password) return user def allow_anonymous(self): return self._spine.send_query("authorizationAllowAnonymousUser") def valid_session_header(self, headers): return self._spine.send_query("authorizationValidSessionHeader", headers) def remove_session(self, session_id): return self._spine.send_command("authorizationRemoveSession", session_id) def get_users(self): return self._spine.send_query("authorizationGetUsers")
class _WebEventHandler(object): def __init__(self, event, id_event, protocol): self.protocol = protocol self.event = event self.id_event = id_event self.spine = Spine() self.spine.register_event_handler(event, self.on_event, id_event, injected="socketSpine") self._eps_counter = 0 self._eps_start_time = time.time() self._eps = 0 def on_event(self, id_event, *args, **kwargs): injected = kwargs.get("injected", "") groups = kwargs.get("groups", None) #process_id = kwargs.get("process_id", None) #self.spine.log.debug("WS relay event:{0} injected:{1}", self.event, injected) self._eps_counter += 1 now = time.time() seconds = now - self._eps_start_time if (seconds) > 1 : self._eps = self._eps_counter / seconds self._eps_counter = 0 self._eps_start_time = now authorized = True if self.protocol.user != None and self.protocol.user["groups"] != None and groups != None and len(groups) > 0: for group in groups: if group in self.protocol.user["groups"]: break else: authorized = False if authorized and self.protocol.authenticated and not injected == "socketSpine": cmd = {"messageType":"event", "event":self.event, "id":id_event, "args":args, "eps": self._eps, "ts": now} jsonres = json.dumps(cmd, cls=_ObjectEncoder, ensure_ascii=False).encode('utf8') self.protocol.broadcast_message(self.protocol, jsonres)
class Region: def __init__(self, region_group, stream_id, position_x, position_y, caption=None, width=0, height=0, focus_x=None, focus_y=None, text=None, region_id=None): if region_id: self.region_id = region_id else: self.region_id = uuid.uuid4().hex self.region_group = region_group self.stream_id = stream_id self.x = position_x self.y = position_y self.caption = caption self.width = width self.height = height self.focus_x = focus_x self.focus_y = focus_y self.text = text self.visible = True self.spine = Spine() Regions.add(self) self.spine.trigger_event( "visionRegionChange", self.stream_id, {"action":"add", "region":self._region_info()} ) def _region_info(self): return { "region_id": self.region_id, "group": self.region_group, "stream_id": self.stream_id, "x": self.x, "y": self.y, "caption": self.caption, "width": self.width, "height": self.height, "focus_x": self.focus_x, "focus_y": self.focus_y, "text": self.text, "visible": self.visible } def update(self): self.spine.trigger_event( "visionRegionChange", self.stream_id, {"action":"update", "region":self._region_info()} ) def invalidate(self): Regions.remove(self) self.spine.trigger_event( "visionRegionChange", self.stream_id, {"action":"invalidate", "region":self._region_info()} )
class ChannelPollingThread(KerviThread): def __init__(self, channel, device, callback, polling_time=.1): KerviThread.__init__(self) self._callback = callback self._channel = channel self._device = device self._value = None self._polling_time = polling_time self.alive = False self.spine = Spine() if self.spine: self.spine.register_command_handler("startThreads", self._start_command) self.spine.register_command_handler("stopThreads", self._stop_command) def _step(self): """Private method do not call it directly or override it.""" try: new_value = self._device.get(self._channel) if new_value != self._value: self._callback(new_value) self._value = new_value time.sleep(self._polling_time) except: self.spine.log.exception("_PollingThread") def _start_command(self): if not self.alive: self.alive = True KerviThread.start(self) def _stop_command(self): if self.alive: self.alive = False self.stop()
def __init__(self, config): #coro = None self._started = False self._config = config self._spine = Spine() try: import asyncio except ImportError: ## Trollius >= 0.3 was renamed import trollius as asyncio from autobahn.asyncio.websocket import WebSocketServerFactory ssl_context = None if encryption.enabled(): self._spine.log.debug("socket using ssl") cert_file, key_file = encryption.get_cert() try: import ssl ssl_context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) ssl_context.load_cert_chain(cert_file, key_file) #self._spine.log.debug("socket ssl found") except: ssl_context = None self._spine.log.error("socket failed to use ssl") self._spine.log.debug( "start websocket on:{0}, port:{1}", self._config.network.ip, self._config.network.ws_port ) self.factory = WebSocketServerFactory() self.factory.protocol = _SpineProtocol self.loop = asyncio.get_event_loop() _SpineProtocol.loop = self.loop self.coro = self.loop.create_server( self.factory, self._config.network.ip, self._config.network.ws_port, ssl=ssl_context )
def __init__(self, name, config, manager): from kervi.config.configuration import _Configuration self._config = _Configuration() from kervi.config import Configuration self._global_config = Configuration plugin_config = {} if config: plugin_config = config.as_dict() self._config._load(config_user=plugin_config, config_base=self.get_default_config()) self._name = name self._manager = manager from kervi.spine import Spine self.spine = Spine() from kervi.core.utility.bind_decorators import bind_decorators_to_class bind_decorators_to_class(self)
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)
def logger(self): return Spine().log