layrz-sdk 4.0.8__tar.gz → 4.0.10__tar.gz

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 (132) hide show
  1. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/CHANGELOG.md +11 -0
  2. {layrz_sdk-4.0.8/layrz_sdk.egg-info → layrz_sdk-4.0.10}/PKG-INFO +6 -5
  3. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/ats_possible_exit.py +0 -1
  4. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/message.py +22 -8
  5. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/operation.py +11 -0
  6. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/operation_payload.py +11 -0
  7. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/position.py +6 -6
  8. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/report.py +40 -30
  9. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/report_col.py +1 -0
  10. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/telemetry/assetmessage.py +1 -1
  11. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/lcl/core.py +137 -117
  12. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10/layrz_sdk.egg-info}/PKG-INFO +6 -5
  13. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk.egg-info/requires.txt +3 -4
  14. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/manual_deploy.py +0 -2
  15. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/pyproject.toml +7 -5
  16. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/uv.lock +18 -6
  17. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/.github/workflows/checks.yml +0 -0
  18. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/.github/workflows/deploy.yml +0 -0
  19. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/.gitignore +0 -0
  20. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/.vscode/extensions.json +0 -0
  21. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/CODE_OF_CONDUCT.md +0 -0
  22. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/CONTRIBUTING.md +0 -0
  23. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/LICENSE +0 -0
  24. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/README.md +0 -0
  25. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/__init__.py +0 -0
  26. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/constants.py +0 -0
  27. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/__init__.py +0 -0
  28. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/action.py +0 -0
  29. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/action_geofence_ownership.py +0 -0
  30. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/action_kind.py +0 -0
  31. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/action_subkind.py +0 -0
  32. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/asset.py +0 -0
  33. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/asset_constants.py +0 -0
  34. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/asset_contact.py +0 -0
  35. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/asset_operation_mode.py +0 -0
  36. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/ats_entry.py +0 -0
  37. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/ats_exit_history.py +0 -0
  38. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/ats_possible_entry.py +0 -0
  39. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/ats_reception.py +0 -0
  40. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/broadcast/__init__.py +0 -0
  41. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/broadcast/payload.py +0 -0
  42. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/broadcast/request.py +0 -0
  43. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/broadcast/response.py +0 -0
  44. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/broadcast/result.py +0 -0
  45. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/broadcast/service.py +0 -0
  46. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/broadcast/status.py +0 -0
  47. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/case.py +0 -0
  48. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/case_ignored_status.py +0 -0
  49. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/case_status.py +0 -0
  50. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/charts/axis_config.py +0 -0
  51. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/charts/bar_chart.py +0 -0
  52. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/charts/chart_alignment.py +0 -0
  53. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/charts/chart_color.py +0 -0
  54. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/charts/chart_configuration.py +0 -0
  55. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/charts/chart_data_serie.py +0 -0
  56. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/charts/chart_data_serie_type.py +0 -0
  57. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/charts/chart_data_type.py +0 -0
  58. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/charts/chart_render_technology.py +0 -0
  59. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/charts/column_chart.py +0 -0
  60. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/charts/html_chart.py +0 -0
  61. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/charts/line_chart.py +0 -0
  62. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/charts/map_center_type.py +0 -0
  63. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/charts/map_chart.py +0 -0
  64. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/charts/map_point.py +0 -0
  65. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/charts/number_chart.py +0 -0
  66. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/charts/pie_chart.py +0 -0
  67. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/charts/radar_chart.py +0 -0
  68. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/charts/radial_bar_chart.py +0 -0
  69. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/charts/scatter_chart.py +0 -0
  70. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/charts/scatter_serie.py +0 -0
  71. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/charts/scatter_serie_item.py +0 -0
  72. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/charts/table_chart.py +0 -0
  73. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/charts/table_header.py +0 -0
  74. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/charts/table_row.py +0 -0
  75. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/charts/timeline_chart.py +0 -0
  76. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/charts/timeline_serie.py +0 -0
  77. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/charts/timeline_serie_item.py +0 -0
  78. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/checkpoint.py +0 -0
  79. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/command_series_ticket.py +0 -0
  80. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/comment.py +0 -0
  81. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/custom_field.py +0 -0
  82. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/custom_report_page.py +0 -0
  83. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/destination_phone.py +0 -0
  84. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/device.py +0 -0
  85. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/event.py +0 -0
  86. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/exchange_service.py +0 -0
  87. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/function.py +0 -0
  88. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/geofence.py +0 -0
  89. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/geofence_category.py +0 -0
  90. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/last_message.py +0 -0
  91. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/modbus/__init__.py +0 -0
  92. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/modbus/config.py +0 -0
  93. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/modbus/parameter.py +0 -0
  94. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/modbus/schema.py +0 -0
  95. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/modbus/status.py +0 -0
  96. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/modbus/wait.py +0 -0
  97. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/notification_type.py +0 -0
  98. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/operation_case_payload.py +0 -0
  99. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/operation_type.py +0 -0
  100. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/outbound_service.py +0 -0
  101. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/platform.py +0 -0
  102. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/presence_type.py +0 -0
  103. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/preset.py +0 -0
  104. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/report_configuration.py +0 -0
  105. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/report_data_type.py +0 -0
  106. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/report_format.py +0 -0
  107. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/report_header.py +0 -0
  108. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/report_page.py +0 -0
  109. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/report_row.py +0 -0
  110. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/request_type.py +0 -0
  111. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/sensor.py +0 -0
  112. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/sound_effect.py +0 -0
  113. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/static_position.py +0 -0
  114. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/telemetry/__init__.py +0 -0
  115. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/telemetry/devicemessage.py +0 -0
  116. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/text_alignment.py +0 -0
  117. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/timezone.py +0 -0
  118. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/trigger.py +0 -0
  119. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/trigger_kind.py +0 -0
  120. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/user.py +0 -0
  121. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/waypoint.py +0 -0
  122. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/entities/weekday.py +0 -0
  123. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/helpers/__init__.py +0 -0
  124. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/helpers/color.py +0 -0
  125. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/lcl/__init__.py +0 -0
  126. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk/py.typed +0 -0
  127. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk.egg-info/SOURCES.txt +0 -0
  128. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk.egg-info/dependency_links.txt +0 -0
  129. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/layrz_sdk.egg-info/top_level.txt +0 -0
  130. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/setup.cfg +0 -0
  131. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/tests/__init__.py +0 -0
  132. {layrz_sdk-4.0.8 → layrz_sdk-4.0.10}/tests/test_lcl.py +0 -0
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.0.10
4
+
5
+ - Added support for lock cells in `ReportCol` entity and their export to Microsoft Excel.
6
+ - Added support for `list[Geofence]` on `Message` entity for presence in geofences.
7
+
8
+ ## 4.0.9
9
+
10
+ - Added validation for `destination_phones` field in `Operation` entity to ensure it is a list of `DestinationPhone` objects.
11
+ - Updated `OperationPayload` entity to use `DestinationPhone` instead of a list of strings for `destinations`.
12
+
13
+
3
14
  ## 4.0.8
