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.
Files changed (104) hide show
  1. layrz_sdk/decorators/__init__.py +5 -0
  2. layrz_sdk/decorators/func_timing.py +103 -0
  3. layrz_sdk/entities/__init__.py +19 -0
  4. layrz_sdk/entities/action.py +28 -16
  5. layrz_sdk/entities/action_geofence_ownership.py +0 -2
  6. layrz_sdk/entities/action_kind.py +0 -2
  7. layrz_sdk/entities/action_subkind.py +0 -2
  8. layrz_sdk/entities/asset.py +20 -9
  9. layrz_sdk/entities/asset_constants.py +10 -9
  10. layrz_sdk/entities/asset_contact.py +7 -3
  11. layrz_sdk/entities/asset_operation_mode.py +0 -2
  12. layrz_sdk/entities/ats_entry.py +11 -4
  13. layrz_sdk/entities/ats_exit_history.py +21 -19
  14. layrz_sdk/entities/ats_operation.py +87 -0
  15. layrz_sdk/entities/ats_possible_entry.py +10 -7
  16. layrz_sdk/entities/ats_possible_exit.py +19 -9
  17. layrz_sdk/entities/ats_purchaseorder.py +106 -0
  18. layrz_sdk/entities/ats_reception.py +16 -4
  19. layrz_sdk/entities/broadcast/__init__.py +2 -1
  20. layrz_sdk/entities/broadcast/payload.py +40 -8
  21. layrz_sdk/entities/broadcast/result.py +72 -1
  22. layrz_sdk/entities/broadcast/service.py +12 -2
  23. layrz_sdk/entities/broadcast/status.py +2 -2
  24. layrz_sdk/entities/case.py +51 -8
  25. layrz_sdk/entities/case_ignored_status.py +1 -0
  26. layrz_sdk/entities/charts/axis_config.py +13 -5
  27. layrz_sdk/entities/charts/bar_chart.py +12 -1
  28. layrz_sdk/entities/charts/chart_data_serie.py +17 -1
  29. layrz_sdk/entities/charts/column_chart.py +12 -1
  30. layrz_sdk/entities/charts/html_chart.py +8 -4
  31. layrz_sdk/entities/charts/line_chart.py +12 -3
  32. layrz_sdk/entities/charts/map_chart.py +14 -5
  33. layrz_sdk/entities/charts/map_point.py +7 -1
  34. layrz_sdk/entities/charts/number_chart.py +8 -4
  35. layrz_sdk/entities/charts/pie_chart.py +11 -3
  36. layrz_sdk/entities/charts/radar_chart.py +11 -3
  37. layrz_sdk/entities/charts/radial_bar_chart.py +11 -3
  38. layrz_sdk/entities/charts/scatter_chart.py +12 -3
  39. layrz_sdk/entities/charts/scatter_serie.py +11 -1
  40. layrz_sdk/entities/charts/scatter_serie_item.py +7 -1
  41. layrz_sdk/entities/charts/table_chart.py +7 -3
  42. layrz_sdk/entities/charts/table_header.py +7 -1
  43. layrz_sdk/entities/charts/table_row.py +7 -1
  44. layrz_sdk/entities/charts/timeline_chart.py +11 -3
  45. layrz_sdk/entities/charts/timeline_serie.py +7 -1
  46. layrz_sdk/entities/charts/timeline_serie_item.py +7 -1
  47. layrz_sdk/entities/checkpoint.py +20 -13
  48. layrz_sdk/entities/command_series_ticket.py +29 -4
  49. layrz_sdk/entities/comment.py +22 -5
  50. layrz_sdk/entities/custom_field.py +12 -4
  51. layrz_sdk/entities/custom_report_page.py +3 -0
  52. layrz_sdk/entities/destination_phone.py +7 -1
  53. layrz_sdk/entities/device.py +11 -4
  54. layrz_sdk/entities/event.py +20 -4
  55. layrz_sdk/entities/exchange_service.py +12 -4
  56. layrz_sdk/entities/function.py +11 -4
  57. layrz_sdk/entities/geofence.py +20 -5
  58. layrz_sdk/entities/geofence_category.py +0 -2
  59. layrz_sdk/entities/last_message.py +7 -3
  60. layrz_sdk/entities/locator.py +95 -0
  61. layrz_sdk/entities/message.py +16 -9
  62. layrz_sdk/entities/modbus/config.py +7 -1
  63. layrz_sdk/entities/modbus/parameter.py +7 -1
  64. layrz_sdk/entities/modbus/wait.py +11 -1
  65. layrz_sdk/entities/notification_type.py +0 -2
  66. layrz_sdk/entities/operation.py +37 -16
  67. layrz_sdk/entities/operation_case_payload.py +39 -13
  68. layrz_sdk/entities/operation_payload.py +63 -26
  69. layrz_sdk/entities/operation_type.py +0 -2
  70. layrz_sdk/entities/outbound_service.py +11 -4
  71. layrz_sdk/entities/parameter_update.py +25 -0
  72. layrz_sdk/entities/platform.py +0 -2
  73. layrz_sdk/entities/position.py +7 -3
  74. layrz_sdk/entities/preset.py +15 -9
  75. layrz_sdk/entities/report.py +9 -5
  76. layrz_sdk/entities/report_col.py +17 -3
  77. layrz_sdk/entities/report_configuration.py +7 -1
  78. layrz_sdk/entities/report_data_type.py +1 -3
  79. layrz_sdk/entities/report_format.py +1 -5
  80. layrz_sdk/entities/report_header.py +12 -29
  81. layrz_sdk/entities/report_page.py +7 -3
  82. layrz_sdk/entities/report_row.py +7 -19
  83. layrz_sdk/entities/request_type.py +0 -2
  84. layrz_sdk/entities/sensor.py +21 -3
  85. layrz_sdk/entities/sensor_mask.py +28 -0
  86. layrz_sdk/entities/sound_effect.py +0 -2
  87. layrz_sdk/entities/static_position.py +6 -1
  88. layrz_sdk/entities/telemetry/assetmessage.py +14 -15
  89. layrz_sdk/entities/telemetry/devicemessage.py +19 -9
  90. layrz_sdk/entities/text_alignment.py +0 -2
  91. layrz_sdk/entities/timezone.py +12 -4
  92. layrz_sdk/entities/trigger.py +102 -17
  93. layrz_sdk/entities/trigger_kind.py +2 -5
  94. layrz_sdk/entities/user.py +11 -4
  95. layrz_sdk/entities/waypoint.py +38 -16
  96. layrz_sdk/entities/weekday.py +1 -3
  97. layrz_sdk/helpers/color.py +1 -6
  98. layrz_sdk/lcl/core.py +0 -1
  99. {layrz_sdk-4.0.11.dist-info → layrz_sdk-4.1.8.dist-info}/METADATA +2 -2
  100. layrz_sdk-4.1.8.dist-info/RECORD +123 -0
  101. layrz_sdk-4.0.11.dist-info/RECORD +0 -116
  102. {layrz_sdk-4.0.11.dist-info → layrz_sdk-4.1.8.dist-info}/WHEEL +0 -0
  103. {layrz_sdk-4.0.11.dist-info → layrz_sdk-4.1.8.dist-info}/licenses/LICENSE +0 -0
  104. {layrz_sdk-4.0.11.dist-info → layrz_sdk-4.1.8.dist-info}/top_level.txt +0 -0
