layrz-sdk 4.0.35__py3-none-any.whl → 4.1.0__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.

Files changed (97) hide show
  1. layrz_sdk/decorators/func_timing.py +14 -7
  2. layrz_sdk/entities/action.py +28 -16
  3. layrz_sdk/entities/action_geofence_ownership.py +0 -2
  4. layrz_sdk/entities/action_kind.py +0 -2
  5. layrz_sdk/entities/action_subkind.py +0 -2
  6. layrz_sdk/entities/asset.py +15 -9
  7. layrz_sdk/entities/asset_constants.py +10 -9
  8. layrz_sdk/entities/asset_contact.py +7 -3
  9. layrz_sdk/entities/asset_operation_mode.py +0 -2
  10. layrz_sdk/entities/ats_entry.py +11 -4
  11. layrz_sdk/entities/ats_exit_history.py +21 -19
  12. layrz_sdk/entities/ats_operation.py +57 -17
  13. layrz_sdk/entities/ats_possible_entry.py +9 -4
  14. layrz_sdk/entities/ats_possible_exit.py +19 -9
  15. layrz_sdk/entities/ats_purchaseorder.py +47 -12
  16. layrz_sdk/entities/ats_reception.py +16 -4
  17. layrz_sdk/entities/broadcast/result.py +21 -2
  18. layrz_sdk/entities/broadcast/service.py +12 -2
  19. layrz_sdk/entities/case.py +34 -7
  20. layrz_sdk/entities/charts/axis_config.py +13 -5
  21. layrz_sdk/entities/charts/bar_chart.py +12 -1
  22. layrz_sdk/entities/charts/chart_data_serie.py +17 -1
  23. layrz_sdk/entities/charts/column_chart.py +12 -1
  24. layrz_sdk/entities/charts/html_chart.py +8 -4
  25. layrz_sdk/entities/charts/line_chart.py +12 -3
  26. layrz_sdk/entities/charts/map_chart.py +14 -5
  27. layrz_sdk/entities/charts/map_point.py +7 -1
  28. layrz_sdk/entities/charts/number_chart.py +8 -4
  29. layrz_sdk/entities/charts/pie_chart.py +11 -3
  30. layrz_sdk/entities/charts/radar_chart.py +11 -3
  31. layrz_sdk/entities/charts/radial_bar_chart.py +11 -3
  32. layrz_sdk/entities/charts/scatter_chart.py +12 -3
  33. layrz_sdk/entities/charts/scatter_serie.py +11 -1
  34. layrz_sdk/entities/charts/scatter_serie_item.py +7 -1
  35. layrz_sdk/entities/charts/table_chart.py +7 -3
  36. layrz_sdk/entities/charts/table_header.py +7 -1
  37. layrz_sdk/entities/charts/table_row.py +7 -1
  38. layrz_sdk/entities/charts/timeline_chart.py +11 -3
  39. layrz_sdk/entities/charts/timeline_serie.py +7 -1
  40. layrz_sdk/entities/charts/timeline_serie_item.py +7 -1
  41. layrz_sdk/entities/checkpoint.py +20 -13
  42. layrz_sdk/entities/command_series_ticket.py +29 -4
  43. layrz_sdk/entities/comment.py +15 -4
  44. layrz_sdk/entities/custom_field.py +12 -4
  45. layrz_sdk/entities/custom_report_page.py +3 -0
  46. layrz_sdk/entities/destination_phone.py +7 -1
  47. layrz_sdk/entities/device.py +11 -4
  48. layrz_sdk/entities/event.py +20 -4
  49. layrz_sdk/entities/exchange_service.py +12 -4
  50. layrz_sdk/entities/function.py +11 -4
  51. layrz_sdk/entities/geofence.py +12 -4
  52. layrz_sdk/entities/geofence_category.py +0 -2
  53. layrz_sdk/entities/last_message.py +7 -3
  54. layrz_sdk/entities/locator.py +16 -2
  55. layrz_sdk/entities/message.py +16 -9
  56. layrz_sdk/entities/modbus/config.py +7 -1
  57. layrz_sdk/entities/modbus/parameter.py +7 -1
  58. layrz_sdk/entities/modbus/wait.py +11 -1
  59. layrz_sdk/entities/notification_type.py +0 -2
  60. layrz_sdk/entities/operation.py +37 -16
  61. layrz_sdk/entities/operation_case_payload.py +39 -13
  62. layrz_sdk/entities/operation_payload.py +13 -51
  63. layrz_sdk/entities/operation_type.py +0 -2
  64. layrz_sdk/entities/outbound_service.py +11 -4
  65. layrz_sdk/entities/platform.py +0 -2
  66. layrz_sdk/entities/position.py +7 -3
  67. layrz_sdk/entities/preset.py +15 -9
  68. layrz_sdk/entities/report.py +7 -3
  69. layrz_sdk/entities/report_col.py +17 -3
  70. layrz_sdk/entities/report_configuration.py +7 -1
  71. layrz_sdk/entities/report_data_type.py +1 -3
  72. layrz_sdk/entities/report_format.py +1 -5
  73. layrz_sdk/entities/report_header.py +12 -29
  74. layrz_sdk/entities/report_page.py +7 -3
  75. layrz_sdk/entities/report_row.py +7 -19
  76. layrz_sdk/entities/request_type.py +0 -2
  77. layrz_sdk/entities/sensor.py +11 -4
  78. layrz_sdk/entities/sensor_mask.py +7 -3
  79. layrz_sdk/entities/sound_effect.py +0 -2
  80. layrz_sdk/entities/static_position.py +6 -1
  81. layrz_sdk/entities/telemetry/assetmessage.py +14 -15
  82. layrz_sdk/entities/telemetry/devicemessage.py +17 -8
  83. layrz_sdk/entities/text_alignment.py +0 -2
  84. layrz_sdk/entities/timezone.py +12 -4
  85. layrz_sdk/entities/trigger.py +12 -14
  86. layrz_sdk/entities/trigger_kind.py +1 -5
  87. layrz_sdk/entities/user.py +11 -4
  88. layrz_sdk/entities/waypoint.py +38 -16
  89. layrz_sdk/entities/weekday.py +1 -3
  90. layrz_sdk/helpers/color.py +1 -6
  91. layrz_sdk/lcl/core.py +0 -1
  92. {layrz_sdk-4.0.35.dist-info → layrz_sdk-4.1.0.dist-info}/METADATA +2 -2
  93. layrz_sdk-4.1.0.dist-info/RECORD +122 -0
  94. layrz_sdk-4.0.35.dist-info/RECORD +0 -122
  95. {layrz_sdk-4.0.35.dist-info → layrz_sdk-4.1.0.dist-info}/WHEEL +0 -0
  96. {layrz_sdk-4.0.35.dist-info → layrz_sdk-4.1.0.dist-info}/licenses/LICENSE +0 -0
  97. {layrz_sdk-4.0.35.dist-info → layrz_sdk-4.1.0.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,3 @@
1
- """Http Operation Type"""
2
-
3
1
  from enum import StrEnum
4
2
  from typing import Self
5
3
 
@@ -1,6 +1,4 @@
1
- """Sensor entity"""
2
-
3
- from pydantic import BaseModel, Field
1
+ from pydantic import BaseModel, ConfigDict, Field
4
2
 
5
3
  from .sensor_mask import SensorMask
6
4
 
@@ -8,7 +6,16 @@ from .sensor_mask import SensorMask
8
6
  class Sensor(BaseModel):
9
7
  """Sensor entity"""
10
8
 
11
- pk: int = Field(description='Defines the primary key of the sensor', alias='id')
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='Defines the primary key of the sensor',
17
+ alias='id',
18
+ )
12
19
  name: str = Field(description='Defines the name of the sensor')
