layrz-sdk 3.1.33__tar.gz → 3.1.35__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 (124) hide show
  1. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/CHANGELOG.md +8 -0
  2. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/PKG-INFO +1 -1
  3. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/__init__.py +19 -0
  4. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/action.py +2 -2
  5. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/asset.py +5 -0
  6. layrz_sdk-3.1.35/layrz_sdk/entities/notification_type.py +32 -0
  7. layrz_sdk-3.1.35/layrz_sdk/entities/operation.py +170 -0
  8. layrz_sdk-3.1.35/layrz_sdk/entities/operation_case_payload.py +83 -0
  9. layrz_sdk-3.1.35/layrz_sdk/entities/operation_payload.py +281 -0
  10. layrz_sdk-3.1.35/layrz_sdk/entities/operation_type.py +44 -0
  11. layrz_sdk-3.1.35/layrz_sdk/entities/platform.py +44 -0
  12. layrz_sdk-3.1.35/layrz_sdk/entities/request_type.py +28 -0
  13. layrz_sdk-3.1.35/layrz_sdk/entities/sound_effect.py +47 -0
  14. layrz_sdk-3.1.35/layrz_sdk/entities/timezone.py +11 -0
  15. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk.egg-info/PKG-INFO +1 -1
  16. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk.egg-info/SOURCES.txt +9 -0
  17. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/pyproject.toml +1 -1
  18. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/uv.lock +1 -1
  19. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/.github/workflows/checks.yml +0 -0
  20. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/.github/workflows/deploy.yml +0 -0
  21. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/.gitignore +0 -0
  22. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/.vscode/extensions.json +0 -0
  23. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/CODE_OF_CONDUCT.md +0 -0
  24. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/CONTRIBUTING.md +0 -0
  25. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/LICENSE +0 -0
  26. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/README.md +0 -0
  27. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/__init__.py +0 -0
  28. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/backwards.py +0 -0
  29. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/constants.py +0 -0
  30. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/action_geofence_ownership.py +0 -0
  31. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/action_kind.py +0 -0
  32. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/action_subkind.py +0 -0
  33. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/asset_constants.py +0 -0
  34. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/asset_operation_mode.py +0 -0
  35. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/ats_reception.py +0 -0
  36. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/broadcast/__init__.py +0 -0
  37. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/broadcast/payload.py +0 -0
  38. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/broadcast/request.py +0 -0
  39. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/broadcast/response.py +0 -0
  40. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/broadcast/result.py +0 -0
  41. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/broadcast/service.py +0 -0
  42. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/broadcast/status.py +0 -0
  43. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/case.py +0 -0
  44. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/case_ignored_status.py +0 -0
  45. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/case_status.py +0 -0
  46. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/charts/axis_config.py +0 -0
  47. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/charts/bar_chart.py +0 -0
  48. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/charts/chart_alignment.py +0 -0
  49. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/charts/chart_color.py +0 -0
  50. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/charts/chart_configuration.py +0 -0
  51. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/charts/chart_data_serie.py +0 -0
  52. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/charts/chart_data_serie_type.py +0 -0
  53. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/charts/chart_data_type.py +0 -0
  54. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/charts/chart_render_technology.py +0 -0
  55. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/charts/column_chart.py +0 -0
  56. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/charts/html_chart.py +0 -0
  57. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/charts/line_chart.py +0 -0
  58. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/charts/map_center_type.py +0 -0
  59. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/charts/map_chart.py +0 -0
  60. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/charts/map_point.py +0 -0
  61. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/charts/number_chart.py +0 -0
  62. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/charts/pie_chart.py +0 -0
  63. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/charts/radar_chart.py +0 -0
  64. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/charts/radial_bar_chart.py +0 -0
  65. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/charts/scatter_chart.py +0 -0
  66. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/charts/scatter_serie.py +0 -0
  67. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/charts/scatter_serie_item.py +0 -0
  68. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/charts/table_chart.py +0 -0
  69. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/charts/table_header.py +0 -0
  70. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/charts/table_row.py +0 -0
  71. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/charts/timeline_chart.py +0 -0
  72. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/charts/timeline_serie.py +0 -0
  73. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/charts/timeline_serie_item.py +0 -0
  74. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/checkpoint.py +0 -0
  75. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/comment.py +0 -0
  76. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/custom_field.py +0 -0
  77. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/custom_report_page.py +0 -0
  78. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/device.py +0 -0
  79. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/event.py +0 -0
  80. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/function.py +0 -0
  81. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/geofence.py +0 -0
  82. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/geofence_category.py +0 -0
  83. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/last_message.py +0 -0
  84. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/message.py +0 -0
  85. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/modbus/__init__.py +0 -0
  86. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/modbus/config.py +0 -0
  87. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/modbus/parameter.py +0 -0
  88. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/modbus/schema.py +0 -0
  89. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/modbus/status.py +0 -0
  90. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/modbus/wait.py +0 -0
  91. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/outbound_service.py +0 -0
  92. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/position.py +0 -0
  93. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/presence_type.py +0 -0
  94. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/report.py +0 -0
  95. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/report_col.py +0 -0
  96. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/report_configuration.py +0 -0
  97. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/report_data_type.py +0 -0
  98. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/report_format.py +0 -0
  99. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/report_header.py +0 -0
  100. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/report_page.py +0 -0
  101. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/report_row.py +0 -0
  102. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/sensor.py +0 -0
  103. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/static_position.py +0 -0
  104. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/telemetry/__init__.py +0 -0
  105. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/telemetry/assetmessage.py +0 -0
  106. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/telemetry/devicemessage.py +0 -0
  107. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/text_alignment.py +0 -0
  108. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/trigger.py +0 -0
  109. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/trigger_kind.py +0 -0
  110. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/user.py +0 -0
  111. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/waypoint.py +0 -0
  112. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/entities/weekday.py +0 -0
  113. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/helpers/__init__.py +0 -0
  114. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/helpers/color.py +0 -0
  115. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/lcl/__init__.py +0 -0
  116. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/lcl/core.py +0 -0
  117. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk/py.typed +0 -0
  118. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk.egg-info/dependency_links.txt +0 -0
  119. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk.egg-info/requires.txt +0 -0
  120. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/layrz_sdk.egg-info/top_level.txt +0 -0
  121. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/manual_deploy.py +0 -0
  122. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/setup.cfg +0 -0
  123. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/tests/__init__.py +0 -0
  124. {layrz_sdk-3.1.33 → layrz_sdk-3.1.35}/tests/test_lcl.py +0 -0
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.1.35
4
+
5
+ - Added models for operations handling
6
+
7
+ ## 3.1.34
8
+
9
+ - Fixes on data types onf `Action` model
10
+
3
11
  ## 3.1.33