4
15
 
5
16
  - Allowed `int | str | None` for `account_id` in `Operation` and `OperationPayload` entities.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: layrz-sdk
3
- Version: 4.0.8
3
+ Version: 4.0.10
4
4
  Summary: Layrz SDK for Python
5
5
  Author-email: "Golden M, Inc." <software@goldenm.com>
6
6
  Maintainer-email: Kenny Mochizuki <kenny@goldenm.com>, Luis Reyes <lreyes@goldenm.com>, Kasen Li <kli@goldenm.com>, Miguel Zauzich <miguel@goldenm.com>, Angel Prieto <aprieto@goldenm.com>
@@ -12,17 +12,18 @@ Classifier: Programming Language :: Python :: 3
12
12
  Classifier: Programming Language :: Python :: 3.13
13
13
  Classifier: Programming Language :: Python :: 3.14
14
14
  Classifier: Operating System :: OS Independent
15
+ Classifier: Development Status :: 5 - Production/Stable
16
+ Classifier: Intended Audience :: Developers
15
17
  Requires-Python: >=3.13
16
18
  Description-Content-Type: text/markdown
17
19
  License-File: LICENSE
18
- Requires-Dist: requests
19
- Requires-Dist: xlsxwriter
20
- Requires-Dist: tzdata
20
+ Requires-Dist: xlsxwriter<4.0.0,>=3.2.5
21
21
  Requires-Dist: pydantic>=2.10.6
