zepben.ewb 1.0.0__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 (641) hide show
  1. zepben/ewb/__init__.py +601 -0
  2. zepben/ewb/auth/__init__.py +10 -0
  3. zepben/ewb/auth/client/__init__.py +5 -0
  4. zepben/ewb/auth/client/zepben_token_fetcher.py +273 -0
  5. zepben/ewb/auth/common/__init__.py +5 -0
  6. zepben/ewb/auth/common/auth_exception.py +16 -0
  7. zepben/ewb/auth/common/auth_method.py +28 -0
  8. zepben/ewb/auth/common/auth_provider_config.py +96 -0
  9. zepben/ewb/database/__init__.py +4 -0
  10. zepben/ewb/database/paths/__init__.py +4 -0
  11. zepben/ewb/database/paths/database_type.py +34 -0
  12. zepben/ewb/database/paths/ewb_data_file_paths.py +237 -0
  13. zepben/ewb/database/sql/__init__.py +4 -0
  14. zepben/ewb/database/sql/column.py +37 -0
  15. zepben/ewb/database/sql/sql_table.py +142 -0
  16. zepben/ewb/database/sqlite/__init__.py +4 -0
  17. zepben/ewb/database/sqlite/common/__init__.py +4 -0
  18. zepben/ewb/database/sqlite/common/base_cim_reader.py +212 -0
  19. zepben/ewb/database/sqlite/common/base_cim_writer.py +159 -0
  20. zepben/ewb/database/sqlite/common/base_collection_reader.py +96 -0
  21. zepben/ewb/database/sqlite/common/base_collection_writer.py +73 -0
  22. zepben/ewb/database/sqlite/common/base_database_reader.py +127 -0
  23. zepben/ewb/database/sqlite/common/base_database_tables.py +137 -0
  24. zepben/ewb/database/sqlite/common/base_database_writer.py +195 -0
  25. zepben/ewb/database/sqlite/common/base_entry_writer.py +34 -0
  26. zepben/ewb/database/sqlite/common/base_service_reader.py +50 -0
  27. zepben/ewb/database/sqlite/common/base_service_writer.py +104 -0
  28. zepben/ewb/database/sqlite/common/metadata_collection_reader.py +39 -0
  29. zepben/ewb/database/sqlite/common/metadata_collection_writer.py +38 -0
  30. zepben/ewb/database/sqlite/common/metadata_entry_reader.py +45 -0
  31. zepben/ewb/database/sqlite/common/metadata_entry_writer.py +41 -0
  32. zepben/ewb/database/sqlite/common/reader_exceptions.py +30 -0
  33. zepben/ewb/database/sqlite/customer/__init__.py +4 -0
  34. zepben/ewb/database/sqlite/customer/customer_cim_reader.py +169 -0
  35. zepben/ewb/database/sqlite/customer/customer_cim_writer.py +137 -0
  36. zepben/ewb/database/sqlite/customer/customer_database_reader.py +44 -0
  37. zepben/ewb/database/sqlite/customer/customer_database_tables.py +37 -0
  38. zepben/ewb/database/sqlite/customer/customer_database_writer.py +45 -0
  39. zepben/ewb/database/sqlite/customer/customer_service_reader.py +57 -0
  40. zepben/ewb/database/sqlite/customer/customer_service_writer.py +47 -0
  41. zepben/ewb/database/sqlite/diagram/__init__.py +4 -0
  42. zepben/ewb/database/sqlite/diagram/diagram_cim_reader.py +105 -0
  43. zepben/ewb/database/sqlite/diagram/diagram_cim_writer.py +81 -0
  44. zepben/ewb/database/sqlite/diagram/diagram_database_reader.py +45 -0
  45. zepben/ewb/database/sqlite/diagram/diagram_database_tables.py +29 -0
  46. zepben/ewb/database/sqlite/diagram/diagram_database_writer.py +44 -0
  47. zepben/ewb/database/sqlite/diagram/diagram_service_reader.py +49 -0
  48. zepben/ewb/database/sqlite/diagram/diagram_service_writer.py +41 -0
  49. zepben/ewb/database/sqlite/extensions/__init__.py +4 -0
  50. zepben/ewb/database/sqlite/extensions/prepared_statement.py +112 -0
  51. zepben/ewb/database/sqlite/extensions/result_set.py +153 -0
  52. zepben/ewb/database/sqlite/network/__init__.py +4 -0
  53. zepben/ewb/database/sqlite/network/network_cim_reader.py +3167 -0
  54. zepben/ewb/database/sqlite/network/network_cim_writer.py +2561 -0
  55. zepben/ewb/database/sqlite/network/network_database_reader.py +175 -0
  56. zepben/ewb/database/sqlite/network/network_database_tables.py +242 -0
  57. zepben/ewb/database/sqlite/network/network_database_writer.py +43 -0
  58. zepben/ewb/database/sqlite/network/network_service_reader.py +265 -0
  59. zepben/ewb/database/sqlite/network/network_service_writer.py +209 -0
  60. zepben/ewb/database/sqlite/tables/__init__.py +4 -0
  61. zepben/ewb/database/sqlite/tables/associations/__init__.py +4 -0
  62. zepben/ewb/database/sqlite/tables/associations/loop_substation_relationship.py +17 -0
  63. zepben/ewb/database/sqlite/tables/associations/table_asset_organisation_roles_assets.py +40 -0
  64. zepben/ewb/database/sqlite/tables/associations/table_assets_power_system_resources.py +41 -0
  65. zepben/ewb/database/sqlite/tables/associations/table_battery_units_battery_controls.py +40 -0
  66. zepben/ewb/database/sqlite/tables/associations/table_circuits_substations.py +40 -0
  67. zepben/ewb/database/sqlite/tables/associations/table_circuits_terminals.py +40 -0
  68. zepben/ewb/database/sqlite/tables/associations/table_customer_agreements_pricing_structures.py +40 -0
  69. zepben/ewb/database/sqlite/tables/associations/table_end_devices_end_device_functions.py +40 -0
  70. zepben/ewb/database/sqlite/tables/associations/table_equipment_equipment_containers.py +40 -0
  71. zepben/ewb/database/sqlite/tables/associations/table_equipment_operational_restrictions.py +40 -0
  72. zepben/ewb/database/sqlite/tables/associations/table_equipment_usage_points.py +40 -0
  73. zepben/ewb/database/sqlite/tables/associations/table_loops_substations.py +43 -0
  74. zepben/ewb/database/sqlite/tables/associations/table_pricing_structures_tariffs.py +40 -0
  75. zepben/ewb/database/sqlite/tables/associations/table_protection_relay_functions_protected_switches.py +40 -0
  76. zepben/ewb/database/sqlite/tables/associations/table_protection_relay_functions_sensors.py +40 -0
  77. zepben/ewb/database/sqlite/tables/associations/table_protection_relay_schemes_protection_relay_functions.py +40 -0
  78. zepben/ewb/database/sqlite/tables/associations/table_synchronous_machines_reactive_capability_curves.py +39 -0
  79. zepben/ewb/database/sqlite/tables/associations/table_usage_points_end_devices.py +40 -0
  80. zepben/ewb/database/sqlite/tables/exceptions.py +10 -0
  81. zepben/ewb/database/sqlite/tables/extensions/__init__.py +4 -0
  82. zepben/ewb/database/sqlite/tables/extensions/iec61968/__init__.py +4 -0
  83. zepben/ewb/database/sqlite/tables/extensions/iec61968/assetinfo/__init__.py +4 -0
  84. zepben/ewb/database/sqlite/tables/extensions/iec61968/assetinfo/table_reclose_delays.py +38 -0
  85. zepben/ewb/database/sqlite/tables/extensions/iec61968/assetinfo/table_relay_info.py +21 -0
  86. zepben/ewb/database/sqlite/tables/extensions/iec61968/metering/__init__.py +4 -0
  87. zepben/ewb/database/sqlite/tables/extensions/iec61968/metering/table_pan_demand_response_functions.py +21 -0
  88. zepben/ewb/database/sqlite/tables/extensions/iec61970/__init__.py +4 -0
  89. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/__init__.py +4 -0
  90. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/core/__init__.py +4 -0
  91. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/core/table_sites.py +15 -0
  92. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/feeder/__init__.py +4 -0
  93. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/feeder/table_loops.py +15 -0
  94. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/feeder/table_lv_feeders.py +20 -0
  95. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/generation/__init__.py +4 -0
  96. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/generation/production/__init__.py +4 -0
  97. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/generation/production/table_ev_charging_units.py +15 -0
  98. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/__init__.py +4 -0
  99. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/table_distance_relays.py +28 -0
  100. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/table_protection_relay_function_thresholds.py +36 -0
  101. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/table_protection_relay_function_time_limits.py +34 -0
  102. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/table_protection_relay_functions.py +24 -0
  103. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/table_protection_relay_schemes.py +20 -0
  104. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/table_protection_relay_systems.py +20 -0
  105. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/table_voltage_relays.py +15 -0
  106. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/wires/__init__.py +4 -0
  107. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/wires/table_battery_controls.py +23 -0
  108. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/wires/table_power_transformer_end_ratings.py +34 -0
  109. zepben/ewb/database/sqlite/tables/iec61968/__init__.py +4 -0
  110. zepben/ewb/database/sqlite/tables/iec61968/assetinfo/__init__.py +4 -0
  111. zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_cable_info.py +15 -0
  112. zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_no_load_tests.py +24 -0
  113. zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_open_circuit_tests.py +24 -0
  114. zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_overhead_wire_info.py +15 -0
  115. zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_power_transformer_info.py +15 -0
  116. zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_short_circuit_tests.py +29 -0
  117. zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_shunt_compensator_info.py +23 -0
  118. zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_switch_info.py +20 -0
  119. zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_transformer_end_info.py +46 -0
  120. zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_transformer_tank_info.py +27 -0
  121. zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_transformer_test.py +19 -0
  122. zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_wire_info.py +19 -0
  123. zepben/ewb/database/sqlite/tables/iec61968/assets/__init__.py +4 -0
  124. zepben/ewb/database/sqlite/tables/iec61968/assets/table_asset_containers.py +14 -0
  125. zepben/ewb/database/sqlite/tables/iec61968/assets/table_asset_functions.py +14 -0
  126. zepben/ewb/database/sqlite/tables/iec61968/assets/table_asset_info.py +14 -0
  127. zepben/ewb/database/sqlite/tables/iec61968/assets/table_asset_organisation_roles.py +14 -0
  128. zepben/ewb/database/sqlite/tables/iec61968/assets/table_asset_owners.py +15 -0
  129. zepben/ewb/database/sqlite/tables/iec61968/assets/table_assets.py +18 -0
  130. zepben/ewb/database/sqlite/tables/iec61968/assets/table_streetlights.py +22 -0
  131. zepben/ewb/database/sqlite/tables/iec61968/assets/table_structures.py +14 -0
  132. zepben/ewb/database/sqlite/tables/iec61968/common/__init__.py +4 -0
  133. zepben/ewb/database/sqlite/tables/iec61968/common/table_agreements.py +14 -0
  134. zepben/ewb/database/sqlite/tables/iec61968/common/table_documents.py +23 -0
  135. zepben/ewb/database/sqlite/tables/iec61968/common/table_location_street_address_field.py +18 -0
  136. zepben/ewb/database/sqlite/tables/iec61968/common/table_location_street_addresses.py +33 -0
  137. zepben/ewb/database/sqlite/tables/iec61968/common/table_locations.py +15 -0
  138. zepben/ewb/database/sqlite/tables/iec61968/common/table_organisation_roles.py +18 -0
  139. zepben/ewb/database/sqlite/tables/iec61968/common/table_organisations.py +15 -0
  140. zepben/ewb/database/sqlite/tables/iec61968/common/table_position_points.py +30 -0
  141. zepben/ewb/database/sqlite/tables/iec61968/common/table_street_addresses.py +26 -0
  142. zepben/ewb/database/sqlite/tables/iec61968/common/table_town_details.py +19 -0
  143. zepben/ewb/database/sqlite/tables/iec61968/customers/__init__.py +4 -0
  144. zepben/ewb/database/sqlite/tables/iec61968/customers/table_customer_agreements.py +27 -0
  145. zepben/ewb/database/sqlite/tables/iec61968/customers/table_customers.py +22 -0
  146. zepben/ewb/database/sqlite/tables/iec61968/customers/table_pricing_structures.py +15 -0
  147. zepben/ewb/database/sqlite/tables/iec61968/customers/table_tariffs.py +15 -0
  148. zepben/ewb/database/sqlite/tables/iec61968/infiec61968/__init__.py +4 -0
  149. zepben/ewb/database/sqlite/tables/iec61968/infiec61968/infassetinfo/__init__.py +4 -0
  150. zepben/ewb/database/sqlite/tables/iec61968/infiec61968/infassetinfo/table_current_transformer_info.py +33 -0
  151. zepben/ewb/database/sqlite/tables/iec61968/infiec61968/infassetinfo/table_potential_transformer_info.py +26 -0
  152. zepben/ewb/database/sqlite/tables/iec61968/infiec61968/infassets/__init__.py +4 -0
  153. zepben/ewb/database/sqlite/tables/iec61968/infiec61968/infassets/table_poles.py +20 -0
  154. zepben/ewb/database/sqlite/tables/iec61968/metering/__init__.py +4 -0
  155. zepben/ewb/database/sqlite/tables/iec61968/metering/table_end_device_functions.py +18 -0
  156. zepben/ewb/database/sqlite/tables/iec61968/metering/table_end_devices.py +19 -0
  157. zepben/ewb/database/sqlite/tables/iec61968/metering/table_meters.py +15 -0
  158. zepben/ewb/database/sqlite/tables/iec61968/metering/table_usage_points.py +23 -0
  159. zepben/ewb/database/sqlite/tables/iec61968/operations/__init__.py +4 -0
  160. zepben/ewb/database/sqlite/tables/iec61968/operations/table_operational_restrictions.py +15 -0
  161. zepben/ewb/database/sqlite/tables/iec61970/__init__.py +4 -0
  162. zepben/ewb/database/sqlite/tables/iec61970/base/__init__.py +4 -0
  163. zepben/ewb/database/sqlite/tables/iec61970/base/auxiliaryequipment/__init__.py +4 -0
  164. zepben/ewb/database/sqlite/tables/iec61970/base/auxiliaryequipment/table_auxiliary_equipment.py +18 -0
  165. zepben/ewb/database/sqlite/tables/iec61970/base/auxiliaryequipment/table_current_transformers.py +21 -0
  166. zepben/ewb/database/sqlite/tables/iec61970/base/auxiliaryequipment/table_fault_indicators.py +15 -0
  167. zepben/ewb/database/sqlite/tables/iec61970/base/auxiliaryequipment/table_potential_transformers.py +21 -0
  168. zepben/ewb/database/sqlite/tables/iec61970/base/auxiliaryequipment/table_sensors.py +14 -0
  169. zepben/ewb/database/sqlite/tables/iec61970/base/core/__init__.py +4 -0
  170. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_ac_dc_terminals.py +14 -0
  171. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_base_voltages.py +20 -0
  172. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_conducting_equipment.py +18 -0
  173. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_connectivity_node_containers.py +14 -0
  174. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_connectivity_nodes.py +15 -0
  175. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_curve_data.py +46 -0
  176. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_curves.py +17 -0
  177. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_equipment.py +20 -0
  178. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_equipment_containers.py +14 -0
  179. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_feeders.py +28 -0
  180. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_geographical_regions.py +15 -0
  181. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_identified_objects.py +29 -0
  182. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_name_types.py +28 -0
  183. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_names.py +36 -0
  184. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_power_system_resources.py +19 -0
  185. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_sub_geographical_regions.py +27 -0
  186. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_substations.py +27 -0
  187. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_terminals.py +35 -0
  188. zepben/ewb/database/sqlite/tables/iec61970/base/diagramlayout/__init__.py +4 -0
  189. zepben/ewb/database/sqlite/tables/iec61970/base/diagramlayout/table_diagram_object_points.py +35 -0
  190. zepben/ewb/database/sqlite/tables/iec61970/base/diagramlayout/table_diagram_objects.py +31 -0
  191. zepben/ewb/database/sqlite/tables/iec61970/base/diagramlayout/table_diagrams.py +21 -0
  192. zepben/ewb/database/sqlite/tables/iec61970/base/equivalents/__init__.py +4 -0
  193. zepben/ewb/database/sqlite/tables/iec61970/base/equivalents/table_equivalent_branches.py +35 -0
  194. zepben/ewb/database/sqlite/tables/iec61970/base/equivalents/table_equivalent_equipment.py +14 -0
  195. zepben/ewb/database/sqlite/tables/iec61970/base/generation/__init__.py +4 -0
  196. zepben/ewb/database/sqlite/tables/iec61970/base/generation/production/__init__.py +4 -0
  197. zepben/ewb/database/sqlite/tables/iec61970/base/generation/production/table_battery_units.py +22 -0
  198. zepben/ewb/database/sqlite/tables/iec61970/base/generation/production/table_photo_voltaic_units.py +15 -0
  199. zepben/ewb/database/sqlite/tables/iec61970/base/generation/production/table_power_electronics_units.py +26 -0
  200. zepben/ewb/database/sqlite/tables/iec61970/base/generation/production/table_power_electronics_wind_units.py +15 -0
  201. zepben/ewb/database/sqlite/tables/iec61970/base/meas/__init__.py +4 -0
  202. zepben/ewb/database/sqlite/tables/iec61970/base/meas/table_accumulators.py +15 -0
  203. zepben/ewb/database/sqlite/tables/iec61970/base/meas/table_analogs.py +20 -0
  204. zepben/ewb/database/sqlite/tables/iec61970/base/meas/table_controls.py +20 -0
  205. zepben/ewb/database/sqlite/tables/iec61970/base/meas/table_discretes.py +15 -0
  206. zepben/ewb/database/sqlite/tables/iec61970/base/meas/table_io_points.py +14 -0
  207. zepben/ewb/database/sqlite/tables/iec61970/base/meas/table_measurements.py +30 -0
  208. zepben/ewb/database/sqlite/tables/iec61970/base/protection/__init__.py +4 -0
  209. zepben/ewb/database/sqlite/tables/iec61970/base/protection/table_current_relays.py +22 -0
  210. zepben/ewb/database/sqlite/tables/iec61970/base/scada/__init__.py +4 -0
  211. zepben/ewb/database/sqlite/tables/iec61970/base/scada/table_remote_controls.py +20 -0
  212. zepben/ewb/database/sqlite/tables/iec61970/base/scada/table_remote_points.py +14 -0
  213. zepben/ewb/database/sqlite/tables/iec61970/base/scada/table_remote_sources.py +20 -0
  214. zepben/ewb/database/sqlite/tables/iec61970/base/wires/__init__.py +4 -0
  215. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_ac_line_segments.py +20 -0
  216. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_breakers.py +20 -0
  217. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_busbar_sections.py +15 -0
  218. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_clamps.py +23 -0
  219. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_conductors.py +21 -0
  220. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_connectors.py +14 -0
  221. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_cuts.py +23 -0
  222. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_disconnectors.py +15 -0
  223. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_earth_fault_compensators.py +22 -0
  224. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_energy_connections.py +14 -0
  225. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_energy_consumer_phases.py +37 -0
  226. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_energy_consumers.py +26 -0
  227. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_energy_source_phases.py +33 -0
  228. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_energy_sources.py +44 -0
  229. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_fuses.py +20 -0
  230. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_ground_disconnectors.py +15 -0
  231. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_grounding_impedances.py +24 -0
  232. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_grounds.py +15 -0
  233. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_jumpers.py +15 -0
  234. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_junctions.py +15 -0
  235. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_linear_shunt_compensators.py +23 -0
  236. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_lines.py +14 -0
  237. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_load_break_switches.py +15 -0
  238. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_per_length_impedances.py +14 -0
  239. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_per_length_line_parameters.py +14 -0
  240. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_per_length_phase_impedances.py +18 -0
  241. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_per_length_sequence_impedances.py +27 -0
  242. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_petersen_coils.py +27 -0
  243. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_phase_impedance_data.py +52 -0
  244. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_power_electronics_connection_phases.py +30 -0
  245. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_power_electronics_connections.py +50 -0
  246. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_power_transformer_ends.py +43 -0
  247. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_power_transformers.py +24 -0
  248. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_protected_switches.py +18 -0
  249. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_ratio_tap_changers.py +28 -0
  250. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_reactive_capability_curves.py +18 -0
  251. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_reclosers.py +15 -0
  252. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_regulating_cond_eq.py +19 -0
  253. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_regulating_controls.py +29 -0
  254. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_rotating_machines.py +36 -0
  255. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_series_compensators.py +25 -0
  256. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_shunt_compensators.py +22 -0
  257. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_static_var_compensator.py +24 -0
  258. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_switches.py +21 -0
  259. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_synchronous_machines.py +95 -0
  260. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_tap_changer_controls.py +28 -0
  261. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_tap_changers.py +25 -0
  262. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_transformer_ends.py +30 -0
  263. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_transformer_star_impedances.py +32 -0
  264. zepben/ewb/database/sqlite/tables/iec61970/infiec61970/__init__.py +4 -0
  265. zepben/ewb/database/sqlite/tables/iec61970/infiec61970/feeder/__init__.py +4 -0
  266. zepben/ewb/database/sqlite/tables/iec61970/infiec61970/feeder/table_circuits.py +27 -0
  267. zepben/ewb/database/sqlite/tables/sqlite_table.py +45 -0
  268. zepben/ewb/database/sqlite/tables/table_metadata_data_sources.py +21 -0
  269. zepben/ewb/database/sqlite/tables/table_version.py +39 -0
  270. zepben/ewb/dataclassy/__init__.py +15 -0
  271. zepben/ewb/dataclassy/dataclass.py +192 -0
  272. zepben/ewb/dataclassy/decorator.py +35 -0
  273. zepben/ewb/dataclassy/functions.py +80 -0
  274. zepben/ewb/examples/__init__.py +6 -0
  275. zepben/ewb/examples/simple_test_network.py +158 -0
  276. zepben/ewb/exceptions.py +52 -0
  277. zepben/ewb/model/__init__.py +4 -0
  278. zepben/ewb/model/busbranch/__init__.py +4 -0
  279. zepben/ewb/model/busbranch/bus_branch.py +1051 -0
  280. zepben/ewb/model/cim/__init__.py +4 -0
  281. zepben/ewb/model/cim/extensions/__init__.py +4 -0
  282. zepben/ewb/model/cim/extensions/iec61968/__init__.py +4 -0
  283. zepben/ewb/model/cim/extensions/iec61968/assetinfo/__init__.py +4 -0
  284. zepben/ewb/model/cim/extensions/iec61968/assetinfo/relay_info.py +128 -0
  285. zepben/ewb/model/cim/extensions/iec61968/metering/__init__.py +4 -0
  286. zepben/ewb/model/cim/extensions/iec61968/metering/pan_demand_reponse_function.py +112 -0
  287. zepben/ewb/model/cim/extensions/iec61970/__init__.py +4 -0
  288. zepben/ewb/model/cim/extensions/iec61970/base/__init__.py +4 -0
  289. zepben/ewb/model/cim/extensions/iec61970/base/core/__init__.py +4 -0
  290. zepben/ewb/model/cim/extensions/iec61970/base/core/site.py +37 -0
  291. zepben/ewb/model/cim/extensions/iec61970/base/feeder/__init__.py +4 -0
  292. zepben/ewb/model/cim/extensions/iec61970/base/feeder/loop.py +207 -0
  293. zepben/ewb/model/cim/extensions/iec61970/base/feeder/lv_feeder.py +258 -0
  294. zepben/ewb/model/cim/extensions/iec61970/base/generation/__init__.py +4 -0
  295. zepben/ewb/model/cim/extensions/iec61970/base/generation/production/__init__.py +4 -0
  296. zepben/ewb/model/cim/extensions/iec61970/base/generation/production/ev_charging_unit.py +18 -0
  297. zepben/ewb/model/cim/extensions/iec61970/base/protection/__init__.py +4 -0
  298. zepben/ewb/model/cim/extensions/iec61970/base/protection/distance_relay.py +69 -0
  299. zepben/ewb/model/cim/extensions/iec61970/base/protection/power_direction_kind.py +36 -0
  300. zepben/ewb/model/cim/extensions/iec61970/base/protection/protection_kind.py +112 -0
  301. zepben/ewb/model/cim/extensions/iec61970/base/protection/protection_relay_function.py +448 -0
  302. zepben/ewb/model/cim/extensions/iec61970/base/protection/protection_relay_scheme.py +97 -0
  303. zepben/ewb/model/cim/extensions/iec61970/base/protection/protection_relay_system.py +97 -0
  304. zepben/ewb/model/cim/extensions/iec61970/base/protection/relay_setting.py +35 -0
  305. zepben/ewb/model/cim/extensions/iec61970/base/protection/voltage_relay.py +20 -0
  306. zepben/ewb/model/cim/extensions/iec61970/base/wires/__init__.py +4 -0
  307. zepben/ewb/model/cim/extensions/iec61970/base/wires/battery_control.py +36 -0
  308. zepben/ewb/model/cim/extensions/iec61970/base/wires/battery_control_mode.py +83 -0
  309. zepben/ewb/model/cim/extensions/iec61970/base/wires/transformer_cooling_type.py +57 -0
  310. zepben/ewb/model/cim/extensions/iec61970/base/wires/transformer_end_rated_s.py +26 -0
  311. zepben/ewb/model/cim/extensions/iec61970/base/wires/vector_group.py +293 -0
  312. zepben/ewb/model/cim/extensions/zbex.py +17 -0
  313. zepben/ewb/model/cim/iec61968/__init__.py +4 -0
  314. zepben/ewb/model/cim/iec61968/assetinfo/__init__.py +4 -0
  315. zepben/ewb/model/cim/iec61968/assetinfo/cable_info.py +15 -0
  316. zepben/ewb/model/cim/iec61968/assetinfo/no_load_test.py +42 -0
  317. zepben/ewb/model/cim/iec61968/assetinfo/open_circuit_test.py +42 -0
  318. zepben/ewb/model/cim/iec61968/assetinfo/overhead_wire_info.py +15 -0
  319. zepben/ewb/model/cim/iec61968/assetinfo/power_transformer_info.py +103 -0
  320. zepben/ewb/model/cim/iec61968/assetinfo/short_circuit_test.py +67 -0
  321. zepben/ewb/model/cim/iec61968/assetinfo/shunt_compensator_info.py +26 -0
  322. zepben/ewb/model/cim/iec61968/assetinfo/switch_info.py +17 -0
  323. zepben/ewb/model/cim/iec61968/assetinfo/transformer_end_info.py +137 -0
  324. zepben/ewb/model/cim/iec61968/assetinfo/transformer_tank_info.py +108 -0
  325. zepben/ewb/model/cim/iec61968/assetinfo/transformer_test.py +26 -0
  326. zepben/ewb/model/cim/iec61968/assetinfo/wire_info.py +24 -0
  327. zepben/ewb/model/cim/iec61968/assetinfo/wire_material_kind.py +57 -0
  328. zepben/ewb/model/cim/iec61968/assets/__init__.py +4 -0
  329. zepben/ewb/model/cim/iec61968/assets/asset.py +154 -0
  330. zepben/ewb/model/cim/iec61968/assets/asset_container.py +16 -0
  331. zepben/ewb/model/cim/iec61968/assets/asset_function.py +15 -0
  332. zepben/ewb/model/cim/iec61968/assets/asset_info.py +19 -0
  333. zepben/ewb/model/cim/iec61968/assets/asset_organisation_role.py +13 -0
  334. zepben/ewb/model/cim/iec61968/assets/asset_owner.py +13 -0
  335. zepben/ewb/model/cim/iec61968/assets/streetlight.py +29 -0
  336. zepben/ewb/model/cim/iec61968/assets/structure.py +16 -0
  337. zepben/ewb/model/cim/iec61968/common/__init__.py +4 -0
  338. zepben/ewb/model/cim/iec61968/common/agreement.py +16 -0
  339. zepben/ewb/model/cim/iec61968/common/document.py +36 -0
  340. zepben/ewb/model/cim/iec61968/common/location.py +129 -0
  341. zepben/ewb/model/cim/iec61968/common/organisation.py +15 -0
  342. zepben/ewb/model/cim/iec61968/common/organisation_role.py +22 -0
  343. zepben/ewb/model/cim/iec61968/common/position_point.py +44 -0
  344. zepben/ewb/model/cim/iec61968/common/street_address.py +28 -0
  345. zepben/ewb/model/cim/iec61968/common/street_detail.py +46 -0
  346. zepben/ewb/model/cim/iec61968/common/town_detail.py +25 -0
  347. zepben/ewb/model/cim/iec61968/customers/__init__.py +4 -0
  348. zepben/ewb/model/cim/iec61968/customers/customer.py +93 -0
  349. zepben/ewb/model/cim/iec61968/customers/customer_agreement.py +107 -0
  350. zepben/ewb/model/cim/iec61968/customers/customer_kind.py +69 -0
  351. zepben/ewb/model/cim/iec61968/customers/pricing_structure.py +88 -0
  352. zepben/ewb/model/cim/iec61968/customers/tariff.py +18 -0
  353. zepben/ewb/model/cim/iec61968/infiec61968/__init__.py +4 -0
  354. zepben/ewb/model/cim/iec61968/infiec61968/infassetinfo/__init__.py +4 -0
  355. zepben/ewb/model/cim/iec61968/infiec61968/infassetinfo/current_transformer_info.py +51 -0
  356. zepben/ewb/model/cim/iec61968/infiec61968/infassetinfo/potential_transformer_info.py +33 -0
  357. zepben/ewb/model/cim/iec61968/infiec61968/infassetinfo/transformer_construction_kind.py +69 -0
  358. zepben/ewb/model/cim/iec61968/infiec61968/infassetinfo/transformer_function_kind.py +45 -0
  359. zepben/ewb/model/cim/iec61968/infiec61968/infassets/__init__.py +4 -0
  360. zepben/ewb/model/cim/iec61968/infiec61968/infassets/pole.py +87 -0
  361. zepben/ewb/model/cim/iec61968/infiec61968/infassets/streetlight_lamp_kind.py +27 -0
  362. zepben/ewb/model/cim/iec61968/infiec61968/infcommon/__init__.py +4 -0
  363. zepben/ewb/model/cim/iec61968/infiec61968/infcommon/ratio.py +34 -0
  364. zepben/ewb/model/cim/iec61968/metering/__init__.py +4 -0
  365. zepben/ewb/model/cim/iec61968/metering/controlled_appliance.py +152 -0
  366. zepben/ewb/model/cim/iec61968/metering/end_device.py +165 -0
  367. zepben/ewb/model/cim/iec61968/metering/end_device_function.py +17 -0
  368. zepben/ewb/model/cim/iec61968/metering/end_device_function_kind.py +48 -0
  369. zepben/ewb/model/cim/iec61968/metering/meter.py +28 -0
  370. zepben/ewb/model/cim/iec61968/metering/usage_point.py +186 -0
  371. zepben/ewb/model/cim/iec61968/operations/__init__.py +4 -0
  372. zepben/ewb/model/cim/iec61968/operations/operational_restriction.py +92 -0
  373. zepben/ewb/model/cim/iec61970/__init__.py +4 -0
  374. zepben/ewb/model/cim/iec61970/base/__init__.py +4 -0
  375. zepben/ewb/model/cim/iec61970/base/auxiliaryequipment/__init__.py +4 -0
  376. zepben/ewb/model/cim/iec61970/base/auxiliaryequipment/auxiliary_equipment.py +24 -0
  377. zepben/ewb/model/cim/iec61970/base/auxiliaryequipment/current_transformer.py +37 -0
  378. zepben/ewb/model/cim/iec61970/base/auxiliaryequipment/fault_indicator.py +18 -0
  379. zepben/ewb/model/cim/iec61970/base/auxiliaryequipment/potential_transformer.py +38 -0
  380. zepben/ewb/model/cim/iec61970/base/auxiliaryequipment/potential_transformer_kind.py +30 -0
  381. zepben/ewb/model/cim/iec61970/base/auxiliaryequipment/sensor.py +92 -0
  382. zepben/ewb/model/cim/iec61970/base/core/__init__.py +4 -0
  383. zepben/ewb/model/cim/iec61970/base/core/ac_dc_terminal.py +16 -0
  384. zepben/ewb/model/cim/iec61970/base/core/base_voltage.py +17 -0
  385. zepben/ewb/model/cim/iec61970/base/core/conducting_equipment.py +198 -0
  386. zepben/ewb/model/cim/iec61970/base/core/connectivity_node.py +105 -0
  387. zepben/ewb/model/cim/iec61970/base/core/connectivity_node_container.py +15 -0
  388. zepben/ewb/model/cim/iec61970/base/core/curve.py +125 -0
  389. zepben/ewb/model/cim/iec61970/base/core/curve_data.py +29 -0
  390. zepben/ewb/model/cim/iec61970/base/core/equipment.py +366 -0
  391. zepben/ewb/model/cim/iec61970/base/core/equipment_container.py +199 -0
  392. zepben/ewb/model/cim/iec61970/base/core/feeder.py +260 -0
  393. zepben/ewb/model/cim/iec61970/base/core/geographical_region.py +82 -0
  394. zepben/ewb/model/cim/iec61970/base/core/identified_object.py +239 -0
  395. zepben/ewb/model/cim/iec61970/base/core/name.py +36 -0
  396. zepben/ewb/model/cim/iec61970/base/core/name_type.py +203 -0
  397. zepben/ewb/model/cim/iec61970/base/core/phase_code.py +202 -0
  398. zepben/ewb/model/cim/iec61970/base/core/power_system_resource.py +106 -0
  399. zepben/ewb/model/cim/iec61970/base/core/sub_geographical_region.py +93 -0
  400. zepben/ewb/model/cim/iec61970/base/core/substation.py +277 -0
  401. zepben/ewb/model/cim/iec61970/base/core/terminal.py +171 -0
  402. zepben/ewb/model/cim/iec61970/base/diagramlayout/__init__.py +4 -0
  403. zepben/ewb/model/cim/iec61970/base/diagramlayout/diagram.py +109 -0
  404. zepben/ewb/model/cim/iec61970/base/diagramlayout/diagram_object.py +160 -0
  405. zepben/ewb/model/cim/iec61970/base/diagramlayout/diagram_object_point.py +25 -0
  406. zepben/ewb/model/cim/iec61970/base/diagramlayout/diagram_style.py +28 -0
  407. zepben/ewb/model/cim/iec61970/base/diagramlayout/orientation_kind.py +29 -0
  408. zepben/ewb/model/cim/iec61970/base/domain/__init__.py +4 -0
  409. zepben/ewb/model/cim/iec61970/base/domain/unit_symbol.py +494 -0
  410. zepben/ewb/model/cim/iec61970/base/equivalents/__init__.py +4 -0
  411. zepben/ewb/model/cim/iec61970/base/equivalents/equivalent_branch.py +113 -0
  412. zepben/ewb/model/cim/iec61970/base/equivalents/equivalent_equipment.py +15 -0
  413. zepben/ewb/model/cim/iec61970/base/generation/__init__.py +4 -0
  414. zepben/ewb/model/cim/iec61970/base/generation/production/__init__.py +4 -0
  415. zepben/ewb/model/cim/iec61970/base/generation/production/battery_state_kind.py +39 -0
  416. zepben/ewb/model/cim/iec61970/base/generation/production/battery_unit.py +108 -0
  417. zepben/ewb/model/cim/iec61970/base/generation/production/photo_voltaic_unit.py +13 -0
  418. zepben/ewb/model/cim/iec61970/base/generation/production/power_electronics_unit.py +28 -0
  419. zepben/ewb/model/cim/iec61970/base/generation/production/power_electronics_wind_unit.py +13 -0
  420. zepben/ewb/model/cim/iec61970/base/meas/__init__.py +4 -0
  421. zepben/ewb/model/cim/iec61970/base/meas/accumulator.py +13 -0
  422. zepben/ewb/model/cim/iec61970/base/meas/accumulator_value.py +20 -0
  423. zepben/ewb/model/cim/iec61970/base/meas/analog.py +18 -0
  424. zepben/ewb/model/cim/iec61970/base/meas/analog_value.py +20 -0
  425. zepben/ewb/model/cim/iec61970/base/meas/control.py +26 -0
  426. zepben/ewb/model/cim/iec61970/base/meas/discrete.py +13 -0
  427. zepben/ewb/model/cim/iec61970/base/meas/discrete_value.py +20 -0
  428. zepben/ewb/model/cim/iec61970/base/meas/iopoint.py +16 -0
  429. zepben/ewb/model/cim/iec61970/base/meas/measurement.py +60 -0
  430. zepben/ewb/model/cim/iec61970/base/meas/measurement_value.py +21 -0
  431. zepben/ewb/model/cim/iec61970/base/protection/__init__.py +4 -0
  432. zepben/ewb/model/cim/iec61970/base/protection/current_relay.py +23 -0
  433. zepben/ewb/model/cim/iec61970/base/scada/__init__.py +4 -0
  434. zepben/ewb/model/cim/iec61970/base/scada/remote_control.py +22 -0
  435. zepben/ewb/model/cim/iec61970/base/scada/remote_point.py +16 -0
  436. zepben/ewb/model/cim/iec61970/base/scada/remote_source.py +22 -0
  437. zepben/ewb/model/cim/iec61970/base/wires/__init__.py +4 -0
  438. zepben/ewb/model/cim/iec61970/base/wires/ac_line_segment.py +214 -0
  439. zepben/ewb/model/cim/iec61970/base/wires/breaker.py +32 -0
  440. zepben/ewb/model/cim/iec61970/base/wires/busbar_section.py +19 -0
  441. zepben/ewb/model/cim/iec61970/base/wires/clamp.py +32 -0
  442. zepben/ewb/model/cim/iec61970/base/wires/conductor.py +49 -0
  443. zepben/ewb/model/cim/iec61970/base/wires/connector.py +16 -0
  444. zepben/ewb/model/cim/iec61970/base/wires/cut.py +36 -0
  445. zepben/ewb/model/cim/iec61970/base/wires/disconnector.py +17 -0
  446. zepben/ewb/model/cim/iec61970/base/wires/earth_fault_compensator.py +21 -0
  447. zepben/ewb/model/cim/iec61970/base/wires/energy_connection.py +15 -0
  448. zepben/ewb/model/cim/iec61970/base/wires/energy_consumer.py +107 -0
  449. zepben/ewb/model/cim/iec61970/base/wires/energy_consumer_phase.py +56 -0
  450. zepben/ewb/model/cim/iec61970/base/wires/energy_source.py +172 -0
  451. zepben/ewb/model/cim/iec61970/base/wires/energy_source_phase.py +45 -0
  452. zepben/ewb/model/cim/iec61970/base/wires/fuse.py +23 -0
  453. zepben/ewb/model/cim/iec61970/base/wires/ground.py +15 -0
  454. zepben/ewb/model/cim/iec61970/base/wires/ground_disconnector.py +15 -0
  455. zepben/ewb/model/cim/iec61970/base/wires/grounding_impedance.py +19 -0
  456. zepben/ewb/model/cim/iec61970/base/wires/jumper.py +16 -0
  457. zepben/ewb/model/cim/iec61970/base/wires/junction.py +15 -0
  458. zepben/ewb/model/cim/iec61970/base/wires/line.py +13 -0
  459. zepben/ewb/model/cim/iec61970/base/wires/linear_shunt_compensator.py +26 -0
  460. zepben/ewb/model/cim/iec61970/base/wires/load_break_switch.py +14 -0
  461. zepben/ewb/model/cim/iec61970/base/wires/per_length_impedance.py +13 -0
  462. zepben/ewb/model/cim/iec61970/base/wires/per_length_line_parameter.py +13 -0
  463. zepben/ewb/model/cim/iec61970/base/wires/per_length_phase_impedance.py +99 -0
  464. zepben/ewb/model/cim/iec61970/base/wires/per_length_sequence_impedance.py +43 -0
  465. zepben/ewb/model/cim/iec61970/base/wires/petersen_coil.py +22 -0
  466. zepben/ewb/model/cim/iec61970/base/wires/phase_impedance_data.py +37 -0
  467. zepben/ewb/model/cim/iec61970/base/wires/phase_shunt_connection_kind.py +40 -0
  468. zepben/ewb/model/cim/iec61970/base/wires/power_electronics_connection.py +524 -0
  469. zepben/ewb/model/cim/iec61970/base/wires/power_electronics_connection_phase.py +34 -0
  470. zepben/ewb/model/cim/iec61970/base/wires/power_transformer.py +217 -0
  471. zepben/ewb/model/cim/iec61970/base/wires/power_transformer_end.py +208 -0
  472. zepben/ewb/model/cim/iec61970/base/wires/protected_switch.py +96 -0
  473. zepben/ewb/model/cim/iec61970/base/wires/ratio_tap_changer.py +30 -0
  474. zepben/ewb/model/cim/iec61970/base/wires/reactive_capability_curve.py +16 -0
  475. zepben/ewb/model/cim/iec61970/base/wires/recloser.py +15 -0
  476. zepben/ewb/model/cim/iec61970/base/wires/regulating_cond_eq.py +45 -0
  477. zepben/ewb/model/cim/iec61970/base/wires/regulating_control.py +173 -0
  478. zepben/ewb/model/cim/iec61970/base/wires/regulating_control_mode_kind.py +48 -0
  479. zepben/ewb/model/cim/iec61970/base/wires/rotating_machine.py +36 -0
  480. zepben/ewb/model/cim/iec61970/base/wires/series_compensator.py +42 -0
  481. zepben/ewb/model/cim/iec61970/base/wires/shunt_compensator.py +59 -0
  482. zepben/ewb/model/cim/iec61970/base/wires/single_phase_kind.py +107 -0
  483. zepben/ewb/model/cim/iec61970/base/wires/static_var_compensator.py +40 -0
  484. zepben/ewb/model/cim/iec61970/base/wires/svc_control_mode.py +30 -0
  485. zepben/ewb/model/cim/iec61970/base/wires/switch.py +119 -0
  486. zepben/ewb/model/cim/iec61970/base/wires/synchronous_machine.py +168 -0
  487. zepben/ewb/model/cim/iec61970/base/wires/synchronous_machine_kind.py +46 -0
  488. zepben/ewb/model/cim/iec61970/base/wires/tap_changer.py +150 -0
  489. zepben/ewb/model/cim/iec61970/base/wires/tap_changer_control.py +49 -0
  490. zepben/ewb/model/cim/iec61970/base/wires/transformer_end.py +73 -0
  491. zepben/ewb/model/cim/iec61970/base/wires/transformer_star_impedance.py +48 -0
  492. zepben/ewb/model/cim/iec61970/base/wires/winding_connection.py +45 -0
  493. zepben/ewb/model/cim/iec61970/infiec61970/__init__.py +4 -0
  494. zepben/ewb/model/cim/iec61970/infiec61970/feeder/__init__.py +4 -0
  495. zepben/ewb/model/cim/iec61970/infiec61970/feeder/circuit.py +144 -0
  496. zepben/ewb/model/phases.py +168 -0
  497. zepben/ewb/model/resistance_reactance.py +40 -0
  498. zepben/ewb/services/__init__.py +4 -0
  499. zepben/ewb/services/common/__init__.py +16 -0
  500. zepben/ewb/services/common/base_service.py +383 -0
  501. zepben/ewb/services/common/base_service_comparator.py +394 -0
  502. zepben/ewb/services/common/difference.py +47 -0
  503. zepben/ewb/services/common/enum_mapper.py +55 -0
  504. zepben/ewb/services/common/meta/__init__.py +4 -0
  505. zepben/ewb/services/common/meta/data_source.py +16 -0
  506. zepben/ewb/services/common/meta/metadata_collection.py +28 -0
  507. zepben/ewb/services/common/meta/metadata_translations.py +47 -0
  508. zepben/ewb/services/common/meta/service_info.py +22 -0
  509. zepben/ewb/services/common/reference_resolvers.py +374 -0
  510. zepben/ewb/services/common/resolver.py +597 -0
  511. zepben/ewb/services/common/translator/__init__.py +4 -0
  512. zepben/ewb/services/common/translator/base_cim2proto.py +115 -0
  513. zepben/ewb/services/common/translator/base_proto2cim.py +146 -0
  514. zepben/ewb/services/common/translator/service_differences.py +81 -0
  515. zepben/ewb/services/common/translator/util.py +75 -0
  516. zepben/ewb/services/customer/__init__.py +4 -0
  517. zepben/ewb/services/customer/customer_service_comparator.py +52 -0
  518. zepben/ewb/services/customer/customers.py +23 -0
  519. zepben/ewb/services/customer/translator/__init__.py +21 -0
  520. zepben/ewb/services/customer/translator/customer_cim2proto.py +71 -0
  521. zepben/ewb/services/customer/translator/customer_enum_mappers.py +18 -0
  522. zepben/ewb/services/customer/translator/customer_proto2cim.py +87 -0
  523. zepben/ewb/services/diagram/__init__.py +4 -0
  524. zepben/ewb/services/diagram/diagram_service_comparator.py +39 -0
  525. zepben/ewb/services/diagram/diagrams.py +107 -0
  526. zepben/ewb/services/diagram/translator/__init__.py +11 -0
  527. zepben/ewb/services/diagram/translator/diagram_cim2proto.py +51 -0
  528. zepben/ewb/services/diagram/translator/diagram_enum_mappers.py +21 -0
  529. zepben/ewb/services/diagram/translator/diagram_proto2cim.py +61 -0
  530. zepben/ewb/services/measurement/__init__.py +4 -0
  531. zepben/ewb/services/measurement/measurements.py +35 -0
  532. zepben/ewb/services/measurement/translator/__init__.py +6 -0
  533. zepben/ewb/services/measurement/translator/measurement_cim2proto.py +42 -0
  534. zepben/ewb/services/measurement/translator/measurement_proto2cim.py +52 -0
  535. zepben/ewb/services/network/__init__.py +4 -0
  536. zepben/ewb/services/network/network_extensions.py +119 -0
  537. zepben/ewb/services/network/network_service.py +302 -0
  538. zepben/ewb/services/network/network_service_comparator.py +1322 -0
  539. zepben/ewb/services/network/network_state.py +36 -0
  540. zepben/ewb/services/network/tracing/__init__.py +4 -0
  541. zepben/ewb/services/network/tracing/busbranch_trace.py +36 -0
  542. zepben/ewb/services/network/tracing/connectivity/__init__.py +4 -0
  543. zepben/ewb/services/network/tracing/connectivity/connectivity_result.py +105 -0
  544. zepben/ewb/services/network/tracing/connectivity/nominal_phase_path.py +23 -0
  545. zepben/ewb/services/network/tracing/connectivity/phase_paths.py +70 -0
  546. zepben/ewb/services/network/tracing/connectivity/terminal_connectivity_connected.py +226 -0
  547. zepben/ewb/services/network/tracing/connectivity/terminal_connectivity_internal.py +64 -0
  548. zepben/ewb/services/network/tracing/connectivity/transformer_phase_paths.py +202 -0
  549. zepben/ewb/services/network/tracing/connectivity/xy_candidate_phase_paths.py +235 -0
  550. zepben/ewb/services/network/tracing/connectivity/xy_phase_step.py +24 -0
  551. zepben/ewb/services/network/tracing/feeder/__init__.py +4 -0
  552. zepben/ewb/services/network/tracing/feeder/assign_to_feeders.py +202 -0
  553. zepben/ewb/services/network/tracing/feeder/assign_to_lv_feeders.py +202 -0
  554. zepben/ewb/services/network/tracing/feeder/clear_direction.py +80 -0
  555. zepben/ewb/services/network/tracing/feeder/direction_status.py +133 -0
  556. zepben/ewb/services/network/tracing/feeder/feeder_direction.py +107 -0
  557. zepben/ewb/services/network/tracing/feeder/set_direction.py +143 -0
  558. zepben/ewb/services/network/tracing/find_swer_equipment.py +175 -0
  559. zepben/ewb/services/network/tracing/networktrace/__init__.py +4 -0
  560. zepben/ewb/services/network/tracing/networktrace/actions/__init__.py +4 -0
  561. zepben/ewb/services/network/tracing/networktrace/actions/equipment_tree_builder.py +104 -0
  562. zepben/ewb/services/network/tracing/networktrace/actions/tree_node.py +35 -0
  563. zepben/ewb/services/network/tracing/networktrace/compute_data.py +60 -0
  564. zepben/ewb/services/network/tracing/networktrace/conditions/__init__.py +4 -0
  565. zepben/ewb/services/network/tracing/networktrace/conditions/conditions.py +73 -0
  566. zepben/ewb/services/network/tracing/networktrace/conditions/direction_condition.py +63 -0
  567. zepben/ewb/services/network/tracing/networktrace/conditions/equipment_step_limit_condition.py +26 -0
  568. zepben/ewb/services/network/tracing/networktrace/conditions/equipment_type_step_limit_condition.py +44 -0
  569. zepben/ewb/services/network/tracing/networktrace/conditions/network_trace_queue_condition.py +67 -0
  570. zepben/ewb/services/network/tracing/networktrace/conditions/network_trace_stop_condition.py +65 -0
  571. zepben/ewb/services/network/tracing/networktrace/conditions/open_condition.py +39 -0
  572. zepben/ewb/services/network/tracing/networktrace/network_trace.py +433 -0
  573. zepben/ewb/services/network/tracing/networktrace/network_trace_action_type.py +42 -0
  574. zepben/ewb/services/network/tracing/networktrace/network_trace_queue_next.py +84 -0
  575. zepben/ewb/services/network/tracing/networktrace/network_trace_step.py +128 -0
  576. zepben/ewb/services/network/tracing/networktrace/network_trace_step_path_provider.py +351 -0
  577. zepben/ewb/services/network/tracing/networktrace/network_trace_tracker.py +39 -0
  578. zepben/ewb/services/network/tracing/networktrace/operators/__init__.py +14 -0
  579. zepben/ewb/services/network/tracing/networktrace/operators/equipment_container_state_operators.py +264 -0
  580. zepben/ewb/services/network/tracing/networktrace/operators/feeder_direction_state_operations.py +181 -0
  581. zepben/ewb/services/network/tracing/networktrace/operators/in_service_state_operators.py +76 -0
  582. zepben/ewb/services/network/tracing/networktrace/operators/network_state_operators.py +120 -0
  583. zepben/ewb/services/network/tracing/networktrace/operators/open_state_operators.py +104 -0
  584. zepben/ewb/services/network/tracing/networktrace/operators/phase_state_operators.py +56 -0
  585. zepben/ewb/services/network/tracing/networktrace/tracing.py +132 -0
  586. zepben/ewb/services/network/tracing/phases/__init__.py +4 -0
  587. zepben/ewb/services/network/tracing/phases/phase_inferrer.py +205 -0
  588. zepben/ewb/services/network/tracing/phases/phase_status.py +101 -0
  589. zepben/ewb/services/network/tracing/phases/remove_phases.py +143 -0
  590. zepben/ewb/services/network/tracing/phases/set_phases.py +490 -0
  591. zepben/ewb/services/network/tracing/traversal/__init__.py +4 -0
  592. zepben/ewb/services/network/tracing/traversal/context_value_computer.py +63 -0
  593. zepben/ewb/services/network/tracing/traversal/debug_logging.py +124 -0
  594. zepben/ewb/services/network/tracing/traversal/queue.py +112 -0
  595. zepben/ewb/services/network/tracing/traversal/queue_condition.py +75 -0
  596. zepben/ewb/services/network/tracing/traversal/step_action.py +83 -0
  597. zepben/ewb/services/network/tracing/traversal/step_context.py +59 -0
  598. zepben/ewb/services/network/tracing/traversal/stop_condition.py +57 -0
  599. zepben/ewb/services/network/tracing/traversal/traversal.py +634 -0
  600. zepben/ewb/services/network/tracing/traversal/traversal_condition.py +22 -0
  601. zepben/ewb/services/network/tracing/traversal/weighted_priority_queue.py +85 -0
  602. zepben/ewb/services/network/tracing/util.py +93 -0
  603. zepben/ewb/services/network/translator/__init__.py +392 -0
  604. zepben/ewb/services/network/translator/network_cim2proto.py +1867 -0
  605. zepben/ewb/services/network/translator/network_enum_mappers.py +78 -0
  606. zepben/ewb/services/network/translator/network_proto2cim.py +2201 -0
  607. zepben/ewb/services/services.py +48 -0
  608. zepben/ewb/streaming/__init__.py +4 -0
  609. zepben/ewb/streaming/data/__init__.py +4 -0
  610. zepben/ewb/streaming/data/current_state_event.py +314 -0
  611. zepben/ewb/streaming/data/current_state_event_batch.py +25 -0
  612. zepben/ewb/streaming/data/set_current_states_status.py +286 -0
  613. zepben/ewb/streaming/exceptions.py +14 -0
  614. zepben/ewb/streaming/get/__init__.py +4 -0
  615. zepben/ewb/streaming/get/consumer.py +209 -0
  616. zepben/ewb/streaming/get/customer_consumer.py +111 -0
  617. zepben/ewb/streaming/get/diagram_consumer.py +107 -0
  618. zepben/ewb/streaming/get/hierarchy/__init__.py +4 -0
  619. zepben/ewb/streaming/get/hierarchy/data.py +27 -0
  620. zepben/ewb/streaming/get/included_energized_containers.py +36 -0
  621. zepben/ewb/streaming/get/included_energizing_containers.py +36 -0
  622. zepben/ewb/streaming/get/network_consumer.py +870 -0
  623. zepben/ewb/streaming/get/query_network_state_client.py +64 -0
  624. zepben/ewb/streaming/get/query_network_state_service.py +94 -0
  625. zepben/ewb/streaming/grpc/__init__.py +4 -0
  626. zepben/ewb/streaming/grpc/auth_token_plugin.py +24 -0
  627. zepben/ewb/streaming/grpc/connect.py +209 -0
  628. zepben/ewb/streaming/grpc/grpc.py +107 -0
  629. zepben/ewb/streaming/grpc/grpc_channel_builder.py +190 -0
  630. zepben/ewb/streaming/mutations/__init__.py +4 -0
  631. zepben/ewb/streaming/mutations/update_network_state_client.py +80 -0
  632. zepben/ewb/streaming/mutations/update_network_state_service.py +61 -0
  633. zepben/ewb/testing/__init__.py +4 -0
  634. zepben/ewb/testing/test_network_builder.py +816 -0
  635. zepben/ewb/types.py +17 -0
  636. zepben/ewb/util.py +200 -0
  637. zepben_ewb-1.0.0.dist-info/METADATA +90 -0
  638. zepben_ewb-1.0.0.dist-info/RECORD +641 -0
  639. zepben_ewb-1.0.0.dist-info/WHEEL +5 -0
  640. zepben_ewb-1.0.0.dist-info/licenses/LICENSE +374 -0
  641. zepben_ewb-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1051 @@
