COSEMpdu 0.3.2__tar.gz → 0.3.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. {cosempdu-0.3.2/src/COSEMpdu.egg-info → cosempdu-0.3.4}/PKG-INFO +1 -1
  2. {cosempdu-0.3.2 → cosempdu-0.3.4}/pyproject.toml +1 -1
  3. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/axdr.py +3 -4
  4. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/data.py +30 -4
  5. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/user_information.py +40 -5
  6. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/x680/bit_string.py +2 -0
  7. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/x680/constrained_type.py +2 -3
  8. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/x680/enumerated_type.py +5 -0
  9. {cosempdu-0.3.2 → cosempdu-0.3.4/src/COSEMpdu.egg-info}/PKG-INFO +1 -1
  10. {cosempdu-0.3.2 → cosempdu-0.3.4}/.github/workflows/publish.yml +0 -0
  11. {cosempdu-0.3.2 → cosempdu-0.3.4}/.gitignore +0 -0
  12. {cosempdu-0.3.2 → cosempdu-0.3.4}/.vscode/launch.json +0 -0
  13. {cosempdu-0.3.2 → cosempdu-0.3.4}/README.md +0 -0
  14. {cosempdu-0.3.2 → cosempdu-0.3.4}/setup.cfg +0 -0
  15. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/__init__.py +0 -0
  16. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/acse.py +0 -0
  17. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/apdu.py +0 -0
  18. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/ber.py +0 -0
  19. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/byte_buffer.py +0 -0
  20. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/key_info.py +0 -0
  21. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/py.typed +0 -0
  22. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/service_error.py +0 -0
  23. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/types_used.py +0 -0
  24. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/useful_types.py +0 -0
  25. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/x680/__init__.py +0 -0
  26. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/x680/boolean_type.py +0 -0
  27. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/x680/choice_type.py +0 -0
  28. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/x680/generalized_time.py +0 -0
  29. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/x680/integer_type.py +0 -0
  30. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/x680/null_type.py +0 -0
  31. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/x680/object_identifier_type.py +0 -0
  32. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/x680/octet_string_type.py +0 -0
  33. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/x680/sequence_of_type.py +0 -0
  34. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/x680/sequence_type.py +0 -0
  35. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/x680/tag.py +0 -0
  36. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/x680/tagged_type.py +0 -0
  37. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/x680/type.py +0 -0
  38. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu/x690.py +0 -0
  39. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu.egg-info/SOURCES.txt +0 -0
  40. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu.egg-info/dependency_links.txt +0 -0
  41. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu.egg-info/requires.txt +0 -0
  42. {cosempdu-0.3.2 → cosempdu-0.3.4}/src/COSEMpdu.egg-info/top_level.txt +0 -0
  43. {cosempdu-0.3.2 → cosempdu-0.3.4}/test/__init__.py +0 -0
  44. {cosempdu-0.3.2 → cosempdu-0.3.4}/test/test_acse_pdu.py +0 -0
  45. {cosempdu-0.3.2 → cosempdu-0.3.4}/test/test_apdu.py +0 -0
  46. {cosempdu-0.3.2 → cosempdu-0.3.4}/test/test_axdr.py +0 -0
  47. {cosempdu-0.3.2 → cosempdu-0.3.4}/test/test_ber.py +0 -0
  48. {cosempdu-0.3.2 → cosempdu-0.3.4}/test/test_bytebuffer.py +0 -0
  49. {cosempdu-0.3.2 → cosempdu-0.3.4}/test/test_constraint.py +0 -0
  50. {cosempdu-0.3.2 → cosempdu-0.3.4}/test/test_data.py +0 -0
  51. {cosempdu-0.3.2 → cosempdu-0.3.4}/test/test_main.py +0 -0
  52. {cosempdu-0.3.2 → cosempdu-0.3.4}/test/test_service_error.py +0 -0
  53. {cosempdu-0.3.2 → cosempdu-0.3.4}/test/test_types_used.py +0 -0
  54. {cosempdu-0.3.2 → cosempdu-0.3.4}/test/test_x680_bitstring.py +0 -0
  55. {cosempdu-0.3.2 → cosempdu-0.3.4}/test/test_x690.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: COSEMpdu
3
- Version: 0.3.2
3
+ Version: 0.3.4
4
4
  Summary: cosem-pdu
5
5
  Author-email: Serj Kotilevski <youserj@outlook.com>
6
6
  Project-URL: Source, https://github.com/youserj/COSEMpdu_project
@@ -9,7 +9,7 @@ package-dir = {"" = "src"}
9
9
 
10
10
  [project]
11
11
  name = "COSEMpdu"
12
- version = "0.3.2"
12
+ version = "0.3.4"
13
13
  authors = [
14
14
  {name="Serj Kotilevski", email="youserj@outlook.com"}
15
15
  ]
