switch-api 0.6.15__tar.gz → 0.6.16__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.
- {switch_api-0.6.15 → switch_api-0.6.16}/HISTORY.md +6 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/PKG-INFO +7 -1
- {switch_api-0.6.15 → switch_api-0.6.16}/setup.py +1 -1
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/__init__.py +1 -1
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/controls/controls.py +114 -44
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api.egg-info/PKG-INFO +7 -1
- {switch_api-0.6.15 → switch_api-0.6.16}/AUTHORS.rst +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/LICENCE +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/MANIFEST.in +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/README.md +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/pyproject.toml +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/setup.cfg +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/_authentication/__init__.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/_authentication/_authentication.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/_authentication/_credentials_store/__init__.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/_authentication/_credentials_store/_credentials_store.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/_authentication/_msal/__init__.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/_authentication/_msal/_custom_application.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/_compute/__init__.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/_compute/_commands.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/_compute/_compute.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/_compute/_iotservice.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/_compute/_models.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/_compute/_utils.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/_guide/__init__.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/_guide/main.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/_guide/processor.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/_utils/__init__.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/_utils/_constants.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/_utils/_marketplace.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/_utils/_mqtt.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/_utils/_platform.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/_utils/_utils.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/analytics/__init__.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/analytics/analytics.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/cache/__init__.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/cache/cache.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/controls/__init__.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/controls/_constants.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/controls/_enums.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/controls/_mqtt.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/dataset/__init__.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/dataset/dataset.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/email/__init__.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/email/email_sender.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/error_handlers/__init__.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/error_handlers/error_handlers.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/extensions/__init__.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/extensions/extensions.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/extensions/field_meta.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/extensions/helpers.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/extensions/pipeline.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/initialize.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/integration/__init__.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/integration/_utils.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/integration/helpers.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/integration/integration.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/pipeline/__init__.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/pipeline/automation.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/pipeline/definitions.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/pipeline/pipeline.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/platform_insights/__init__.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/platform_insights/platform_insights.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/realtime/__init__.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/realtime/_mqtt.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api/realtime/realtime.py +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api.egg-info/SOURCES.txt +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api.egg-info/dependency_links.txt +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api.egg-info/requires.txt +0 -0
- {switch_api-0.6.15 → switch_api-0.6.16}/switch_api.egg-info/top_level.txt +0 -0
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# History
|
|
2
2
|
|
|
3
|
+
#0.6.16
|
|
4
|
+
### Changed
|
|
5
|
+
In the `controls` module:
|
|
6
|
+
- Updated `submit_control_continue()` to send log control requests to the IoT endpoint in chunks of 50 per request, improving reliability and preventing oversized payloads.
|
|
7
|
+
- Updated `submit_control_continue()` to also batch control requests sent via MQTT (50 per batch), ensuring more stable and efficient message delivery.
|
|
8
|
+
|
|
3
9
|
#0.6.15
|
|
4
10
|
### Added
|
|
5
11
|
In the `automation` module:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: switch_api
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.16
|
|
4
4
|
Summary: A complete package for data ingestion into the Switch Automation Platform.
|
|
5
5
|
Home-page: UNKNOWN
|
|
6
6
|
Author: Switch Automation Pty Ltd.
|
|
@@ -38,6 +38,12 @@ pip install switch_api
|
|
|
38
38
|
|
|
39
39
|
# History
|
|
40
40
|
|
|
41
|
+
#0.6.16
|
|
42
|
+
### Changed
|
|
43
|
+
In the `controls` module:
|
|
44
|
+
- Updated `submit_control_continue()` to send log control requests to the IoT endpoint in chunks of 50 per request, improving reliability and preventing oversized payloads.
|
|
45
|
+
- Updated `submit_control_continue()` to also batch control requests sent via MQTT (50 per batch), ensuring more stable and efficient message delivery.
|
|
46
|
+
|
|
41
47
|
#0.6.15
|
|
42
48
|
### Added
|
|
43
49
|
In the `automation` module:
|
|
@@ -16,7 +16,7 @@ setup(
|
|
|
16
16
|
long_description_content_type='text/markdown',
|
|
17
17
|
license='MIT License',
|
|
18
18
|
name="switch_api",
|
|
19
|
-
version="0.6.
|
|
19
|
+
version="0.6.16",
|
|
20
20
|
packages=find_packages(include=["switch_api", "switch_api.*"]),
|
|
21
21
|
install_requires=['pandas==1.5.3', 'requests', 'azure-storage-blob', 'pandera[io]==0.7.1', 'azure-servicebus',
|
|
22
22
|
'msal>=1.11.0', 'paho-mqtt==1.6.1', 'uvicorn==0.22.0', 'fastapi==0.98.0', 'pyodbc==4.0.39', 'cachetools==5.5.0',
|
|
@@ -55,6 +55,43 @@ global _session
|
|
|
55
55
|
_control_components = {}
|
|
56
56
|
_switch_mqtt = None
|
|
57
57
|
_session = None
|
|
58
|
+
MAX_CONTROL_REQUEST_SENSORS = 50
|
|
59
|
+
|
|
60
|
+
def _chunk_dataframe(df: pandas.DataFrame, chunk_size: int = MAX_CONTROL_REQUEST_SENSORS) -> List[pandas.DataFrame]:
|
|
61
|
+
"""Split a dataframe into bounded chunks while preserving row order."""
|
|
62
|
+
if df.empty:
|
|
63
|
+
return []
|
|
64
|
+
|
|
65
|
+
return [
|
|
66
|
+
df.iloc[start_idx:start_idx + chunk_size].copy()
|
|
67
|
+
for start_idx in range(0, len(df), chunk_size)
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
def _build_chunk_session_ids(chunk_count: int, session_id: Union[uuid.UUID, str, None] = None) -> List[uuid.UUID]:
|
|
71
|
+
"""Return one unique session id per chunk, reusing the provided id for the first chunk when valid."""
|
|
72
|
+
if chunk_count <= 0:
|
|
73
|
+
return []
|
|
74
|
+
|
|
75
|
+
chunk_session_ids: List[uuid.UUID] = []
|
|
76
|
+
seen_session_ids = set()
|
|
77
|
+
|
|
78
|
+
if is_valid_uuid(session_id):
|
|
79
|
+
first_session_id = uuid.UUID(str(session_id))
|
|
80
|
+
else:
|
|
81
|
+
first_session_id = uuid.uuid4()
|
|
82
|
+
|
|
83
|
+
chunk_session_ids.append(first_session_id)
|
|
84
|
+
seen_session_ids.add(str(first_session_id))
|
|
85
|
+
|
|
86
|
+
while len(chunk_session_ids) < chunk_count:
|
|
87
|
+
next_session_id = uuid.uuid4()
|
|
88
|
+
if str(next_session_id) in seen_session_ids:
|
|
89
|
+
continue
|
|
90
|
+
|
|
91
|
+
chunk_session_ids.append(next_session_id)
|
|
92
|
+
seen_session_ids.add(str(next_session_id))
|
|
93
|
+
|
|
94
|
+
return chunk_session_ids
|
|
58
95
|
|
|
59
96
|
def submit_control_continue(api_inputs: ApiInputs, data: pandas.DataFrame, information_columns: list = [],
|
|
60
97
|
is_send_control: bool = True, ws_timeout_in_seconds: int = WS_MQTT_CONNECTION_TIMEOUT):
|
|
@@ -409,39 +446,70 @@ def __send_control(api_inputs: ApiInputs, installation_id: Union[uuid.UUID, str]
|
|
|
409
446
|
acknowledgement_df = format_acknowledgement_payload_df(
|
|
410
447
|
df=acknowledgement_df, required_columns=required_columns, has_priority=has_priority)
|
|
411
448
|
|
|
449
|
+
control_request_df = control_request_df.copy()
|
|
450
|
+
control_request_df = format_control_payload_df(
|
|
451
|
+
required_columns=required_columns, has_priority=has_priority, df=control_request_df)
|
|
452
|
+
|
|
453
|
+
acknowledgement_chunks = _chunk_dataframe(acknowledgement_df)
|
|
454
|
+
control_request_chunks = _chunk_dataframe(control_request_df)
|
|
455
|
+
chunk_session_ids = _build_chunk_session_ids(
|
|
456
|
+
chunk_count=len(control_request_chunks),
|
|
457
|
+
session_id=session_id)
|
|
458
|
+
|
|
412
459
|
if is_send_control:
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
api_inputs=api_inputs,
|
|
416
|
-
df=acknowledgement_df,
|
|
417
|
-
session_id=session_id,
|
|
418
|
-
installation_id=installation_id)
|
|
419
|
-
if result_df.empty:
|
|
460
|
+
if len(acknowledgement_chunks) != len(control_request_chunks):
|
|
461
|
+
logger.error("Chunk count mismatch between control acknowledgement and MQTT payloads.")
|
|
420
462
|
df_matrix[COL_CONTROL_STATUS] = ControlStatus.NotSentToService.value
|
|
421
463
|
return df_matrix
|
|
422
464
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
465
|
+
successful_ack_chunks = []
|
|
466
|
+
successful_control_chunks = []
|
|
467
|
+
successful_session_ids = []
|
|
468
|
+
|
|
469
|
+
for acknowledgement_chunk, control_request_chunk, chunk_session_id in zip(
|
|
470
|
+
acknowledgement_chunks,
|
|
471
|
+
control_request_chunks,
|
|
472
|
+
chunk_session_ids,
|
|
473
|
+
):
|
|
474
|
+
_, result_df = log_control_request(
|
|
475
|
+
session=_session,
|
|
476
|
+
api_inputs=api_inputs,
|
|
477
|
+
df=acknowledgement_chunk,
|
|
478
|
+
session_id=chunk_session_id,
|
|
479
|
+
installation_id=installation_id,
|
|
480
|
+
)
|
|
426
481
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
482
|
+
if result_df.empty:
|
|
483
|
+
logger.warning(
|
|
484
|
+
"Skipping failed chunk for session_id=%s",
|
|
485
|
+
chunk_session_id,
|
|
486
|
+
)
|
|
487
|
+
continue
|
|
431
488
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
489
|
+
successful_ack_chunks.append(acknowledgement_chunk)
|
|
490
|
+
successful_control_chunks.append(control_request_chunk)
|
|
491
|
+
successful_session_ids.append(chunk_session_id)
|
|
435
492
|
|
|
436
|
-
|
|
437
|
-
|
|
493
|
+
#only successfuly chunks are used for the control request next
|
|
494
|
+
acknowledgement_chunks = successful_ack_chunks
|
|
495
|
+
control_request_chunks = successful_control_chunks
|
|
496
|
+
chunk_session_ids = successful_session_ids
|
|
438
497
|
|
|
439
|
-
|
|
498
|
+
if not acknowledgement_chunks:
|
|
499
|
+
logger.error("All chunks failed during log control request.")
|
|
500
|
+
df_matrix[COL_CONTROL_STATUS] = ControlStatus.NotSentToService.value
|
|
501
|
+
return df_matrix
|
|
502
|
+
|
|
503
|
+
def process_paged_request(chunks: List[pandas.DataFrame], chunk_session_ids: List[uuid.UUID]):
|
|
504
|
+
paged_results = pandas.DataFrame()
|
|
505
|
+
|
|
506
|
+
for page_data, chunk_session_id in zip(chunks, chunk_session_ids):
|
|
507
|
+
result = send_control(page_data, chunk_session_id)
|
|
440
508
|
paged_results = pandas.concat([paged_results, result])
|
|
441
509
|
|
|
442
510
|
return paged_results
|
|
443
511
|
|
|
444
|
-
def send_control(page_data):
|
|
512
|
+
def send_control(page_data: pandas.DataFrame, chunk_session_id: uuid.UUID):
|
|
445
513
|
retry_count = 0
|
|
446
514
|
max_retries = 3
|
|
447
515
|
success_results = pandas.DataFrame()
|
|
@@ -451,7 +519,7 @@ def __send_control(api_inputs: ApiInputs, installation_id: Union[uuid.UUID, str]
|
|
|
451
519
|
|
|
452
520
|
while retry_count < max_retries:
|
|
453
521
|
success_response, missing_response = _switch_mqtt.send_control_request(
|
|
454
|
-
session_id=str(
|
|
522
|
+
session_id=str(chunk_session_id),
|
|
455
523
|
installation_id=installation_id,
|
|
456
524
|
sensors=dataframe_to_control.to_dict(orient='records'))
|
|
457
525
|
|
|
@@ -522,7 +590,7 @@ def __send_control(api_inputs: ApiInputs, installation_id: Union[uuid.UUID, str]
|
|
|
522
590
|
return control_result
|
|
523
591
|
|
|
524
592
|
if is_send_control:
|
|
525
|
-
control_results = process_paged_request(
|
|
593
|
+
control_results = process_paged_request(control_request_chunks, chunk_session_ids)
|
|
526
594
|
control_results = control_results.rename(
|
|
527
595
|
columns={'sensorId': COL_OBJECT_PROPERTY_ID})
|
|
528
596
|
control_results = pandas.merge(control_results, df_matrix[[
|
|
@@ -673,12 +741,18 @@ def submit_control(api_inputs: ApiInputs, installation_id: Union[uuid.UUID, str]
|
|
|
673
741
|
if _session == None:
|
|
674
742
|
_session = requests_retry_session2(retries=5, backoff_factor=2)
|
|
675
743
|
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
744
|
+
acknowledgement_chunks = _chunk_dataframe(data_frame)
|
|
745
|
+
chunk_session_ids = _build_chunk_session_ids(
|
|
746
|
+
chunk_count=len(acknowledgement_chunks),
|
|
747
|
+
session_id=session_id)
|
|
748
|
+
|
|
749
|
+
for acknowledgement_chunk, chunk_session_id in zip(acknowledgement_chunks, chunk_session_ids):
|
|
750
|
+
_, result_df = log_control_request(session=_session,
|
|
751
|
+
api_inputs=api_inputs,
|
|
752
|
+
df=acknowledgement_chunk,
|
|
753
|
+
session_id=chunk_session_id,
|
|
754
|
+
installation_id=installation_id)
|
|
755
|
+
if result_df.empty:
|
|
682
756
|
return pandas.DataFrame()
|
|
683
757
|
|
|
684
758
|
# Proceeds when the control request is successful
|
|
@@ -722,24 +796,18 @@ def submit_control(api_inputs: ApiInputs, installation_id: Union[uuid.UUID, str]
|
|
|
722
796
|
logger.info("Could not connect to MQTT Broker.")
|
|
723
797
|
return 'Could not connect to MQTT Broker.', pandas.DataFrame()
|
|
724
798
|
|
|
725
|
-
|
|
726
|
-
paged_results = pandas.DataFrame()
|
|
727
|
-
total_rows = len(df)
|
|
728
|
-
num_pages = (total_rows + page_size - 1) // page_size
|
|
729
|
-
|
|
730
|
-
for page_num in range(num_pages):
|
|
731
|
-
start_idx = page_num * page_size
|
|
732
|
-
end_idx = min((page_num + 1) * page_size, total_rows)
|
|
799
|
+
control_request_chunks = _chunk_dataframe(data_frame)
|
|
733
800
|
|
|
734
|
-
|
|
735
|
-
|
|
801
|
+
def process_paged_request(chunks: List[pandas.DataFrame], chunk_session_ids: List[uuid.UUID]):
|
|
802
|
+
paged_results = pandas.DataFrame()
|
|
736
803
|
|
|
737
|
-
|
|
804
|
+
for page_data, chunk_session_id in zip(chunks, chunk_session_ids):
|
|
805
|
+
result = send_control(page_data, chunk_session_id)
|
|
738
806
|
paged_results = pandas.concat([paged_results, result])
|
|
739
807
|
|
|
740
808
|
return paged_results
|
|
741
809
|
|
|
742
|
-
def send_control(page_data):
|
|
810
|
+
def send_control(page_data: pandas.DataFrame, chunk_session_id: uuid.UUID):
|
|
743
811
|
retry_count = 0
|
|
744
812
|
max_retries = 3
|
|
745
813
|
success_results = pandas.DataFrame()
|
|
@@ -749,7 +817,7 @@ def submit_control(api_inputs: ApiInputs, installation_id: Union[uuid.UUID, str]
|
|
|
749
817
|
|
|
750
818
|
while retry_count < max_retries:
|
|
751
819
|
success_response, missing_response = _switch_mqtt.send_control_request(
|
|
752
|
-
session_id=str(
|
|
820
|
+
session_id=str(chunk_session_id),
|
|
753
821
|
installation_id=installation_id,
|
|
754
822
|
sensors=dataframe_to_control.to_dict(orient='records'))
|
|
755
823
|
|
|
@@ -821,7 +889,7 @@ def submit_control(api_inputs: ApiInputs, installation_id: Union[uuid.UUID, str]
|
|
|
821
889
|
|
|
822
890
|
# [Subscribe] to ClientId + Site State Topics
|
|
823
891
|
_switch_mqtt.subscribe_installation(installation_id=installation_id)
|
|
824
|
-
control_results = process_paged_request(
|
|
892
|
+
control_results = process_paged_request(control_request_chunks, chunk_session_ids)
|
|
825
893
|
|
|
826
894
|
return control_results
|
|
827
895
|
|
|
@@ -983,6 +1051,8 @@ def log_control_request(session: requests.Session, api_inputs: ApiInputs, df: pa
|
|
|
983
1051
|
logger.info("Control Request Session Id: %s", session_id)
|
|
984
1052
|
logger.info("Control Request for User: %s=%s",
|
|
985
1053
|
api_inputs.email_address, api_inputs.user_id)
|
|
1054
|
+
logger.info("Log Control Request Payload:")
|
|
1055
|
+
logger.info(json_payload)
|
|
986
1056
|
|
|
987
1057
|
try:
|
|
988
1058
|
response = session_post(session, url, json_payload, headers)
|
|
@@ -1177,4 +1247,4 @@ def session_post(session, url, json_payload, headers):
|
|
|
1177
1247
|
if "Connection refused" in str(ex):
|
|
1178
1248
|
logger.error("Hard failure: Connection Refused. Not retrying.")
|
|
1179
1249
|
raise
|
|
1180
|
-
raise
|
|
1250
|
+
raise
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: switch-api
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.16
|
|
4
4
|
Summary: A complete package for data ingestion into the Switch Automation Platform.
|
|
5
5
|
Home-page: UNKNOWN
|
|
6
6
|
Author: Switch Automation Pty Ltd.
|
|
@@ -38,6 +38,12 @@ pip install switch_api
|
|
|
38
38
|
|
|
39
39
|
# History
|
|
40
40
|
|
|
41
|
+
#0.6.16
|
|
42
|
+
### Changed
|
|
43
|
+
In the `controls` module:
|
|
44
|
+
- Updated `submit_control_continue()` to send log control requests to the IoT endpoint in chunks of 50 per request, improving reliability and preventing oversized payloads.
|
|
45
|
+
- Updated `submit_control_continue()` to also batch control requests sent via MQTT (50 per batch), ensuring more stable and efficient message delivery.
|
|
46
|
+
|
|
41
47
|
#0.6.15
|
|
42
48
|
### Added
|
|
43
49
|
In the `automation` module:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{switch_api-0.6.15 → switch_api-0.6.16}/switch_api/_authentication/_credentials_store/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{switch_api-0.6.15 → switch_api-0.6.16}/switch_api/_authentication/_msal/_custom_application.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|