DLMS-SPODES-client 0.19.25__py3-none-any.whl → 0.19.28__py3-none-any.whl

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.
@@ -338,7 +338,7 @@ class Client:
338
338
  # TODO: make return pdu
339
339
  if reply.command is None:
340
340
  if reply.data.size - reply.data.position == 0:
341
- return result.Error(ValueError("Invalid PDU"), "getpdu")
341
+ return result.Error.from_e(ValueError("Invalid PDU"), "getpdu")
342
342
  index = reply.data.position
343
343
  reply.command = XDLMSAPDU(reply.data.getUInt8())
344
344
  match reply.command:
@@ -444,7 +444,7 @@ class Client:
444
444
  case pdu.ActionResponse.NORMAL:
445
445
  reply.error = pdu.ActionResult(reply.data.getUInt8())
446
446
  if reply.error != 0:
447
- return result.Error(exc.ResultError(reply.error), "get pdu")
447
+ return result.Error.from_e(exc.ResultError(reply.error), "get pdu")
448
448
  if reply.data.position < reply.data.size:
449
449
  ret = reply.data.getUInt8()
450
450
  if ret == 0:
@@ -780,7 +780,10 @@ class Client:
780
780
  return result.Error.from_e(exc.NoObject(), "read data block")
781
781
  case _:
782
782
  return result.Error.from_e(GXDLMSException(reply.error), "read data block")
783
- if self.received_frames[-1].control.is_info() or self.received_frames[-1].control == frame.Control.UI_PF:
783
+ if (
784
+ self.received_frames[-1].control.is_info()
785
+ or self.received_frames[-1].control == frame.Control.UI_PF
786
+ ):
784
787
  if self.received_frames[-1].is_segmentation:
785
788
  """pass handle frame. wait all information"""
786
789
  else:
@@ -11,19 +11,19 @@ _h: dict[str, [str]] = dict(settings.from_csv.header_names)
11
11
  class IpAddress:
12
12
  __value: list[int]
13
13
 
14
- def __init__(self, value: str = '127.0.0.1'):
14
+ def __init__(self, value: str = "127.0.0.1"):
15
15
  self.__value = list()
16
- for el1 in value.split('.'):
16
+ for el1 in value.split("."):
17
17
  if el1.isdigit():
18
18
  el = int(el1)
19
19
  if 0 <= el <= 255:
20
20
  self.__value.append(el)
21
21
  else:
22
- raise ValueError(F'Wrong digit in value: {el}, must be 0..255')
22
+ raise ValueError(F"Wrong digit in value: {el}, must be 0..255")
23
23
  else:
24
- raise ValueError(F'Value is not digit: {el1}')
24
+ raise ValueError(F"Value is not digit: {el1}")
25
25
  if len(self.__value) != 4:
26
- raise ValueError(F'Length of Ip address {value} must be 4, got {len(self.__value)}')
26
+ raise ValueError(F"Length of Ip address {value} must be 4, got {len(self.__value)}")
27
27
 
28
28
  @classmethod
29
29
  def is_valid(cls, value: str) -> bool:
@@ -34,64 +34,57 @@ class IpAddress:
34
34
  return False
35
35
 
36
36
  def __str__(self):
37
- return '.'.join(map(str, self.__value))
37
+ return ".".join(map(str, self.__value))
38
38
 
39
39
 
40
40
  def get_client_from_csv(
41
41
  file_name: str,
42
- id_factory: IDFactory = None,
42
+ id_factory: IDFactory,
43
43
  universal: bool = False
44
44
  ) -> list[Client]:
45
45
  """file in utf-8 format"""
46
46
  da: str
47
- with open(file_name, 'r', encoding="utf-8-sig") as csv_file:
48
- sniffer = csv.Sniffer()
49
- dialect = sniffer.sniff(csv_file.readline(1024))
47
+ with open(file_name, "r", encoding="utf-8-sig") as csv_file:
48
+ dialect = csv.Sniffer().sniff(csv_file.readline(1024))
50
49
  csv_file.seek(0)
51
50
  reader = csv.reader(csv_file, dialect=dialect)
52
51
  first_row: list[str] = next(reader)
53
52
  if any(map(IpAddress.is_valid, first_row)): # search ip_address in first row