@@ -17,13 +17,12 @@ Standards:
17
17
  - X.680: ASN.1 notation
18
18
  - X.690: BER encoding (reference for comparison)
19
19
  """
20
-
21
- from typing import ClassVar, Self, Optional, cast, TypeAlias, Annotated, Protocol, Any, override
20
+ from typing import ClassVar, Self, Optional, cast, TypeAlias, Annotated, Protocol, Any, override, runtime_checkable
22
21
  from StructResult.result import ValueOrError, Error
23
22
  from COSEMpdu import x690
24
23
  from .x680.tagged_type import TaggingMode
25
24
  from .x680.constrained_type import ValueRange, SizeConstraint
26
- from .x680.type import OptionalNamedType, DefaultNamedType, NamedType, INTEGER, SEQUENCE_OF, CHOICE, OCTET_STRING
25
+ from .x680.type import OptionalNamedType, DefaultNamedType, NamedType, INTEGER, SEQUENCE_OF, CHOICE
27
26
  from . import x680
28
27
  from .byte_buffer import ByteBuffer, put_chain
29
28
 
@@ -480,7 +479,7 @@ class Utf8String(Type, x680.VisibleString): # todo: copypast VisibleString
480
479
  # =============================================================================
481
480
  # CHOICE Type (IEC 61334-6 §6.6)
482
481
  # =============================================================================
483
-
482
+ @runtime_checkable
484
483
  class ChoiceType(Type, x680.ChoiceType[Type], Protocol):
485
484
  """
486
485
  CHOICE with A-XDR encoding/decoding (IEC 61334-6 §6.6)
@@ -262,6 +262,10 @@ class Structure(ImplicitTaggedType[SequenceOfData[ImplicitTaggedType[Any]]]):
262
262
  tag = 2
263
263
  components: ClassVar[Optional[tuple[NamedType[Type], ...]]] = None # 4.1.5 Common data types Table 2
264
264
 
265
+ @classmethod
266
+ def default(cls) -> Self:
267
+ return cls(SequenceOfData([component.type_.default() for component in cls.components]))
268
+
265
269
  @property
266
270
  def get_el0(self):
267
271
  return self.value[0]
