#!/usr/bin/env python3 # vim: sts=4 sw=4 et """ This module allows the creation of userspace HAL components in Python. This includes pins and parameters of the various HAL types. Typical usage: import hal, time h = hal.component("component-name") # create pins and parameters with calls to h.newpin and h.newparam h.newpin("in", hal.HAL_FLOAT, hal.HAL_IN) h.newpin("out", hal.HAL_FLOAT, hal.HAL_OUT) h.ready() # mark the component as 'ready' try: while 1: # act on changed input pins; update values on output pins time.sleep(1) h['out'] = h['in'] except KeyboardInterrupt: pass When the component is requested to exit with 'halcmd unload', a KeyboardInterrupt exception will be raised. """ import _hal from _hal import * from _hal import query import sys import warnings import lcnc_realtime # _hal.query is a submodule, not a plain attribute. Registering it in # sys.modules under its dotted name makes 'import hal.query' and 'from hal # import query' work as they would for a real package. sys.modules['hal.query'] = query def __getattr__(name): if name == 'is_rt': warnings.warn(f"{name} is deprecated, use lcnc_realtime.verify() instead", FutureWarning, stacklevel=2) return lcnc_realtime.verify() if name == 'is_sim': warnings.warn(f"{name} is deprecated, use lcnc_realtime.verify() instead", FutureWarning, stacklevel=2) return not lcnc_realtime.verify() raise AttributeError(f"module {__name__!r} has no attribute {name!r}") class _ItemWrap(object): def __new__(cls, item): if not isinstance(item, _hal.item): raise TypeError("Constructor argument must be _hal.item: %s" % type(item)) self = super(_ItemWrap, cls).__new__(cls) return self._item_wrap(item) def _item_wrap(self, item): for f in ['get', 'set', 'get_type', 'get_name', 'get_dir', 'is_pin', '__repr__']: setattr(self, f, getattr(item, f)) # Only ports can use the extra methods if _hal.HAL_PORT == item.get_type(): for f in ['write', 'read', 'peek', 'peek_commit', 'clear', 'size']: setattr(self, f, getattr(item, f)) return self def __init__(self, item): self._item = item name = property(lambda s: s._item.get_name()) type = property(lambda s: s._item.get_type()) dir = property(lambda s: s._item.get_dir()) value = property(lambda s: s._item.get(), lambda s,v: s._item.set(v)) class Pin(_ItemWrap): def __init__(self, item): _ItemWrap.__init__(self, item) if not item.is_pin(): raise TypeError("Must be constructed from pin object") class Param(_ItemWrap): def __init__(self, item): _ItemWrap.__init__(self, item) if item.is_pin(): raise TypeError("Must be constructed from param object") class component(_hal.component): def newpin(self, *a, **kw): return Pin(_hal.component.newpin(self, *a, **kw)) def newparam(self, *a, **kw): return Param(_hal.component.newparam(self, *a, **kw)) def getpin(self, *a, **kw): return Pin(_hal.component.getpin(self, *a, **kw)) def getparam(self, *a, **kw): return Param(_hal.component.getparam(self, *a, **kw)) def getpins(self, *a, **kw): return _hal.component.getpins(self, *a, **kw)