hat.drivers.iec101

IEC 60870-5-101 communication protocol

  1"""IEC 60870-5-101 communication protocol"""
  2
  3from hat.drivers.iec101.common import (AsduTypeError,
  4                                       Address,
  5                                       AddressSize,
  6                                       CauseSize,
  7                                       AsduAddressSize,
  8                                       IoAddressSize,
  9                                       TimeSize,
 10                                       Time,
 11                                       OriginatorAddress,
 12                                       AsduAddress,
 13                                       IoAddress,
 14                                       IndicationQuality,
 15                                       MeasurementQuality,
 16                                       CounterQuality,
 17                                       ProtectionQuality,
 18                                       Quality,
 19                                       FreezeCode,
 20                                       SingleValue,
 21                                       DoubleValue,
 22                                       RegulatingValue,
 23                                       StepPositionValue,
 24                                       BitstringValue,
 25                                       NormalizedValue,
 26                                       ScaledValue,
 27                                       FloatingValue,
 28                                       BinaryCounterValue,
 29                                       ProtectionValue,
 30                                       ProtectionStartValue,
 31                                       ProtectionCommandValue,
 32                                       StatusValue,
 33                                       OtherCause,
 34                                       DataResCause,
 35                                       DataCause,
 36                                       CommandReqCause,
 37                                       CommandResCause,
 38                                       CommandCause,
 39                                       InitializationResCause,
 40                                       InitializationCause,
 41                                       ReadReqCause,
 42                                       ReadResCause,
 43                                       ReadCause,
 44                                       ClockSyncReqCause,
 45                                       ClockSyncResCause,
 46                                       ClockSyncCause,
 47                                       ActivationReqCause,
 48                                       ActivationResCause,
 49                                       ActivationCause,
 50                                       DelayReqCause,
 51                                       DelayResCause,
 52                                       DelayCause,
 53                                       ParameterReqCause,
 54                                       ParameterResCause,
 55                                       ParameterCause,
 56                                       ParameterActivationReqCause,
 57                                       ParameterActivationResCause,
 58                                       ParameterActivationCause,
 59                                       SingleData,
 60                                       DoubleData,
 61                                       StepPositionData,
 62                                       BitstringData,
 63                                       NormalizedData,
 64                                       ScaledData,
 65                                       FloatingData,
 66                                       BinaryCounterData,
 67                                       ProtectionData,
 68                                       ProtectionStartData,
 69                                       ProtectionCommandData,
 70                                       StatusData,
 71                                       Data,
 72                                       SingleCommand,
 73                                       DoubleCommand,
 74                                       RegulatingCommand,
 75                                       NormalizedCommand,
 76                                       ScaledCommand,
 77                                       FloatingCommand,
 78                                       BitstringCommand,
 79                                       Command,
 80                                       NormalizedParameter,
 81                                       ScaledParameter,
 82                                       FloatingParameter,
 83                                       Parameter,
 84                                       DataMsg,
 85                                       CommandMsg,
 86                                       InitializationMsg,
 87                                       InterrogationMsg,
 88                                       CounterInterrogationMsg,
 89                                       ReadMsg,
 90                                       ClockSyncMsg,
 91                                       TestMsg,
 92                                       ResetMsg,
 93                                       DelayMsg,
 94                                       ParameterMsg,
 95                                       ParameterActivationMsg,
 96                                       Msg,
 97                                       time_from_datetime,
 98                                       time_to_datetime)
 99from hat.drivers.iec101.connection import Connection
100
101
102__all__ = ['AsduTypeError',
103           'Address',
104           'AddressSize',
105           'CauseSize',
106           'AsduAddressSize',
107           'IoAddressSize',
108           'TimeSize',
109           'Time',
110           'OriginatorAddress',
111           'AsduAddress',
112           'IoAddress',
113           'IndicationQuality',
114           'MeasurementQuality',
115           'CounterQuality',
116           'ProtectionQuality',
117           'Quality',
118           'FreezeCode',
119           'SingleValue',
120           'DoubleValue',
121           'RegulatingValue',
122           'StepPositionValue',
123           'BitstringValue',
124           'NormalizedValue',
125           'ScaledValue',
126           'FloatingValue',
127           'BinaryCounterValue',
128           'ProtectionValue',
129           'ProtectionStartValue',
130           'ProtectionCommandValue',
131           'StatusValue',
132           'OtherCause',
133           'DataResCause',
134           'DataCause',
135           'CommandReqCause',
136           'CommandResCause',
137           'CommandCause',
138           'InitializationResCause',
139           'InitializationCause',
140           'ReadReqCause',
141           'ReadResCause',
142           'ReadCause',
143           'ClockSyncReqCause',
144           'ClockSyncResCause',
145           'ClockSyncCause',
146           'ActivationReqCause',
147           'ActivationResCause',
148           'ActivationCause',
149           'DelayReqCause',
150           'DelayResCause',
151           'DelayCause',
152           'ParameterReqCause',
153           'ParameterResCause',
154           'ParameterCause',
155           'ParameterActivationReqCause',
156           'ParameterActivationResCause',
157           'ParameterActivationCause',
158           'SingleData',
159           'DoubleData',
160           'StepPositionData',
161           'BitstringData',
162           'NormalizedData',
163           'ScaledData',
164           'FloatingData',
165           'BinaryCounterData',
166           'ProtectionData',
167           'ProtectionStartData',
168           'ProtectionCommandData',
169           'StatusData',
170           'Data',
171           'SingleCommand',
172           'DoubleCommand',
173           'RegulatingCommand',
174           'NormalizedCommand',
175           'ScaledCommand',
176           'FloatingCommand',
177           'BitstringCommand',
178           'Command',
179           'NormalizedParameter',
180           'ScaledParameter',
181           'FloatingParameter',
182           'Parameter',
183           'DataMsg',
184           'CommandMsg',
185           'InitializationMsg',
186           'InterrogationMsg',
187           'CounterInterrogationMsg',
188           'ReadMsg',
189           'ClockSyncMsg',
190           'TestMsg',
191           'ResetMsg',
192           'DelayMsg',
193           'ParameterMsg',
194           'ParameterActivationMsg',
195           'Msg',
196           'time_from_datetime',
197           'time_to_datetime',
198           'Connection']
class AsduTypeError(builtins.Exception):
8class AsduTypeError(Exception):
9    pass

Common base class for all non-exit exceptions.

Address = <class 'int'>
class AddressSize(enum.Enum):
16class AddressSize(enum.Enum):
17    ZERO = 0
18    ONE = 1
19    TWO = 2
ZERO = <AddressSize.ZERO: 0>
ONE = <AddressSize.ONE: 1>
TWO = <AddressSize.TWO: 2>
class CauseSize(enum.Enum):
12class CauseSize(enum.Enum):
13    ONE = 1
14    TWO = 2
ONE = <CauseSize.ONE: 1>
TWO = <CauseSize.TWO: 2>
class AsduAddressSize(enum.Enum):
17class AsduAddressSize(enum.Enum):
18    ONE = 1
19    TWO = 2
ONE = <AsduAddressSize.ONE: 1>
TWO = <AsduAddressSize.TWO: 2>
class IoAddressSize(enum.Enum):
22class IoAddressSize(enum.Enum):
23    ONE = 1
24    TWO = 2
25    THREE = 3
ONE = <IoAddressSize.ONE: 1>
TWO = <IoAddressSize.TWO: 2>
THREE = <IoAddressSize.THREE: 3>
class TimeSize(enum.Enum):
28class TimeSize(enum.Enum):
29    TWO = 2
30    THREE = 3
31    FOUR = 4
32    SEVEN = 7
TWO = <TimeSize.TWO: 2>
THREE = <TimeSize.THREE: 3>
FOUR = <TimeSize.FOUR: 4>
SEVEN = <TimeSize.SEVEN: 7>
class Time(typing.NamedTuple):
35class Time(typing.NamedTuple):
36    size: TimeSize
37    milliseconds: int
38    """milliseconds in range [0, 59999]"""
39    invalid: bool | None
40    """available for size THREE, FOUR, SEVEN"""
41    minutes: int | None
42    """available for size THREE, FOUR, SEVEN (minutes in range [0, 59])"""
43    summer_time: bool | None
44    """available for size FOUR, SEVEN"""
45    hours: int | None
46    """available for size FOUR, SEVEN (hours in range [0, 23])"""
47    day_of_week: int | None
48    """available for size SEVEN (day_of_week in range [1, 7])"""
49    day_of_month: int | None
50    """available for size SEVEN (day_of_month in range [1, 31])"""
51    months: int | None
52    """available for size SEVEN (months in range [1, 12])"""
53    years: int | None
54    """available for size SEVEN (years in range [0, 99])"""