22
- Requires-Dist: typing-extensions>=4.10.0
23
22
  Requires-Dist: geopy>=2.4.1
24
23
  Requires-Dist: shapely>=2.1.1
25
24
  Requires-Dist: strenum>=0.4.15
25
+ Requires-Dist: requests>=2.32.4
26
+ Requires-Dist: tzdata>=2025.2
26
27
  Dynamic: license-file
27
28
 
28
29
  # Layrz SDK
@@ -19,7 +19,6 @@ class AtsPossibleExit(BaseModel):
19
19
  identifier: int | None = Field(
20
20
  default=None,
21
21
  description='Nullable positive big integer identifier for the exit',
22
- ge=0,
23
22
  )
24
23
 
25
24
  # Volume / gauge snapshots
@@ -1,15 +1,13 @@
1
1
  """Message entity"""
2
2
 
3
3
  from datetime import datetime
4
- from typing import Any, TypeAlias
4
+ from typing import Any
5
5
 
6
- from pydantic import BaseModel, Field
6
+ from pydantic import BaseModel, Field, field_validator
7
7
 
8
8
  from layrz_sdk.constants import UTC
9
-
10
- from .position import Position
11
-
12
- PayloadType: TypeAlias = dict[str, Any]
9
+ from layrz_sdk.entities.geofence import Geofence
10
+ from layrz_sdk.entities.position import Position
13
11
 
14
12
 
15
13
  class Message(BaseModel):
@@ -27,11 +25,11 @@ class Message(BaseModel):
27
25
  default_factory=lambda: Position(),
28
26
  description='Current position of the device',
29
27
  )
30
- payload: PayloadType = Field(
28
+ payload: dict[str, Any] = Field(
31
29
  default_factory=dict,
32
30
  description='Payload data of the device message',
33
31
  )
34
- sensors: PayloadType = Field(
32
+ sensors: dict[str, Any] = Field(
35
33
  default_factory=dict,
36
34
  description='Sensor data of the device message',
37
35
  )
@@ -39,3 +37,19 @@ class Message(BaseModel):
39
37
  default_factory=lambda: datetime.now(UTC),
40
38
  description='Timestamp when the message was received',
41
39
  )
40
+
41
+ geofences: list[Geofence] = Field(
42
+ default_factory=list,
43
+ description='List of geofences associated with the message',
44
+ )
45
+
46
+ @field_validator('geofences', mode='before')
47
+ def _validate_geofences(cls, value: Any) -> list[Geofence]:
48
+ """Validate geofences"""
49
+ if value is None:
50
+ return []
51
+
52
+ if not isinstance(value, list):
53
+ return []
54
+
55
+ return value
@@ -150,6 +150,17 @@ class Operation(BaseModel):
150
150
  description='Defines the destination phone numbers for Twilio notifications',
151
151
  )
152
152
 
153
+ @field_validator('destination_phones', mode='before')
154
+ def serialize_destination_phones(cls, value: Any) -> list[DestinationPhone]:
155
+ """Serialize destination phones to a list of DestinationPhone"""
156
+ if isinstance(value, list):
157
+ return value
158
+
159
+ if isinstance(value, DestinationPhone):
160
+ return [value]
161
+
162
+ return []
163
+
153
164
  attach_image: bool = Field(
154
165
  default=False,
155
166
  description='Defines if the operation should attach an image',
@@ -204,6 +204,17 @@ class OperationPayload(BaseModel):
204
204
  description='Defines the destination phone numbers for Twilio notifications',
205
205
  )
