Source code for secsgem.hsms.header

#####################################################################
# header.py
#
# (c) Copyright 2021, Benjamin Parzella. All rights reserved.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This software 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 Lesser General Public License for more details.
#####################################################################
"""Header for the hsms messages."""

from __future__ import annotations

import enum
import struct
import typing

import secsgem.common


[docs] class HsmsSType(enum.Enum): """HSMS SType enum.""" DATA_MESSAGE = 0 SELECT_REQ = 1 SELECT_RSP = 2 DESELECT_REQ = 3 DESELECT_RSP = 4 LINKTEST_REQ = 5 LINKTEST_RSP = 6 REJECT_REQ = 7 SEPARATE_REQ = 9
[docs] @classmethod def names(cls) -> dict[HsmsSType, str]: """Get the names associated with the scode. Returns: dictionary of names associated with enum values """ return { cls.DATA_MESSAGE: "Data.msg", cls.SELECT_REQ: "Select.req", cls.SELECT_RSP: "Select.rsp", cls.DESELECT_REQ: "Deselect.req", cls.DESELECT_RSP: "Deselect.rsp", cls.LINKTEST_REQ: "Linktest.req", cls.LINKTEST_RSP: "Linktest.rsp", cls.REJECT_REQ: "Reject.req", cls.SEPARATE_REQ: "Separate.req", }
@property def text(self) -> str: """Get the text for the item.""" return self.names()[self]
[docs] class HsmsHeader(secsgem.common.Header): """Generic HSMS header. Base for different specific headers """ length = 10 def __init__( # pylint: disable=too-many-arguments,too-many-positional-arguments self, system: int, device_id: int, stream: int = 0, function: int = 0, requires_response: bool = False, p_type: int = 0x00, s_type: HsmsSType = HsmsSType.SELECT_REQ, ): """Initialize a hsms header. Args: system: message ID device_id: device ID stream: stream function: function requires_response: is response required p_type: P-Type s_type: S-Type Example: >>> import secsgem.hsms >>> >>> secsgem.hsms.HsmsHeader(3, 100) HsmsHeader({device_id:0x0064, stream:00, function:00, p_type:0x00, s_type:0x01, system:0x00000003, \ require_response:False}) """ super().__init__(system, device_id, stream, function, requires_response) self._p_type = p_type self._s_type = s_type def __str__(self) -> str: """Generate string representation for an object of this class.""" return ( f"{{device_id:0x{self.device_id:04x}, " f"stream:{self.stream:02d}, " f"function:{self.function:02d}, " f"p_type:0x{self.p_type:02x}, " f"s_type:0x{self.s_type.value:02x}, " f"system:0x{self.system:08x}, " f"require_response:{self.require_response!r}}}" ) def __repr__(self) -> str: """Generate textual representation for an object of this class.""" return f"{self.__class__.__name__}({self.__str__()})" @property def p_type(self) -> int: """Get P-type.""" return self._p_type @property def s_type(self) -> HsmsSType: """Get S-type.""" return self._s_type @property def _as_dictionary(self) -> dict[str, typing.Any]: """Get the data as dictionary. Returns: Header data as dictionary. """ return { "system": self._system, "device_id": self._device_id, "stream": self._stream, "function": self._function, "requires_response": self._require_response, "p_type": self._p_type, "s_type": self._s_type, }
[docs] def encode(self) -> bytes: """Encode header to hsms message. Returns: encoded header Example: >>> import secsgem.hsms >>> import secsgem.common >>> >>> header = secsgem.hsms.HsmsLinktestReqHeader(2) >>> secsgem.common.format_hex(header.encode()) 'ff:ff:00:00:00:05:00:00:00:02' """ header_stream = self.stream if self.require_response: header_stream |= 0b10000000 return struct.pack( ">HBBBBL", self.device_id, header_stream, self.function, self.p_type, self.s_type.value, self.system, )
[docs] @classmethod def decode(cls, data: bytes) -> HsmsHeader: """Decode data to HsmsHeader object. Args: data: data to decode Returns: new header object """ res = struct.unpack(">HBBBBL", data) return HsmsHeader( res[5], res[0], res[1] & 0b01111111, res[2], (((res[1] & 0b10000000) >> 7) == 1), res[3], HsmsSType(res[4]), )