54
- # header is absence
55
- raise ValueError('Не найден заголовок таблицы')
56
- else: # header is exist
57
- # search column by name
58
- column_name_count = count()
59
- field_names: list[str] = list()
60
- for index, cell in enumerate(first_row):
61
- for column in _h:
62
- if any(map(cell.lower().startswith, _h[column])):
63
- field_names.append(_h[column][0])
64
- break
65
- else:
66
- field_names.append(F'unknown{next(column_name_count)}')
67
- if all(map(lambda name: name in field_names, ('ip',))):
68
- csv_file.seek(0)
69
- reader = csv.DictReader(csv_file, fieldnames=field_names, dialect=dialect)
70
- next(reader)
71
- res: list[Client] = list()
72
- for i in reader:
73
- if IpAddress.is_valid(i['ip']):
74
- res.append(c := Client(
75
- media=Network(
76
- host=i.get("ip", "127.0.0.1"),
77
- port="8888"
78
- ),
79
- id_=id_factory.create() if id_factory else None,
80
- universal=universal
81
- ))
82
- c.com_profile.parameters.inactivity_time_out = int(i.get("timeout", 120)) # todo: work only for HDLC, make better
83
- c.secret = bytes(i.get('secret', '0000000000000000'), 'utf-8')
84
- if m_id := i.get('m_id'):
85
- c.m_id.set(m_id)
86
- if port := i.get('port'):
87
- c.media.port = port
88
- if sap := i.get('sap'):
89
- c.SAP.set(sap)
90
- if (
91
- (da := i.get('da'))
92
- and da.isdigit()
93
- ):
94
- c.com_profile.parameters.device_address = int(da)
95
- if name := i.get("name"):
96
- c.name = name
97
- return res
53
+ raise ValueError("Table header not found")
54
+ # header is exist search column by name
55
+ field_names: list[str] = []
56
+ for index, cell in enumerate(first_row):
57
+ for column in _h:
58
+ if any(map(cell.lower().startswith, _h[column])):
59
+ field_names.append(_h[column][0])
60
+ break
61
+ else:
62
+ field_names.append(F"unknown{index}")
63
+ if all(map(lambda name: name in field_names, ("ip",))):
64
+ csv_file.seek(0)
65
+ reader = csv.DictReader(csv_file, fieldnames=field_names, dialect=dialect)
66
+ next(reader) # skeep header
67
+ res: list[Client] = []
68
+ for i in reader:
69
+ if IpAddress.is_valid(i["ip"]):
70
+ res.append(c := Client(
71
+ media=Network(
72
+ host=i.get("ip") or "127.0.0.1",
73
+ port=i.get("port") or "8888",
74
+ to_recv=float(i.get("timeout") or 120.0)
75
+ ),
76
+ SAP=int(i.get("sap") or 0x30),
77
+ secret=bytes(i.get("secret", "0000000000000000"), "utf-8"),
78
+ m_id=int(i.get("m_id") or 2),
79
+ id_=id_factory.create(),
80
+ universal=universal
81
+ ))
82
+ if (
83
+ (da := i.get("da"))
84
+ and da.isdigit()
85
+ ):
86
+ c.com_profile.parameters.device_address = int(da)
87
+ if name := i.get("name"):
88
+ c.name = name
89
+ return res
90
+ raise ValueError("not find at least one client")
@@ -104,7 +104,7 @@ class Base[T: result.Result](Protocol):
104
104
  return res_terminate
105
105
  return ret
106
106
 
107
- async def DL_connect(self, c: Client) -> None:
107
+ async def DL_connect(self, c: Client) -> result.Ok | result.Error:
108
108
  """Data link Layer connect"""
109
109
  c.send_frames.clear()
110
110
  # calculate addresses todo: move to c.com_profile(HDLC)
@@ -128,10 +128,12 @@ class Base[T: result.Result](Protocol):
128
128
  if isinstance(res_pdu := await c.read_data_block(), result.Error):
129
129
  return res_pdu
130
130
  c.level |= OSI.DATA_LINK
131
+ return result.OK
131
132
 
132
133
  async def data_link(self, c: Client) -> T | result.Error:
133
134
  if OSI.DATA_LINK not in c.level:
134
- await self.DL_connect(c)
135
+ if isinstance(res_conn := await self.DL_connect(c), result.Error):
136
+ return res_conn
135
137
  # todo: make tile
136
138
  return await self.application(c)
137
139
 
@@ -212,7 +214,11 @@ class Base[T: result.Result](Protocol):
212
214
  if isinstance(res_pdu := await c.read_data_block(), result.Error):
213
215
  return res_pdu
214
216
  # await c.read_attr(ut.CosemAttributeDescriptor((collection.ClassID.ASSOCIATION_LN, ut.CosemObjectInstanceId("0.0.40.0.0.255"), ut.CosemObjectAttributeId(6)))) # for test only
215
- match c.parseAareResponse(res_pdu.value):
217
+ try:
218
+ parse = c.parseAareResponse(res_pdu.value)
219
+ except IndexError as e:
220
+ print(e)
221
+ match parse:
216
222
  case AcseServiceUser.NULL:
217
223
  c.log(logL.INFO, "Authentication success")
218
224
  c.level |= OSI.APPLICATION
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: DLMS_SPODES_client
3
- Version: 0.19.25
3
+ Version: 0.19.28
4
4
  Summary: dlms-spodes
5
5
  Author-email: Serj Kotilevski <youserj@outlook.com>