4
12
 
5
13
  - New `Action` model
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: layrz-sdk
3
- Version: 3.1.33
3
+ Version: 3.1.35
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>
@@ -59,7 +59,13 @@ from .geofence_category import GeofenceCategory
59
59
  from .last_message import LastMessage
60
60
  from .message import Message
61
61
  from .modbus import ModbusConfig, ModbusParameter, ModbusSchema, ModbusStatus, ModbusWait
62
+ from .notification_type import TwilioNotificationType
63
+ from .operation import Operation
64
+ from .operation_case_payload import OperationCaseCommentPayload, OperationCasePayload
65
+ from .operation_payload import OperationPayload
66
+ from .operation_type import OperationType
62
67
  from .outbound_service import OutboundService
68
+ from .platform import Platform
63
69
  from .position import Position
64
70
  from .presence_type import PresenceType
65
71
  from .report import Report
@@ -70,9 +76,12 @@ from .report_format import ReportFormat
70
76
  from .report_header import ReportHeader
71
77
  from .report_page import ReportPage
72
78
  from .report_row import ReportRow
79
+ from .request_type import HttpRequestType
73
80
  from .sensor import Sensor
81
+ from .sound_effect import SoundEffect
74
82
  from .telemetry import AssetMessage, DeviceMessage
75
83
  from .text_alignment import TextAlignment