Time(size, milliseconds, invalid, minutes, summer_time, hours, day_of_week, day_of_month, months, years)

Time( size: TimeSize, milliseconds: int, invalid: bool | None, minutes: int | None, summer_time: bool | None, hours: int | None, day_of_week: int | None, day_of_month: int | None, months: int | None, years: int | None)

Create new instance of Time(size, milliseconds, invalid, minutes, summer_time, hours, day_of_week, day_of_month, months, years)

size: TimeSize

Alias for field number 0

milliseconds: int

milliseconds in range [0, 59999]

invalid: bool | None

available for size THREE, FOUR, SEVEN

minutes: int | None

available for size THREE, FOUR, SEVEN (minutes in range [0, 59])

summer_time: bool | None

available for size FOUR, SEVEN

hours: int | None

available for size FOUR, SEVEN (hours in range [0, 23])

day_of_week: int | None

available for size SEVEN (day_of_week in range [1, 7])

day_of_month: int | None

available for size SEVEN (day_of_month in range [1, 31])

months: int | None

available for size SEVEN (months in range [1, 12])

years: int | None

available for size SEVEN (years in range [0, 99])

OriginatorAddress = <class 'int'>
AsduAddress = <class 'int'>
IoAddress = <class 'int'>
class IndicationQuality(typing.NamedTuple):
143class IndicationQuality(typing.NamedTuple):
144    invalid: bool
145    not_topical: bool
146    substituted: bool
147    blocked: bool

IndicationQuality(invalid, not_topical, substituted, blocked)

IndicationQuality(invalid: bool, not_topical: bool, substituted: bool, blocked: bool)

Create new instance of IndicationQuality(invalid, not_topical, substituted, blocked)

invalid: bool

Alias for field number 0

not_topical: bool

Alias for field number 1

substituted: bool

Alias for field number 2

blocked: bool

Alias for field number 3

class MeasurementQuality(typing.NamedTuple):
150class MeasurementQuality(typing.NamedTuple):
151    invalid: bool
152    not_topical: bool
153    substituted: bool
154    blocked: bool
155    overflow: bool

MeasurementQuality(invalid, not_topical, substituted, blocked, overflow)

MeasurementQuality( invalid: bool, not_topical: bool, substituted: bool, blocked: bool, overflow: bool)

Create new instance of MeasurementQuality(invalid, not_topical, substituted, blocked, overflow)

invalid: bool

Alias for field number 0

not_topical: bool

Alias for field number 1

substituted: bool

Alias for field number 2

blocked: bool

Alias for field number 3

overflow: bool

Alias for field number 4

class CounterQuality(typing.NamedTuple):
158class CounterQuality(typing.NamedTuple):
159    invalid: bool
160    adjusted: bool
161    overflow: bool
162    sequence: int
163    """sequence in range [0, 31]"""

CounterQuality(invalid, adjusted, overflow, sequence)

CounterQuality(invalid: bool, adjusted: bool, overflow: bool, sequence: int)

Create new instance of CounterQuality(invalid, adjusted, overflow, sequence)

invalid: bool

Alias for field number 0

adjusted: bool

Alias for field number 1

overflow: bool

Alias for field number 2

sequence: int

sequence in range [0, 31]

class ProtectionQuality(typing.NamedTuple):
166class ProtectionQuality(typing.NamedTuple):
167    invalid: bool
168    not_topical: bool
169    substituted: bool
170    blocked: bool
171    time_invalid: bool

ProtectionQuality(invalid, not_topical, substituted, blocked, time_invalid)

ProtectionQuality( invalid: bool, not_topical: bool, substituted: bool, blocked: bool, time_invalid: bool)

Create new instance of ProtectionQuality(invalid, not_topical, substituted, blocked, time_invalid)

invalid: bool

Alias for field number 0

not_topical: bool

Alias for field number 1

substituted: bool

Alias for field number 2

blocked: bool

Alias for field number 3

time_invalid: bool

Alias for field number 4

class FreezeCode(enum.Enum):
180class FreezeCode(enum.Enum):
181    READ = 0
182    FREEZE = 1
183    FREEZE_AND_RESET = 2
184    RESET = 3
READ = <FreezeCode.READ: 0>
FREEZE = <FreezeCode.FREEZE: 1>
FREEZE_AND_RESET = <FreezeCode.FREEZE_AND_RESET: 2>
RESET = <FreezeCode.RESET: 3>
class SingleValue(enum.Enum):
187class SingleValue(enum.Enum):
188    OFF = 0
189    ON = 1
OFF = <SingleValue.OFF: 0>
ON = <SingleValue.ON: 1>
class DoubleValue(enum.Enum):
192class DoubleValue(enum.Enum):
193    """DoubleDataValue
194
195    `FAULT` stands for value 3, defined in the protocol as *INDETERMINATE*.
196    This is in order to make it more distinguishable from ``INTERMEDIATE``.
197
198    """
199    INTERMEDIATE = 0
200    OFF = 1
201    ON = 2
202    FAULT = 3

DoubleDataValue

FAULT stands for value 3, defined in the protocol as INDETERMINATE. This is in order to make it more distinguishable from INTERMEDIATE.

INTERMEDIATE = <DoubleValue.INTERMEDIATE: 0>
OFF = <DoubleValue.OFF: 1>
ON = <DoubleValue.ON: 2>
FAULT = <DoubleValue.FAULT: 3>
class RegulatingValue(enum.Enum):
205class RegulatingValue(enum.Enum):
206    LOWER = 1
207    HIGHER = 2
LOWER = <RegulatingValue.LOWER: 1>
HIGHER = <RegulatingValue.HIGHER: 2>
class StepPositionValue(typing.NamedTuple):
210class StepPositionValue(typing.NamedTuple):
211    value: int
212    """value in range [-64, 63]"""
213    transient: bool

StepPositionValue(value, transient)

StepPositionValue(value: int, transient: bool)

Create new instance of StepPositionValue(value, transient)

value: int

value in range [-64, 63]

transient: bool

Alias for field number 1

class BitstringValue(typing.NamedTuple):
216class BitstringValue(typing.NamedTuple):
217    value: util.Bytes
218    """bitstring encoded as 4 bytes"""

BitstringValue(value,)

BitstringValue(value: bytes | bytearray | memoryview)

Create new instance of BitstringValue(value,)

value: bytes | bytearray | memoryview

bitstring encoded as 4 bytes

class NormalizedValue(typing.NamedTuple):
221class NormalizedValue(typing.NamedTuple):
222    value: float
223    """value in range [-1.0, 1.0)"""

NormalizedValue(value,)

NormalizedValue(value: float)

Create new instance of NormalizedValue(value,)

value: float

value in range [-1.0, 1.0)

class ScaledValue(typing.NamedTuple):
226class ScaledValue(typing.NamedTuple):
227    value: int
228    """value in range [-2^15, 2^15-1]"""

ScaledValue(value,)

ScaledValue(value: int)

Create new instance of ScaledValue(value,)

value: int

value in range [-2^15, 2^15-1]

class FloatingValue(typing.NamedTuple):
231class FloatingValue(typing.NamedTuple):
232    value: float

FloatingValue(value,)

FloatingValue(value: float)

Create new instance of FloatingValue(value,)

value: float

Alias for field number 0

class BinaryCounterValue(typing.NamedTuple):
235class BinaryCounterValue(typing.NamedTuple):
236    value: int
237    """value in range [-2^31, 2^31-1]"""

BinaryCounterValue(value,)

BinaryCounterValue(value: int)

Create new instance of BinaryCounterValue(value,)

value: int

value in range [-2^31, 2^31-1]

class ProtectionValue(enum.Enum):
240class ProtectionValue(enum.Enum):
241    OFF = 1
242    ON = 2
OFF = <ProtectionValue.OFF: 1>
ON = <ProtectionValue.ON: 2>
class ProtectionStartValue(typing.NamedTuple):
245class ProtectionStartValue(typing.NamedTuple):
246    general: bool
247    l1: bool
248    l2: bool
249    l3: bool
250    ie: bool
251    reverse: bool

ProtectionStartValue(general, l1, l2, l3, ie, reverse)

ProtectionStartValue(general: bool, l1: bool, l2: bool, l3: bool, ie: bool, reverse: bool)

Create new instance of ProtectionStartValue(general, l1, l2, l3, ie, reverse)

general: bool

Alias for field number 0

l1: bool

Alias for field number 1

l2: bool

Alias for field number 2

l3: bool

Alias for field number 3

ie: bool

Alias for field number 4

reverse: bool

Alias for field number 5

class ProtectionCommandValue(typing.NamedTuple):
254class ProtectionCommandValue(typing.NamedTuple):
255    general: bool
256    l1: bool
257    l2: bool
258    l3: bool

ProtectionCommandValue(general, l1, l2, l3)

ProtectionCommandValue(general: bool, l1: bool, l2: bool, l3: bool)

Create new instance of ProtectionCommandValue(general, l1, l2, l3)

general: bool

Alias for field number 0

l1: bool

Alias for field number 1

l2: bool

Alias for field number 2

l3: bool

Alias for field number 3

class StatusValue(typing.NamedTuple):
261class StatusValue(typing.NamedTuple):
262    value: list[bool]
263    """value length is 16"""
264    change: list[bool]
265    """change length is 16"""

StatusValue(value, change)

StatusValue(value: list[bool], change: list[bool])

Create new instance of StatusValue(value, change)

value: list[bool]

value length is 16

change: list[bool]

change length is 16

