hat.drivers.iec60870.encodings.iec104
IEC 60870-5-104 messages
1"""IEC 60870-5-104 messages""" 2 3from hat.drivers.iec60870.encodings.iec104.common import ( 4 AsduTypeError, 5 TimeSize, 6 Time, 7 time_from_datetime, 8 time_to_datetime, 9 OriginatorAddress, 10 AsduAddress, 11 IoAddress, 12 AsduType, 13 CauseType, 14 OtherCauseType, 15 Cause, 16 QualityType, 17 IndicationQuality, 18 MeasurementQuality, 19 CounterQuality, 20 ProtectionQuality, 21 Quality, 22 FreezeCode, 23 SingleValue, 24 DoubleValue, 25 RegulatingValue, 26 StepPositionValue, 27 BitstringValue, 28 NormalizedValue, 29 ScaledValue, 30 FloatingValue, 31 BinaryCounterValue, 32 ProtectionValue, 33 ProtectionStartValue, 34 ProtectionCommandValue, 35 StatusValue, 36 IoElement_M_SP_NA, 37 IoElement_M_DP_NA, 38 IoElement_M_ST_NA, 39 IoElement_M_BO_NA, 40 IoElement_M_ME_NA, 41 IoElement_M_ME_NB, 42 IoElement_M_ME_NC, 43 IoElement_M_IT_NA, 44 IoElement_M_PS_NA, 45 IoElement_M_ME_ND, 46 IoElement_M_SP_TB, 47 IoElement_M_DP_TB, 48 IoElement_M_ST_TB, 49 IoElement_M_BO_TB, 50 IoElement_M_ME_TD, 51 IoElement_M_ME_TE, 52 IoElement_M_ME_TF, 53 IoElement_M_IT_TB, 54 IoElement_M_EP_TD, 55 IoElement_M_EP_TE, 56 IoElement_M_EP_TF, 57 IoElement_C_SC_NA, 58 IoElement_C_DC_NA, 59 IoElement_C_RC_NA, 60 IoElement_C_SE_NA, 61 IoElement_C_SE_NB, 62 IoElement_C_SE_NC, 63 IoElement_C_BO_NA, 64 IoElement_M_EI_NA, 65 IoElement_C_IC_NA, 66 IoElement_C_CI_NA, 67 IoElement_C_RD_NA, 68 IoElement_C_CS_NA, 69 IoElement_C_RP_NA, 70 IoElement_P_ME_NA, 71 IoElement_P_ME_NB, 72 IoElement_P_ME_NC, 73 IoElement_P_AC_NA, 74 IoElement_F_FR_NA, 75 IoElement_F_SR_NA, 76 IoElement_F_SC_NA, 77 IoElement_F_LS_NA, 78 IoElement_F_AF_NA, 79 IoElement_F_SG_NA, 80 IoElement_F_DR_TA, 81 IoElement_C_SC_TA, 82 IoElement_C_DC_TA, 83 IoElement_C_RC_TA, 84 IoElement_C_SE_TA, 85 IoElement_C_SE_TB, 86 IoElement_C_SE_TC, 87 IoElement_C_BO_TA, 88 IoElement_C_TS_TA, 89 IoElement, 90 IO, 91 ASDU) 92from hat.drivers.iec60870.encodings.iec104.encoder import ( 93 iec101_asdu_types, 94 Encoder) 95 96 97__all__ = ['AsduTypeError', 98 'TimeSize', 99 'Time', 100 'time_from_datetime', 101 'time_to_datetime', 102 'OriginatorAddress', 103 'AsduAddress', 104 'IoAddress', 105 'AsduType', 106 'CauseType', 107 'OtherCauseType', 108 'Cause', 109 'QualityType', 110 'IndicationQuality', 111 'MeasurementQuality', 112 'CounterQuality', 113 'ProtectionQuality', 114 'Quality', 115 'FreezeCode', 116 'SingleValue', 117 'DoubleValue', 118 'RegulatingValue', 119 'StepPositionValue', 120 'BitstringValue', 121 'NormalizedValue', 122 'ScaledValue', 123 'FloatingValue', 124 'BinaryCounterValue', 125 'ProtectionValue', 126 'ProtectionStartValue', 127 'ProtectionCommandValue', 128 'StatusValue', 129 'IoElement_M_SP_NA', 130 'IoElement_M_DP_NA', 131 'IoElement_M_ST_NA', 132 'IoElement_M_BO_NA', 133 'IoElement_M_ME_NA', 134 'IoElement_M_ME_NB', 135 'IoElement_M_ME_NC', 136 'IoElement_M_IT_NA', 137 'IoElement_M_PS_NA', 138 'IoElement_M_ME_ND', 139 'IoElement_M_SP_TB', 140 'IoElement_M_DP_TB', 141 'IoElement_M_ST_TB', 142 'IoElement_M_BO_TB', 143 'IoElement_M_ME_TD', 144 'IoElement_M_ME_TE', 145 'IoElement_M_ME_TF', 146 'IoElement_M_IT_TB', 147 'IoElement_M_EP_TD', 148 'IoElement_M_EP_TE', 149 'IoElement_M_EP_TF', 150 'IoElement_C_SC_NA', 151 'IoElement_C_DC_NA', 152 'IoElement_C_RC_NA', 153 'IoElement_C_SE_NA', 154 'IoElement_C_SE_NB', 155 'IoElement_C_SE_NC', 156 'IoElement_C_BO_NA', 157 'IoElement_M_EI_NA', 158 'IoElement_C_IC_NA', 159 'IoElement_C_CI_NA', 160 'IoElement_C_RD_NA', 161 'IoElement_C_CS_NA', 162 'IoElement_C_RP_NA', 163 'IoElement_P_ME_NA', 164 'IoElement_P_ME_NB', 165 'IoElement_P_ME_NC', 166 'IoElement_P_AC_NA', 167 'IoElement_F_FR_NA', 168 'IoElement_F_SR_NA', 169 'IoElement_F_SC_NA', 170 'IoElement_F_LS_NA', 171 'IoElement_F_AF_NA', 172 'IoElement_F_SG_NA', 173 'IoElement_F_DR_TA', 174 'IoElement_C_SC_TA', 175 'IoElement_C_DC_TA', 176 'IoElement_C_RC_TA', 177 'IoElement_C_SE_TA', 178 'IoElement_C_SE_TB', 179 'IoElement_C_SE_TC', 180 'IoElement_C_BO_TA', 181 'IoElement_C_TS_TA', 182 'IoElement', 183 'IO', 184 'ASDU', 185 'iec101_asdu_types', 186 'Encoder']
Common base class for all non-exit exceptions.
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)
Create new instance of Time(size, milliseconds, invalid, minutes, summer_time, hours, day_of_week, day_of_month, months, years)
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
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
21class AsduType(enum.Enum): 22 M_SP_NA = iec101.AsduType.M_SP_NA.value 23 M_DP_NA = iec101.AsduType.M_DP_NA.value 24 M_ST_NA = iec101.AsduType.M_ST_NA.value 25 M_BO_NA = iec101.AsduType.M_BO_NA.value 26 M_ME_NA = iec101.AsduType.M_ME_NA.value 27 M_ME_NB = iec101.AsduType.M_ME_NB.value 28 M_ME_NC = iec101.AsduType.M_ME_NC.value 29 M_IT_NA = iec101.AsduType.M_IT_NA.value 30 M_PS_NA = iec101.AsduType.M_PS_NA.value 31 M_ME_ND = iec101.AsduType.M_ME_ND.value 32 M_SP_TB = iec101.AsduType.M_SP_TB.value 33 M_DP_TB = iec101.AsduType.M_DP_TB.value 34 M_ST_TB = iec101.AsduType.M_ST_TB.value 35 M_BO_TB = iec101.AsduType.M_BO_TB.value 36 M_ME_TD = iec101.AsduType.M_ME_TD.value 37 M_ME_TE = iec101.AsduType.M_ME_TE.value 38 M_ME_TF = iec101.AsduType.M_ME_TF.value 39 M_IT_TB = iec101.AsduType.M_IT_TB.value 40 M_EP_TD = iec101.AsduType.M_EP_TD.value 41 M_EP_TE = iec101.AsduType.M_EP_TE.value 42 M_EP_TF = iec101.AsduType.M_EP_TF.value 43 C_SC_NA = iec101.AsduType.C_SC_NA.value 44 C_DC_NA = iec101.AsduType.C_DC_NA.value 45 C_RC_NA = iec101.AsduType.C_RC_NA.value 46 C_SE_NA = iec101.AsduType.C_SE_NA.value 47 C_SE_NB = iec101.AsduType.C_SE_NB.value 48 C_SE_NC = iec101.AsduType.C_SE_NC.value 49 C_BO_NA = iec101.AsduType.C_BO_NA.value 50 C_SC_TA = 58 51 C_DC_TA = 59 52 C_RC_TA = 60 53 C_SE_TA = 61 54 C_SE_TB = 62 55 C_SE_TC = 63 56 C_BO_TA = 64 57 M_EI_NA = iec101.AsduType.M_EI_NA.value 58 C_IC_NA = iec101.AsduType.C_IC_NA.value 59 C_CI_NA = iec101.AsduType.C_CI_NA.value 60 C_RD_NA = iec101.AsduType.C_RD_NA.value 61 C_CS_NA = iec101.AsduType.C_CS_NA.value 62 C_RP_NA = iec101.AsduType.C_RP_NA.value 63 C_TS_TA = 107 64 P_ME_NA = iec101.AsduType.P_ME_NA.value 65 P_ME_NB = iec101.AsduType.P_ME_NB.value 66 P_ME_NC = iec101.AsduType.P_ME_NC.value 67 P_AC_NA = iec101.AsduType.P_AC_NA.value 68 F_FR_NA = iec101.AsduType.F_FR_NA.value 69 F_SR_NA = iec101.AsduType.F_SR_NA.value 70 F_SC_NA = iec101.AsduType.F_SC_NA.value 71 F_LS_NA = iec101.AsduType.F_LS_NA.value 72 F_AF_NA = iec101.AsduType.F_AF_NA.value 73 F_SG_NA = iec101.AsduType.F_SG_NA.value 74 F_DR_TA = iec101.AsduType.F_DR_TA.value
86class CauseType(enum.Enum): 87 UNDEFINED = 0 88 PERIODIC = 1 89 BACKGROUND_SCAN = 2 90 SPONTANEOUS = 3 91 INITIALIZED = 4 92 REQUEST = 5 93 ACTIVATION = 6 94 ACTIVATION_CONFIRMATION = 7 95 DEACTIVATION = 8 96 DEACTIVATION_CONFIRMATION = 9 97 ACTIVATION_TERMINATION = 10 98 REMOTE_COMMAND = 11 99 LOCAL_COMMAND = 12 100 FILE_TRANSFER = 13 101 INTERROGATED_STATION = 20 102 INTERROGATED_GROUP01 = 21 103 INTERROGATED_GROUP02 = 22 104 INTERROGATED_GROUP03 = 23 105 INTERROGATED_GROUP04 = 24 106 INTERROGATED_GROUP05 = 25 107 INTERROGATED_GROUP06 = 26 108 INTERROGATED_GROUP07 = 27 109 INTERROGATED_GROUP08 = 28 110 INTERROGATED_GROUP09 = 29 111 INTERROGATED_GROUP10 = 30 112 INTERROGATED_GROUP11 = 31 113 INTERROGATED_GROUP12 = 32 114 INTERROGATED_GROUP13 = 33 115 INTERROGATED_GROUP14 = 34 116 INTERROGATED_GROUP15 = 35 117 INTERROGATED_GROUP16 = 36 118 INTERROGATED_COUNTER = 37 119 INTERROGATED_COUNTER01 = 38 120 INTERROGATED_COUNTER02 = 39 121 INTERROGATED_COUNTER03 = 40 122 INTERROGATED_COUNTER04 = 41 123 UNKNOWN_TYPE = 44 124 UNKNOWN_CAUSE = 45 125 UNKNOWN_ASDU_ADDRESS = 46 126 UNKNOWN_IO_ADDRESS = 47
129class Cause(typing.NamedTuple): 130 type: CauseType | OtherCauseType 131 is_negative_confirm: bool 132 is_test: bool 133 originator_address: OriginatorAddress
Cause(type, is_negative_confirm, is_test, originator_address)
Create new instance of Cause(type, is_negative_confirm, is_test, originator_address)
136class QualityType(enum.Enum): 137 INDICATION = 0 138 MEASUREMENT = 1 139 COUNTER = 2 140 PROTECTION = 3
143class IndicationQuality(typing.NamedTuple): 144 invalid: bool 145 not_topical: bool 146 substituted: bool 147 blocked: bool
IndicationQuality(invalid, not_topical, substituted, blocked)
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)
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)
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)
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.
210class StepPositionValue(typing.NamedTuple): 211 value: int 212 """value in range [-64, 63]""" 213 transient: bool
StepPositionValue(value, transient)
216class BitstringValue(typing.NamedTuple): 217 value: util.Bytes 218 """bitstring encoded as 4 bytes"""
BitstringValue(value,)
NormalizedValue(value,)
ScaledValue(value,)
FloatingValue(value,)
235class BinaryCounterValue(typing.NamedTuple): 236 value: int 237 """value in range [-2^31, 2^31-1]"""
BinaryCounterValue(value,)
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)
254class ProtectionCommandValue(typing.NamedTuple): 255 general: bool 256 l1: bool 257 l2: bool 258 l3: bool
ProtectionCommandValue(general, l1, l2, l3)
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)
268class IoElement_M_SP_NA(typing.NamedTuple): 269 value: SingleValue 270 quality: IndicationQuality
IoElement_M_SP_NA(value, quality)
Create new instance of IoElement_M_SP_NA(value, quality)
278class IoElement_M_DP_NA(typing.NamedTuple): 279 value: DoubleValue 280 quality: IndicationQuality
IoElement_M_DP_NA(value, quality)
Create new instance of IoElement_M_DP_NA(value, quality)
288class IoElement_M_ST_NA(typing.NamedTuple): 289 value: StepPositionValue 290 quality: MeasurementQuality
IoElement_M_ST_NA(value, quality)
Create new instance of IoElement_M_ST_NA(value, quality)
298class IoElement_M_BO_NA(typing.NamedTuple): 299 value: BitstringValue 300 quality: MeasurementQuality
IoElement_M_BO_NA(value, quality)
Create new instance of IoElement_M_BO_NA(value, quality)
308class IoElement_M_ME_NA(typing.NamedTuple): 309 value: NormalizedValue 310 quality: MeasurementQuality
IoElement_M_ME_NA(value, quality)
Create new instance of IoElement_M_ME_NA(value, quality)
318class IoElement_M_ME_NB(typing.NamedTuple): 319 value: ScaledValue 320 quality: MeasurementQuality
IoElement_M_ME_NB(value, quality)
Create new instance of IoElement_M_ME_NB(value, quality)
328class IoElement_M_ME_NC(typing.NamedTuple): 329 value: FloatingValue 330 quality: MeasurementQuality
IoElement_M_ME_NC(value, quality)
Create new instance of IoElement_M_ME_NC(value, quality)
338class IoElement_M_IT_NA(typing.NamedTuple): 339 value: BinaryCounterValue 340 quality: CounterQuality
IoElement_M_IT_NA(value, quality)
Create new instance of IoElement_M_IT_NA(value, quality)
369class IoElement_M_PS_NA(typing.NamedTuple): 370 value: StatusValue 371 quality: MeasurementQuality
IoElement_M_PS_NA(value, quality)
Create new instance of IoElement_M_PS_NA(value, quality)
IoElement_M_ME_ND(value,)
378class IoElement_M_SP_TB(typing.NamedTuple): 379 value: SingleValue 380 quality: IndicationQuality
IoElement_M_SP_TB(value, quality)
Create new instance of IoElement_M_SP_TB(value, quality)
383class IoElement_M_DP_TB(typing.NamedTuple): 384 value: DoubleValue 385 quality: IndicationQuality
IoElement_M_DP_TB(value, quality)
Create new instance of IoElement_M_DP_TB(value, quality)
388class IoElement_M_ST_TB(typing.NamedTuple): 389 value: StepPositionValue 390 quality: MeasurementQuality
IoElement_M_ST_TB(value, quality)
Create new instance of IoElement_M_ST_TB(value, quality)
393class IoElement_M_BO_TB(typing.NamedTuple): 394 value: BitstringValue 395 quality: MeasurementQuality
IoElement_M_BO_TB(value, quality)
Create new instance of IoElement_M_BO_TB(value, quality)
398class IoElement_M_ME_TD(typing.NamedTuple): 399 value: NormalizedValue 400 quality: MeasurementQuality
IoElement_M_ME_TD(value, quality)
Create new instance of IoElement_M_ME_TD(value, quality)
403class IoElement_M_ME_TE(typing.NamedTuple): 404 value: ScaledValue 405 quality: MeasurementQuality
IoElement_M_ME_TE(value, quality)
Create new instance of IoElement_M_ME_TE(value, quality)
408class IoElement_M_ME_TF(typing.NamedTuple): 409 value: FloatingValue 410 quality: MeasurementQuality
IoElement_M_ME_TF(value, quality)
Create new instance of IoElement_M_ME_TF(value, quality)
413class IoElement_M_IT_TB(typing.NamedTuple): 414 value: BinaryCounterValue 415 quality: CounterQuality
IoElement_M_IT_TB(value, quality)
Create new instance of IoElement_M_IT_TB(value, quality)
418class IoElement_M_EP_TD(typing.NamedTuple): 419 value: ProtectionValue 420 quality: ProtectionQuality 421 elapsed_time: int 422 """elapsed_time in range [0, 65535]"""
IoElement_M_EP_TD(value, quality, elapsed_time)
Create new instance of IoElement_M_EP_TD(value, quality, elapsed_time)
425class IoElement_M_EP_TE(typing.NamedTuple): 426 value: ProtectionStartValue 427 quality: ProtectionQuality 428 duration_time: int 429 """duration_time in range [0, 65535]"""
IoElement_M_EP_TE(value, quality, duration_time)
Create new instance of IoElement_M_EP_TE(value, quality, duration_time)
432class IoElement_M_EP_TF(typing.NamedTuple): 433 value: ProtectionCommandValue 434 quality: ProtectionQuality 435 operating_time: int 436 """operating_time in range [0, 65535]"""
IoElement_M_EP_TF(value, quality, operating_time)
Create new instance of IoElement_M_EP_TF(value, quality, operating_time)
439class IoElement_C_SC_NA(typing.NamedTuple): 440 value: SingleValue 441 select: bool 442 qualifier: int 443 """qualifier in range [0, 31]"""
IoElement_C_SC_NA(value, select, qualifier)
Create new instance of IoElement_C_SC_NA(value, select, qualifier)
446class IoElement_C_DC_NA(typing.NamedTuple): 447 value: DoubleValue 448 select: bool 449 qualifier: int 450 """qualifier in range [0, 31]"""
IoElement_C_DC_NA(value, select, qualifier)
Create new instance of IoElement_C_DC_NA(value, select, qualifier)
453class IoElement_C_RC_NA(typing.NamedTuple): 454 value: RegulatingValue 455 select: bool 456 qualifier: int 457 """qualifier in range [0, 31]"""
IoElement_C_RC_NA(value, select, qualifier)
Create new instance of IoElement_C_RC_NA(value, select, qualifier)
IoElement_C_SE_NA(value, select)
Create new instance of IoElement_C_SE_NA(value, select)
IoElement_C_SE_NB(value, select)
Create new instance of IoElement_C_SE_NB(value, select)
IoElement_C_SE_NC(value, select)
Create new instance of IoElement_C_SE_NC(value, select)
IoElement_C_BO_NA(value,)
479class IoElement_M_EI_NA(typing.NamedTuple): 480 param_change: bool 481 cause: int 482 """cause in range [0, 127]"""
IoElement_M_EI_NA(param_change, cause)
485class IoElement_C_IC_NA(typing.NamedTuple): 486 qualifier: int 487 """qualifier in range [0, 255]"""
IoElement_C_IC_NA(qualifier,)
490class IoElement_C_CI_NA(typing.NamedTuple): 491 request: int 492 """request in range [0, 63]""" 493 freeze: FreezeCode
IoElement_C_CI_NA(request, freeze)
Create new instance of IoElement_C_CI_NA(request, freeze)
IoElement_C_RD_NA()
IoElement_C_CS_NA(time,)
509class IoElement_C_RP_NA(typing.NamedTuple): 510 qualifier: int 511 """qualifier in range [0, 255]"""
IoElement_C_RP_NA(qualifier,)
519class IoElement_P_ME_NA(typing.NamedTuple): 520 value: NormalizedValue 521 qualifier: int 522 """qualifier in range [0, 255]"""
IoElement_P_ME_NA(value, qualifier)
Create new instance of IoElement_P_ME_NA(value, qualifier)
525class IoElement_P_ME_NB(typing.NamedTuple): 526 value: ScaledValue 527 qualifier: int 528 """qualifier in range [0, 255]"""
IoElement_P_ME_NB(value, qualifier)
Create new instance of IoElement_P_ME_NB(value, qualifier)
531class IoElement_P_ME_NC(typing.NamedTuple): 532 value: FloatingValue 533 qualifier: int 534 """qualifier in range [0, 255]"""
IoElement_P_ME_NC(value, qualifier)
Create new instance of IoElement_P_ME_NC(value, qualifier)
537class IoElement_P_AC_NA(typing.NamedTuple): 538 qualifier: int 539 """qualifier in range [0, 255]"""
IoElement_P_AC_NA(qualifier,)
542class IoElement_F_FR_NA(typing.NamedTuple): 543 file_name: int 544 """file_name in range [0, 65535]""" 545 file_length: int 546 """file_length in range [0, 16777215]""" 547 ready: bool
IoElement_F_FR_NA(file_name, file_length, ready)
550class IoElement_F_SR_NA(typing.NamedTuple): 551 file_name: int 552 """file_name in range [0, 65535]""" 553 section_name: int 554 """section_name in range [0, 255]""" 555 section_length: int 556 """section_length in range [0, 16777215]""" 557 ready: bool
IoElement_F_SR_NA(file_name, section_name, section_length, ready)
560class IoElement_F_SC_NA(typing.NamedTuple): 561 file_name: int 562 """file_name in range [0, 65535]""" 563 section_name: int 564 """section_name in range [0, 255]""" 565 qualifier: int 566 """qualifier in range [0, 255]"""
IoElement_F_SC_NA(file_name, section_name, qualifier)
569class IoElement_F_LS_NA(typing.NamedTuple): 570 file_name: int 571 """file_name in range [0, 65535]""" 572 section_name: int 573 """section_name in range [0, 255]""" 574 last_qualifier: int 575 """last_qualifier in range [0, 255]""" 576 checksum: int 577 """checksum in range [0, 255]"""
IoElement_F_LS_NA(file_name, section_name, last_qualifier, checksum)
580class IoElement_F_AF_NA(typing.NamedTuple): 581 file_name: int 582 """file_name in range [0, 65535]""" 583 section_name: int 584 """section_name in range [0, 255]""" 585 qualifier: int 586 """qualifier in range [0, 255]"""
IoElement_F_AF_NA(file_name, section_name, qualifier)
589class IoElement_F_SG_NA(typing.NamedTuple): 590 file_name: int 591 """file_name in range [0, 65535]""" 592 section_name: int 593 """section_name in range [0, 255]""" 594 segment: util.Bytes
IoElement_F_SG_NA(file_name, section_name, segment)
597class IoElement_F_DR_TA(typing.NamedTuple): 598 file_name: int 599 """file_name in range [0, 65535]""" 600 file_length: int 601 """file_length in range [0, 16777215]""" 602 more_follows: bool 603 is_directory: bool 604 transfer_active: bool 605 creation_time: Time
IoElement_F_DR_TA(file_name, file_length, more_follows, is_directory, transfer_active, creation_time)
Create new instance of IoElement_F_DR_TA(file_name, file_length, more_follows, is_directory, transfer_active, creation_time)
151class IoElement_C_SC_TA(typing.NamedTuple): 152 value: SingleValue 153 select: bool 154 qualifier: int 155 """qualifier in range [0, 31]"""
IoElement_C_SC_TA(value, select, qualifier)
Create new instance of IoElement_C_SC_TA(value, select, qualifier)
158class IoElement_C_DC_TA(typing.NamedTuple): 159 value: DoubleValue 160 select: bool 161 qualifier: int 162 """qualifier in range [0, 31]"""
IoElement_C_DC_TA(value, select, qualifier)
Create new instance of IoElement_C_DC_TA(value, select, qualifier)
165class IoElement_C_RC_TA(typing.NamedTuple): 166 value: RegulatingValue 167 select: bool 168 qualifier: int 169 """qualifier in range [0, 31]"""
IoElement_C_RC_TA(value, select, qualifier)
Create new instance of IoElement_C_RC_TA(value, select, qualifier)
IoElement_C_SE_TA(value, select)
Create new instance of IoElement_C_SE_TA(value, select)
IoElement_C_SE_TB(value, select)
Create new instance of IoElement_C_SE_TB(value, select)
IoElement_C_SE_TC(value, select)
Create new instance of IoElement_C_SE_TC(value, select)
IoElement_C_BO_TA(value,)
191class IoElement_C_TS_TA(typing.NamedTuple): 192 counter: int 193 """counter in range [0, 65535]"""
IoElement_C_TS_TA(counter,)
251class IO(typing.NamedTuple): 252 address: IoAddress 253 elements: list[IoElement] 254 time: Time | None
IO(address, elements, time)
Create new instance of IO(address, elements, time)
Alias for field number 1
257class ASDU(typing.NamedTuple): 258 type: AsduType 259 cause: Cause 260 address: AsduAddress 261 ios: list[IO]
ASDU(type, cause, address, ios)
56class Encoder: 57 58 def __init__(self, max_asdu_size: int = 249): 59 self._max_asdu_size = max_asdu_size 60 self._encoder = encoder.Encoder( 61 cause_size=common.CauseSize.TWO, 62 asdu_address_size=common.AsduAddressSize.TWO, 63 io_address_size=common.IoAddressSize.THREE, 64 asdu_type_time_sizes=_asdu_type_time_sizes, 65 inverted_sequence_bit=False, 66 decode_io_element_cb=_decode_io_element, 67 encode_io_element_cb=_encode_io_element) 68 69 @property 70 def max_asdu_size(self) -> int: 71 return self._max_asdu_size 72 73 @property 74 def cause_size(self) -> common.CauseSize: 75 return self._encoder.cause_size 76 77 @property 78 def asdu_address_size(self) -> common.AsduAddressSize: 79 return self._encoder.asdu_address_size 80 81 @property 82 def io_address_size(self) -> common.IoAddressSize: 83 return self._encoder.io_address_size 84 85 def decode_asdu(self, 86 asdu_bytes: util.Bytes 87 ) -> tuple[common.ASDU, util.Bytes]: 88 asdu, rest = self._encoder.decode_asdu(asdu_bytes) 89 90 asdu_type = _decode_asdu_type(asdu.type) 91 92 cause = iec101.decode_cause(asdu.cause, common.CauseSize.TWO) 93 address = asdu.address 94 ios = [common.IO(address=io.address, 95 elements=io.elements, 96 time=io.time) 97 for io in asdu.ios] 98 99 asdu = common.ASDU(type=asdu_type, 100 cause=cause, 101 address=address, 102 ios=ios) 103 return asdu, rest 104 105 def encode_asdu(self, asdu: common.ASDU) -> util.Bytes: 106 asdu_type = asdu.type.value 107 cause = iec101.encode_cause(asdu.cause, common.CauseSize.TWO) 108 address = asdu.address 109 ios = [encoder.common.IO(address=io.address, 110 elements=io.elements, 111 time=io.time) 112 for io in asdu.ios] 113 114 asdu = encoder.common.ASDU(type=asdu_type, 115 cause=cause, 116 address=address, 117 ios=ios) 118 119 return self._encoder.encode_asdu(asdu)
58 def __init__(self, max_asdu_size: int = 249): 59 self._max_asdu_size = max_asdu_size 60 self._encoder = encoder.Encoder( 61 cause_size=common.CauseSize.TWO, 62 asdu_address_size=common.AsduAddressSize.TWO, 63 io_address_size=common.IoAddressSize.THREE, 64 asdu_type_time_sizes=_asdu_type_time_sizes, 65 inverted_sequence_bit=False, 66 decode_io_element_cb=_decode_io_element, 67 encode_io_element_cb=_encode_io_element)
85 def decode_asdu(self, 86 asdu_bytes: util.Bytes 87 ) -> tuple[common.ASDU, util.Bytes]: 88 asdu, rest = self._encoder.decode_asdu(asdu_bytes) 89 90 asdu_type = _decode_asdu_type(asdu.type) 91 92 cause = iec101.decode_cause(asdu.cause, common.CauseSize.TWO) 93 address = asdu.address 94 ios = [common.IO(address=io.address, 95 elements=io.elements, 96 time=io.time) 97 for io in asdu.ios] 98 99 asdu = common.ASDU(type=asdu_type, 100 cause=cause, 101 address=address, 102 ios=ios) 103 return asdu, rest
105 def encode_asdu(self, asdu: common.ASDU) -> util.Bytes: 106 asdu_type = asdu.type.value 107 cause = iec101.encode_cause(asdu.cause, common.CauseSize.TWO) 108 address = asdu.address 109 ios = [encoder.common.IO(address=io.address, 110 elements=io.elements, 111 time=io.time) 112 for io in asdu.ios] 113 114 asdu = encoder.common.ASDU(type=asdu_type, 115 cause=cause, 116 address=address, 117 ios=ios) 118 119 return self._encoder.encode_asdu(asdu)