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,143 @@
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
+ from typing import Set, Union, Type, TYPE_CHECKING
9
+
10
+ from zepben.ewb import NetworkService
11
+ from zepben.ewb.model.cim.iec61970.base.core.phase_code import PhaseCode
12
+ from zepben.ewb.model.cim.iec61970.base.core.terminal import Terminal
13
+ from zepben.ewb.model.cim.iec61970.base.wires.single_phase_kind import SinglePhaseKind
14
+ from zepben.ewb.services.network.tracing.networktrace.conditions.conditions import stop_at_open
15
+ from zepben.ewb.services.network.tracing.networktrace.network_trace import NetworkTrace
16
+ from zepben.ewb.services.network.tracing.networktrace.network_trace_action_type import NetworkTraceActionType
17
+ from zepben.ewb.services.network.tracing.networktrace.network_trace_step import NetworkTraceStep
18
+ from zepben.ewb.services.network.tracing.networktrace.operators.network_state_operators import NetworkStateOperators
19
+ from zepben.ewb.services.network.tracing.networktrace.tracing import Tracing
20
+ from zepben.ewb.services.network.tracing.traversal.weighted_priority_queue import WeightedPriorityQueue
21
+
22
+ if TYPE_CHECKING:
23
+ from logging import Logger
24
+ from zepben.ewb.services.network.tracing.traversal.step_context import StepContext
25
+
26
+
27
+ class EbbPhases:
28
+ def __init__(self, phases_to_ebb: Set[SinglePhaseKind]):
29
+ self.phases_to_ebb = phases_to_ebb
30
+ self.ebbed_phases: Set[SinglePhaseKind] = set()
31
+
32
+
33
+ class RemovePhases(object):
34
+ """
35
+ Convenience class that provides methods for removing phases on a `NetworkService`
36
+ This class is backed by a `BranchRecursiveTraversal`.
37
+ """
38
+
39
+ def __init__(self, debug_logger: Logger = None):
40
+ self._debug_logger = debug_logger
41
+
42
+ async def run(
43
+ self,
44
+ start: Union[NetworkService, Terminal],
45
+ nominal_phases_to_ebb: Union[PhaseCode, SinglePhaseKind] = None,
46
+ network_state_operators: Type[NetworkStateOperators] = NetworkStateOperators.NORMAL
47
+ ):
48
+ """
49
+ If nominal_phases_to_ebb is `None` this will remove all phases for all equipment connected
50
+ to `start`
51
+ If `start` is a:
52
+ - `NetworkService` - Remove traced phases from the specified network.
53
+ - `Terminal` - Allows the removal of phases from a terminal and the connected equipment chain
54
+
55
+ :param start: NetworkService or Terminal to start phase removal
56
+ :param nominal_phases_to_ebb: The nominal phases to remove traced phasing from. Defaults to all phases.
57
+ :param network_state_operators: The `NetworkStateOperators` to be used when removing phases.
58
+ """
59
+
60
+ if nominal_phases_to_ebb is None:
61
+
62
+ if isinstance(start, NetworkService):
63
+ return await self._run_with_network(start, network_state_operators)
64
+
65
+ if isinstance(start, Terminal):
66
+ return await self._run_with_terminal(start, network_state_operators)
67
+
68
+ return await self._run_with_phases_to_ebb(start, nominal_phases_to_ebb, network_state_operators)
69
+
70
+ @staticmethod
71
+ async def _run_with_network(network_service: NetworkService, network_state_operators: Type[NetworkStateOperators] = NetworkStateOperators.NORMAL) -> None:
72
+ """
73
+ Remove all traced phases from the specified network.
74
+
75
+ :param network_service: The network service to remove traced phasing from.
76
+ :param network_state_operators: The `NetworkStateOperators` to be used when removing phases.
77
+ """
78
+
79
+ for t in network_service.objects(Terminal):
80
+ t.traced_phases.phase_status = 0
81
+
82
+ async def _run_with_terminal(self, terminal: Terminal, network_state_operators: Type[NetworkStateOperators] = NetworkStateOperators.NORMAL):
83
+ """
84
+ Allows the removal of traced phases from a terminal and the connected equipment chain
85
+
86
+ :param terminal: Removes all nominal phases a terminal traced phases and the connected equipment chain
87
+ :param network_state_operators: The `NetworkStateOperators` to be used when removing phases.
88
+ """
89
+
90
+ return await self._run_with_phases_to_ebb(terminal, terminal.phases, network_state_operators)
91
+
92
+ async def _run_with_phases_to_ebb(
93
+ self,
94
+ terminal: Terminal,
95
+ nominal_phases_to_ebb: Union[PhaseCode, Set[SinglePhaseKind]],
96
+ network_state_operators: Type[NetworkStateOperators] = NetworkStateOperators.NORMAL):
97
+ """
98
+ Allows the removal of traced phases from a terminal and the connected equipment chain
99
+
100
+ :param terminal: Terminal to start phase removal
101
+ :param nominal_phases_to_ebb: The nominal phases to remove traced phasing from. Defaults to all phases.
102
+ :param network_state_operators: The `NetworkStateOperators` to be used when removing phases.
103
+ """
104
+
105
+ if isinstance(nominal_phases_to_ebb, PhaseCode):
106
+ return await self._run_with_phases_to_ebb(terminal, set(nominal_phases_to_ebb.single_phases), network_state_operators)
107
+
108
+ trace = await self._create_trace(network_state_operators)
109
+ return await trace.run(terminal, EbbPhases(nominal_phases_to_ebb), terminal.phases)
110
+
111
+ async def _create_trace(self, state_operators: Type[NetworkStateOperators]) -> NetworkTrace[EbbPhases]:
112
+
113
+ def compute_data(step: NetworkTraceStep[EbbPhases], context: StepContext, next_path: NetworkTraceStep.Path):
114
+ data = []
115
+ for to_phase in [phase.to_phase for phase in next_path.nominal_phase_paths]:
116
+ if to_phase in step.data.phases_to_ebb:
117
+ data.append(to_phase)
118
+ return EbbPhases(set(data))
119
+
120
+ async def step_action(nts: NetworkTraceStep, ctx: StepContext):
121
+ nts.data.ebbed_phases = await self._ebb(state_operators, nts.path.to_terminal, nts.data.phases_to_ebb)
122
+
123
+ def queue_condition(next_step: NetworkTraceStep, next_ctx: StepContext = None, step: NetworkTraceStep = None, ctx: StepContext = None):
124
+ return len(next_step.data.phases_to_ebb) > 0 and (step is None or len(step.data.ebbed_phases) > 0)
125
+
126
+ return Tracing.network_trace(
127
+ network_state_operators=state_operators,
128
+ action_step_type=NetworkTraceActionType.ALL_STEPS,
129
+ debug_logger=self._debug_logger,
130
+ name=f'RemovePhases({state_operators.description})',
131
+ queue=WeightedPriorityQueue.process_queue(lambda it: len(it.data.phases_to_ebb)),
132
+ compute_data=compute_data
133
+ ).add_condition(stop_at_open()) \
134
+ .add_step_action(step_action) \
135
+ .add_queue_condition(queue_condition)
136
+
137
+ @staticmethod
138
+ async def _ebb(state_operators: Type[NetworkStateOperators], terminal: Terminal, phases_to_ebb: Set[SinglePhaseKind]) -> Set[SinglePhaseKind]:
139
+ phases = state_operators.phase_status(terminal)
140
+ for phase in phases_to_ebb:
141
+ if phases[phase] != SinglePhaseKind.NONE:
142
+ phases[phase] = SinglePhaseKind.NONE
143
+ return set(phases_to_ebb)
@@ -0,0 +1,490 @@
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__ = ["SetPhases"]
9
+
10
+ from collections.abc import Sequence
11
+ from functools import singledispatchmethod
12
+ from typing import Union, Set, Iterable, List, Type, TYPE_CHECKING, Optional, Callable
13
+
14
+ from zepben.ewb import PhaseStatus, add_neutral
15
+ from zepben.ewb.exceptions import TracingException, PhaseException
16
+ from zepben.ewb.model.cim.iec61970.base.core.phase_code import PhaseCode
17
+ from zepben.ewb.model.cim.iec61970.base.core.terminal import Terminal
18
+ from zepben.ewb.model.cim.iec61970.base.wires.energy_source import EnergySource
19
+ from zepben.ewb.model.cim.iec61970.base.wires.power_transformer import PowerTransformer
20
+ from zepben.ewb.model.cim.iec61970.base.wires.single_phase_kind import SinglePhaseKind
21
+ from zepben.ewb.services.network.network_service import NetworkService
22
+ from zepben.ewb.services.network.tracing.connectivity.nominal_phase_path import NominalPhasePath
23
+ from zepben.ewb.services.network.tracing.connectivity.terminal_connectivity_connected import TerminalConnectivityConnected
24
+ from zepben.ewb.services.network.tracing.connectivity.terminal_connectivity_internal import TerminalConnectivityInternal
25
+ from zepben.ewb.services.network.tracing.networktrace.compute_data import ComputeData
26
+ from zepben.ewb.services.network.tracing.networktrace.network_trace import NetworkTrace
27
+ from zepben.ewb.services.network.tracing.networktrace.network_trace_action_type import NetworkTraceActionType
28
+ from zepben.ewb.services.network.tracing.networktrace.operators.network_state_operators import NetworkStateOperators
29
+ from zepben.ewb.services.network.tracing.networktrace.tracing import Tracing
30
+ from zepben.ewb.services.network.tracing.traversal.weighted_priority_queue import WeightedPriorityQueue
31
+
32
+ if TYPE_CHECKING:
33
+ from logging import Logger
34
+
35
+
36
+ class SetPhases:
37
+ """
38
+ Convenience class that provides methods for setting phases on a `NetworkService`.
39
+ This class is backed by a `NetworkTrace`.
40
+ """
41
+
42
+ def __init__(self, debug_logger: Logger = None):
43
+ self._debug_logger = debug_logger
44
+
45
+ class PhasesToFlow:
46
+ def __init__(self, nominal_phase_paths: Iterable[NominalPhasePath], step_flowed_phases: bool = False):
47
+ self.nominal_phase_paths = nominal_phase_paths
48
+ self.step_flowed_phases = step_flowed_phases
49
+
50
+ def __str__(self):
51
+ return f'PhasesToFlow(nominal_phase_paths={self.nominal_phase_paths}, step_flowed_phases={self.step_flowed_phases})'
52
+
53
+ @singledispatchmethod
54
+ async def run(
55
+ self,
56
+ target: Union[NetworkService, Terminal],
57
+ phases: Union[PhaseCode, Iterable[SinglePhaseKind]] = None,
58
+ network_state_operators: Type[NetworkStateOperators] = NetworkStateOperators.NORMAL
59
+ ):
60
+ """
61
+
62
+ :param target:
63
+ :param phases:
64
+ :param network_state_operators: The `NetworkStateOperators` to be used when setting phases.
65
+ """
66
+
67
+ raise ValueError('INTERNAL ERROR: incorrect params')
68
+
69
+ @run.register
70
+ async def _(
71
+ self,
72
+ network: NetworkService,
73
+ network_state_operators: Type[NetworkStateOperators] = NetworkStateOperators.NORMAL
74
+ ):
75
+ """
76
+ Apply phases and flow from all energy sources in the network.
77
+ This will apply `Terminal.phases` to all terminals on each `EnergySource` and then flow along the connected network.
78
+
79
+ :param network: The network in which to apply phases.
80
+ :param network_state_operators: The `NetworkStateOperators` to be used when setting phases.
81
+ """
82
+
83
+ def _terminals_from_network():
84
+ for energy_source in network.objects(EnergySource):
85
+ for terminal in energy_source.terminals:
86
+ self._apply_phases(terminal.phases.single_phases, terminal, network_state_operators)
87
+ yield terminal
88
+
89
+ await self._run_terminals(_terminals_from_network(), network_state_operators=network_state_operators)
90
+
91
+ @run.register
92
+ async def _(
93
+ self,
94
+ start_terminal: Terminal,
95
+ phases: Union[PhaseCode, List[SinglePhaseKind], Set[SinglePhaseKind]] = None,
96
+ network_state_operators: Type[NetworkStateOperators] = NetworkStateOperators.NORMAL,
97
+ seed_terminal: Terminal = None
98
+ ):
99
+ """
100
+ Apply phases to the `start_terminal` and flow, optionally specifying a `seed_terminal`. If specified, the `seed_terminal`
101
+ and `start_terminal` must have the same `Terminal.conducting_equipment`
102
+
103
+ :param start_terminal: The terminal to start applying phases from.
104
+ :param phases: The phases to apply. Must only contain ABCN, if None, `SetPhases` will flow phases already set on `start_terminal`.
105
+ :param network_state_operators: The `NetworkStateOperators` to be used when setting phases.
106
+ :param seed_terminal: The terminal from which to spread the phases from.
107
+ """
108
+
109
+ if phases is None:
110
+ # Flow phases already set on the given Terminal
111
+ await self._run_terminals([start_terminal], network_state_operators=network_state_operators)
112
+
113
+ elif isinstance(phases, PhaseCode):
114
+ await self.run(start_terminal, phases=phases.single_phases, network_state_operators=network_state_operators)
115
+
116
+ elif isinstance(phases, (List, Set)):
117
+ if seed_terminal:
118
+ nominal_phase_paths = self._get_nominal_phase_paths(network_state_operators, seed_terminal, start_terminal, list(phases))
119
+
120
+ if self._flow_phases(network_state_operators, seed_terminal, start_terminal, nominal_phase_paths):
121
+ await self.run(start_terminal, network_state_operators=network_state_operators)
122
+
123
+ else:
124
+ if len(phases) != len(start_terminal.phases.single_phases):
125
+ raise TracingException(
126
+ f"Attempted to apply phases [{', '.join(phase.name for phase in phases)}] to {start_terminal} with nominal phases {start_terminal.phases.name}. "
127
+ f"Number of phases to apply must match the number of nominal phases. Found {len(phases)}, expected {len(start_terminal.phases.single_phases)}"
128
+ )
129
+ self._apply_phases(phases, start_terminal, network_state_operators)
130
+ await self._run_terminals([start_terminal], network_state_operators=network_state_operators)
131
+
132
+ else:
133
+ raise ValueError('ERROR: phases must either be a PhaseCode, or Union[List, Set]')
134
+
135
+ def spread_phases(
136
+ self,
137
+ from_terminal: Terminal,
138
+ to_terminal: Terminal,
139
+ phases: List[SinglePhaseKind] = None,
140
+ network_state_operators: Type[NetworkStateOperators] = NetworkStateOperators.NORMAL
141
+ ):
142
+ """
143
+ Apply nominal phases from the `from_terminal` to the `to_terminal`.
144
+
145
+ :param from_terminal: The terminal to from which to spread phases.
146
+ :param to_terminal: The terminal to spread phases to.
147
+ :param phases: The nominal phases on which to spread phases, if None, `SetPhases` will use phases from `from_terminal`.
148
+ :param network_state_operators: The `NetworkStateOperators` to be used when setting phases.
149
+ """
150
+
151
+ paths = self._get_nominal_phase_paths(network_state_operators, from_terminal, to_terminal, phases or from_terminal.phases.single_phases)
152
+ self._flow_phases(network_state_operators, from_terminal, to_terminal, paths)
153
+
154
+ async def _run_terminals(self, terminals: Iterable[Terminal], network_state_operators: Type[NetworkStateOperators]):
155
+
156
+ partially_energised_transformers: Set[PowerTransformer] = set()
157
+ trace = self._create_network_trace(network_state_operators, partially_energised_transformers)
158
+
159
+ for terminal in terminals:
160
+ await self._run_terminal_trace(terminal, trace)
161
+
162
+ # Go back and add any missing phases to transformers that were energised from a downstream side with fewer phases
163
+ # when they were in parallel, that successfully energised all the upstream side phases. This setup stops the spread
164
+ # from coming back down the upstream (it is fully energised) and processing the transformer correctly.
165
+
166
+ if self._debug_logger:
167
+ self._debug_logger.info('Reprocessing partially energised transformers...')
168
+
169
+ for tx in partially_energised_transformers:
170
+ terminals_by_energisation = [(terminal, _not_fully_energised(network_state_operators, terminal)) for terminal in tx.terminals]
171
+ if any(energised for _, energised in terminals_by_energisation):
172
+
173
+ partially_energised = []
174
+ fully_energised = []
175
+ for terminal, energised in terminals_by_energisation:
176
+ if energised:
177
+ partially_energised.append(terminal)
178
+ else:
179
+ fully_energised.append(terminal)
180
+
181
+ for partial in partially_energised:
182
+ for full in fully_energised:
183
+ self._flow_transformer_phases(network_state_operators, full, partial, allow_suspect_flow=True)
184
+ await self._run_terminal_trace(partial, trace)
185
+
186
+ if self._debug_logger:
187
+ self._debug_logger.info("Reprocessing complete.")
188
+
189
+ async def _run_terminal_trace(self, terminal: Terminal, network_trace: NetworkTrace[PhasesToFlow]):
190
+ await network_trace.run(
191
+ terminal,
192
+ self.PhasesToFlow(
193
+ [NominalPhasePath(SinglePhaseKind.NONE, it) for it in terminal.phases]
194
+ ), can_stop_on_start_item=False
195
+ )
196
+
197
+ # This is called in a loop so we need to reset it for each call. We choose to do this after to release the memory
198
+ # used by the trace once it is finished, rather than before, which has would be marginally quicker on the first
199
+ # call, but would hold onto the memory as long as the `SetPhases` instance is referenced.
200
+
201
+ network_trace.reset()
202
+
203
+ @staticmethod
204
+ def _nominal_phase_path_to_phases(nominal_phase_paths: list[NominalPhasePath]) -> list[SinglePhaseKind]:
205
+ return [it.to_phase for it in nominal_phase_paths]
206
+
207
+ def _create_network_trace(
208
+ self,
209
+ state_operators: Type[NetworkStateOperators],
210
+ partially_energised_transformers: Set[PowerTransformer]
211
+ ) -> NetworkTrace[PhasesToFlow]:
212
+
213
+ def step_action(nts, ctx):
214
+ path, phases_to_flow = nts
215
+ # We always assume the first step terminal already has the phases applied, so we don't do anything on the first step
216
+ phases_to_flow.step_flowed_phases = True if ctx.is_start_item else (
217
+ self._flow_phases(state_operators, path.from_terminal, path.to_terminal, phases_to_flow.nominal_phase_paths)
218
+ )
219
+
220
+ # If we flowed phases but failed to completely energise a transformer, keep track of it for reprocessing later.
221
+ if (phases_to_flow.step_flowed_phases
222
+ and isinstance(path.to_equipment, PowerTransformer)
223
+ and _not_fully_energised(state_operators, path.to_terminal)
224
+ ):
225
+ partially_energised_transformers.add(path.to_equipment)
226
+
227
+ return (
228
+ Tracing.network_trace_branching(
229
+ network_state_operators=state_operators,
230
+ action_step_type=NetworkTraceActionType.ALL_STEPS,
231
+ debug_logger=self._debug_logger,
232
+ name=f'SetPhases({state_operators.description})',
233
+ queue_factory=lambda: WeightedPriorityQueue.process_queue(lambda it: it.path.to_terminal.phases.num_phases),
234
+ branch_queue_factory=lambda: WeightedPriorityQueue.branch_queue(lambda it: it.path.to_terminal.phases.num_phases),
235
+ compute_data=self._compute_next_phases_to_flow(state_operators)
236
+ )
237
+ .add_queue_condition(
238
+ lambda next_step, x, y, z: len(next_step.data.nominal_phase_paths) > 0
239
+ )
240
+ .add_step_action(step_action)
241
+ )
242
+
243
+ def _compute_next_phases_to_flow(self, state_operators: Type[NetworkStateOperators]) -> ComputeData[PhasesToFlow]:
244
+ def inner(step, _, next_path):
245
+ if not step.data.step_flowed_phases:
246
+ return self.PhasesToFlow([])
247
+
248
+ return self.PhasesToFlow(
249
+ self._get_nominal_phase_paths(
250
+ state_operators,
251
+ next_path.from_terminal,
252
+ next_path.to_terminal,
253
+ self._nominal_phase_path_to_phases(step.data.nominal_phase_paths)
254
+ )
255
+ )
256
+
257
+ return ComputeData(inner)
258
+
259
+ @staticmethod
260
+ def _apply_phases(
261
+ phases: List[SinglePhaseKind],
262
+ terminal: Terminal,
263
+ state_operators: Type[NetworkStateOperators]
264
+ ):
265
+ traced_phases = state_operators.phase_status(terminal)
266
+ for i, nominal_phase in enumerate(terminal.phases.single_phases):
267
+ traced_phases[nominal_phase] = phases[i] if phases[i] not in PhaseCode.XY else SinglePhaseKind.NONE
268
+
269
+ def _get_nominal_phase_paths(
270
+ self,
271
+ state_operators: Type[NetworkStateOperators],
272
+ from_terminal: Terminal,
273
+ to_terminal: Terminal,
274
+ phases: Sequence[SinglePhaseKind] = None
275
+ ) -> List[NominalPhasePath]:
276
+
277
+ if phases is None:
278
+ phases = from_terminal.phases.single_phases
279
+
280
+ traced_internally = from_terminal.conducting_equipment == to_terminal.conducting_equipment
281
+ phases_to_flow = self._get_phases_to_flow(state_operators, from_terminal, phases, traced_internally)
282
+
283
+ if traced_internally:
284
+ return list(TerminalConnectivityInternal().between(from_terminal, to_terminal, phases_to_flow).nominal_phase_paths)
285
+ else:
286
+ return list(TerminalConnectivityConnected().terminal_connectivity(from_terminal, to_terminal, phases_to_flow).nominal_phase_paths)
287
+
288
+ @staticmethod
289
+ def _get_phases_to_flow(
290
+ state_operators: Type[NetworkStateOperators],
291
+ terminal: Terminal,
292
+ phases: Sequence[SinglePhaseKind],
293
+ internal_flow: bool
294
+ ) -> Set[SinglePhaseKind]:
295
+
296
+ if internal_flow:
297
+ if ce := terminal.conducting_equipment:
298
+ return set(p for p in phases if not state_operators.is_open(ce, p))
299
+ return set()
300
+ return set(phases)
301
+
302
+ def _flow_phases(
303
+ self,
304
+ state_operators: Type[NetworkStateOperators],
305
+ from_terminal: Terminal,
306
+ to_terminal: Terminal,
307
+ nominal_phase_paths: List[NominalPhasePath]
308
+ ) -> bool:
309
+
310
+ if (from_terminal.conducting_equipment == to_terminal.conducting_equipment
311
+ and isinstance(from_terminal.conducting_equipment, PowerTransformer)
312
+ ):
313
+ return self._flow_transformer_phases(state_operators, from_terminal, to_terminal, nominal_phase_paths, allow_suspect_flow=False)
314
+ else:
315
+ return self._flow_straight_phases(state_operators, from_terminal, to_terminal, nominal_phase_paths)
316
+
317
+ def _flow_straight_phases(
318
+ self,
319
+ state_operators: Type[NetworkStateOperators],
320
+ from_terminal: Terminal,
321
+ to_terminal: Terminal,
322
+ nominal_phase_paths: List[NominalPhasePath]
323
+ ) -> bool:
324
+
325
+ from_phases = state_operators.phase_status(from_terminal)
326
+ to_phases = state_operators.phase_status(to_terminal)
327
+
328
+ updated_phases = []
329
+
330
+ for from_, to_ in ((p.from_phase, p.to_phase) for p in nominal_phase_paths):
331
+ self._try_set_phase(from_phases[from_], from_terminal, from_phases, from_, to_terminal, to_phases, to_, lambda: updated_phases.append(True))
332
+
333
+ return any(updated_phases)
334
+
335
+ def _flow_transformer_phases(
336
+ self,
337
+ state_operators: Type[NetworkStateOperators],
338
+ from_terminal: Terminal,
339
+ to_terminal: Terminal,
340
+ nominal_phase_paths: List[NominalPhasePath] = None,
341
+ allow_suspect_flow: bool = False
342
+ ) -> bool:
343
+
344
+ paths = nominal_phase_paths or self._get_nominal_phase_paths(state_operators, from_terminal, to_terminal)
345
+
346
+ # If this transformer doesn't mess with phases (or only adds or removes a neutral), just use the straight
347
+ # processor. We use the number of phases rather than the phases themselves to correctly handle the shift
348
+ # from known to unknown phases. e.g. AB -> XY.
349
+
350
+ if from_terminal.phases.without_neutral.num_phases == to_terminal.phases.without_neutral.num_phases:
351
+ return self._flow_transformer_phases_adding_neutral(state_operators, from_terminal, to_terminal, paths)
352
+
353
+ from_phases = state_operators.phase_status(from_terminal)
354
+ to_phases = state_operators.phase_status(to_terminal)
355
+
356
+ updated_phases = []
357
+
358
+ # Split the phases into ones we need to flow directly, and ones that have been added by a transformer. In
359
+ # the case of an added Y phase (SWER -> LV2 transformer) we need to flow the phases before we can calculate
360
+ # the missing phase.
361
+ flow_phases = (p for p in paths if p.from_phase == SinglePhaseKind.NONE)
362
+ add_phases = (p for p in paths if p.from_phase != SinglePhaseKind.NONE)
363
+ for p in flow_phases:
364
+ self._try_add_phase(from_terminal, from_phases, to_terminal, to_phases, p.to_phase, allow_suspect_flow,
365
+ lambda: updated_phases.append(True))
366
+
367
+ for p in add_phases:
368
+ self._try_set_phase(from_phases[p.from_phase], from_terminal, from_phases, p.from_phase,
369
+ to_terminal, to_phases, p.to_phase, lambda: updated_phases.append(True))
370
+
371
+ return any(updated_phases)
372
+
373
+ def _flow_transformer_phases_adding_neutral(
374
+ self,
375
+ state_operators: Type[NetworkStateOperators],
376
+ from_terminal: Terminal,
377
+ to_terminal: Terminal,
378
+ paths: List[NominalPhasePath]
379
+ ) -> bool:
380
+
381
+ updated_phases = self._flow_straight_phases(state_operators, from_terminal, to_terminal,
382
+ [it for it in paths if it != add_neutral])
383
+
384
+ # Only add the neutral if we added a phases to the transformer, otherwise you will flag an energised neutral
385
+ # with no active phases. We check to see if we need to add the neutral to prevent adding it when we traverse
386
+ # through the transformer in the opposite direction.
387
+
388
+ if updated_phases and (add_neutral in paths):
389
+ state_operators.phase_status(to_terminal)[SinglePhaseKind.N] = SinglePhaseKind.N
390
+
391
+ return updated_phases
392
+
393
+ def _try_set_phase(
394
+ self,
395
+ phase: SinglePhaseKind,
396
+ from_terminal: Terminal,
397
+ from_phases: PhaseStatus,
398
+ from_: SinglePhaseKind,
399
+ to_terminal: Terminal,
400
+ to_phases: PhaseStatus,
401
+ to_: SinglePhaseKind,
402
+ on_success: Callable[[], None]
403
+ ):
404
+ try:
405
+ if phase != SinglePhaseKind.NONE and to_phases.__setitem__(to_, phase):
406
+ if self._debug_logger:
407
+ self._debug_logger.info(f' {from_terminal.mrid}[{from_}] -> {to_terminal.mrid}[{to_}]: set to {phase}')
408
+ on_success()
409
+ except PhaseException:
410
+ self._throw_cross_phase_exception(from_terminal, from_phases, from_, to_terminal, to_phases, to_)
411
+
412
+ def _try_add_phase(
413
+ self,
414
+ from_terminal: Terminal,
415
+ from_phases: PhaseStatus,
416
+ to_terminal: Terminal,
417
+ to_phases: PhaseStatus,
418
+ to_: SinglePhaseKind,
419
+ allow_suspect_flow: bool,
420
+ on_success: Callable[[], None]
421
+ ):
422
+ # The phases that can be added are ABCN and Y, so for all cases other than Y we can just use the added phase. For
423
+ # Y we need to look at what the phases on the other side of the transformer are to determine what has been added.
424
+
425
+ phase = _unless_none(
426
+ to_phases[to_], _to_y_phase(from_phases[from_terminal.phases.single_phases[0]], allow_suspect_flow)
427
+ ) if to_ == SinglePhaseKind.Y else to_
428
+
429
+ self._try_set_phase(phase, from_terminal, from_phases, SinglePhaseKind.NONE, to_terminal, to_phases, to_, on_success)
430
+
431
+ @staticmethod
432
+ def _throw_cross_phase_exception(
433
+ from_terminal: Terminal,
434
+ from_phases: PhaseStatus,
435
+ from_: SinglePhaseKind,
436
+ to_terminal: Terminal,
437
+ to_phases: PhaseStatus,
438
+ to_: SinglePhaseKind
439
+ ):
440
+ phase_desc = f'{from_.name}' if from_ == to_ else f'path {from_.name} to {to_.name}'
441
+
442
+ def get_ce_details(terminal: Terminal):
443
+ if terminal.conducting_equipment:
444
+ return terminal.conducting_equipment
445
+ return ''
446
+
447
+ if from_terminal.conducting_equipment == to_terminal.conducting_equipment:
448
+ terminal_desc = f'from {from_terminal} to {to_terminal} through {from_terminal.conducting_equipment}'
449
+ else:
450
+ terminal_desc = f'between {from_terminal} on {get_ce_details(from_terminal)} and {to_terminal} on {get_ce_details(to_terminal)}'
451
+
452
+ raise PhaseException(
453
+ f"Attempted to flow conflicting phase {from_phases[from_].name} onto {to_phases[to_].name} on nominal phase {phase_desc}. This occurred while " +
454
+ f"flowing {terminal_desc}. This is often caused by missing open points, or incorrect phases in upstream equipment that should be " +
455
+ "corrected in the source data."
456
+ )
457
+
458
+
459
+ def _not_fully_energised(network_state_operators: Type[NetworkStateOperators], terminal: Terminal) -> bool:
460
+ phase_status = network_state_operators.phase_status(terminal)
461
+ return any(phase_status[it] == SinglePhaseKind.NONE for it in terminal.phases.single_phases)
462
+
463
+
464
+ def _unless_none(single_phase_kind: SinglePhaseKind, default: SinglePhaseKind) -> Optional[SinglePhaseKind]:
465
+ if single_phase_kind == SinglePhaseKind.NONE:
466
+ return default
467
+ return single_phase_kind
468
+
469
+
470
+ def _to_y_phase(phase: SinglePhaseKind, allow_suspect_flow: bool) -> SinglePhaseKind:
471
+ # NOTE: If we are adding Y to a C <-> XYN transformer we will leave it de-energised to prevent cross-phase energisation
472
+ # when there is a parallel C to XN transformer. This can be changed if the entire way XY mappings are reworked to
473
+ # use traced phases instead of the X and Y, which includes in straight paths to prevent cross-phase wiring.
474
+ #
475
+ # Due to both AB and AC energising X with A, until the above is fixed we don't know which one we are using, so if
476
+ # we aren't allowing suspect flows we will also leave it de-energised to prevent cross-phase energisation when you
477
+ # have parallel XY <-> XN transformers on an AC line (adds B to the Y "C wire"). If we are allowing suspect flows
478
+ # for partially energised transformers on a second pass we will default these to use AB.
479
+
480
+ if phase == SinglePhaseKind.A:
481
+ if allow_suspect_flow:
482
+ return SinglePhaseKind.B
483
+ else:
484
+ return SinglePhaseKind.NONE
485
+ elif phase == SinglePhaseKind.B:
486
+ return SinglePhaseKind.C
487
+ elif phase == SinglePhaseKind.C:
488
+ return SinglePhaseKind.NONE
489
+ else:
490
+ return SinglePhaseKind.NONE
@@ -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/.