OtherCause = <class 'int'>
class DataResCause(enum.Enum):
52class DataResCause(enum.Enum):
53    PERIODIC = iec101.CauseType.PERIODIC.value
54    BACKGROUND_SCAN = iec101.CauseType.BACKGROUND_SCAN.value
55    SPONTANEOUS = iec101.CauseType.SPONTANEOUS.value
56    REQUEST = iec101.CauseType.REQUEST.value
57    REMOTE_COMMAND = iec101.CauseType.REMOTE_COMMAND.value
58    LOCAL_COMMAND = iec101.CauseType.LOCAL_COMMAND.value
59    INTERROGATED_STATION = iec101.CauseType.INTERROGATED_STATION.value
60    INTERROGATED_GROUP01 = iec101.CauseType.INTERROGATED_GROUP01.value
61    INTERROGATED_GROUP02 = iec101.CauseType.INTERROGATED_GROUP02.value
62    INTERROGATED_GROUP03 = iec101.CauseType.INTERROGATED_GROUP03.value
63    INTERROGATED_GROUP04 = iec101.CauseType.INTERROGATED_GROUP04.value
64    INTERROGATED_GROUP05 = iec101.CauseType.INTERROGATED_GROUP05.value
65    INTERROGATED_GROUP06 = iec101.CauseType.INTERROGATED_GROUP06.value
66    INTERROGATED_GROUP07 = iec101.CauseType.INTERROGATED_GROUP07.value
67    INTERROGATED_GROUP08 = iec101.CauseType.INTERROGATED_GROUP08.value
68    INTERROGATED_GROUP09 = iec101.CauseType.INTERROGATED_GROUP09.value
69    INTERROGATED_GROUP10 = iec101.CauseType.INTERROGATED_GROUP10.value
70    INTERROGATED_GROUP11 = iec101.CauseType.INTERROGATED_GROUP11.value
71    INTERROGATED_GROUP12 = iec101.CauseType.INTERROGATED_GROUP12.value
72    INTERROGATED_GROUP13 = iec101.CauseType.INTERROGATED_GROUP13.value
73    INTERROGATED_GROUP14 = iec101.CauseType.INTERROGATED_GROUP14.value
74    INTERROGATED_GROUP15 = iec101.CauseType.INTERROGATED_GROUP15.value
75    INTERROGATED_GROUP16 = iec101.CauseType.INTERROGATED_GROUP16.value
76    INTERROGATED_COUNTER = iec101.CauseType.INTERROGATED_COUNTER.value
77    INTERROGATED_COUNTER01 = iec101.CauseType.INTERROGATED_COUNTER01.value
78    INTERROGATED_COUNTER02 = iec101.CauseType.INTERROGATED_COUNTER02.value
79    INTERROGATED_COUNTER03 = iec101.CauseType.INTERROGATED_COUNTER03.value
80    INTERROGATED_COUNTER04 = iec101.CauseType.INTERROGATED_COUNTER04.value
PERIODIC = <DataResCause.PERIODIC: 1>
BACKGROUND_SCAN = <DataResCause.BACKGROUND_SCAN: 2>
SPONTANEOUS = <DataResCause.SPONTANEOUS: 3>
REQUEST = <DataResCause.REQUEST: 5>
REMOTE_COMMAND = <DataResCause.REMOTE_COMMAND: 11>
LOCAL_COMMAND = <DataResCause.LOCAL_COMMAND: 12>
INTERROGATED_STATION = <DataResCause.INTERROGATED_STATION: 20>
INTERROGATED_GROUP01 = <DataResCause.INTERROGATED_GROUP01: 21>
INTERROGATED_GROUP02 = <DataResCause.INTERROGATED_GROUP02: 22>
INTERROGATED_GROUP03 = <DataResCause.INTERROGATED_GROUP03: 23>
INTERROGATED_GROUP04 = <DataResCause.INTERROGATED_GROUP04: 24>
INTERROGATED_GROUP05 = <DataResCause.INTERROGATED_GROUP05: 25>
INTERROGATED_GROUP06 = <DataResCause.INTERROGATED_GROUP06: 26>
INTERROGATED_GROUP07 = <DataResCause.INTERROGATED_GROUP07: 27>
INTERROGATED_GROUP08 = <DataResCause.INTERROGATED_GROUP08: 28>
INTERROGATED_GROUP09 = <DataResCause.INTERROGATED_GROUP09: 29>
INTERROGATED_GROUP10 = <DataResCause.INTERROGATED_GROUP10: 30>
INTERROGATED_GROUP11 = <DataResCause.INTERROGATED_GROUP11: 31>
INTERROGATED_GROUP12 = <DataResCause.INTERROGATED_GROUP12: 32>
INTERROGATED_GROUP13 = <DataResCause.INTERROGATED_GROUP13: 33>
INTERROGATED_GROUP14 = <DataResCause.INTERROGATED_GROUP14: 34>
INTERROGATED_GROUP15 = <DataResCause.INTERROGATED_GROUP15: 35>
INTERROGATED_GROUP16 = <DataResCause.INTERROGATED_GROUP16: 36>
INTERROGATED_COUNTER = <DataResCause.INTERROGATED_COUNTER: 37>
INTERROGATED_COUNTER01 = <DataResCause.INTERROGATED_COUNTER01: 38>
INTERROGATED_COUNTER02 = <DataResCause.INTERROGATED_COUNTER02: 39>
INTERROGATED_COUNTER03 = <DataResCause.INTERROGATED_COUNTER03: 40>
INTERROGATED_COUNTER04 = <DataResCause.INTERROGATED_COUNTER04: 41>
DataCause = DataResCause | int
class CommandReqCause(enum.Enum):
86class CommandReqCause(enum.Enum):
87    ACTIVATION = iec101.CauseType.ACTIVATION.value
88    DEACTIVATION = iec101.CauseType.DEACTIVATION.value
ACTIVATION = <CommandReqCause.ACTIVATION: 6>
DEACTIVATION = <CommandReqCause.DEACTIVATION: 8>
class CommandResCause(enum.Enum):
91class CommandResCause(enum.Enum):
92    ACTIVATION_CONFIRMATION = iec101.CauseType.ACTIVATION_CONFIRMATION.value
93    DEACTIVATION_CONFIRMATION = iec101.CauseType.DEACTIVATION_CONFIRMATION.value  # NOQA
94    ACTIVATION_TERMINATION = iec101.CauseType.ACTIVATION_TERMINATION.value
95    UNKNOWN_TYPE = iec101.CauseType.UNKNOWN_TYPE.value
96    UNKNOWN_CAUSE = iec101.CauseType.UNKNOWN_CAUSE.value
97    UNKNOWN_ASDU_ADDRESS = iec101.CauseType.UNKNOWN_ASDU_ADDRESS.value
98    UNKNOWN_IO_ADDRESS = iec101.CauseType.UNKNOWN_IO_ADDRESS.value
ACTIVATION_CONFIRMATION = <CommandResCause.ACTIVATION_CONFIRMATION: 7>
DEACTIVATION_CONFIRMATION = <CommandResCause.DEACTIVATION_CONFIRMATION: 9>
ACTIVATION_TERMINATION = <CommandResCause.ACTIVATION_TERMINATION: 10>
UNKNOWN_TYPE = <CommandResCause.UNKNOWN_TYPE: 44>
UNKNOWN_CAUSE = <CommandResCause.UNKNOWN_CAUSE: 45>
UNKNOWN_ASDU_ADDRESS = <CommandResCause.UNKNOWN_ASDU_ADDRESS: 46>
UNKNOWN_IO_ADDRESS = <CommandResCause.UNKNOWN_IO_ADDRESS: 47>
CommandCause = CommandReqCause | CommandResCause | int
class InitializationResCause(enum.Enum):
104class InitializationResCause(enum.Enum):
105    LOCAL_POWER = 0
106    LOCAL_RESET = 1
107    REMOTE_RESET = 2
InitializationCause = InitializationResCause | int
class ReadReqCause(enum.Enum):
113class ReadReqCause(enum.Enum):
114    REQUEST = iec101.CauseType.REQUEST.value
REQUEST = <ReadReqCause.REQUEST: 5>
class ReadResCause(enum.Enum):
117class ReadResCause(enum.Enum):
118    UNKNOWN_TYPE = iec101.CauseType.UNKNOWN_TYPE.value
119    UNKNOWN_CAUSE = iec101.CauseType.UNKNOWN_CAUSE.value
120    UNKNOWN_ASDU_ADDRESS = iec101.CauseType.UNKNOWN_ASDU_ADDRESS.value
121    UNKNOWN_IO_ADDRESS = iec101.CauseType.UNKNOWN_IO_ADDRESS.value
UNKNOWN_TYPE = <ReadResCause.UNKNOWN_TYPE: 44>
UNKNOWN_CAUSE = <ReadResCause.UNKNOWN_CAUSE: 45>
UNKNOWN_ASDU_ADDRESS = <ReadResCause.UNKNOWN_ASDU_ADDRESS: 46>
UNKNOWN_IO_ADDRESS = <ReadResCause.UNKNOWN_IO_ADDRESS: 47>
ReadCause = ReadReqCause | ReadResCause | int
class ClockSyncReqCause(enum.Enum):
127class ClockSyncReqCause(enum.Enum):
128    ACTIVATION = iec101.CauseType.ACTIVATION.value
ACTIVATION = <ClockSyncReqCause.ACTIVATION: 6>
class ClockSyncResCause(enum.Enum):
131class ClockSyncResCause(enum.Enum):
132    SPONTANEOUS = iec101.CauseType.SPONTANEOUS.value
133    ACTIVATION_CONFIRMATION = iec101.CauseType.ACTIVATION_CONFIRMATION.value
134    UNKNOWN_TYPE = iec101.CauseType.UNKNOWN_TYPE.value
135    UNKNOWN_CAUSE = iec101.CauseType.UNKNOWN_CAUSE.value
136    UNKNOWN_ASDU_ADDRESS = iec101.CauseType.UNKNOWN_ASDU_ADDRESS.value
137    UNKNOWN_IO_ADDRESS = iec101.CauseType.UNKNOWN_IO_ADDRESS.value
SPONTANEOUS = <ClockSyncResCause.SPONTANEOUS: 3>
ACTIVATION_CONFIRMATION = <ClockSyncResCause.ACTIVATION_CONFIRMATION: 7>
UNKNOWN_TYPE = <ClockSyncResCause.UNKNOWN_TYPE: 44>
UNKNOWN_CAUSE = <ClockSyncResCause.UNKNOWN_CAUSE: 45>
UNKNOWN_ASDU_ADDRESS = <ClockSyncResCause.UNKNOWN_ASDU_ADDRESS: 46>
UNKNOWN_IO_ADDRESS = <ClockSyncResCause.UNKNOWN_IO_ADDRESS: 47>
ClockSyncCause = ClockSyncReqCause | ClockSyncResCause | int
class ActivationReqCause(enum.Enum):
145class ActivationReqCause(enum.Enum):
146    ACTIVATION = iec101.CauseType.ACTIVATION.value
ACTIVATION = <ActivationReqCause.ACTIVATION: 6>
class ActivationResCause(enum.Enum):
149class ActivationResCause(enum.Enum):
150    ACTIVATION_CONFIRMATION = iec101.CauseType.ACTIVATION_CONFIRMATION.value
151    UNKNOWN_TYPE = iec101.CauseType.UNKNOWN_TYPE.value
152    UNKNOWN_CAUSE = iec101.CauseType.UNKNOWN_CAUSE.value
153    UNKNOWN_ASDU_ADDRESS = iec101.CauseType.UNKNOWN_ASDU_ADDRESS.value
154    UNKNOWN_IO_ADDRESS = iec101.CauseType.UNKNOWN_IO_ADDRESS.value
ACTIVATION_CONFIRMATION = <ActivationResCause.ACTIVATION_CONFIRMATION: 7>
UNKNOWN_TYPE = <ActivationResCause.UNKNOWN_TYPE: 44>
UNKNOWN_CAUSE = <ActivationResCause.UNKNOWN_CAUSE: 45>
UNKNOWN_ASDU_ADDRESS = <ActivationResCause.UNKNOWN_ASDU_ADDRESS: 46>
UNKNOWN_IO_ADDRESS = <ActivationResCause.UNKNOWN_IO_ADDRESS: 47>
ActivationCause = ActivationReqCause | ActivationResCause | int
class DelayReqCause(enum.Enum):
162class DelayReqCause(enum.Enum):
163    SPONTANEOUS = iec101.CauseType.SPONTANEOUS.value
164    ACTIVATION = iec101.CauseType.ACTIVATION.value
SPONTANEOUS = <DelayReqCause.SPONTANEOUS: 3>
ACTIVATION = <DelayReqCause.ACTIVATION: 6>
class DelayResCause(enum.Enum):
167class DelayResCause(enum.Enum):
168    ACTIVATION_CONFIRMATION = iec101.CauseType.ACTIVATION_CONFIRMATION.value
169    UNKNOWN_TYPE = iec101.CauseType.UNKNOWN_TYPE.value
170    UNKNOWN_CAUSE = iec101.CauseType.UNKNOWN_CAUSE.value
171    UNKNOWN_ASDU_ADDRESS = iec101.CauseType.UNKNOWN_ASDU_ADDRESS.value
172    UNKNOWN_IO_ADDRESS = iec101.CauseType.UNKNOWN_IO_ADDRESS.value
ACTIVATION_CONFIRMATION = <DelayResCause.ACTIVATION_CONFIRMATION: 7>
UNKNOWN_TYPE = <DelayResCause.UNKNOWN_TYPE: 44>
UNKNOWN_CAUSE = <DelayResCause.UNKNOWN_CAUSE: 45>
UNKNOWN_ASDU_ADDRESS = <DelayResCause.UNKNOWN_ASDU_ADDRESS: 46>
UNKNOWN_IO_ADDRESS = <DelayResCause.UNKNOWN_IO_ADDRESS: 47>
DelayCause = DelayReqCause | DelayResCause | int
class ParameterReqCause(enum.Enum):
178class ParameterReqCause(enum.Enum):
179    SPONTANEOUS = iec101.CauseType.SPONTANEOUS.value
180    ACTIVATION = iec101.CauseType.ACTIVATION.value
SPONTANEOUS = <ParameterReqCause.SPONTANEOUS: 3>
ACTIVATION = <ParameterReqCause.ACTIVATION: 6>
class ParameterResCause(enum.Enum):
183class ParameterResCause(enum.Enum):
184    ACTIVATION_CONFIRMATION = iec101.CauseType.ACTIVATION_CONFIRMATION.value
185    INTERROGATED_STATION = iec101.CauseType.INTERROGATED_STATION.value
186    INTERROGATED_GROUP01 = iec101.CauseType.INTERROGATED_GROUP01.value
187    INTERROGATED_GROUP02 = iec101.CauseType.INTERROGATED_GROUP02.value
188    INTERROGATED_GROUP03 = iec101.CauseType.INTERROGATED_GROUP03.value
189    INTERROGATED_GROUP04 = iec101.CauseType.INTERROGATED_GROUP04.value
190    INTERROGATED_GROUP05 = iec101.CauseType.INTERROGATED_GROUP05.value
191    INTERROGATED_GROUP06 = iec101.CauseType.INTERROGATED_GROUP06.value
192    INTERROGATED_GROUP07 = iec101.CauseType.INTERROGATED_GROUP07.value
193    INTERROGATED_GROUP08 = iec101.CauseType.INTERROGATED_GROUP08.value
194    INTERROGATED_GROUP09 = iec101.CauseType.INTERROGATED_GROUP09.value
195    INTERROGATED_GROUP10 = iec101.CauseType.INTERROGATED_GROUP10.value
196    INTERROGATED_GROUP11 = iec101.CauseType.INTERROGATED_GROUP11.value
197    INTERROGATED_GROUP12 = iec101.CauseType.INTERROGATED_GROUP12.value
198    INTERROGATED_GROUP13 = iec101.CauseType.INTERROGATED_GROUP13.value
199    INTERROGATED_GROUP14 = iec101.CauseType.INTERROGATED_GROUP14.value
200    INTERROGATED_GROUP15 = iec101.CauseType.INTERROGATED_GROUP15.value
201    INTERROGATED_GROUP16 = iec101.CauseType.INTERROGATED_GROUP16.value
202    UNKNOWN_TYPE = iec101.CauseType.UNKNOWN_TYPE.value
203    UNKNOWN_CAUSE = iec101.CauseType.UNKNOWN_CAUSE.value
204    UNKNOWN_ASDU_ADDRESS = iec101.CauseType.UNKNOWN_ASDU_ADDRESS.value
205    UNKNOWN_IO_ADDRESS = iec101.CauseType.UNKNOWN_IO_ADDRESS.value
ACTIVATION_CONFIRMATION = <ParameterResCause.ACTIVATION_CONFIRMATION: 7>
INTERROGATED_STATION = <ParameterResCause.INTERROGATED_STATION: 20>
INTERROGATED_GROUP01 = <ParameterResCause.INTERROGATED_GROUP01: 21>
INTERROGATED_GROUP02 = <ParameterResCause.INTERROGATED_GROUP02: 22>
INTERROGATED_GROUP03 = <ParameterResCause.INTERROGATED_GROUP03: 23>
INTERROGATED_GROUP04 = <ParameterResCause.INTERROGATED_GROUP04: 24>
INTERROGATED_GROUP05 = <ParameterResCause.INTERROGATED_GROUP05: 25>
INTERROGATED_GROUP06 = <ParameterResCause.INTERROGATED_GROUP06: 26>
INTERROGATED_GROUP07 = <ParameterResCause.INTERROGATED_GROUP07: 27>
INTERROGATED_GROUP08 = <ParameterResCause.INTERROGATED_GROUP08: 28>
INTERROGATED_GROUP09 = <ParameterResCause.INTERROGATED_GROUP09: 29>
INTERROGATED_GROUP10 = <ParameterResCause.INTERROGATED_GROUP10: 30>
INTERROGATED_GROUP11 = <ParameterResCause.INTERROGATED_GROUP11: 31>
INTERROGATED_GROUP12 = <ParameterResCause.INTERROGATED_GROUP12: 32>
INTERROGATED_GROUP13 = <ParameterResCause.INTERROGATED_GROUP13: 33>
INTERROGATED_GROUP14 = <ParameterResCause.INTERROGATED_GROUP14: 34>
INTERROGATED_GROUP15 = <ParameterResCause.INTERROGATED_GROUP15: 35>
INTERROGATED_GROUP16 = <ParameterResCause.INTERROGATED_GROUP16: 36>
UNKNOWN_TYPE = <ParameterResCause.UNKNOWN_TYPE: 44>
UNKNOWN_CAUSE = <ParameterResCause.UNKNOWN_CAUSE: 45>
UNKNOWN_ASDU_ADDRESS = <ParameterResCause.UNKNOWN_ASDU_ADDRESS: 46>
UNKNOWN_IO_ADDRESS = <ParameterResCause.UNKNOWN_IO_ADDRESS: 47>
ParameterCause = ParameterReqCause | ParameterResCause | int
class ParameterActivationReqCause(enum.Enum):
213class ParameterActivationReqCause(enum.Enum):
214    ACTIVATION = iec101.CauseType.ACTIVATION.value
215    DEACTIVATION = iec101.CauseType.DEACTIVATION.value
class ParameterActivationResCause(enum.Enum):
218class ParameterActivationResCause(enum.Enum):
219    ACTIVATION_CONFIRMATION = iec101.CauseType.ACTIVATION_CONFIRMATION.value
220    DEACTIVATION_CONFIRMATION = iec101.CauseType.DEACTIVATION_CONFIRMATION.value  # NOQA
221    UNKNOWN_TYPE = iec101.CauseType.UNKNOWN_TYPE.value
222    UNKNOWN_CAUSE = iec101.CauseType.UNKNOWN_CAUSE.value
223    UNKNOWN_ASDU_ADDRESS = iec101.CauseType.UNKNOWN_ASDU_ADDRESS.value
224    UNKNOWN_IO_ADDRESS = iec101.CauseType.UNKNOWN_IO_ADDRESS.value
ParameterActivationCause = ParameterActivationReqCause | ParameterActivationResCause | int
class SingleData(typing.NamedTuple):
232class SingleData(typing.NamedTuple):
233    value: SingleValue
234    quality: IndicationQuality