@@ -354,6 +358,9 @@ class DigitalMixin[T: Unsigned8 | Unsigned16 | Unsigned32 | Unsigned64 | Integer
354
358
  def __int__(self) -> int:
355
359
  return self.value.value.value
356
360
 
361
+ def normalize(self) -> INTEGER:
362
+ return self.value.normalize()
363
+
357
364
 
358
365
  class Boolean(ImplicitTaggedType[BooleanType]):
359
366
  """[3] IMPLICIT BOOLEAN"""
@@ -379,6 +386,9 @@ class OctetString(ImplicitTaggedType[OctetStringType]):
379
386
  """[9] IMPLICIT OCTET STRING"""
380
387
  tag = 9
381
388
 
389
+ def normalize(self) -> OCTET_STRING:
390
+ return super().normalize()
391
+
382
392
 
383
393
  class VisibleString(ImplicitTaggedType[axdr.VisibleString]):
384
394
  """[10] IMPLICIT VisibleString"""
@@ -494,10 +504,26 @@ class EnumMixin:
494
504
 
495
505
  def __str__(self) -> str:
496
506
  value = self.normalize()
497
- add: str = ""
498
- if value in self.enumeration_item:
499
- add = f"{self.enumeration_item[value]}"
500
- return f"({value}){add}"
507
+ return f"({value}){self.enumeration_item.get(value, "")}"
508
+
509
+
510
+ class BitMixin:
511
+ enumeration_item: ClassVar[dict[int, str]]
512
+ value: Unsigned8
513
+
514
+ def normalize(self) -> INTEGER:
515
+ return self.value.normalize()
516
+
517
+ def __str__(self) -> str:
518
+ value = self.normalize()
519
+ values: list[str] = []
520
+ for (k, v) in self.enumeration_item.items():
521
+ if k & value:
522
+ values.append(v)
523
+ return f"({value}){" | ".join(values)}"
524
+
525
+ def __contains__(self, item: INTEGER) -> bool:
526
+ return bool(item & self.normalize())
501
527
 
502
528
 
503
529
  class Enum(EnumMixin, ImplicitTaggedType[Unsigned8]):
@@ -1,9 +1,10 @@
1
- from typing import Optional, Self, ClassVar
1
+ from typing import Optional, Self, ClassVar, Literal
2
2
  from .x680 import tag, TaggingMode
3
3
  from .x680.type import (
4
4
  OptionalNamedType,
5
5
  DefaultNamedType,
6
- NamedType
6
+ NamedType,
7
+ INTEGER
7
8
  )
8
9
  from .x680.bit_string import NamedBitList, NamedBit
9
10
  from .x680.constrained_type import SizeConstraint
@@ -13,8 +14,7 @@ from . import axdr
13
14
  from .useful_types import Integer8, Unsigned16, Unsigned8, ObjectName
14
15
 
15
16
 
16
- class Conformance_(ber.ConstrainedType[ber.BitStringType]):
17
- """Conformance"""
17
+ class BitStringConformance(ber.BitStringType):
18
18
  named_bits: ClassVar[Optional[NamedBitList]] = NamedBitList((
19
19
  NamedBit("reserved-zero", 0),
20
20
  NamedBit("general-protection", 1),
@@ -41,8 +41,40 @@ class Conformance_(ber.ConstrainedType[ber.BitStringType]):
41
41
  NamedBit("event-notification", 22),
42
42
  NamedBit("action", 23),
43
43
  ))
44
+
45
+
46
+ class Conformance_(ber.ConstrainedType[BitStringConformance]):
47
+ """Conformance"""
44
48
  constraint_spec = SizeConstraint(24)
45
- value: ber.BitStringType
49
+ value: BitStringConformance
50
+
51
+
52
+ NamedBitLiteral = Literal[
53
+ "reserved-zero",
54
+ "general-protection",
55
+ "general-block-transfer",
56
+ "read",
57
+ "write",
58
+ "unconfirmed-write",
59
+ "delta-value-encoding",
60
+ "reserved-seven",
61
+ "attribute0-supported-with-set",
62
+ "priority-mgmt-supported",
63
+ "attribute0-supported-with-get",
64
+ "block-transfer-with-get-or-read",
65
+ "block-transfer-with-set-or-write",
66
+ "block-transfer-with-action",
67
+ "multiple-references",
68
+ "information-report",
69
+ "data-notification",
70
+ "access",
71
+ "parameterized-access",
72
+ "get",
73
+ "set",
74
+ "selective-access",
75
+ "event-notification",
76
+ "action"
77
+ ]
46
78
 
47
79
 
48
80
  class Conformance(ber.TaggedType[Conformance_]):
@@ -53,6 +85,9 @@ class Conformance(ber.TaggedType[Conformance_]):
53
85
  mode = TaggingMode.IMPLICIT
54
86
  value: Conformance_
55
87
 
88
+ def __getitem__(self, key: NamedBitLiteral) -> INTEGER:
89
+ return self.value.value[key]
90
+
56
91
 
57
92
  LN_REFERENCE = ObjectName(axdr.IntegerType(0x0007))
58
93
  SN_REFERENCE = ObjectName(axdr.IntegerType(-1536)) # 0xFA00
@@ -77,6 +77,8 @@ class BitStringType(Simple[BIT_STRING], BuiltinType):
77
77
  @classmethod
78
78
  def default(cls) -> Self:
79
79
  """Default value: all bits 0"""
80
+ if cls.named_bits:
81
+ return cls((0,) * len(cls.named_bits.bits))
80
82
  return cls(())
81
83
 
82
84
  @classmethod
@@ -1,6 +1,5 @@
1
1
  from dataclasses import dataclass
2
2
  from typing import ClassVar, Optional, Protocol, Any, Self, get_type_hints, override
3
- from StructResult.result import ValueOrError
4
3
  from .type import Type, TYPE_VALUE, OCTET_STRING
5
4
  from .integer_type import IntegerType
6
5
  from .bit_string import BitStringType
@@ -157,8 +156,8 @@ class ConstrainedType[T: Type](Type, Protocol):
157
156
  def parse(cls, value: Any) -> Self:
158
157
  return cls(cls.get_type().parse(value))
159
158
 
160
- # def normalize(self) -> TYPE_VALUE:
161
- # return self.value.normalize()
159
+ def normalize(self) -> TYPE_VALUE:
160
+ return self.value.normalize()
162
161
 
163
162
  @classmethod
164
163
  def default(cls) -> Self:
@@ -83,6 +83,11 @@ class EnumeratedType(Simple[INTEGER], BuiltinType):
83
83
  named_members: ClassVar[Optional[EnumerationList]] = None
84
84
  value: INTEGER
85
85
 
86
+ def __init_subclass__(cls) -> None:
87
+ if cls.named_members:
88
+ for member in cls.named_members:
89
+ setattr(cls, member.identifier, member.value)
90
+
86
91
  @classmethod
87
92
  def default(cls) -> Self:
88
93
  """Default value: first member in the list."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: COSEMpdu
3
- Version: 0.3.2
3
+ Version: 0.3.4
4
4
  Summary: cosem-pdu
5
5
  Author-email: Serj Kotilevski <youserj@outlook.com>
6
6
  Project-URL: Source, https://github.com/youserj/COSEMpdu_project
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes