layrz-sdk 4.0.23__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/func_timing.py +14 -7
- layrz_sdk/entities/__init__.py +7 -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 +15 -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 +57 -17
- layrz_sdk/entities/ats_possible_entry.py +9 -4
- layrz_sdk/entities/ats_possible_exit.py +19 -9
- layrz_sdk/entities/ats_purchaseorder.py +53 -12
- layrz_sdk/entities/ats_reception.py +16 -4
- layrz_sdk/entities/broadcast/payload.py +40 -8
- layrz_sdk/entities/broadcast/result.py +21 -2
- layrz_sdk/entities/broadcast/service.py +12 -2
- layrz_sdk/entities/case.py +34 -7
- 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 +15 -4
- 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 +12 -4
- 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 +11 -4
- layrz_sdk/entities/sensor_mask.py +16 -5
- 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 +46 -13
- layrz_sdk/entities/trigger_kind.py +1 -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.23.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.23.dist-info/RECORD +0 -121
- {layrz_sdk-4.0.23.dist-info → layrz_sdk-4.1.8.dist-info}/WHEEL +0 -0
- {layrz_sdk-4.0.23.dist-info → layrz_sdk-4.1.8.dist-info}/licenses/LICENSE +0 -0
- {layrz_sdk-4.0.23.dist-info → layrz_sdk-4.1.8.dist-info}/top_level.txt +0 -0
layrz_sdk/entities/message.py
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
"""Message entity"""
|
|
2
|
-
|
|
3
1
|
from datetime import datetime
|
|
4
2
|
from typing import Any
|
|
5
3
|
|
|
6
|
-
from pydantic import BaseModel, Field, field_validator
|
|
4
|
+
from pydantic import BaseModel, ConfigDict, Field, field_serializer, field_validator
|
|
7
5
|
|
|
8
6
|
from layrz_sdk.constants import UTC
|
|
9
7
|
from layrz_sdk.entities.geofence import Geofence
|
|
@@ -13,13 +11,17 @@ from layrz_sdk.entities.position import Position
|
|
|
13
11
|
class Message(BaseModel):
|
|
14
12
|
"""Message definition"""
|
|
15
13
|
|
|
16
|
-
model_config =
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
model_config = ConfigDict(
|
|
15
|
+
validate_by_name=False,
|
|
16
|
+
validate_by_alias=True,
|
|
17
|
+
serialize_by_alias=True,
|
|
18
|
+
)
|
|
21
19
|
|
|
22
|
-
pk: int = Field(
|
|
20
|
+
pk: int = Field(
|
|
21
|
+
...,
|
|
22
|
+
description='Message ID',
|
|
23
|
+
alias='id',
|
|
24
|
+
)
|
|
23
25
|
asset_id: int = Field(..., description='Asset ID')
|
|
24
26
|
position: Position = Field(
|
|
25
27
|
default_factory=lambda: Position(),
|
|
@@ -38,6 +40,11 @@ class Message(BaseModel):
|
|
|
38
40
|
description='Timestamp when the message was received',
|
|
39
41
|
)
|
|
40
42
|
|
|
43
|
+
@field_serializer('received_at', when_used='always')
|
|
44
|
+
def serialize_received_at(self, value: datetime) -> float:
|
|
45
|
+
"""Serialize received_at to a timestamp."""
|
|
46
|
+
return value.timestamp()
|
|
47
|
+
|
|
41
48
|
geofences: list[Geofence] = Field(
|
|
42
49
|
default_factory=list,
|
|
43
50
|
description='List of geofences associated with the message',
|
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
from pydantic import BaseModel, Field
|
|
1
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
2
2
|
|
|
3
3
|
from .parameter import ModbusParameter
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class ModbusConfig(BaseModel):
|
|
7
|
+
model_config = ConfigDict(
|
|
8
|
+
validate_by_name=False,
|
|
9
|
+
validate_by_alias=True,
|
|
10
|
+
serialize_by_alias=True,
|
|
11
|
+
)
|
|
12
|
+
|
|
7
13
|
port_id: str = Field(
|
|
8
14
|
...,
|
|
9
15
|
description='Port ID for Modbus communication',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from typing import Any
|
|
2
2
|
|
|
3
|
-
from pydantic import BaseModel, Field, field_validator
|
|
3
|
+
from pydantic import BaseModel, ConfigDict, Field, field_validator
|
|
4
4
|
|
|
5
5
|
from .schema import ModbusSchema
|
|
6
6
|
|
|
@@ -8,6 +8,12 @@ from .schema import ModbusSchema
|
|
|
8
8
|
class ModbusParameter(BaseModel):
|
|
9
9
|
"""Modbus parameter model"""
|
|
10
10
|
|
|
11
|
+
model_config = ConfigDict(
|
|
12
|
+
validate_by_name=False,
|
|
13
|
+
validate_by_alias=True,
|
|
14
|
+
serialize_by_alias=True,
|
|
15
|
+
)
|
|
16
|
+
|
|
11
17
|
schema_: ModbusSchema = Field(
|
|
12
18
|
...,
|
|
13
19
|
description='Modbus schema',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from typing import Any
|
|
2
2
|
|
|
3
|
-
from pydantic import BaseModel, Field, field_validator
|
|
3
|
+
from pydantic import BaseModel, ConfigDict, Field, field_serializer, field_validator
|
|
4
4
|
|
|
5
5
|
from .schema import ModbusSchema
|
|
6
6
|
from .status import ModbusStatus
|
|
@@ -9,11 +9,21 @@ from .status import ModbusStatus
|
|
|
9
9
|
class ModbusWait(BaseModel):
|
|
10
10
|
"""Modbus parameter model"""
|
|
11
11
|
|
|
12
|
+
model_config = ConfigDict(
|
|
13
|
+
validate_by_name=False,
|
|
14
|
+
validate_by_alias=True,
|
|
15
|
+
serialize_by_alias=True,
|
|
16
|
+
)
|
|
17
|
+
|
|
12
18
|
status: ModbusStatus = Field(
|
|
13
19
|
...,
|
|
14
20
|
description='Status of the Modbus command',
|
|
15
21
|
)
|
|
16
22
|
|
|
23
|
+
@field_serializer('status', when_used='always')
|
|
24
|
+
def serialize_status(self, status: ModbusStatus) -> str:
|
|
25
|
+
return status.value
|
|
26
|
+
|
|
17
27
|
structure: ModbusSchema = Field(
|
|
18
28
|
...,
|
|
19
29
|
description='Modbus structure schema',
|
layrz_sdk/entities/operation.py
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
from datetime import time, timedelta
|
|
1
|
+
from datetime import timedelta
|
|
4
2
|
from typing import Any, Self
|
|
5
3
|
|
|
6
|
-
from pydantic import BaseModel, Field, field_validator
|
|
4
|
+
from pydantic import BaseModel, ConfigDict, Field, field_serializer, field_validator
|
|
7
5
|
|
|
8
6
|
from .destination_phone import DestinationPhone
|
|
9
7
|
from .notification_type import TwilioNotificationType
|
|
@@ -17,18 +15,16 @@ from .timezone import Timezone
|
|
|
17
15
|
class Operation(BaseModel):
|
|
18
16
|
"""Operation entity"""
|
|
19
17
|
|
|
20
|
-
model_config =
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
pk: int = Field(description='Defines the primary key of the trigger', alias='id')
|
|
18
|
+
model_config = ConfigDict(
|
|
19
|
+
validate_by_name=False,
|
|
20
|
+
validate_by_alias=True,
|
|
21
|
+
serialize_by_alias=True,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
pk: int = Field(
|
|
25
|
+
description='Defines the primary key of the trigger',
|
|
26
|
+
alias='id',
|
|
27
|
+
)
|
|
32
28
|
name: str = Field(description='Defines the name of the trigger')
|
|
33
29
|
|
|
34
30
|
cooldown_time: timedelta = Field(
|
|
@@ -36,11 +32,19 @@ class Operation(BaseModel):
|
|
|
36
32
|
description='Defines the cooldown time of the trigger',
|
|
37
33
|
)
|
|
38
34
|
|
|
35
|
+
@field_serializer('cooldown_time', when_used='always')
|
|
36
|
+
def serialize_cooldown_time(self, value: timedelta) -> float:
|
|
37
|
+
return value.total_seconds()
|
|
38
|
+
|
|
39
39
|
operation_type: OperationType = Field(
|
|
40
40
|
...,
|
|
41
41
|
description='Defines the kind of the operation',
|
|
42
42
|
)
|
|
43
43
|
|
|
44
|
+
@field_serializer('operation_type', when_used='always')
|
|
45
|
+
def serialize_operation_type(self, value: OperationType) -> str:
|
|
46
|
+
return value.value
|
|
47
|
+
|
|
44
48
|
@property
|
|
45
49
|
def kind(self: Self) -> OperationType:
|
|
46
50
|
"""Get the kind of the operation"""
|
|
@@ -51,6 +55,10 @@ class Operation(BaseModel):
|
|
|
51
55
|
description='Defines the HTTP method of the operation',
|
|
52
56
|
)
|
|
53
57
|
|
|
58
|
+
@field_serializer('request_type', when_used='always')
|
|
59
|
+
def serialize_request_type(self, value: HttpRequestType | None) -> str | None:
|
|
60
|
+
return value.value if value else None
|
|
61
|
+
|
|
54
62
|
@property
|
|
55
63
|
def http_method(self: Self) -> HttpRequestType | None:
|
|
56
64
|
"""Get the HTTP method of the operation"""
|
|
@@ -125,6 +133,11 @@ class Operation(BaseModel):
|
|
|
125
133
|
description='Defines the Twilio notification type of the operation',
|
|
126
134
|
)
|
|
127
135
|
|
|
136
|
+
@field_serializer('notification_type', when_used='always')
|
|
137
|
+
def serialize_notification_type(self, value: TwilioNotificationType) -> str:
|
|
138
|
+
"""Serialize notification_type to its value."""
|
|
139
|
+
return value.value
|
|
140
|
+
|
|
128
141
|
@property
|
|
129
142
|
def twilio_notification_type(self: Self) -> TwilioNotificationType:
|
|
130
143
|
"""Get the Twilio notification type of the operation"""
|
|
@@ -201,6 +214,10 @@ class Operation(BaseModel):
|
|
|
201
214
|
description='Defines the sound effect for the operation',
|
|
202
215
|
)
|
|
203
216
|
|
|
217
|
+
@field_serializer('sound_effect', when_used='always')
|
|
218
|
+
def serialize_sound_effect(self, value: SoundEffect) -> str:
|
|
219
|
+
return value.value
|
|
220
|
+
|
|
204
221
|
sound_effect_uri: str | None = Field(
|
|
205
222
|
default=None,
|
|
206
223
|
description='Defines the URI for the sound effect of the operation. Only when sound_effect is set to CUSTOM.',
|
|
@@ -211,6 +228,10 @@ class Operation(BaseModel):
|
|
|
211
228
|
description='Defines the duration of the operation',
|
|
212
229
|
)
|
|
213
230
|
|
|
231
|
+
@field_serializer('duration', when_used='always')
|
|
232
|
+
def serialize_duration(self, value: timedelta | None) -> float | None:
|
|
233
|
+
return value.total_seconds() if value else None
|
|
234
|
+
|
|
214
235
|
@field_validator('duration', mode='before')
|
|
215
236
|
def validate_duration(cls, value: Any) -> timedelta:
|
|
216
237
|
if value is None:
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
"""Operation case payload entity"""
|
|
2
|
-
|
|
3
1
|
from datetime import datetime, timedelta
|
|
4
2
|
from typing import Any
|
|
5
3
|
|
|
6
|
-
from pydantic import BaseModel, Field, field_validator
|
|
4
|
+
from pydantic import BaseModel, ConfigDict, Field, field_serializer, field_validator
|
|
7
5
|
|
|
8
6
|
from layrz_sdk.constants import UTC
|
|
9
7
|
from layrz_sdk.entities.trigger import Trigger
|
|
@@ -12,7 +10,17 @@ from layrz_sdk.entities.trigger import Trigger
|
|
|
12
10
|
class OperationCaseCommentPayload(BaseModel):
|
|
13
11
|
"""Operation case comment payload entity"""
|
|
14
12
|
|
|
15
|
-
|
|
13
|
+
model_config = ConfigDict(
|
|
14
|
+
validate_by_name=False,
|
|
15
|
+
validate_by_alias=True,
|
|
16
|
+
serialize_by_alias=True,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
pk: int = Field(
|
|
20
|
+
...,
|
|
21
|
+
description='Defines the primary key of the operation case comment',
|
|
22
|
+
alias='id',
|
|
23
|
+
)
|
|
16
24
|
user: str = Field(..., description='Defines the user who created the operation case comment')
|
|
17
25
|
content: str = Field(..., description='Defines the content of the operation case comment')
|
|
18
26
|
created_at: datetime = Field(
|
|
@@ -20,28 +28,42 @@ class OperationCaseCommentPayload(BaseModel):
|
|
|
20
28
|
description='Defines the creation date of the operation case comment',
|
|
21
29
|
)
|
|
22
30
|
|
|
31
|
+
@field_serializer('created_at', when_used='always')
|
|
32
|
+
def serialize_created_at(self, created_at: datetime) -> float:
|
|
33
|
+
return created_at.timestamp()
|
|
34
|
+
|
|
23
35
|
|
|
24
36
|
class OperationCasePayload(BaseModel):
|
|
25
37
|
"""Operation case payload entity"""
|
|
26
38
|
|
|
27
|
-
model_config =
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
},
|
|
33
|
-
}
|
|
39
|
+
model_config = ConfigDict(
|
|
40
|
+
validate_by_name=False,
|
|
41
|
+
validate_by_alias=True,
|
|
42
|
+
serialize_by_alias=True,
|
|
43
|
+
)
|
|
34
44
|
|
|
35
|
-
pk: int = Field(
|
|
45
|
+
pk: int = Field(
|
|
46
|
+
description='Defines the primary key of the operation case payload',
|
|
47
|
+
alias='id',
|
|
48
|
+
)
|
|
36
49
|
created_at: datetime = Field(
|
|
37
50
|
default_factory=lambda: datetime.now(UTC),
|
|
38
51
|
description='Defines the creation date of the operation case payload',
|
|
39
52
|
)
|
|
53
|
+
|
|
54
|
+
@field_serializer('created_at', when_used='always')
|
|
55
|
+
def serialize_created_at(self, created_at: datetime) -> float:
|
|
56
|
+
return created_at.timestamp()
|
|
57
|
+
|
|
40
58
|
updated_at: datetime = Field(
|
|
41
59
|
default_factory=lambda: datetime.now(UTC),
|
|
42
60
|
description='Defines the last update date of the operation case payload',
|
|
43
61
|
)
|
|
44
62
|
|
|
63
|
+
@field_serializer('updated_at', when_used='always')
|
|
64
|
+
def serialize_updated_at(self, updated_at: datetime) -> float:
|
|
65
|
+
return updated_at.timestamp()
|
|
66
|
+
|
|
45
67
|
trigger: Trigger = Field(
|
|
46
68
|
...,
|
|
47
69
|
description='Defines the trigger associated with the operation case payload',
|
|
@@ -52,7 +74,7 @@ class OperationCasePayload(BaseModel):
|
|
|
52
74
|
"""Serialize trigger to a dictionary"""
|
|
53
75
|
if isinstance(value, Trigger):
|
|
54
76
|
return Trigger(
|
|
55
|
-
id=value.pk,
|
|
77
|
+
id=value.pk, # ty: ignore
|
|
56
78
|
name=value.name,
|
|
57
79
|
code=value.code,
|
|
58
80
|
)
|
|
@@ -71,6 +93,10 @@ class OperationCasePayload(BaseModel):
|
|
|
71
93
|
description='Defines the creation date of the file associated with the operation case payload',
|
|
72
94
|
)
|
|
73
95
|
|
|
96
|
+
@field_serializer('file_created_at', when_used='always')
|
|
97
|
+
def serialize_file_created_at(self, file_created_at: datetime | None) -> float | None:
|
|
98
|
+
return file_created_at.timestamp() if file_created_at else None
|
|
99
|
+
|
|
74
100
|
comment: OperationCaseCommentPayload | None = Field(
|
|
75
101
|
default=None,
|
|
76
102
|
description='Defines the comment associated with the operation case payload',
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
"""Operation Payload entity"""
|
|
2
|
-
|
|
3
1
|
from datetime import datetime, timedelta
|
|
4
|
-
from typing import Any
|
|
2
|
+
from typing import Any
|
|
5
3
|
|
|
6
|
-
from pydantic import BaseModel, Field, field_validator
|
|
4
|
+
from pydantic import BaseModel, ConfigDict, Field, field_serializer, field_validator
|
|
7
5
|
|
|
8
6
|
from layrz_sdk.entities.asset import Asset
|
|
9
7
|
from layrz_sdk.entities.destination_phone import DestinationPhone
|
|
10
8
|
from layrz_sdk.entities.geofence import Geofence
|
|
9
|
+
from layrz_sdk.entities.locator import Locator
|
|
11
10
|
from layrz_sdk.entities.notification_type import TwilioNotificationType
|
|
12
11
|
from layrz_sdk.entities.operation import Operation
|
|
13
12
|
from layrz_sdk.entities.operation_case_payload import OperationCasePayload
|
|
@@ -22,22 +21,11 @@ from layrz_sdk.entities.trigger import Trigger
|
|
|
22
21
|
class OperationPayload(BaseModel):
|
|
23
22
|
"""Operation Payload entity"""
|
|
24
23
|
|
|
25
|
-
model_config =
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
Trigger: lambda v: v.model_dump(by_alias=True, exclude_none=True),
|
|
31
|
-
Operation: lambda v: v.model_dump(by_alias=True, exclude_none=True),
|
|
32
|
-
Geofence: lambda v: v.model_dump(by_alias=True, exclude_none=True),
|
|
33
|
-
OperationType: lambda v: v.value,
|
|
34
|
-
HttpRequestType: lambda v: v.value,
|
|
35
|
-
TwilioNotificationType: lambda v: v.value,
|
|
36
|
-
SoundEffect: lambda v: v.value,
|
|
37
|
-
Platform: lambda v: v.value,
|
|
38
|
-
PresenceType: lambda v: v.value,
|
|
39
|
-
},
|
|
40
|
-
}
|
|
24
|
+
model_config = ConfigDict(
|
|
25
|
+
validate_by_name=False,
|
|
26
|
+
validate_by_alias=True,
|
|
27
|
+
serialize_by_alias=True,
|
|
28
|
+
)
|
|
41
29
|
|
|
42
30
|
kind: OperationType = Field(
|
|
43
31
|
...,
|
|
@@ -45,14 +33,18 @@ class OperationPayload(BaseModel):
|
|
|
45
33
|
alias='operationType',
|
|
46
34
|
)
|
|
47
35
|
|
|
36
|
+
@field_serializer('kind', when_used='always')
|
|
37
|
+
def serialize_kind(self, value: OperationType) -> str:
|
|
38
|
+
return value.value
|
|
39
|
+
|
|
48
40
|
asset: Asset = Field(..., description='Defines the asset associated with the operation')
|
|
49
41
|
|
|
50
42
|
@field_validator('asset', mode='before')
|
|
51
|
-
def
|
|
43
|
+
def validate_asset(cls, value: Any) -> Asset:
|
|
52
44
|
"""Serialize asset to a dictionary"""
|
|
53
45
|
if isinstance(value, Asset):
|
|
54
46
|
return Asset(
|
|
55
|
-
id=value.pk,
|
|
47
|
+
id=value.pk, # ty: ignore
|
|
56
48
|
name=value.name,
|
|
57
49
|
operation_mode=value.operation_mode,
|
|
58
50
|
vin=value.vin,
|
|
@@ -69,11 +61,11 @@ class OperationPayload(BaseModel):
|
|
|
69
61
|
trigger: Trigger = Field(..., description='Defines the trigger associated with the operation')
|
|
70
62
|
|
|
71
63
|
@field_validator('trigger', mode='before')
|
|
72
|
-
def
|
|
64
|
+
def validate_trigger(cls, value: Any) -> Trigger:
|
|
73
65
|
"""Serialize trigger to a dictionary"""
|
|
74
66
|
if isinstance(value, Trigger):
|
|
75
67
|
return Trigger(
|
|
76
|
-
id=value.pk,
|
|
68
|
+
id=value.pk, # ty: ignore
|
|
77
69
|
name=value.name,
|
|
78
70
|
code=value.code,
|
|
79
71
|
)
|
|
@@ -86,11 +78,11 @@ class OperationPayload(BaseModel):
|
|
|
86
78
|
operation: Operation = Field(..., description='Defines the operation associated with the payload')
|
|
87
79
|
|
|
88
80
|
@field_validator('operation', mode='before')
|
|
89
|
-
def
|
|
81
|
+
def validate_operation(cls, value: Any) -> Operation:
|
|
90
82
|
"""Serialize operation to a dictionary"""
|
|
91
83
|
if isinstance(value, Operation):
|
|
92
84
|
return Operation(
|
|
93
|
-
id=value.pk,
|
|
85
|
+
id=value.pk, # ty: ignore
|
|
94
86
|
name=value.name,
|
|
95
87
|
operation_type=value.kind,
|
|
96
88
|
timezone=value.timezone,
|
|
@@ -107,6 +99,10 @@ class OperationPayload(BaseModel):
|
|
|
107
99
|
alias='activatedAt',
|
|
108
100
|
)
|
|
109
101
|
|
|
102
|
+
@field_serializer('activated_at', when_used='always')
|
|
103
|
+
def serialize_activated_at(self, value: datetime) -> float:
|
|
104
|
+
return value.timestamp()
|
|
105
|
+
|
|
110
106
|
position: dict[str, Any] = Field(
|
|
111
107
|
default_factory=dict,
|
|
112
108
|
description='Defines the position of the operation',
|
|
@@ -128,6 +124,10 @@ class OperationPayload(BaseModel):
|
|
|
128
124
|
alias='presenceType',
|
|
129
125
|
)
|
|
130
126
|
|
|
127
|
+
@field_serializer('presence_type', when_used='always')
|
|
128
|
+
def serialize_presence_type(self, value: PresenceType | None) -> Any:
|
|
129
|
+
return value.value if value else None
|
|
130
|
+
|
|
131
131
|
case_: OperationCasePayload | None = Field(
|
|
132
132
|
default=None,
|
|
133
133
|
description='Defines the case of the operation',
|
|
@@ -167,6 +167,11 @@ class OperationPayload(BaseModel):
|
|
|
167
167
|
description='Defines the HTTP method of the operation',
|
|
168
168
|
alias='method',
|
|
169
169
|
)
|
|
170
|
+
|
|
171
|
+
@field_serializer('http_method', when_used='always')
|
|
172
|
+
def serialize_http_method(self, value: HttpRequestType | None) -> Any:
|
|
173
|
+
return value.value if value else None
|
|
174
|
+
|
|
170
175
|
http_headers: list[dict[str, Any]] = Field(
|
|
171
176
|
default_factory=list,
|
|
172
177
|
description='Defines the headers of the operation',
|
|
@@ -221,12 +226,27 @@ class OperationPayload(BaseModel):
|
|
|
221
226
|
alias='hostPhone',
|
|
222
227
|
)
|
|
223
228
|
|
|
229
|
+
@field_validator('twilio_host_phone', mode='before')
|
|
230
|
+
def serialize_twilio_host_phone(cls, value: Any) -> DestinationPhone | None:
|
|
231
|
+
"""Serialize host phone to a DestinationPhone"""
|
|
232
|
+
if isinstance(value, DestinationPhone):
|
|
233
|
+
return value
|
|
234
|
+
|
|
235
|
+
if isinstance(value, dict):
|
|
236
|
+
return DestinationPhone.model_validate(value)
|
|
237
|
+
|
|
238
|
+
return None
|
|
239
|
+
|
|
224
240
|
twilio_notification_type: TwilioNotificationType = Field(
|
|
225
241
|
default=TwilioNotificationType.SMS,
|
|
226
242
|
description='Defines the Twilio notification type of the operation',
|
|
227
243
|
alias='notificationType',
|
|
228
244
|
)
|
|
229
245
|
|
|
246
|
+
@field_serializer('twilio_notification_type', when_used='always')
|
|
247
|
+
def serialize_twilio_notification_type(self, value: TwilioNotificationType) -> str:
|
|
248
|
+
return value.value
|
|
249
|
+
|
|
230
250
|
username: str | None = Field(
|
|
231
251
|
default=None,
|
|
232
252
|
description='Defines the username for the operation',
|
|
@@ -262,6 +282,10 @@ class OperationPayload(BaseModel):
|
|
|
262
282
|
alias='pushPlatforms',
|
|
263
283
|
)
|
|
264
284
|
|
|
285
|
+
@field_serializer('push_platforms', when_used='always')
|
|
286
|
+
def serialize_push_platforms(self, value: list[Platform]) -> list[str]:
|
|
287
|
+
return [platform.value for platform in value]
|
|
288
|
+
|
|
265
289
|
## For usage of In-app notifications operations
|
|
266
290
|
destinations_ids: list[int] = Field(
|
|
267
291
|
default_factory=list,
|
|
@@ -274,6 +298,10 @@ class OperationPayload(BaseModel):
|
|
|
274
298
|
alias='soundEffect',
|
|
275
299
|
)
|
|
276
300
|
|
|
301
|
+
@field_serializer('sound_effect', when_used='always')
|
|
302
|
+
def serialize_sound_effect(self, value: SoundEffect) -> str:
|
|
303
|
+
return value.value
|
|
304
|
+
|
|
277
305
|
sound_effect_uri: str | None = Field(
|
|
278
306
|
default=None,
|
|
279
307
|
description='Defines the sound effect URI for the operation',
|
|
@@ -301,3 +329,12 @@ class OperationPayload(BaseModel):
|
|
|
301
329
|
if isinstance(value, (int, float)):
|
|
302
330
|
return timedelta(seconds=value)
|
|
303
331
|
return timedelta(seconds=0)
|
|
332
|
+
|
|
333
|
+
@field_serializer('duration', when_used='always')
|
|
334
|
+
def serialize_duration(self, value: timedelta) -> float:
|
|
335
|
+
return value.total_seconds()
|
|
336
|
+
|
|
337
|
+
locator: Locator | None = Field(
|
|
338
|
+
default=None,
|
|
339
|
+
description='Defines the generated locator for the operation',
|
|
340
|
+
)
|
|
@@ -1,14 +1,21 @@
|
|
|
1
|
-
"""Service entity"""
|
|
2
|
-
|
|
3
1
|
from typing import Any
|
|
4
2
|
|
|
5
|
-
from pydantic import BaseModel, Field
|
|
3
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
6
4
|
|
|
7
5
|
|
|
8
6
|
class OutboundService(BaseModel):
|
|
9
7
|
"""Outbound service definition"""
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
model_config = ConfigDict(
|
|
10
|
+
validate_by_name=False,
|
|
11
|
+
validate_by_alias=True,
|
|
12
|
+
serialize_by_alias=True,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
pk: int = Field(
|
|
16
|
+
description='Service ID',
|
|
17
|
+
alias='id',
|
|
18
|
+
)
|
|
12
19
|
name: str = Field(description='Service name')
|
|
13
20
|
|
|
14
21
|
protocol_name: str | None = Field(
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from pydantic import BaseModel, Field, field_serializer, field_validator
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ParamData(BaseModel):
|
|
8
|
+
value: Any | None = Field(default=None, description='The current value of the parameter.')
|
|
9
|
+
updated_at: datetime = Field(..., description='The timestamp when the parameter was updated.')
|
|
10
|
+
|
|
11
|
+
@field_serializer('updated_at', when_used='always')
|
|
12
|
+
def serialize_updated_at(self, value: datetime) -> float:
|
|
13
|
+
return value.timestamp()
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ParameterUpdate(BaseModel):
|
|
17
|
+
asset_id: int = Field(..., description='The unique identifier for the asset.')
|
|
18
|
+
parameters: dict[str, ParamData] = Field(
|
|
19
|
+
default_factory=dict,
|
|
20
|
+
description='A mapping of parameter names to their data.',
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
@field_validator('parameters', mode='before')
|
|
24
|
+
def validate_parameter(cls, value: dict[str, Any]) -> dict[str, Any]:
|
|
25
|
+
return {k.replace('__', '.'): v for k, v in value.items()}
|
layrz_sdk/entities/platform.py
CHANGED
layrz_sdk/entities/position.py
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
"""Position entity"""
|
|
2
|
-
|
|
3
1
|
from typing import Any, Self, cast
|
|
4
2
|
|
|
5
|
-
from pydantic import BaseModel, Field, field_validator
|
|
3
|
+
from pydantic import BaseModel, ConfigDict, Field, field_validator
|
|
6
4
|
|
|
7
5
|
|
|
8
6
|
class Position(BaseModel):
|
|
9
7
|
"""Geographic position definition"""
|
|
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
|
latitude: float | None = Field(default=None, description='Defines the latitude of the position')
|
|
12
16
|
longitude: float | None = Field(default=None, description='Defines the longitude of the position')
|
|
13
17
|
altitude: float | None = Field(default=None, description='Defines the altitude of the position')
|
layrz_sdk/entities/preset.py
CHANGED
|
@@ -1,25 +1,31 @@
|
|
|
1
|
-
"""Preset 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 Preset(BaseModel):
|
|
9
7
|
"""Preset 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 preset',
|
|
17
|
+
alias='id',
|
|
18
|
+
)
|
|
18
19
|
name: str = Field(description='Defines the name of the preset')
|
|
19
20
|
valid_before: datetime = Field(
|
|
20
21
|
...,
|
|
21
22
|
description='Defines the date and time before which the preset is valid',
|
|
22
23
|
)
|
|
24
|
+
|
|
25
|
+
@field_serializer('valid_before', when_used='always')
|
|
26
|
+
def serialize_valid_before(self, valid_before: datetime) -> float:
|
|
27
|
+
return valid_before.timestamp()
|
|
28
|
+
|
|
23
29
|
comment: str = Field(
|
|
24
30
|
default='',
|
|
25
31
|
description='Defines the comment of the preset',
|
layrz_sdk/entities/report.py
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
"""Report class"""
|
|
2
|
-
|
|
3
1
|
import logging
|
|
4
2
|
import os
|
|
5
3
|
import time
|
|
@@ -8,7 +6,7 @@ from pathlib import Path
|
|
|
8
6
|
from typing import Any, Optional, Self
|
|
9
7
|
|
|
10
8
|
import xlsxwriter
|
|
11
|
-
from pydantic import BaseModel, Field, field_validator
|
|
9
|
+
from pydantic import BaseModel, ConfigDict, Field, field_validator
|
|
12
10
|
|
|
13
11
|
from layrz_sdk.entities.custom_report_page import CustomReportPage
|
|
14
12
|
from layrz_sdk.entities.report_data_type import ReportDataType
|
|
@@ -22,6 +20,12 @@ log = logging.getLogger(__name__)
|
|
|
22
20
|
class Report(BaseModel):
|
|
23
21
|
"""Report definition"""
|
|
24
22
|
|
|
23
|
+
model_config = ConfigDict(
|
|
24
|
+
validate_by_name=False,
|
|
25
|
+
validate_by_alias=True,
|
|
26
|
+
serialize_by_alias=True,
|
|
27
|
+
)
|
|
28
|
+
|
|
25
29
|
name: str = Field(description='Name of the report. Length should be less than 60 characters')
|
|
26
30
|
pages: list[ReportPage | CustomReportPage] = Field(
|
|
27
31
|
description='List of report pages',
|
|
@@ -113,10 +117,10 @@ class Report(BaseModel):
|
|
|
113
117
|
for cell in row.content:
|
|
114
118
|
cells.append(
|
|
115
119
|
{
|
|
116
|
-
'content': cell.content,
|
|
120
|
+
'content': cell.content.timestamp() if cell.data_type == ReportDataType.DATETIME else cell.content,
|
|
117
121
|
'text_color': '#000000' if use_black(cell.color) else '#ffffff',
|
|
118
122
|
'color': cell.color,
|
|
119
|
-
'data_type': cell.data_type.
|
|
123
|
+
'data_type': cell.data_type.name,
|
|
120
124
|
}
|
|
121
125
|
)
|
|
122
126
|
rows.append(
|