SingleData(value, quality)

SingleData( value: SingleValue, quality: IndicationQuality)

Create new instance of SingleData(value, quality)

value: SingleValue

Alias for field number 0

Alias for field number 1

class DoubleData(typing.NamedTuple):
237class DoubleData(typing.NamedTuple):
238    value: DoubleValue
239    quality: IndicationQuality

DoubleData(value, quality)

DoubleData( value: DoubleValue, quality: IndicationQuality)

Create new instance of DoubleData(value, quality)

value: DoubleValue

Alias for field number 0

Alias for field number 1

class StepPositionData(typing.NamedTuple):
242class StepPositionData(typing.NamedTuple):
243    value: StepPositionValue
244    quality: MeasurementQuality

StepPositionData(value, quality)

StepPositionData( value: StepPositionValue, quality: MeasurementQuality)

Create new instance of StepPositionData(value, quality)

Alias for field number 0

Alias for field number 1

class BitstringData(typing.NamedTuple):
247class BitstringData(typing.NamedTuple):
248    value: BitstringValue
249    quality: MeasurementQuality

BitstringData(value, quality)

BitstringData( value: BitstringValue, quality: MeasurementQuality)

Create new instance of BitstringData(value, quality)

Alias for field number 0

Alias for field number 1

class NormalizedData(typing.NamedTuple):
252class NormalizedData(typing.NamedTuple):
253    value: NormalizedValue
254    quality: MeasurementQuality | None

NormalizedData(value, quality)

NormalizedData( value: NormalizedValue, quality: MeasurementQuality | None)

Create new instance of NormalizedData(value, quality)

Alias for field number 0

quality: MeasurementQuality | None

Alias for field number 1

class ScaledData(typing.NamedTuple):
257class ScaledData(typing.NamedTuple):
258    value: ScaledValue
259    quality: MeasurementQuality

ScaledData(value, quality)

ScaledData( value: ScaledValue, quality: MeasurementQuality)

Create new instance of ScaledData(value, quality)

value: ScaledValue

Alias for field number 0

Alias for field number 1

class FloatingData(typing.NamedTuple):
262class FloatingData(typing.NamedTuple):
263    value: FloatingValue
264    quality: MeasurementQuality

FloatingData(value, quality)

