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,175 @@
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__ = ["FindSwerEquipment"]
9
+
10
+ from typing import Set, Union, AsyncGenerator, Type, TYPE_CHECKING
11
+
12
+ from typing_extensions import TypeVar
13
+
14
+ from zepben.ewb.model.cim.iec61970.base.core.conducting_equipment import ConductingEquipment
15
+ from zepben.ewb.model.cim.iec61970.base.core.feeder import Feeder
16
+ from zepben.ewb.model.cim.iec61970.base.core.terminal import Terminal
17
+ from zepben.ewb.model.cim.iec61970.base.wires.power_transformer import PowerTransformer
18
+ from zepben.ewb.model.cim.iec61970.base.wires.switch import Switch
19
+ from zepben.ewb.services.network.network_service import NetworkService
20
+ from zepben.ewb.services.network.tracing.networktrace.conditions.conditions import stop_at_open
21
+ from zepben.ewb.services.network.tracing.networktrace.network_trace import NetworkTrace
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
+
25
+ if TYPE_CHECKING:
26
+ from logging import Logger
27
+
28
+ T = TypeVar
29
+
30
+
31
+ class FindSwerEquipment:
32
+ """
33
+ A class which can be used for finding the SWER equipment in a [NetworkService] or [Feeder].
34
+ """
35
+
36
+ def __init__(self, debug_logger: Logger = None):
37
+ self._debug_logger = debug_logger
38
+
39
+ async def find(
40
+ self,
41
+ to_process: Union[NetworkService, Feeder],
42
+ network_state_operators: Type[NetworkStateOperators] = NetworkStateOperators.NORMAL
43
+ ) -> Set[ConductingEquipment]:
44
+ """
45
+ Convenience method to call out to `find_all` or `find_on_feeder` based on the class type of `to_process`
46
+
47
+ :param to_process: the object to process
48
+ :param network_state_operators: The `NetworkStateOperators` to be used when finding SWER equipment
49
+
50
+ :return: A `Set` of `ConductingEquipment` on `Feeder` that is SWER, or energised via SWER.
51
+ """
52
+
53
+ if isinstance(to_process, Feeder):
54
+ return set(await self.find_on_feeder(to_process, network_state_operators))
55
+ elif isinstance(to_process, NetworkService):
56
+ return set([item async for item in self.find_all(to_process, network_state_operators)])
57
+ else:
58
+ raise NotImplementedError
59
+
60
+ async def find_all(
61
+ self,
62
+ network_service: NetworkService,
63
+ network_state_operators: Type[NetworkStateOperators] = NetworkStateOperators.NORMAL
64
+ ) -> AsyncGenerator[ConductingEquipment, None]:
65
+ """
66
+ Find the `ConductingEquipment` on any `Feeder` in a `NetworkService` which is SWER. This will include any equipment on the LV network that is energised
67
+ via SWER.
68
+
69
+ :param network_service: The `NetworkService` to process.
70
+ :param network_state_operators: The `NetworkStateOperators` to be used when finding SWER equipment
71
+
72
+ :return: A `Set` of `ConductingEquipment` on `Feeder` that is SWER, or energised via SWER.
73
+ """
74
+
75
+ for feeder in network_service.objects(Feeder):
76
+ for item in await self.find_on_feeder(feeder, network_state_operators):
77
+ yield item
78
+
79
+ async def find_on_feeder(
80
+ self,
81
+ feeder: Feeder,
82
+ network_state_operators: Type[NetworkStateOperators] = NetworkStateOperators.NORMAL
83
+ ) -> Set[ConductingEquipment]:
84
+ """
85
+ Find the `ConductingEquipment` on a `Feeder` which is SWER. This will include any equipment on the LV network that is energised via SWER.
86
+
87
+ :param feeder: The `Feeder` to process.
88
+ :param network_state_operators: The `NetworkStateOperators` to be used when finding SWER equipment
89
+
90
+ :return: A `Set` of `ConductingEquipment` on `feeder` that is SWER, or energised via SWER.
91
+ """
92
+
93
+ swer_equipment: Set[ConductingEquipment] = set()
94
+
95
+ # We will add all the SWER transformers to the swer_equipment list before starting any traces to prevent tracing though them by accident. In
96
+ # order to do this, we collect the sequence to a list to change the iteration order.
97
+ for equipment in network_state_operators.get_equipment(feeder):
98
+ if isinstance(equipment, PowerTransformer):
99
+ if _has_swer_terminal(equipment) and _has_non_swer_terminal(equipment):
100
+ swer_equipment.add(equipment)
101
+ await self._trace_from(network_state_operators, equipment, swer_equipment)
102
+ return swer_equipment
103
+
104
+ def _create_trace(self, state_operators: Type[NetworkStateOperators]) -> NetworkTrace[T]:
105
+ return Tracing.network_trace(
106
+ network_state_operators=state_operators,
107
+ debug_logger=self._debug_logger,
108
+ name=f'FindSwerEquipment({state_operators.description})'
109
+ ).add_condition(stop_at_open())
110
+
111
+ async def _trace_from(self, state_operators: Type[NetworkStateOperators], transformer: PowerTransformer, swer_equipment: Set[ConductingEquipment]):
112
+ # Trace from any SWER terminals.
113
+ await self._trace_swer_from(state_operators, transformer, swer_equipment)
114
+
115
+ # Trace from any LV terminals.
116
+ await self._trace_lv_from(state_operators, transformer, swer_equipment)
117
+
118
+ async def _trace_swer_from(
119
+ self,
120
+ state_operators: Type[NetworkStateOperators],
121
+ transformer: PowerTransformer,
122
+ swer_equipment: Set[ConductingEquipment]
123
+ ):
124
+
125
+ def condition(next_step, nctx, step, ctx):
126
+ if _is_swer_terminal(next_step.path.to_terminal) or isinstance(next_step.path.to_equipment, Switch):
127
+ return next_step.path.to_equipment not in swer_equipment
128
+
129
+ trace = (
130
+ self._create_trace(state_operators)
131
+ .add_queue_condition(condition)
132
+ .add_step_action(lambda step, ctx: swer_equipment.add(step.path.to_equipment))
133
+ )
134
+
135
+ for it in (t for t in transformer.terminals if _is_swer_terminal(t)):
136
+ trace.reset()
137
+ await trace.run(it, None)
138
+
139
+ async def _trace_lv_from(
140
+ self,
141
+ state_operators: Type[NetworkStateOperators],
142
+ transformer: PowerTransformer,
143
+ swer_equipment: Set[ConductingEquipment]
144
+ ):
145
+
146
+ def condition(next_step, nctx, step, ctx):
147
+ if 1 <= next_step.path.to_equipment.base_voltage_value <= 1000:
148
+ return next_step.path.to_equipment not in swer_equipment
149
+
150
+ trace = (
151
+ self._create_trace(state_operators)
152
+ .add_queue_condition(condition)
153
+ .add_step_action(lambda step, ctx: swer_equipment.add(step.path.to_equipment))
154
+ )
155
+
156
+ for terminal in transformer.terminals:
157
+ if _is_non_swer_terminal(terminal):
158
+ trace.reset()
159
+ await trace.run(terminal, None)
160
+
161
+
162
+ def _is_swer_terminal(terminal: Terminal) -> bool:
163
+ return terminal.phases.num_phases == 1
164
+
165
+
166
+ def _is_non_swer_terminal(terminal: Terminal) -> bool:
167
+ return terminal.phases.num_phases > 1
168
+
169
+
170
+ def _has_swer_terminal(ce: ConductingEquipment) -> bool:
171
+ return any(_is_swer_terminal(it) for it in ce.terminals)
172
+
173
+
174
+ def _has_non_swer_terminal(ce: ConductingEquipment) -> bool:
175
+ return any(_is_non_swer_terminal(it) for it in ce.terminals)
@@ -0,0 +1,4 @@
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/.
@@ -0,0 +1,4 @@
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/.
@@ -0,0 +1,104 @@
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
+ __all__ = ['EquipmentTreeBuilder']
7
+
8
+ import uuid
9
+ from typing import Any, Generator
10
+
11
+ from zepben.ewb.model.cim.iec61970.base.core.conducting_equipment import ConductingEquipment
12
+ from zepben.ewb.services.network.tracing.networktrace.actions.tree_node import TreeNode
13
+ from zepben.ewb.services.network.tracing.networktrace.network_trace_step import NetworkTraceStep
14
+ from zepben.ewb.services.network.tracing.traversal.step_action import StepActionWithContextValue
15
+ from zepben.ewb.services.network.tracing.traversal.step_context import StepContext
16
+
17
+ EquipmentTreeNode = TreeNode[ConductingEquipment]
18
+
19
+
20
+ class EquipmentTreeBuilder(StepActionWithContextValue):
21
+ """
22
+
23
+ A `StepAction` that can be added to a `NetworkTrace` to build a tree structure representing the paths taken during a trace.
24
+ The `_roots` are the start items of the trace and the children of a tree node represent the next step paths from a given step in the trace.
25
+
26
+ eg:
27
+
28
+ >>> from zepben.ewb import Tracing, NetworkStateOperators
29
+ >>>
30
+ >>> tree_builder = EquipmentTreeBuilder()
31
+ >>> state_operators = NetworkStateOperators.NORMAL
32
+ >>> (Tracing.network_trace_branching(network_state_operators=state_operators)
33
+ >>> .add_condition(state_operators.downstream())
34
+ >>> .add_step_action(tree_builder)).run()
35
+ """
36
+
37
+ def __init__(self, calculate_leaves: bool = False):
38
+ super().__init__(key=str(uuid.uuid4()))
39
+
40
+ self._roots: dict[ConductingEquipment, EquipmentTreeNode] = {}
41
+ self._leaves: set[EquipmentTreeNode] = set()
42
+
43
+ self._calculate_leaves = calculate_leaves
44
+
45
+ @property
46
+ def roots(self) -> Generator[TreeNode[ConductingEquipment], None, None]:
47
+ return (r for r in self._roots.values())
48
+
49
+ def recurse_nodes(self) -> Generator[TreeNode[ConductingEquipment], None, None]:
50
+ """
51
+ Returns a generator that will yield every node in the tree structure.
52
+ """
53
+ def recurse(node: TreeNode[ConductingEquipment]):
54
+ yield node
55
+ for child in node.children:
56
+ yield from recurse(child)
57
+
58
+ for root in self._roots.values():
59
+ yield from recurse(root)
60
+
61
+ @property
62
+ def leaves(self) -> set[EquipmentTreeNode]:
63
+ """
64
+ Return the leaves of the tree structure.
65
+ Depending on how the backing trace is configured, there may be extra unexpected leaves in loops.
66
+ """
67
+ if not self._calculate_leaves:
68
+ raise AttributeError('leaves were not calculated, you must pass calculate_leaves=True to the EquipmentTreeBuilder when creating.')
69
+ return set(self._leaves)
70
+
71
+ def compute_initial_value(self, item: NetworkTraceStep[Any]) -> EquipmentTreeNode:
72
+ node = self._roots.get(item.path.to_equipment)
73
+ if node is None:
74
+ node = TreeNode(item.path.to_equipment, None)
75
+ self._roots[item.path.to_equipment] = node
76
+ return node
77
+
78
+ def compute_next_value(
79
+ self,
80
+ next_item: NetworkTraceStep[Any],
81
+ current_item: NetworkTraceStep[Any],
82
+ current_value: EquipmentTreeNode
83
+ ) -> EquipmentTreeNode:
84
+
85
+ if next_item.path.traced_internally:
86
+ return current_value
87
+ else:
88
+ return TreeNode(next_item.path.to_equipment, current_value)
89
+
90
+ def _apply(self, _: NetworkTraceStep[Any], context: StepContext):
91
+ current_node: TreeNode = self.get_context_value(context)
92
+ if current_node.parent:
93
+ current_node.parent.add_child(current_node)
94
+
95
+ if self._calculate_leaves:
96
+ self._process_leaf(current_node)
97
+
98
+ def _process_leaf(self, current_node: TreeNode[ConductingEquipment]):
99
+ self._leaves.add(current_node) # add this node to _leaves as it has no children
100
+ if current_node.parent:
101
+ self._leaves.discard(current_node.parent) # this nodes parent now has a child, it's not a leaf anymore
102
+
103
+ def clear(self):
104
+ self._roots.clear()
@@ -0,0 +1,35 @@
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
+ __all__ = ['TreeNode']
7
+
8
+ from typing import TypeVar, Generic, Set
9
+
10
+ T = TypeVar('T')
11
+
12
+
13
+ class TreeNode(Generic[T]):
14
+ """
15
+ Represents a node in the NetworkTrace tree
16
+ """
17
+
18
+ def __init__(self, identified_object: T, parent=None):
19
+ self.identified_object = identified_object
20
+ self._parent: TreeNode = parent
21
+ self._children: Set[TreeNode] = set()
22
+
23
+ @property
24
+ def parent(self) -> 'TreeNode[T]':
25
+ return self._parent
26
+
27
+ @property
28
+ def children(self) -> Set['TreeNode[T]']:
29
+ return set(self._children)
30
+
31
+ def add_child(self, child: 'TreeNode[T]'):
32
+ self._children.add(child)
33
+
34
+ def __str__(self):
35
+ return f"{{object: {self.identified_object}, parent: {self.parent or ''}, num children: {len(self.children)}}}"
@@ -0,0 +1,60 @@
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
+ __all__ = ['ComputeData', 'ComputeDataWithPaths']
7
+
8
+ from typing import TypeVar, Generic
9
+
10
+ from zepben.ewb.services.network.tracing.networktrace.network_trace_step import NetworkTraceStep
11
+ from zepben.ewb.services.network.tracing.traversal.step_context import StepContext
12
+
13
+ T = TypeVar('T')
14
+
15
+
16
+ class ComputeData(Generic[T]):
17
+ """
18
+ Functional interface used to compute contextual data stored on a NetworkTraceStep.
19
+ """
20
+
21
+ def __init__(self, func):
22
+ self._func = func
23
+
24
+ def compute_next(self, current_step: NetworkTraceStep[T], current_context: StepContext, next_path: NetworkTraceStep.Path) -> T:
25
+ """
26
+ Called for each new NetworkTraceStep in a NetworkTrace. The value returned from this function
27
+ will be stored against the next step within NetworkTraceStep. data.
28
+
29
+ `currentStep` - The current step of the trace.
30
+ `currentContext` - The context of teh current step in the trace.
31
+ `nextPath` - The next path of the next NetworkTraceStep that the data will be associated with.
32
+
33
+ Returns The data to associate with the next NetworkTraceStep.
34
+ """
35
+ return self._func(current_step, current_context, next_path)
36
+
37
+
38
+ class ComputeDataWithPaths(Generic[T]):
39
+ """
40
+ Functional interface used to compute contextual data stored on a NetworkTraceStep. This can be used when the
41
+ contextual data can only be computed by knowing all the next paths that can be stepped to from a given step.
42
+ """
43
+
44
+ def __init__(self, func):
45
+ self._func = func or (lambda *args: None)
46
+
47
+ def compute_next(self, current_step: NetworkTraceStep[T], current_context: StepContext, next_path: NetworkTraceStep.Path,
48
+ next_paths: list[NetworkTraceStep.Path]) -> T:
49
+ """
50
+ Called for each new NetworkTraceStep in a NetworkTrace. The value returned from this function
51
+ will be stored against the next step within NetworkTraceStep. data.
52
+
53
+ `currentStep` - The current step of the trace.
54
+ `currentContext` - The context of teh current step in the trace.
55
+ `nextPath` - The next path of the next NetworkTraceStep that the data will be associated with.
56
+ `nextPaths` - A list of all the next paths that the current step can trace to.
57
+
58
+ Returns The data to associate with the next NetworkTraceStep.
59
+ """
60
+ return self._func(current_step, current_context, next_path, next_paths)
@@ -0,0 +1,4 @@
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/.
@@ -0,0 +1,73 @@
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__ = ['upstream', 'downstream', 'with_direction', 'limit_equipment_steps', 'stop_at_open']
9
+
10
+ from typing import TYPE_CHECKING, TypeVar, Type, Callable
11
+
12
+ from zepben.ewb.services.network.tracing.feeder.feeder_direction import FeederDirection
13
+ from zepben.ewb.services.network.tracing.networktrace.conditions.direction_condition import DirectionCondition
14
+ from zepben.ewb.services.network.tracing.networktrace.conditions.equipment_step_limit_condition import EquipmentStepLimitCondition
15
+ from zepben.ewb.services.network.tracing.networktrace.conditions.equipment_type_step_limit_condition import EquipmentTypeStepLimitCondition
16
+
17
+ T = TypeVar('T')
18
+
19
+ if TYPE_CHECKING:
20
+ from zepben.ewb.services.network.tracing.networktrace.network_trace_step import NetworkTraceStep
21
+ from zepben.ewb.services.network.tracing.traversal.queue_condition import QueueCondition
22
+ from zepben.ewb.services.network.tracing.traversal.stop_condition import StopCondition
23
+ from zepben.ewb import ConductingEquipment, NetworkStateOperators
24
+
25
+ DSLLambda = Callable[[NetworkStateOperators], QueueCondition[NetworkTraceStep[T]]]
26
+
27
+
28
+ def upstream() -> DSLLambda:
29
+ """
30
+ Creates a [NetworkTrace] condition that will cause tracing a feeder upstream (towards the head terminal).
31
+ This uses [FeederDirectionStateOperations.get_direction] receiver instance method within the condition.
32
+
33
+ :return: [NetworkTraceQueueCondition] that results in upstream tracing.
34
+ """
35
+ return lambda state_operator: state_operator.with_direction(FeederDirection.UPSTREAM)
36
+
37
+
38
+ def downstream() -> DSLLambda:
39
+ """
40
+ Creates a [NetworkTrace] condition that will cause tracing a feeder downstream (away from the head terminal).
41
+ This uses [FeederDirectionStateOperations.get_direction] receiver instance method within the condition.
42
+
43
+ :return: [NetworkTraceQueueCondition] that results in downstream tracing.
44
+ """
45
+ return lambda state_operator: state_operator.with_direction(FeederDirection.DOWNSTREAM)
46
+
47
+
48
+ def with_direction(direction: FeederDirection) -> DSLLambda:
49
+ """
50
+ Creates a [NetworkTrace] condition that will cause tracing only terminals with directions that match [direction].
51
+ This uses [FeederDirectionStateOperations.get_direction] receiver instance method within the condition.
52
+
53
+ :return: [NetworkTraceQueueCondition] that results in upstream tracing.
54
+ """
55
+ return lambda state_operator: DirectionCondition(direction, state_operator)
56
+
57
+
58
+ def limit_equipment_steps(limit: int, equipment_type: Type[ConductingEquipment] = None) -> StopCondition[NetworkTraceStep[T]]:
59
+ """
60
+ Creates a [NetworkTrace] condition that stops tracing a path once a specified number of equipment steps have been reached.
61
+
62
+ :param limit: The maximum number of equipment steps allowed before stopping.
63
+ :param equipment_type: The class of the equipment type to track against the limit
64
+
65
+ :return: A [NetworkTraceStopCondition] that stops tracing the path once the step limit is reached.
66
+ """
67
+ if equipment_type is not None:
68
+ return EquipmentTypeStepLimitCondition(limit, equipment_type)
69
+ return EquipmentStepLimitCondition(limit)
70
+
71
+
72
+ def stop_at_open():
73
+ return lambda state_operator: state_operator.stop_at_open()
@@ -0,0 +1,63 @@
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__ = ['DirectionCondition']
9
+
10
+ from typing import TypeVar, TYPE_CHECKING, Generic, Type
11
+
12
+ from zepben.ewb import require
13
+ from zepben.ewb.model.cim.iec61970.base.wires.clamp import Clamp
14
+ from zepben.ewb.model.cim.iec61970.base.wires.cut import Cut
15
+ from zepben.ewb.services.network.tracing.feeder.feeder_direction import FeederDirection
16
+ from zepben.ewb.services.network.tracing.networktrace.network_trace_step import NetworkTraceStep
17
+ from zepben.ewb.services.network.tracing.traversal.queue_condition import QueueCondition
18
+
19
+ if TYPE_CHECKING:
20
+ from zepben.ewb.services.network.tracing.networktrace.operators.network_state_operators import NetworkStateOperators
21
+ from zepben.ewb import StepContext
22
+
23
+ T = TypeVar('T')
24
+
25
+
26
+ class DirectionCondition(QueueCondition[NetworkTraceStep[T]], Generic[T]):
27
+
28
+ def __init__(self, direction: FeederDirection, state_operators: Type[NetworkStateOperators]):
29
+ require(direction != FeederDirection.CONNECTOR, lambda: 'A direction of CONNECTOR is not currently supported')
30
+ self.direction = direction
31
+ self.state_operators = state_operators
32
+ self.get_direction = self.state_operators.get_direction
33
+
34
+ def should_queue(self, next_item: NetworkTraceStep[T], next_context: StepContext[T], current_item: NetworkTraceStep[T],
35
+ current_context: StepContext[T]) -> bool:
36
+ return self._should_queue(next_item.path)
37
+
38
+ def _should_queue(self, path: NetworkTraceStep.Path) -> bool:
39
+ # Cuts do weird things with directions depending on if they are energised from an external connection, or through a "closed" cut. To prevent
40
+ # dealing with this awful mess, it is much simpler to just ask if anything else past it needs queueing. This could be made to short-circuit
41
+ # for traversing downstream, but the code is much more complex to only save one extra step.
42
+ if isinstance(path.to_equipment, Cut):
43
+ return self._should_queue_next_paths(path)
44
+ elif path.traced_internally or path.did_traverse_ac_line_segment:
45
+ return self.direction in self.get_direction(path.to_terminal)
46
+ else:
47
+ return self.direction.complementary_external_direction in self.get_direction(path.to_terminal)
48
+
49
+ def should_queue_start_item(self, item: NetworkTraceStep[T]) -> bool:
50
+ if self.direction in self.get_direction(item.path.to_terminal):
51
+ return True
52
+ # Because cuts and clamps behave a bit different with directions than other equipment terminals, we can also check if any further paths needs to be
53
+ # queued, and if they do we queue the start item.
54
+ elif isinstance(item.path.to_equipment, (Clamp, Cut)):
55
+ return self._should_queue_next_paths(item.path)
56
+ return False
57
+
58
+ def _should_queue_next_paths(self, path: NetworkTraceStep.Path) -> bool:
59
+ for next_path in self.state_operators.next_paths(path):
60
+ if not (next_path.traced_internally and self.state_operators.is_open(path.to_equipment)):
61
+ if self._should_queue(next_path):
62
+ return True
63
+ return False
@@ -0,0 +1,26 @@
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__ = ['EquipmentStepLimitCondition']
9
+
10
+ from typing import TypeVar, TYPE_CHECKING
11
+
12
+ from zepben.ewb.services.network.tracing.traversal.stop_condition import StopCondition
13
+
14
+ T = TypeVar('T')
15
+
16
+ if TYPE_CHECKING:
17
+ from zepben.ewb import StepContext, NetworkTraceStep
18
+
19
+
20
+ class EquipmentStepLimitCondition(StopCondition['NetworkTraceStep[T]']):
21
+ def __init__(self, limit: int):
22
+ super().__init__()
23
+ self.limit = limit
24
+
25
+ def should_stop(self, item: NetworkTraceStep[T], context: StepContext) -> bool:
26
+ return item.num_equipment_steps >= self.limit
@@ -0,0 +1,44 @@
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__ = ['EquipmentTypeStepLimitCondition']
9
+
10
+ from typing import Generic, TypeVar, TYPE_CHECKING, Type
11
+
12
+ from zepben.ewb.services.network.tracing.traversal.context_value_computer import ContextValueComputer
13
+ from zepben.ewb.services.network.tracing.traversal.stop_condition import StopConditionWithContextValue
14
+
15
+ if TYPE_CHECKING:
16
+ from zepben.ewb import ConductingEquipment, StepContext, NetworkTraceStep
17
+
18
+ T = TypeVar('T')
19
+ U = TypeVar('U')
20
+
21
+
22
+ class EquipmentTypeStepLimitCondition(StopConditionWithContextValue[T], Generic[T, U]):
23
+ def __init__(self, limit: int, equipment_type: Type[ConductingEquipment]):
24
+ StopConditionWithContextValue.__init__(self, self.should_stop)
25
+ ContextValueComputer.__init__(self, f'sdk:{equipment_type.name}Count')
26
+ self.limit = limit
27
+ self.equipment_type = equipment_type
28
+
29
+ def should_stop(self, item: NetworkTraceStep[T], context: StepContext) -> bool:
30
+ return self.get_context_value(context) >= self.limit
31
+
32
+ def compute_initial_value(self, item: NetworkTraceStep[T]) -> int:
33
+ return 0
34
+
35
+ def compute_next_value(self, next_item: NetworkTraceStep[T], current_item: NetworkTraceStep[T], current_value: int) -> int:
36
+ if next_item.path.traced_internally:
37
+ return current_value
38
+ if self.matches_equipment_type(next_item.path.to_equipment):
39
+ return current_value + 1
40
+ else:
41
+ return current_value
42
+
43
+ def matches_equipment_type(self, conducting_equipment: ConductingEquipment) -> bool:
44
+ return isinstance(conducting_equipment, self.equipment_type)
@@ -0,0 +1,67 @@
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
+ __all__ = ['NetworkTraceQueueCondition']
7
+
8
+ from typing import TypeVar, Generic
9
+
10
+ from zepben.ewb.services.network.tracing.networktrace.network_trace_step import NetworkTraceStep
11
+ from zepben.ewb.services.network.tracing.traversal.queue_condition import QueueCondition, ShouldQueue
12
+ from zepben.ewb.services.network.tracing.traversal.step_context import StepContext
13
+
14
+ T = TypeVar('T')
15
+
16
+
17
+ class NetworkTraceQueueCondition(QueueCondition[NetworkTraceStep[T]], Generic[T]):
18
+ """
19
+ A special queue condition implementation that allows only checking `should_queue` when a [NetworkTraceStep] matches a given
20
+ [NetworkTraceStep.Type]. When [step_type] is:
21
+ *[NetworkTraceStep.Type.ALL]: [should_queue] will be called for every step.
22
+ *[NetworkTraceStep.Type.INTERNAL]: [shouldQueue] will be called only when [NetworkTraceStep.type] is [NetworkTraceStep.Type.INTERNAL].
23
+ *[NetworkTraceStep.Type.EXTERNAL]: [shouldQueue] will be called only when [NetworkTraceStep.type] is [NetworkTraceStep.Type.EXTERNAL].
24
+
25
+ If the step does not match the given step type, `true` will always be returned.
26
+ """
27
+
28
+ def __init__(self, step_type: NetworkTraceStep.Type, condition: ShouldQueue = None):
29
+ """
30
+ :param step_type: The step type to match to check `should_queue`.
31
+ :param condition: function with the signature of `ShouldQueue` to be called when step_type matches the current items step
32
+ """
33
+ super().__init__(self.should_queue)
34
+ if condition is not None:
35
+ self.should_queue_matched_step = condition
36
+ self.should_queue = self._should_queue_func(step_type)
37
+
38
+ def should_queue(self, next_item: T, next_context: StepContext, current_item: T, current_context: StepContext) -> bool:
39
+ raise NotImplementedError()
40
+
41
+ def should_queue_matched_step(self, next_item: NetworkTraceStep[T], next_context: StepContext, current_item: NetworkTraceStep[T],
42
+ current_context: StepContext) -> bool:
43
+ """
44
+ The logic you would normally put in `should_queue`. However, this will only be called when a step matches the `step_type`
45
+ """
46
+ raise NotImplementedError()
47
+
48
+ def should_queue_internal_step(self, next_item: NetworkTraceStep[T], next_context: StepContext, current_item: NetworkTraceStep[T],
49
+ current_context: StepContext) -> bool:
50
+ if next_item.type() == NetworkTraceStep.Type.INTERNAL:
51
+ return self.should_queue_matched_step(next_item, next_context, current_item, current_context)
52
+ return True
53
+
54
+ def should_queue_external_step(self, next_item: NetworkTraceStep[T], next_context: StepContext, current_item: NetworkTraceStep[T],
55
+ current_context: StepContext) -> bool:
56
+ if next_item.type() == NetworkTraceStep.Type.EXTERNAL:
57
+ return self.should_queue_matched_step(next_item, next_context, current_item, current_context)
58
+ return True
59
+
60
+ def _should_queue_func(self, step_type: NetworkTraceStep.Type) -> ShouldQueue:
61
+ if step_type == NetworkTraceStep.Type.ALL:
62
+ return self.should_queue_matched_step
63
+ elif step_type == NetworkTraceStep.Type.INTERNAL:
64
+ return self.should_queue_internal_step
65
+ elif step_type == NetworkTraceStep.Type.EXTERNAL:
66
+ return self.should_queue_external_step
67
+ raise ValueError(f"INTERNAL ERROR: step type [{step_type}] didn't match expected")