Source code for ingenialink.register

from enum import Enum

from ._ingenialink import ffi, lib
from ingenialink.utils._utils import *

from abc import ABC

# CANOPEN DTYPES
IL_REG_DTYPE_DOMAIN = 15


[docs]class REG_DTYPE(Enum): """Data Type.""" U8 = lib.IL_REG_DTYPE_U8 """Unsigned 8-bit integer.""" S8 = lib.IL_REG_DTYPE_S8 """Signed 8-bit integer.""" U16 = lib.IL_REG_DTYPE_U16 """Unsigned 16-bit integer.""" S16 = lib.IL_REG_DTYPE_S16 """Signed 16-bit integer.""" U32 = lib.IL_REG_DTYPE_U32 """Unsigned 32-bit integer.""" S32 = lib.IL_REG_DTYPE_S32 """Signed 32-bit integer.""" U64 = lib.IL_REG_DTYPE_U64 """Unsigned 64-bit integer.""" S64 = lib.IL_REG_DTYPE_S64 """Signed 64-bit integer.""" FLOAT = lib.IL_REG_DTYPE_FLOAT """Float.""" STR = lib.IL_REG_DTYPE_STR """String.""" DOMAIN = IL_REG_DTYPE_DOMAIN """Domain."""
[docs]class REG_ACCESS(Enum): """Access Type.""" RW = lib.IL_REG_ACCESS_RW """Read/Write.""" RO = lib.IL_REG_ACCESS_RO """Read-only.""" WO = lib.IL_REG_ACCESS_WO """Write-only."""
[docs]class REG_PHY(Enum): """Physical Units.""" NONE = lib.IL_REG_PHY_NONE """None.""" TORQUE = lib.IL_REG_PHY_TORQUE """Torque.""" POS = lib.IL_REG_PHY_POS """Position.""" VEL = lib.IL_REG_PHY_VEL """Velocity.""" ACC = lib.IL_REG_PHY_ACC """Acceleration.""" VOLT_REL = lib.IL_REG_PHY_VOLT_REL """Relative voltage (DC).""" RAD = lib.IL_REG_PHY_RAD """Radians."""
dtypes_ranges = { REG_DTYPE.U8: {"max": 255, "min": 0}, REG_DTYPE.S8: {"max": 127, "min": -128}, REG_DTYPE.U16: {"max": 65535, "min": 0}, REG_DTYPE.S16: {"max": 32767, "min": -32767 - 1}, REG_DTYPE.U32: {"max": 4294967295, "min": 0}, REG_DTYPE.S32: {"max": 2147483647, "min": -2147483647 - 1}, REG_DTYPE.U64: {"max": 18446744073709551615, "min": 0}, REG_DTYPE.S64: {"max": 9223372036854775807, "min": 9223372036854775807 - 1}, REG_DTYPE.FLOAT: {"max": 2147483647, "min": -2147483647 - 1} } def dtype_size(dtype): sizes = { REG_DTYPE.U8: 1, REG_DTYPE.S8: 1, REG_DTYPE.U16: 2, REG_DTYPE.S16: 2, REG_DTYPE.U32: 4, REG_DTYPE.S32: 4, REG_DTYPE.U64: 8, REG_DTYPE.S64: 8, REG_DTYPE.FLOAT: 4 } return sizes[dtype] def _get_reg_id(reg): """Obtain Register and ID. Args: reg (str, Register): Register. """ if isinstance(reg, str): return ffi.NULL, cstr(reg) elif isinstance(reg, Register): return reg._reg, ffi.NULL raise TypeError('Unexpected register type')
[docs]class Register(ABC): """Register. Args: identifier (str): Identifier. units (str): Units. cyclic (str): Cyclic typed register. dtype (REG_DTYPE): Data type. access (REG_ACCESS): Access type. phy (REG_PHY, optional): Physical units. subnode (int): Subnode storage (any, optional): Storage. reg_range (tuple, optional): Range (min, max). labels (dict, optional): Register labels. enums (dict, optional): Enumeration values. cat_id (str, optional): Category ID. scat_id (str, optional): Sub-category ID. internal_use (int, optional): Internal use. Raises: TypeError: If any of the parameters has invalid type. """ def __init__(self, identifier, units, cyclic, dtype, access, phy=REG_PHY.NONE, subnode=1, storage=None, reg_range=None, labels=None, enums=None, enums_count=0, cat_id=None, scat_id=None, internal_use=0): if labels is None: labels = {} if enums is None: enums = [] if not isinstance(dtype, REG_DTYPE): raise TypeError('Invalid data type') if not isinstance(access, REG_ACCESS): raise TypeError('Invalid access type') if not isinstance(phy, REG_PHY): raise TypeError('Invalid physical units type') self._identifier = identifier self._units = units self._subnode = subnode self._cyclic = cyclic self._dtype = dtype.value self._access = access.value self._phy = phy.value self._storage = storage self._storage_valid = 0 if not storage else 1 self._internal_use = internal_use self._range = (None, None) if not reg_range else reg_range self._labels = labels self._enums = enums self._enums_count = enums_count self._cat_id = cat_id self._scat_id = scat_id @property def identifier(self): """str: Register identifier.""" return self._identifier @property def units(self): """str: Units of the register.""" return self._units @property def subnode(self): """int: Target subnode of the register.""" return self._subnode @property def cyclic(self): """str: Defines if the register is cyclic.""" return self._cyclic @property def dtype(self): """REG_DTYPE: Data type of the register.""" return REG_DTYPE(self._dtype) @property def access(self): """REG_ACCESS: Access type of the register.""" return REG_ACCESS(self._access) @property def phy(self): """REG_PHY: Physical units of the register.""" return REG_PHY(self._phy) @property def storage(self): """any: Defines if the register needs to be stored.""" return self._storage @property def storage_valid(self): """bool: Defines if the register storage is valid.""" return self._storage_valid @property def range(self): """tuple: Containing the minimum and the maximum values of the register.""" return self._range @property def labels(self): """dict: Containing the labels of the register.""" return self._labels @property def enums(self): """dict: Containing all the enums for the register.""" return self._enums @property def enums_count(self): """int: The number of the enums in the register.""" return self._enums_count @property def cat_id(self): """str: Category ID""" return self._cat_id @property def scat_id(self): """str: Sub-Category ID""" return self._scat_id @property def internal_use(self): """int: Defines if the register is only for internal uses.""" return self._internal_use