|
| 1 | +from __future__ import annotations |
| 2 | +from collections.abc import Callable |
1 | 3 | import logging |
2 | 4 |
|
3 | | -from .ldm_classes import Location |
| 5 | +from .ldm_classes import ( |
| 6 | + Location, |
| 7 | + SubscribeDataobjectsReq, |
| 8 | + SubscribeDataObjectsResp, |
| 9 | + RegisterDataConsumerReq, |
| 10 | + RegisterDataConsumerResp, |
| 11 | + Filter, |
| 12 | + FilterStatement, |
| 13 | + ComparisonOperators, |
| 14 | + AccessPermission, |
| 15 | +) |
4 | 16 |
|
5 | 17 | from .ldm_maintenance_reactive import LDMMaintenanceReactive |
6 | 18 | from .ldm_maintenance_thread import LDMMaintenanceThread |
|
16 | 28 | from .exceptions import LDMMaintenanceKeyError, LDMServiceKeyError, LDMDatabaseKeyError |
17 | 29 |
|
18 | 30 |
|
19 | | -def ldm_factory( |
20 | | - ldm_location: Location, |
21 | | - ldm_maintenance_type: str = "Reactive", |
22 | | - ldm_service_type: str = "Reactive", |
23 | | - ldm_database_type: str = "Dictionary", |
24 | | -) -> LDMFacility: |
25 | | - """ |
26 | | - Factory function to create a Local Dynamic Map Facility. |
27 | | -
|
28 | | - Parameters |
29 | | - ---------- |
30 | | - ldm_location : Location |
31 | | - Location object to be used by the LDM Facility. |
32 | | - ldm_maintenance_type : str, optional |
33 | | - Type of LDM Maintenance to be used. Defaults to "Reactive". |
34 | | - ldm_service_type : str, optional |
35 | | - Type of LDM Service to be used. Defaults to "Reactive". |
36 | | - ldm_database_type : str, optional |
37 | | - Type of LDM Database to be used. Defaults to "Dictionary". |
38 | | - """ |
39 | | - |
40 | | - logs = logging.getLogger("local_dynamic_map") |
41 | | - |
42 | | - if ldm_database_type == "Dictionary": |
43 | | - ldm_database = DictionaryDataBase() |
44 | | - logs.info('LDM Database "Dictionary" configured.') |
45 | | - elif ldm_database_type == "TinyDB": |
46 | | - ldm_database = TinyDB() |
47 | | - logs.info('LDM Database "TindyDB" configured.') |
48 | | - else: |
49 | | - logs.error( |
50 | | - 'LDM Database must be either "Dictionary" or "TindyDB". %s is an invalid type for LDM Database.', |
51 | | - ldm_database_type, |
52 | | - ) |
53 | | - raise LDMDatabaseKeyError( |
54 | | - f'LDM Database must be either "Dictionary" or "TindyDB". {ldm_database_type} is an invalid type.' |
55 | | - ) |
| 31 | +from flexstack.facilities.local_dynamic_map.ldm_classes import ( |
| 32 | + Location, |
| 33 | + SubscribeDataobjectsReq, |
| 34 | + SubscribeDataObjectsResp, |
| 35 | + RequestDataObjectsResp, |
| 36 | + RegisterDataConsumerReq, |
| 37 | + RegisterDataConsumerResp, |
| 38 | + Filter, |
| 39 | + FilterStatement, |
| 40 | + ComparisonOperators, |
| 41 | + AccessPermission, |
| 42 | +) |
56 | 43 |
|
57 | | - if ldm_maintenance_type == "Reactive": |
58 | | - ldm_maintenance = LDMMaintenanceReactive(ldm_location, ldm_database) |
59 | | - logs.info('LDM Maintenance "Reactive" configured.') |
60 | | - elif ldm_maintenance_type == "Thread": |
61 | | - ldm_maintenance = LDMMaintenanceThread(ldm_location, ldm_database, None) |
62 | | - logs.info('LDM Maintenance "Thread" configured.') |
63 | | - else: |
64 | | - logs.error( |
65 | | - 'LDM Maintenance must be either "Reactive" or "Thread". %s is an invalid type for LDM Maintenance.', |
66 | | - ldm_maintenance_type, |
67 | | - ) |
68 | | - raise LDMMaintenanceKeyError( |
69 | | - f'LDM Maintenance must be either "Reactive" or "Thread". {ldm_maintenance_type} is an invalid type.' |
70 | | - ) |
| 44 | +class LDMFactory: |
| 45 | + """ Factory class to create a Local Dynamic Map Facility.""" |
| 46 | + |
| 47 | + def __init__(self) -> None: |
| 48 | + self.ldm = None |
| 49 | + |
| 50 | + def create_ldm( |
| 51 | + self, |
| 52 | + ldm_location: Location, |
| 53 | + ldm_maintenance_type: str = "Reactive", |
| 54 | + ldm_service_type: str = "Reactive", |
| 55 | + ldm_database_type: str = "Dictionary", |
| 56 | + ) -> LDMFacility: |
| 57 | + """ |
| 58 | + Factory function to create a Local Dynamic Map Facility. |
| 59 | +
|
| 60 | + Parameters |
| 61 | + ---------- |
| 62 | + ldm_location : Location |
| 63 | + Location object to be used by the LDM Facility. |
| 64 | + ldm_maintenance_type : str, optional |
| 65 | + Type of LDM Maintenance to be used. Defaults to "Reactive". |
| 66 | + ldm_service_type : str, optional |
| 67 | + Type of LDM Service to be used. Defaults to "Reactive". |
| 68 | + ldm_database_type : str, optional |
| 69 | + Type of LDM Database to be used. Defaults to "Dictionary". |
| 70 | + """ |
| 71 | + |
| 72 | + logs = logging.getLogger("local_dynamic_map") |
| 73 | + |
| 74 | + if ldm_database_type == "Dictionary": |
| 75 | + ldm_database = DictionaryDataBase() |
| 76 | + logs.info('LDM Database "Dictionary" configured.') |
| 77 | + elif ldm_database_type == "TinyDB": |
| 78 | + ldm_database = TinyDB() |
| 79 | + logs.info('LDM Database "TinyDB" configured.') |
| 80 | + else: |
| 81 | + logs.error( |
| 82 | + 'LDM Database must be either "Dictionary" or "TinyDB". %s is an invalid type for LDM Database.', |
| 83 | + ldm_database_type, |
| 84 | + ) |
| 85 | + raise LDMDatabaseKeyError( |
| 86 | + f'LDM Database must be either "Dictionary" or "TinyDB". {ldm_database_type} is an invalid type.' |
| 87 | + ) |
71 | 88 |
|
72 | | - if ldm_service_type == "Reactive": |
73 | | - ldm_service = LDMServiceReactive(ldm_maintenance) |
74 | | - logs.info('LDM Service "Reactive" configured.') |
75 | | - elif ldm_service_type == "Thread": |
76 | | - ldm_service = LDMServiceThreads(ldm_maintenance) |
77 | | - logs.info('LDM Service "Thread" configured.') |
78 | | - else: |
79 | | - logs.error( |
80 | | - 'LDM Service must be either "Reactive" or "Thread". %s is an invalid type for LDM Service.', |
| 89 | + if ldm_maintenance_type == "Reactive": |
| 90 | + ldm_maintenance = LDMMaintenanceReactive(ldm_location, ldm_database) |
| 91 | + logs.info('LDM Maintenance "Reactive" configured.') |
| 92 | + elif ldm_maintenance_type == "Thread": |
| 93 | + ldm_maintenance = LDMMaintenanceThread(ldm_location, ldm_database, None) |
| 94 | + logs.info('LDM Maintenance "Thread" configured.') |
| 95 | + else: |
| 96 | + logs.error( |
| 97 | + 'LDM Maintenance must be either "Reactive" or "Thread". %s is an invalid type for LDM Maintenance.', |
| 98 | + ldm_maintenance_type, |
| 99 | + ) |
| 100 | + raise LDMMaintenanceKeyError( |
| 101 | + f'LDM Maintenance must be either "Reactive" or "Thread". {ldm_maintenance_type} is an invalid type.' |
| 102 | + ) |
| 103 | + |
| 104 | + if ldm_service_type == "Reactive": |
| 105 | + ldm_service = LDMServiceReactive(ldm_maintenance) |
| 106 | + logs.info('LDM Service "Reactive" configured.') |
| 107 | + elif ldm_service_type == "Thread": |
| 108 | + ldm_service = LDMServiceThreads(ldm_maintenance) |
| 109 | + logs.info('LDM Service "Thread" configured.') |
| 110 | + else: |
| 111 | + logs.error( |
| 112 | + 'LDM Service must be either "Reactive" or "Thread". %s is an invalid type for LDM Service.', |
| 113 | + ldm_service_type, |
| 114 | + ) |
| 115 | + raise LDMServiceKeyError( |
| 116 | + f'LDM Service must be either "Reactive" or "Thread". {ldm_service_type} is an invalid type for LDM Service.' |
| 117 | + ) |
| 118 | + |
| 119 | + ldm_facility = LDMFacility(ldm_maintenance, ldm_service) |
| 120 | + logs.info( |
| 121 | + 'LDM Facility configured with: LDM Maintenance: "%s", LDM Service: "%s", LDM Database: "%s".', |
| 122 | + ldm_maintenance_type, |
81 | 123 | ldm_service_type, |
| 124 | + ldm_database_type, |
82 | 125 | ) |
83 | | - raise LDMServiceKeyError( |
84 | | - f'LDM Service must be either "Reactive" or "Thread". {ldm_service_type} is an invalid type for LDM Service.' |
| 126 | + self.ldm = ldm_facility |
| 127 | + return ldm_facility |
| 128 | + |
| 129 | + |
| 130 | + def subscribe_to_ldm(self, own_station_id: int, ldm_location: Location, callback_function: Callable[[RequestDataObjectsResp], None],) -> None: |
| 131 | + """ |
| 132 | + Method to subscribe to the LDM Facility. |
| 133 | +
|
| 134 | + Parameters |
| 135 | + ---------- |
| 136 | + subscription_request : SubscribeDataobjectsReq |
| 137 | + Subscription request object. |
| 138 | + callback_function : Callable |
| 139 | + Callback function to be called when new data is available. |
| 140 | +
|
| 141 | + Returns |
| 142 | + ------- |
| 143 | + int |
| 144 | + Subscription ID. |
| 145 | + """ |
| 146 | + if self.ldm is None: |
| 147 | + raise Exception("LDM Facility not initialized. Please create an LDM Facility first.") |
| 148 | + |
| 149 | + register_data_consumer_reponse: RegisterDataConsumerResp = self.ldm.if_ldm_4.register_data_consumer( |
| 150 | + RegisterDataConsumerReq( |
| 151 | + application_id=AccessPermission.CAM, |
| 152 | + access_permisions=(AccessPermission.CAM, AccessPermission.VAM), |
| 153 | + area_of_interest=ldm_location, |
| 154 | + ) |
85 | 155 | ) |
| 156 | + if register_data_consumer_reponse.result == 2: |
| 157 | + raise Exception(f"Failed to register data consumer: {str(register_data_consumer_reponse)}") |
86 | 158 |
|
87 | | - ldm_facility = LDMFacility(ldm_maintenance, ldm_service) |
88 | | - logs.info( |
89 | | - 'LDM Facility configured with: LDM Maintenance: "%s", LDM Service: "%s", LDM Database: "%s".', |
90 | | - ldm_maintenance_type, |
91 | | - ldm_service_type, |
92 | | - ldm_database_type, |
93 | | - ) |
94 | | - return ldm_facility |
| 159 | + |
| 160 | + subscribe_data_consumer_response: SubscribeDataObjectsResp = self.ldm.if_ldm_4.subscribe_data_consumer( |
| 161 | + SubscribeDataobjectsReq( |
| 162 | + application_id=AccessPermission.CAM, |
| 163 | + data_object_type=(AccessPermission.CAM, AccessPermission.VAM), |
| 164 | + filter=Filter(FilterStatement("header.stationId", ComparisonOperators.NOT_EQUAL, own_station_id)), |
| 165 | + ), |
| 166 | + callback_function, |
| 167 | + ) |
| 168 | + if subscribe_data_consumer_response.result != 0: |
| 169 | + raise Exception(f"Failed to subscribe to data objects: {str(subscribe_data_consumer_response.result)}") |
0 commit comments