@@ -1,13 +1,12 @@
1
- """Operation Payload entity"""
2
-
3
1
  from datetime import datetime, timedelta
4
- from typing import Any, Self
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
- 'json_encoders': {
27
- timedelta: lambda v: v.total_seconds(),
28
- datetime: lambda v: v.timestamp(),
29
- Asset: lambda v: v.model_dump(by_alias=True, exclude_none=True),
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 serialize_asset(cls, value: Any) -> Asset:
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 serialize_trigger(cls, value: Any) -> Trigger:
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 serialize_operation(cls, value: Any) -> Operation:
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,5 +1,3 @@
1
- """Operation type"""
2
-
3
1
  from enum import StrEnum
4
2
  from typing import Self
5
3
 
@@ -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
- pk: int = Field(description='Service ID', 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='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()}
@@ -1,5 +1,3 @@
1
- """Platform"""
2
-
3
1
  from enum import StrEnum
4
2
  from typing import Self
5
3
 
@@ -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')
@@ -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
- 'json_encoders': {
13
- datetime: lambda v: v.timestamp(),
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(description='Defines the primary key of the preset', alias='id')
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',
@@ -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.value,
123
+ 'data_type': cell.data_type.name,
120
124
  }
121
125
  )
122
126
  rows.append(
@@ -1,9 +1,7 @@
1
- """Report col"""
2
-
3
1
  import warnings
4
2
  from typing import Any, Optional, 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 .report_data_type import ReportDataType
9
7
  from .text_alignment import TextAlignment
@@ -12,11 +10,27 @@ from .text_alignment import TextAlignment
12
10
  class ReportCol(BaseModel):
13
11
  """Report column entity"""
14
12
 
13
+ model_config = ConfigDict(
14
+ validate_by_name=False,
15
+ validate_by_alias=True,
16
+ serialize_by_alias=True,
17
+ )
18
+
15
19
  content: Any = Field(description='Column content')
16
20
  color: str = Field(description='Column color', default='#ffffff')
17
21
  text_color: Optional[str] = Field(description='Column text color', default=None)
18
22
  align: TextAlignment = Field(description='Column text alignment', default=TextAlignment.LEFT)
23
+
24
+ @field_serializer('align', when_used='always')
25
+ def serialize_align(self, align: TextAlignment) -> str:
26
+ return align.value
27
+
19
28
  data_type: ReportDataType = Field(description='Column data type', default=ReportDataType.STR)
29
+
30
+ @field_serializer('data_type', when_used='always')
31
+ def serialize_data_type(self, data_type: ReportDataType) -> str:
32
+ return data_type.value
33
+
20
34
  datetime_format: str = Field(description='Datetime format', default='%Y-%m-%d %H:%M:%S')
21
35
  currency_symbol: str = Field(description='Currency symbol', default='')
22
36
  bold: bool = Field(description='Bold text', default=False)
@@ -1,8 +1,14 @@
1
- from pydantic import BaseModel, Field
1
+ from pydantic import BaseModel, ConfigDict, Field
2
2
 
3
3
 
4
4
  class ReportConfiguration(BaseModel):
5
5
  """Report configuration entity"""
6
6
 
7
+ model_config = ConfigDict(
8
+ validate_by_name=False,
9
+ validate_by_alias=True,
10
+ serialize_by_alias=True,
11
+ )
12
+
7
13
  title: str = Field(description='Report title')
8
14
  pages_count: int = Field(description='Number of pages in the report')
@@ -3,9 +3,7 @@ from typing import Self
3
3
 
4
4
 
5
5
  class ReportDataType(StrEnum):
6
- """
7
- Report date type
8
- """
6
+ """Report date type"""
9
7
 
10
8
  STR = 'str'
11
9
  INT = 'int'
@@ -1,13 +1,9 @@
1
- """Report formats"""
2
-
3
1
  from enum import StrEnum
4
2
  from typing import Self
5
3
 
6
4
 
7
5
  class ReportFormat(StrEnum):
8
- """
9
- Report format definition.
10
- """
6
+ """Report format definition."""
11
7
 
12
8
  MICROSOFT_EXCEL = 'MICROSOFT_EXCEL'
13
9
  JSON = 'JSON'
@@ -1,9 +1,7 @@
1
- """Report header"""
2
-
3
1
  import warnings
4
2
  from typing import Any, Optional
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 .text_alignment import TextAlignment
9
7
 
@@ -11,33 +9,18 @@ from .text_alignment import TextAlignment
11
9
  class ReportHeader(BaseModel):
12
10
  """Report header entity"""
13
11
 
12
+ model_config = ConfigDict(
13
+ validate_by_name=False,
14
+ validate_by_alias=True,
15
+ serialize_by_alias=True,
16
+ )
17
+
14
18
  content: Any = Field(description='Header content')
15
19
  color: str = Field(description='Header color', default='#ffffff')
16
- text_color: Optional[str] = Field(description='Header text color', default=None)
17
20
  align: TextAlignment = Field(description='Header text alignment', default=TextAlignment.CENTER)
21
+
22
+ @field_serializer('align', when_used='always')
23
+ def serialize_align(self, align: TextAlignment) -> str:
24
+ return align.value
25
+
18
26
  bold: bool = Field(description='Bold text', default=False)
19
- width: Optional[float] = Field(description='Header width', default=None)
20
-
21
- @field_validator('text_color', mode='before')
22
- def _validate_text_color(cls, value: Any) -> Any:
23
- """Validate text color"""
24
- if value is not None:
25
- warnings.warn(
26
- 'text_color is deprecated, the algorithm will calculate the rigth text color instead',
27
- DeprecationWarning,
28
- stacklevel=2,
29
- )
30
-
31
- return value
32
-
33
- @field_validator('width', mode='before')
34
- def _validate_width(cls, value: Any) -> Any:
35
- """Validate width"""
36
- if value is not None:
37
- warnings.warn(
38
- 'width is deprecated, the algorithm will calculate the rigth width instead',
39
- DeprecationWarning,
40
- stacklevel=2,
41
- )
42
-
43
- return value
@@ -1,6 +1,4 @@
1
- """Report page"""
2
-
3
- from pydantic import BaseModel, Field
1
+ from pydantic import BaseModel, ConfigDict, Field
4
2
 
5
3
  from .report_header import ReportHeader
6
4
  from .report_row import ReportRow
@@ -9,6 +7,12 @@ from .report_row import ReportRow
9
7
  class ReportPage(BaseModel):
10
8
  """Report page definition"""
11
9
 
10
+ model_config = ConfigDict(
11
+ validate_by_name=False,
12
+ validate_by_alias=True,
13
+ serialize_by_alias=True,
14
+ )
15
+
12
16
  name: str = Field(description='Name of the page. Length should be less than 60 characters')
13
17
  headers: list[ReportHeader] = Field(description='List of report headers', default_factory=list)
14
18
  rows: list[ReportRow] = Field(description='List of report rows', default_factory=list)
@@ -1,9 +1,4 @@
1
- """Report row"""
2
-
3
- import warnings
4
- from typing import Any, Optional
5
-
6
- from pydantic import BaseModel, Field, field_validator
1
+ from pydantic import BaseModel, ConfigDict, Field
7
2
 
8
3
  from .report_col import ReportCol
9
4
 
@@ -11,18 +6,11 @@ from .report_col import ReportCol
11
6
  class ReportRow(BaseModel):
12
7
  """Report row definition"""
13
8
 
9
+ model_config = ConfigDict(
10
+ validate_by_name=False,
11
+ validate_by_alias=True,
12
+ serialize_by_alias=True,
13
+ )
14
+
14
15
  content: list[ReportCol] = Field(description='List of report columns', default_factory=list)
15
- height: Optional[float] = Field(description='Row height', default=None)
16
16
  compact: bool = Field(description='Compact mode', default=False)
17
-
18
- @field_validator('height', mode='before')
19
- def _validate_height(cls, value: Any) -> Any:
20
- """Validate height"""
21
- if value is not None:
22
- warnings.warn(
23
- 'height is deprecated, the algorithm will calculate the rigth text color instead',
24
- DeprecationWarning,
25
- stacklevel=2,
26
- )
27
-
28
- return value
@@ -1,5 +1,3 @@
1
- """Http Operation Type"""
2
-
3
1
  from enum import StrEnum
4
2
  from typing import Self
5
3
 
@@ -1,15 +1,33 @@
1
- """Sensor entity"""
1
+ from pydantic import BaseModel, ConfigDict, Field
2
2
 
3
- from pydantic import BaseModel, Field
3
+ from .sensor_mask import SensorMask
4
4
 
5
5
 
6
6
  class Sensor(BaseModel):
7
7
  """Sensor entity"""
8
8
 
9
- 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
+ )
10
19
  name: str = Field(description='Defines the name of the sensor')
11
20
  slug: str = Field(description='Defines the slug of the sensor')
12
21
  formula: str = Field(
13
22
  default='',
14
23
  description='Defines the formula of the sensor, used for calculations',
15
24
  )
25
+ mask: list[SensorMask] | None = Field(
26
+ default=None,
27
+ description='Defines the mask of the sensor, used for filtering data',
28
+ )
29
+
30
+ measuring_unit: str | None = Field(
31
+ default=None,
32
+ description='Defines the measuring unit of the sensor, e.g., km/h, °C',
33
+ )
@@ -0,0 +1,28 @@
1
+ from pydantic import BaseModel, ConfigDict, Field
2
+
3
+
4
+ class SensorMask(BaseModel):
5
+ """Sensor entity"""
6
+
7
+ model_config = ConfigDict(
8
+ validate_by_name=False,
9
+ validate_by_alias=True,
10
+ serialize_by_alias=True,
11
+ )
12
+
13
+ icon: str | None = Field(
14
+ default=None,
15
+ description='Defines the icon of the sensor',
16
+ )
17
+ text: str | None = Field(
18
+ default=None,
19
+ description='Defines the text of the sensor',
20
+ )
21
+ color: str | None = Field(
22
+ default=None,
23
+ description='Defines the color of the sensor, used for visual representation',
24
+ )
25
+ value: str | float | int | None = Field(
26
+ default=None,
27
+ description='Defines the value of the sensor, can be of various types',
28
+ )
@@ -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',