206
206
 
207
+ @field_validator('destinations', mode='before')
208
+ def serialize_destinations(cls, value: Any) -> list[DestinationPhone]:
209
+ """Serialize destinations to a list of DestinationPhone"""
210
+ if isinstance(value, list):
211
+ return value
212
+
213
+ if isinstance(value, DestinationPhone):
214
+ return [value]
215
+
216
+ return []
217
+
207
218
  twilio_host_phone: DestinationPhone | None = Field(
208
219
  default=None,
209
220
  description='Defines the host phone number for Twilio notifications',
@@ -1,6 +1,6 @@
1
1
  """Position entity"""
2
2
 
3
- from typing import Any, Self
3
+ from typing import Any, Self, cast
4
4
 
5
5
  from pydantic import BaseModel, Field, field_validator
6
6
 
@@ -32,7 +32,7 @@ class Position(BaseModel):
32
32
  value = float(value)
33
33
 
34
34
  if -90 <= value <= 90:
35
- return value
35
+ return cast(float, value)
36
36
 
37
37
  return None
38
38
 
@@ -49,7 +49,7 @@ class Position(BaseModel):
49
49
  value = float(value)
50
50
 
51
51
  if -180 <= value <= 180:
52
- return value
52
+ return cast(float, value)
53
53
 
54
54
  return None
55
55
 
@@ -76,7 +76,7 @@ class Position(BaseModel):
76
76
  if isinstance(value, int):
77
77
  value = float(value)
78
78
 
79
- return value
79
+ return cast(float, value)
80
80
 
81
81
  @field_validator('speed', mode='before')
82
82
  def _validate_speed(cls: Self, value: Any) -> None | float:
@@ -90,7 +90,7 @@ class Position(BaseModel):
90
90
  if isinstance(value, int):
91
91
  value = float(value)
92
92
 
93
- return abs(value)
93
+ return cast(float, abs(value))
94
94
 
95
95
  @field_validator('direction', mode='before')
96
96
  def _validate_direction(cls: Self, value: Any) -> None | float:
@@ -105,6 +105,6 @@ class Position(BaseModel):
105
105
  value = float(value)
106
106
 
107
107
  if 0 <= value <= 360:
108
- return value
108
+ return cast(float, value)
109
109
 
110
110
  return None
@@ -10,13 +10,12 @@ from typing import Any, Optional, Self
10
10
  import xlsxwriter
11
11
  from pydantic import BaseModel, Field, field_validator
12
12
 
13
+ from layrz_sdk.entities.custom_report_page import CustomReportPage
14
+ from layrz_sdk.entities.report_data_type import ReportDataType
15
+ from layrz_sdk.entities.report_format import ReportFormat
16
+ from layrz_sdk.entities.report_page import ReportPage
13
17
  from layrz_sdk.helpers.color import use_black
14
18
 
15
- from .custom_report_page import CustomReportPage
16
- from .report_data_type import ReportDataType
17
- from .report_format import ReportFormat
18
- from .report_page import ReportPage
19
-
20
19
  log = logging.getLogger(__name__)
21
20
 
22
21
 
@@ -87,6 +86,7 @@ class Report(BaseModel):
87
86
  else:
88
87
  raise AttributeError(f'Unsupported export format: {self.export_format}')
89
88
 
89
+ @warnings.deprecated('export_as_json is deprecated, use export with export_format=ReportFormat.JSON instead')
90
90
  def export_as_json(self: Self) -> dict[str, Any]:
91
91
  """Returns the report as a JSON dict"""
92
92
  return self._export_json()
@@ -98,7 +98,7 @@ class Report(BaseModel):
98
98
  if isinstance(page, CustomReportPage):
99
99
  continue
100
100
 
101
- headers = []
101
+ headers: list[dict[str, Any]] = []
102
102
  for header in page.headers:
103
103
  headers.append(
104
104
  {
@@ -231,34 +231,44 @@ class Report(BaseModel):
231
231
  'font_name': 'Aptos Narrow',
232
232
  }
233
233
 
234
+ format_ = book.add_format(style)
235
+
236
+ if cell.lock:
237
+ format_.set_locked(True)
238
+
234
239
  value: Any = None
235
240
 
236
- if cell.data_type == ReportDataType.BOOL:
237
- value = 'Yes' if cell.content else 'No'
238
- elif cell.data_type == ReportDataType.DATETIME:
239
- value = cell.content.strftime(cell.datetime_format)
240
- elif cell.data_type == ReportDataType.INT:
241
- try:
242
- value = int(cell.content)
243
- except ValueError:
244
- value = cell.content
245
- log.warning(f'Invalid int value: {cell.content} in cell {i + 1}, {j}')
246
- elif cell.data_type == ReportDataType.FLOAT:
247
- try:
241
+ match cell.data_type:
242
+ case ReportDataType.BOOL:
243
+ value = 'Yes' if cell.content else 'No'
244
+
245
+ case ReportDataType.DATETIME:
246
+ value = cell.content.strftime(cell.datetime_format)
247
+
248
+ case ReportDataType.INT:
249
+ try:
250
+ value = int(cell.content)
251
+ except ValueError:
252
+ value = cell.content
253
+ log.warning(f'Invalid int value: {cell.content} in cell {i + 1}, {j}')
254
+
255
+ case ReportDataType.FLOAT:
256
+ try:
257
+ value = float(cell.content)
258
+ format_.set_num_format('0.00')
259
+
260
+ except ValueError:
261
+ value = cell.content
262
+ log.warning(f'Invalid float value: {cell.content} in cell {i + 1}, {j}')
263
+
264
+ case ReportDataType.CURRENCY:
248
265
  value = float(cell.content)
249
- style.update({'num_format': '0.00'})
250
- except ValueError:
251
- value = cell.content
252
- log.warning(f'Invalid float value: {cell.content} in cell {i + 1}, {j}')
253
- elif cell.data_type == ReportDataType.CURRENCY:
254
- value = float(cell.content)
255
- style.update(
256
- {'num_format': f'"{cell.currency_symbol}" * #,##0.00;[Red]"{cell.currency_symbol}" * #,##0.00'}
257
- )
258
- else:
259
- value = cell.content
266
+ format_.set_num_format(f'"{cell.currency_symbol}" * #,##0.00;[Red]"{cell.currency_symbol}" * #,##0.00')
267
+
268
+ case _:
269
+ value = str(cell.content)
260
270
 
261
- sheet.write(i + 1, j, value, book.add_format(style))
271
+ sheet.write(i + 1, j, value, format_)
262
272
 
263
273
  if row.compact:
264
274
  sheet.set_row(i + 1, None, None, {'level': 1, 'hidden': True})
@@ -20,6 +20,7 @@ class ReportCol(BaseModel):
20
20
  datetime_format: str = Field(description='Datetime format', default='%Y-%m-%d %H:%M:%S')
21
21
  currency_symbol: str = Field(description='Currency symbol', default='')
22
22
  bold: bool = Field(description='Bold text', default=False)
23
+ lock: bool = Field(description='Lock column', default=False)
23
24
 
24
25
  @field_validator('text_color', mode='before')
25
26
  def _validate_text_color(cls: Self, value: Any) -> Any:
@@ -117,7 +117,7 @@ class AssetMessage(BaseModel):
117
117
  case AssetOperationMode.STATIC:
118
118
  obj.position = asset.static_position.model_dump(exclude_none=True) if asset.static_position else {}
119
119
  case AssetOperationMode.ZONE:
120
- points = MultiPoint([(p.longitude, p.latitude) for p in asset.points])
120
+ points: MultiPoint = MultiPoint([(p.longitude, p.latitude) for p in asset.points])
121
121
  obj.position = {'latitude': points.centroid.y, 'longitude': points.centroid.x}
122
122
  case _:
123
123
  obj.position = device_message.position