zepben.ewb 1.0.0b1__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 (639) 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/sqlite/__init__.py +4 -0
  14. zepben/ewb/database/sqlite/common/__init__.py +4 -0
  15. zepben/ewb/database/sqlite/common/base_cim_reader.py +212 -0
  16. zepben/ewb/database/sqlite/common/base_cim_writer.py +159 -0
  17. zepben/ewb/database/sqlite/common/base_collection_reader.py +96 -0
  18. zepben/ewb/database/sqlite/common/base_collection_writer.py +73 -0
  19. zepben/ewb/database/sqlite/common/base_database_reader.py +127 -0
  20. zepben/ewb/database/sqlite/common/base_database_tables.py +137 -0
  21. zepben/ewb/database/sqlite/common/base_database_writer.py +195 -0
  22. zepben/ewb/database/sqlite/common/base_entry_writer.py +34 -0
  23. zepben/ewb/database/sqlite/common/base_service_reader.py +50 -0
  24. zepben/ewb/database/sqlite/common/base_service_writer.py +104 -0
  25. zepben/ewb/database/sqlite/common/metadata_collection_reader.py +39 -0
  26. zepben/ewb/database/sqlite/common/metadata_collection_writer.py +38 -0
  27. zepben/ewb/database/sqlite/common/metadata_entry_reader.py +45 -0
  28. zepben/ewb/database/sqlite/common/metadata_entry_writer.py +41 -0
  29. zepben/ewb/database/sqlite/common/reader_exceptions.py +30 -0
  30. zepben/ewb/database/sqlite/customer/__init__.py +4 -0
  31. zepben/ewb/database/sqlite/customer/customer_cim_reader.py +169 -0
  32. zepben/ewb/database/sqlite/customer/customer_cim_writer.py +137 -0
  33. zepben/ewb/database/sqlite/customer/customer_database_reader.py +44 -0
  34. zepben/ewb/database/sqlite/customer/customer_database_tables.py +37 -0
  35. zepben/ewb/database/sqlite/customer/customer_database_writer.py +45 -0
  36. zepben/ewb/database/sqlite/customer/customer_service_reader.py +57 -0
  37. zepben/ewb/database/sqlite/customer/customer_service_writer.py +47 -0
  38. zepben/ewb/database/sqlite/diagram/__init__.py +4 -0
  39. zepben/ewb/database/sqlite/diagram/diagram_cim_reader.py +105 -0
  40. zepben/ewb/database/sqlite/diagram/diagram_cim_writer.py +81 -0
  41. zepben/ewb/database/sqlite/diagram/diagram_database_reader.py +45 -0
  42. zepben/ewb/database/sqlite/diagram/diagram_database_tables.py +29 -0
  43. zepben/ewb/database/sqlite/diagram/diagram_database_writer.py +44 -0
  44. zepben/ewb/database/sqlite/diagram/diagram_service_reader.py +49 -0
  45. zepben/ewb/database/sqlite/diagram/diagram_service_writer.py +41 -0
  46. zepben/ewb/database/sqlite/extensions/__init__.py +4 -0
  47. zepben/ewb/database/sqlite/extensions/prepared_statement.py +112 -0
  48. zepben/ewb/database/sqlite/extensions/result_set.py +153 -0
  49. zepben/ewb/database/sqlite/network/__init__.py +4 -0
  50. zepben/ewb/database/sqlite/network/network_cim_reader.py +3167 -0
  51. zepben/ewb/database/sqlite/network/network_cim_writer.py +2561 -0
  52. zepben/ewb/database/sqlite/network/network_database_reader.py +173 -0
  53. zepben/ewb/database/sqlite/network/network_database_tables.py +242 -0
  54. zepben/ewb/database/sqlite/network/network_database_writer.py +43 -0
  55. zepben/ewb/database/sqlite/network/network_service_reader.py +265 -0
  56. zepben/ewb/database/sqlite/network/network_service_writer.py +209 -0
  57. zepben/ewb/database/sqlite/tables/__init__.py +4 -0
  58. zepben/ewb/database/sqlite/tables/associations/__init__.py +4 -0
  59. zepben/ewb/database/sqlite/tables/associations/loop_substation_relationship.py +17 -0
  60. zepben/ewb/database/sqlite/tables/associations/table_asset_organisation_roles_assets.py +40 -0
  61. zepben/ewb/database/sqlite/tables/associations/table_assets_power_system_resources.py +41 -0
  62. zepben/ewb/database/sqlite/tables/associations/table_battery_units_battery_controls.py +40 -0
  63. zepben/ewb/database/sqlite/tables/associations/table_circuits_substations.py +40 -0
  64. zepben/ewb/database/sqlite/tables/associations/table_circuits_terminals.py +40 -0
  65. zepben/ewb/database/sqlite/tables/associations/table_customer_agreements_pricing_structures.py +40 -0
  66. zepben/ewb/database/sqlite/tables/associations/table_end_devices_end_device_functions.py +40 -0
  67. zepben/ewb/database/sqlite/tables/associations/table_equipment_equipment_containers.py +40 -0
  68. zepben/ewb/database/sqlite/tables/associations/table_equipment_operational_restrictions.py +40 -0
  69. zepben/ewb/database/sqlite/tables/associations/table_equipment_usage_points.py +40 -0
  70. zepben/ewb/database/sqlite/tables/associations/table_loops_substations.py +43 -0
  71. zepben/ewb/database/sqlite/tables/associations/table_pricing_structures_tariffs.py +40 -0
  72. zepben/ewb/database/sqlite/tables/associations/table_protection_relay_functions_protected_switches.py +40 -0
  73. zepben/ewb/database/sqlite/tables/associations/table_protection_relay_functions_sensors.py +40 -0
  74. zepben/ewb/database/sqlite/tables/associations/table_protection_relay_schemes_protection_relay_functions.py +40 -0
  75. zepben/ewb/database/sqlite/tables/associations/table_synchronous_machines_reactive_capability_curves.py +39 -0
  76. zepben/ewb/database/sqlite/tables/associations/table_usage_points_end_devices.py +40 -0
  77. zepben/ewb/database/sqlite/tables/column.py +37 -0
  78. zepben/ewb/database/sqlite/tables/exceptions.py +10 -0
  79. zepben/ewb/database/sqlite/tables/extensions/__init__.py +4 -0
  80. zepben/ewb/database/sqlite/tables/extensions/iec61968/__init__.py +4 -0
  81. zepben/ewb/database/sqlite/tables/extensions/iec61968/assetinfo/__init__.py +4 -0
  82. zepben/ewb/database/sqlite/tables/extensions/iec61968/assetinfo/table_reclose_delays.py +38 -0
  83. zepben/ewb/database/sqlite/tables/extensions/iec61968/assetinfo/table_relay_info.py +21 -0
  84. zepben/ewb/database/sqlite/tables/extensions/iec61968/metering/__init__.py +4 -0
  85. zepben/ewb/database/sqlite/tables/extensions/iec61968/metering/table_pan_demand_response_functions.py +21 -0
  86. zepben/ewb/database/sqlite/tables/extensions/iec61970/__init__.py +4 -0
  87. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/__init__.py +4 -0
  88. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/core/__init__.py +4 -0
  89. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/core/table_sites.py +15 -0
  90. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/feeder/__init__.py +4 -0
  91. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/feeder/table_loops.py +15 -0
  92. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/feeder/table_lv_feeders.py +20 -0
  93. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/generation/__init__.py +4 -0
  94. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/generation/production/__init__.py +4 -0
  95. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/generation/production/table_ev_charging_units.py +15 -0
  96. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/__init__.py +4 -0
  97. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/table_distance_relays.py +28 -0
  98. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/table_protection_relay_function_thresholds.py +36 -0
  99. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/table_protection_relay_function_time_limits.py +34 -0
  100. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/table_protection_relay_functions.py +24 -0
  101. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/table_protection_relay_schemes.py +20 -0
  102. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/table_protection_relay_systems.py +20 -0
  103. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/table_voltage_relays.py +15 -0
  104. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/wires/__init__.py +4 -0
  105. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/wires/table_battery_controls.py +23 -0
  106. zepben/ewb/database/sqlite/tables/extensions/iec61970/base/wires/table_power_transformer_end_ratings.py +34 -0
  107. zepben/ewb/database/sqlite/tables/iec61968/__init__.py +4 -0
  108. zepben/ewb/database/sqlite/tables/iec61968/assetinfo/__init__.py +4 -0
  109. zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_cable_info.py +15 -0
  110. zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_no_load_tests.py +24 -0
  111. zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_open_circuit_tests.py +24 -0
  112. zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_overhead_wire_info.py +15 -0
  113. zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_power_transformer_info.py +15 -0
  114. zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_short_circuit_tests.py +29 -0
  115. zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_shunt_compensator_info.py +23 -0
  116. zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_switch_info.py +20 -0
  117. zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_transformer_end_info.py +46 -0
  118. zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_transformer_tank_info.py +27 -0
  119. zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_transformer_test.py +19 -0
  120. zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_wire_info.py +19 -0
  121. zepben/ewb/database/sqlite/tables/iec61968/assets/__init__.py +4 -0
  122. zepben/ewb/database/sqlite/tables/iec61968/assets/table_asset_containers.py +14 -0
  123. zepben/ewb/database/sqlite/tables/iec61968/assets/table_asset_functions.py +14 -0
  124. zepben/ewb/database/sqlite/tables/iec61968/assets/table_asset_info.py +14 -0
  125. zepben/ewb/database/sqlite/tables/iec61968/assets/table_asset_organisation_roles.py +14 -0
  126. zepben/ewb/database/sqlite/tables/iec61968/assets/table_asset_owners.py +15 -0
  127. zepben/ewb/database/sqlite/tables/iec61968/assets/table_assets.py +18 -0
  128. zepben/ewb/database/sqlite/tables/iec61968/assets/table_streetlights.py +22 -0
  129. zepben/ewb/database/sqlite/tables/iec61968/assets/table_structures.py +14 -0
  130. zepben/ewb/database/sqlite/tables/iec61968/common/__init__.py +4 -0
  131. zepben/ewb/database/sqlite/tables/iec61968/common/table_agreements.py +14 -0
  132. zepben/ewb/database/sqlite/tables/iec61968/common/table_documents.py +23 -0
  133. zepben/ewb/database/sqlite/tables/iec61968/common/table_location_street_address_field.py +18 -0
  134. zepben/ewb/database/sqlite/tables/iec61968/common/table_location_street_addresses.py +33 -0
  135. zepben/ewb/database/sqlite/tables/iec61968/common/table_locations.py +15 -0
  136. zepben/ewb/database/sqlite/tables/iec61968/common/table_organisation_roles.py +18 -0
  137. zepben/ewb/database/sqlite/tables/iec61968/common/table_organisations.py +15 -0
  138. zepben/ewb/database/sqlite/tables/iec61968/common/table_position_points.py +30 -0
  139. zepben/ewb/database/sqlite/tables/iec61968/common/table_street_addresses.py +26 -0
  140. zepben/ewb/database/sqlite/tables/iec61968/common/table_town_details.py +19 -0
  141. zepben/ewb/database/sqlite/tables/iec61968/customers/__init__.py +4 -0
  142. zepben/ewb/database/sqlite/tables/iec61968/customers/table_customer_agreements.py +27 -0
  143. zepben/ewb/database/sqlite/tables/iec61968/customers/table_customers.py +22 -0
  144. zepben/ewb/database/sqlite/tables/iec61968/customers/table_pricing_structures.py +15 -0
  145. zepben/ewb/database/sqlite/tables/iec61968/customers/table_tariffs.py +15 -0
  146. zepben/ewb/database/sqlite/tables/iec61968/infiec61968/__init__.py +4 -0
  147. zepben/ewb/database/sqlite/tables/iec61968/infiec61968/infassetinfo/__init__.py +4 -0
  148. zepben/ewb/database/sqlite/tables/iec61968/infiec61968/infassetinfo/table_current_transformer_info.py +33 -0
  149. zepben/ewb/database/sqlite/tables/iec61968/infiec61968/infassetinfo/table_potential_transformer_info.py +26 -0
  150. zepben/ewb/database/sqlite/tables/iec61968/infiec61968/infassets/__init__.py +4 -0
  151. zepben/ewb/database/sqlite/tables/iec61968/infiec61968/infassets/table_poles.py +20 -0
  152. zepben/ewb/database/sqlite/tables/iec61968/metering/__init__.py +4 -0
  153. zepben/ewb/database/sqlite/tables/iec61968/metering/table_end_device_functions.py +18 -0
  154. zepben/ewb/database/sqlite/tables/iec61968/metering/table_end_devices.py +19 -0
  155. zepben/ewb/database/sqlite/tables/iec61968/metering/table_meters.py +15 -0
  156. zepben/ewb/database/sqlite/tables/iec61968/metering/table_usage_points.py +23 -0
  157. zepben/ewb/database/sqlite/tables/iec61968/operations/__init__.py +4 -0
  158. zepben/ewb/database/sqlite/tables/iec61968/operations/table_operational_restrictions.py +15 -0
  159. zepben/ewb/database/sqlite/tables/iec61970/__init__.py +4 -0
  160. zepben/ewb/database/sqlite/tables/iec61970/base/__init__.py +4 -0
  161. zepben/ewb/database/sqlite/tables/iec61970/base/auxiliaryequipment/__init__.py +4 -0
  162. zepben/ewb/database/sqlite/tables/iec61970/base/auxiliaryequipment/table_auxiliary_equipment.py +18 -0
  163. zepben/ewb/database/sqlite/tables/iec61970/base/auxiliaryequipment/table_current_transformers.py +21 -0
  164. zepben/ewb/database/sqlite/tables/iec61970/base/auxiliaryequipment/table_fault_indicators.py +15 -0
  165. zepben/ewb/database/sqlite/tables/iec61970/base/auxiliaryequipment/table_potential_transformers.py +21 -0
  166. zepben/ewb/database/sqlite/tables/iec61970/base/auxiliaryequipment/table_sensors.py +14 -0
  167. zepben/ewb/database/sqlite/tables/iec61970/base/core/__init__.py +4 -0
  168. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_ac_dc_terminals.py +14 -0
  169. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_base_voltages.py +20 -0
  170. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_conducting_equipment.py +18 -0
  171. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_connectivity_node_containers.py +14 -0
  172. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_connectivity_nodes.py +15 -0
  173. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_curve_data.py +46 -0
  174. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_curves.py +17 -0
  175. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_equipment.py +20 -0
  176. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_equipment_containers.py +14 -0
  177. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_feeders.py +28 -0
  178. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_geographical_regions.py +15 -0
  179. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_identified_objects.py +29 -0
  180. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_name_types.py +28 -0
  181. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_names.py +36 -0
  182. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_power_system_resources.py +19 -0
  183. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_sub_geographical_regions.py +27 -0
  184. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_substations.py +27 -0
  185. zepben/ewb/database/sqlite/tables/iec61970/base/core/table_terminals.py +35 -0
  186. zepben/ewb/database/sqlite/tables/iec61970/base/diagramlayout/__init__.py +4 -0
  187. zepben/ewb/database/sqlite/tables/iec61970/base/diagramlayout/table_diagram_object_points.py +35 -0
  188. zepben/ewb/database/sqlite/tables/iec61970/base/diagramlayout/table_diagram_objects.py +31 -0
  189. zepben/ewb/database/sqlite/tables/iec61970/base/diagramlayout/table_diagrams.py +21 -0
  190. zepben/ewb/database/sqlite/tables/iec61970/base/equivalents/__init__.py +4 -0
  191. zepben/ewb/database/sqlite/tables/iec61970/base/equivalents/table_equivalent_branches.py +35 -0
  192. zepben/ewb/database/sqlite/tables/iec61970/base/equivalents/table_equivalent_equipment.py +14 -0
  193. zepben/ewb/database/sqlite/tables/iec61970/base/generation/__init__.py +4 -0
  194. zepben/ewb/database/sqlite/tables/iec61970/base/generation/production/__init__.py +4 -0
  195. zepben/ewb/database/sqlite/tables/iec61970/base/generation/production/table_battery_units.py +22 -0
  196. zepben/ewb/database/sqlite/tables/iec61970/base/generation/production/table_photo_voltaic_units.py +15 -0
  197. zepben/ewb/database/sqlite/tables/iec61970/base/generation/production/table_power_electronics_units.py +26 -0
  198. zepben/ewb/database/sqlite/tables/iec61970/base/generation/production/table_power_electronics_wind_units.py +15 -0
  199. zepben/ewb/database/sqlite/tables/iec61970/base/meas/__init__.py +4 -0
  200. zepben/ewb/database/sqlite/tables/iec61970/base/meas/table_accumulators.py +15 -0
  201. zepben/ewb/database/sqlite/tables/iec61970/base/meas/table_analogs.py +20 -0
  202. zepben/ewb/database/sqlite/tables/iec61970/base/meas/table_controls.py +20 -0
  203. zepben/ewb/database/sqlite/tables/iec61970/base/meas/table_discretes.py +15 -0
  204. zepben/ewb/database/sqlite/tables/iec61970/base/meas/table_io_points.py +14 -0
  205. zepben/ewb/database/sqlite/tables/iec61970/base/meas/table_measurements.py +30 -0
  206. zepben/ewb/database/sqlite/tables/iec61970/base/protection/__init__.py +4 -0
  207. zepben/ewb/database/sqlite/tables/iec61970/base/protection/table_current_relays.py +22 -0
  208. zepben/ewb/database/sqlite/tables/iec61970/base/scada/__init__.py +4 -0
  209. zepben/ewb/database/sqlite/tables/iec61970/base/scada/table_remote_controls.py +20 -0
  210. zepben/ewb/database/sqlite/tables/iec61970/base/scada/table_remote_points.py +14 -0
  211. zepben/ewb/database/sqlite/tables/iec61970/base/scada/table_remote_sources.py +20 -0
  212. zepben/ewb/database/sqlite/tables/iec61970/base/wires/__init__.py +4 -0
  213. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_ac_line_segments.py +20 -0
  214. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_breakers.py +20 -0
  215. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_busbar_sections.py +15 -0
  216. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_clamps.py +23 -0
  217. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_conductors.py +21 -0
  218. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_connectors.py +14 -0
  219. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_cuts.py +23 -0
  220. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_disconnectors.py +15 -0
  221. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_earth_fault_compensators.py +22 -0
  222. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_energy_connections.py +14 -0
  223. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_energy_consumer_phases.py +37 -0
  224. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_energy_consumers.py +26 -0
  225. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_energy_source_phases.py +33 -0
  226. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_energy_sources.py +44 -0
  227. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_fuses.py +20 -0
  228. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_ground_disconnectors.py +15 -0
  229. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_grounding_impedances.py +24 -0
  230. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_grounds.py +15 -0
  231. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_jumpers.py +15 -0
  232. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_junctions.py +15 -0
  233. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_linear_shunt_compensators.py +23 -0
  234. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_lines.py +14 -0
  235. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_load_break_switches.py +15 -0
  236. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_per_length_impedances.py +14 -0
  237. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_per_length_line_parameters.py +14 -0
  238. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_per_length_phase_impedances.py +18 -0
  239. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_per_length_sequence_impedances.py +27 -0
  240. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_petersen_coils.py +27 -0
  241. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_phase_impedance_data.py +52 -0
  242. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_power_electronics_connection_phases.py +30 -0
  243. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_power_electronics_connections.py +50 -0
  244. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_power_transformer_ends.py +43 -0
  245. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_power_transformers.py +24 -0
  246. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_protected_switches.py +18 -0
  247. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_ratio_tap_changers.py +28 -0
  248. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_reactive_capability_curves.py +18 -0
  249. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_reclosers.py +15 -0
  250. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_regulating_cond_eq.py +19 -0
  251. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_regulating_controls.py +29 -0
  252. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_rotating_machines.py +36 -0
  253. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_series_compensators.py +25 -0
  254. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_shunt_compensators.py +22 -0
  255. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_static_var_compensator.py +24 -0
  256. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_switches.py +21 -0
  257. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_synchronous_machines.py +95 -0
  258. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_tap_changer_controls.py +28 -0
  259. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_tap_changers.py +25 -0
  260. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_transformer_ends.py +30 -0
  261. zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_transformer_star_impedances.py +32 -0
  262. zepben/ewb/database/sqlite/tables/iec61970/infiec61970/__init__.py +4 -0
  263. zepben/ewb/database/sqlite/tables/iec61970/infiec61970/feeder/__init__.py +4 -0
  264. zepben/ewb/database/sqlite/tables/iec61970/infiec61970/feeder/table_circuits.py +27 -0
  265. zepben/ewb/database/sqlite/tables/sqlite_table.py +142 -0
  266. zepben/ewb/database/sqlite/tables/table_metadata_data_sources.py +21 -0
  267. zepben/ewb/database/sqlite/tables/table_version.py +38 -0
  268. zepben/ewb/dataclassy/__init__.py +15 -0
  269. zepben/ewb/dataclassy/dataclass.py +192 -0
  270. zepben/ewb/dataclassy/decorator.py +35 -0
  271. zepben/ewb/dataclassy/functions.py +80 -0
  272. zepben/ewb/examples/__init__.py +6 -0
  273. zepben/ewb/examples/simple_test_network.py +158 -0
  274. zepben/ewb/exceptions.py +52 -0
  275. zepben/ewb/model/__init__.py +4 -0
  276. zepben/ewb/model/busbranch/__init__.py +4 -0
  277. zepben/ewb/model/busbranch/bus_branch.py +1051 -0
  278. zepben/ewb/model/cim/__init__.py +4 -0
  279. zepben/ewb/model/cim/extensions/__init__.py +4 -0
  280. zepben/ewb/model/cim/extensions/iec61968/__init__.py +4 -0
  281. zepben/ewb/model/cim/extensions/iec61968/assetinfo/__init__.py +4 -0
  282. zepben/ewb/model/cim/extensions/iec61968/assetinfo/relay_info.py +128 -0
  283. zepben/ewb/model/cim/extensions/iec61968/metering/__init__.py +4 -0
  284. zepben/ewb/model/cim/extensions/iec61968/metering/pan_demand_reponse_function.py +112 -0
  285. zepben/ewb/model/cim/extensions/iec61970/__init__.py +4 -0
  286. zepben/ewb/model/cim/extensions/iec61970/base/__init__.py +4 -0
  287. zepben/ewb/model/cim/extensions/iec61970/base/core/__init__.py +4 -0
  288. zepben/ewb/model/cim/extensions/iec61970/base/core/site.py +37 -0
  289. zepben/ewb/model/cim/extensions/iec61970/base/feeder/__init__.py +4 -0
  290. zepben/ewb/model/cim/extensions/iec61970/base/feeder/loop.py +207 -0
  291. zepben/ewb/model/cim/extensions/iec61970/base/feeder/lv_feeder.py +258 -0
  292. zepben/ewb/model/cim/extensions/iec61970/base/generation/__init__.py +4 -0
  293. zepben/ewb/model/cim/extensions/iec61970/base/generation/production/__init__.py +4 -0
  294. zepben/ewb/model/cim/extensions/iec61970/base/generation/production/ev_charging_unit.py +18 -0
  295. zepben/ewb/model/cim/extensions/iec61970/base/protection/__init__.py +4 -0
  296. zepben/ewb/model/cim/extensions/iec61970/base/protection/distance_relay.py +69 -0
  297. zepben/ewb/model/cim/extensions/iec61970/base/protection/power_direction_kind.py +35 -0
  298. zepben/ewb/model/cim/extensions/iec61970/base/protection/protection_kind.py +113 -0
  299. zepben/ewb/model/cim/extensions/iec61970/base/protection/protection_relay_function.py +448 -0
  300. zepben/ewb/model/cim/extensions/iec61970/base/protection/protection_relay_scheme.py +97 -0
  301. zepben/ewb/model/cim/extensions/iec61970/base/protection/protection_relay_system.py +97 -0
  302. zepben/ewb/model/cim/extensions/iec61970/base/protection/relay_setting.py +35 -0
  303. zepben/ewb/model/cim/extensions/iec61970/base/protection/voltage_relay.py +20 -0
  304. zepben/ewb/model/cim/extensions/iec61970/base/wires/__init__.py +4 -0
  305. zepben/ewb/model/cim/extensions/iec61970/base/wires/battery_control.py +36 -0
  306. zepben/ewb/model/cim/extensions/iec61970/base/wires/battery_control_mode.py +82 -0
  307. zepben/ewb/model/cim/extensions/iec61970/base/wires/transformer_cooling_type.py +56 -0
  308. zepben/ewb/model/cim/extensions/iec61970/base/wires/transformer_end_rated_s.py +26 -0
  309. zepben/ewb/model/cim/extensions/iec61970/base/wires/vector_group.py +292 -0
  310. zepben/ewb/model/cim/extensions/zbex.py +17 -0
  311. zepben/ewb/model/cim/iec61968/__init__.py +4 -0
  312. zepben/ewb/model/cim/iec61968/assetinfo/__init__.py +4 -0
  313. zepben/ewb/model/cim/iec61968/assetinfo/cable_info.py +15 -0
  314. zepben/ewb/model/cim/iec61968/assetinfo/no_load_test.py +42 -0
  315. zepben/ewb/model/cim/iec61968/assetinfo/open_circuit_test.py +42 -0
  316. zepben/ewb/model/cim/iec61968/assetinfo/overhead_wire_info.py +15 -0
  317. zepben/ewb/model/cim/iec61968/assetinfo/power_transformer_info.py +103 -0
  318. zepben/ewb/model/cim/iec61968/assetinfo/short_circuit_test.py +67 -0
  319. zepben/ewb/model/cim/iec61968/assetinfo/shunt_compensator_info.py +26 -0
  320. zepben/ewb/model/cim/iec61968/assetinfo/switch_info.py +17 -0
  321. zepben/ewb/model/cim/iec61968/assetinfo/transformer_end_info.py +137 -0
  322. zepben/ewb/model/cim/iec61968/assetinfo/transformer_tank_info.py +108 -0
  323. zepben/ewb/model/cim/iec61968/assetinfo/transformer_test.py +26 -0
  324. zepben/ewb/model/cim/iec61968/assetinfo/wire_info.py +24 -0
  325. zepben/ewb/model/cim/iec61968/assetinfo/wire_material_kind.py +55 -0
  326. zepben/ewb/model/cim/iec61968/assets/__init__.py +4 -0
  327. zepben/ewb/model/cim/iec61968/assets/asset.py +154 -0
  328. zepben/ewb/model/cim/iec61968/assets/asset_container.py +16 -0
  329. zepben/ewb/model/cim/iec61968/assets/asset_function.py +15 -0
  330. zepben/ewb/model/cim/iec61968/assets/asset_info.py +19 -0
  331. zepben/ewb/model/cim/iec61968/assets/asset_organisation_role.py +13 -0
  332. zepben/ewb/model/cim/iec61968/assets/asset_owner.py +13 -0
  333. zepben/ewb/model/cim/iec61968/assets/streetlight.py +29 -0
  334. zepben/ewb/model/cim/iec61968/assets/structure.py +16 -0
  335. zepben/ewb/model/cim/iec61968/common/__init__.py +4 -0
  336. zepben/ewb/model/cim/iec61968/common/agreement.py +16 -0
  337. zepben/ewb/model/cim/iec61968/common/document.py +36 -0
  338. zepben/ewb/model/cim/iec61968/common/location.py +129 -0
  339. zepben/ewb/model/cim/iec61968/common/organisation.py +15 -0
  340. zepben/ewb/model/cim/iec61968/common/organisation_role.py +22 -0
  341. zepben/ewb/model/cim/iec61968/common/position_point.py +44 -0
  342. zepben/ewb/model/cim/iec61968/common/street_address.py +28 -0
  343. zepben/ewb/model/cim/iec61968/common/street_detail.py +45 -0
  344. zepben/ewb/model/cim/iec61968/common/town_detail.py +25 -0
  345. zepben/ewb/model/cim/iec61968/customers/__init__.py +4 -0
  346. zepben/ewb/model/cim/iec61968/customers/customer.py +93 -0
  347. zepben/ewb/model/cim/iec61968/customers/customer_agreement.py +107 -0
  348. zepben/ewb/model/cim/iec61968/customers/customer_kind.py +67 -0
  349. zepben/ewb/model/cim/iec61968/customers/pricing_structure.py +88 -0
  350. zepben/ewb/model/cim/iec61968/customers/tariff.py +18 -0
  351. zepben/ewb/model/cim/iec61968/infiec61968/__init__.py +4 -0
  352. zepben/ewb/model/cim/iec61968/infiec61968/infassetinfo/__init__.py +4 -0
  353. zepben/ewb/model/cim/iec61968/infiec61968/infassetinfo/current_transformer_info.py +51 -0
  354. zepben/ewb/model/cim/iec61968/infiec61968/infassetinfo/potential_transformer_info.py +33 -0
  355. zepben/ewb/model/cim/iec61968/infiec61968/infassetinfo/transformer_construction_kind.py +67 -0
  356. zepben/ewb/model/cim/iec61968/infiec61968/infassetinfo/transformer_function_kind.py +43 -0
  357. zepben/ewb/model/cim/iec61968/infiec61968/infassets/__init__.py +4 -0
  358. zepben/ewb/model/cim/iec61968/infiec61968/infassets/pole.py +87 -0
  359. zepben/ewb/model/cim/iec61968/infiec61968/infassets/streetlight_lamp_kind.py +25 -0
  360. zepben/ewb/model/cim/iec61968/infiec61968/infcommon/__init__.py +4 -0
  361. zepben/ewb/model/cim/iec61968/infiec61968/infcommon/ratio.py +34 -0
  362. zepben/ewb/model/cim/iec61968/metering/__init__.py +4 -0
  363. zepben/ewb/model/cim/iec61968/metering/controlled_appliance.py +150 -0
  364. zepben/ewb/model/cim/iec61968/metering/end_device.py +165 -0
  365. zepben/ewb/model/cim/iec61968/metering/end_device_function.py +17 -0
  366. zepben/ewb/model/cim/iec61968/metering/end_device_function_kind.py +46 -0
  367. zepben/ewb/model/cim/iec61968/metering/meter.py +26 -0
  368. zepben/ewb/model/cim/iec61968/metering/usage_point.py +186 -0
  369. zepben/ewb/model/cim/iec61968/operations/__init__.py +4 -0
  370. zepben/ewb/model/cim/iec61968/operations/operational_restriction.py +92 -0
  371. zepben/ewb/model/cim/iec61970/__init__.py +4 -0
  372. zepben/ewb/model/cim/iec61970/base/__init__.py +4 -0
  373. zepben/ewb/model/cim/iec61970/base/auxiliaryequipment/__init__.py +4 -0
  374. zepben/ewb/model/cim/iec61970/base/auxiliaryequipment/auxiliary_equipment.py +24 -0
  375. zepben/ewb/model/cim/iec61970/base/auxiliaryequipment/current_transformer.py +37 -0
  376. zepben/ewb/model/cim/iec61970/base/auxiliaryequipment/fault_indicator.py +18 -0
  377. zepben/ewb/model/cim/iec61970/base/auxiliaryequipment/potential_transformer.py +38 -0
  378. zepben/ewb/model/cim/iec61970/base/auxiliaryequipment/potential_transformer_kind.py +28 -0
  379. zepben/ewb/model/cim/iec61970/base/auxiliaryequipment/sensor.py +92 -0
  380. zepben/ewb/model/cim/iec61970/base/core/__init__.py +4 -0
  381. zepben/ewb/model/cim/iec61970/base/core/ac_dc_terminal.py +16 -0
  382. zepben/ewb/model/cim/iec61970/base/core/base_voltage.py +17 -0
  383. zepben/ewb/model/cim/iec61970/base/core/conducting_equipment.py +198 -0
  384. zepben/ewb/model/cim/iec61970/base/core/connectivity_node.py +105 -0
  385. zepben/ewb/model/cim/iec61970/base/core/connectivity_node_container.py +15 -0
  386. zepben/ewb/model/cim/iec61970/base/core/curve.py +124 -0
  387. zepben/ewb/model/cim/iec61970/base/core/curve_data.py +29 -0
  388. zepben/ewb/model/cim/iec61970/base/core/equipment.py +366 -0
  389. zepben/ewb/model/cim/iec61970/base/core/equipment_container.py +199 -0
  390. zepben/ewb/model/cim/iec61970/base/core/feeder.py +260 -0
  391. zepben/ewb/model/cim/iec61970/base/core/geographical_region.py +82 -0
  392. zepben/ewb/model/cim/iec61970/base/core/identified_object.py +234 -0
  393. zepben/ewb/model/cim/iec61970/base/core/name.py +36 -0
  394. zepben/ewb/model/cim/iec61970/base/core/name_type.py +203 -0
  395. zepben/ewb/model/cim/iec61970/base/core/phase_code.py +201 -0
  396. zepben/ewb/model/cim/iec61970/base/core/power_system_resource.py +106 -0
  397. zepben/ewb/model/cim/iec61970/base/core/sub_geographical_region.py +93 -0
  398. zepben/ewb/model/cim/iec61970/base/core/substation.py +277 -0
  399. zepben/ewb/model/cim/iec61970/base/core/terminal.py +171 -0
  400. zepben/ewb/model/cim/iec61970/base/diagramlayout/__init__.py +4 -0
  401. zepben/ewb/model/cim/iec61970/base/diagramlayout/diagram.py +109 -0
  402. zepben/ewb/model/cim/iec61970/base/diagramlayout/diagram_object.py +160 -0
  403. zepben/ewb/model/cim/iec61970/base/diagramlayout/diagram_object_point.py +25 -0
  404. zepben/ewb/model/cim/iec61970/base/diagramlayout/diagram_style.py +26 -0
  405. zepben/ewb/model/cim/iec61970/base/diagramlayout/orientation_kind.py +27 -0
  406. zepben/ewb/model/cim/iec61970/base/domain/__init__.py +4 -0
  407. zepben/ewb/model/cim/iec61970/base/domain/unit_symbol.py +492 -0
  408. zepben/ewb/model/cim/iec61970/base/equivalents/__init__.py +4 -0
  409. zepben/ewb/model/cim/iec61970/base/equivalents/equivalent_branch.py +113 -0
  410. zepben/ewb/model/cim/iec61970/base/equivalents/equivalent_equipment.py +15 -0
  411. zepben/ewb/model/cim/iec61970/base/generation/__init__.py +4 -0
  412. zepben/ewb/model/cim/iec61970/base/generation/production/__init__.py +4 -0
  413. zepben/ewb/model/cim/iec61970/base/generation/production/battery_state_kind.py +37 -0
  414. zepben/ewb/model/cim/iec61970/base/generation/production/battery_unit.py +108 -0
  415. zepben/ewb/model/cim/iec61970/base/generation/production/photo_voltaic_unit.py +13 -0
  416. zepben/ewb/model/cim/iec61970/base/generation/production/power_electronics_unit.py +28 -0
  417. zepben/ewb/model/cim/iec61970/base/generation/production/power_electronics_wind_unit.py +13 -0
  418. zepben/ewb/model/cim/iec61970/base/meas/__init__.py +4 -0
  419. zepben/ewb/model/cim/iec61970/base/meas/accumulator.py +13 -0
  420. zepben/ewb/model/cim/iec61970/base/meas/accumulator_value.py +20 -0
  421. zepben/ewb/model/cim/iec61970/base/meas/analog.py +16 -0
  422. zepben/ewb/model/cim/iec61970/base/meas/analog_value.py +20 -0
  423. zepben/ewb/model/cim/iec61970/base/meas/control.py +26 -0
  424. zepben/ewb/model/cim/iec61970/base/meas/discrete.py +13 -0
  425. zepben/ewb/model/cim/iec61970/base/meas/discrete_value.py +20 -0
  426. zepben/ewb/model/cim/iec61970/base/meas/iopoint.py +16 -0
  427. zepben/ewb/model/cim/iec61970/base/meas/measurement.py +60 -0
  428. zepben/ewb/model/cim/iec61970/base/meas/measurement_value.py +21 -0
  429. zepben/ewb/model/cim/iec61970/base/protection/__init__.py +4 -0
  430. zepben/ewb/model/cim/iec61970/base/protection/current_relay.py +23 -0
  431. zepben/ewb/model/cim/iec61970/base/scada/__init__.py +4 -0
  432. zepben/ewb/model/cim/iec61970/base/scada/remote_control.py +22 -0
  433. zepben/ewb/model/cim/iec61970/base/scada/remote_point.py +16 -0
  434. zepben/ewb/model/cim/iec61970/base/scada/remote_source.py +22 -0
  435. zepben/ewb/model/cim/iec61970/base/wires/__init__.py +4 -0
  436. zepben/ewb/model/cim/iec61970/base/wires/ac_line_segment.py +214 -0
  437. zepben/ewb/model/cim/iec61970/base/wires/breaker.py +32 -0
  438. zepben/ewb/model/cim/iec61970/base/wires/busbar_section.py +19 -0
  439. zepben/ewb/model/cim/iec61970/base/wires/clamp.py +32 -0
  440. zepben/ewb/model/cim/iec61970/base/wires/conductor.py +49 -0
  441. zepben/ewb/model/cim/iec61970/base/wires/connector.py +16 -0
  442. zepben/ewb/model/cim/iec61970/base/wires/cut.py +36 -0
  443. zepben/ewb/model/cim/iec61970/base/wires/disconnector.py +17 -0
  444. zepben/ewb/model/cim/iec61970/base/wires/earth_fault_compensator.py +21 -0
  445. zepben/ewb/model/cim/iec61970/base/wires/energy_connection.py +15 -0
  446. zepben/ewb/model/cim/iec61970/base/wires/energy_consumer.py +107 -0
  447. zepben/ewb/model/cim/iec61970/base/wires/energy_consumer_phase.py +56 -0
  448. zepben/ewb/model/cim/iec61970/base/wires/energy_source.py +172 -0
  449. zepben/ewb/model/cim/iec61970/base/wires/energy_source_phase.py +45 -0
  450. zepben/ewb/model/cim/iec61970/base/wires/fuse.py +23 -0
  451. zepben/ewb/model/cim/iec61970/base/wires/ground.py +15 -0
  452. zepben/ewb/model/cim/iec61970/base/wires/ground_disconnector.py +15 -0
  453. zepben/ewb/model/cim/iec61970/base/wires/grounding_impedance.py +19 -0
  454. zepben/ewb/model/cim/iec61970/base/wires/jumper.py +16 -0
  455. zepben/ewb/model/cim/iec61970/base/wires/junction.py +15 -0
  456. zepben/ewb/model/cim/iec61970/base/wires/line.py +13 -0
  457. zepben/ewb/model/cim/iec61970/base/wires/linear_shunt_compensator.py +26 -0
  458. zepben/ewb/model/cim/iec61970/base/wires/load_break_switch.py +14 -0
  459. zepben/ewb/model/cim/iec61970/base/wires/per_length_impedance.py +13 -0
  460. zepben/ewb/model/cim/iec61970/base/wires/per_length_line_parameter.py +13 -0
  461. zepben/ewb/model/cim/iec61970/base/wires/per_length_phase_impedance.py +99 -0
  462. zepben/ewb/model/cim/iec61970/base/wires/per_length_sequence_impedance.py +43 -0
  463. zepben/ewb/model/cim/iec61970/base/wires/petersen_coil.py +22 -0
  464. zepben/ewb/model/cim/iec61970/base/wires/phase_impedance_data.py +37 -0
  465. zepben/ewb/model/cim/iec61970/base/wires/phase_shunt_connection_kind.py +38 -0
  466. zepben/ewb/model/cim/iec61970/base/wires/power_electronics_connection.py +524 -0
  467. zepben/ewb/model/cim/iec61970/base/wires/power_electronics_connection_phase.py +34 -0
  468. zepben/ewb/model/cim/iec61970/base/wires/power_transformer.py +217 -0
  469. zepben/ewb/model/cim/iec61970/base/wires/power_transformer_end.py +208 -0
  470. zepben/ewb/model/cim/iec61970/base/wires/protected_switch.py +96 -0
  471. zepben/ewb/model/cim/iec61970/base/wires/ratio_tap_changer.py +30 -0
  472. zepben/ewb/model/cim/iec61970/base/wires/reactive_capability_curve.py +16 -0
  473. zepben/ewb/model/cim/iec61970/base/wires/recloser.py +15 -0
  474. zepben/ewb/model/cim/iec61970/base/wires/regulating_cond_eq.py +45 -0
  475. zepben/ewb/model/cim/iec61970/base/wires/regulating_control.py +173 -0
  476. zepben/ewb/model/cim/iec61970/base/wires/regulating_control_mode_kind.py +46 -0
  477. zepben/ewb/model/cim/iec61970/base/wires/rotating_machine.py +36 -0
  478. zepben/ewb/model/cim/iec61970/base/wires/series_compensator.py +42 -0
  479. zepben/ewb/model/cim/iec61970/base/wires/shunt_compensator.py +59 -0
  480. zepben/ewb/model/cim/iec61970/base/wires/single_phase_kind.py +105 -0
  481. zepben/ewb/model/cim/iec61970/base/wires/static_var_compensator.py +40 -0
  482. zepben/ewb/model/cim/iec61970/base/wires/svc_control_mode.py +28 -0
  483. zepben/ewb/model/cim/iec61970/base/wires/switch.py +119 -0
  484. zepben/ewb/model/cim/iec61970/base/wires/synchronous_machine.py +168 -0
  485. zepben/ewb/model/cim/iec61970/base/wires/synchronous_machine_kind.py +44 -0
  486. zepben/ewb/model/cim/iec61970/base/wires/tap_changer.py +150 -0
  487. zepben/ewb/model/cim/iec61970/base/wires/tap_changer_control.py +49 -0
  488. zepben/ewb/model/cim/iec61970/base/wires/transformer_end.py +73 -0
  489. zepben/ewb/model/cim/iec61970/base/wires/transformer_star_impedance.py +48 -0
  490. zepben/ewb/model/cim/iec61970/base/wires/winding_connection.py +43 -0
  491. zepben/ewb/model/cim/iec61970/infiec61970/__init__.py +4 -0
  492. zepben/ewb/model/cim/iec61970/infiec61970/feeder/__init__.py +4 -0
  493. zepben/ewb/model/cim/iec61970/infiec61970/feeder/circuit.py +144 -0
  494. zepben/ewb/model/phases.py +168 -0
  495. zepben/ewb/model/resistance_reactance.py +40 -0
  496. zepben/ewb/services/__init__.py +4 -0
  497. zepben/ewb/services/common/__init__.py +16 -0
  498. zepben/ewb/services/common/base_service.py +383 -0
  499. zepben/ewb/services/common/base_service_comparator.py +394 -0
  500. zepben/ewb/services/common/difference.py +47 -0
  501. zepben/ewb/services/common/enum_mapper.py +55 -0
  502. zepben/ewb/services/common/meta/__init__.py +4 -0
  503. zepben/ewb/services/common/meta/data_source.py +16 -0
  504. zepben/ewb/services/common/meta/metadata_collection.py +28 -0
  505. zepben/ewb/services/common/meta/metadata_translations.py +47 -0
  506. zepben/ewb/services/common/meta/service_info.py +22 -0
  507. zepben/ewb/services/common/reference_resolvers.py +374 -0
  508. zepben/ewb/services/common/resolver.py +597 -0
  509. zepben/ewb/services/common/translator/__init__.py +4 -0
  510. zepben/ewb/services/common/translator/base_cim2proto.py +92 -0
  511. zepben/ewb/services/common/translator/base_proto2cim.py +112 -0
  512. zepben/ewb/services/common/translator/service_differences.py +81 -0
  513. zepben/ewb/services/common/translator/util.py +78 -0
  514. zepben/ewb/services/customer/__init__.py +4 -0
  515. zepben/ewb/services/customer/customer_service_comparator.py +52 -0
  516. zepben/ewb/services/customer/customers.py +23 -0
  517. zepben/ewb/services/customer/translator/__init__.py +21 -0
  518. zepben/ewb/services/customer/translator/customer_cim2proto.py +71 -0
  519. zepben/ewb/services/customer/translator/customer_enum_mappers.py +18 -0
  520. zepben/ewb/services/customer/translator/customer_proto2cim.py +87 -0
  521. zepben/ewb/services/diagram/__init__.py +4 -0
  522. zepben/ewb/services/diagram/diagram_service_comparator.py +39 -0
  523. zepben/ewb/services/diagram/diagrams.py +107 -0
  524. zepben/ewb/services/diagram/translator/__init__.py +11 -0
  525. zepben/ewb/services/diagram/translator/diagram_cim2proto.py +51 -0
  526. zepben/ewb/services/diagram/translator/diagram_enum_mappers.py +21 -0
  527. zepben/ewb/services/diagram/translator/diagram_proto2cim.py +61 -0
  528. zepben/ewb/services/measurement/__init__.py +4 -0
  529. zepben/ewb/services/measurement/measurements.py +35 -0
  530. zepben/ewb/services/measurement/translator/__init__.py +6 -0
  531. zepben/ewb/services/measurement/translator/measurement_cim2proto.py +42 -0
  532. zepben/ewb/services/measurement/translator/measurement_proto2cim.py +52 -0
  533. zepben/ewb/services/network/__init__.py +4 -0
  534. zepben/ewb/services/network/network_extensions.py +119 -0
  535. zepben/ewb/services/network/network_service.py +302 -0
  536. zepben/ewb/services/network/network_service_comparator.py +1322 -0
  537. zepben/ewb/services/network/network_state.py +34 -0
  538. zepben/ewb/services/network/tracing/__init__.py +4 -0
  539. zepben/ewb/services/network/tracing/busbranch_trace.py +36 -0
  540. zepben/ewb/services/network/tracing/connectivity/__init__.py +4 -0
  541. zepben/ewb/services/network/tracing/connectivity/connectivity_result.py +105 -0
  542. zepben/ewb/services/network/tracing/connectivity/nominal_phase_path.py +23 -0
  543. zepben/ewb/services/network/tracing/connectivity/phase_paths.py +70 -0
  544. zepben/ewb/services/network/tracing/connectivity/terminal_connectivity_connected.py +226 -0
  545. zepben/ewb/services/network/tracing/connectivity/terminal_connectivity_internal.py +64 -0
  546. zepben/ewb/services/network/tracing/connectivity/transformer_phase_paths.py +202 -0
  547. zepben/ewb/services/network/tracing/connectivity/xy_candidate_phase_paths.py +235 -0
  548. zepben/ewb/services/network/tracing/connectivity/xy_phase_step.py +24 -0
  549. zepben/ewb/services/network/tracing/feeder/__init__.py +4 -0
  550. zepben/ewb/services/network/tracing/feeder/assign_to_feeders.py +202 -0
  551. zepben/ewb/services/network/tracing/feeder/assign_to_lv_feeders.py +202 -0
  552. zepben/ewb/services/network/tracing/feeder/clear_direction.py +80 -0
  553. zepben/ewb/services/network/tracing/feeder/direction_status.py +133 -0
  554. zepben/ewb/services/network/tracing/feeder/feeder_direction.py +107 -0
  555. zepben/ewb/services/network/tracing/feeder/set_direction.py +143 -0
  556. zepben/ewb/services/network/tracing/find_swer_equipment.py +175 -0
  557. zepben/ewb/services/network/tracing/networktrace/__init__.py +4 -0
  558. zepben/ewb/services/network/tracing/networktrace/actions/__init__.py +4 -0
  559. zepben/ewb/services/network/tracing/networktrace/actions/equipment_tree_builder.py +71 -0
  560. zepben/ewb/services/network/tracing/networktrace/actions/tree_node.py +37 -0
  561. zepben/ewb/services/network/tracing/networktrace/compute_data.py +60 -0
  562. zepben/ewb/services/network/tracing/networktrace/conditions/__init__.py +4 -0
  563. zepben/ewb/services/network/tracing/networktrace/conditions/conditions.py +73 -0
  564. zepben/ewb/services/network/tracing/networktrace/conditions/direction_condition.py +63 -0
  565. zepben/ewb/services/network/tracing/networktrace/conditions/equipment_step_limit_condition.py +26 -0
  566. zepben/ewb/services/network/tracing/networktrace/conditions/equipment_type_step_limit_condition.py +44 -0
  567. zepben/ewb/services/network/tracing/networktrace/conditions/network_trace_queue_condition.py +67 -0
  568. zepben/ewb/services/network/tracing/networktrace/conditions/network_trace_stop_condition.py +65 -0
  569. zepben/ewb/services/network/tracing/networktrace/conditions/open_condition.py +39 -0
  570. zepben/ewb/services/network/tracing/networktrace/network_trace.py +450 -0
  571. zepben/ewb/services/network/tracing/networktrace/network_trace_action_type.py +42 -0
  572. zepben/ewb/services/network/tracing/networktrace/network_trace_queue_next.py +84 -0
  573. zepben/ewb/services/network/tracing/networktrace/network_trace_step.py +125 -0
  574. zepben/ewb/services/network/tracing/networktrace/network_trace_step_path_provider.py +351 -0
  575. zepben/ewb/services/network/tracing/networktrace/network_trace_tracker.py +39 -0
  576. zepben/ewb/services/network/tracing/networktrace/operators/__init__.py +14 -0
  577. zepben/ewb/services/network/tracing/networktrace/operators/equipment_container_state_operators.py +264 -0
  578. zepben/ewb/services/network/tracing/networktrace/operators/feeder_direction_state_operations.py +181 -0
  579. zepben/ewb/services/network/tracing/networktrace/operators/in_service_state_operators.py +76 -0
  580. zepben/ewb/services/network/tracing/networktrace/operators/network_state_operators.py +120 -0
  581. zepben/ewb/services/network/tracing/networktrace/operators/open_state_operators.py +104 -0
  582. zepben/ewb/services/network/tracing/networktrace/operators/phase_state_operators.py +56 -0
  583. zepben/ewb/services/network/tracing/networktrace/tracing.py +132 -0
  584. zepben/ewb/services/network/tracing/phases/__init__.py +4 -0
  585. zepben/ewb/services/network/tracing/phases/phase_inferrer.py +205 -0
  586. zepben/ewb/services/network/tracing/phases/phase_status.py +101 -0
  587. zepben/ewb/services/network/tracing/phases/remove_phases.py +143 -0
  588. zepben/ewb/services/network/tracing/phases/set_phases.py +490 -0
  589. zepben/ewb/services/network/tracing/traversal/__init__.py +4 -0
  590. zepben/ewb/services/network/tracing/traversal/context_value_computer.py +63 -0
  591. zepben/ewb/services/network/tracing/traversal/debug_logging.py +124 -0
  592. zepben/ewb/services/network/tracing/traversal/queue.py +112 -0
  593. zepben/ewb/services/network/tracing/traversal/queue_condition.py +75 -0
  594. zepben/ewb/services/network/tracing/traversal/step_action.py +83 -0
  595. zepben/ewb/services/network/tracing/traversal/step_context.py +59 -0
  596. zepben/ewb/services/network/tracing/traversal/stop_condition.py +57 -0
  597. zepben/ewb/services/network/tracing/traversal/traversal.py +634 -0
  598. zepben/ewb/services/network/tracing/traversal/traversal_condition.py +22 -0
  599. zepben/ewb/services/network/tracing/traversal/weighted_priority_queue.py +85 -0
  600. zepben/ewb/services/network/tracing/util.py +93 -0
  601. zepben/ewb/services/network/translator/__init__.py +392 -0
  602. zepben/ewb/services/network/translator/network_cim2proto.py +1782 -0
  603. zepben/ewb/services/network/translator/network_enum_mappers.py +78 -0
  604. zepben/ewb/services/network/translator/network_proto2cim.py +2147 -0
  605. zepben/ewb/services/services.py +48 -0
  606. zepben/ewb/streaming/__init__.py +4 -0
  607. zepben/ewb/streaming/data/__init__.py +4 -0
  608. zepben/ewb/streaming/data/current_state_event.py +314 -0
  609. zepben/ewb/streaming/data/current_state_event_batch.py +25 -0
  610. zepben/ewb/streaming/data/set_current_states_status.py +286 -0
  611. zepben/ewb/streaming/exceptions.py +14 -0
  612. zepben/ewb/streaming/get/__init__.py +4 -0
  613. zepben/ewb/streaming/get/consumer.py +209 -0
  614. zepben/ewb/streaming/get/customer_consumer.py +111 -0
  615. zepben/ewb/streaming/get/diagram_consumer.py +107 -0
  616. zepben/ewb/streaming/get/hierarchy/__init__.py +4 -0
  617. zepben/ewb/streaming/get/hierarchy/data.py +27 -0
  618. zepben/ewb/streaming/get/included_energized_containers.py +34 -0
  619. zepben/ewb/streaming/get/included_energizing_containers.py +34 -0
  620. zepben/ewb/streaming/get/network_consumer.py +870 -0
  621. zepben/ewb/streaming/get/query_network_state_client.py +64 -0
  622. zepben/ewb/streaming/get/query_network_state_service.py +94 -0
  623. zepben/ewb/streaming/grpc/__init__.py +4 -0
  624. zepben/ewb/streaming/grpc/auth_token_plugin.py +24 -0
  625. zepben/ewb/streaming/grpc/connect.py +209 -0
  626. zepben/ewb/streaming/grpc/grpc.py +107 -0
  627. zepben/ewb/streaming/grpc/grpc_channel_builder.py +185 -0
  628. zepben/ewb/streaming/mutations/__init__.py +4 -0
  629. zepben/ewb/streaming/mutations/update_network_state_client.py +80 -0
  630. zepben/ewb/streaming/mutations/update_network_state_service.py +61 -0
  631. zepben/ewb/testing/__init__.py +4 -0
  632. zepben/ewb/testing/test_network_builder.py +816 -0
  633. zepben/ewb/types.py +17 -0
  634. zepben/ewb/util.py +189 -0
  635. zepben_ewb-1.0.0b1.dist-info/METADATA +102 -0
  636. zepben_ewb-1.0.0b1.dist-info/RECORD +639 -0
  637. zepben_ewb-1.0.0b1.dist-info/WHEEL +5 -0
  638. zepben_ewb-1.0.0b1.dist-info/licenses/LICENSE +374 -0
  639. zepben_ewb-1.0.0b1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,202 @@
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
+ __all__ = ["transformer_phase_paths", "add_neutral"]
7
+
8
+ from typing import Dict, List
9
+
10
+ from zepben.ewb import SinglePhaseKind as Phase, NominalPhasePath, PhaseCode
11
+
12
+
13
+ def _path(from_phase: Phase, to_phase: Phase) -> NominalPhasePath:
14
+ # noinspection PyArgumentList
15
+ return NominalPhasePath(from_phase, to_phase)
16
+
17
+
18
+ # This is used to indicate that a transformer adds a neutral, and it should be energised from the transformer.
19
+ add_neutral = _path(Phase.NONE, Phase.N)
20
+
21
+ transformer_phase_paths: Dict[PhaseCode, Dict[PhaseCode, List[NominalPhasePath]]] = {
22
+ PhaseCode.ABCN: {
23
+ PhaseCode.ABCN: [_path(Phase.A, Phase.A), _path(Phase.B, Phase.B), _path(Phase.C, Phase.C), _path(Phase.N, Phase.N)],
24
+ PhaseCode.ABC: [_path(Phase.A, Phase.A), _path(Phase.B, Phase.B), _path(Phase.C, Phase.C)],
25
+ },
26
+ PhaseCode.AN: {
27
+ PhaseCode.AN: [_path(Phase.A, Phase.A), _path(Phase.N, Phase.N)],
28
+ PhaseCode.XN: [_path(Phase.A, Phase.X), _path(Phase.N, Phase.N)],
29
+ PhaseCode.AB: [_path(Phase.A, Phase.A), _path(Phase.NONE, Phase.B)],
30
+ PhaseCode.XY: [_path(Phase.A, Phase.X), _path(Phase.NONE, Phase.Y)],
31
+ PhaseCode.X: [_path(Phase.A, Phase.X)],
32
+ PhaseCode.A: [_path(Phase.A, Phase.A)],
33
+ },
34
+ PhaseCode.BN: {
35
+ PhaseCode.BN: [_path(Phase.B, Phase.B), _path(Phase.N, Phase.N)],
36
+ PhaseCode.XN: [_path(Phase.B, Phase.X), _path(Phase.N, Phase.N)],
37
+ PhaseCode.BC: [_path(Phase.B, Phase.B), _path(Phase.NONE, Phase.C)],
38
+ PhaseCode.XY: [_path(Phase.B, Phase.X), _path(Phase.NONE, Phase.Y)],
39
+ PhaseCode.B: [_path(Phase.B, Phase.B)],
40
+ PhaseCode.X: [_path(Phase.B, Phase.X)],
41
+ },
42
+ PhaseCode.CN: {
43
+ PhaseCode.CN: [_path(Phase.C, Phase.C), _path(Phase.N, Phase.N)],
44
+ PhaseCode.XN: [_path(Phase.C, Phase.X), _path(Phase.N, Phase.N)],
45
+ PhaseCode.AC: [_path(Phase.C, Phase.C), _path(Phase.NONE, Phase.A)],
46
+ PhaseCode.XY: [_path(Phase.C, Phase.X), _path(Phase.NONE, Phase.Y)],
47
+ PhaseCode.C: [_path(Phase.C, Phase.C)],
48
+ PhaseCode.X: [_path(Phase.C, Phase.X)],
49
+ },
50
+ PhaseCode.XN: {
51
+ PhaseCode.AN: [_path(Phase.X, Phase.A), _path(Phase.N, Phase.N)],
52
+ PhaseCode.BN: [_path(Phase.X, Phase.B), _path(Phase.N, Phase.N)],
53
+ PhaseCode.CN: [_path(Phase.X, Phase.C), _path(Phase.N, Phase.N)],
54
+ PhaseCode.XN: [_path(Phase.X, Phase.X), _path(Phase.N, Phase.N)],
55
+ PhaseCode.AB: [_path(Phase.X, Phase.A), _path(Phase.NONE, Phase.B)],
56
+ PhaseCode.BC: [_path(Phase.X, Phase.B), _path(Phase.NONE, Phase.C)],
57
+ PhaseCode.AC: [_path(Phase.X, Phase.C), _path(Phase.NONE, Phase.A)],
58
+ PhaseCode.XY: [_path(Phase.X, Phase.X), _path(Phase.NONE, Phase.Y)],
59
+ PhaseCode.A: [_path(Phase.X, Phase.A)],
60
+ PhaseCode.B: [_path(Phase.X, Phase.B)],
61
+ PhaseCode.C: [_path(Phase.X, Phase.C)],
62
+ PhaseCode.X: [_path(Phase.X, Phase.X)],
63
+ },
64
+ PhaseCode.ABC: {
65
+ PhaseCode.ABCN: [_path(Phase.A, Phase.A), _path(Phase.B, Phase.B), _path(Phase.C, Phase.C), add_neutral],
66
+ PhaseCode.ABC: [_path(Phase.A, Phase.A), _path(Phase.B, Phase.B), _path(Phase.C, Phase.C)],
67
+ },
68
+ PhaseCode.ABN: {
69
+ PhaseCode.ABN: [_path(Phase.A, Phase.A), _path(Phase.B, Phase.B), _path(Phase.N, Phase.N)],
70
+ PhaseCode.XYN: [_path(Phase.A, Phase.X), _path(Phase.B, Phase.Y), _path(Phase.N, Phase.N)],
71
+ PhaseCode.AB: [_path(Phase.A, Phase.A), _path(Phase.B, Phase.B)],
72
+ PhaseCode.XY: [_path(Phase.A, Phase.X), _path(Phase.B, Phase.Y)],
73
+ PhaseCode.A: [_path(Phase.A, Phase.A)],
74
+ PhaseCode.X: [_path(Phase.A, Phase.X)],
75
+ },
76
+ PhaseCode.BCN: {
77
+ PhaseCode.BCN: [_path(Phase.B, Phase.B), _path(Phase.C, Phase.C), _path(Phase.N, Phase.N)],
78
+ PhaseCode.XYN: [_path(Phase.B, Phase.X), _path(Phase.C, Phase.Y), _path(Phase.N, Phase.N)],
79
+ PhaseCode.BC: [_path(Phase.B, Phase.B), _path(Phase.C, Phase.C)],
80
+ PhaseCode.XY: [_path(Phase.B, Phase.X), _path(Phase.C, Phase.Y)],
81
+ PhaseCode.B: [_path(Phase.B, Phase.B)],
82
+ PhaseCode.X: [_path(Phase.B, Phase.X)],
83
+ },
84
+ PhaseCode.ACN: {
85
+ PhaseCode.ACN: [_path(Phase.A, Phase.A), _path(Phase.C, Phase.C), _path(Phase.N, Phase.N)],
86
+ PhaseCode.XYN: [_path(Phase.A, Phase.X), _path(Phase.C, Phase.Y), _path(Phase.N, Phase.N)],
87
+ PhaseCode.AC: [_path(Phase.A, Phase.A), _path(Phase.C, Phase.C)],
88
+ PhaseCode.XY: [_path(Phase.A, Phase.X), _path(Phase.C, Phase.Y)],
89
+ PhaseCode.C: [_path(Phase.C, Phase.C)],
90
+ PhaseCode.X: [_path(Phase.C, Phase.X)],
91
+ },
92
+ PhaseCode.XYN: {
93
+ PhaseCode.ABN: [_path(Phase.X, Phase.A), _path(Phase.Y, Phase.B), _path(Phase.N, Phase.N)],
94
+ PhaseCode.BCN: [_path(Phase.X, Phase.B), _path(Phase.Y, Phase.C), _path(Phase.N, Phase.N)],
95
+ PhaseCode.ACN: [_path(Phase.X, Phase.A), _path(Phase.Y, Phase.C), _path(Phase.N, Phase.N)],
96
+ PhaseCode.XYN: [_path(Phase.X, Phase.X), _path(Phase.Y, Phase.Y), _path(Phase.N, Phase.N)],
97
+ PhaseCode.AB: [_path(Phase.X, Phase.A), _path(Phase.Y, Phase.B)],
98
+ PhaseCode.BC: [_path(Phase.X, Phase.B), _path(Phase.Y, Phase.C)],
99
+ PhaseCode.AC: [_path(Phase.X, Phase.A), _path(Phase.Y, Phase.C)],
100
+ PhaseCode.XY: [_path(Phase.X, Phase.X), _path(Phase.Y, Phase.Y)],
101
+ PhaseCode.A: [_path(Phase.X, Phase.A)],
102
+ PhaseCode.B: [_path(Phase.X, Phase.B)],
103
+ PhaseCode.C: [_path(Phase.X, Phase.C)],
104
+ PhaseCode.X: [_path(Phase.X, Phase.X)],
105
+ },
106
+ PhaseCode.AB: {
107
+ PhaseCode.ABN: [_path(Phase.A, Phase.A), _path(Phase.B, Phase.B), add_neutral],
108
+ PhaseCode.XYN: [_path(Phase.A, Phase.X), _path(Phase.B, Phase.Y), add_neutral],
109
+ PhaseCode.AN: [_path(Phase.A, Phase.A), add_neutral],
110
+ PhaseCode.XN: [_path(Phase.A, Phase.X), add_neutral],
111
+ PhaseCode.AB: [_path(Phase.A, Phase.A), _path(Phase.B, Phase.B)],
112
+ PhaseCode.XY: [_path(Phase.A, Phase.X), _path(Phase.B, Phase.Y)],
113
+ PhaseCode.A: [_path(Phase.A, Phase.A)],
114
+ PhaseCode.X: [_path(Phase.A, Phase.X)],
115
+ },
116
+ PhaseCode.BC: {
117
+ PhaseCode.BCN: [_path(Phase.B, Phase.B), _path(Phase.C, Phase.C), add_neutral],
118
+ PhaseCode.XYN: [_path(Phase.B, Phase.X), _path(Phase.C, Phase.Y), add_neutral],
119
+ PhaseCode.BN: [_path(Phase.B, Phase.B), add_neutral],
120
+ PhaseCode.XN: [_path(Phase.B, Phase.X), add_neutral],
121
+ PhaseCode.BC: [_path(Phase.B, Phase.B), _path(Phase.C, Phase.C)],
122
+ PhaseCode.XY: [_path(Phase.B, Phase.X), _path(Phase.C, Phase.Y)],
123
+ PhaseCode.B: [_path(Phase.B, Phase.B)],
124
+ PhaseCode.X: [_path(Phase.B, Phase.X)],
125
+ },
126
+ PhaseCode.AC: {
127
+ PhaseCode.ACN: [_path(Phase.A, Phase.A), _path(Phase.C, Phase.C), add_neutral],
128
+ PhaseCode.XYN: [_path(Phase.A, Phase.X), _path(Phase.C, Phase.Y), add_neutral],
129
+ PhaseCode.CN: [_path(Phase.C, Phase.C), add_neutral],
130
+ PhaseCode.XN: [_path(Phase.C, Phase.X), add_neutral],
131
+ PhaseCode.AC: [_path(Phase.A, Phase.A), _path(Phase.C, Phase.C)],
132
+ PhaseCode.XY: [_path(Phase.A, Phase.X), _path(Phase.C, Phase.Y)],
133
+ PhaseCode.C: [_path(Phase.C, Phase.C)],
134
+ PhaseCode.X: [_path(Phase.C, Phase.X)],
135
+ },
136
+ PhaseCode.XY: {
137
+ PhaseCode.ABN: [_path(Phase.X, Phase.A), _path(Phase.Y, Phase.B), add_neutral],
138
+ PhaseCode.BCN: [_path(Phase.X, Phase.B), _path(Phase.Y, Phase.C), add_neutral],
139
+ PhaseCode.ACN: [_path(Phase.X, Phase.A), _path(Phase.Y, Phase.C), add_neutral],
140
+ PhaseCode.XYN: [_path(Phase.X, Phase.X), _path(Phase.Y, Phase.Y), add_neutral],
141
+ PhaseCode.AN: [_path(Phase.X, Phase.A), add_neutral],
142
+ PhaseCode.BN: [_path(Phase.X, Phase.B), add_neutral],
143
+ PhaseCode.CN: [_path(Phase.X, Phase.C), add_neutral],
144
+ PhaseCode.XN: [_path(Phase.X, Phase.X), add_neutral],
145
+ PhaseCode.AB: [_path(Phase.X, Phase.A), _path(Phase.Y, Phase.B)],
146
+ PhaseCode.BC: [_path(Phase.X, Phase.B), _path(Phase.Y, Phase.C)],
147
+ PhaseCode.AC: [_path(Phase.X, Phase.A), _path(Phase.Y, Phase.C)],
148
+ PhaseCode.XY: [_path(Phase.X, Phase.X), _path(Phase.Y, Phase.Y)],
149
+ PhaseCode.A: [_path(Phase.X, Phase.A)],
150
+ PhaseCode.B: [_path(Phase.X, Phase.B)],
151
+ PhaseCode.C: [_path(Phase.X, Phase.C)],
152
+ PhaseCode.X: [_path(Phase.X, Phase.X)],
153
+ },
154
+ PhaseCode.A: {
155
+ PhaseCode.AN: [_path(Phase.A, Phase.A), add_neutral],
156
+ PhaseCode.XN: [_path(Phase.A, Phase.X), add_neutral],
157
+ PhaseCode.AB: [_path(Phase.A, Phase.A), _path(Phase.NONE, Phase.B)],
158
+ PhaseCode.XY: [_path(Phase.A, Phase.X), _path(Phase.NONE, Phase.Y)],
159
+ PhaseCode.A: [_path(Phase.A, Phase.A)],
160
+ PhaseCode.X: [_path(Phase.A, Phase.X)],
161
+ PhaseCode.ABN: [_path(Phase.A, Phase.A), _path(Phase.NONE, Phase.B), add_neutral],
162
+ PhaseCode.XYN: [_path(Phase.A, Phase.X), _path(Phase.NONE, Phase.Y), add_neutral],
163
+ },
164
+ PhaseCode.B: {
165
+ PhaseCode.BN: [_path(Phase.B, Phase.B), add_neutral],
166
+ PhaseCode.XN: [_path(Phase.B, Phase.X), add_neutral],
167
+ PhaseCode.BC: [_path(Phase.B, Phase.B), _path(Phase.NONE, Phase.C)],
168
+ PhaseCode.XY: [_path(Phase.B, Phase.X), _path(Phase.NONE, Phase.Y)],
169
+ PhaseCode.B: [_path(Phase.B, Phase.B)],
170
+ PhaseCode.X: [_path(Phase.B, Phase.X)],
171
+ PhaseCode.BCN: [_path(Phase.B, Phase.B), _path(Phase.NONE, Phase.C), add_neutral],
172
+ PhaseCode.XYN: [_path(Phase.B, Phase.X), _path(Phase.NONE, Phase.Y), add_neutral],
173
+ },
174
+ PhaseCode.C: {
175
+ PhaseCode.CN: [_path(Phase.C, Phase.C), add_neutral],
176
+ PhaseCode.XN: [_path(Phase.C, Phase.X), add_neutral],
177
+ PhaseCode.AC: [_path(Phase.C, Phase.C), _path(Phase.NONE, Phase.A)],
178
+ PhaseCode.XY: [_path(Phase.C, Phase.X), _path(Phase.NONE, Phase.Y)],
179
+ PhaseCode.C: [_path(Phase.C, Phase.C)],
180
+ PhaseCode.X: [_path(Phase.C, Phase.X)],
181
+ PhaseCode.ACN: [_path(Phase.C, Phase.C), _path(Phase.NONE, Phase.A), add_neutral],
182
+ PhaseCode.XYN: [_path(Phase.C, Phase.X), _path(Phase.NONE, Phase.Y), add_neutral],
183
+ },
184
+ PhaseCode.X: {
185
+ PhaseCode.AN: [_path(Phase.X, Phase.A), add_neutral],
186
+ PhaseCode.BN: [_path(Phase.X, Phase.B), add_neutral],
187
+ PhaseCode.CN: [_path(Phase.X, Phase.C), add_neutral],
188
+ PhaseCode.XN: [_path(Phase.X, Phase.X), add_neutral],
189
+ PhaseCode.AB: [_path(Phase.X, Phase.A), _path(Phase.NONE, Phase.B)],
190
+ PhaseCode.BC: [_path(Phase.X, Phase.B), _path(Phase.NONE, Phase.C)],
191
+ PhaseCode.AC: [_path(Phase.X, Phase.C), _path(Phase.NONE, Phase.A)],
192
+ PhaseCode.XY: [_path(Phase.X, Phase.X), _path(Phase.NONE, Phase.Y)],
193
+ PhaseCode.A: [_path(Phase.X, Phase.A)],
194
+ PhaseCode.B: [_path(Phase.X, Phase.B)],
195
+ PhaseCode.C: [_path(Phase.X, Phase.C)],
196
+ PhaseCode.X: [_path(Phase.X, Phase.X)],
197
+ PhaseCode.ABN: [_path(Phase.X, Phase.A), _path(Phase.NONE, Phase.B), add_neutral],
198
+ PhaseCode.BCN: [_path(Phase.X, Phase.B), _path(Phase.NONE, Phase.C), add_neutral],
199
+ PhaseCode.ACN: [_path(Phase.X, Phase.C), _path(Phase.NONE, Phase.A), add_neutral],
200
+ PhaseCode.XYN: [_path(Phase.X, Phase.X), _path(Phase.NONE, Phase.Y), add_neutral],
201
+ },
202
+ }
@@ -0,0 +1,235 @@
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
+ __all__ = ["X_PRIORITY", "Y_PRIORITY", "XyCandidatePhasePaths", "is_before", "is_after"]
7
+
8
+ from collections import Counter
9
+ from itertools import takewhile
10
+ from typing import List, Dict, Tuple, Optional, Counter as CounterType
11
+
12
+ from zepben.ewb import SinglePhaseKind, PhaseCode
13
+ from zepben.ewb.dataclassy import dataclass
14
+
15
+ X_PRIORITY = [SinglePhaseKind.A, SinglePhaseKind.B, SinglePhaseKind.C]
16
+ """
17
+ The pathing priority for nominal phase X
18
+ """
19
+
20
+ Y_PRIORITY = [SinglePhaseKind.C, SinglePhaseKind.B]
21
+ """
22
+ The pathing priority for nominal phase X
23
+ """
24
+
25
+
26
+ def is_before(phase: SinglePhaseKind, before: Optional[SinglePhaseKind]) -> bool:
27
+ if (before is None) or (before == SinglePhaseKind.NONE):
28
+ return True
29
+ elif before == SinglePhaseKind.A:
30
+ return False
31
+ elif before == SinglePhaseKind.B:
32
+ return phase == SinglePhaseKind.A
33
+ elif before == SinglePhaseKind.C:
34
+ return (phase == SinglePhaseKind.A) or (phase == SinglePhaseKind.B)
35
+ else:
36
+ raise ValueError("INTERNAL ERROR: is_before should only ever be checking against valid Y phases. If you get this message you need to ask the dev "
37
+ "team to go put the planets back into alignment as they stuffed something up!")
38
+
39
+
40
+ def is_after(phase: SinglePhaseKind, after: Optional[SinglePhaseKind]) -> bool:
41
+ if (after is None) or (after == SinglePhaseKind.NONE):
42
+ return True
43
+ elif after == SinglePhaseKind.C:
44
+ return False
45
+ elif after == SinglePhaseKind.B:
46
+ return phase == SinglePhaseKind.C
47
+ elif after == SinglePhaseKind.A:
48
+ return (phase == SinglePhaseKind.C) or (phase == SinglePhaseKind.B)
49
+ else:
50
+ raise ValueError("INTERNAL ERROR: is_after should only ever be checking against valid X phases. If you get this message you need to ask the dev "
51
+ "team to go put the planets back into alignment as they stuffed something up!")
52
+
53
+
54
+ @dataclass(slots=True)
55
+ class XyCandidatePhasePaths:
56
+ """
57
+ Used to track the candidate and know paths for XY phase connectivity.
58
+ """
59
+
60
+ _known_tracking: Dict[SinglePhaseKind, SinglePhaseKind] = {}
61
+ """
62
+ Map of nominal phase to known phase.
63
+ """
64
+
65
+ _candidate_tracking: Dict[SinglePhaseKind, List[SinglePhaseKind]] = {}
66
+ """
67
+ Map of nominal phase to list of candidate phases.
68
+ """
69
+
70
+ def add_known(self, xy_phase: SinglePhaseKind, known_phase: SinglePhaseKind):
71
+ """
72
+ Add a `known_phase` for the specified `xy_phase`. If there is already a `known_phase` the new value will be ignored.
73
+
74
+ `xy_phase` The phase that is being tracked.
75
+
76
+ `known_phase` The phase that should be allocated to the tracked phase.
77
+
78
+ Raises `NominalPhaseException` if the `xy_phase` is invalid.
79
+ """
80
+ _validate_for_tracking(xy_phase)
81
+ if xy_phase not in self._known_tracking:
82
+ self._known_tracking[xy_phase] = known_phase
83
+
84
+ def add_candidates(self, xy_phase: SinglePhaseKind, candidate_phases: List[SinglePhaseKind]):
85
+ """
86
+ Add `candidate_phases` for the specified `xy_phase`. If the same candidate has been found from more than
87
+ one path it should be added multiple times
88
+
89
+ `xy_phase` The phase that is being tracked.
90
+
91
+ `candidate_phases` The phases that could be allocated to the tracked phase.
92
+
93
+ Raises `NominalPhaseException` if the `xy_phase` is invalid.
94
+
95
+ Raises `PhaseException` if the `candidate_phases` is invalid.
96
+ """
97
+ _validate_for_tracking(xy_phase)
98
+ if xy_phase not in self._candidate_tracking:
99
+ self._candidate_tracking[xy_phase] = []
100
+
101
+ self._candidate_tracking[xy_phase].extend([it for it in candidate_phases if _is_valid_candidate(it, xy_phase)])
102
+
103
+ def calculate_paths(self) -> Dict[SinglePhaseKind, SinglePhaseKind]:
104
+ """
105
+ Calculate the paths for the tracked phases taking into account the following:
106
+ 1. Known phases take preference.
107
+ 2. X is always a "lower" phase than Y.
108
+ 3. If multiple candidates are valid then the one with the most occurrences will be chosen.
109
+ 4. If multiple candidates are valid and are equally common, the phases will be chosen with the following priority maintaining the above rules:
110
+ X: A, B then C
111
+ Y: C then B
112
+ """
113
+ paths = {}
114
+
115
+ known_x = self._known_tracking.get(SinglePhaseKind.X)
116
+ if known_x is not None:
117
+ paths[SinglePhaseKind.X] = known_x
118
+
119
+ known_y = self._known_tracking.get(SinglePhaseKind.Y)
120
+ if (known_y is not None) and (known_x != known_y):
121
+ paths[SinglePhaseKind.Y] = known_y
122
+ else:
123
+ known_y = None
124
+
125
+ if (known_x is not None) and (known_y is not None):
126
+ return paths
127
+
128
+ candidate_phase_counts = {xy: Counter(candidates) for xy, candidates in self._candidate_tracking.items()}
129
+ if known_x is not None:
130
+ candidates = candidate_phase_counts.get(SinglePhaseKind.Y)
131
+ if candidates:
132
+ paths[SinglePhaseKind.Y] = self._find_candidate(candidates, priority=Y_PRIORITY, after=known_x)
133
+ else:
134
+ paths[SinglePhaseKind.Y] = SinglePhaseKind.NONE
135
+ elif known_y is not None:
136
+ candidates = candidate_phase_counts.get(SinglePhaseKind.X)
137
+ if candidates:
138
+ paths[SinglePhaseKind.X] = self._find_candidate(candidates, priority=X_PRIORITY, before=known_y)
139
+ else:
140
+ paths[SinglePhaseKind.X] = SinglePhaseKind.NONE
141
+ else:
142
+ x_candidate, y_candidate = self._process_candidates(candidate_phase_counts)
143
+ paths[SinglePhaseKind.X] = x_candidate
144
+ paths[SinglePhaseKind.Y] = y_candidate
145
+
146
+ return paths
147
+
148
+ def _process_candidates(self, candidate_phase_counts: Dict[SinglePhaseKind, CounterType[SinglePhaseKind]]) -> Tuple[SinglePhaseKind, SinglePhaseKind]:
149
+ candidate_x_counts = candidate_phase_counts.get(SinglePhaseKind.X, Counter())
150
+ candidate_y_counts = candidate_phase_counts.get(SinglePhaseKind.Y, Counter())
151
+
152
+ if not candidate_x_counts:
153
+ return SinglePhaseKind.NONE, self._find_candidate(candidate_y_counts, priority=Y_PRIORITY)
154
+ elif len(candidate_x_counts) == 1:
155
+ x_candidate = list(candidate_x_counts.keys())[0]
156
+ return x_candidate, self._find_candidate(candidate_y_counts, priority=Y_PRIORITY, after=x_candidate)
157
+ elif not candidate_y_counts:
158
+ return self._find_candidate(candidate_x_counts, priority=X_PRIORITY), SinglePhaseKind.NONE
159
+ elif len(candidate_y_counts) == 1:
160
+ y_candidate = list(candidate_y_counts.keys())[0]
161
+ return self._find_candidate(candidate_x_counts, priority=X_PRIORITY, before=y_candidate), y_candidate
162
+ else:
163
+ x_candidate = self._find_candidate(candidate_x_counts, priority=X_PRIORITY)
164
+ y_candidate = self._find_candidate(candidate_y_counts, priority=Y_PRIORITY)
165
+
166
+ if is_before(x_candidate, y_candidate):
167
+ return x_candidate, y_candidate
168
+ elif candidate_x_counts[x_candidate] > candidate_y_counts[y_candidate]:
169
+ return x_candidate, self._find_candidate(candidate_y_counts, priority=Y_PRIORITY, after=x_candidate)
170
+ elif candidate_y_counts[y_candidate] > candidate_x_counts[x_candidate]:
171
+ return self._find_candidate(candidate_x_counts, priority=X_PRIORITY, before=y_candidate), y_candidate
172
+ else:
173
+ x_candidate2 = self._find_candidate(candidate_x_counts, priority=X_PRIORITY, before=y_candidate)
174
+ y_candidate2 = self._find_candidate(candidate_y_counts, priority=Y_PRIORITY, after=x_candidate)
175
+
176
+ if x_candidate2 == SinglePhaseKind.NONE:
177
+ return x_candidate, y_candidate2
178
+ elif y_candidate2 == SinglePhaseKind.NONE:
179
+ return x_candidate2, y_candidate
180
+ elif candidate_x_counts[x_candidate2] > candidate_y_counts[y_candidate2]:
181
+ return x_candidate2, y_candidate
182
+ elif candidate_y_counts[y_candidate2] > candidate_x_counts[x_candidate2]:
183
+ return x_candidate, y_candidate2
184
+ else:
185
+ return x_candidate, y_candidate2
186
+
187
+ @staticmethod
188
+ def _find_candidate(
189
+ candidate_counts: CounterType[SinglePhaseKind],
190
+ priority: List[SinglePhaseKind],
191
+ before: Optional[SinglePhaseKind] = None,
192
+ after: Optional[SinglePhaseKind] = None
193
+ ) -> SinglePhaseKind:
194
+ valid_candidates = [(phase, count) for (phase, count) in candidate_counts.most_common() if is_before(phase, before) and is_after(phase, after)]
195
+ if not valid_candidates:
196
+ return SinglePhaseKind.NONE
197
+ elif len(valid_candidates) == 1:
198
+ return valid_candidates[0][0]
199
+
200
+ candidates = list(takewhile(lambda cand: cand[1] == valid_candidates[0][1], valid_candidates))
201
+ if len(candidates) == 1:
202
+ return candidates[0][0]
203
+
204
+ for phase in priority:
205
+ for candidate, _ in candidates:
206
+ if candidate == phase:
207
+ return candidate
208
+
209
+ raise ValueError("INTERNAL ERROR: If you get here it means you did not limit the candidates to only valid phases, go fix that!")
210
+
211
+
212
+ def _validate_for_tracking(phase: SinglePhaseKind):
213
+ if phase not in PhaseCode.XY:
214
+ raise ValueError(f"Unable to track phase {phase}, expected X or Y.")
215
+
216
+
217
+ def _is_valid_candidate(phase: SinglePhaseKind, xy_phase: SinglePhaseKind) -> bool:
218
+ if xy_phase == SinglePhaseKind.X:
219
+ return _is_valid_candidate_x(phase)
220
+ else:
221
+ return _is_valid_candidate_y(phase)
222
+
223
+
224
+ def _is_valid_candidate_x(phase: SinglePhaseKind) -> bool:
225
+ if phase in PhaseCode.ABC:
226
+ return True
227
+ else:
228
+ raise ValueError(f"Unable to use phase {phase} as a candidate, expected A, B or C.")
229
+
230
+
231
+ def _is_valid_candidate_y(phase: SinglePhaseKind) -> bool:
232
+ if phase in PhaseCode.BC:
233
+ return True
234
+ else:
235
+ raise ValueError(f"Unable to use phase {phase} as a candidate, expected B or C.")
@@ -0,0 +1,24 @@
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
+ __all__ = ["XyPhaseStep"]
7
+
8
+ from zepben.ewb.dataclassy import dataclass
9
+
10
+ from zepben.ewb import Terminal, PhaseCode
11
+
12
+
13
+ @dataclass(slots=True)
14
+ class XyPhaseStep(object):
15
+
16
+ terminal: Terminal
17
+ """
18
+ The incoming terminal
19
+ """
20
+
21
+ phase_code: PhaseCode
22
+ """
23
+ The phases used to get to this step (should only be, XY, X or Y)
24
+ """
@@ -0,0 +1,4 @@
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/.
@@ -0,0 +1,202 @@
1
+ # Copyright 2025 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__ = ["AssignToFeeders", "BaseFeedersInternal"]
9
+
10
+ from collections.abc import Collection
11
+ from logging import Logger
12
+ from typing import Iterable, Union, List, Dict, Any, Set, Type, Generator, TYPE_CHECKING
13
+
14
+ from zepben.ewb import Switch, ProtectedSwitch, PowerElectronicsConnection
15
+ from zepben.ewb.model.cim.iec61970.base.core.feeder import Feeder
16
+ from zepben.ewb.model.cim.iec61970.base.wires.power_transformer import PowerTransformer
17
+ from zepben.ewb.services.network.network_service import NetworkService
18
+ from zepben.ewb.services.network.tracing.networktrace.conditions.conditions import stop_at_open
19
+ from zepben.ewb.services.network.tracing.networktrace.network_trace import NetworkTrace
20
+ from zepben.ewb.services.network.tracing.networktrace.network_trace_action_type import NetworkTraceActionType
21
+ from zepben.ewb.services.network.tracing.networktrace.network_trace_step import NetworkTraceStep
22
+ from zepben.ewb.services.network.tracing.networktrace.operators.network_state_operators import NetworkStateOperators
23
+ from zepben.ewb.services.network.tracing.networktrace.tracing import Tracing
24
+ from zepben.ewb.services.network.tracing.traversal.step_context import StepContext
25
+
26
+ if TYPE_CHECKING:
27
+ from zepben.ewb import AuxiliaryEquipment, Equipment, LvFeeder, ConductingEquipment, EquipmentContainer, Terminal
28
+
29
+
30
+ class AssignToFeeders:
31
+ """
32
+ Convenience class that provides methods for assigning HV/MV feeders on a `NetworkService`.
33
+ Requires that a Feeder have a normalHeadTerminal with associated ConductingEquipment.
34
+ This class is backed by a `NetworkTrace`.
35
+ """
36
+
37
+ def __init__(self, debug_logger: Logger = None):
38
+ self._debug_logger = debug_logger
39
+
40
+ async def run(
41
+ self,
42
+ network: NetworkService,
43
+ network_state_operators: Type[NetworkStateOperators] = NetworkStateOperators.NORMAL,
44
+ start_terminal: Terminal = None
45
+ ):
46
+ """
47
+ Assign equipment to feeders in the specified network, given an optional start terminal.
48
+
49
+ :param network: The [NetworkService] to process.
50
+ :param network_state_operators: operator interfaces relating to the network state we are operating on
51
+ :param start_terminal: An optional [Terminal] to start from:
52
+ * When a start terminal is provided, the trace will assign all feeders associated with the terminals equipment to all connected equipment.
53
+ * If no start terminal is provided, all feeder head terminals in the network will be used instead, assigning their associated feeder.
54
+ """
55
+
56
+ await AssignToFeedersInternal(
57
+ network_state_operators,
58
+ self._debug_logger
59
+ ).run(network, start_terminal)
60
+
61
+
62
+ class BaseFeedersInternal:
63
+ def __init__(self, network_state_operators: Type[NetworkStateOperators] = NetworkStateOperators.NORMAL, debug_logger: Logger = None):
64
+ self.network_state_operators = network_state_operators
65
+ self._debug_logger = debug_logger
66
+
67
+ def _feeders_from_terminal(self, terminal: Terminal) -> Generator[Feeder, None, None]:
68
+ return terminal.conducting_equipment.feeders(self.network_state_operators)
69
+
70
+ def _associate_equipment_with_containers(self, equipment_containers: Iterable[EquipmentContainer], equipment: Iterable[Equipment]):
71
+ for feeder in equipment_containers:
72
+ for it in equipment:
73
+ #todo remove this and fix the test that is using PatchedNetworkTraceStepPath (removing it). Error is that the feeder test doesn't have a head
74
+ # equipment, and the trace validation throws an error.
75
+ if it is not None:
76
+ self.network_state_operators.associate_equipment_and_container(it, feeder)
77
+
78
+ def _associate_relay_systems_with_containers(self, equipment_containers: Iterable[EquipmentContainer], to_equipment: ProtectedSwitch):
79
+ self._associate_equipment_with_containers(
80
+ equipment_containers,
81
+ [scheme.system for relayFunction in to_equipment.relay_functions for scheme in relayFunction.schemes if scheme.system is not None]
82
+ )
83
+
84
+ def _associate_power_electronic_units(self, equipment_containers: Iterable[EquipmentContainer], to_equipment: PowerElectronicsConnection):
85
+ self._associate_equipment_with_containers(equipment_containers, to_equipment.units)
86
+
87
+ def _feeder_energizes(self, feeders: Iterable[Union[LvFeeder, Feeder]], lv_feeders: Iterable[LvFeeder]):
88
+ for feeder in feeders:
89
+ for lv_feeder in lv_feeders:
90
+ self.network_state_operators.associate_energizing_feeder(feeder, lv_feeder)
91
+
92
+ def _feeder_try_energize_lv_feeders(self, feeders: Iterable[Feeder], lv_feeder_start_points: Set[ConductingEquipment], to_equipment: PowerTransformer):
93
+
94
+ lv_feeders = []
95
+ if len(sites := list(to_equipment.sites)) > 0:
96
+ for s in sites:
97
+ lv_feeders.extend(lv_f for lv_f in s.find_lv_feeders(lv_feeder_start_points, self.network_state_operators))
98
+ else:
99
+ for eq in to_equipment:
100
+ lv_feeders.extend(eq.lv_feeders(self.network_state_operators))
101
+
102
+ self._feeder_energizes(feeders, lv_feeders)
103
+
104
+
105
+ class AssignToFeedersInternal(BaseFeedersInternal):
106
+
107
+ async def run(
108
+ self,
109
+ network: NetworkService,
110
+ start_terminal: Terminal = None
111
+ ):
112
+ feeder_start_points = network.feeder_start_points
113
+ lv_feeder_start_points = network.lv_feeder_start_points
114
+ terminal_to_aux_equipment = network.aux_equipment_by_terminal
115
+
116
+ if start_terminal is None:
117
+ for it in list(it for it in network.objects(Feeder)):
118
+ await self.run_with_feeders(it.normal_head_terminal,
119
+ feeder_start_points,
120
+ lv_feeder_start_points,
121
+ terminal_to_aux_equipment,
122
+ [it])
123
+
124
+ else:
125
+ await self.run_with_feeders(start_terminal,
126
+ feeder_start_points,
127
+ lv_feeder_start_points,
128
+ terminal_to_aux_equipment,
129
+ list(self._feeders_from_terminal(start_terminal)))
130
+
131
+ async def run_with_feeders(self,
132
+ terminal: Terminal,
133
+ feeder_start_points: Set[ConductingEquipment],
134
+ lv_feeder_start_points: Set[ConductingEquipment],
135
+ terminal_to_aux_equipment: Dict[Terminal, List[AuxiliaryEquipment]],
136
+ feeders_to_assign: List[Feeder]):
137
+
138
+ if terminal is None or len(feeders_to_assign) == 0:
139
+ return
140
+
141
+ if isinstance(start_ce := terminal.conducting_equipment, Switch) and self.network_state_operators.is_open(start_ce):
142
+ self._associate_equipment_with_containers(feeders_to_assign, [start_ce])
143
+ else:
144
+ traversal = await self._create_trace(terminal_to_aux_equipment, feeder_start_points, lv_feeder_start_points, feeders_to_assign)
145
+ await traversal.run(terminal, False, can_stop_on_start_item=False)
146
+
147
+ async def _create_trace(self,
148
+ terminal_to_aux_equipment: Dict[Terminal, List[AuxiliaryEquipment]],
149
+ feeder_start_points: Set[ConductingEquipment],
150
+ lv_feeder_start_points: Set[ConductingEquipment],
151
+ feeders_to_assign: List[Feeder]
152
+ ) -> NetworkTrace[Any]:
153
+
154
+ def _reached_lv(ce: ConductingEquipment):
155
+ return True if ce.base_voltage and ce.base_voltage.nominal_voltage < 1000 else False
156
+
157
+ def _reached_substation_transformer(ce: ConductingEquipment):
158
+ return True if isinstance(ce, PowerTransformer) and len(list(ce.substations)) > 0 else False
159
+
160
+ async def step_action(nts: NetworkTraceStep, context: StepContext):
161
+ await self._process(nts.path, context, terminal_to_aux_equipment, lv_feeder_start_points, feeders_to_assign)
162
+
163
+ return (
164
+ Tracing.network_trace(
165
+ network_state_operators=self.network_state_operators,
166
+ action_step_type=NetworkTraceActionType.ALL_STEPS,
167
+ debug_logger=self._debug_logger,
168
+ name=f'AssignToFeeders({self.network_state_operators.description})'
169
+ )
170
+ .add_condition(stop_at_open())
171
+ .add_stop_condition(
172
+ lambda step, ctx: step.path.to_equipment in feeder_start_points
173
+ )
174
+ .add_queue_condition(
175
+ lambda step, ctx, x, y: not _reached_substation_transformer(step.path.to_equipment)
176
+ )
177
+ .add_queue_condition(
178
+ lambda step, ctx, x, y: not _reached_lv(step.path.to_equipment)
179
+ )
180
+ .add_step_action(step_action)
181
+ )
182
+
183
+ async def _process(self,
184
+ step_path: NetworkTraceStep.Path,
185
+ step_context: StepContext,
186
+ terminal_to_aux_equipment: Dict[Terminal, Collection[AuxiliaryEquipment]],
187
+ lv_feeder_start_points: Set[ConductingEquipment],
188
+ feeders_to_assign: List[Feeder]):
189
+
190
+ if step_path.traced_internally and not step_context.is_start_item:
191
+ return
192
+
193
+ self._associate_equipment_with_containers(feeders_to_assign, terminal_to_aux_equipment.get(step_path.to_terminal, {}))
194
+ self._associate_equipment_with_containers(feeders_to_assign, [step_path.to_equipment])
195
+
196
+ to_equip = step_path.to_equipment
197
+ if isinstance(to_equip, PowerTransformer):
198
+ self._feeder_try_energize_lv_feeders(feeders_to_assign, lv_feeder_start_points, to_equip)
199
+ elif isinstance(to_equip, ProtectedSwitch):
200
+ self._associate_relay_systems_with_containers(feeders_to_assign, to_equip)
201
+ elif isinstance(to_equip, PowerElectronicsConnection):
202
+ self._associate_power_electronic_units(feeders_to_assign, to_equip)