layrz-sdk 4.0.11__py3-none-any.whl → 4.1.8__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.
- layrz_sdk/decorators/__init__.py +5 -0
- layrz_sdk/decorators/func_timing.py +103 -0
- layrz_sdk/entities/__init__.py +19 -0
- layrz_sdk/entities/action.py +28 -16
- layrz_sdk/entities/action_geofence_ownership.py +0 -2
- layrz_sdk/entities/action_kind.py +0 -2
- layrz_sdk/entities/action_subkind.py +0 -2
- layrz_sdk/entities/asset.py +20 -9
- layrz_sdk/entities/asset_constants.py +10 -9
- layrz_sdk/entities/asset_contact.py +7 -3
- layrz_sdk/entities/asset_operation_mode.py +0 -2
- layrz_sdk/entities/ats_entry.py +11 -4
- layrz_sdk/entities/ats_exit_history.py +21 -19
- layrz_sdk/entities/ats_operation.py +87 -0
- layrz_sdk/entities/ats_possible_entry.py +10 -7
- layrz_sdk/entities/ats_possible_exit.py +19 -9
- layrz_sdk/entities/ats_purchaseorder.py +106 -0
- layrz_sdk/entities/ats_reception.py +16 -4
- layrz_sdk/entities/broadcast/__init__.py +2 -1
- layrz_sdk/entities/broadcast/payload.py +40 -8
- layrz_sdk/entities/broadcast/result.py +72 -1
- layrz_sdk/entities/broadcast/service.py +12 -2
- layrz_sdk/entities/broadcast/status.py +2 -2
- layrz_sdk/entities/case.py +51 -8
- layrz_sdk/entities/case_ignored_status.py +1 -0
- layrz_sdk/entities/charts/axis_config.py +13 -5
- layrz_sdk/entities/charts/bar_chart.py +12 -1
- layrz_sdk/entities/charts/chart_data_serie.py +17 -1
- layrz_sdk/entities/charts/column_chart.py +12 -1
- layrz_sdk/entities/charts/html_chart.py +8 -4
- layrz_sdk/entities/charts/line_chart.py +12 -3
- layrz_sdk/entities/charts/map_chart.py +14 -5
- layrz_sdk/entities/charts/map_point.py +7 -1
- layrz_sdk/entities/charts/number_chart.py +8 -4
- layrz_sdk/entities/charts/pie_chart.py +11 -3
- layrz_sdk/entities/charts/radar_chart.py +11 -3
- layrz_sdk/entities/charts/radial_bar_chart.py +11 -3
- layrz_sdk/entities/charts/scatter_chart.py +12 -3
- layrz_sdk/entities/charts/scatter_serie.py +11 -1
- layrz_sdk/entities/charts/scatter_serie_item.py +7 -1
- layrz_sdk/entities/charts/table_chart.py +7 -3
- layrz_sdk/entities/charts/table_header.py +7 -1
- layrz_sdk/entities/charts/table_row.py +7 -1
- layrz_sdk/entities/charts/timeline_chart.py +11 -3
- layrz_sdk/entities/charts/timeline_serie.py +7 -1
- layrz_sdk/entities/charts/timeline_serie_item.py +7 -1
- layrz_sdk/entities/checkpoint.py +20 -13
- layrz_sdk/entities/command_series_ticket.py +29 -4
- layrz_sdk/entities/comment.py +22 -5
- layrz_sdk/entities/custom_field.py +12 -4
- layrz_sdk/entities/custom_report_page.py +3 -0
- layrz_sdk/entities/destination_phone.py +7 -1
- layrz_sdk/entities/device.py +11 -4
- layrz_sdk/entities/event.py +20 -4
- layrz_sdk/entities/exchange_service.py +12 -4
- layrz_sdk/entities/function.py +11 -4
- layrz_sdk/entities/geofence.py +20 -5
- layrz_sdk/entities/geofence_category.py +0 -2
- layrz_sdk/entities/last_message.py +7 -3
- layrz_sdk/entities/locator.py +95 -0
- layrz_sdk/entities/message.py +16 -9
- layrz_sdk/entities/modbus/config.py +7 -1
- layrz_sdk/entities/modbus/parameter.py +7 -1
- layrz_sdk/entities/modbus/wait.py +11 -1
- layrz_sdk/entities/notification_type.py +0 -2
- layrz_sdk/entities/operation.py +37 -16
- layrz_sdk/entities/operation_case_payload.py +39 -13
- layrz_sdk/entities/operation_payload.py +63 -26
- layrz_sdk/entities/operation_type.py +0 -2
- layrz_sdk/entities/outbound_service.py +11 -4
- layrz_sdk/entities/parameter_update.py +25 -0
- layrz_sdk/entities/platform.py +0 -2
- layrz_sdk/entities/position.py +7 -3
- layrz_sdk/entities/preset.py +15 -9
- layrz_sdk/entities/report.py +9 -5
- layrz_sdk/entities/report_col.py +17 -3
- layrz_sdk/entities/report_configuration.py +7 -1
- layrz_sdk/entities/report_data_type.py +1 -3
- layrz_sdk/entities/report_format.py +1 -5
- layrz_sdk/entities/report_header.py +12 -29
- layrz_sdk/entities/report_page.py +7 -3
- layrz_sdk/entities/report_row.py +7 -19
- layrz_sdk/entities/request_type.py +0 -2
- layrz_sdk/entities/sensor.py +21 -3
- layrz_sdk/entities/sensor_mask.py +28 -0
- layrz_sdk/entities/sound_effect.py +0 -2
- layrz_sdk/entities/static_position.py +6 -1
- layrz_sdk/entities/telemetry/assetmessage.py +14 -15
- layrz_sdk/entities/telemetry/devicemessage.py +19 -9
- layrz_sdk/entities/text_alignment.py +0 -2
- layrz_sdk/entities/timezone.py +12 -4
- layrz_sdk/entities/trigger.py +102 -17
- layrz_sdk/entities/trigger_kind.py +2 -5
- layrz_sdk/entities/user.py +11 -4
- layrz_sdk/entities/waypoint.py +38 -16
- layrz_sdk/entities/weekday.py +1 -3
- layrz_sdk/helpers/color.py +1 -6
- layrz_sdk/lcl/core.py +0 -1
- {layrz_sdk-4.0.11.dist-info → layrz_sdk-4.1.8.dist-info}/METADATA +2 -2
- layrz_sdk-4.1.8.dist-info/RECORD +123 -0
- layrz_sdk-4.0.11.dist-info/RECORD +0 -116
- {layrz_sdk-4.0.11.dist-info → layrz_sdk-4.1.8.dist-info}/WHEEL +0 -0
- {layrz_sdk-4.0.11.dist-info → layrz_sdk-4.1.8.dist-info}/licenses/LICENSE +0 -0
- {layrz_sdk-4.0.11.dist-info → layrz_sdk-4.1.8.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"""Timing decorator"""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import logging
|
|
5
|
+
import os
|
|
6
|
+
from collections.abc import Callable, Coroutine
|
|
7
|
+
from functools import wraps
|
|
8
|
+
from typing import Any, ParamSpec, TypeVar, overload
|
|
9
|
+
|
|
10
|
+
T = TypeVar('T')
|
|
11
|
+
P = ParamSpec('P')
|
|
12
|
+
|
|
13
|
+
log = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
SHOULD_DISPLAY = os.environ.get('LAYRZ_SDK_DISPLAY_TIMING', '1') == '1'
|
|
16
|
+
if raw_depth := os.environ.get('LAYRZ_SDK_TIMING_DEPTH'):
|
|
17
|
+
try:
|
|
18
|
+
MAX_DEPTH = int(raw_depth)
|
|
19
|
+
except ValueError:
|
|
20
|
+
MAX_DEPTH = 0
|
|
21
|
+
else:
|
|
22
|
+
MAX_DEPTH = 0
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@overload
|
|
26
|
+
def func_timing(func: Callable[P, T]) -> Callable[P, T | Coroutine[Any, Any, T]]: ...
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@overload
|
|
30
|
+
def func_timing(*, depth: int) -> Callable[[Callable[P, T]], Callable[P, T | Coroutine[Any, Any, T]]]: ...
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def func_timing(
|
|
34
|
+
func: Callable[P, T] | None = None,
|
|
35
|
+
*,
|
|
36
|
+
depth: int = 0,
|
|
37
|
+
) -> Any:
|
|
38
|
+
"""
|
|
39
|
+
Decorator to time a function execution.
|
|
40
|
+
|
|
41
|
+
:param depth: The depth of the function call for logging indentation.
|
|
42
|
+
:return: The wrapped function with timing functionality.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
def decorator(func: Callable[P, T]) -> Callable[P, T]:
|
|
46
|
+
"""Decorator to time a function"""
|
|
47
|
+
import time
|
|
48
|
+
|
|
49
|
+
prefix = '\t' * depth
|
|
50
|
+
|
|
51
|
+
@wraps(func)
|
|
52
|
+
async def async_wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
|
|
53
|
+
start_time = time.perf_counter_ns()
|
|
54
|
+
result: T = await func(*args, **kwargs) # type: ignore
|
|
55
|
+
diff = time.perf_counter_ns() - start_time
|
|
56
|
+
|
|
57
|
+
if SHOULD_DISPLAY and depth <= MAX_DEPTH:
|
|
58
|
+
log.info(f'{prefix}{func.__name__}() took {_readable_time(diff)}') # ty: ignore
|
|
59
|
+
|
|
60
|
+
return result
|
|
61
|
+
|
|
62
|
+
@wraps(func)
|
|
63
|
+
def sync_wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
|
|
64
|
+
start_time = time.perf_counter_ns()
|
|
65
|
+
result = func(*args, **kwargs)
|
|
66
|
+
diff = time.perf_counter_ns() - start_time
|
|
67
|
+
|
|
68
|
+
if SHOULD_DISPLAY and depth <= MAX_DEPTH:
|
|
69
|
+
log.info(f'{prefix}{func.__name__}() took {_readable_time(diff)}') # ty: ignore
|
|
70
|
+
|
|
71
|
+
return result
|
|
72
|
+
|
|
73
|
+
if asyncio.iscoroutinefunction(func):
|
|
74
|
+
return async_wrapper # type: ignore
|
|
75
|
+
return sync_wrapper
|
|
76
|
+
|
|
77
|
+
if func is None:
|
|
78
|
+
return decorator
|
|
79
|
+
return decorator(func)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _readable_time(diff: int) -> str:
|
|
83
|
+
"""Convert nanoseconds to a readable format"""
|
|
84
|
+
if diff < 1_000:
|
|
85
|
+
return f'{diff} ns'
|
|
86
|
+
|
|
87
|
+
diff = diff // 1_000
|
|
88
|
+
if diff < 1_000:
|
|
89
|
+
return f'{diff} μs'
|
|
90
|
+
|
|
91
|
+
diff = diff // 1_000
|
|
92
|
+
if diff < 1_000:
|
|
93
|
+
return f'{diff} ms'
|
|
94
|
+
|
|
95
|
+
diff = diff // 1_000
|
|
96
|
+
if diff < 60:
|
|
97
|
+
return f'{diff} s'
|
|
98
|
+
|
|
99
|
+
diff = diff // 60
|
|
100
|
+
if diff < 60:
|
|
101
|
+
return f'{diff} m'
|
|
102
|
+
|
|
103
|
+
return f'{diff // 60} h'
|
layrz_sdk/entities/__init__.py
CHANGED
|
@@ -10,8 +10,10 @@ from .asset_contact import AssetContact
|
|
|
10
10
|
from .asset_operation_mode import AssetOperationMode
|
|
11
11
|
from .ats_entry import AtsEntry
|
|
12
12
|
from .ats_exit_history import AtsExitExecutionHistory
|
|
13
|
+
from .ats_operation import AtsOperation, AtsOperationMovement
|
|
13
14
|
from .ats_possible_entry import AtsPossibleEntry
|
|
14
15
|
from .ats_possible_exit import AtsPossibleExit
|
|
16
|
+
from .ats_purchaseorder import AtsPurchaseOrder, DeliveryCategories, OrderCategories, OrderStatus
|
|
15
17
|
from .ats_reception import AtsReception
|
|
16
18
|
from .broadcast import (
|
|
17
19
|
BroadcastPayload,
|
|
@@ -20,6 +22,7 @@ from .broadcast import (
|
|
|
20
22
|
BroadcastResult,
|
|
21
23
|
BroadcastService,
|
|
22
24
|
BroadcastStatus,
|
|
25
|
+
RawBroadcastResult,
|
|
23
26
|
)
|
|
24
27
|
from .case import Case
|
|
25
28
|
from .case_ignored_status import CaseIgnoredStatus
|
|
@@ -65,6 +68,7 @@ from .function import Function
|
|
|
65
68
|
from .geofence import Geofence
|
|
66
69
|
from .geofence_category import GeofenceCategory
|
|
67
70
|
from .last_message import LastMessage
|
|
71
|
+
from .locator import Locator, LocatorMqttConfig
|
|
68
72
|
from .message import Message
|
|
69
73
|
from .modbus import ModbusConfig, ModbusParameter, ModbusSchema, ModbusStatus, ModbusWait
|
|
70
74
|
from .notification_type import TwilioNotificationType
|
|
@@ -73,6 +77,7 @@ from .operation_case_payload import OperationCaseCommentPayload, OperationCasePa
|
|
|
73
77
|
from .operation_payload import OperationPayload
|
|
74
78
|
from .operation_type import OperationType
|
|
75
79
|
from .outbound_service import OutboundService
|
|
80
|
+
from .parameter_update import ParameterUpdate
|
|
76
81
|
from .platform import Platform
|
|
77
82
|
from .position import Position
|
|
78
83
|
from .presence_type import PresenceType
|
|
@@ -87,7 +92,9 @@ from .report_page import ReportPage
|
|
|
87
92
|
from .report_row import ReportRow
|
|
88
93
|
from .request_type import HttpRequestType
|
|
89
94
|
from .sensor import Sensor
|
|
95
|
+
from .sensor_mask import SensorMask
|
|
90
96
|
from .sound_effect import SoundEffect
|
|
97
|
+
from .static_position import StaticPosition
|
|
91
98
|
from .telemetry import AssetMessage, DeviceMessage
|
|
92
99
|
from .text_alignment import TextAlignment
|
|
93
100
|
from .timezone import Timezone
|
|
@@ -118,6 +125,7 @@ __all__ = [
|
|
|
118
125
|
'BroadcastRequest',
|
|
119
126
|
'BroadcastResponse',
|
|
120
127
|
'BroadcastResult',
|
|
128
|
+
'RawBroadcastResult',
|
|
121
129
|
'BroadcastService',
|
|
122
130
|
'BroadcastStatus',
|
|
123
131
|
'Case',
|
|
@@ -150,6 +158,8 @@ __all__ = [
|
|
|
150
158
|
'HttpRequestType',
|
|
151
159
|
'LastMessage',
|
|
152
160
|
'LineChart',
|
|
161
|
+
'Locator',
|
|
162
|
+
'LocatorMqttConfig',
|
|
153
163
|
'MapCenterType',
|
|
154
164
|
'MapChart',
|
|
155
165
|
'MapPoint',
|
|
@@ -185,7 +195,9 @@ __all__ = [
|
|
|
185
195
|
'ScatterSerie',
|
|
186
196
|
'ScatterSerieItem',
|
|
187
197
|
'Sensor',
|
|
198
|
+
'SensorMask',
|
|
188
199
|
'SoundEffect',
|
|
200
|
+
'StaticPosition',
|
|
189
201
|
'TableChart',
|
|
190
202
|
'TableHeader',
|
|
191
203
|
'TableRow',
|
|
@@ -206,4 +218,11 @@ __all__ = [
|
|
|
206
218
|
'WaypointKind',
|
|
207
219
|
'WaypointRef',
|
|
208
220
|
'Weekday',
|
|
221
|
+
'AtsPurchaseOrder',
|
|
222
|
+
'DeliveryCategories',
|
|
223
|
+
'OrderCategories',
|
|
224
|
+
'OrderStatus',
|
|
225
|
+
'AtsOperationMovement',
|
|
226
|
+
'AtsOperation',
|
|
227
|
+
'ParameterUpdate',
|
|
209
228
|
]
|
layrz_sdk/entities/action.py
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
from datetime import timedelta
|
|
4
|
-
|
|
5
|
-
from pydantic import BaseModel, Field
|
|
1
|
+
from pydantic import BaseModel, ConfigDict, Field, field_serializer
|
|
6
2
|
|
|
7
3
|
from .action_geofence_ownership import ActionGeofenceOwnership
|
|
8
4
|
from .action_kind import ActionKind
|
|
@@ -13,20 +9,24 @@ from .geofence_category import GeofenceCategory
|
|
|
13
9
|
class Action(BaseModel):
|
|
14
10
|
"""Action entity"""
|
|
15
11
|
|
|
16
|
-
model_config =
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
12
|
+
model_config = ConfigDict(
|
|
13
|
+
validate_by_name=False,
|
|
14
|
+
validate_by_alias=True,
|
|
15
|
+
serialize_by_alias=True,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
pk: int = Field(
|
|
19
|
+
...,
|
|
20
|
+
description='Primary key of the action entity',
|
|
21
|
+
alias='id',
|
|
22
|
+
)
|
|
27
23
|
name: str = Field(..., description='Name of the action')
|
|
28
24
|
kind: ActionKind = Field(..., description='Kind of the action')
|
|
29
25
|
|
|
26
|
+
@field_serializer('kind', when_used='always')
|
|
27
|
+
def serialize_kind(self, kind: ActionKind) -> str:
|
|
28
|
+
return kind.value
|
|
29
|
+
|
|
30
30
|
command_id: int | None = Field(
|
|
31
31
|
default=None,
|
|
32
32
|
description='Tag ID associated with the action to send commands to primary devices',
|
|
@@ -34,6 +34,10 @@ class Action(BaseModel):
|
|
|
34
34
|
|
|
35
35
|
subkind: ActionSubKind = Field(default=ActionSubKind.UNUSED, description='Subkind of the action')
|
|
36
36
|
|
|
37
|
+
@field_serializer('subkind', when_used='always')
|
|
38
|
+
def serialize_subkind(self, subkind: ActionSubKind) -> str:
|
|
39
|
+
return subkind.value
|
|
40
|
+
|
|
37
41
|
wait_for_image: bool = Field(
|
|
38
42
|
default=False,
|
|
39
43
|
description='Whether to wait for an image to be taken before executing the action',
|
|
@@ -45,6 +49,10 @@ class Action(BaseModel):
|
|
|
45
49
|
description='Geofence category of the action',
|
|
46
50
|
)
|
|
47
51
|
|
|
52
|
+
@field_serializer('geofence_cateogry', when_used='always')
|
|
53
|
+
def serialize_geofence_category(self, geofence_category: GeofenceCategory) -> str:
|
|
54
|
+
return geofence_category.value
|
|
55
|
+
|
|
48
56
|
geofence_name_formula: str | None = Field(
|
|
49
57
|
default=None,
|
|
50
58
|
description='Formula to generate the geofence name',
|
|
@@ -67,4 +75,8 @@ class Action(BaseModel):
|
|
|
67
75
|
description='Ownership of the new geofence created by the action',
|
|
68
76
|
)
|
|
69
77
|
|
|
78
|
+
@field_serializer('new_geofence_ownership', when_used='always')
|
|
79
|
+
def serialize_new_geofence_ownership(self, ownership: ActionGeofenceOwnership) -> str:
|
|
80
|
+
return ownership.value
|
|
81
|
+
|
|
70
82
|
owner_id: int | None = Field(default=None, description='Owner ID')
|
layrz_sdk/entities/asset.py
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
"""Asset Entity"""
|
|
2
|
-
|
|
3
1
|
from typing import Any, Self
|
|
4
2
|
|
|
5
|
-
from pydantic import BaseModel, Field, field_validator, model_validator
|
|
3
|
+
from pydantic import BaseModel, ConfigDict, Field, field_serializer, field_validator, model_validator
|
|
6
4
|
|
|
7
5
|
from .asset_contact import AssetContact
|
|
8
6
|
from .asset_operation_mode import AssetOperationMode
|
|
@@ -15,13 +13,16 @@ from .static_position import StaticPosition
|
|
|
15
13
|
class Asset(BaseModel):
|
|
16
14
|
"""Asset entity definition"""
|
|
17
15
|
|
|
18
|
-
model_config =
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
model_config = ConfigDict(
|
|
17
|
+
validate_by_name=False,
|
|
18
|
+
validate_by_alias=True,
|
|
19
|
+
serialize_by_alias=True,
|
|
20
|
+
)
|
|
23
21
|
|
|
24
|
-
pk: int = Field(
|
|
22
|
+
pk: int = Field(
|
|
23
|
+
description='Defines the primary key of the asset',
|
|
24
|
+
alias='id',
|
|
25
|
+
)
|
|
25
26
|
name: str = Field(description='Defines the name of the asset')
|
|
26
27
|
vin: str | None = Field(
|
|
27
28
|
default=None,
|
|
@@ -30,6 +31,11 @@ class Asset(BaseModel):
|
|
|
30
31
|
plate: str | None = Field(default=None, description='Defines the plate number of the asset')
|
|
31
32
|
kind_id: int | None = Field(description='Defines the type of the asset', default=None)
|
|
32
33
|
operation_mode: AssetOperationMode = Field(description='Defines the operation mode of the asset')
|
|
34
|
+
|
|
35
|
+
@field_serializer('operation_mode', when_used='always')
|
|
36
|
+
def serialize_operation_mode(self, operation_mode: AssetOperationMode) -> str:
|
|
37
|
+
return operation_mode.value
|
|
38
|
+
|
|
33
39
|
sensors: list[Sensor] = Field(default_factory=list, description='Defines the list of sensors of the asset')
|
|
34
40
|
custom_fields: list[CustomField] = Field(
|
|
35
41
|
default_factory=list, description='Defines the list of custom fields of the asset'
|
|
@@ -104,3 +110,8 @@ class Asset(BaseModel):
|
|
|
104
110
|
def asset_type(self: Self) -> int | None:
|
|
105
111
|
"""Get asset type"""
|
|
106
112
|
return self.kind_id
|
|
113
|
+
|
|
114
|
+
partition_number: int | None = Field(
|
|
115
|
+
default=None,
|
|
116
|
+
description='Partition number assigned for this Asset, if is None, will be auto-assigned by the system',
|
|
117
|
+
)
|
|
@@ -1,22 +1,23 @@
|
|
|
1
|
-
"""Asset constants"""
|
|
2
|
-
|
|
3
1
|
from datetime import timedelta
|
|
4
2
|
|
|
5
|
-
from pydantic import BaseModel, Field
|
|
3
|
+
from pydantic import BaseModel, ConfigDict, Field, field_serializer
|
|
6
4
|
|
|
7
5
|
|
|
8
6
|
class AssetConstants(BaseModel):
|
|
9
7
|
"""Asset constants"""
|
|
10
8
|
|
|
11
|
-
model_config =
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
model_config = ConfigDict(
|
|
10
|
+
validate_by_name=False,
|
|
11
|
+
validate_by_alias=True,
|
|
12
|
+
serialize_by_alias=True,
|
|
13
|
+
)
|
|
17
14
|
distance_traveled: float = Field(default=0.0, description='Total distance traveled by the asset in meters')
|
|
18
15
|
primary_device: str = Field(default='N/A', description='Primary device associated with the asset')
|
|
19
16
|
elapsed_time: timedelta = Field(
|
|
20
17
|
default=timedelta(seconds=0),
|
|
21
18
|
description='Total elapsed time for the asset in seconds',
|
|
22
19
|
)
|
|
20
|
+
|
|
21
|
+
@field_serializer('elapsed_time', when_used='always')
|
|
22
|
+
def serialize_elapsed_time(self, elapsed_time: timedelta) -> float:
|
|
23
|
+
return elapsed_time.total_seconds()
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
from pydantic import BaseModel, Field
|
|
1
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
4
2
|
|
|
5
3
|
|
|
6
4
|
class AssetContact(BaseModel):
|
|
7
5
|
"""Asset contact information"""
|
|
8
6
|
|
|
7
|
+
model_config = ConfigDict(
|
|
8
|
+
validate_by_name=False,
|
|
9
|
+
validate_by_alias=True,
|
|
10
|
+
serialize_by_alias=True,
|
|
11
|
+
)
|
|
12
|
+
|
|
9
13
|
name: str = Field(default='', description='Name of the contact person for the asset')
|
|
10
14
|
phone: str = Field(default='', description='Phone number of the contact person for the asset')
|
|
11
15
|
email: str = Field(default='', description='Email address of the contact person for the asset')
|
layrz_sdk/entities/ats_entry.py
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
from pydantic import BaseModel, Field
|
|
1
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
4
2
|
|
|
5
3
|
|
|
6
4
|
class AtsEntry(BaseModel):
|
|
7
5
|
"""Entry entity"""
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
model_config = ConfigDict(
|
|
8
|
+
validate_by_name=False,
|
|
9
|
+
validate_by_alias=True,
|
|
10
|
+
serialize_by_alias=True,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
pk: int = Field(
|
|
14
|
+
description='Defines the primary key of the Function',
|
|
15
|
+
alias='id',
|
|
16
|
+
)
|
|
10
17
|
old_tank_level: float = Field(description='Old tank level in liters', default=0.0)
|
|
11
18
|
new_tank_level: float = Field(description='New tank level in liters', default=0.0)
|
|
12
19
|
density: float | None = Field(description='Density of the fuel in kg/m3', default=None)
|
|
@@ -1,30 +1,24 @@
|
|
|
1
|
-
"""Exit Execution History"""
|
|
2
|
-
|
|
3
1
|
from datetime import datetime
|
|
4
2
|
from typing import Literal
|
|
5
3
|
|
|
6
|
-
from pydantic import
|
|
7
|
-
BaseModel,
|
|
8
|
-
ConfigDict,
|
|
9
|
-
Field,
|
|
10
|
-
)
|
|
4
|
+
from pydantic import BaseModel, ConfigDict, Field, field_serializer
|
|
11
5
|
|
|
12
6
|
|
|
13
7
|
class AtsExitExecutionHistory(BaseModel):
|
|
14
|
-
model_config =
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
pk: int = Field(description='Primary key of the Exit Execution History', alias='id')
|
|
20
|
-
|
|
21
|
-
from_asset_id: int = Field(
|
|
22
|
-
description='ID of the asset from which the exit is initiated',
|
|
8
|
+
model_config = ConfigDict(
|
|
9
|
+
validate_by_name=False,
|
|
10
|
+
validate_by_alias=True,
|
|
11
|
+
serialize_by_alias=True,
|
|
12
|
+
from_attributes=True,
|
|
23
13
|
)
|
|
24
|
-
|
|
25
|
-
description='
|
|
14
|
+
pk: int = Field(
|
|
15
|
+
description='Primary key of the Exit Execution History',
|
|
16
|
+
alias='id',
|
|
26
17
|
)
|
|
27
18
|
|
|
19
|
+
from_asset_id: int = Field(description='ID of the asset from which the exit is initiated')
|
|
20
|
+
to_asset_id: int = Field(description='ID of the asset to which the exit is directed')
|
|
21
|
+
|
|
28
22
|
status: Literal['PENDING', 'FAILED', 'SUCCESS'] = Field(default='PENDING')
|
|
29
23
|
|
|
30
24
|
from_app: Literal['ATSWEB', 'ATSMOBILE', 'NFC'] | None = Field(
|
|
@@ -38,5 +32,13 @@ class AtsExitExecutionHistory(BaseModel):
|
|
|
38
32
|
to_asset_mileage: float | None = Field(default=None, description='Mileage of the asset to which the exit is directed')
|
|
39
33
|
|
|
40
34
|
created_at: datetime = Field(description='Timestamp when the exit was created')
|
|
35
|
+
|
|
36
|
+
@field_serializer('created_at', when_used='always')
|
|
37
|
+
def serialize_created_at(self, created_at: datetime) -> float:
|
|
38
|
+
return created_at.timestamp()
|
|
39
|
+
|
|
41
40
|
updated_at: datetime = Field(description='Timestamp when the exit was last updated')
|
|
42
|
-
|
|
41
|
+
|
|
42
|
+
@field_serializer('updated_at', when_used='always')
|
|
43
|
+
def serialize_updated_at(self, updated_at: datetime) -> float:
|
|
44
|
+
return updated_at.timestamp()
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""Entry entity"""
|
|
2
|
+
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from enum import StrEnum
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel, ConfigDict, Field, field_serializer
|
|
7
|
+
|
|
8
|
+
from .ats_purchaseorder import AtsPurchaseOrder, DeliveryCategories, OrderCategories, OrderStatus
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class AtsOperationMovement(BaseModel):
|
|
12
|
+
"""Ats operation movement entity"""
|
|
13
|
+
|
|
14
|
+
model_config = ConfigDict(
|
|
15
|
+
validate_by_name=False,
|
|
16
|
+
validate_by_alias=True,
|
|
17
|
+
serialize_by_alias=True,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
pk: int | None = Field(
|
|
21
|
+
description='Defines the primary key of the Function',
|
|
22
|
+
default=None,
|
|
23
|
+
alias='id',
|
|
24
|
+
)
|
|
25
|
+
status: OrderStatus | None = Field(description='Current status of the order', default=None)
|
|
26
|
+
|
|
27
|
+
@field_serializer('status', when_used='always')
|
|
28
|
+
def serialize_status(self, status: OrderStatus | None) -> str | None:
|
|
29
|
+
return status.value if status else None
|
|
30
|
+
|
|
31
|
+
created_at: datetime | None = Field(description='Timestamp when the operation movement was created', default=None)
|
|
32
|
+
|
|
33
|
+
@field_serializer('created_at', when_used='always')
|
|
34
|
+
def serialize_created_at(self, created_at: datetime | None) -> float | None:
|
|
35
|
+
return created_at.timestamp() if created_at else None
|
|
36
|
+
|
|
37
|
+
asset_id: int | None = Field(description='ID of the asset', default=None)
|
|
38
|
+
operation_id: int | None = Field(description='ID of the operation', default=None)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class AtsOperation(BaseModel):
|
|
42
|
+
"""Entry entity"""
|
|
43
|
+
|
|
44
|
+
model_config = ConfigDict(
|
|
45
|
+
validate_by_name=False,
|
|
46
|
+
validate_by_alias=True,
|
|
47
|
+
serialize_by_alias=True,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
pk: int = Field(
|
|
51
|
+
description='Defines the primary key of the Function',
|
|
52
|
+
alias='id',
|
|
53
|
+
)
|
|
54
|
+
purchased_at: datetime = Field(description='Timestamp when the operation was purchased')
|
|
55
|
+
|
|
56
|
+
@field_serializer('purchased_at', when_used='always')
|
|
57
|
+
def serialize_purchased_at(self, purchased_at: datetime) -> float:
|
|
58
|
+
return purchased_at.timestamp()
|
|
59
|
+
|
|
60
|
+
order_status: OrderStatus = Field(..., description='Current status of the order')
|
|
61
|
+
|
|
62
|
+
@field_serializer('order_status', when_used='always')
|
|
63
|
+
def serialize_order_status(self, order_status: OrderStatus) -> str:
|
|
64
|
+
return order_status.value
|
|
65
|
+
|
|
66
|
+
category: OrderCategories = Field(..., description='Category of the operation')
|
|
67
|
+
|
|
68
|
+
@field_serializer('category', when_used='always')
|
|
69
|
+
def serialize_category(self, category: OrderCategories) -> str:
|
|
70
|
+
return category.value
|
|
71
|
+
|
|
72
|
+
deliver_category: DeliveryCategories = Field(..., description='Delivery category of the operation')
|
|
73
|
+
|
|
74
|
+
@field_serializer('deliver_category', when_used='always')
|
|
75
|
+
def serialize_deliver_category(self, deliver_category: DeliveryCategories) -> str:
|
|
76
|
+
return deliver_category.value
|
|
77
|
+
|
|
78
|
+
seller_asset_id: int = Field(description='ID of the seller asset')
|
|
79
|
+
transport_asset_id: int = Field(description='ID of the transport asset')
|
|
80
|
+
finished_at: datetime | None = Field(description='Timestamp when the operation was finished', default=None)
|
|
81
|
+
|
|
82
|
+
@field_serializer('finished_at', when_used='always')
|
|
83
|
+
def serialize_finished_at(self, finished_at: datetime | None) -> float | None:
|
|
84
|
+
return finished_at.timestamp() if finished_at else None
|
|
85
|
+
|
|
86
|
+
history: list[AtsOperationMovement] = Field(description='List of operation movements')
|
|
87
|
+
purchase_orders: list[AtsPurchaseOrder] = Field(description='List of purchase orders')
|
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
"""Entry entity"""
|
|
2
|
-
|
|
3
1
|
from datetime import datetime
|
|
4
2
|
|
|
5
|
-
from pydantic import BaseModel, Field
|
|
3
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
6
4
|
|
|
7
5
|
|
|
8
6
|
class AtsPossibleEntry(BaseModel):
|
|
9
7
|
"""Entry entity"""
|
|
10
8
|
|
|
9
|
+
model_config = ConfigDict(
|
|
10
|
+
validate_by_name=False,
|
|
11
|
+
validate_by_alias=True,
|
|
12
|
+
serialize_by_alias=True,
|
|
13
|
+
)
|
|
14
|
+
|
|
11
15
|
initial_tank_level: float = Field(description='Initial tank level in liters', default=0.0)
|
|
12
16
|
tank_accumulator: float = Field(description='Tank accumulator in liters', default=0.0)
|
|
13
17
|
is_ready: bool = Field(description='Indicates if the entry is ready', default=False)
|
|
@@ -20,10 +24,9 @@ class AtsPossibleEntry(BaseModel):
|
|
|
20
24
|
is_recalculated: bool = Field(description='Indicates if the entry is recalculated', default=False)
|
|
21
25
|
is_blackbox: bool = Field(description='Indicates if the entry is a black box', default=False)
|
|
22
26
|
is_executed_by_command: bool | None = Field(
|
|
23
|
-
description='Indicates if the entry is executed by command',
|
|
27
|
+
description='Indicates if the entry is executed by command',
|
|
28
|
+
default=False,
|
|
24
29
|
)
|
|
25
30
|
is_ready_by_reception: bool | None = Field(description='Indicates if the entry is ready by reception', default=False)
|
|
26
31
|
false_positive_count: int = Field(description='Count of false positives for the entry', default=0)
|
|
27
|
-
reception_id: int | None = Field(
|
|
28
|
-
description='Reception ID associated with the entry', default=None, alias='receptionId'
|
|
29
|
-
)
|
|
32
|
+
reception_id: int | None = Field(description='Reception ID associated with the entry', default=None)
|
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
"""Ats Exit entity"""
|
|
2
|
-
|
|
3
1
|
from datetime import datetime
|
|
4
2
|
|
|
5
|
-
from pydantic import BaseModel, Field
|
|
3
|
+
from pydantic import BaseModel, ConfigDict, Field, field_serializer
|
|
6
4
|
|
|
7
5
|
|
|
8
6
|
class AtsPossibleExit(BaseModel):
|
|
9
7
|
"""AtsPossibleExit entity"""
|
|
10
8
|
|
|
11
|
-
model_config =
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
model_config = ConfigDict(
|
|
10
|
+
validate_by_name=False,
|
|
11
|
+
validate_by_alias=True,
|
|
12
|
+
serialize_by_alias=True,
|
|
13
|
+
)
|
|
16
14
|
|
|
17
|
-
pk: int = Field(
|
|
15
|
+
pk: int = Field(
|
|
16
|
+
description='Defines the primary key of the AtsPossibleExit',
|
|
17
|
+
alias='id',
|
|
18
|
+
)
|
|
18
19
|
|
|
19
20
|
identifier: int | None = Field(
|
|
20
21
|
default=None,
|
|
@@ -54,11 +55,20 @@ class AtsPossibleExit(BaseModel):
|
|
|
54
55
|
default_factory=datetime.now,
|
|
55
56
|
description='Timestamp when the exit started',
|
|
56
57
|
)
|
|
58
|
+
|
|
59
|
+
@field_serializer('start_at', when_used='always')
|
|
60
|
+
def serialize_start_at(self, start_at: datetime) -> float:
|
|
61
|
+
return start_at.timestamp()
|
|
62
|
+
|
|
57
63
|
end_at: datetime | None = Field(
|
|
58
64
|
default=None,
|
|
59
65
|
description='Timestamp when the exit ended',
|
|
60
66
|
)
|
|
61
67
|
|
|
68
|
+
@field_serializer('end_at', when_used='always')
|
|
69
|
+
def serialize_end_at(self, end_at: datetime | None) -> float | None:
|
|
70
|
+
return end_at.timestamp() if end_at else None
|
|
71
|
+
|
|
62
72
|
# Derived / bookkeeping flags
|
|
63
73
|
is_recalculated: bool = Field(
|
|
64
74
|
default=False,
|