FloatingData( value: FloatingValue, quality: MeasurementQuality)

Create new instance of FloatingData(value, quality)

value: FloatingValue

Alias for field number 0

Alias for field number 1

class BinaryCounterData(typing.NamedTuple):
267class BinaryCounterData(typing.NamedTuple):
268    value: BinaryCounterValue
269    quality: CounterQuality

BinaryCounterData(value, quality)

BinaryCounterData( value: BinaryCounterValue, quality: CounterQuality)

Create new instance of BinaryCounterData(value, quality)

Alias for field number 0

quality: CounterQuality

Alias for field number 1

class ProtectionData(typing.NamedTuple):
272class ProtectionData(typing.NamedTuple):
273    value: ProtectionValue
274    quality: ProtectionQuality
275    elapsed_time: int
276    """elapsed_time in range [0, 65535]"""

ProtectionData(value, quality, elapsed_time)

ProtectionData( value: ProtectionValue, quality: ProtectionQuality, elapsed_time: int)

Create new instance of ProtectionData(value, quality, elapsed_time)

Alias for field number 0

Alias for field number 1

elapsed_time: int

elapsed_time in range [0, 65535]

class ProtectionStartData(typing.NamedTuple):
279class ProtectionStartData(typing.NamedTuple):
280    value: ProtectionStartValue
281    quality: ProtectionQuality
282    duration_time: int
283    """duration_time in range [0, 65535]"""

ProtectionStartData(value, quality, duration_time)

ProtectionStartData( value: ProtectionStartValue, quality: ProtectionQuality, duration_time: int)

Create new instance of ProtectionStartData(value, quality, duration_time)

Alias for field number 0

Alias for field number 1

duration_time: int

duration_time in range [0, 65535]

class ProtectionCommandData(typing.NamedTuple):
286class ProtectionCommandData(typing.NamedTuple):
287    value: ProtectionCommandValue
288    quality: ProtectionQuality
289    operating_time: int
290    """operating_time in range [0, 65535]"""

ProtectionCommandData(value, quality, operating_time)

ProtectionCommandData( value: ProtectionCommandValue, quality: ProtectionQuality, operating_time: int)

Create new instance of ProtectionCommandData(value, quality, operating_time)

Alias for field number 0

Alias for field number 1

operating_time: int

operating_time in range [0, 65535]

class StatusData(typing.NamedTuple):
293class StatusData(typing.NamedTuple):
294    value: StatusValue
295    quality: MeasurementQuality

StatusData(value, quality)

StatusData( value: StatusValue, quality: MeasurementQuality)

Create new instance of StatusData(value, quality)

value: StatusValue

Alias for field number 0

Alias for field number 1

class SingleCommand(typing.NamedTuple):
312class SingleCommand(typing.NamedTuple):
313    value: SingleValue
314    select: bool
315    qualifier: int
316    """qualifier in range [0, 31]"""

SingleCommand(value, select, qualifier)

SingleCommand( value: SingleValue, select: bool, qualifier: int)

Create new instance of SingleCommand(value, select, qualifier)

value: SingleValue

Alias for field number 0

select: bool

Alias for field number 1

qualifier: int

qualifier in range [0, 31]

class DoubleCommand(typing.NamedTuple):
319class DoubleCommand(typing.NamedTuple):
320    value: DoubleValue
321    select: bool
322    qualifier: int
323    """qualifier in range [0, 31]"""

DoubleCommand(value, select, qualifier)

DoubleCommand( value: DoubleValue, select: bool, qualifier: int)

Create new instance of DoubleCommand(value, select, qualifier)

value: DoubleValue

Alias for field number 0

select: bool

Alias for field number 1

qualifier: int

qualifier in range [0, 31]

class RegulatingCommand(typing.NamedTuple):
326class RegulatingCommand(typing.NamedTuple):
327    value: RegulatingValue
328    select: bool
329    qualifier: int
330    """qualifier in range [0, 31]"""

RegulatingCommand(value, select, qualifier)

RegulatingCommand( value: RegulatingValue, select: bool, qualifier: int)

Create new instance of RegulatingCommand(value, select, qualifier)

Alias for field number 0

select: bool

Alias for field number 1

qualifier: int

qualifier in range [0, 31]

class NormalizedCommand(typing.NamedTuple):
333class NormalizedCommand(typing.NamedTuple):
334    value: NormalizedValue
335    select: bool

NormalizedCommand(value, select)

NormalizedCommand( value: NormalizedValue, select: bool)

Create new instance of NormalizedCommand(value, select)

Alias for field number 0

select: bool

Alias for field number 1

class ScaledCommand(typing.NamedTuple):
338class ScaledCommand(typing.NamedTuple):
339    value: ScaledValue
340    select: bool

ScaledCommand(value, select)

ScaledCommand( value: ScaledValue, select: bool)

Create new instance of ScaledCommand(value, select)

value: ScaledValue

Alias for field number 0

select: bool

Alias for field number 1

class FloatingCommand(typing.NamedTuple):
343class FloatingCommand(typing.NamedTuple):
344    value: FloatingValue
345    select: bool

FloatingCommand(value, select)

FloatingCommand( value: FloatingValue, select: bool)

Create new instance of FloatingCommand(value, select)

value: FloatingValue

Alias for field number 0

select: bool

Alias for field number 1

class BitstringCommand(typing.NamedTuple):
348class BitstringCommand(typing.NamedTuple):
349    value: BitstringValue

BitstringCommand(value,)

BitstringCommand(value: BitstringValue)

Create new instance of BitstringCommand(value,)

Alias for field number 0

class NormalizedParameter(typing.NamedTuple):
361class NormalizedParameter(typing.NamedTuple):
362    value: NormalizedValue
363    qualifier: int
364    """qualifier in range [0, 255]"""

NormalizedParameter(value, qualifier)

NormalizedParameter( value: NormalizedValue, qualifier: int)

Create new instance of NormalizedParameter(value, qualifier)

Alias for field number 0

qualifier: int

qualifier in range [0, 255]

class ScaledParameter(typing.NamedTuple):
367class ScaledParameter(typing.NamedTuple):
368    value: ScaledValue
369    qualifier: int
370    """qualifier in range [0, 255]"""

ScaledParameter(value, qualifier)

ScaledParameter( value: ScaledValue, qualifier: int)

Create new instance of ScaledParameter(value, qualifier)

value: ScaledValue

Alias for field number 0

qualifier: int

qualifier in range [0, 255]

class FloatingParameter(typing.NamedTuple):
373class FloatingParameter(typing.NamedTuple):
374    value: FloatingValue
375    qualifier: int
376    """qualifier in range [0, 255]"""

FloatingParameter(value, qualifier)

FloatingParameter( value: FloatingValue, qualifier: int)

Create new instance of FloatingParameter(value, qualifier)

value: FloatingValue

Alias for field number 0

qualifier: int

qualifier in range [0, 255]

class DataMsg(typing.NamedTuple):
384class DataMsg(typing.NamedTuple):
385    is_test: bool
386    originator_address: OriginatorAddress
387    asdu_address: AsduAddress
388    io_address: IoAddress
389    data: Data
390    time: Time | None
391    cause: DataCause

DataMsg(is_test, originator_address, asdu_address, io_address, data, time, cause)

DataMsg( is_test: bool, originator_address: int, asdu_address: int, io_address: int, data: SingleData | DoubleData | StepPositionData | BitstringData | NormalizedData | ScaledData | FloatingData | BinaryCounterData | ProtectionData | ProtectionStartData | ProtectionCommandData | StatusData, time: Time | None, cause: DataResCause | int)

Create new instance of DataMsg(is_test, originator_address, asdu_address, io_address, data, time, cause)

is_test: bool

Alias for field number 0

originator_address: int

Alias for field number 1

asdu_address: int

Alias for field number 2

io_address: int

Alias for field number 3

time: Time | None

Alias for field number 5

cause: DataResCause | int

Alias for field number 6

class CommandMsg(typing.NamedTuple):
394class CommandMsg(typing.NamedTuple):
395    is_test: bool
396    originator_address: OriginatorAddress
397    asdu_address: AsduAddress
398    io_address: IoAddress
399    command: Command
400    is_negative_confirm: bool
401    cause: CommandCause