13
20
  slug: str = Field(description='Defines the slug of the sensor')
14
21
  formula: str = Field(
@@ -1,11 +1,15 @@
1
- """Sensor entity"""
2
-
3
- from pydantic import BaseModel, Field
1
+ from pydantic import BaseModel, ConfigDict, Field
4
2
 
5
3
 
6
4
  class SensorMask(BaseModel):
7
5
  """Sensor entity"""
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
  icon: str | None = Field(description='Defines the icon of the sensor')
10
14
  text: str | None = Field(description='Defines the text of the sensor')
11
15
  color: str | None = Field(
@@ -1,5 +1,3 @@
1
- """SoundEffect"""
2
-
3
1
  from enum import StrEnum
4
2
  from typing import Self
5
3
 
@@ -1,7 +1,12 @@
1
- from pydantic import BaseModel, Field
1
+ from pydantic import BaseModel, ConfigDict, Field
2
2
 
3
3
 
4
4
  class StaticPosition(BaseModel):
5
+ model_config = ConfigDict(
6
+ validate_by_name=False,
7
+ validate_by_alias=True,
8
+ serialize_by_alias=True,
9
+ )
5
10
  latitude: float = Field(
6
11
  ...,
7
12
  description='Latitude of the static position',
@@ -1,13 +1,10 @@
1
- """Asset message"""
2
-
3
1
  from __future__ import annotations
4
2
 
5
- import json
6
3
  from datetime import datetime, timedelta
7
4
  from typing import Any, Self, cast
8
5
 
9
6
  from geopy.distance import geodesic
10
- from pydantic import BaseModel, Field, field_serializer
7
+ from pydantic import BaseModel, ConfigDict, Field, field_serializer
11
8
  from shapely.geometry import MultiPoint
12
9
 
13
10
  from layrz_sdk.constants import UTC
@@ -21,15 +18,17 @@ from layrz_sdk.entities.telemetry.devicemessage import DeviceMessage
21
18
  class AssetMessage(BaseModel):
22
19
  """Asset message model"""
23
20
 
24
- model_config = {
25
- 'json_encoders': {
26
- datetime: lambda v: v.timestamp(),
27
- timedelta: lambda v: v.total_seconds(),
28
- Position: lambda v: json.loads(v.model_dump_json(exclude_none=True)),
29
- }
30
- }
21
+ model_config = ConfigDict(
22
+ validate_by_name=False,
23
+ validate_by_alias=True,
24
+ serialize_by_alias=True,
25
+ )
31
26
 
32
- pk: int | None = Field(default=None, description='Message ID', alias='id')
27
+ pk: int | None = Field(
28
+ default=None,
29
+ description='Message ID',
30
+ alias='id',
31
+ )
33
32
  asset_id: int = Field(..., description='Asset ID')
34
33
 
35
34
  position: dict[str, float | int] = Field(
@@ -62,7 +61,7 @@ class AssetMessage(BaseModel):
62
61
  description='Timestamp when the message was received',
63
62
  )
64
63
 
65
- @field_serializer('received_at')
64
+ @field_serializer('received_at', when_used='always')
66
65
  def serialize_received_at(self: Self, value: datetime) -> float:
67
66
  """Serialize received_at to a timestamp."""
68
67
  return value.timestamp()
@@ -72,7 +71,7 @@ class AssetMessage(BaseModel):
72
71
  description='Elapsed time since the last message',
73
72
  )
74
73
 
75
- @field_serializer('elapsed_time')
74
+ @field_serializer('elapsed_time', when_used='always')
76
75
  def serialize_elapsed_time(self: Self, value: timedelta) -> float:
77
76
  """Serialize elapsed_time to total seconds."""
78
77
  return value.total_seconds()
@@ -153,7 +152,7 @@ class AssetMessage(BaseModel):
153
152
  def to_message(self: Self) -> Message:
154
153
  """Convert the asset message to a Message object."""
155
154
  return Message(
156
- id=self.pk if self.pk is not None else 0,
155
+ id=self.pk if self.pk is not None else 0, # ty: ignore
157
156
  asset_id=self.asset_id,
158
157
  position=Position.model_validate(self.position),
159
158
  payload=self.payload,
@@ -1,12 +1,9 @@
1
- """Device message"""
2
-
3
1
  from __future__ import annotations
4
2
 
5
- import json
6
3
  from datetime import datetime
7
4
  from typing import Any, Self
8
5
 
9
- from pydantic import BaseModel, Field, field_serializer
6
+ from pydantic import BaseModel, ConfigDict, Field, field_serializer
10
7
 
11
8
  from layrz_sdk.constants import REJECTED_KEYS, UTC
12
9
  from layrz_sdk.entities.device import Device
@@ -17,7 +14,16 @@ from layrz_sdk.entities.position import Position
17
14
  class DeviceMessage(BaseModel):
18
15
  """Device message model"""
19
16
 
20
- pk: int | None = Field(default=None, description='Device message ID', alias='id')
17
+ model_config = ConfigDict(
18
+ validate_by_name=False,
19
+ validate_by_alias=True,
20
+ serialize_by_alias=True,
21
+ )
22
+ pk: int | None = Field(
23
+ default=None,
24
+ description='Device message ID',
25
+ alias='id',
26
+ )
21
27
  ident: str = Field(..., description='Device identifier')
22
28
  device_id: int = Field(..., description='Device ID')
23
29
  protocol_id: int = Field(..., description='Protocol ID')
@@ -37,7 +43,7 @@ class DeviceMessage(BaseModel):
37
43
  description='Timestamp when the message was received',
38
44
  )
39
45
 
40
- @field_serializer('received_at')
46
+ @field_serializer('received_at', when_used='always')
41
47
  def serialize_received_at(self: Self, value: datetime) -> float:
42
48
  """Serialize received_at to a timestamp."""
43
49
  return value.timestamp()
@@ -69,6 +75,9 @@ class DeviceMessage(BaseModel):
69
75
  @classmethod
70
76
  def parse_from_dict(cls, *, raw_payload: dict[str, Any], device: Device) -> DeviceMessage:
71
77
  """Format a DeviceMessage from a dictionary."""
78
+ if not device.protocol_id:
79
+ raise ValueError('Device protocol_id is required to parse DeviceMessage')
80
+
72
81
  received_at: datetime
73
82
  position: dict[str, float | int] = {}
74
83
  payload: dict[str, Any] = {}
@@ -88,7 +97,7 @@ class DeviceMessage(BaseModel):
88
97
  return cls(
89
98
  ident=device.ident,
90
99
  device_id=device.pk,
91
- protocol_id=device.protocol_id, # type: ignore
100
+ protocol_id=device.protocol_id,
92
101
  position=position,
93
102
  payload=payload,
94
103
  received_at=received_at,
@@ -97,7 +106,7 @@ class DeviceMessage(BaseModel):
97
106
  def to_message(self: Self) -> Message:
98
107
  """Convert the asset message to a Message object."""
99
108
  return Message(
100
- id=self.pk if self.pk is not None else 0,
109
+ id=self.pk if self.pk is not None else 0, # ty: ignore
101
110
  asset_id=self.device_id if self.device_id is not None else 0,
102
111
  position=Position.model_validate(self.position),
103
112
  payload=self.payload,
@@ -1,5 +1,3 @@
1
- """Text alignment"""
2
-
3
1
  from enum import StrEnum
4
2
  from typing import Self
5
3
 
@@ -1,11 +1,19 @@
1
- """Timezone entity"""
2
-
3
- from pydantic import BaseModel, Field
1
+ from pydantic import BaseModel, ConfigDict, Field
4
2
 
5
3
 
6
4
  class Timezone(BaseModel):
7
5
  """Timezone entity"""
8
6
 
9
- pk: int = Field(..., description='Defines the primary key of the timezone', alias='id')
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
+ ...,
15
+ description='Defines the primary key of the timezone',
16
+ alias='id',
17
+ )
10
18
  name: str = Field(..., description='Defines the name of the timezone')
11
19
  offset: int = Field(..., description='Defines the offset of the timezone in seconds from UTC')
@@ -3,7 +3,7 @@
3
3
  from datetime import time, timedelta
4
4
  from typing import Any
5
5
 
6
- from pydantic import BaseModel, Field, field_serializer, field_validator
6
+ from pydantic import BaseModel, ConfigDict, Field, field_serializer, field_validator
7
7
 
8
8
  from .trigger_kind import TriggerCaseKind, TriggerCommentPattern, TriggerGeofenceKind, TriggerKind
9
9
  from .weekday import Weekday
@@ -12,7 +12,16 @@ from .weekday import Weekday
12
12
  class Trigger(BaseModel):
13
13
  """Trigger entity"""
14
14
 
15
- pk: int = Field(description='Defines the primary key of the trigger', alias='id')
15
+ model_config = ConfigDict(
16
+ validate_by_name=False,
17
+ validate_by_alias=True,
18
+ serialize_by_alias=True,
19
+ )
20
+
21
+ pk: int = Field(
22
+ description='Defines the primary key of the trigger',
23
+ alias='id',
24
+ )
16
25
  name: str = Field(description='Defines the name of the trigger')
17
26
  code: str = Field(description='Defines the code of the trigger')
18
27
 
@@ -34,7 +43,6 @@ class Trigger(BaseModel):
34
43
 
35
44
  @field_serializer('type_', when_used='always')
36
45
  def serialize_type(self, value: TriggerKind | None) -> str | None:
37
- """Serialize type_ to its value."""
38
46
  return value.value if value else None
39
47
 
40
48
  presence_type: TriggerGeofenceKind | None = Field(
@@ -44,7 +52,6 @@ class Trigger(BaseModel):
44
52
 
45
53
  @field_serializer('presence_type', when_used='always')
46
54
  def serialize_presence_type(self, value: TriggerGeofenceKind | None) -> str | None:
47
- """Serialize presence_type to its value."""
48
55
  return value.value if value else None
49
56
 
50
57
  case_type: TriggerCaseKind | None = Field(
@@ -54,7 +61,6 @@ class Trigger(BaseModel):
54
61
 
55
62
  @field_serializer('case_type', when_used='always')
56
63
  def serialize_case_type(self, value: TriggerCaseKind | None) -> str | None:
57
- """Serialize case_type to its value."""
58
64
  return value.value if value else None
59
65
 
60
66
  case_comment_pattern: TriggerCommentPattern | None = Field(
@@ -64,7 +70,6 @@ class Trigger(BaseModel):
64
70
 
65
71
  @field_serializer('case_comment_pattern', when_used='always')
66
72
  def serialize_case_comment_pattern(self, value: TriggerCommentPattern | None) -> str | None:
67
- """Serialize case_comment_pattern to its value."""
68
73
  return value.value if value else None
69
74
 
70
75
  case_comment_value: str | None = Field(
@@ -88,7 +93,6 @@ class Trigger(BaseModel):
88
93
 
89
94
  @field_serializer('weekdays', when_used='always')
90
95
  def serialize_weekdays(self, value: list[Weekday]) -> list[str]:
91
- """Serialize weekdays to their values."""
92
96
  return [day.value for day in value]
93
97
 
94
98
  is_plain_crontab: bool = Field(
@@ -113,10 +117,7 @@ class Trigger(BaseModel):
113
117
 
114
118
  @field_validator('manual_action_fields', mode='before')
115
119
  def validate_manual_action_fields(cls, value: Any) -> list[dict[str, Any]]:
116
- """Ensure manual_action_fields is a list of dictionaries."""
117
- if isinstance(value, list):
118
- return value
119
- return []
120
+ return value if isinstance(value, list) else []
120
121
 
121
122
  formula: str | None = Field(
122
123
  default=None,
@@ -176,7 +177,6 @@ class Trigger(BaseModel):
176
177
 
177
178
  @field_serializer('when_case_expires_delta', when_used='always')
178
179
  def serialize_when_case_expires_delta(self, value: timedelta | None) -> float | None:
179
- """Serialize when_case_expires_delta to total seconds."""
180
180
  return value.total_seconds() if value else None
181
181
 
182
182
  should_stack: bool = Field(
@@ -200,7 +200,6 @@ class Trigger(BaseModel):
200
200
 
201
201
  @field_serializer('search_time_delta', when_used='always')
202
202
  def serialize_search_time_delta(self, value: timedelta | None) -> float | None:
203
- """Serialize search_time_delta to total seconds."""
204
203
  return value.total_seconds() if value else None
205
204
 
206
205
  is_paused: bool = Field(
@@ -220,7 +219,6 @@ class Trigger(BaseModel):
220
219
 
221
220
  @field_serializer('locator_expires_delta', when_used='always')
222
221
  def serialize_locator_expires_delta(self, value: timedelta | None) -> float | None:
223
- """Serialize locator_expires_delta to total seconds."""
224
222
  return value.total_seconds() if value else None
225
223
 
226
224
  locator_expires_triggers_ids: list[int] = Field(
@@ -1,13 +1,9 @@
1
- """Asset Operation Mode"""
2
-
3
1
  from enum import StrEnum
4
2
  from typing import Self
5
3
 
6
4
 
7
5
  class TriggerKind(StrEnum):
8
- """
9
- Trigger Kind definition
10
- """
6
+ """Trigger Kind definition"""
11
7
 
12
8
  PRESENCE_IN_GEOFENCE = 'PRESENCEINGEOFENCE'
13
9
  EXACT_TIME = 'EXACTTIME'
@@ -1,10 +1,17 @@
1
- """User entity"""
2
-
3
- from pydantic import BaseModel, Field
1
+ from pydantic import BaseModel, ConfigDict, Field
4
2
 
5
3
 
6
4
  class User(BaseModel):
7
5
  """User entity"""
8
6
 
9
- pk: int = Field(description='Defines the primary key of the user', alias='id')
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 user',
15
+ alias='id',
16
+ )
10
17
  name: str = Field(description='Defines the name of the user')
@@ -1,9 +1,7 @@
1
- """Waypoint entity"""
2
-
3
1
  from datetime import datetime, timedelta
4
2
  from enum import StrEnum
5
3
 
6
- from pydantic import BaseModel, Field
4
+ from pydantic import BaseModel, ConfigDict, Field, field_serializer
7
5
 
8
6
  from .geofence import Geofence
9
7
 
@@ -25,17 +23,30 @@ class WaypointKind(StrEnum):
25
23
  class Waypoint(BaseModel):
26
24
  """Waypoint entity definition"""
27
25
 
28
- model_config = {
29
- 'json_encoders': {
30
- datetime: lambda v: v.timestamp(),
31
- },
32
- }
26
+ model_config = ConfigDict(
27
+ validate_by_name=False,
28
+ validate_by_alias=True,
29
+ serialize_by_alias=True,
30
+ )
33
31
 
34
- pk: int = Field(description='Waypoint ID', alias='id')
32
+ pk: int = Field(
33
+ description='Waypoint ID',
34
+ alias='id',
35
+ )
35
36
  geofence: Geofence | None = Field(default=None, description='Geofence object')
36
37
  geofence_id: int | None = Field(default=None, description='Geofence ID')
37
38
  start_at: datetime | None = Field(default=None, description='Waypoint start date')
39
+
40
+ @field_serializer('start_at', when_used='always')
41
+ def serialize_start_at(self, value: datetime | None) -> float | None:
42
+ return value.timestamp() if value else None
43
+
38
44
  end_at: datetime | None = Field(default=None, description='Waypoint end date')
45
+
46
+ @field_serializer('end_at', when_used='always')
47
+ def serialize_end_at(self, value: datetime | None) -> float | None:
48
+ return value.timestamp() if value else None
49
+
39
50
  sequence_real: int = Field(..., description='Real sequence number')
40
51
  sequence_ideal: int = Field(..., description='Ideal sequence number')
41
52
 
@@ -43,20 +54,31 @@ class Waypoint(BaseModel):
43
54
  class WaypointRef(BaseModel):
44
55
  """Waypoint reference entity definition"""
45
56
 
46
- model_config = {
47
- 'json_encoders': {
48
- timedelta: lambda v: v.total_seconds(),
49
- datetime: lambda v: v.timestamp(),
50
- },
51
- }
57
+ model_config = ConfigDict(
58
+ validate_by_name=False,
59
+ validate_by_alias=True,
60
+ serialize_by_alias=True,
61
+ )
52
62
 
53
- pk: int = Field(description='Waypoint ID', alias='id')
63
+ pk: int = Field(
64
+ description='Waypoint ID',
65
+ alias='id',
66
+ )
54
67
  geofence_id: int = Field(description='Geofence ID')
55
68
  time: timedelta = Field(
56
69
  default_factory=lambda: timedelta(seconds=0),
57
70
  description='Time offset from the start of the checkpoint',
58
71
  )
72
+
73
+ @field_serializer('time', when_used='always')
74
+ def serialize_time(self, value: timedelta) -> float:
75
+ return value.total_seconds()
76
+
59
77
  kind: WaypointKind = Field(
60
78
  ...,
61
79
  description='Defines the kind of waypoint',
62
80
  )
81
+
82
+ @field_serializer('kind', when_used='always')
83
+ def serialize_kind(self, value: WaypointKind) -> str:
84
+ return value.value
@@ -3,9 +3,7 @@ from typing import Self
3
3
 
4
4
 
5
5
  class Weekday(StrEnum):
6
- """
7
- Weekday definition
8
- """
6
+ """Weekday definition"""
9
7
 
10
8
  MONDAY = 'MON'
11
9
  TUESDAY = 'TUE'
@@ -10,11 +10,7 @@ def convert_to_rgba(hex_color: str) -> Color:
10
10
  Convert Hex (or Hexa) color to RGB (or RGBA) color
11
11
 
12
12
  :param hex_color: Hex color
13
- :type hex_color: str
14
-
15
13
  :return: RGB or RGBA color
16
- :rtype: tuple
17
-
18
14
  :raises ValueError: If the color is invalid
19
15
  """
20
16
 
@@ -33,10 +29,9 @@ def use_black(color: str) -> bool:
33
29
  Use black
34
30
  Will return when the background color works well with black text color.
35
31
  Note: This method is not 100% accurate and will not work with alpha channel (Hexa color)
32
+
36
33
  :param color: Hex color
37
- :type color: str
38
34
  :return: True if the color works well with black text color
39
- :rtype: bool
40
35
  :raises ValueError: If the color is invalid
41
36
  """
42
37
  rgb = convert_to_rgba(color)
layrz_sdk/lcl/core.py CHANGED
@@ -1,6 +1,5 @@
1
1
  """Layrz Compute Language SDK"""
2
2
 
3
- # ruff: noqa: ANN401
4
3
  from typing import Any, Optional, Self, cast
5
4
 
6
5
  PATTERN_INVALID = 'Pattern should be string, received {received}'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: layrz-sdk
3
- Version: 4.0.35
3
+ Version: 4.1.0
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>
@@ -18,7 +18,7 @@ Requires-Python: >=3.13
18
18
  Description-Content-Type: text/markdown
19
19
  License-File: LICENSE
20
20
  Requires-Dist: xlsxwriter<4.0.0,>=3.2.5
21
- Requires-Dist: pydantic>=2.10.6
21
+ Requires-Dist: pydantic>=2.12.3
22
22
  Requires-Dist: geopy>=2.4.1
23
23
  Requires-Dist: shapely>=2.1.1
24
24
  Requires-Dist: strenum>=0.4.15
@@ -0,0 +1,122 @@
1
+ layrz_sdk/__init__.py,sha256=OutylN0QazaeDVIA5NRDVyzwfYnZkAwVQzT-2F6iX2M,28
2
+ layrz_sdk/constants.py,sha256=guXfIsVAcex76OEMv6DAJy1km1A_WUfWJuUO2Lo3kXE,344
3
+ layrz_sdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ layrz_sdk/decorators/__init__.py,sha256=btoa1egRuYFWggsnfXprvCnxBN9Oq8pbRGcRUR2lm10,82
5
+ layrz_sdk/decorators/func_timing.py,sha256=EAha7WMeADyv7oI070848msfWlsnDjIS09pewcNsGD4,2488
6
+ layrz_sdk/entities/__init__.py,sha256=hvsAyhEmAbQ0WD0Z2x--ILnBG6qbamYAsI38WSopLE8,6613
7
+ layrz_sdk/entities/action.py,sha256=w8i4VKG1lrVIt4-coAJIFQqyXxgV6wy1DCnwWv0HF0Y,2491
8
+ layrz_sdk/entities/action_geofence_ownership.py,sha256=WIt4YjKXXNUJFps01n8AuxQwuO3Wqk50wCoWzw64QYw,557
9
+ layrz_sdk/entities/action_kind.py,sha256=RR7Tf2LiWrDcZsiSxMr_EIx9H-Yqm-ghGXK_kK1MQGs,1170
10
+ layrz_sdk/entities/action_subkind.py,sha256=BHXuMe-q5ZZwdSSWsURQNz_3Dz7JCy2F5Yb_CRHtyfw,612
11
+ layrz_sdk/entities/asset.py,sha256=RJHkU-5yojCLYyTdKPkc9gp9gzQwx1Os1HRRzz9Zs_s,3745
12
+ layrz_sdk/entities/asset_constants.py,sha256=_kSd520m4kg8ioJROcv33nDmKq6sQsSN1_J3cFypXwo,792
13
+ layrz_sdk/entities/asset_contact.py,sha256=YmzgeCfFfJTm1pRMPv8FIIlw-ct-eReyJ-GdPU1hnoQ,520
14
+ layrz_sdk/entities/asset_operation_mode.py,sha256=UrxE3X1TNahiIdWZt2Vsy1WSRuAO00TEKdDpaG1uNgE,523
15
+ layrz_sdk/entities/ats_entry.py,sha256=wmvpUOpC3EmdzuhFMmqBUrg0hnw7pqh7zTleqYbiSLk,793
16
+ layrz_sdk/entities/ats_exit_history.py,sha256=DZXioMuWgCv_jIw0xuNUimctHS4HE2ja8lx0AI02cLU,1739
17
+ layrz_sdk/entities/ats_operation.py,sha256=yHuagfSAflFAOCudcQfBFpsIx2phPvl1v1e3bA94zXg,3206
18
+ layrz_sdk/entities/ats_possible_entry.py,sha256=Tta2Yc_GJ9VfRghghFtXNN2x5m1vdY-wLJPvAbnvcAA,1548
19
+ layrz_sdk/entities/ats_possible_exit.py,sha256=KMGtwc_JMdLemh3yXZUpOaAhtYu_HVtlQrM2RSNEZ0Y,2186
20
+ layrz_sdk/entities/ats_purchaseorder.py,sha256=06c-Go-uxZP6Ojiexq58pwplr6vr40yUia88Od4tS80,3981
21
+ layrz_sdk/entities/ats_reception.py,sha256=J21wK5OpB1DNkhue-Qk5T8aT2wX7TogOm4vXLQ6qazU,1251
22
+ layrz_sdk/entities/case.py,sha256=P6KZmAAMm76Cu2FkWH4FjTsc1IvPbXJyIDOzQjkqRiI,3084
23
+ layrz_sdk/entities/case_ignored_status.py,sha256=RWu3pK_BN5Hu35wCg03nnY7xqznACY_m7v8bXbJbZxE,451
24
+ layrz_sdk/entities/case_status.py,sha256=XdlgfOm1OZmHVvlarJuf7CDPPlV80-2koXSSzcdWnt4,355
25
+ layrz_sdk/entities/checkpoint.py,sha256=QiK4zkVRq-zEwln6QW0UMGqo2AhSvo4ByIRW-UYDPP4,1726
26
+ layrz_sdk/entities/command_series_ticket.py,sha256=XZnVGC1kd18WOVh6GMtKY9y8LPFAvFDxw7-ZPtpokLs,2961
27
+ layrz_sdk/entities/comment.py,sha256=-gjdep5_pNvDvFt5Zz-gWVpiczHHvwHIJyjM4TUPh_w,918
28
+ layrz_sdk/entities/custom_field.py,sha256=EMH2o27Q5xdqCHK9GWuTjuKcNexPrHGcy8kJfL90Bio,594
29
+ layrz_sdk/entities/custom_report_page.py,sha256=R60pn5swUFI31BepU8AtN7PkWOzrvL_DVaeHZLkqTxo,1316
30
+ layrz_sdk/entities/destination_phone.py,sha256=nrLrkc-inQB1oaAjmVjJWIbK6JRJjIVEn36uj57lmrM,687
31
+ layrz_sdk/entities/device.py,sha256=vMuqfyCC6SUivEbQku59cxUcPxN_ZdDbBjrv5Id_Olw,1213
32
+ layrz_sdk/entities/event.py,sha256=m4V8PyaySXKs5WwdcUWJ6LXeWSvTfwDJcASUJ79G0uc,1240
33
+ layrz_sdk/entities/exchange_service.py,sha256=HrOzZApx2WNV42Ttua9tPf6iDqxm9nsyXMIWOPO5HD0,782
34
+ layrz_sdk/entities/function.py,sha256=vL5lMfE76t1E5xkKN5T0WjHa1PKdJzdSwcq20mNgtlY,1346
35
+ layrz_sdk/entities/geofence.py,sha256=vtNHgW1imWU9e7-az4BqTCjR9Xfjs9wwojgajXrEyIk,806
36
+ layrz_sdk/entities/geofence_category.py,sha256=kA_LhR9-Miz3M6WLNgIPS3k90a4YdjJLQWWq1WeX1EI,875
37
+ layrz_sdk/entities/last_message.py,sha256=js3U5zQHeBTgvcHdJO2Ql4LG9Y9KK_ShIW-ab9dc8Ds,373
38
+ layrz_sdk/entities/locator.py,sha256=RxWqgn0_7x240Daw2hi4Iq0MCA_qg12UOLnpPiFpHpE,3137
39
+ layrz_sdk/entities/message.py,sha256=8YclcxaVGCmx7FE4AwZzE4FTitXmUf_NwQPWGYRSAns,1659
40
+ layrz_sdk/entities/notification_type.py,sha256=KDAqSNlJGUEq2tOwCrJGiifQlh9muayJJwxEMrUcAAM,632
41
+ layrz_sdk/entities/operation.py,sha256=kdl-8nSnEWURx2yjsJRn87nIoRZNa8VMb3K2RIMLi-U,7406
42
+ layrz_sdk/entities/operation_case_payload.py,sha256=WDL_7YVbrg_eu4E7ZQeWpJTpy7mbsSAhb8zQnHYDdPs,3261
43
+ layrz_sdk/entities/operation_payload.py,sha256=gcSlYT-bQFhltDP-uOresC6W3My0eY1Q0K3ND5DrPeY,10172
44
+ layrz_sdk/entities/operation_type.py,sha256=zoBa0oF42Vf42NzX-HoP7AHMWw4mEg0nMvGyErKB7k0,917
45
+ layrz_sdk/entities/outbound_service.py,sha256=dRh9CvP7bR-tZjTAwTguYvqISx6ZsY7H5C29VzLw34M,785
46
+ layrz_sdk/entities/platform.py,sha256=8iTRAQ-P-utPSN1vmnRUAKB2pgzv2aV1M91---6Fn3w,610
47
+ layrz_sdk/entities/position.py,sha256=jC7s_yj-heRB-5yLp51B97GUiruwqs5Zlf8dYHNSNgE,3081
48
+ layrz_sdk/entities/presence_type.py,sha256=1p_MVREYkB7pey_TUf51QXQdlY5okZpkbiEd_l6oa04,335
49
+ layrz_sdk/entities/preset.py,sha256=koTNXd-uvKVgEV0FekD9p32uYxVQkcqeho4_7cpyt5Q,914
50
+ layrz_sdk/entities/report.py,sha256=if3W6lMRCj6Coh0C0jFtrQHrq0aY9Wv7hVNz5AqIWIg,9607
51
+ layrz_sdk/entities/report_col.py,sha256=pEA8XBTAmzOUgbZaAc-dDuEyzGZcqCGoZHCEa2bti9E,1729
52
+ layrz_sdk/entities/report_configuration.py,sha256=uBD9Hv8u15P9N_3Xe9NGO_wTs5J9ej-vxtQrZJ0nNjs,367
53
+ layrz_sdk/entities/report_data_type.py,sha256=lcruMigtk20Tc2SLU2yta0D__b-kiY5tkGK48NAAhfE,408
54
+ layrz_sdk/entities/report_format.py,sha256=8bgiwd6dos7dxLasLy_FZkuirn9nZSFv2_qZAX_rT5Y,371
55
+ layrz_sdk/entities/report_header.py,sha256=nW3kcEE8WXMtTsrIVTHnqVg4-xX0rQ4xH2ylUQOfivI,772
56
+ layrz_sdk/entities/report_page.py,sha256=7IDsXBq5qdAAHTuSO95yg3kHtkIF6YFFJ6CzXTj6BW4,662
57
+ layrz_sdk/entities/report_row.py,sha256=sDhRNza-tZpT_DMkgDTCab6ujmnSu_Un7jFrqsZrESM,427
58
+ layrz_sdk/entities/request_type.py,sha256=vSEuKT70RDjYhWY1EKGmwFHgEyGQdQj7YjgmR7KyR7I,381
59
+ layrz_sdk/entities/sensor.py,sha256=I3GH7SiX_DDSHibPg4jwocYSTJYGP_9UjgQfn8D79bQ,880
60
+ layrz_sdk/entities/sensor_mask.py,sha256=xZqsLjjQPvfO1igy9jkwSAQfbc0jZdLqWhlSKWAMZvs,626
61
+ layrz_sdk/entities/sound_effect.py,sha256=5VPXKsxIpg_FCMPvikk6Pq7g6r4LAZekq-W0R86BgBs,1044
62
+ layrz_sdk/entities/static_position.py,sha256=B40ghu8y2l1JSoa8LUAfjt_SwLCB-NXEjmRi0jDatTU,495
63
+ layrz_sdk/entities/text_alignment.py,sha256=IdSEcvDYpD9lHVwyHMd6cXzOBjbgR__pfNYOdiPfyyE,386
64
+ layrz_sdk/entities/timezone.py,sha256=_Uky46st0kJ3NavVl6vXyV-npp-zf5y17V8fi_ikFXQ,500
65
+ layrz_sdk/entities/trigger.py,sha256=8tBfbuINLQldXxQhvb_lbVznt5M-GGHLiG3nHsahX_s,7172
66
+ layrz_sdk/entities/trigger_kind.py,sha256=HuINA2yt1TTpw6K-5Y49koVo4j00df8zz0lpE71kjk8,1684
67
+ layrz_sdk/entities/user.py,sha256=CgDgxLfZBB2XLv9bwqXvq_1xmM83xFxy00RLtarA_-0,373
68
+ layrz_sdk/entities/waypoint.py,sha256=9RPDhxpqNlAfLQ-1c7tKp6tkeRQqtTv5jBQgI48W8SA,2381
69
+ layrz_sdk/entities/weekday.py,sha256=qE7MiLrvmqTSRPPHMY_MJ-BYYsx0sfrejAad0QFy14c,412
70
+ layrz_sdk/entities/broadcast/__init__.py,sha256=vXw01LIoVQhGgfLLhhT289Qc0mWhF0_fmF_JuKeCEs4,416
71
+ layrz_sdk/entities/broadcast/payload.py,sha256=l6cVJtfNtWQWeXLzQTe5BU6sfbMV-ADf1hxyfkdAcU0,2637
72
+ layrz_sdk/entities/broadcast/request.py,sha256=MQb9kyDSAMXtp4_sPOamBsYyCVZ02wj8NXmi8IEmM68,260
73
+ layrz_sdk/entities/broadcast/response.py,sha256=hK3D05pecln9wbkdGr892Kzmd7bMzjsaayPxzJPVHsw,263
74
+ layrz_sdk/entities/broadcast/result.py,sha256=AeKaOiiR2ht3UE_nUbVFqB9FbtO_f5vPs2r2cfNwug4,2474
75
+ layrz_sdk/entities/broadcast/service.py,sha256=VB_pI9OvuKYBuyI53FECuEP7xNQIfJA6PsqHLHvoktM,522
76
+ layrz_sdk/entities/broadcast/status.py,sha256=eZMEIL_PmyJ5DFrHOhnvjBXA_LJZtXWUQbZDLamEcao,511
77
+ layrz_sdk/entities/charts/axis_config.py,sha256=ic2Yu2b8grXxi2CpetwZnorH2pQPs4YjNcWcrChshug,865
78
+ layrz_sdk/entities/charts/bar_chart.py,sha256=Rt5glMMznlXMDoHTzKsfBRxsscjWQVODtBN-aHa3jGU,5192
79
+ layrz_sdk/entities/charts/chart_alignment.py,sha256=NemdGai33s7mOUe35ye41bo_VvzOnaIz82TloI1BqB0,379
80
+ layrz_sdk/entities/charts/chart_color.py,sha256=RORxt0L31IrNUneshvtUmn8oQ_XsBRWgiDKbagUJw5M,793
81
+ layrz_sdk/entities/charts/chart_configuration.py,sha256=EnyQHOulIXLH4TqBXVY7tD_YaH0AbPmp4yhNbKAO0Zc,249
82
+ layrz_sdk/entities/charts/chart_data_serie.py,sha256=etWCp8zLHWh9KyfO3M2uSfP7SsdyXVJSwh13hFtSZ7I,1175
83
+ layrz_sdk/entities/charts/chart_data_serie_type.py,sha256=aCUo248y5NFvHX0MsnXE7ooT63fmtCQ8aBXjrJnfr4w,410
84
+ layrz_sdk/entities/charts/chart_data_type.py,sha256=esl_4GDrlUBcWhwl9ruqNkuJW_3__eU2lIHk9ZGuPkU,387
85
+ layrz_sdk/entities/charts/chart_render_technology.py,sha256=0p-a5EOm_WZEeRbF4z2ngjt5rOjdYydeQJ4iU6BAR0o,549
86
+ layrz_sdk/entities/charts/column_chart.py,sha256=RLrKCr0D7ISKQJNuUcnMbv1NXUxkFKCfmej-EuB9VEk,6204
87
+ layrz_sdk/entities/charts/html_chart.py,sha256=CtK9sQq2etcNqur_jjHNmwDOH3vDGg96mq_w1FBXYIY,987
88
+ layrz_sdk/entities/charts/line_chart.py,sha256=QkV3iBd_uUb8alQoRfVhbZKrBuZP3FcVfrS1pfkgV8g,7407
89
+ layrz_sdk/entities/charts/map_center_type.py,sha256=oBojrWuYSdSJFq0AFQOX9y0Je8wqeCcSr5Jvxrv69sc,340
90
+ layrz_sdk/entities/charts/map_chart.py,sha256=W3T0e07gTy5NUXiLOpVi9c_UYWmt3EYZn7-UUYkhnXI,3032
91
+ layrz_sdk/entities/charts/map_point.py,sha256=lBPabfQM2CzDDlsBkKS0SxO9kTUumlmRoBJhRx6G08A,937
92
+ layrz_sdk/entities/charts/number_chart.py,sha256=q_zqGUYga7qquzbwzRg05Qt8AJI7nssfjiwyr0RG6H8,1400
93
+ layrz_sdk/entities/charts/pie_chart.py,sha256=nAiQb4ZbMPiyg1wyYEBE7GYggyuqgtKIVmZTq1ZQuEY,3546
94
+ layrz_sdk/entities/charts/radar_chart.py,sha256=N_r2yzM_Lg_fqYC8FRGgruqTv36kYjEntLGqBfJN0oY,2559
95
+ layrz_sdk/entities/charts/radial_bar_chart.py,sha256=9NXWH52zwajbEh7oUYFKNuTt0ivbPhSnZ1NL8I_vNxQ,3526
96
+ layrz_sdk/entities/charts/scatter_chart.py,sha256=2vS9SS3VGkYeuq4Y0m13QlmMlvmuhuI6kQcEwoKZr4k,5742
97
+ layrz_sdk/entities/charts/scatter_serie.py,sha256=juztEf-cc1omWH9pObX-yTWDjthIeBTDgYZjOTsPnDY,866
98
+ layrz_sdk/entities/charts/scatter_serie_item.py,sha256=7t3CHDheJSvNoqOJ7ikf_FruaaGcSM-YdXIqJap_TOM,364
99
+ layrz_sdk/entities/charts/table_chart.py,sha256=u4bYk1n9RgXIAlPnueKG0rxM0YtEJbxCyrqSprXYu-w,1534
100
+ layrz_sdk/entities/charts/table_header.py,sha256=ibT8dRGEIEUBMJbc7XMYjMss3mVwcdoft1VcXFpHcO4,351
101
+ layrz_sdk/entities/charts/table_row.py,sha256=_deKF1TGRbQOYSFpGRg5h-spgxawCzx-FXOiuTVIiuU,312
102
+ layrz_sdk/entities/charts/timeline_chart.py,sha256=pRGwn5Vk3aodVaArm4u71u2TSWuWRPe3I70IfLs5iL8,2261
103
+ layrz_sdk/entities/charts/timeline_serie.py,sha256=8ORIM6BfCGhUU4-Em9YDeEILSbQ99HuFf4gCe2SoQEY,453
104
+ layrz_sdk/entities/charts/timeline_serie_item.py,sha256=t_vxEesgpEzGhU7GguCvrR49WHyDIIsDBW3JbXhumSM,525
105
+ layrz_sdk/entities/modbus/__init__.py,sha256=tb37MWV2FyvPOU01adaekA-r59bsBU4chC6n1aUNmF0,281
106
+ layrz_sdk/entities/modbus/config.py,sha256=nGN-Nde1pesVmwBv9n1W3ZGT2LeVlKGEjHY9qgn06tw,597
107
+ layrz_sdk/entities/modbus/parameter.py,sha256=jUInvvmjvJ1EjKKTJ6IC_P3QqfQNoXx2RR35S1Z-c2k,3523
108
+ layrz_sdk/entities/modbus/schema.py,sha256=gyL0VyGSXTZWzsamjLUGoW5cqhn7MfXisCbH_FlFnu8,222
109
+ layrz_sdk/entities/modbus/status.py,sha256=VnsWAR7C2dz7Y6_dPCnvS3CBaMaP7odZSu6db2KaTlE,611
110
+ layrz_sdk/entities/modbus/wait.py,sha256=2apORFkB2BPxSohjlTBmaiwMMyrkejvVDBwcHo5x9P0,4314
111
+ layrz_sdk/entities/telemetry/__init__.py,sha256=hfyekj-4_iB-aEbw43DXtSuMLBtMR1uoL8vvkRa_nJg,149
112
+ layrz_sdk/entities/telemetry/assetmessage.py,sha256=KE9K2SLpF1Wtv1l0jEpVGi2YlXFCysUimay6_ZeI6hU,5102
113
+ layrz_sdk/entities/telemetry/devicemessage.py,sha256=YqDiYIBLtn9D6MJ0C0LqU2XkBv6GZg6DKHRBYGkV6og,3419
114
+ layrz_sdk/helpers/__init__.py,sha256=5iW3z2m3jrYhvTfxX-p-QTkR9X9oTKfEsbtVOg9jFFY,115
115
+ layrz_sdk/helpers/color.py,sha256=oDB14_PRemopVIcvXqcsyI-OZK06MVV6lDFRIl8HZdw,1129
116
+ layrz_sdk/lcl/__init__.py,sha256=U967AWANkL3u_YVxMNAYlh8jkZ6hqHfStacz7yz6sOA,89
117
+ layrz_sdk/lcl/core.py,sha256=yMCsnrfDMHtIr8RHS9SDtLfwPhQYdoNj1AIl6fRQk9c,25140
118
+ layrz_sdk-4.1.0.dist-info/licenses/LICENSE,sha256=d5ZrU--lIPER7QByXDKcrtOTOMk1JvN_9FdYDuoWi7Y,1057
119
+ layrz_sdk-4.1.0.dist-info/METADATA,sha256=BEzPUgsSBnZx2RttuM8wV7myfqe24PZky-bv4n21rqg,2044
120
+ layrz_sdk-4.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
121
+ layrz_sdk-4.1.0.dist-info/top_level.txt,sha256=yUTMMzfdZ0HDWQH5TaSlFM4xtwmP1fSGxmlL1dmu4l4,10
122
+ layrz_sdk-4.1.0.dist-info/RECORD,,