6
6
  Project-URL: Source, https://github.com/youserj/SPODESclient_prj
@@ -1,12 +1,12 @@
1
1
  DLMS_SPODES_client/FCS16.py,sha256=RhoN4fX7eesKWfWCkRT_uWNfiQHqFd3T6lRwxfamUqw,2697
2
2
  DLMS_SPODES_client/__init__.py,sha256=6wphXvqkodng7h4nKNmkfldbaxf--IDVGfT0yNbas-o,449
3
- DLMS_SPODES_client/client.py,sha256=pRkFriDGu2DKZQDDNWmNaYXTRvPeWWIcITjfHwYx3CE,112082
3
+ DLMS_SPODES_client/client.py,sha256=HnsbECdBGzrlyT0RzNGweIBms5LKRNP4uUMSmaMEPIA,112148
4
4
  DLMS_SPODES_client/logger.py,sha256=zAbihLloMU99w8Sw3djQ0cwItzyGq0Fz8DI9_suazv4,1913
5
5
  DLMS_SPODES_client/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- DLMS_SPODES_client/services.py,sha256=xM_-h322V1bGBcw9cJh7XOSUMTL3_E-GX89-z3YwIYw,3909
6
+ DLMS_SPODES_client/services.py,sha256=g2Rv2j7mlIcNpnqxRZrKgSpy7k6pnaJHAkZ3JJUhK3s,3418
7
7
  DLMS_SPODES_client/session.py,sha256=nPzXujpmGSTFFvhyZRjgH_RLX1DS9moRddUEZuf-QEE,12760
8
8
  DLMS_SPODES_client/settings.py,sha256=6mitGe9UYeEgL61sf933MJ-S5N-ReoxvXqiI3agBGYE,1623
9
- DLMS_SPODES_client/task.py,sha256=wW6sjKKR31dc1FNKFptGTcob3mBRAVaOVa1h6tUWp10,78083
9
+ DLMS_SPODES_client/task.py,sha256=hylTkESBK3J8xVksmLGGhdGiI0tYNnkqShThZioaGN0,78300
10
10
  DLMS_SPODES_client/gurux_common/enums/TraceLevel.py,sha256=Ne0Rn3c9ACqQjmde_ksbiQxIUv6nXsPQRnhkGwIv3QI,521
11
11
  DLMS_SPODES_client/gurux_common/enums/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
12
  DLMS_SPODES_client/gurux_dlms/AesGcmParameter.py,sha256=HJt0uvxtkqKEkvfiqXTMNsiayN15AgPJa9_iMSSFZsQ,1429
@@ -54,8 +54,8 @@ DLMS_SPODES_client/gurux_dlms/enums/Task.py,sha256=chuOL6-IMxBvABUZtoFcaYaQQB4GZ
54
54
  DLMS_SPODES_client/gurux_dlms/enums/VdeStateError.py,sha256=qT87LMbIYEs3TYPIp3N-dR2Tcg9KhKyiELwhVl5U-tw,233
55
55
  DLMS_SPODES_client/gurux_dlms/enums/__init__.py,sha256=F_sgGwNmmdpbKvP1klJQUNiLXxU2BtZ-LgEI9e6xP8g,1314
56
56
  DLMS_SPODES_client/gurux_dlms/internal/_GXCommon.py,sha256=7D9EYcfiZxwbk8sfpHv7s2nYqrbmGf-Tbwv2T-gqmgk,53226
57
- dlms_spodes_client-0.19.25.dist-info/METADATA,sha256=bn_R-U_lc1TyTuOOGkNrUZFYRc6oDiEcYF7IZgISCl0,1062
58
- dlms_spodes_client-0.19.25.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
59
- dlms_spodes_client-0.19.25.dist-info/entry_points.txt,sha256=Z6UTeQjjCf2k1Y3Bjs0s7yr-UYSWb-TvJMuG2K2MApw,70
60
- dlms_spodes_client-0.19.25.dist-info/top_level.txt,sha256=rh_3Uig5bc6J_lKni01btol7dX_IgIJulNtGjGehmBE,19
61
- dlms_spodes_client-0.19.25.dist-info/RECORD,,
57
+ dlms_spodes_client-0.19.28.dist-info/METADATA,sha256=l2Fgx6uY4RUQlFP0zdS6UfHJFc_6sfFbdRJCama8LHQ,1062
58
+ dlms_spodes_client-0.19.28.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
59
+ dlms_spodes_client-0.19.28.dist-info/entry_points.txt,sha256=Z6UTeQjjCf2k1Y3Bjs0s7yr-UYSWb-TvJMuG2K2MApw,70
60
+ dlms_spodes_client-0.19.28.dist-info/top_level.txt,sha256=rh_3Uig5bc6J_lKni01btol7dX_IgIJulNtGjGehmBE,19
61
+ dlms_spodes_client-0.19.28.dist-info/RECORD,,