1
+ # Copyright 2024 Zeppelin Bend Pty Ltd
2
+ # This Source Code Form is subject to the terms of the Mozilla Public
3
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ # file, You can obtain one at https://mozilla.org/MPL/2.0/.
5
+
6
+ from __future__ import annotations
7
+
8
+ __all__ = [
9
+ "BusBranchNetworkCreationValidator",
10
+ "BusBranchNetworkCreator",
11
+ "BusBranchNetworkCreationMappings",
12
+ "BusBranchNetworkCreationResult",
13
+ "TerminalGrouping"
14
+ ]
15
+
16
+ import abc
17
+ from collections import Counter
18
+ from dataclasses import dataclass, field
19
+ from functools import reduce
20
+ from typing import Set, Tuple, FrozenSet, Dict, Callable, Union, TypeVar, Any, List, Generic, Optional, Iterable, TYPE_CHECKING
21
+
22
+ from zepben.ewb import EquivalentBranch, Traversal
23
+ from zepben.ewb.model.cim.iec61970.base.core.conducting_equipment import ConductingEquipment
24
+ from zepben.ewb.model.cim.iec61970.base.core.terminal import Terminal
25
+ from zepben.ewb.model.cim.iec61970.base.wires.ac_line_segment import AcLineSegment
26
+ from zepben.ewb.model.cim.iec61970.base.wires.busbar_section import BusbarSection
27
+ from zepben.ewb.model.cim.iec61970.base.wires.energy_consumer import EnergyConsumer
28
+ from zepben.ewb.model.cim.iec61970.base.wires.energy_source import EnergySource
29
+ from zepben.ewb.model.cim.iec61970.base.wires.junction import Junction
30
+ from zepben.ewb.model.cim.iec61970.base.wires.power_electronics_connection import PowerElectronicsConnection
31
+ from zepben.ewb.model.cim.iec61970.base.wires.power_transformer import PowerTransformer
32
+ from zepben.ewb.model.cim.iec61970.base.wires.power_transformer_end import PowerTransformerEnd
33
+ from zepben.ewb.model.cim.iec61970.base.wires.switch import Switch
34
+ from zepben.ewb.services.network.network_service import NetworkService
35
+ from zepben.ewb.services.network.tracing.busbranch_trace import BusBranchTrace, BusBranchTraceStep
36
+
37
+ if TYPE_CHECKING:
38
+ from zepben.ewb import StepContext
39
+
40
+ BBN = TypeVar('BBN') # Bus-Branch Network
41
+ TN = TypeVar('TN') # Topological Node
42
+ TB = TypeVar('TB') # Topological Branch
43
+ EB = TypeVar('EB') # Equivalent Branch
44
+ PT = TypeVar('PT') # Power Transformer
45
+ ES = TypeVar('ES') # Energy Source
46
+ EC = TypeVar('EC') # Energy Consumer
47
+ PEC = TypeVar('PEC') # Power Electronics Connection
48
+
49
+ D = TypeVar('D')
50
+
51
+
52
+ class BusBranchNetworkCreationValidator(Generic[BBN, TN, TB, EB, PT, ES, EC, PEC], metaclass=abc.ABCMeta):
53
+ """
54
+ Validator used to determine if node-breaker network data is fit for the creation of a bus-branch network.
55
+ """
56
+
57
+ @classmethod
58
+ def __subclasshook__(cls, subclass):
59
+ return (hasattr(subclass, "is_valid_network_data") and callable(subclass.is_valid_network_data)
60
+ and hasattr(subclass, "is_valid_topological_node_data") and callable(subclass.is_valid_topological_node_data)
61
+ and hasattr(subclass, "is_valid_topological_branch_data") and callable(subclass.is_valid_topological_branch_data)
62
+ and hasattr(subclass, "is_valid_equivalent_branch_data") and callable(subclass.is_valid_topological_branch_data)
63
+ and hasattr(subclass, "is_valid_power_transformer_data") and callable(subclass.is_valid_power_transformer_data)
64
+ and hasattr(subclass, "is_valid_energy_source_data") and callable(subclass.is_valid_energy_source_data)
65
+ and hasattr(subclass, "is_valid_energy_consumer_data") and callable(subclass.is_valid_energy_consumer_data)
66
+ and hasattr(subclass, "is_valid_power_electronics_connection_data") and callable(subclass.is_valid_power_electronics_connection_data)
67
+ or NotImplemented)
68
+
69
+ @abc.abstractmethod
70
+ def is_valid_network_data(self, node_breaker_network: NetworkService) -> bool:
71
+ """
72
+ Validates if provided data is fit for the creation of a bus-branch network.
73
+ NOTE: Refer to class `BusBranchNetworkCreator` for parameter information.
74
+
75
+ :return: Whether data is valid or not.
76
+ """
77
+ raise NotImplementedError
78
+
79
+ @abc.abstractmethod
80
+ def is_valid_topological_node_data(
81
+ self,
82
+ bus_branch_network: BBN,
83
+ base_voltage: Optional[int],
84
+ collapsed_conducting_equipment: FrozenSet[ConductingEquipment],
85
+ border_terminals: FrozenSet[Terminal],
86
+ inner_terminals: FrozenSet[Terminal],
87
+ node_breaker_network: NetworkService
88
+ ) -> bool:
89
+ """
90
+ Validates if provided data is fit for the creation of a topological node.
91
+ NOTE: Refer to class `BusBranchNetworkCreator` for parameter information.
92
+
93
+ :return: Whether data is valid or not.
94
+ """
95
+ raise NotImplementedError
96
+
97
+ @abc.abstractmethod
98
+ def is_valid_topological_branch_data(
99
+ self,
100
+ bus_branch_network: BBN,
101
+ connected_topological_nodes: Tuple[TN, TN],
102
+ length: Optional[float],
103
+ collapsed_ac_line_segments: FrozenSet[AcLineSegment],
104
+ border_terminals: FrozenSet[Terminal],
105
+ inner_terminals: FrozenSet[Terminal],
106
+ node_breaker_network: NetworkService
107
+ ) -> bool:
108
+ """
109
+ Validates if provided data is fit for the creation of a topological branch.
110
+ NOTE: Refer to class `BusBranchNetworkCreator` for parameter information.
111
+
112
+ :return: Whether data is valid or not.
113
+ """
114
+ raise NotImplementedError
115
+
116
+ @abc.abstractmethod
117
+ def is_valid_equivalent_branch_data(
118
+ self,
119
+ bus_branch_network: BBN,
120
+ connected_topological_nodes: List[TN],
121
+ equivalent_branch: EquivalentBranch,
122
+ node_breaker_network: NetworkService
123
+ ) -> bool:
124
+ """
125
+ Validates if provided data is fit for the creation of an equivalent branch.
126
+ NOTE: Refer to class `BusBranchNetworkCreator` for parameter information.
127
+
128
+ :return: Whether data is valid or not.
129
+ """
130
+ raise NotImplementedError
131
+
132
+ @abc.abstractmethod
133
+ def is_valid_power_transformer_data(
134
+ self,
135
+ bus_branch_network: BBN,
136
+ power_transformer: PowerTransformer,
137
+ ends_to_topological_nodes: List[Tuple[PowerTransformerEnd, Optional[TN]]],
138
+ node_breaker_network: NetworkService
139
+ ) -> bool:
140
+ """
141
+ Validates if provided data is fit for the creation of a power transformer.
142
+ NOTE: Refer to class `BusBranchNetworkCreator` for parameter information.
143
+
144
+ :return: Whether data is valid or not.
145
+ """
146
+ raise NotImplementedError
147
+
148
+ @abc.abstractmethod
149
+ def is_valid_energy_source_data(
150
+ self,
151
+ bus_branch_network: BBN,
152
+ energy_source: EnergySource,
153
+ connected_topological_node: TN,
154
+ node_breaker_network: NetworkService
155
+ ) -> bool:
156
+ """
157
+ Validates if provided data is fit for the creation of an energy source.
158
+ NOTE: Refer to class `BusBranchNetworkCreator` for parameter information.
159
+
160
+ :return: Whether data is valid or not.
161
+ """
162
+ raise NotImplementedError
163
+
164
+ @abc.abstractmethod
165
+ def is_valid_energy_consumer_data(
166
+ self,
167
+ bus_branch_network: BBN,
168
+ energy_consumer: EnergyConsumer,
169
+ connected_topological_node: TN,
170
+ node_breaker_network: NetworkService,
171
+ ) -> bool:
172
+ """
173
+ Validates if provided data is fit for the creation of an energy consumer.
174
+ NOTE: Refer to class `BusBranchNetworkCreator` for parameter information.
175
+
176
+ :return: Whether data is valid or not.
177
+ """
178
+ raise NotImplementedError
179
+
180
+ @abc.abstractmethod
181
+ def is_valid_power_electronics_connection_data(
182
+ self,
183
+ bus_branch_network: BBN,
184
+ power_electronics_connection: PowerElectronicsConnection,
185
+ connected_topological_node: TN,
186
+ node_breaker_network: NetworkService
187
+ ) -> bool:
188
+ """
189
+ Validates if provided data is fit for the creation of a power electronics connection.
190
+ NOTE: Refer to class `BusBranchNetworkCreator` for parameter information.
191
+
192
+ :return: Whether data is valid or not.
193
+ """
194
+ raise NotImplementedError
195
+
196
+
197
+ BNV = TypeVar('BNV', bound=BusBranchNetworkCreationValidator) # Subtype of BusBranchNetworkCreationValidator
198
+
199
+
200
+ class BusBranchNetworkCreator(Generic[BBN, TN, TB, EB, PT, ES, EC, PEC, BNV], metaclass=abc.ABCMeta):
201
+ """Contains the logic needed to generate a target bus-branch network from a source `NetworkService`.
202
+
203
+ NOTE: All bus-branch network elements returned from the creators must have a uuid (universally unique identifier). This is needed to prevent collisions
204
+ when generating the mappings object between the source `NetworkService` and the target bus-branch network.
205
+
206
+ Generic Types:
207
+ - BBN := Type for the object used to represent the bus-branch network.
208
+ - TN := Type for the object used to represent a topological node in the bus-branch network.
209
+ - TB := Type for the object used to represent a topological branch in the bus-branch network.
210
+ - EB := Type for the object used to represent an equivalent branch in the bus-branch network.
211
+ - PT := Type for the object used to represent a power transformer in the bus-branch network.
212
+ - ES := Type for the object used to represent an energy source in the bus-branch network.
213
+ - EC := Type for the object used to represent an energy consumer in the bus-branch network.
214
+ - PEC := Type for the object used to represent a power electronics connection in the bus-branch network.
215
+ - BNV := Type for the validator instance used in the creation of the bus-branch network.
216
+ """
217
+
218
+ @classmethod
219
+ def __subclasshook__(cls, subclass):
220
+ return (hasattr(subclass, "bus_branch_network_creator") and callable(subclass.bus_branch_network_creator)
221
+ and hasattr(subclass, "topological_node_creator") and callable(subclass.topological_node_creator)
222
+ and hasattr(subclass, "topological_branch_creator") and callable(subclass.topological_branch_creator)
223
+ and hasattr(subclass, "equivalent_branch_creator") and callable(subclass.topological_branch_creator)
224
+ and hasattr(subclass, "power_transformer_creator") and callable(subclass.power_transformer_creator)
225
+ and hasattr(subclass, "energy_source_creator") and callable(subclass.energy_source_creator)
226
+ and hasattr(subclass, "energy_consumer_creator") and callable(subclass.energy_consumer_creator)
227
+ and hasattr(subclass, "power_electronics_connection_creator") and callable(subclass.power_electronics_connection_creator)
228
+ and hasattr(subclass, "validator_creator") and callable(subclass.validator_creator)
229
+ or NotImplemented)
230
+
231
+ @abc.abstractmethod
232
+ def bus_branch_network_creator(self, node_breaker_network: NetworkService) -> BBN:
233
+ """
234
+ Creates an empty target bus-branch network instance of type BBN.
235
+
236
+ :param node_breaker_network: Instance of type `NetworkService` being used as a source node-breaker network.
237
+ :return: Target bus-branch network of type BBN.
238
+ """
239
+ raise NotImplementedError
240
+
241
+ @abc.abstractmethod
242
+ def topological_node_creator(
243
+ self,
244
+ bus_branch_network: BBN,
245
+ base_voltage: Optional[int],
246
+ collapsed_conducting_equipment: FrozenSet[ConductingEquipment],
247
+ border_terminals: FrozenSet[Terminal],
248
+ inner_terminals: FrozenSet[Terminal],
249
+ node_breaker_network: NetworkService
250
+ ) -> Tuple[Any, TN]:
251
+ """
252
+ Callback used to create a topological node instance of type TN.
253
+
254
+ :param bus_branch_network: Instance of type BBN being used as a target bus-branch network.
255
+ :param base_voltage: Base voltage value to be used for the topological node in Volts.
256
+ :param collapsed_conducting_equipment: Set that contains all instances of `ConductingEquipment` being collapsed in this topological node.
257
+ :param border_terminals: Set that contains all instances of `Terminal` that connect this topological node to other equipment.
258
+ :param inner_terminals: Set that contains all instances of `Terminal` collapsed in this topological node.
259
+ :param node_breaker_network: Instance of type `NetworkService` being used as a source node-breaker network.
260
+ :return: A 2-tuple with the first element being an id for the topological node and the second element being an instance of type TN that represents a
261
+ topological node in the target bus-branch network. This instance will be passed into the appropriate bus-branch model element creators for
262
+ the elements that are connected to this topological node.
263
+ """
264
+ raise NotImplementedError
265
+
266
+ @abc.abstractmethod
267
+ def topological_branch_creator(
268
+ self,
269
+ bus_branch_network: BBN,
270
+ connected_topological_nodes: Tuple[TN, TN],
271
+ length: Optional[float],
272
+ collapsed_ac_line_segments: FrozenSet[AcLineSegment],
273
+ border_terminals: FrozenSet[Terminal],
274
+ inner_terminals: FrozenSet[Terminal],
275
+ node_breaker_network: NetworkService
276
+ ) -> Tuple[Any, TB]:
277
+ """
278
+ Callback used to create a topological branch instance in target bus-branch network.
279
+
280
+ :param bus_branch_network: Instance of type BBN being used as a target bus-branch network.
281
+ :param connected_topological_nodes: Instances of type TN connected to this topological branch sorted by `FeederDirection`.
282
+ :param length: Length of the topological branch in meters.
283
+ :param collapsed_ac_line_segments: Set that contains all instances of `AcLineSegment` being collapsed in this topological branch. e.g. connected lines
284
+ with the same impedance values.
285
+ :param border_terminals: Set that contains all instances of `Terminal` that connect this topological branch to other equipment.
286
+ :param inner_terminals: Set that contains all instances of `Terminal` collapsed in this topological branch.
287
+ :param node_breaker_network: Instance of type `NetworkService` being used as a source node-breaker network.
288
+ :return: A 2-tuple with the first element being an id for the topological branch and the second element being an instance of type TB that represents a
289
+ topological branch in the target bus-branch network.
290
+ """
291
+ raise NotImplementedError
292
+
293
+ @abc.abstractmethod
294
+ def equivalent_branch_creator(
295
+ self,
296
+ bus_branch_network: BBN,
297
+ connected_topological_nodes: List[TN],
298
+ equivalent_branch: EquivalentBranch,
299
+ node_breaker_network: NetworkService
300
+ ) -> Tuple[Any, EB]:
301
+ """
302
+ Callback used to create an equivalent branch instance in target bus-branch network.
303
+
304
+ :param bus_branch_network: Instance of type BBN being used as a target bus-branch network.
305
+ :param connected_topological_nodes: Instances of type TN connected to this topological branch sorted by `FeederDirection`.
306
+ :param equivalent_branch: Instance of `EquivalentBranch` used to generate the equivalent branch in target bus-branch network.
307
+ :param node_breaker_network: Instance of type `NetworkService` being used as a source node-breaker network.
308
+ :return: A 2-tuple with the first element being an id for the topological branch and the second element being an instance of type TB that represents a
309
+ topological branch in the target bus-branch network.
310
+ """
311
+ raise NotImplementedError
312
+
313
+ @abc.abstractmethod
314
+ def power_transformer_creator(
315
+ self,
316
+ bus_branch_network: BBN,
317
+ power_transformer: PowerTransformer,
318
+ ends_to_topological_nodes: List[Tuple[PowerTransformerEnd, Optional[TN]]],
319
+ node_breaker_network: NetworkService
320
+ ) -> Dict[Any, PT]:
321
+ """
322
+ Callback used to create a power transformer instance in target bus-branch network.
323
+
324
+ :param bus_branch_network: Instance of type BBN being used as a target bus-branch network.
325
+ :param power_transformer: Instance of `PowerTransformer` used to generate power transformer in target bus-branch network.
326
+ :param ends_to_topological_nodes: List holding power transformer ends with the topological nodes they are connected to sorted by `FeederDirection`.
327
+ :param node_breaker_network: Instance of type `NetworkService` being used as a source node-breaker network.
328
+ :return: A dictionary with keys being uuids for the instance/s of type PT that represents a power transformer in the target bus-branch network.
329
+ """
330
+ raise NotImplementedError
331
+
332
+ @abc.abstractmethod
333
+ def energy_source_creator(
334
+ self,
335
+ bus_branch_network: BBN,
336
+ energy_source: EnergySource,
337
+ connected_topological_node: TN,
338
+ node_breaker_network: NetworkService
339
+ ) -> Dict[Any, ES]:
340
+ """
341
+ Callback used to create an energy source instance in target bus-branch network.
342
+
343
+ :param bus_branch_network: Instance of type BBN being used as a target bus-branch network.
344
+ :param energy_source: Instance of `EnergySource` used to generate energy source in target bus-branch network.
345
+ :param connected_topological_node: Topological node of type TN that is connected to this energy source.
346
+ :param node_breaker_network: Instance of type `NetworkService` being used as a source node-breaker network.
347
+ :return: A dictionary with keys being uuids for the instance/s of type ES that represents an energy source in the target bus-branch network.
348
+ """
349
+ raise NotImplementedError
350
+
351
+ @abc.abstractmethod
352
+ def energy_consumer_creator(
353
+ self,
354
+ bus_branch_network: BBN,
355
+ energy_consumer: EnergyConsumer,
356
+ connected_topological_node: TN,
357
+ node_breaker_network: NetworkService,
358
+ ) -> Dict[Any, EC]:
359
+ """
360
+ Callback used to pass all the required values to generate an energy consumer object.
361
+
362
+ :param bus_branch_network: Instance of type BBN being used as a target bus-branch network.
363
+ :param energy_consumer: Instance of `EnergyConsumer` used to generate energy consumer in target bus-branch network.
364
+ :param connected_topological_node: Topological node of type TN that is connected to this energy consumer.
365
+ :param node_breaker_network: Instance of type `NetworkService` being used as a source node-breaker network.
366
+ :return: A dictionary with keys being uuids for the instance/s of type EC that represents an energy consumer in the target bus-branch network.
367
+ """
368
+ raise NotImplementedError
369
+
370
+ @abc.abstractmethod
371
+ def power_electronics_connection_creator(
372
+ self,
373
+ bus_branch_network: BBN,
374
+ power_electronics_connection: PEC,
375
+ connected_topological_node: TN,
376
+ node_breaker_network: NetworkService
377
+ ) -> Dict[Any, PEC]:
378
+ """
379
+ Callback used to pass all the required values to generate a power electronics connection object.
380
+
381
+ :param bus_branch_network: Instance of type BBN being used as a target bus-branch network.
382
+ :param power_electronics_connection: Instance of `PowerElectronicsConnection` used to generate power electronics connection in target bus-branch
383
+ network.
384
+ :param connected_topological_node: Topological node of type TN that is connected to this power electronics connection.
385
+ :param node_breaker_network: Instance of type `NetworkService` being used as a source node-breaker network.
386
+ :return: A dictionary with keys being uuids for the instance/s of type PEC that represents a power electronics connection in the target bus-branch
387
+ network.
388
+ """
389
+ raise NotImplementedError
390
+
391
+ @abc.abstractmethod
392
+ def validator_creator(self) -> BNV:
393
+ """
394
+ Callback used to create 'BusBranchNetworkCreationValidator' instance used for validation while creating a bus-branch
395
+ network.
396
+
397
+ :return: Instance of type 'BusBranchNetworkCreationValidator'.
398
+ """
399
+ raise NotImplementedError
400
+
401
+ # noinspection PyMethodMayBeStatic
402
+ def has_negligible_impedance(self, ce: ConductingEquipment) -> bool:
403
+ """
404
+ Callback used to evaluate if an instance of `ConductingEquipment` has negligible impedance.
405
+
406
+ :param ce: `ConductingEquipment` instance whose impedance is being evaluated.
407
+ :return: True if 'ce' has negligible impedance, False otherwise.
408
+ """
409
+ if isinstance(ce, AcLineSegment):
410
+ return ce.length == 0
411
+ if isinstance(ce, Switch):
412
+ return not ce.is_open()
413
+ if isinstance(ce, Junction) or isinstance(ce, BusbarSection):
414
+ return True
415
+ if isinstance(ce, EquivalentBranch):
416
+ return _is_no_impedance_branch(ce)
417
+ return False
418
+
419
+ async def create(self, node_breaker_network: NetworkService) -> 'BusBranchNetworkCreationResult[BBN, BNV]':
420
+ return await _create_bus_branch_network(self, node_breaker_network)
421
+
422
+
423
+ CE = TypeVar("CE", bound=ConductingEquipment)
424
+
425
+
426
+ @dataclass()
427
+ class TerminalGrouping(Generic[CE]):
428
+ border_terminals: Set[Terminal] = field(default_factory=set)
429
+ inner_terminals: Set[Terminal] = field(default_factory=set)
430
+ conducting_equipment_group: Set[CE] = field(default_factory=set)
431
+
432
+ def terminals(self) -> Set[Terminal]:
433
+ return {*self.border_terminals, *self.inner_terminals}
434
+
435
+
436
+ class BusBranchToNodeBreakerMappings:
437
+
438
+ def __init__(self):
439
+ self.topological_nodes: Dict[Any, TerminalGrouping[ConductingEquipment]] = {}
440
+ self.topological_branches: Dict[Any, TerminalGrouping[AcLineSegment]] = {}
441
+ self.equivalent_branches: Dict[Any, Set[EquivalentBranch]] = {}
442
+ self.power_transformers: Dict[Any, Set[PowerTransformer]] = {}
443
+ self.energy_sources: Dict[Any, Set[EnergySource]] = {}
444
+ self.energy_consumers: Dict[Any, Set[EnergyConsumer]] = {}
445
+ self.power_electronics_connections: Dict[Any, Set[PowerElectronicsConnection]] = {}
446
+
447
+
448
+ class NodeBreakerToBusBranchMappings:
449
+
450
+ def __init__(self):
451
+ self.objects: Dict[str, Set[Any]] = {}
452
+
453
+
454
+ class BusBranchNetworkCreationMappings:
455
+ """
456
+ Holds mappings between a bus-branch network (bbn) and a node-breaker network (nbn) of type `NetworkService`.
457
+ """
458
+
459
+ def __init__(self):
460
+ self.to_nbn = BusBranchToNodeBreakerMappings()
461
+ self.to_bbn = NodeBreakerToBusBranchMappings()
462
+
463
+
464
+ def _add_to_mapping(mapping: Dict[Any, Set[Any]], uuid: Any, obj_to_add: Any) -> None:
465
+ if uuid not in mapping:
466
+ mapping[uuid] = set()
467
+ mapping[uuid].add(obj_to_add)
468
+
469
+
470
+ class BusBranchNetworkCreationResult(Generic[BBN, BNV]):
471
+ """
472
+ Represents the results of creating a bus-branch network from a node-breaker network.
473
+ """
474
+
475
+ def __init__(self, validator: BNV):
476
+ self.validator: BNV = validator
477
+ self.mappings: BusBranchNetworkCreationMappings = BusBranchNetworkCreationMappings()
478
+ self.network: BBN = None
479
+ self.was_successful: bool = False
480
+
481
+
482
+ async def _create_bus_branch_network(
483
+ bus_branch_network_creator: BusBranchNetworkCreator[BBN, TN, TB, EB, PT, ES, EC, PEC, BNV],
484
+ node_breaker_network: NetworkService
485
+ ) -> BusBranchNetworkCreationResult[BBN, BNV]:
486
+ """
487
+ Creates bus-branch network.
488
+
489
+ :param bus_branch_network_creator: Instance of type `BusBranchNetworkCreator` used to generate the target bus-branch network.
490
+ :param node_breaker_network: Instance of type `NetworkService` being used as a source node-breaker network.
491
+ :return: `CreationResult`
492
+ """
493
+ _validate_number_of_terminals(node_breaker_network)
494
+ validator = bus_branch_network_creator.validator_creator()
495
+
496
+ result: BusBranchNetworkCreationResult[BBN, BNV] = BusBranchNetworkCreationResult(validator)
497
+
498
+ if not validator.is_valid_network_data(node_breaker_network):
499
+ return result
500
+
501
+ bus_branch_network = bus_branch_network_creator.bus_branch_network_creator(node_breaker_network)
502
+
503
+ terminals_to_tns = {}
504
+ # create topological branches
505
+ tbs_creation_success = await _create_topological_branches(node_breaker_network, bus_branch_network,
506
+ bus_branch_network_creator, result,
507
+ terminals_to_tns, validator)
508
+ if not tbs_creation_success:
509
+ return result
510
+
511
+ # create equivalent branches
512
+ ebs_creation_success = await _create_equivalent_branches(node_breaker_network, bus_branch_network,
513
+ bus_branch_network_creator, result,
514
+ terminals_to_tns, validator)
515
+ if not ebs_creation_success:
516
+ return result
517
+
518
+ # create power transformers
519
+ pt_creation_success = await _create_power_transformers(node_breaker_network, bus_branch_network,
520
+ bus_branch_network_creator, result,
521
+ terminals_to_tns, validator)
522
+ if not pt_creation_success:
523
+ return result
524
+
525
+ # create energy sources
526
+ es_creation_success = await _create_energy_sources(node_breaker_network, bus_branch_network,
527
+ bus_branch_network_creator,
528
+ result, terminals_to_tns, validator)
529
+ if not es_creation_success:
530
+ return result
531
+
532
+ # create energy consumers
533
+ ec_creation_success = await _create_energy_consumers(node_breaker_network, bus_branch_network,
534
+ bus_branch_network_creator,
535
+ result, terminals_to_tns, validator)
536
+ if not ec_creation_success:
537
+ return result
538
+
539
+ # create power electronics connections
540
+ pec_creation_success = await _create_power_electronics_connections(node_breaker_network, bus_branch_network,
541
+ bus_branch_network_creator,
542
+ result, terminals_to_tns, validator)
543
+ if not pec_creation_success:
544
+ return result
545
+
546
+ result.network = bus_branch_network
547
+ result.was_successful = True
548
+ return result
549
+
550
+
551
+ async def _get_or_create_topological_node(
552
+ terminal: Terminal,
553
+ terminals_to_tns: Dict[str, TN],
554
+ node_breaker_network: NetworkService,
555
+ bus_branch_network: BBN,
556
+ bus_branch_network_creator: BusBranchNetworkCreator[BBN, TN, TB, EB, PT, ES, EC, PEC, BNV],
557
+ result: BusBranchNetworkCreationResult[BBN, BNV],
558
+ validator: BNV
559
+ ) -> (bool, TN):
560
+ cached_tn = terminals_to_tns.get(terminal.mrid)
561
+ if cached_tn is not None:
562
+ return True, cached_tn
563
+
564
+ # group terminals connected by negligible impedance equipment
565
+ terminals_grouping = await _group_negligible_impedance_terminals(terminal,
566
+ bus_branch_network_creator.has_negligible_impedance)
567
+ negligible_impedance_equipment = frozenset(terminals_grouping.conducting_equipment_group)
568
+ inner_terms = frozenset(terminals_grouping.inner_terminals)
569
+ border_terms = frozenset(terminals_grouping.border_terminals)
570
+
571
+ rated_u = _get_base_voltage(border_terms)
572
+
573
+ # create topological node
574
+ if not validator.is_valid_topological_node_data(bus_branch_network,
575
+ rated_u,
576
+ negligible_impedance_equipment,
577
+ border_terms,
578
+ inner_terms,
579
+ node_breaker_network):
580
+ return False, None
581
+
582
+ tn_id, tn = bus_branch_network_creator.topological_node_creator(
583
+ bus_branch_network,
584
+ rated_u,
585
+ negligible_impedance_equipment,
586
+ border_terms,
587
+ inner_terms,
588
+ node_breaker_network
589
+ )
590
+
591
+ # populate result mappings
592
+ result.mappings.to_nbn.topological_nodes[tn_id] = terminals_grouping
593
+
594
+ for t in terminals_grouping.terminals():
595
+ _add_to_mapping(result.mappings.to_bbn.objects, t.mrid, tn)
596
+ if t.connectivity_node is not None:
597
+ _add_to_mapping(result.mappings.to_bbn.objects, t.connectivity_node.mrid, tn)
598
+
599
+ for ce in terminals_grouping.conducting_equipment_group:
600
+ _add_to_mapping(result.mappings.to_bbn.objects, ce.mrid, tn)
601
+
602
+ # map terminals to associated topological nodes for easy lookup when creating connected equipment
603
+ for t in border_terms:
604
+ terminals_to_tns[t.mrid] = tn
605
+ for t in inner_terms:
606
+ terminals_to_tns[t.mrid] = tn
607
+
608
+ return True, tn
609
+
610
+
611
+ async def _create_topological_branches(
612
+ node_breaker_network: NetworkService,
613
+ bus_branch_network: BBN,
614
+ bus_branch_network_creator: BusBranchNetworkCreator[BBN, TN, TB, EB, PT, ES, EC, PEC, BNV],
615
+ result: BusBranchNetworkCreationResult[BBN, BNV],
616
+ terminals_to_tns: Dict[str, TN],
617
+ validator: BNV
618
+ ) -> bool:
619
+ processed_acls_ids = set()
620
+ for acls in node_breaker_network.objects(AcLineSegment):
621
+ if not (acls.mrid in processed_acls_ids or bus_branch_network_creator.has_negligible_impedance(acls)):
622
+ lines_grouping = await _group_common_ac_line_segment_terminals(acls)
623
+ border_terms = frozenset(lines_grouping.border_terminals)
624
+ common_acls = frozenset(lines_grouping.conducting_equipment_group)
625
+ inner_terms = frozenset(lines_grouping.inner_terminals)
626
+
627
+ # get/create connected topological nodes
628
+ acls_tns = []
629
+ for t in _sort_terminals_by_feeder_direction(border_terms):
630
+ tn_creation_success, tn = await _get_or_create_topological_node(t, terminals_to_tns,
631
+ node_breaker_network,
632
+ bus_branch_network,
633
+ bus_branch_network_creator,
634
+ result, validator)
635
+ if not tn_creation_success:
636
+ return False
637
+ acls_tns.append(tn)
638
+
639
+ total_length = reduce(lambda s, l: l.length + s, (common_acl for common_acl in common_acls), 0.0)
640
+
641
+ # create topological branch
642
+ if not validator.is_valid_topological_branch_data(bus_branch_network,
643
+ (acls_tns[0], acls_tns[1]),
644
+ total_length,
645
+ common_acls,
646
+ border_terms,
647
+ inner_terms,
648
+ node_breaker_network):
649
+ return False
650
+
651
+ tb_id, tb = bus_branch_network_creator.topological_branch_creator(
652
+ bus_branch_network,
653
+ (acls_tns[0], acls_tns[1]),
654
+ total_length,
655
+ common_acls,
656
+ border_terms,
657
+ inner_terms,
658
+ node_breaker_network
659
+ )
660
+
661
+ # populate result mappings
662
+ result.mappings.to_nbn.topological_branches[tb_id] = lines_grouping
663
+
664
+ for line in lines_grouping.conducting_equipment_group:
665
+ _add_to_mapping(result.mappings.to_bbn.objects, line.mrid, tb)
666
+
667
+ for t in lines_grouping.inner_terminals:
668
+ _add_to_mapping(result.mappings.to_bbn.objects, t.mrid, tb)
669
+
670
+ if t.connectivity_node is not None:
671
+ _add_to_mapping(result.mappings.to_bbn.objects, t.connectivity_node.mrid, tb)
672
+
673
+ # flag processed ac-line-segments
674
+ processed_acls_ids.update({acls.mrid for acls in common_acls})
675
+ return True
676
+
677
+
678
+ async def _create_equivalent_branches(
679
+ node_breaker_network: NetworkService,
680
+ bus_branch_network: BBN,
681
+ bus_branch_network_creator: BusBranchNetworkCreator[BBN, TN, TB, EB, PT, ES, EC, PEC, BNV],
682
+ result: BusBranchNetworkCreationResult[BBN, BNV],
683
+ terminals_to_tns: Dict[str, TN],
684
+ validator: BNV
685
+ ) -> bool:
686
+ for eb in node_breaker_network.objects(EquivalentBranch):
687
+ if eb.mrid in result.mappings.to_bbn.objects:
688
+ # skip if already processed
689
+ continue
690
+
691
+ # get/create connected topological nodes
692
+ eb_tns = []
693
+ for t in _sort_terminals_by_feeder_direction(eb.terminals):
694
+ tn_creation_success, tn = await _get_or_create_topological_node(t, terminals_to_tns,
695
+ node_breaker_network,
696
+ bus_branch_network,
697
+ bus_branch_network_creator,
698
+ result, validator)
699
+ if not tn_creation_success:
700
+ return False
701
+ eb_tns.append(tn)
702
+
703
+ if bus_branch_network_creator.has_negligible_impedance(eb):
704
+ continue
705
+
706
+ # create equivalent branch
707
+ if not validator.is_valid_equivalent_branch_data(bus_branch_network, eb_tns, eb, node_breaker_network):
708
+ return False
709
+
710
+ teb_id, teb = bus_branch_network_creator.equivalent_branch_creator(bus_branch_network, eb_tns, eb, node_breaker_network)
711
+
712
+ # populate result mappings
713
+ _add_to_mapping(result.mappings.to_nbn.equivalent_branches, teb_id, eb)
714
+ _add_to_mapping(result.mappings.to_bbn.objects, eb.mrid, teb)
715
+
716
+ return True
717
+
718
+
719
+ async def _create_power_transformers(
720
+ node_breaker_network: NetworkService,
721
+ bus_branch_network: BBN,
722
+ bus_branch_network_creator: BusBranchNetworkCreator[BBN, TN, TB, EB, PT, ES, EC, PEC, BNV],
723
+ result: BusBranchNetworkCreationResult[BBN, BNV],
724
+ terminals_to_tns: Dict[str, TN],
725
+ validator: BNV
726
+ ) -> bool:
727
+ for pt in node_breaker_network.objects(PowerTransformer):
728
+ # create list of ends with their connected topological nodes
729
+ ends_to_topological_nodes = []
730
+ for end in _sort_ends_by_feeder_direction(pt.ends):
731
+ if end.terminal is not None:
732
+ tn_creation_success, tn = await _get_or_create_topological_node(end.terminal, terminals_to_tns,
733
+ node_breaker_network,
734
+ bus_branch_network,
735
+ bus_branch_network_creator, result,
736
+ validator)
737
+ if not tn_creation_success:
738
+ return False
739
+ ends_to_topological_nodes.append((end, tn))
740
+ else:
741
+ ends_to_topological_nodes.append((end, None))
742
+
743
+ # create power transformer
744
+ if not validator.is_valid_power_transformer_data(bus_branch_network, pt, ends_to_topological_nodes,
745
+ node_breaker_network):
746
+ return False
747
+
748
+ txs = bus_branch_network_creator.power_transformer_creator(bus_branch_network, pt, ends_to_topological_nodes,
749
+ node_breaker_network)
750
+
751
+ # populate result mappings
752
+ for tx_id, tx in txs.items():
753
+ _add_to_mapping(result.mappings.to_nbn.power_transformers, tx_id, pt)
754
+ _add_to_mapping(result.mappings.to_bbn.objects, pt.mrid, tx)
755
+
756
+ return True
757
+
758
+
759
+ async def _create_energy_sources(
760
+ node_breaker_network: NetworkService,
761
+ bus_branch_network: BBN,
762
+ bus_branch_network_creator: BusBranchNetworkCreator[BBN, TN, TB, EB, PT, ES, EC, PEC, BNV],
763
+ result: BusBranchNetworkCreationResult[BBN, BNV],
764
+ terminals_to_tns: Dict[str, TN],
765
+ validator: BNV
766
+ ) -> bool:
767
+ for es in node_breaker_network.objects(EnergySource):
768
+ es_terminal = next((t for t in es.terminals))
769
+ tn_creation_success, tn = await _get_or_create_topological_node(es_terminal, terminals_to_tns,
770
+ node_breaker_network,
771
+ bus_branch_network, bus_branch_network_creator,
772
+ result, validator)
773
+ if not tn_creation_success:
774
+ return False
775
+
776
+ if not validator.is_valid_energy_source_data(bus_branch_network, es, tn, node_breaker_network):
777
+ return False
778
+
779
+ bb_ess = bus_branch_network_creator.energy_source_creator(bus_branch_network, es, tn, node_breaker_network)
780
+
781
+ # populate result mappings
782
+ for bb_es_id, bb_es in bb_ess.items():
783
+ _add_to_mapping(result.mappings.to_nbn.energy_sources, bb_es_id, es)
784
+ _add_to_mapping(result.mappings.to_bbn.objects, es.mrid, bb_es)
785
+
786
+ return True
787
+
788
+
789
+ async def _create_energy_consumers(
790
+ node_breaker_network: NetworkService,
791
+ bus_branch_network: BBN,
792
+ bus_branch_network_creator: BusBranchNetworkCreator[BBN, TN, TB, EB, PT, ES, EC, PEC, BNV],
793
+ result: BusBranchNetworkCreationResult[BBN, BNV],
794
+ terminals_to_tns: Dict[str, TN],
795
+ validator: BNV
796
+ ):
797
+ for ec in node_breaker_network.objects(EnergyConsumer):
798
+ ec_terminal = next((t for t in ec.terminals))
799
+ tn_creation_success, tn = await _get_or_create_topological_node(ec_terminal, terminals_to_tns,
800
+ node_breaker_network,
801
+ bus_branch_network, bus_branch_network_creator,
802
+ result, validator)
803
+ if not tn_creation_success:
804
+ return False
805
+
806
+ if not validator.is_valid_energy_consumer_data(bus_branch_network, ec, tn, node_breaker_network):
807
+ return False
808
+
809
+ bb_ecs = bus_branch_network_creator.energy_consumer_creator(bus_branch_network, ec, tn,
810
+ node_breaker_network)
811
+
812
+ # populate result mappings
813
+ for bb_ec_id, bb_ec in bb_ecs.items():
814
+ _add_to_mapping(result.mappings.to_nbn.energy_consumers, bb_ec_id, ec)
815
+ _add_to_mapping(result.mappings.to_bbn.objects, ec.mrid, bb_ec)
816
+
817
+ return True
818
+
819
+
820
+ async def _create_power_electronics_connections(
821
+ node_breaker_network: NetworkService,
822
+ bus_branch_network: BBN,
823
+ bus_branch_network_creator: BusBranchNetworkCreator[BBN, TN, TB, EB, PT, ES, EC, PEC, BNV],
824
+ result: BusBranchNetworkCreationResult[BBN, BNV],
825
+ terminals_to_tns: Dict[str, TN],
826
+ validator: BNV
827
+ ):
828
+ for pec in node_breaker_network.objects(PowerElectronicsConnection):
829
+ pec_terminal = next((t for t in pec.terminals))
830
+ tn_creation_success, tn = await _get_or_create_topological_node(pec_terminal, terminals_to_tns,
831
+ node_breaker_network,
832
+ bus_branch_network, bus_branch_network_creator,
833
+ result, validator)
834
+ if not tn_creation_success:
835
+ return False
836
+
837
+ if not validator.is_valid_power_electronics_connection_data(bus_branch_network, pec, tn, node_breaker_network):
838
+ return False
839
+
840
+ bb_pecs = bus_branch_network_creator.power_electronics_connection_creator(bus_branch_network, pec, tn,
841
+ node_breaker_network)
842
+
843
+ # populate result mappings
844
+ for bb_pec_id, bb_pec in bb_pecs.items():
845
+ _add_to_mapping(result.mappings.to_nbn.power_electronics_connections, bb_pec_id, pec)
846
+ _add_to_mapping(result.mappings.to_bbn.objects, pec.mrid, bb_pec)
847
+
848
+ return True
849
+
850
+
851
+ def _get_base_voltage(border_terminals: FrozenSet[Terminal]) -> Union[int, None]:
852
+ voltages = set()
853
+ for t in border_terminals:
854
+ ce = t.conducting_equipment
855
+ # Open switches may have a different voltage rating from the negligible-impedance equipment group due to the equipment on the other side of it.
856
+ if isinstance(ce, Switch):
857
+ continue
858
+ if isinstance(ce, PowerTransformer):
859
+ end_voltage = next((e.rated_u for e in ce.ends if e.terminal is t), None)
860
+ if end_voltage is not None:
861
+ voltages.add(end_voltage)
862
+ else:
863
+ if ce.base_voltage is not None:
864
+ voltages.add(ce.base_voltage.nominal_voltage)
865
+ return next(iter(voltages), None)
866
+
867
+
868
+ def _validate_number_of_terminals(network: NetworkService):
869
+ illegal_acls = []
870
+ for acl in network.objects(AcLineSegment):
871
+ if acl.num_terminals() != 2:
872
+ illegal_acls.append(acl.mrid)
873
+
874
+ if len(illegal_acls) != 0:
875
+ raise ValueError(
876
+ f"NetworkService contains the following AcLineSegments with an invalid number of terminals: {illegal_acls}")
877
+
878
+ illegal_es = []
879
+ for es in network.objects(EnergySource):
880
+ if es.num_terminals() != 1:
881
+ illegal_es.append(es.mrid)
882
+
883
+ if len(illegal_es) != 0:
884
+ raise ValueError(
885
+ f"NetworkService contains the following EnergySources with an invalid number of terminals: {illegal_es}")
886
+
887
+ illegal_ec = []
888
+ for ec in network.objects(EnergyConsumer):
889
+ if ec.num_terminals() != 1:
890
+ illegal_ec.append(ec.mrid)
891
+
892
+ if len(illegal_ec) != 0:
893
+ raise ValueError(
894
+ f"NetworkService contains the following EnergyConsumers with an invalid number of terminals: {illegal_ec}")
895
+
896
+ illegal_pec = []
897
+ for pec in network.objects(PowerElectronicsConnection):
898
+ if pec.num_terminals() != 1:
899
+ illegal_pec.append(pec.mrid)
900
+
901
+ if len(illegal_pec) != 0:
902
+ raise ValueError(
903
+ f"NetworkService contains the following PowerElectronicsConnections with an invalid number of terminals: {illegal_pec}")
904
+
905
+
906
+ async def _group_negligible_impedance_terminals(
907
+ terminal: Terminal,
908
+ has_negligible_impedance: Callable[[ConductingEquipment], bool]
909
+ ) -> TerminalGrouping[ConductingEquipment]:
910
+ tg = TerminalGrouping[ConductingEquipment]()
911
+
912
+ trace = (
913
+ BusBranchTrace(
914
+ queue_next=Traversal.QueueNext(_queue_terminals_across_negligible_impedance(has_negligible_impedance))
915
+ ).add_start_item(terminal)
916
+ .add_step_action(_process_terminal(tg, has_negligible_impedance))
917
+ )
918
+
919
+ await trace.run()
920
+ return tg
921
+
922
+
923
+ def _create_traversal_step_object(next_item: Union[Terminal, AcLineSegment]) -> BusBranchTraceStep:
924
+ return BusBranchTraceStep(next_item)
925
+
926
+
927
+ def _process_terminal(
928
+ tg: TerminalGrouping[ConductingEquipment],
929
+ has_negligible_impedance: Callable[[ConductingEquipment], bool]
930
+ ):
931
+ async def add_to_group(item: BusBranchTraceStep, _):
932
+ t = item.identified_object
933
+ if has_negligible_impedance(t.conducting_equipment):
934
+ tg.conducting_equipment_group.add(t.conducting_equipment)
935
+ tg.inner_terminals.add(t)
936
+ else:
937
+ tg.border_terminals.add(t)
938
+
939
+ return add_to_group
940
+
941
+
942
+ def _queue_terminals_across_negligible_impedance(
943
+ has_negligible_impedance: Callable[[ConductingEquipment], bool]
944
+ ):
945
+ def queue_next(item: BusBranchTraceStep, context: StepContext, _queue_next: Callable[[BusBranchTraceStep], bool]):
946
+ terminal = item.identified_object
947
+ if terminal.connectivity_node is not None:
948
+ for ot in terminal.connectivity_node.terminals:
949
+ if ot != terminal:
950
+ _queue_next(_create_traversal_step_object(ot))
951
+
952
+ if has_negligible_impedance(terminal.conducting_equipment):
953
+ for ot in terminal.conducting_equipment.terminals:
954
+ if ot != terminal:
955
+ _queue_next(_create_traversal_step_object(ot))
956
+
957
+ return queue_next
958
+
959
+
960
+ async def _group_common_ac_line_segment_terminals(acls: AcLineSegment) -> TerminalGrouping[AcLineSegment]:
961
+ def has_common_impedance(line: AcLineSegment):
962
+ return line.per_length_sequence_impedance.mrid == acls.per_length_sequence_impedance.mrid
963
+
964
+ common_acls: TerminalGrouping[AcLineSegment] = TerminalGrouping()
965
+ connectivity_node_counter = Counter()
966
+
967
+ trace = (
968
+ BusBranchTrace(
969
+ queue_next=Traversal.QueueNext(_queue_common_impedance_lines(common_acls, has_common_impedance))
970
+ ).add_start_item(acls)
971
+ .add_step_action(_process_acls(common_acls, connectivity_node_counter))
972
+ )
973
+
974
+ await trace.run()
975
+
976
+ for t in (t for line in common_acls.conducting_equipment_group for t in line.terminals):
977
+ if t.connectivity_node is None:
978
+ common_acls.border_terminals.add(t)
979
+ continue
980
+
981
+ count = connectivity_node_counter.get(t.connectivity_node, 0)
982
+ if count == 1:
983
+ common_acls.border_terminals.add(t)
984
+ else:
985
+ common_acls.inner_terminals.add(t)
986
+
987
+ return common_acls
988
+
989
+
990
+ def _process_acls(
991
+ common_acls: TerminalGrouping[AcLineSegment],
992
+ connectivity_node_counter: Counter
993
+ ):
994
+ async def add_to_group(item: BusBranchTraceStep, _):
995
+ acls = item.identified_object
996
+ if acls in common_acls.conducting_equipment_group:
997
+ return
998
+
999
+ common_acls.conducting_equipment_group.add(acls)
1000
+ connectivity_node_counter.update(
1001
+ (t.connectivity_node for t in acls.terminals if t.connectivity_node is not None))
1002
+
1003
+ return add_to_group
1004
+
1005
+
1006
+ def _queue_common_impedance_lines(
1007
+ common_acls: TerminalGrouping[AcLineSegment],
1008
+ has_common_impedance: Callable[[AcLineSegment], bool]
1009
+ ):
1010
+ def queue_next(item: BusBranchTraceStep, context: StepContext, _queue_next: Callable[[BusBranchTraceStep], bool]):
1011
+ acls = item.identified_object
1012
+
1013
+ for it in _next_common_acls(acls, has_common_impedance, common_acls):
1014
+ _queue_next(_create_traversal_step_object(it))
1015
+
1016
+ return queue_next
1017
+
1018
+
1019
+ def _next_common_acls(
1020
+ acls: AcLineSegment,
1021
+ has_common_impedance: Callable[[AcLineSegment], bool],
1022
+ common_acls: TerminalGrouping[AcLineSegment]
1023
+ ) -> Set[AcLineSegment]:
1024
+ acls_terminals = {*acls.terminals}
1025
+
1026
+ def can_process_ac_line(o: Terminal) -> bool:
1027
+ return o not in acls_terminals \
1028
+ and isinstance(o.conducting_equipment, AcLineSegment) \
1029
+ and has_common_impedance(o.conducting_equipment) \
1030
+ and o.conducting_equipment not in common_acls.conducting_equipment_group
1031
+
1032
+ def is_non_forking_ac_line(t: Terminal) -> bool:
1033
+ return t.connectivity_node is not None and len(list(t.connectivity_node.terminals)) == 2
1034
+
1035
+ return {
1036
+ o.conducting_equipment
1037
+ for t in acls.terminals if is_non_forking_ac_line(t)
1038
+ for o in t.connectivity_node.terminals if can_process_ac_line(o)
1039
+ }
1040
+
1041
+
1042
+ def _is_no_impedance_branch(eb: EquivalentBranch):
1043
+ return eb.r is None or eb.x is None or eb.r == 0.0 or eb.x == 0.0
1044
+
1045
+
1046
+ def _sort_ends_by_feeder_direction(ends: Iterable[PowerTransformerEnd]) -> List[PowerTransformerEnd]:
1047
+ return sorted(iter(ends), key=lambda pte: 999 if pte.terminal is None else pte.terminal.normal_feeder_direction.value)
1048
+
1049
+
1050
+ def _sort_terminals_by_feeder_direction(terminals: Iterable[Terminal]) -> List[Terminal]:
1051
+ return sorted(iter(terminals), key=lambda ter: ter.normal_feeder_direction.value)