CommandMsg(is_test, originator_address, asdu_address, io_address, command, is_negative_confirm, cause)

CommandMsg( is_test: bool, originator_address: int, asdu_address: int, io_address: int, command: SingleCommand | DoubleCommand | RegulatingCommand | NormalizedCommand | ScaledCommand | FloatingCommand | BitstringCommand, is_negative_confirm: bool, cause: CommandReqCause | CommandResCause | int)

Create new instance of CommandMsg(is_test, originator_address, asdu_address, io_address, command, is_negative_confirm, cause)

is_test: bool

Alias for field number 0

originator_address: int

Alias for field number 1

asdu_address: int

Alias for field number 2

io_address: int

Alias for field number 3

is_negative_confirm: bool

Alias for field number 5

Alias for field number 6

class InitializationMsg(typing.NamedTuple):
404class InitializationMsg(typing.NamedTuple):
405    is_test: bool
406    originator_address: OriginatorAddress
407    asdu_address: AsduAddress
408    param_change: bool
409    cause: InitializationCause

InitializationMsg(is_test, originator_address, asdu_address, param_change, cause)

InitializationMsg( is_test: bool, originator_address: int, asdu_address: int, param_change: bool, cause: InitializationResCause | int)

Create new instance of InitializationMsg(is_test, originator_address, asdu_address, param_change, cause)

is_test: bool

Alias for field number 0

originator_address: int

Alias for field number 1

asdu_address: int

Alias for field number 2

param_change: bool

Alias for field number 3

cause: InitializationResCause | int

Alias for field number 4

class InterrogationMsg(typing.NamedTuple):
412class InterrogationMsg(typing.NamedTuple):
413    is_test: bool
414    originator_address: OriginatorAddress
415    asdu_address: AsduAddress
416    request: int
417    """request in range [0, 255]"""
418    is_negative_confirm: bool
419    cause: CommandCause

InterrogationMsg(is_test, originator_address, asdu_address, request, is_negative_confirm, cause)

InterrogationMsg( is_test: bool, originator_address: int, asdu_address: int, request: int, is_negative_confirm: bool, cause: CommandReqCause | CommandResCause | int)

Create new instance of InterrogationMsg(is_test, originator_address, asdu_address, request, is_negative_confirm, cause)

is_test: bool

Alias for field number 0

originator_address: int

Alias for field number 1

asdu_address: int

Alias for field number 2

request: int

request in range [0, 255]

is_negative_confirm: bool

Alias for field number 4

Alias for field number 5

class CounterInterrogationMsg(typing.NamedTuple):
422class CounterInterrogationMsg(typing.NamedTuple):
423    is_test: bool
424    originator_address: OriginatorAddress
425    asdu_address: AsduAddress
426    request: int
427    """request in range [0, 63]"""
428    freeze: FreezeCode
429    is_negative_confirm: bool
430    cause: CommandCause

CounterInterrogationMsg(is_test, originator_address, asdu_address, request, freeze, is_negative_confirm, cause)

CounterInterrogationMsg( is_test: bool, originator_address: int, asdu_address: int, request: int, freeze: FreezeCode, is_negative_confirm: bool, cause: CommandReqCause | CommandResCause | int)

Create new instance of CounterInterrogationMsg(is_test, originator_address, asdu_address, request, freeze, is_negative_confirm, cause)

is_test: bool

Alias for field number 0

originator_address: int

Alias for field number 1

asdu_address: int

Alias for field number 2

request: int

request in range [0, 63]

freeze: FreezeCode

Alias for field number 4

is_negative_confirm: bool

Alias for field number 5

Alias for field number 6

class ReadMsg(typing.NamedTuple):
433class ReadMsg(typing.NamedTuple):
434    is_test: bool
435    originator_address: OriginatorAddress
436    asdu_address: AsduAddress
437    io_address: IoAddress
438    cause: ReadCause

ReadMsg(is_test, originator_address, asdu_address, io_address, cause)

ReadMsg( is_test: bool, originator_address: int, asdu_address: int, io_address: int, cause: ReadReqCause | ReadResCause | int)

Create new instance of ReadMsg(is_test, originator_address, asdu_address, io_address, cause)

is_test: bool

Alias for field number 0

originator_address: int

Alias for field number 1

asdu_address: int

Alias for field number 2

io_address: int

Alias for field number 3

cause: ReadReqCause | ReadResCause | int

Alias for field number 4

class ClockSyncMsg(typing.NamedTuple):
441class ClockSyncMsg(typing.NamedTuple):
442    is_test: bool
443    originator_address: OriginatorAddress
444    asdu_address: AsduAddress
445    time: Time
446    is_negative_confirm: bool
447    cause: ClockSyncCause

ClockSyncMsg(is_test, originator_address, asdu_address, time, is_negative_confirm, cause)

ClockSyncMsg( is_test: bool, originator_address: int, asdu_address: int, time: Time, is_negative_confirm: bool, cause: ClockSyncReqCause | ClockSyncResCause | int)

Create new instance of ClockSyncMsg(is_test, originator_address, asdu_address, time, is_negative_confirm, cause)

is_test: bool

Alias for field number 0

originator_address: int

Alias for field number 1

asdu_address: int

Alias for field number 2

time: Time

Alias for field number 3

is_negative_confirm: bool

Alias for field number 4

Alias for field number 5

class TestMsg(typing.NamedTuple):
450class TestMsg(typing.NamedTuple):
451    is_test: bool
452    originator_address: OriginatorAddress
453    asdu_address: AsduAddress
454    cause: ActivationCause

TestMsg(is_test, originator_address, asdu_address, cause)

TestMsg( is_test: bool, originator_address: int, asdu_address: int, cause: ActivationReqCause | ActivationResCause | int)

Create new instance of TestMsg(is_test, originator_address, asdu_address, cause)

is_test: bool

Alias for field number 0

originator_address: int

Alias for field number 1

asdu_address: int

Alias for field number 2

Alias for field number 3

class ResetMsg(typing.NamedTuple):
457class ResetMsg(typing.NamedTuple):
458    is_test: bool
459    originator_address: OriginatorAddress
460    asdu_address: AsduAddress
461    qualifier: int
462    """qualifier in range [0, 255]"""
463    cause: ActivationCause

ResetMsg(is_test, originator_address, asdu_address, qualifier, cause)

ResetMsg( is_test: bool, originator_address: int, asdu_address: int, qualifier: int, cause: ActivationReqCause | ActivationResCause | int)

Create new instance of ResetMsg(is_test, originator_address, asdu_address, qualifier, cause)

is_test: bool

Alias for field number 0

originator_address: int

Alias for field number 1

asdu_address: int

Alias for field number 2

qualifier: int

qualifier in range [0, 255]

Alias for field number 4

class DelayMsg(typing.NamedTuple):
466class DelayMsg(typing.NamedTuple):
467    is_test: bool
468    originator_address: OriginatorAddress
469    asdu_address: AsduAddress
470    time: int
471    """time in range [0, 65535]"""
472    cause: DelayCause

DelayMsg(is_test, originator_address, asdu_address, time, cause)

DelayMsg( is_test: bool, originator_address: int, asdu_address: int, time: int, cause: DelayReqCause | DelayResCause | int)

Create new instance of DelayMsg(is_test, originator_address, asdu_address, time, cause)

is_test: bool

Alias for field number 0

originator_address: int

Alias for field number 1

asdu_address: int

Alias for field number 2

time: int

time in range [0, 65535]

cause: DelayReqCause | DelayResCause | int

Alias for field number 4

class ParameterMsg(typing.NamedTuple):
475class ParameterMsg(typing.NamedTuple):
476    is_test: bool
477    originator_address: OriginatorAddress
478    asdu_address: AsduAddress
479    io_address: IoAddress
480    parameter: Parameter
481    cause: ParameterCause

ParameterMsg(is_test, originator_address, asdu_address, io_address, parameter, cause)

ParameterMsg( is_test: bool, originator_address: int, asdu_address: int, io_address: int, parameter: NormalizedParameter | ScaledParameter | FloatingParameter, cause: ParameterReqCause | ParameterResCause | int)

Create new instance of ParameterMsg(is_test, originator_address, asdu_address, io_address, parameter, cause)