84
+ from .timezone import Timezone
76
85
  from .trigger import Trigger
77
86
  from .trigger_kind import TriggerCaseKind, TriggerCommentPattern, TriggerGeofenceKind, TriggerKind
78
87
  from .user import User
@@ -164,4 +173,14 @@ __all__ = [
164
173
  'ActionSubKind',
165
174
  'GeofenceCategory',
166
175
  'ActionGeofenceOwnership',
176
+ 'SoundEffect',
177
+ 'OperationType',
178
+ 'Operation',
179
+ 'TwilioNotificationType',
180
+ 'HttpRequestType',
181
+ 'Platform',
182
+ 'Timezone',
183
+ 'OperationCasePayload',
184
+ 'OperationCaseCommentPayload',
185
+ 'OperationPayload',
167
186
  ]
@@ -23,7 +23,7 @@ class Action(BaseModel):
23
23
  },
24
24
  }
25
25
 
26
- pk: str = Field(
26
+ pk: int = Field(
27
27
  ...,
28
28
  description='Primary key of the action entity',
29
29
  alias='id',
@@ -37,7 +37,7 @@ class Action(BaseModel):
37
37
  description='Kind of the action',
38
38
  )
39
39
 
40
- command_id: str | None = Field(
40
+ command_id: int | None = Field(
41
41
  default=None,
42
42
  description='Tag ID associated with the action to send commands to primary devices',
43
43
  )
@@ -74,3 +74,8 @@ class Asset(BaseModel):
74
74
  return device
75
75
 
76
76
  return None
77
+
78
+ contacts: list[str] = Field(
79
+ default_factory=list,
80
+ description='Defines the list of contacts of the asset, used for notifications',
81
+ )
@@ -0,0 +1,32 @@
1
+ """Twilio Notification Type Enum"""
2
+
3
+ import sys
4
+ from enum import Enum
5
+
6
+ if sys.version_info >= (3, 11):
7
+ from typing import Self
8
+ else:
9
+ from typing_extensions import Self
10
+
11
+
12
+ class TwilioNotificationType(str, Enum):
13
+ """
14
+ Twilio Notification Type Enum definition
15
+ """
16
+
17
+ SMS = 'SMS'
18
+ """ Short Message Service (SMS) notification type, used for sending text messages. """
19
+
20
+ VOICE = 'VOICE'
21
+ """ Voice notification type, used for making phone calls. """
22
+
23
+ WHATSAPP = 'WHATSAPP'
24
+ """ WhatsApp notification type, used for sending messages via WhatsApp. """
25
+
26
+ def __str__(self: Self) -> str:
27
+ """Readable property"""
28
+ return self.name
29
+
30
+ def __repr__(self: Self) -> str:
31
+ """Readable property"""
32
+ return f'TwilioNotificationType.{self.name}'
@@ -0,0 +1,170 @@
1
+ """Operation entity"""
2
+
3
+ from datetime import time, timedelta
4
+ from typing import Any
5
+
6
+ from pydantic import BaseModel, Field
7
+
8
+ from .notification_type import TwilioNotificationType
9
+ from .operation_type import OperationType
10
+ from .platform import Platform
11
+ from .request_type import HttpRequestType
12
+ from .sound_effect import SoundEffect
13
+ from .timezone import Timezone
14
+
15
+
16
+ class Operation(BaseModel):
17
+ """Operation entity"""
18
+
19
+ model_config = {
20
+ 'json_encoders': {
21
+ timedelta: lambda v: v.total_seconds(),
22
+ OperationType: lambda v: v.value,
23
+ HttpRequestType: lambda v: v.value,
24
+ TwilioNotificationType: lambda v: v.value,
25
+ SoundEffect: lambda v: v.value,
26
+ Platform: lambda v: v.value,
27
+ },
28
+ }
29
+
30
+ pk: int = Field(description='Defines the primary key of the trigger', alias='id')
31
+ name: str = Field(description='Defines the name of the trigger')
32
+
33
+ cooldown_time: timedelta = Field(
34
+ default_factory=lambda: timedelta(seconds=0),
35
+ description='Defines the cooldown time of the trigger',
36
+ )
37
+
38
+ kind: OperationType = Field(
39
+ ...,
40
+ description='Defines the kind of the operation',
41
+ alias='operation_type',
42
+ )
43
+
44
+ http_method: HttpRequestType | None = Field(
45
+ default=None,
46
+ description='Defines the HTTP method of the operation',
47
+ alias='request_type',
48
+ )
49
+
50
+ url: str | None = Field(
51
+ default=None,
52
+ description='Defines the URL of the operation',
53
+ )
54
+
55
+ headers: list[dict[str, Any]] = Field(
56
+ default_factory=list,
57
+ description='Defines the headers of the operation',
58
+ )
59
+
60
+ reception_emails: list[str] = Field(
61
+ default_factory=list,
62
+ description='Defines the reception emails of the operation',
63
+ )
64
+
65
+ language_id: int = Field(
66
+ default=2,
67
+ description='Defines the language ID of the operation',
68
+ )
69
+
70
+ payload: str = Field(
71
+ default='',
72
+ description='Defines the payload of the operation',
73
+ )
74
+
75
+ timezone_id: int | None = Field(
76
+ default=None,
77
+ description='Defines the timezone ID of the operation',
78
+ )
79
+
80
+ email_subject: str = Field(
81
+ default='',
82
+ description='Defines the email subject of the operation',
83
+ )
84
+
85
+ color: str = Field(
86
+ default='#2196F3',
87
+ description='Defines the color of the operation',
88
+ )
89
+
90
+ external_account_id: int | None = Field(
91
+ default=None,
92
+ description='Defines the external account ID of the operation',
93
+ alias='account_id',
94
+ )
95
+
96
+ twilio_notification_type: TwilioNotificationType = Field(
97
+ default=TwilioNotificationType.SMS,
98
+ description='Defines the Twilio notification type of the operation',
99
+ alias='notification_type',
100
+ )
101
+
102
+ destination_phones: list[str] = Field(
103
+ default_factory=list,
104
+ description='Defines the destination phone numbers for Twilio notifications',
105
+ )
106
+
107
+ attach_image: bool = Field(
108
+ default=False,
109
+ description='Defines if the operation should attach an image',
110
+ )
111
+
112
+ use_asset_contacts_instead: bool = Field(
113
+ default=False,
114
+ description='Defines if the operation should use asset contacts instead of reception emails',
115
+ )
116
+
117
+ email_template_id: int | None = Field(
118
+ default=None,
119
+ description='Defines the email template ID of the operation',
120
+ )
121
+
122
+ push_platforms: list[Platform] = Field(
123
+ default_factory=list,
124
+ description='Defines the platforms for push notifications',
125
+ )
126
+
127
+ push_title: str = Field(
128
+ default='',
129
+ description='Defines the title for push notifications',
130
+ )
131
+
132
+ requires_bhs_validation: bool = Field(
133
+ default=False,
134
+ description='Defines if the operation requires BHS validation',
135
+ )
136
+
137
+ bhs_tier_id: int | None = Field(
138
+ default=None,
139
+ description='Defines the BHS tier ID for the operation',
140
+ )
141
+
142
+ sound_effect: SoundEffect = Field(
143
+ default=SoundEffect.NONE,
144
+ description='Defines the sound effect for the operation',
145
+ )
146
+
147
+ sound_effect_uri: str | None = Field(
148
+ default=None,
149
+ description='Defines the URI for the sound effect of the operation. Only when sound_effect is set to CUSTOM.',
150
+ )
151
+
152
+ duration: timedelta = Field(
153
+ default_factory=lambda: timedelta(seconds=5),
154
+ description='Defines the duration of the operation',
155
+ )
156
+
157
+ credentials: dict[str, Any] = Field(
158
+ default_factory=dict,
159
+ description='Defines the credentials for the operation',
160
+ )
161
+
162
+ timezone: Timezone | None = Field(
163
+ default=None,
164
+ description='Defines the timezone of the operation',
165
+ )
166
+
167
+ icon: str | None = Field(
168
+ default=None,
169
+ description='Defines the icon for the operation',
170
+ )
@@ -0,0 +1,83 @@
1
+ """Operation case payload entity"""
2
+
3
+ from datetime import datetime, timedelta
4
+ from typing import Any
5
+
6
+ from pydantic import BaseModel, Field, field_validator
7
+
8
+ from layrz_sdk.constants import UTC
9
+ from layrz_sdk.entities.trigger import Trigger
10
+
11
+
12
+ class OperationCaseCommentPayload(BaseModel):
13
+ """Operation case comment payload entity"""
14
+
15
+ pk: int = Field(..., description='Defines the primary key of the operation case comment', alias='id')
16
+ user: str = Field(..., description='Defines the user who created the operation case comment')
17
+ content: str = Field(..., description='Defines the content of the operation case comment')
18
+ created_at: datetime = Field(
19
+ default_factory=lambda: datetime.now(UTC),
20
+ description='Defines the creation date of the operation case comment',
21
+ alias='createdAt',
22
+ )
23
+
24
+
25
+ class OperationCasePayload(BaseModel):
26
+ """Operation case payload entity"""
27
+
28
+ model_config = {
29
+ 'json_encoders': {
30
+ timedelta: lambda v: v.total_seconds(),
31
+ datetime: lambda v: v.timestamp(),
32
+ Trigger: lambda v: v.model_dump(by_alias=True, exclude_none=True),
33
+ },
34
+ }
35
+
36
+ pk: int = Field(description='Defines the primary key of the operation case payload', alias='id')
37
+ created_at: datetime = Field(
38
+ default_factory=lambda: datetime.now(UTC),
39
+ description='Defines the creation date of the operation case payload',
40
+ alias='createdAt',
41
+ )
42
+ updated_at: datetime = Field(
43
+ default_factory=lambda: datetime.now(UTC),
44
+ description='Defines the last update date of the operation case payload',
45
+ alias='updatedAt',
46
+ )
47
+
48
+ trigger: Trigger = Field(
49
+ ...,
50
+ description='Defines the trigger associated with the operation case payload',
51
+ )
52
+
53
+ @field_validator('trigger', mode='before')
54
+ def serialize_trigger(cls, value: Any) -> Trigger:
55
+ """Serialize trigger to a dictionary"""
56
+ if isinstance(value, Trigger):
57
+ return Trigger(
58
+ pk=value.pk,
59
+ name=value.name,
60
+ code=value.code,
61
+ )
62
+ if isinstance(value, dict):
63
+ return Trigger.model_validate(value)
64
+
65
+ raise ValueError('Trigger must be an instance of Trigger or a dictionary')
66
+
67
+ file_id: int | None = Field(
68
+ default=None,
69
+ description='Defines the file ID associated with the operation case payload',
70
+ alias='fileId',
71
+ )
72
+
73
+ file_created_at: datetime | None = Field(
74
+ default=None,
75
+ description='Defines the creation date of the file associated with the operation case payload',
76
+ alias='fileCreatedAt',
77
+ )
78
+
79
+ comment: OperationCaseCommentPayload | None = Field(
80
+ default=None,
81
+ description='Defines the comment associated with the operation case payload',
82
+ alias='comment',
83
+ )
@@ -0,0 +1,281 @@
1
+ """Operation Payload entity"""
2
+
3
+ from datetime import datetime, timedelta
4
+ from typing import Any
5
+
6
+ from pydantic import BaseModel, Field, field_validator
7
+
8
+ from layrz_sdk.entities.asset import Asset
9
+ from layrz_sdk.entities.geofence import Geofence
10
+ from layrz_sdk.entities.notification_type import TwilioNotificationType
11
+ from layrz_sdk.entities.operation import Operation
12
+ from layrz_sdk.entities.operation_case_payload import OperationCasePayload
13
+ from layrz_sdk.entities.operation_type import OperationType
14
+ from layrz_sdk.entities.platform import Platform
15
+ from layrz_sdk.entities.presence_type import PresenceType
16
+ from layrz_sdk.entities.request_type import HttpRequestType
17
+ from layrz_sdk.entities.sound_effect import SoundEffect
18
+ from layrz_sdk.entities.trigger import Trigger
19
+
20
+
21
+ class OperationPayload(BaseModel):
22
+ """Operation Payload entity"""
23
+
24
+ model_config = {
25
+ 'json_encoders': {
26
+ timedelta: lambda v: v.total_seconds(),
27
+ datetime: lambda v: v.timestamp(),
28
+ Asset: lambda v: v.model_dump(by_alias=True, exclude_none=True),
29
+ Trigger: lambda v: v.model_dump(by_alias=True, exclude_none=True),
30
+ Operation: lambda v: v.model_dump(by_alias=True, exclude_none=True),
31
+ Geofence: lambda v: v.model_dump(by_alias=True, exclude_none=True),
32
+ OperationType: lambda v: v.value,
33
+ HttpRequestType: lambda v: v.value,
34
+ TwilioNotificationType: lambda v: v.value,
35
+ SoundEffect: lambda v: v.value,
36
+ Platform: lambda v: v.value,
37
+ PresenceType: lambda v: v.value,
38
+ },
39
+ }
40
+
41
+ kind: OperationType = Field(
42
+ ...,
43
+ description='Defines the kind of the operation',
44
+ alias='operationType',
45
+ )
46
+
47
+ asset: Asset = Field(..., description='Defines the asset associated with the operation')
48
+
49
+ @field_validator('asset', mode='before')
50
+ def serialize_asset(cls, value: Any) -> Asset:
51
+ """Serialize asset to a dictionary"""
52
+ if isinstance(value, Asset):
53
+ return Asset(
54
+ pk=value.pk,
55
+ name=value.name,
56
+ operation_mode=value.operation_mode,
57
+ vin=value.vin,
58
+ plate=value.plate,
59
+ custom_fields=value.custom_fields,
60
+ contacts=value.contacts,
61
+ )
62
+
63
+ if isinstance(value, dict):
64
+ return Asset.model_validate(value)
65
+
66
+ raise ValueError('Asset must be an instance of Asset or a dictionary')
67
+
68
+ trigger: Trigger = Field(..., description='Defines the trigger associated with the operation')
69
+
70
+ @field_validator('trigger', mode='before')
71
+ def serialize_trigger(cls, value: Any) -> Trigger:
72
+ """Serialize trigger to a dictionary"""
73
+ if isinstance(value, Trigger):
74
+ return Trigger(
75
+ pk=value.pk,
76
+ name=value.name,
77
+ code=value.code,
78
+ )
79
+
80
+ if isinstance(value, dict):
81
+ return Trigger.model_validate(value)
82
+
83
+ raise ValueError('Trigger must be an instance of Trigger or a dictionary')
84
+
85
+ operation: Operation = Field(..., description='Defines the operation associated with the payload')
86
+
87
+ @field_validator('operation', mode='before')
88
+ def serialize_operation(cls, value: Any) -> Operation:
89
+ """Serialize operation to a dictionary"""
90
+ if isinstance(value, Operation):
91
+ return Operation(
92
+ id=value.pk,
93
+ name=value.name,
94
+ operation_type=value.kind,
95
+ timezone=value.timezone,
96
+ )
97
+
98
+ if isinstance(value, dict):
99
+ return Operation.model_validate(value)
100
+
101
+ raise ValueError('Operation must be an instance of Operation or a dictionary')
102
+
103
+ activated_at: datetime = Field(
104
+ ...,
105
+ description='Defines the date when the operation was activated',
106
+ alias='activatedAt',
107
+ )
108
+
109
+ position: dict[str, Any] = Field(
110
+ default_factory=dict,
111
+ description='Defines the position of the operation',
112
+ )
113
+
114
+ sensors: dict[str, Any] = Field(
115
+ default_factory=dict,
116
+ description='Defines the sensors of the operation',
117
+ )
118
+
119
+ geofence: Geofence | None = Field(
120
+ default=None,
121
+ description='Defines the geofence of the operation',
122
+ )
123
+
124
+ presence_type: PresenceType | None = Field(
125
+ default=None,
126
+ description='Defines the presence type of the operation',
127
+ alias='presenceType',
128
+ )
129
+
130
+ case_: OperationCasePayload | None = Field(
131
+ default=None,
132
+ description='Defines the case of the operation',
133
+ alias='case',
134
+ )
135
+
136
+ language_id: int = Field(
137
+ default=2,
138
+ description='Defines the language ID of the operation',
139
+ alias='languageId',
140
+ )
141
+
142
+ payload: str = Field(
143
+ default='',
144
+ description='Defines the payload of the operation',
145
+ )
146
+
147
+ use_asset_contacts_instead: bool = Field(
148
+ default=False,
149
+ description='Defines if the operation should use asset contacts instead of reception emails',
150
+ alias='useAssetContactsInstead',
151
+ )
152
+
153
+ account_id: int | None = Field(
154
+ default=None,
155
+ description='Defines the external account ID of the operation',
156
+ alias='accountId',
157
+ )
158
+
159
+ ## For usage of Webhooks operations
160
+ http_url: str | None = Field(
161
+ default=None,
162
+ description='Defines the URL of the operation',
163
+ )
164
+ http_method: HttpRequestType | None = Field(
165
+ default=None,
166
+ description='Defines the HTTP method of the operation',
167
+ alias='method',
168
+ )
169
+ http_headers: list[dict[str, Any]] = Field(
170
+ default_factory=list,
171
+ description='Defines the headers of the operation',
172
+ alias='headers',
173
+ )
174
+
175
+ ## For usage of Email operations
176
+ email_subject: str = Field(
177
+ default='',
178
+ description='Defines the email subject of the operation',
179
+ alias='emailSubject',
180
+ )
181
+
182
+ attach_image: bool = Field(
183
+ default=False,
184
+ description='Defines if the operation should attach an image',
185
+ alias='attachImage',
186
+ )
187
+
188
+ reception_emails: list[str] = Field(
189
+ default_factory=list,
190
+ description='Defines the reception emails of the operation',
191
+ alias='receptionEmails',
192
+ )
193
+
194
+ template_id: int | None = Field(
195
+ default=None,
196
+ description='Defines the template ID of the operation',
197
+ alias='templateId',
198
+ )
199
+
200
+ ## For usage of Twilio operations
201
+ destinations: list[str] = Field(
202
+ default_factory=list,
203
+ description='Defines the destination phone numbers for Twilio notifications',
204
+ )
205
+
206
+ twilio_host_phone: str | None = Field(
207
+ default=None,
208
+ description='Defines the host phone number for Twilio notifications',
209
+ alias='hostPhone',
210
+ )
211
+
212
+ twilio_notification_type: TwilioNotificationType = Field(
213
+ default=TwilioNotificationType.SMS,
214
+ description='Defines the Twilio notification type of the operation',
215
+ alias='notificationType',
216
+ )
217
+
218
+ username: str | None = Field(
219
+ default=None,
220
+ description='Defines the username for the operation',
221
+ )
222
+
223
+ token: str | None = Field(
224
+ default=None,
225
+ description='Defines the token for the operation',
226
+ )
227
+
228
+ requires_bhs_validation: bool = Field(
229
+ default=False,
230
+ description='Defines if the operation requires BHS validation',
231
+ alias='requiresBhsValidation',
232
+ )
233
+
234
+ bhs_tier_id: int | None = Field(
235
+ default=None,
236
+ description='Defines the BHS tier ID for the operation',
237
+ alias='bhsTierId',
238
+ )
239
+
240
+ ## For usage of BHS Push operations
241
+ push_title: str = Field(
242
+ default='',
243
+ description='Defines the title for push notifications',
244
+ alias='pushTitle',
245
+ )
246
+
247
+ push_platforms: list[Platform] = Field(
248
+ default_factory=list,
249
+ description='Defines the platforms for push notifications',
250
+ alias='pushPlatforms',
251
+ )
252
+
253
+ ## For usage of In-app notifications operations
254
+ destinations_ids: list[int] = Field(
255
+ default_factory=list,
256
+ description='Defines the destination IDs for in-app notifications',
257
+ alias='destinationsIds',
258
+ )
259
+ sound_effect: SoundEffect = Field(
260
+ default=SoundEffect.NONE,
261
+ description='Defines the sound effect for the operation',
262
+ alias='soundEffect',
263
+ )
264
+
265
+ sound_effect_uri: str | None = Field(
266
+ default=None,
267
+ description='Defines the sound effect URI for the operation',
268
+ alias='soundEffectUri',
269
+ )
270
+
271
+ icon: str | None = Field(
272
+ default=None,
273
+ description='Defines the icon for the in-app notification',
274
+ alias='icon',
275
+ )
276
+
277
+ duration: timedelta = Field(
278
+ default_factory=lambda: timedelta(seconds=0),
279
+ description='Defines the duration of the in-app notification',
280
+ alias='duration',
281
+ )
@@ -0,0 +1,44 @@
1
+ """Operation type"""
2
+
3
+ import sys
4
+ from enum import Enum
5
+
6
+ if sys.version_info >= (3, 11):
7
+ from typing import Self
8
+ else:
9
+ from typing_extensions import Self
10
+
11
+
12
+ class OperationType(str, Enum):
13
+ """
14
+ Operation type definition
15
+ """
16
+
17
+ WEBHOOKS = 'WEBHOOKS'
18
+ """ All the operations by http request """
19
+
20
+ SENDEMAIL = 'SENDEMAIL'
21
+ """ Send notifications emails """
22
+
23
+ ACTIVATEASSET = 'ACTIVATEASSET'
24
+ """ Register an event for the asset """
25
+
26
+ INAPPNOTIFICATION = 'INAPPNOTIFICATION'
27
+ """ Send notifications inside the app """
28
+
29
+ TWILIO = 'TWILIO'
30
+ """ Send notifications using Twilio """
31
+
32
+ MOBILE_POPUP_NOTIFICATION = 'MOBILE_POPUP_NOTIFICATION'
33
+ """ Send notifications using Push Notification (Mobile) """
34
+
35
+ BHS_PUSH = 'BHS_PUSH'
36
+ """ Send notifications using Firebase Push Notifications of Brickhouse Tracking Platform """
37
+
38
+ def __str__(self: Self) -> str:
39
+ """Readable property"""
40
+ return self.name
41
+
42
+ def __repr__(self: Self) -> str:
43
+ """Readable property"""
44
+ return f'OperationType.{self.name}'