layrz-sdk 4.0.8__py3-none-any.whl → 4.0.10__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.
Potentially problematic release.
This version of layrz-sdk might be problematic. Click here for more details.
- layrz_sdk/entities/ats_possible_exit.py +0 -1
- layrz_sdk/entities/message.py +22 -8
- layrz_sdk/entities/operation.py +11 -0
- layrz_sdk/entities/operation_payload.py +11 -0
- layrz_sdk/entities/position.py +6 -6
- layrz_sdk/entities/report.py +40 -30
- layrz_sdk/entities/report_col.py +1 -0
- layrz_sdk/entities/telemetry/assetmessage.py +1 -1
- layrz_sdk/lcl/core.py +137 -117
- {layrz_sdk-4.0.8.dist-info → layrz_sdk-4.0.10.dist-info}/METADATA +6 -5
- {layrz_sdk-4.0.8.dist-info → layrz_sdk-4.0.10.dist-info}/RECORD +14 -14
- {layrz_sdk-4.0.8.dist-info → layrz_sdk-4.0.10.dist-info}/WHEEL +0 -0
- {layrz_sdk-4.0.8.dist-info → layrz_sdk-4.0.10.dist-info}/licenses/LICENSE +0 -0
- {layrz_sdk-4.0.8.dist-info → layrz_sdk-4.0.10.dist-info}/top_level.txt +0 -0
layrz_sdk/entities/message.py
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
"""Message entity"""
|
|
2
2
|
|
|
3
3
|
from datetime import datetime
|
|
4
|
-
from typing import Any
|
|
4
|
+
from typing import Any
|
|
5
5
|
|
|
6
|
-
from pydantic import BaseModel, Field
|
|
6
|
+
from pydantic import BaseModel, Field, field_validator
|
|
7
7
|
|
|
8
8
|
from layrz_sdk.constants import UTC
|
|
9
|
-
|
|
10
|
-
from .position import Position
|
|
11
|
-
|
|
12
|
-
PayloadType: TypeAlias = dict[str, Any]
|
|
9
|
+
from layrz_sdk.entities.geofence import Geofence
|
|
10
|
+
from layrz_sdk.entities.position import Position
|
|
13
11
|
|
|
14
12
|
|
|
15
13
|
class Message(BaseModel):
|
|
@@ -27,11 +25,11 @@ class Message(BaseModel):
|
|
|
27
25
|
default_factory=lambda: Position(),
|
|
28
26
|
description='Current position of the device',
|
|
29
27
|
)
|
|
30
|
-
payload:
|
|
28
|
+
payload: dict[str, Any] = Field(
|
|
31
29
|
default_factory=dict,
|
|
32
30
|
description='Payload data of the device message',
|
|
33
31
|
)
|
|
34
|
-
sensors:
|
|
32
|
+
sensors: dict[str, Any] = Field(
|
|
35
33
|
default_factory=dict,
|
|
36
34
|
description='Sensor data of the device message',
|
|
37
35
|
)
|
|
@@ -39,3 +37,19 @@ class Message(BaseModel):
|
|
|
39
37
|
default_factory=lambda: datetime.now(UTC),
|
|
40
38
|
description='Timestamp when the message was received',
|
|
41
39
|
)
|
|
40
|
+
|
|
41
|
+
geofences: list[Geofence] = Field(
|
|
42
|
+
default_factory=list,
|
|
43
|
+
description='List of geofences associated with the message',
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
@field_validator('geofences', mode='before')
|
|
47
|
+
def _validate_geofences(cls, value: Any) -> list[Geofence]:
|
|
48
|
+
"""Validate geofences"""
|
|
49
|
+
if value is None:
|
|
50
|
+
return []
|
|
51
|
+
|
|
52
|
+
if not isinstance(value, list):
|
|
53
|
+
return []
|
|
54
|
+
|
|
55
|
+
return value
|
layrz_sdk/entities/operation.py
CHANGED
|
@@ -150,6 +150,17 @@ class Operation(BaseModel):
|
|
|
150
150
|
description='Defines the destination phone numbers for Twilio notifications',
|
|
151
151
|
)
|
|
152
152
|
|
|
153
|
+
@field_validator('destination_phones', mode='before')
|
|
154
|
+
def serialize_destination_phones(cls, value: Any) -> list[DestinationPhone]:
|
|
155
|
+
"""Serialize destination phones to a list of DestinationPhone"""
|
|
156
|
+
if isinstance(value, list):
|
|
157
|
+
return value
|
|
158
|
+
|
|
159
|
+
if isinstance(value, DestinationPhone):
|
|
160
|
+
return [value]
|
|
161
|
+
|
|
162
|
+
return []
|
|
163
|
+
|
|
153
164
|
attach_image: bool = Field(
|
|
154
165
|
default=False,
|
|
155
166
|
description='Defines if the operation should attach an image',
|
|
@@ -204,6 +204,17 @@ class OperationPayload(BaseModel):
|
|
|
204
204
|
description='Defines the destination phone numbers for Twilio notifications',
|
|
205
205
|
)
|
|
206
206
|
|
|
207
|
+
@field_validator('destinations', mode='before')
|
|
208
|
+
def serialize_destinations(cls, value: Any) -> list[DestinationPhone]:
|
|
209
|
+
"""Serialize destinations to a list of DestinationPhone"""
|
|
210
|
+
if isinstance(value, list):
|
|
211
|
+
return value
|
|
212
|
+
|
|
213
|
+
if isinstance(value, DestinationPhone):
|
|
214
|
+
return [value]
|
|
215
|
+
|
|
216
|
+
return []
|
|
217
|
+
|
|
207
218
|
twilio_host_phone: DestinationPhone | None = Field(
|
|
208
219
|
default=None,
|
|
209
220
|
description='Defines the host phone number for Twilio notifications',
|
layrz_sdk/entities/position.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Position entity"""
|
|
2
2
|
|
|
3
|
-
from typing import Any, Self
|
|
3
|
+
from typing import Any, Self, cast
|
|
4
4
|
|
|
5
5
|
from pydantic import BaseModel, Field, field_validator
|
|
6
6
|
|
|
@@ -32,7 +32,7 @@ class Position(BaseModel):
|
|
|
32
32
|
value = float(value)
|
|
33
33
|
|
|
34
34
|
if -90 <= value <= 90:
|
|
35
|
-
return value
|
|
35
|
+
return cast(float, value)
|
|
36
36
|
|
|
37
37
|
return None
|
|
38
38
|
|
|
@@ -49,7 +49,7 @@ class Position(BaseModel):
|
|
|
49
49
|
value = float(value)
|
|
50
50
|
|
|
51
51
|
if -180 <= value <= 180:
|
|
52
|
-
return value
|
|
52
|
+
return cast(float, value)
|
|
53
53
|
|
|
54
54
|
return None
|
|
55
55
|
|
|
@@ -76,7 +76,7 @@ class Position(BaseModel):
|
|
|
76
76
|
if isinstance(value, int):
|
|
77
77
|
value = float(value)
|
|
78
78
|
|
|
79
|
-
return value
|
|
79
|
+
return cast(float, value)
|
|
80
80
|
|
|
81
81
|
@field_validator('speed', mode='before')
|
|
82
82
|
def _validate_speed(cls: Self, value: Any) -> None | float:
|
|
@@ -90,7 +90,7 @@ class Position(BaseModel):
|
|
|
90
90
|
if isinstance(value, int):
|
|
91
91
|
value = float(value)
|
|
92
92
|
|
|
93
|
-
return abs(value)
|
|
93
|
+
return cast(float, abs(value))
|
|
94
94
|
|
|
95
95
|
@field_validator('direction', mode='before')
|
|
96
96
|
def _validate_direction(cls: Self, value: Any) -> None | float:
|
|
@@ -105,6 +105,6 @@ class Position(BaseModel):
|
|
|
105
105
|
value = float(value)
|
|
106
106
|
|
|
107
107
|
if 0 <= value <= 360:
|
|
108
|
-
return value
|
|
108
|
+
return cast(float, value)
|
|
109
109
|
|
|
110
110
|
return None
|
layrz_sdk/entities/report.py
CHANGED
|
@@ -10,13 +10,12 @@ from typing import Any, Optional, Self
|
|
|
10
10
|
import xlsxwriter
|
|
11
11
|
from pydantic import BaseModel, Field, field_validator
|
|
12
12
|
|
|
13
|
+
from layrz_sdk.entities.custom_report_page import CustomReportPage
|
|
14
|
+
from layrz_sdk.entities.report_data_type import ReportDataType
|
|
15
|
+
from layrz_sdk.entities.report_format import ReportFormat
|
|
16
|
+
from layrz_sdk.entities.report_page import ReportPage
|
|
13
17
|
from layrz_sdk.helpers.color import use_black
|
|
14
18
|
|
|
15
|
-
from .custom_report_page import CustomReportPage
|
|
16
|
-
from .report_data_type import ReportDataType
|
|
17
|
-
from .report_format import ReportFormat
|
|
18
|
-
from .report_page import ReportPage
|
|
19
|
-
|
|
20
19
|
log = logging.getLogger(__name__)
|
|
21
20
|
|
|
22
21
|
|
|
@@ -87,6 +86,7 @@ class Report(BaseModel):
|
|
|
87
86
|
else:
|
|
88
87
|
raise AttributeError(f'Unsupported export format: {self.export_format}')
|
|
89
88
|
|
|
89
|
+
@warnings.deprecated('export_as_json is deprecated, use export with export_format=ReportFormat.JSON instead')
|
|
90
90
|
def export_as_json(self: Self) -> dict[str, Any]:
|
|
91
91
|
"""Returns the report as a JSON dict"""
|
|
92
92
|
return self._export_json()
|
|
@@ -98,7 +98,7 @@ class Report(BaseModel):
|
|
|
98
98
|
if isinstance(page, CustomReportPage):
|
|
99
99
|
continue
|
|
100
100
|
|
|
101
|
-
headers = []
|
|
101
|
+
headers: list[dict[str, Any]] = []
|
|
102
102
|
for header in page.headers:
|
|
103
103
|
headers.append(
|
|
104
104
|
{
|
|
@@ -231,34 +231,44 @@ class Report(BaseModel):
|
|
|
231
231
|
'font_name': 'Aptos Narrow',
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
+
format_ = book.add_format(style)
|
|
235
|
+
|
|
236
|
+
if cell.lock:
|
|
237
|
+
format_.set_locked(True)
|
|
238
|
+
|
|
234
239
|
value: Any = None
|
|
235
240
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
241
|
+
match cell.data_type:
|
|
242
|
+
case ReportDataType.BOOL:
|
|
243
|
+
value = 'Yes' if cell.content else 'No'
|
|
244
|
+
|
|
245
|
+
case ReportDataType.DATETIME:
|
|
246
|
+
value = cell.content.strftime(cell.datetime_format)
|
|
247
|
+
|
|
248
|
+
case ReportDataType.INT:
|
|
249
|
+
try:
|
|
250
|
+
value = int(cell.content)
|
|
251
|
+
except ValueError:
|
|
252
|
+
value = cell.content
|
|
253
|
+
log.warning(f'Invalid int value: {cell.content} in cell {i + 1}, {j}')
|
|
254
|
+
|
|
255
|
+
case ReportDataType.FLOAT:
|
|
256
|
+
try:
|
|
257
|
+
value = float(cell.content)
|
|
258
|
+
format_.set_num_format('0.00')
|
|
259
|
+
|
|
260
|
+
except ValueError:
|
|
261
|
+
value = cell.content
|
|
262
|
+
log.warning(f'Invalid float value: {cell.content} in cell {i + 1}, {j}')
|
|
263
|
+
|
|
264
|
+
case ReportDataType.CURRENCY:
|
|
248
265
|
value = float(cell.content)
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
elif cell.data_type == ReportDataType.CURRENCY:
|
|
254
|
-
value = float(cell.content)
|
|
255
|
-
style.update(
|
|
256
|
-
{'num_format': f'"{cell.currency_symbol}" * #,##0.00;[Red]"{cell.currency_symbol}" * #,##0.00'}
|
|
257
|
-
)
|
|
258
|
-
else:
|
|
259
|
-
value = cell.content
|
|
266
|
+
format_.set_num_format(f'"{cell.currency_symbol}" * #,##0.00;[Red]"{cell.currency_symbol}" * #,##0.00')
|
|
267
|
+
|
|
268
|
+
case _:
|
|
269
|
+
value = str(cell.content)
|
|
260
270
|
|
|
261
|
-
sheet.write(i + 1, j, value,
|
|
271
|
+
sheet.write(i + 1, j, value, format_)
|
|
262
272
|
|
|
263
273
|
if row.compact:
|
|
264
274
|
sheet.set_row(i + 1, None, None, {'level': 1, 'hidden': True})
|
layrz_sdk/entities/report_col.py
CHANGED
|
@@ -20,6 +20,7 @@ class ReportCol(BaseModel):
|
|
|
20
20
|
datetime_format: str = Field(description='Datetime format', default='%Y-%m-%d %H:%M:%S')
|
|
21
21
|
currency_symbol: str = Field(description='Currency symbol', default='')
|
|
22
22
|
bold: bool = Field(description='Bold text', default=False)
|
|
23
|
+
lock: bool = Field(description='Lock column', default=False)
|
|
23
24
|
|
|
24
25
|
@field_validator('text_color', mode='before')
|
|
25
26
|
def _validate_text_color(cls: Self, value: Any) -> Any:
|
|
@@ -117,7 +117,7 @@ class AssetMessage(BaseModel):
|
|
|
117
117
|
case AssetOperationMode.STATIC:
|
|
118
118
|
obj.position = asset.static_position.model_dump(exclude_none=True) if asset.static_position else {}
|
|
119
119
|
case AssetOperationMode.ZONE:
|
|
120
|
-
points = MultiPoint([(p.longitude, p.latitude) for p in asset.points])
|
|
120
|
+
points: MultiPoint = MultiPoint([(p.longitude, p.latitude) for p in asset.points])
|
|
121
121
|
obj.position = {'latitude': points.centroid.y, 'longitude': points.centroid.x}
|
|
122
122
|
case _:
|
|
123
123
|
obj.position = device_message.position
|
layrz_sdk/lcl/core.py
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"""Layrz Compute Language SDK"""
|
|
2
2
|
|
|
3
3
|
# ruff: noqa: ANN401
|
|
4
|
-
from typing import Any, Optional
|
|
5
|
-
|
|
6
|
-
from layrz_sdk.entities.message import PayloadType
|
|
4
|
+
from typing import Any, Optional, Self, cast
|
|
7
5
|
|
|
8
6
|
PATTERN_INVALID = 'Pattern should be string, received {received}'
|
|
9
7
|
INVALID_NUMBER_OF_PARAMS = 'Invalid number of arguments - Expected {expected} - Given {received}'
|
|
@@ -18,9 +16,9 @@ class LclCore:
|
|
|
18
16
|
def __init__(
|
|
19
17
|
self,
|
|
20
18
|
script: str = '',
|
|
21
|
-
sensors:
|
|
22
|
-
previous_sensors:
|
|
23
|
-
payload:
|
|
19
|
+
sensors: dict[str, Any] | None = None,
|
|
20
|
+
previous_sensors: dict[str, Any] | None = None,
|
|
21
|
+
payload: dict[str, Any] | None = None,
|
|
24
22
|
asset_constants: Optional[dict[str, Any]] = None,
|
|
25
23
|
custom_fields: Optional[dict[str, Any]] = None,
|
|
26
24
|
) -> None:
|
|
@@ -158,7 +156,7 @@ class LclCore:
|
|
|
158
156
|
|
|
159
157
|
return json.dumps(INVALID_ARGUMENTS.format(e=err))
|
|
160
158
|
|
|
161
|
-
def _standarize_datatypes(self, args:
|
|
159
|
+
def _standarize_datatypes(self: Self, args: Any) -> Any:
|
|
162
160
|
"""Standarize data types"""
|
|
163
161
|
result_args = []
|
|
164
162
|
|
|
@@ -170,7 +168,7 @@ class LclCore:
|
|
|
170
168
|
|
|
171
169
|
return result_args
|
|
172
170
|
|
|
173
|
-
def GET_PARAM(self, *args:
|
|
171
|
+
def GET_PARAM(self: Self, *args: Any) -> Any | None:
|
|
174
172
|
"""GET_PARAM Function"""
|
|
175
173
|
if len(args) > 2:
|
|
176
174
|
return INVALID_NUMBER_OF_PARAMS.format(expected=2, received=len(args))
|
|
@@ -178,17 +176,20 @@ class LclCore:
|
|
|
178
176
|
if args[0] is None:
|
|
179
177
|
return None
|
|
180
178
|
|
|
179
|
+
if not isinstance(args[0], str):
|
|
180
|
+
return f'Argument 0 should be a string, got {type(args[0]).__name__}'
|
|
181
|
+
|
|
181
182
|
if len(args) > 1:
|
|
182
|
-
return self._payload.get(args[0], args[1])
|
|
183
|
-
return self._payload.get(args[0], None)
|
|
183
|
+
return self._payload.get(args[0], args[1])
|
|
184
|
+
return self._payload.get(args[0], None)
|
|
184
185
|
|
|
185
|
-
def GET_DISTANCE_TRAVELED(self, *args:
|
|
186
|
+
def GET_DISTANCE_TRAVELED(self: Self, *args: Any) -> str | float:
|
|
186
187
|
"""GET_DISTANCE_TRAVELED Function"""
|
|
187
188
|
if len(args) > 0:
|
|
188
189
|
return INVALID_NUMBER_OF_PARAMS.format(expected=0, received=len(args))
|
|
189
|
-
return self._asset_constants.get('distanceTraveled', 0)
|
|
190
|
+
return cast(float, self._asset_constants.get('distanceTraveled', 0))
|
|
190
191
|
|
|
191
|
-
def GET_PREVIOUS_SENSOR(self, *args:
|
|
192
|
+
def GET_PREVIOUS_SENSOR(self: Self, *args: Any) -> Any:
|
|
192
193
|
"""GET_PREVIOUS_SENSOR Function"""
|
|
193
194
|
if len(args) < 1:
|
|
194
195
|
return INVALID_NUMBER_OF_PARAMS.format(expected=1, received=len(args))
|
|
@@ -200,10 +201,10 @@ class LclCore:
|
|
|
200
201
|
return None
|
|
201
202
|
|
|
202
203
|
if len(args) > 1:
|
|
203
|
-
return self._previous_sensors.get(args[0], args[1])
|
|
204
|
-
return self._previous_sensors.get(args[0], None)
|
|
204
|
+
return self._previous_sensors.get(args[0], args[1])
|
|
205
|
+
return self._previous_sensors.get(args[0], None)
|
|
205
206
|
|
|
206
|
-
def GET_SENSOR(self, *args:
|
|
207
|
+
def GET_SENSOR(self: Self, *args: Any) -> Any:
|
|
207
208
|
"""GET_SENSOR Function"""
|
|
208
209
|
if len(args) < 1:
|
|
209
210
|
return INVALID_NUMBER_OF_PARAMS.format(expected=1, received=len(args))
|
|
@@ -215,16 +216,16 @@ class LclCore:
|
|
|
215
216
|
return None
|
|
216
217
|
|
|
217
218
|
if len(args) > 1:
|
|
218
|
-
return self._sensors.get(args[0], args[1])
|
|
219
|
-
return self._sensors.get(args[0], None)
|
|
219
|
+
return self._sensors.get(args[0], args[1])
|
|
220
|
+
return self._sensors.get(args[0], None)
|
|
220
221
|
|
|
221
|
-
def CONSTANT(self, *args:
|
|
222
|
+
def CONSTANT(self: Self, *args: Any) -> Any:
|
|
222
223
|
"""CONSTANT Function"""
|
|
223
224
|
if len(args) > 1:
|
|
224
225
|
return INVALID_NUMBER_OF_PARAMS.format(expected=1, received=len(args))
|
|
225
226
|
return args[0]
|
|
226
227
|
|
|
227
|
-
def GET_CUSTOM_FIELD(self, *args:
|
|
228
|
+
def GET_CUSTOM_FIELD(self: Self, *args: Any) -> str | None:
|
|
228
229
|
"""GET_CUSTOM_FIELD Function"""
|
|
229
230
|
if len(args) > 2:
|
|
230
231
|
return INVALID_NUMBER_OF_PARAMS.format(expected=2, received=len(args))
|
|
@@ -233,11 +234,11 @@ class LclCore:
|
|
|
233
234
|
return None
|
|
234
235
|
|
|
235
236
|
if len(args) > 1:
|
|
236
|
-
return self._custom_fields.get(args[0], args[1])
|
|
237
|
+
return cast(str | None, self._custom_fields.get(args[0], args[1]))
|
|
237
238
|
|
|
238
|
-
return self._custom_fields.get(args[0], '')
|
|
239
|
+
return cast(str | None, self._custom_fields.get(args[0], ''))
|
|
239
240
|
|
|
240
|
-
def COMPARE(self, *args:
|
|
241
|
+
def COMPARE(self: Self, *args: Any) -> str | None | bool:
|
|
241
242
|
"""COMPARE Function"""
|
|
242
243
|
if len(args) != 2:
|
|
243
244
|
return INVALID_NUMBER_OF_PARAMS.format(expected=2, received=len(args))
|
|
@@ -245,13 +246,13 @@ class LclCore:
|
|
|
245
246
|
if args[0] is None or args[1] is None:
|
|
246
247
|
return None
|
|
247
248
|
|
|
248
|
-
args = self._standarize_datatypes(args)
|
|
249
|
+
args = self._standarize_datatypes(args)
|
|
249
250
|
|
|
250
251
|
if not isinstance(args[0], type(args[1])):
|
|
251
252
|
return DIFFERENT_TYPES.format(arg1=type(args[0]).__name__, arg2=type(args[1]).__name__)
|
|
252
|
-
return args[0] == args[1]
|
|
253
|
+
return cast(bool, args[0] == args[1])
|
|
253
254
|
|
|
254
|
-
def OR_OPERATOR(self, *args:
|
|
255
|
+
def OR_OPERATOR(self: Self, *args: Any) -> bool | None:
|
|
255
256
|
"""OR_OPERATOR Function"""
|
|
256
257
|
result = False
|
|
257
258
|
|
|
@@ -263,7 +264,7 @@ class LclCore:
|
|
|
263
264
|
|
|
264
265
|
return result
|
|
265
266
|
|
|
266
|
-
def AND_OPERATOR(self, *args:
|
|
267
|
+
def AND_OPERATOR(self: Self, *args: Any) -> bool | None:
|
|
267
268
|
"""AND_OPERATOR Function"""
|
|
268
269
|
result = False
|
|
269
270
|
is_first = True
|
|
@@ -274,30 +275,30 @@ class LclCore:
|
|
|
274
275
|
|
|
275
276
|
if is_first:
|
|
276
277
|
is_first = False
|
|
277
|
-
result = val
|
|
278
|
+
result = val
|
|
278
279
|
elif isinstance(val, bool):
|
|
279
280
|
result = result and val
|
|
280
281
|
|
|
281
282
|
return result
|
|
282
283
|
|
|
283
|
-
def SUM(self, *args:
|
|
284
|
+
def SUM(self: Self, *args: Any) -> float | None:
|
|
284
285
|
"""SUM Function"""
|
|
285
|
-
result = 0
|
|
286
|
+
result: float = 0
|
|
286
287
|
|
|
287
288
|
for num in args:
|
|
288
289
|
if num is None:
|
|
289
290
|
return None
|
|
290
291
|
|
|
291
292
|
try:
|
|
292
|
-
result += float(num)
|
|
293
|
+
result += float(num)
|
|
293
294
|
except Exception:
|
|
294
295
|
pass
|
|
295
296
|
|
|
296
297
|
return result
|
|
297
298
|
|
|
298
|
-
def SUBSTRACT(self, *args:
|
|
299
|
+
def SUBSTRACT(self: Self, *args: Any) -> float | None:
|
|
299
300
|
"""SUBSTRACT Function"""
|
|
300
|
-
result = 0
|
|
301
|
+
result: float = 0
|
|
301
302
|
is_first = True
|
|
302
303
|
|
|
303
304
|
for num in args:
|
|
@@ -306,18 +307,18 @@ class LclCore:
|
|
|
306
307
|
|
|
307
308
|
try:
|
|
308
309
|
if is_first:
|
|
309
|
-
result = float(num)
|
|
310
|
+
result = float(num)
|
|
310
311
|
is_first = False
|
|
311
312
|
else:
|
|
312
|
-
result -= float(num)
|
|
313
|
+
result -= float(num)
|
|
313
314
|
except Exception:
|
|
314
315
|
pass
|
|
315
316
|
|
|
316
317
|
return result
|
|
317
318
|
|
|
318
|
-
def MULTIPLY(self, *args:
|
|
319
|
+
def MULTIPLY(self: Self, *args: Any) -> float | None:
|
|
319
320
|
"""MULTIPLY Function"""
|
|
320
|
-
result = 0
|
|
321
|
+
result: float = 0
|
|
321
322
|
is_first = True
|
|
322
323
|
|
|
323
324
|
for num in args:
|
|
@@ -327,17 +328,17 @@ class LclCore:
|
|
|
327
328
|
try:
|
|
328
329
|
if is_first:
|
|
329
330
|
is_first = False
|
|
330
|
-
result = float(num)
|
|
331
|
+
result = float(num)
|
|
331
332
|
else:
|
|
332
|
-
result *= float(num)
|
|
333
|
+
result *= float(num)
|
|
333
334
|
except Exception:
|
|
334
335
|
pass
|
|
335
336
|
|
|
336
337
|
return result
|
|
337
338
|
|
|
338
|
-
def DIVIDE(self, *args:
|
|
339
|
+
def DIVIDE(self: Self, *args: Any) -> float | None:
|
|
339
340
|
"""DIVIDE Function"""
|
|
340
|
-
result = 0
|
|
341
|
+
result: float = 0
|
|
341
342
|
is_first = True
|
|
342
343
|
|
|
343
344
|
for num in args:
|
|
@@ -347,15 +348,15 @@ class LclCore:
|
|
|
347
348
|
try:
|
|
348
349
|
if is_first:
|
|
349
350
|
is_first = False
|
|
350
|
-
result = float(num)
|
|
351
|
+
result = float(num)
|
|
351
352
|
else:
|
|
352
|
-
result /= float(num)
|
|
353
|
+
result /= float(num)
|
|
353
354
|
except Exception:
|
|
354
355
|
pass
|
|
355
356
|
|
|
356
357
|
return result
|
|
357
358
|
|
|
358
|
-
def TO_BOOL(self, *args:
|
|
359
|
+
def TO_BOOL(self: Self, *args: Any) -> str | None | bool:
|
|
359
360
|
"""TO_BOOL Function"""
|
|
360
361
|
if len(args) > 1:
|
|
361
362
|
return INVALID_NUMBER_OF_PARAMS.format(expected=1, received=len(args))
|
|
@@ -365,7 +366,7 @@ class LclCore:
|
|
|
365
366
|
|
|
366
367
|
return bool(args[0])
|
|
367
368
|
|
|
368
|
-
def TO_STR(self, *args:
|
|
369
|
+
def TO_STR(self: Self, *args: Any) -> str | None:
|
|
369
370
|
"""TO_STR Function"""
|
|
370
371
|
if len(args) > 1:
|
|
371
372
|
return INVALID_NUMBER_OF_PARAMS.format(expected=1, received=len(args))
|
|
@@ -375,7 +376,7 @@ class LclCore:
|
|
|
375
376
|
|
|
376
377
|
return str(args[0])
|
|
377
378
|
|
|
378
|
-
def TO_INT(self, *args:
|
|
379
|
+
def TO_INT(self: Self, *args: Any) -> str | None | int:
|
|
379
380
|
"""TO_INT Function"""
|
|
380
381
|
if len(args) > 1:
|
|
381
382
|
return INVALID_NUMBER_OF_PARAMS.format(expected=1, received=len(args))
|
|
@@ -383,9 +384,9 @@ class LclCore:
|
|
|
383
384
|
if args[0] is None:
|
|
384
385
|
return None
|
|
385
386
|
|
|
386
|
-
return int(args[0])
|
|
387
|
+
return int(args[0])
|
|
387
388
|
|
|
388
|
-
def CEIL(self, *args:
|
|
389
|
+
def CEIL(self: Self, *args: Any) -> str | None | int:
|
|
389
390
|
"""CEIL Function"""
|
|
390
391
|
if len(args) > 1:
|
|
391
392
|
return INVALID_NUMBER_OF_PARAMS.format(expected=1, received=len(args))
|
|
@@ -400,7 +401,7 @@ class LclCore:
|
|
|
400
401
|
|
|
401
402
|
return math.ceil(args[0])
|
|
402
403
|
|
|
403
|
-
def FLOOR(self, *args:
|
|
404
|
+
def FLOOR(self: Self, *args: Any) -> str | None | int:
|
|
404
405
|
"""FLOOR Function"""
|
|
405
406
|
if len(args) > 1:
|
|
406
407
|
return INVALID_NUMBER_OF_PARAMS.format(expected=1, received=len(args))
|
|
@@ -415,7 +416,7 @@ class LclCore:
|
|
|
415
416
|
|
|
416
417
|
return math.floor(args[0])
|
|
417
418
|
|
|
418
|
-
def ROUND(self, *args:
|
|
419
|
+
def ROUND(self: Self, *args: Any) -> str | None | int:
|
|
419
420
|
"""ROUND Function"""
|
|
420
421
|
if len(args) > 1:
|
|
421
422
|
return INVALID_NUMBER_OF_PARAMS.format(expected=1, received=len(args))
|
|
@@ -428,7 +429,7 @@ class LclCore:
|
|
|
428
429
|
|
|
429
430
|
return round(args[0])
|
|
430
431
|
|
|
431
|
-
def SQRT(self, *args:
|
|
432
|
+
def SQRT(self: Self, *args: Any) -> str | None | float:
|
|
432
433
|
"""SQRT Function"""
|
|
433
434
|
if len(args) > 1:
|
|
434
435
|
return INVALID_NUMBER_OF_PARAMS.format(expected=1, received=len(args))
|
|
@@ -438,9 +439,9 @@ class LclCore:
|
|
|
438
439
|
|
|
439
440
|
import math
|
|
440
441
|
|
|
441
|
-
return math.sqrt(args[0])
|
|
442
|
+
return math.sqrt(args[0])
|
|
442
443
|
|
|
443
|
-
def CONCAT(self, *args:
|
|
444
|
+
def CONCAT(self: Self, *args: Any) -> str | None:
|
|
444
445
|
"""CONCAT Function"""
|
|
445
446
|
for val in args:
|
|
446
447
|
if val is None:
|
|
@@ -448,7 +449,7 @@ class LclCore:
|
|
|
448
449
|
|
|
449
450
|
return ''.join([str(val) for val in args])
|
|
450
451
|
|
|
451
|
-
def RANDOM(self, *args:
|
|
452
|
+
def RANDOM(self: Self, *args: Any) -> float | str | None:
|
|
452
453
|
"""RANDOM Function"""
|
|
453
454
|
if len(args) > 2:
|
|
454
455
|
return INVALID_NUMBER_OF_PARAMS.format(expected=2, received=len(args))
|
|
@@ -460,9 +461,9 @@ class LclCore:
|
|
|
460
461
|
|
|
461
462
|
import random
|
|
462
463
|
|
|
463
|
-
return random.random() * (float(args[1]) - float(args[0])) + float(args[0])
|
|
464
|
+
return random.random() * (float(args[1]) - float(args[0])) + float(args[0])
|
|
464
465
|
|
|
465
|
-
def RANDOM_INT(self, *args:
|
|
466
|
+
def RANDOM_INT(self: Self, *args: Any) -> int | str | None:
|
|
466
467
|
"""RANDOM_INT Function"""
|
|
467
468
|
if len(args) != 2:
|
|
468
469
|
return INVALID_NUMBER_OF_PARAMS.format(expected=2, received=len(args))
|
|
@@ -472,9 +473,9 @@ class LclCore:
|
|
|
472
473
|
|
|
473
474
|
import random
|
|
474
475
|
|
|
475
|
-
return random.randint(int(args[0]), int(args[1]))
|
|
476
|
+
return random.randint(int(args[0]), int(args[1]))
|
|
476
477
|
|
|
477
|
-
def GREATER_THAN_OR_EQUALS_TO(self, *args:
|
|
478
|
+
def GREATER_THAN_OR_EQUALS_TO(self: Self, *args: Any) -> str | None | bool:
|
|
478
479
|
"""GREATER_THAN_OR_EQUALS_TO Function"""
|
|
479
480
|
if len(args) > 2:
|
|
480
481
|
return INVALID_NUMBER_OF_PARAMS.format(expected=1, received=len(args))
|
|
@@ -484,13 +485,17 @@ class LclCore:
|
|
|
484
485
|
if args[0] is None or args[1] is None:
|
|
485
486
|
return None
|
|
486
487
|
|
|
487
|
-
args = self._standarize_datatypes(args)
|
|
488
|
+
args = self._standarize_datatypes(args)
|
|
489
|
+
|
|
490
|
+
if not isinstance(args[0], (int, float)):
|
|
491
|
+
return f'Invalid argument 0 - must be real number, not {type(args[0]).__name__}'
|
|
492
|
+
|
|
493
|
+
if not isinstance(args[1], (int, float)):
|
|
494
|
+
return f'Invalid argument 1 - must be real number, not {type(args[1]).__name__}'
|
|
488
495
|
|
|
489
|
-
if not isinstance(args[0], type(args[1])):
|
|
490
|
-
return DIFFERENT_TYPES.format(arg1=type(args[0]).__name__, arg2=type(args[1]).__name__)
|
|
491
496
|
return args[0] >= args[1]
|
|
492
497
|
|
|
493
|
-
def GREATER_THAN(self, *args:
|
|
498
|
+
def GREATER_THAN(self: Self, *args: Any) -> str | None | bool:
|
|
494
499
|
"""GREATER_THAN Function"""
|
|
495
500
|
if len(args) > 2:
|
|
496
501
|
return INVALID_NUMBER_OF_PARAMS.format(expected=1, received=len(args))
|
|
@@ -500,13 +505,17 @@ class LclCore:
|
|
|
500
505
|
if args[0] is None or args[1] is None:
|
|
501
506
|
return None
|
|
502
507
|
|
|
503
|
-
args = self._standarize_datatypes(args)
|
|
508
|
+
args = self._standarize_datatypes(args)
|
|
509
|
+
|
|
510
|
+
if not isinstance(args[0], (int, float)):
|
|
511
|
+
return f'Invalid argument 0 - must be real number, not {type(args[0]).__name__}'
|
|
512
|
+
|
|
513
|
+
if not isinstance(args[1], (int, float)):
|
|
514
|
+
return f'Invalid argument 1 - must be real number, not {type(args[1]).__name__}'
|
|
504
515
|
|
|
505
|
-
if not isinstance(args[0], type(args[1])):
|
|
506
|
-
return DIFFERENT_TYPES.format(arg1=type(args[0]).__name__, arg2=type(args[1]).__name__)
|
|
507
516
|
return args[0] > args[1]
|
|
508
517
|
|
|
509
|
-
def LESS_THAN_OR_EQUALS_TO(self, *args:
|
|
518
|
+
def LESS_THAN_OR_EQUALS_TO(self: Self, *args: Any) -> str | None | bool:
|
|
510
519
|
"""LESS_THAN_OR_EQUALS_TO Function"""
|
|
511
520
|
if len(args) > 2:
|
|
512
521
|
return INVALID_NUMBER_OF_PARAMS.format(expected=1, received=len(args))
|
|
@@ -516,13 +525,17 @@ class LclCore:
|
|
|
516
525
|
if args[0] is None or args[1] is None:
|
|
517
526
|
return None
|
|
518
527
|
|
|
519
|
-
args = self._standarize_datatypes(args)
|
|
528
|
+
args = self._standarize_datatypes(args)
|
|
529
|
+
|
|
530
|
+
if not isinstance(args[0], (int, float)):
|
|
531
|
+
return f'Invalid argument 0 - must be real number, not {type(args[0]).__name__}'
|
|
532
|
+
|
|
533
|
+
if not isinstance(args[1], (int, float)):
|
|
534
|
+
return f'Invalid argument 1 - must be real number, not {type(args[1]).__name__}'
|
|
520
535
|
|
|
521
|
-
if not isinstance(args[0], type(args[1])):
|
|
522
|
-
return DIFFERENT_TYPES.format(arg1=type(args[0]).__name__, arg2=type(args[1]).__name__)
|
|
523
536
|
return args[0] <= args[1]
|
|
524
537
|
|
|
525
|
-
def LESS_THAN(self, *args:
|
|
538
|
+
def LESS_THAN(self: Self, *args: Any) -> str | None | bool:
|
|
526
539
|
"""LESS_THAN Function"""
|
|
527
540
|
if len(args) > 2:
|
|
528
541
|
return INVALID_NUMBER_OF_PARAMS.format(expected=1, received=len(args))
|
|
@@ -532,13 +545,17 @@ class LclCore:
|
|
|
532
545
|
if args[0] is None or args[1] is None:
|
|
533
546
|
return None
|
|
534
547
|
|
|
535
|
-
args = self._standarize_datatypes(args)
|
|
548
|
+
args = self._standarize_datatypes(args)
|
|
549
|
+
|
|
550
|
+
if not isinstance(args[0], (int, float)):
|
|
551
|
+
return f'Invalid argument 0 - must be real number, not {type(args[0]).__name__}'
|
|
552
|
+
|
|
553
|
+
if not isinstance(args[1], (int, float)):
|
|
554
|
+
return f'Invalid argument 1 - must be real number, not {type(args[1]).__name__}'
|
|
536
555
|
|
|
537
|
-
if not isinstance(args[0], type(args[1])):
|
|
538
|
-
return DIFFERENT_TYPES.format(arg1=type(args[0]).__name__, arg2=type(args[1]).__name__)
|
|
539
556
|
return args[0] < args[1]
|
|
540
557
|
|
|
541
|
-
def DIFFERENT(self, *args:
|
|
558
|
+
def DIFFERENT(self: Self, *args: Any) -> str | None | bool:
|
|
542
559
|
"""DIFFERENT Function"""
|
|
543
560
|
if len(args) > 2:
|
|
544
561
|
return INVALID_NUMBER_OF_PARAMS.format(expected=1, received=len(args))
|
|
@@ -548,13 +565,14 @@ class LclCore:
|
|
|
548
565
|
if args[0] is None or args[1] is None:
|
|
549
566
|
return None
|
|
550
567
|
|
|
551
|
-
args = self._standarize_datatypes(args)
|
|
568
|
+
args = self._standarize_datatypes(args)
|
|
552
569
|
|
|
553
570
|
if not isinstance(args[0], type(args[1])):
|
|
554
571
|
return DIFFERENT_TYPES.format(arg1=type(args[0]).__name__, arg2=type(args[1]).__name__)
|
|
555
|
-
return args[0] != args[1]
|
|
556
572
|
|
|
557
|
-
|
|
573
|
+
return cast(bool, args[0] != args[1])
|
|
574
|
+
|
|
575
|
+
def HEX_TO_STR(self: Self, *args: Any) -> str | None:
|
|
558
576
|
"""HEX_TO_STR Function"""
|
|
559
577
|
if len(args) > 1:
|
|
560
578
|
return INVALID_NUMBER_OF_PARAMS.format(expected=1, received=len(args))
|
|
@@ -563,16 +581,16 @@ class LclCore:
|
|
|
563
581
|
return None
|
|
564
582
|
|
|
565
583
|
hexa = args[0]
|
|
566
|
-
if hexa.startswith('0x'):
|
|
584
|
+
if hexa.startswith('0x'):
|
|
567
585
|
hexa = hexa[2:]
|
|
568
586
|
|
|
569
587
|
try:
|
|
570
|
-
byte_array = bytes.fromhex(hexa)
|
|
588
|
+
byte_array = bytes.fromhex(hexa)
|
|
571
589
|
return byte_array.decode('ASCII')
|
|
572
590
|
except Exception:
|
|
573
591
|
return 'Invalid hex string'
|
|
574
592
|
|
|
575
|
-
def STR_TO_HEX(self, *args:
|
|
593
|
+
def STR_TO_HEX(self: Self, *args: Any) -> str | None:
|
|
576
594
|
"""STR_TO_HEX Function"""
|
|
577
595
|
if len(args) > 1:
|
|
578
596
|
return INVALID_NUMBER_OF_PARAMS.format(expected=1, received=len(args))
|
|
@@ -582,7 +600,7 @@ class LclCore:
|
|
|
582
600
|
|
|
583
601
|
return str(args[0]).encode('ASCII').hex()
|
|
584
602
|
|
|
585
|
-
def HEX_TO_INT(self, *args:
|
|
603
|
+
def HEX_TO_INT(self: Self, *args: Any) -> str | None | int:
|
|
586
604
|
"""HEX_TO_INT Function"""
|
|
587
605
|
if len(args) > 1:
|
|
588
606
|
return INVALID_NUMBER_OF_PARAMS.format(expected=1, received=len(args))
|
|
@@ -591,11 +609,11 @@ class LclCore:
|
|
|
591
609
|
return None
|
|
592
610
|
|
|
593
611
|
try:
|
|
594
|
-
return int(int(args[0], 16))
|
|
612
|
+
return int(int(args[0], 16))
|
|
595
613
|
except Exception:
|
|
596
614
|
return 'Invalid hex string'
|
|
597
615
|
|
|
598
|
-
def INT_TO_HEX(self, *args:
|
|
616
|
+
def INT_TO_HEX(self: Self, *args: Any) -> str | None:
|
|
599
617
|
"""INT_TO_HEX Function"""
|
|
600
618
|
if len(args) > 1:
|
|
601
619
|
return INVALID_NUMBER_OF_PARAMS.format(expected=1, received=len(args))
|
|
@@ -604,11 +622,11 @@ class LclCore:
|
|
|
604
622
|
return None
|
|
605
623
|
|
|
606
624
|
try:
|
|
607
|
-
return hex(int(args[0]))[2:]
|
|
625
|
+
return hex(int(args[0]))[2:]
|
|
608
626
|
except Exception:
|
|
609
627
|
return 'Invalid int value'
|
|
610
628
|
|
|
611
|
-
def TO_FLOAT(self, *args:
|
|
629
|
+
def TO_FLOAT(self: Self, *args: Any) -> str | None | float:
|
|
612
630
|
"""TO_FLOAT Function"""
|
|
613
631
|
if len(args) > 1:
|
|
614
632
|
return INVALID_NUMBER_OF_PARAMS.format(expected=1, received=len(args))
|
|
@@ -617,11 +635,11 @@ class LclCore:
|
|
|
617
635
|
return None
|
|
618
636
|
|
|
619
637
|
try:
|
|
620
|
-
return float(args[0])
|
|
638
|
+
return float(args[0])
|
|
621
639
|
except Exception:
|
|
622
640
|
return f'Invalid arguments - must be real number, not {type(args[0]).__name__}'
|
|
623
641
|
|
|
624
|
-
def IS_PARAMETER_PRESENT(self, *args:
|
|
642
|
+
def IS_PARAMETER_PRESENT(self: Self, *args: Any) -> str | bool | None:
|
|
625
643
|
"""IS_PARAMETER_PRESENT Function"""
|
|
626
644
|
if len(args) > 1:
|
|
627
645
|
return INVALID_NUMBER_OF_PARAMS.format(expected=1, received=len(args))
|
|
@@ -629,9 +647,9 @@ class LclCore:
|
|
|
629
647
|
if args[0] is None:
|
|
630
648
|
return None
|
|
631
649
|
|
|
632
|
-
return args[0] in self._payload
|
|
650
|
+
return args[0] in self._payload
|
|
633
651
|
|
|
634
|
-
def IS_SENSOR_PRESENT(self, *args:
|
|
652
|
+
def IS_SENSOR_PRESENT(self: Self, *args: Any) -> str | bool | None:
|
|
635
653
|
"""IS_SENSOR_PRESENT Function"""
|
|
636
654
|
if len(args) > 1:
|
|
637
655
|
return INVALID_NUMBER_OF_PARAMS.format(expected=1, received=len(args))
|
|
@@ -639,9 +657,9 @@ class LclCore:
|
|
|
639
657
|
if args[0] is None:
|
|
640
658
|
return None
|
|
641
659
|
|
|
642
|
-
return args[0] in self._sensors
|
|
660
|
+
return args[0] in self._sensors
|
|
643
661
|
|
|
644
|
-
def INSIDE_RANGE(self, *args:
|
|
662
|
+
def INSIDE_RANGE(self: Self, *args: Any) -> str | None | bool:
|
|
645
663
|
"""INSIDE_RANGE Function"""
|
|
646
664
|
if len(args) != 3:
|
|
647
665
|
return INVALID_NUMBER_OF_PARAMS.format(expected=3, received=len(args))
|
|
@@ -649,18 +667,20 @@ class LclCore:
|
|
|
649
667
|
if args[0] is None or args[1] is None or args[2] is None:
|
|
650
668
|
return None
|
|
651
669
|
|
|
652
|
-
args = self._standarize_datatypes(args)
|
|
670
|
+
args = self._standarize_datatypes(args)
|
|
653
671
|
|
|
654
|
-
if not isinstance(args[0],
|
|
655
|
-
return
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
672
|
+
if not isinstance(args[0], (int, float)):
|
|
673
|
+
return f'Invalid argument 0 - must be real number, not {type(args[0]).__name__}'
|
|
674
|
+
|
|
675
|
+
if not isinstance(args[1], (int, float)):
|
|
676
|
+
return f'Invalid argument 1 - must be real number, not {type(args[1]).__name__}'
|
|
677
|
+
|
|
678
|
+
if not isinstance(args[2], (int, float)):
|
|
679
|
+
return f'Invalid argument 2 - must be real number, not {type(args[2]).__name__}'
|
|
660
680
|
|
|
661
681
|
return args[1] <= args[0] <= args[2]
|
|
662
682
|
|
|
663
|
-
def OUTSIDE_RANGE(self, *args:
|
|
683
|
+
def OUTSIDE_RANGE(self: Self, *args: Any) -> str | None | bool:
|
|
664
684
|
"""OUTSIDE_RANGE Function"""
|
|
665
685
|
if len(args) != 3:
|
|
666
686
|
return INVALID_NUMBER_OF_PARAMS.format(expected=3, received=len(args))
|
|
@@ -668,7 +688,7 @@ class LclCore:
|
|
|
668
688
|
if args[0] is None or args[1] is None or args[2] is None:
|
|
669
689
|
return None
|
|
670
690
|
|
|
671
|
-
args = self._standarize_datatypes(args)
|
|
691
|
+
args = self._standarize_datatypes(args)
|
|
672
692
|
|
|
673
693
|
if not isinstance(args[0], type(args[1])):
|
|
674
694
|
return DIFFERENT_TYPES_RANGES.format(
|
|
@@ -679,14 +699,14 @@ class LclCore:
|
|
|
679
699
|
|
|
680
700
|
return not args[1] <= args[0] <= args[2]
|
|
681
701
|
|
|
682
|
-
def GET_TIME_DIFFERENCE(self, *args:
|
|
702
|
+
def GET_TIME_DIFFERENCE(self: Self, *args: Any) -> str | float:
|
|
683
703
|
"""GET_TIME_DIFFERENCE Function"""
|
|
684
704
|
if len(args) > 0:
|
|
685
705
|
return INVALID_NUMBER_OF_PARAMS.format(expected=0, received=len(args))
|
|
686
706
|
|
|
687
|
-
return self._asset_constants.get('timeElapsed', 0)
|
|
707
|
+
return cast(float, self._asset_constants.get('timeElapsed', 0))
|
|
688
708
|
|
|
689
|
-
def IF(self, *args:
|
|
709
|
+
def IF(self: Self, *args: Any) -> Any:
|
|
690
710
|
"""IF Function"""
|
|
691
711
|
if len(args) != 3:
|
|
692
712
|
return INVALID_NUMBER_OF_PARAMS.format(expected=3, received=len(args))
|
|
@@ -696,14 +716,14 @@ class LclCore:
|
|
|
696
716
|
|
|
697
717
|
return args[1] if args[0] else args[2]
|
|
698
718
|
|
|
699
|
-
def NOW(self, *args:
|
|
719
|
+
def NOW(self: Self, *args: Any) -> float:
|
|
700
720
|
"""NOW Function"""
|
|
701
721
|
import zoneinfo
|
|
702
722
|
from datetime import datetime
|
|
703
723
|
|
|
704
724
|
return datetime.now(tz=zoneinfo.ZoneInfo('UTC')).timestamp()
|
|
705
725
|
|
|
706
|
-
def REGEX(self, *args:
|
|
726
|
+
def REGEX(self: Self, *args: Any) -> str | None | bool:
|
|
707
727
|
"""REGEX Function"""
|
|
708
728
|
if len(args) != 2:
|
|
709
729
|
return INVALID_NUMBER_OF_PARAMS.format(expected=2, received=len(args))
|
|
@@ -719,14 +739,14 @@ class LclCore:
|
|
|
719
739
|
pattern = re.compile(args[1])
|
|
720
740
|
return bool(pattern.match(args[0]))
|
|
721
741
|
|
|
722
|
-
def IS_NONE(self, *args:
|
|
742
|
+
def IS_NONE(self: Self, *args: Any) -> str | bool:
|
|
723
743
|
"""IS_NONE Function"""
|
|
724
744
|
if len(args) != 1:
|
|
725
745
|
return INVALID_NUMBER_OF_PARAMS.format(expected=1, received=len(args))
|
|
726
746
|
|
|
727
747
|
return args[0] is None
|
|
728
748
|
|
|
729
|
-
def NOT(self, *args:
|
|
749
|
+
def NOT(self: Self, *args: Any) -> str | bool | None:
|
|
730
750
|
"""NOT Function"""
|
|
731
751
|
if len(args) != 1:
|
|
732
752
|
return INVALID_NUMBER_OF_PARAMS.format(expected=1, received=len(args))
|
|
@@ -736,7 +756,7 @@ class LclCore:
|
|
|
736
756
|
|
|
737
757
|
return not args[0]
|
|
738
758
|
|
|
739
|
-
def CONTAINS(self, *args:
|
|
759
|
+
def CONTAINS(self: Self, *args: Any) -> str | bool | None:
|
|
740
760
|
"""CONTAINS function"""
|
|
741
761
|
if len(args) != 2:
|
|
742
762
|
return INVALID_NUMBER_OF_PARAMS.format(expected=2, received=len(args))
|
|
@@ -746,7 +766,7 @@ class LclCore:
|
|
|
746
766
|
|
|
747
767
|
return str(args[0]) in str(args[1])
|
|
748
768
|
|
|
749
|
-
def STARTS_WITH(self, *args:
|
|
769
|
+
def STARTS_WITH(self: Self, *args: Any) -> str | bool | None:
|
|
750
770
|
"""STARTS_WITH function"""
|
|
751
771
|
if len(args) != 2:
|
|
752
772
|
return INVALID_NUMBER_OF_PARAMS.format(expected=2, received=len(args))
|
|
@@ -756,7 +776,7 @@ class LclCore:
|
|
|
756
776
|
|
|
757
777
|
return str(args[1]).startswith(str(args[0]))
|
|
758
778
|
|
|
759
|
-
def ENDS_WITH(self, *args:
|
|
779
|
+
def ENDS_WITH(self: Self, *args: Any) -> str | bool | None:
|
|
760
780
|
"""ENDS_WITH function"""
|
|
761
781
|
if len(args) != 2:
|
|
762
782
|
return INVALID_NUMBER_OF_PARAMS.format(expected=2, received=len(args))
|
|
@@ -766,14 +786,14 @@ class LclCore:
|
|
|
766
786
|
|
|
767
787
|
return str(args[1]).endswith(str(args[0]))
|
|
768
788
|
|
|
769
|
-
def PRIMARY_DEVICE(self, *args:
|
|
789
|
+
def PRIMARY_DEVICE(self: Self, *args: Any) -> str | None:
|
|
770
790
|
"""PRIMARY_DEVICE function"""
|
|
771
791
|
if len(args) > 0:
|
|
772
792
|
return INVALID_NUMBER_OF_PARAMS.format(expected=0, received=len(args))
|
|
773
793
|
|
|
774
|
-
return self._asset_constants.get('primaryDevice', None)
|
|
794
|
+
return self._asset_constants.get('primaryDevice', None)
|
|
775
795
|
|
|
776
|
-
def SUBSTRING(self, *args:
|
|
796
|
+
def SUBSTRING(self: Self, *args: Any) -> str | None:
|
|
777
797
|
"""Get a substring from string (args[0])"""
|
|
778
798
|
if len(args) < 2:
|
|
779
799
|
return INVALID_NUMBER_OF_PARAMS.format(
|
|
@@ -809,7 +829,7 @@ class LclCore:
|
|
|
809
829
|
return args[0][args[1] : args[2]]
|
|
810
830
|
return args[0][args[1] :]
|
|
811
831
|
|
|
812
|
-
def UNIX_TO_STR(self, *args:
|
|
832
|
+
def UNIX_TO_STR(self: Self, *args: Any) -> str | None:
|
|
813
833
|
"""Convert UNIX timestamp date (args[0]) to format (args[1]) string"""
|
|
814
834
|
if len(args) < 2:
|
|
815
835
|
return INVALID_NUMBER_OF_PARAMS.format(expected=2, received=len(args))
|
|
@@ -830,13 +850,13 @@ class LclCore:
|
|
|
830
850
|
return None
|
|
831
851
|
|
|
832
852
|
try:
|
|
833
|
-
tz = zoneinfo.ZoneInfo(args[2])
|
|
853
|
+
tz = zoneinfo.ZoneInfo(args[2])
|
|
834
854
|
except zoneinfo.ZoneInfoNotFoundError:
|
|
835
855
|
tz = zoneinfo.ZoneInfo('UTC')
|
|
836
856
|
|
|
837
|
-
return datetime.fromtimestamp(int(args[0]), tz=zoneinfo.ZoneInfo('UTC')).astimezone(tz).strftime(args[1])
|
|
857
|
+
return datetime.fromtimestamp(int(args[0]), tz=zoneinfo.ZoneInfo('UTC')).astimezone(tz).strftime(args[1])
|
|
838
858
|
|
|
839
|
-
def VERSION(self, *args:
|
|
859
|
+
def VERSION(self: Self, *args: Any) -> str:
|
|
840
860
|
"""VERSION function"""
|
|
841
861
|
if len(args) > 0:
|
|
842
862
|
return INVALID_NUMBER_OF_PARAMS.format(expected=0, received=len(args))
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: layrz-sdk
|
|
3
|
-
Version: 4.0.
|
|
3
|
+
Version: 4.0.10
|
|
4
4
|
Summary: Layrz SDK for Python
|
|
5
5
|
Author-email: "Golden M, Inc." <software@goldenm.com>
|
|
6
6
|
Maintainer-email: Kenny Mochizuki <kenny@goldenm.com>, Luis Reyes <lreyes@goldenm.com>, Kasen Li <kli@goldenm.com>, Miguel Zauzich <miguel@goldenm.com>, Angel Prieto <aprieto@goldenm.com>
|
|
@@ -12,17 +12,18 @@ Classifier: Programming Language :: Python :: 3
|
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.13
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.14
|
|
14
14
|
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
15
17
|
Requires-Python: >=3.13
|
|
16
18
|
Description-Content-Type: text/markdown
|
|
17
19
|
License-File: LICENSE
|
|
18
|
-
Requires-Dist:
|
|
19
|
-
Requires-Dist: xlsxwriter
|
|
20
|
-
Requires-Dist: tzdata
|
|
20
|
+
Requires-Dist: xlsxwriter<4.0.0,>=3.2.5
|
|
21
21
|
Requires-Dist: pydantic>=2.10.6
|
|
22
|
-
Requires-Dist: typing-extensions>=4.10.0
|
|
23
22
|
Requires-Dist: geopy>=2.4.1
|
|
24
23
|
Requires-Dist: shapely>=2.1.1
|
|
25
24
|
Requires-Dist: strenum>=0.4.15
|
|
25
|
+
Requires-Dist: requests>=2.32.4
|
|
26
|
+
Requires-Dist: tzdata>=2025.2
|
|
26
27
|
Dynamic: license-file
|
|
27
28
|
|
|
28
29
|
# Layrz SDK
|
|
@@ -13,7 +13,7 @@ layrz_sdk/entities/asset_operation_mode.py,sha256=umvmRb8W3kEDUd9dqyKhJ745xe3wss
|
|
|
13
13
|
layrz_sdk/entities/ats_entry.py,sha256=wtrw3F9Pkirn0uGIvWyxbSqf36GWu2CRfqXuc5legmQ,669
|
|
14
14
|
layrz_sdk/entities/ats_exit_history.py,sha256=qfeOQcMQqoGEYk0Tp1Oe5K7M_nld7JxpX09rPUQl7hc,1457
|
|
15
15
|
layrz_sdk/entities/ats_possible_entry.py,sha256=M3eWsKvzE4V2YdP2udB5Kih_8hSHw923jG16YYT_gtw,1461
|
|
16
|
-
layrz_sdk/entities/ats_possible_exit.py,sha256=
|
|
16
|
+
layrz_sdk/entities/ats_possible_exit.py,sha256=gCibHlXicrs7dsACVWIBZ-I7RqEbdbKJQllxkjHNHoY,1822
|
|
17
17
|
layrz_sdk/entities/ats_reception.py,sha256=DuZSsH92wP3cJE-q6g2hxyd4d-tN06hruS6P1pg2FBY,946
|
|
18
18
|
layrz_sdk/entities/case.py,sha256=4ufVTeVRNpLOe0cx2vUWLsraP4mePq8gNl8mt7-XFPo,1782
|
|
19
19
|
layrz_sdk/entities/case_ignored_status.py,sha256=B7HDz6MAD3lQAab2gx5w6wcG_Yp6DRc2VXpeS2M45fw,429
|
|
@@ -31,19 +31,19 @@ layrz_sdk/entities/function.py,sha256=rmUkw0QxD9NpKb1eL42aSsvEa6zPN41MpD86aIKjyB
|
|
|
31
31
|
layrz_sdk/entities/geofence.py,sha256=AORR54bX1mCHCqfvy4iXb3BkeZ1zsf8rcuH7rIET8Mo,338
|
|
32
32
|
layrz_sdk/entities/geofence_category.py,sha256=h9elE_NqDXeOPGGjtwI2AQacl2ijCJP05_cXBnUXf_4,900
|
|
33
33
|
layrz_sdk/entities/last_message.py,sha256=QNgF0xCQ6uLFDMmKQCjSRhGS1Bq7akw5pv6ZIiFlwfY,268
|
|
34
|
-
layrz_sdk/entities/message.py,sha256=
|
|
34
|
+
layrz_sdk/entities/message.py,sha256=UXXIdfJTmf2070_FsrHc2a_nQ5RcXMYQqvNyyKcaHMM,1415
|
|
35
35
|
layrz_sdk/entities/notification_type.py,sha256=WTAFt8cOczXHsIk4RIDbakbtW_JqlvAg7PdW8EVqDew,669
|
|
36
|
-
layrz_sdk/entities/operation.py,sha256=
|
|
36
|
+
layrz_sdk/entities/operation.py,sha256=n2WM2hnvzFznXY5HZWRWQwCymQl9DCHrjUrDepDtf7k,6557
|
|
37
37
|
layrz_sdk/entities/operation_case_payload.py,sha256=NSsZbtP_Iz1At7ok4xlVFzk40Vx_-7wBYMgYNV5Ftu8,2520
|
|
38
|
-
layrz_sdk/entities/operation_payload.py,sha256=
|
|
38
|
+
layrz_sdk/entities/operation_payload.py,sha256=2tDWeDuV76KqlzrPI9hPjKGs60Rd9WDQZVCa0DEqlFg,8904
|
|
39
39
|
layrz_sdk/entities/operation_type.py,sha256=NAe_suR3Zfazu5KsYsPya8AtkSaNNjh78XPBEIqMTQU,939
|
|
40
40
|
layrz_sdk/entities/outbound_service.py,sha256=mDtMwTql8sHmFayP1AnGdMgegF6tsvu-xSC2ftGVNJo,663
|
|
41
41
|
layrz_sdk/entities/platform.py,sha256=fJQXFwRhG_L9h2h7lm_KYqpssJgYtRbfTWPy7BqOnOE,626
|
|
42
|
-
layrz_sdk/entities/position.py,sha256=
|
|
42
|
+
layrz_sdk/entities/position.py,sha256=kbq3xrlHVtSUBx0qI9lXrL7cLdg-vps5g3x9u7anHtE,2973
|
|
43
43
|
layrz_sdk/entities/presence_type.py,sha256=1p_MVREYkB7pey_TUf51QXQdlY5okZpkbiEd_l6oa04,335
|
|
44
44
|
layrz_sdk/entities/preset.py,sha256=1SKTdV2JM1d3vr0cgQyzmtYswtu3JQwkERfpC2Rkt_w,705
|
|
45
|
-
layrz_sdk/entities/report.py,sha256=
|
|
46
|
-
layrz_sdk/entities/report_col.py,sha256=
|
|
45
|
+
layrz_sdk/entities/report.py,sha256=uuK8Sw5jdstr-fzxpNBITHZQyPOysqiptPTtEA7-bxc,9271
|
|
46
|
+
layrz_sdk/entities/report_col.py,sha256=IJds9joY6Wqn187tgcb8LKCRJNCbQ9tassSYdv3jlXI,1317
|
|
47
47
|
layrz_sdk/entities/report_configuration.py,sha256=USgpkEBr40nzS3LW9jd1MF34pFDN1XckgAHsfdJcFTA,236
|
|
48
48
|
layrz_sdk/entities/report_data_type.py,sha256=hIsvSzdfjXQnivj6fI0csmVZtCKbvMGod2-h99RQ428,414
|
|
49
49
|
layrz_sdk/entities/report_format.py,sha256=FzEt1gC-Nwcz8AZAF5tANpocy0qzjxf2TB-tt3VtjKc,399
|
|
@@ -103,14 +103,14 @@ layrz_sdk/entities/modbus/schema.py,sha256=gyL0VyGSXTZWzsamjLUGoW5cqhn7MfXisCbH_
|
|
|
103
103
|
layrz_sdk/entities/modbus/status.py,sha256=VnsWAR7C2dz7Y6_dPCnvS3CBaMaP7odZSu6db2KaTlE,611
|
|
104
104
|
layrz_sdk/entities/modbus/wait.py,sha256=n3p_miYfGde1sxo4OznqWJAOb_WKblOnwFRib3RY_uM,4031
|
|
105
105
|
layrz_sdk/entities/telemetry/__init__.py,sha256=hfyekj-4_iB-aEbw43DXtSuMLBtMR1uoL8vvkRa_nJg,149
|
|
106
|
-
layrz_sdk/entities/telemetry/assetmessage.py,sha256=
|
|
106
|
+
layrz_sdk/entities/telemetry/assetmessage.py,sha256=vKnuOiKLRnHRfp0FAr-ZaSd_eSx4GBEvURxuomZsFk8,5149
|
|
107
107
|
layrz_sdk/entities/telemetry/devicemessage.py,sha256=1IQFUWZMBXLo-RSYYIxHdFX-fLSqplSiraUCjVH4-b4,3176
|
|
108
108
|
layrz_sdk/helpers/__init__.py,sha256=5iW3z2m3jrYhvTfxX-p-QTkR9X9oTKfEsbtVOg9jFFY,115
|
|
109
109
|
layrz_sdk/helpers/color.py,sha256=dlpMafbM-4Wd9D9hMbbnZJf4ALkpie_ZmBR2Vz_YCmM,1203
|
|
110
110
|
layrz_sdk/lcl/__init__.py,sha256=U967AWANkL3u_YVxMNAYlh8jkZ6hqHfStacz7yz6sOA,89
|
|
111
|
-
layrz_sdk/lcl/core.py,sha256=
|
|
112
|
-
layrz_sdk-4.0.
|
|
113
|
-
layrz_sdk-4.0.
|
|
114
|
-
layrz_sdk-4.0.
|
|
115
|
-
layrz_sdk-4.0.
|
|
116
|
-
layrz_sdk-4.0.
|
|
111
|
+
layrz_sdk/lcl/core.py,sha256=_3uK05I0iwJl63cVWKxt-qFkq0DWggCj5M680GHH5uQ,25161
|
|
112
|
+
layrz_sdk-4.0.10.dist-info/licenses/LICENSE,sha256=d5ZrU--lIPER7QByXDKcrtOTOMk1JvN_9FdYDuoWi7Y,1057
|
|
113
|
+
layrz_sdk-4.0.10.dist-info/METADATA,sha256=DF3b0HJ5tkQhzCHLFzLLZNGPwUpEcQG7gULrmiKLAN8,2045
|
|
114
|
+
layrz_sdk-4.0.10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
115
|
+
layrz_sdk-4.0.10.dist-info/top_level.txt,sha256=yUTMMzfdZ0HDWQH5TaSlFM4xtwmP1fSGxmlL1dmu4l4,10
|
|
116
|
+
layrz_sdk-4.0.10.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|