is_test: bool

Alias for field number 0

originator_address: int

Alias for field number 1

asdu_address: int

Alias for field number 2

io_address: int

Alias for field number 3

Alias for field number 4

Alias for field number 5

class ParameterActivationMsg(typing.NamedTuple):
484class ParameterActivationMsg(typing.NamedTuple):
485    is_test: bool
486    originator_address: OriginatorAddress
487    asdu_address: AsduAddress
488    io_address: IoAddress
489    qualifier: int
490    """qualifier in range [0, 255]"""
491    cause: ParameterActivationCause

ParameterActivationMsg(is_test, originator_address, asdu_address, io_address, qualifier, cause)

ParameterActivationMsg( is_test: bool, originator_address: int, asdu_address: int, io_address: int, qualifier: int, cause: ParameterActivationReqCause | ParameterActivationResCause | int)

Create new instance of ParameterActivationMsg(is_test, originator_address, asdu_address, io_address, qualifier, cause)

is_test: bool

Alias for field number 0

originator_address: int

Alias for field number 1

asdu_address: int

Alias for field number 2

io_address: int

Alias for field number 3

qualifier: int

qualifier in range [0, 255]

Alias for field number 5

def time_from_datetime( dt: datetime.datetime, invalid: bool = False) -> Time:
70def time_from_datetime(dt: datetime.datetime,
71                       invalid: bool = False
72                       ) -> Time:
73    """Create Time from datetime.datetime"""
74    # TODO document edge cases (local time, os implementation, ...)
75    #  rounding microseconds to the nearest millisecond
76    dt_rounded = (
77        dt.replace(microsecond=0) +
78        datetime.timedelta(milliseconds=round(dt.microsecond / 1000)))
79    local_time = time.localtime(dt_rounded.timestamp())
80
81    return Time(
82        size=TimeSize.SEVEN,
83        milliseconds=(local_time.tm_sec * 1000 +
84                      dt_rounded.microsecond // 1000),
85        invalid=invalid,
86        minutes=local_time.tm_min,
87        summer_time=bool(local_time.tm_isdst),
88        hours=local_time.tm_hour,
89        day_of_week=local_time.tm_wday + 1,
90        day_of_month=local_time.tm_mday,
91        months=local_time.tm_mon,
92        years=local_time.tm_year % 100)

Create Time from datetime.datetime

def time_to_datetime(t: Time) -> datetime.datetime:
 95def time_to_datetime(t: Time
 96                     ) -> datetime.datetime:
 97    """Convert Time to datetime.datetime"""
 98    # TODO document edge cases (local time, os implementation, ...)
 99    # TODO support TimeSize.FOUR
100    if t.size == TimeSize.TWO:
101        local_now = datetime.datetime.now()
102        local_dt = local_now.replace(
103            second=int(t.milliseconds / 1000),
104            microsecond=(t.milliseconds % 1000) * 1000)
105
106        local_seconds = local_now.second + local_now.microsecond / 1_000_000
107        t_seconds = t.milliseconds / 1_000
108
109        if abs(local_seconds - t_seconds) > 30:
110            if local_seconds < t_seconds:
111                local_dt = local_dt - datetime.timedelta(minutes=1)
112
113            else:
114                local_dt = local_dt + datetime.timedelta(minutes=1)
115
116    elif t.size == TimeSize.THREE:
117        local_now = datetime.datetime.now()
118        local_dt = local_now.replace(
119            minute=t.minutes,
120            second=int(t.milliseconds / 1000),
121            microsecond=(t.milliseconds % 1000) * 1000)
122
123        local_minutes = (local_now.minute +
124                         local_now.second / 60 +
125                         local_now.microsecond / 60_000_000)
126        t_minutes = t.minutes + t.milliseconds / 60_000
127
128        if abs(local_minutes - t_minutes) > 30:
129            if local_minutes < t_minutes:
130                local_dt = local_dt - datetime.timedelta(hours=1)
131
132            else:
133                local_dt = local_dt + datetime.timedelta(hours=1)
134
135    elif t.size == TimeSize.SEVEN:
136        local_dt = datetime.datetime(
137            year=2000 + t.years if t.years < 70 else 1900 + t.years,
138            month=t.months,
139            day=t.day_of_month,
140            hour=t.hours,
141            minute=t.minutes,
142            second=int(t.milliseconds / 1000),
143            microsecond=(t.milliseconds % 1000) * 1000,
144            fold=not t.summer_time)
145
146    else:
147        raise ValueError('unsupported time size')
148
149    return local_dt.astimezone(tz=datetime.timezone.utc)

Convert Time to datetime.datetime

class Connection(hat.aio.group.Resource):
16class Connection(aio.Resource):
17
18    def __init__(self,
19                 conn: link.Connection,
20                 cause_size: common.CauseSize,
21                 asdu_address_size: common.AsduAddressSize,
22                 io_address_size: common.IoAddressSize):
23        self._conn = conn
24        self._encoder = encoder.Encoder(cause_size=cause_size,
25                                        asdu_address_size=asdu_address_size,
26                                        io_address_size=io_address_size)
27        self._comm_log = logger.CommunicationLogger(mlog, conn.info)
28
29        self.async_group.spawn(aio.call_on_cancel, self._comm_log.log,
30                               common.CommLogAction.CLOSE)
31        self._comm_log.log(common.CommLogAction.OPEN)
32
33    @property
34    def async_group(self) -> aio.Group:
35        return self._conn.async_group
36
37    @property
38    def info(self) -> link.ConnectionInfo:
39        return self._conn.info
40
41    async def send(self,
42                   msgs: list[common.Msg],
43                   sent_cb: aio.AsyncCallable[[], None] | None = None):
44        self._comm_log.log(common.CommLogAction.SEND, msgs)
45
46        data = collections.deque(self._encoder.encode(msgs))
47
48        while data:
49            i = data.popleft()
50            await self._conn.send(i, sent_cb=None if data else sent_cb)
51
52    async def receive(self) -> list[common.Msg]:
53        data = await self._conn.receive()
54        msgs = list(self._encoder.decode(data))
55
56        self._comm_log.log(common.CommLogAction.RECEIVE, msgs)
57
58        return msgs

Resource with lifetime control based on Group.

Connection( conn: Connection, cause_size: CauseSize, asdu_address_size: AsduAddressSize, io_address_size: IoAddressSize)
18    def __init__(self,
19                 conn: link.Connection,
20                 cause_size: common.CauseSize,
21                 asdu_address_size: common.AsduAddressSize,
22                 io_address_size: common.IoAddressSize):
23        self._conn = conn
24        self._encoder = encoder.Encoder(cause_size=cause_size,
25                                        asdu_address_size=asdu_address_size,
26                                        io_address_size=io_address_size)
27        self._comm_log = logger.CommunicationLogger(mlog, conn.info)
28
29        self.async_group.spawn(aio.call_on_cancel, self._comm_log.log,
30                               common.CommLogAction.CLOSE)
31        self._comm_log.log(common.CommLogAction.OPEN)
async_group: hat.aio.group.Group
33    @property
34    def async_group(self) -> aio.Group:
35        return self._conn.async_group

Group controlling resource's lifetime.

37    @property
38    def info(self) -> link.ConnectionInfo:
39        return self._conn.info
async def send( self, msgs: list[DataMsg | CommandMsg | InitializationMsg | InterrogationMsg | CounterInterrogationMsg | ReadMsg | ClockSyncMsg | TestMsg | ResetMsg | DelayMsg | ParameterMsg | ParameterActivationMsg], sent_cb: Optional[Callable[[], None | Awaitable[None]]] = None):
41    async def send(self,
42                   msgs: list[common.Msg],
43                   sent_cb: aio.AsyncCallable[[], None] | None = None):
44        self._comm_log.log(common.CommLogAction.SEND, msgs)
45
46        data = collections.deque(self._encoder.encode(msgs))
47
48        while data:
49            i = data.popleft()
50            await self._conn.send(i, sent_cb=None if data else sent_cb)
52    async def receive(self) -> list[common.Msg]:
53        data = await self._conn.receive()
54        msgs = list(self._encoder.decode(data))
55
56        self._comm_log.log(common.CommLogAction.RECEIVE, msgs)
57
58        return msgs