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,2561 @@
1
+ # Copyright 2024 Zeppelin Bend Pty Ltd
2
+ # This Source Code Form is subject to the terms of the Mozilla Public
3
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ # file, You can obtain one at https://mozilla.org/MPL/2.0/.
5
+
6
+ __all__ = ["NetworkCimWriter"]
7
+
8
+ from typing import Optional
9
+
10
+ from zepben.ewb.database.sqlite.common.base_cim_writer import BaseCimWriter
11
+ from zepben.ewb.database.sqlite.extensions.prepared_statement import PreparedStatement
12
+ from zepben.ewb.database.sqlite.network.network_database_tables import NetworkDatabaseTables
13
+ from zepben.ewb.database.sqlite.tables.associations.loop_substation_relationship import LoopSubstationRelationship
14
+ from zepben.ewb.database.sqlite.tables.associations.table_asset_organisation_roles_assets import TableAssetOrganisationRolesAssets
15
+ from zepben.ewb.database.sqlite.tables.associations.table_assets_power_system_resources import TableAssetsPowerSystemResources
16
+ from zepben.ewb.database.sqlite.tables.associations.table_battery_units_battery_controls import TableBatteryUnitsBatteryControls
17
+ from zepben.ewb.database.sqlite.tables.associations.table_circuits_substations import TableCircuitsSubstations
18
+ from zepben.ewb.database.sqlite.tables.associations.table_circuits_terminals import TableCircuitsTerminals
19
+ from zepben.ewb.database.sqlite.tables.associations.table_end_devices_end_device_functions import TableEndDevicesEndDeviceFunctions
20
+ from zepben.ewb.database.sqlite.tables.associations.table_equipment_equipment_containers import TableEquipmentEquipmentContainers
21
+ from zepben.ewb.database.sqlite.tables.associations.table_equipment_operational_restrictions import TableEquipmentOperationalRestrictions
22
+ from zepben.ewb.database.sqlite.tables.associations.table_equipment_usage_points import TableEquipmentUsagePoints
23
+ from zepben.ewb.database.sqlite.tables.associations.table_loops_substations import TableLoopsSubstations
24
+ from zepben.ewb.database.sqlite.tables.associations.table_protection_relay_functions_protected_switches import TableProtectionRelayFunctionsProtectedSwitches
25
+ from zepben.ewb.database.sqlite.tables.associations.table_protection_relay_functions_sensors import TableProtectionRelayFunctionsSensors
26
+ from zepben.ewb.database.sqlite.tables.associations.table_protection_relay_schemes_protection_relay_functions import \
27
+ TableProtectionRelaySchemesProtectionRelayFunctions
28
+ from zepben.ewb.database.sqlite.tables.associations.table_synchronous_machines_reactive_capability_curves import \
29
+ TableSynchronousMachinesReactiveCapabilityCurves
30
+ from zepben.ewb.database.sqlite.tables.associations.table_usage_points_end_devices import TableUsagePointsEndDevices
31
+ from zepben.ewb.database.sqlite.tables.extensions.iec61968.assetinfo.table_reclose_delays import TableRecloseDelays
32
+ from zepben.ewb.database.sqlite.tables.extensions.iec61968.assetinfo.table_relay_info import TableRelayInfo
33
+ from zepben.ewb.database.sqlite.tables.extensions.iec61968.metering.table_pan_demand_response_functions import TablePanDemandResponseFunctions
34
+ from zepben.ewb.database.sqlite.tables.extensions.iec61970.base.core.table_sites import TableSites
35
+ from zepben.ewb.database.sqlite.tables.extensions.iec61970.base.feeder.table_loops import TableLoops
36
+ from zepben.ewb.database.sqlite.tables.extensions.iec61970.base.feeder.table_lv_feeders import TableLvFeeders
37
+ from zepben.ewb.database.sqlite.tables.extensions.iec61970.base.generation.production.table_ev_charging_units import TableEvChargingUnits
38
+ from zepben.ewb.database.sqlite.tables.extensions.iec61970.base.protection.table_distance_relays import TableDistanceRelays
39
+ from zepben.ewb.database.sqlite.tables.extensions.iec61970.base.protection.table_protection_relay_function_thresholds import \
40
+ TableProtectionRelayFunctionThresholds
41
+ from zepben.ewb.database.sqlite.tables.extensions.iec61970.base.protection.table_protection_relay_function_time_limits import \
42
+ TableProtectionRelayFunctionTimeLimits
43
+ from zepben.ewb.database.sqlite.tables.extensions.iec61970.base.protection.table_protection_relay_functions import TableProtectionRelayFunctions
44
+ from zepben.ewb.database.sqlite.tables.extensions.iec61970.base.protection.table_protection_relay_schemes import TableProtectionRelaySchemes
45
+ from zepben.ewb.database.sqlite.tables.extensions.iec61970.base.protection.table_protection_relay_systems import TableProtectionRelaySystems
46
+ from zepben.ewb.database.sqlite.tables.extensions.iec61970.base.protection.table_voltage_relays import TableVoltageRelays
47
+ from zepben.ewb.database.sqlite.tables.extensions.iec61970.base.wires.table_battery_controls import TableBatteryControls
48
+ from zepben.ewb.database.sqlite.tables.extensions.iec61970.base.wires.table_power_transformer_end_ratings import TablePowerTransformerEndRatings
49
+ from zepben.ewb.database.sqlite.tables.iec61968.assetinfo.table_cable_info import TableCableInfo
50
+ from zepben.ewb.database.sqlite.tables.iec61968.assetinfo.table_no_load_tests import TableNoLoadTests
51
+ from zepben.ewb.database.sqlite.tables.iec61968.assetinfo.table_open_circuit_tests import TableOpenCircuitTests
52
+ from zepben.ewb.database.sqlite.tables.iec61968.assetinfo.table_overhead_wire_info import TableOverheadWireInfo
53
+ from zepben.ewb.database.sqlite.tables.iec61968.assetinfo.table_power_transformer_info import TablePowerTransformerInfo
54
+ from zepben.ewb.database.sqlite.tables.iec61968.assetinfo.table_short_circuit_tests import TableShortCircuitTests
55
+ from zepben.ewb.database.sqlite.tables.iec61968.assetinfo.table_shunt_compensator_info import TableShuntCompensatorInfo
56
+ from zepben.ewb.database.sqlite.tables.iec61968.assetinfo.table_switch_info import TableSwitchInfo
57
+ from zepben.ewb.database.sqlite.tables.iec61968.assetinfo.table_transformer_end_info import TableTransformerEndInfo
58
+ from zepben.ewb.database.sqlite.tables.iec61968.assetinfo.table_transformer_tank_info import TableTransformerTankInfo
59
+ from zepben.ewb.database.sqlite.tables.iec61968.assetinfo.table_transformer_test import TableTransformerTest
60
+ from zepben.ewb.database.sqlite.tables.iec61968.assetinfo.table_wire_info import TableWireInfo
61
+ from zepben.ewb.database.sqlite.tables.iec61968.assets.table_asset_containers import TableAssetContainers
62
+ from zepben.ewb.database.sqlite.tables.iec61968.assets.table_asset_functions import TableAssetFunctions
63
+ from zepben.ewb.database.sqlite.tables.iec61968.assets.table_asset_info import TableAssetInfo
64
+ from zepben.ewb.database.sqlite.tables.iec61968.assets.table_asset_organisation_roles import TableAssetOrganisationRoles
65
+ from zepben.ewb.database.sqlite.tables.iec61968.assets.table_asset_owners import TableAssetOwners
66
+ from zepben.ewb.database.sqlite.tables.iec61968.assets.table_assets import TableAssets
67
+ from zepben.ewb.database.sqlite.tables.iec61968.assets.table_streetlights import TableStreetlights
68
+ from zepben.ewb.database.sqlite.tables.iec61968.assets.table_structures import TableStructures
69
+ from zepben.ewb.database.sqlite.tables.iec61968.common.table_location_street_address_field import TableLocationStreetAddressField
70
+ from zepben.ewb.database.sqlite.tables.iec61968.common.table_location_street_addresses import TableLocationStreetAddresses
71
+ from zepben.ewb.database.sqlite.tables.iec61968.common.table_locations import TableLocations
72
+ from zepben.ewb.database.sqlite.tables.iec61968.common.table_position_points import TablePositionPoints
73
+ from zepben.ewb.database.sqlite.tables.iec61968.common.table_street_addresses import TableStreetAddresses
74
+ from zepben.ewb.database.sqlite.tables.iec61968.common.table_town_details import TableTownDetails
75
+ from zepben.ewb.database.sqlite.tables.iec61968.infiec61968.infassetinfo.table_current_transformer_info import TableCurrentTransformerInfo
76
+ from zepben.ewb.database.sqlite.tables.iec61968.infiec61968.infassetinfo.table_potential_transformer_info import TablePotentialTransformerInfo
77
+ from zepben.ewb.database.sqlite.tables.iec61968.infiec61968.infassets.table_poles import TablePoles
78
+ from zepben.ewb.database.sqlite.tables.iec61968.metering.table_end_device_functions import TableEndDeviceFunctions
79
+ from zepben.ewb.database.sqlite.tables.iec61968.metering.table_end_devices import TableEndDevices
80
+ from zepben.ewb.database.sqlite.tables.iec61968.metering.table_meters import TableMeters
81
+ from zepben.ewb.database.sqlite.tables.iec61968.metering.table_usage_points import TableUsagePoints
82
+ from zepben.ewb.database.sqlite.tables.iec61968.operations.table_operational_restrictions import TableOperationalRestrictions
83
+ from zepben.ewb.database.sqlite.tables.iec61970.base.auxiliaryequipment.table_auxiliary_equipment import TableAuxiliaryEquipment
84
+ from zepben.ewb.database.sqlite.tables.iec61970.base.auxiliaryequipment.table_current_transformers import TableCurrentTransformers
85
+ from zepben.ewb.database.sqlite.tables.iec61970.base.auxiliaryequipment.table_fault_indicators import TableFaultIndicators
86
+ from zepben.ewb.database.sqlite.tables.iec61970.base.auxiliaryequipment.table_potential_transformers import TablePotentialTransformers
87
+ from zepben.ewb.database.sqlite.tables.iec61970.base.auxiliaryequipment.table_sensors import TableSensors
88
+ from zepben.ewb.database.sqlite.tables.iec61970.base.core.table_ac_dc_terminals import TableAcDcTerminals
89
+ from zepben.ewb.database.sqlite.tables.iec61970.base.core.table_base_voltages import TableBaseVoltages
90
+ from zepben.ewb.database.sqlite.tables.iec61970.base.core.table_conducting_equipment import TableConductingEquipment
91
+ from zepben.ewb.database.sqlite.tables.iec61970.base.core.table_connectivity_node_containers import TableConnectivityNodeContainers
92
+ from zepben.ewb.database.sqlite.tables.iec61970.base.core.table_connectivity_nodes import TableConnectivityNodes
93
+ from zepben.ewb.database.sqlite.tables.iec61970.base.core.table_curve_data import TableCurveData
94
+ from zepben.ewb.database.sqlite.tables.iec61970.base.core.table_curves import TableCurves
95
+ from zepben.ewb.database.sqlite.tables.iec61970.base.core.table_equipment import TableEquipment
96
+ from zepben.ewb.database.sqlite.tables.iec61970.base.core.table_equipment_containers import TableEquipmentContainers
97
+ from zepben.ewb.database.sqlite.tables.iec61970.base.core.table_feeders import TableFeeders
98
+ from zepben.ewb.database.sqlite.tables.iec61970.base.core.table_geographical_regions import TableGeographicalRegions
99
+ from zepben.ewb.database.sqlite.tables.iec61970.base.core.table_power_system_resources import TablePowerSystemResources
100
+ from zepben.ewb.database.sqlite.tables.iec61970.base.core.table_sub_geographical_regions import TableSubGeographicalRegions
101
+ from zepben.ewb.database.sqlite.tables.iec61970.base.core.table_substations import TableSubstations
102
+ from zepben.ewb.database.sqlite.tables.iec61970.base.core.table_terminals import TableTerminals
103
+ from zepben.ewb.database.sqlite.tables.iec61970.base.equivalents.table_equivalent_branches import TableEquivalentBranches
104
+ from zepben.ewb.database.sqlite.tables.iec61970.base.equivalents.table_equivalent_equipment import TableEquivalentEquipment
105
+ from zepben.ewb.database.sqlite.tables.iec61970.base.generation.production.table_battery_units import TableBatteryUnits
106
+ from zepben.ewb.database.sqlite.tables.iec61970.base.generation.production.table_photo_voltaic_units import TablePhotoVoltaicUnits
107
+ from zepben.ewb.database.sqlite.tables.iec61970.base.generation.production.table_power_electronics_units import TablePowerElectronicsUnits
108
+ from zepben.ewb.database.sqlite.tables.iec61970.base.generation.production.table_power_electronics_wind_units import TablePowerElectronicsWindUnits
109
+ from zepben.ewb.database.sqlite.tables.iec61970.base.meas.table_accumulators import TableAccumulators
110
+ from zepben.ewb.database.sqlite.tables.iec61970.base.meas.table_analogs import TableAnalogs
111
+ from zepben.ewb.database.sqlite.tables.iec61970.base.meas.table_controls import TableControls
112
+ from zepben.ewb.database.sqlite.tables.iec61970.base.meas.table_discretes import TableDiscretes
113
+ from zepben.ewb.database.sqlite.tables.iec61970.base.meas.table_io_points import TableIoPoints
114
+ from zepben.ewb.database.sqlite.tables.iec61970.base.meas.table_measurements import TableMeasurements
115
+ from zepben.ewb.database.sqlite.tables.iec61970.base.protection.table_current_relays import TableCurrentRelays
116
+ from zepben.ewb.database.sqlite.tables.iec61970.base.scada.table_remote_controls import TableRemoteControls
117
+ from zepben.ewb.database.sqlite.tables.iec61970.base.scada.table_remote_points import TableRemotePoints
118
+ from zepben.ewb.database.sqlite.tables.iec61970.base.scada.table_remote_sources import TableRemoteSources
119
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_ac_line_segments import TableAcLineSegments
120
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_breakers import TableBreakers
121
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_busbar_sections import TableBusbarSections
122
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_clamps import TableClamps
123
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_conductors import TableConductors
124
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_connectors import TableConnectors
125
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_cuts import TableCuts
126
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_disconnectors import TableDisconnectors
127
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_earth_fault_compensators import TableEarthFaultCompensators
128
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_energy_connections import TableEnergyConnections
129
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_energy_consumer_phases import TableEnergyConsumerPhases
130
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_energy_consumers import TableEnergyConsumers
131
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_energy_source_phases import TableEnergySourcePhases
132
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_energy_sources import TableEnergySources
133
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_fuses import TableFuses
134
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_ground_disconnectors import TableGroundDisconnectors
135
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_grounding_impedances import TableGroundingImpedances
136
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_grounds import TableGrounds
137
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_jumpers import TableJumpers
138
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_junctions import TableJunctions
139
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_linear_shunt_compensators import TableLinearShuntCompensators
140
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_lines import TableLines
141
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_load_break_switches import TableLoadBreakSwitches
142
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_per_length_impedances import TablePerLengthImpedances
143
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_per_length_line_parameters import TablePerLengthLineParameters
144
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_per_length_phase_impedances import TablePerLengthPhaseImpedances
145
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_per_length_sequence_impedances import TablePerLengthSequenceImpedances
146
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_petersen_coils import TablePetersenCoils
147
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_phase_impedance_data import TablePhaseImpedanceData
148
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_power_electronics_connection_phases import TablePowerElectronicsConnectionPhases
149
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_power_electronics_connections import TablePowerElectronicsConnections
150
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_power_transformer_ends import TablePowerTransformerEnds
151
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_power_transformers import TablePowerTransformers
152
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_protected_switches import TableProtectedSwitches
153
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_ratio_tap_changers import TableRatioTapChangers
154
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_reactive_capability_curves import TableReactiveCapabilityCurves
155
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_reclosers import TableReclosers
156
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_regulating_cond_eq import TableRegulatingCondEq
157
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_regulating_controls import TableRegulatingControls
158
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_rotating_machines import TableRotatingMachines
159
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_series_compensators import TableSeriesCompensators
160
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_shunt_compensators import TableShuntCompensators
161
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_static_var_compensator import TableStaticVarCompensators
162
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_switches import TableSwitches
163
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_synchronous_machines import TableSynchronousMachines
164
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_tap_changer_controls import TableTapChangerControls
165
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_tap_changers import TableTapChangers
166
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_transformer_ends import TableTransformerEnds
167
+ from zepben.ewb.database.sqlite.tables.iec61970.base.wires.table_transformer_star_impedances import TableTransformerStarImpedances
168
+ from zepben.ewb.database.sqlite.tables.iec61970.infiec61970.feeder.table_circuits import TableCircuits
169
+ from zepben.ewb.model.cim.extensions.iec61968.assetinfo.relay_info import RelayInfo
170
+ from zepben.ewb.model.cim.extensions.iec61968.metering.pan_demand_reponse_function import PanDemandResponseFunction
171
+ from zepben.ewb.model.cim.extensions.iec61970.base.core.site import Site
172
+ from zepben.ewb.model.cim.extensions.iec61970.base.feeder.loop import Loop
173
+ from zepben.ewb.model.cim.extensions.iec61970.base.feeder.lv_feeder import LvFeeder
174
+ from zepben.ewb.model.cim.extensions.iec61970.base.generation.production.ev_charging_unit import EvChargingUnit
175
+ from zepben.ewb.model.cim.extensions.iec61970.base.protection.distance_relay import DistanceRelay
176
+ from zepben.ewb.model.cim.extensions.iec61970.base.protection.protection_relay_function import ProtectionRelayFunction
177
+ from zepben.ewb.model.cim.extensions.iec61970.base.protection.protection_relay_scheme import ProtectionRelayScheme
178
+ from zepben.ewb.model.cim.extensions.iec61970.base.protection.protection_relay_system import ProtectionRelaySystem
179
+ from zepben.ewb.model.cim.extensions.iec61970.base.protection.relay_setting import RelaySetting
180
+ from zepben.ewb.model.cim.extensions.iec61970.base.protection.voltage_relay import VoltageRelay
181
+ from zepben.ewb.model.cim.extensions.iec61970.base.wires.battery_control import BatteryControl
182
+ from zepben.ewb.model.cim.iec61968.assetinfo.cable_info import CableInfo
183
+ from zepben.ewb.model.cim.iec61968.assetinfo.no_load_test import NoLoadTest
184
+ from zepben.ewb.model.cim.iec61968.assetinfo.open_circuit_test import OpenCircuitTest
185
+ from zepben.ewb.model.cim.iec61968.assetinfo.overhead_wire_info import OverheadWireInfo
186
+ from zepben.ewb.model.cim.iec61968.assetinfo.power_transformer_info import PowerTransformerInfo
187
+ from zepben.ewb.model.cim.iec61968.assetinfo.short_circuit_test import ShortCircuitTest
188
+ from zepben.ewb.model.cim.iec61968.assetinfo.shunt_compensator_info import ShuntCompensatorInfo
189
+ from zepben.ewb.model.cim.iec61968.assetinfo.switch_info import SwitchInfo
190
+ from zepben.ewb.model.cim.iec61968.assetinfo.transformer_end_info import TransformerEndInfo
191
+ from zepben.ewb.model.cim.iec61968.assetinfo.transformer_tank_info import TransformerTankInfo
192
+ from zepben.ewb.model.cim.iec61968.assetinfo.transformer_test import TransformerTest
193
+ from zepben.ewb.model.cim.iec61968.assetinfo.wire_info import WireInfo
194
+ from zepben.ewb.model.cim.iec61968.assets.asset import Asset
195
+ from zepben.ewb.model.cim.iec61968.assets.asset_container import AssetContainer
196
+ from zepben.ewb.model.cim.iec61968.assets.asset_function import AssetFunction
197
+ from zepben.ewb.model.cim.iec61968.assets.asset_info import AssetInfo
198
+ from zepben.ewb.model.cim.iec61968.assets.asset_organisation_role import AssetOrganisationRole
199
+ from zepben.ewb.model.cim.iec61968.assets.asset_owner import AssetOwner
200
+ from zepben.ewb.model.cim.iec61968.assets.streetlight import Streetlight
201
+ from zepben.ewb.model.cim.iec61968.assets.structure import Structure
202
+ from zepben.ewb.model.cim.iec61968.common.location import Location
203
+ from zepben.ewb.model.cim.iec61968.common.position_point import PositionPoint
204
+ from zepben.ewb.model.cim.iec61968.common.street_address import StreetAddress
205
+ from zepben.ewb.model.cim.iec61968.common.street_detail import StreetDetail
206
+ from zepben.ewb.model.cim.iec61968.common.town_detail import TownDetail
207
+ from zepben.ewb.model.cim.iec61968.infiec61968.infassetinfo.current_transformer_info import CurrentTransformerInfo
208
+ from zepben.ewb.model.cim.iec61968.infiec61968.infassetinfo.potential_transformer_info import PotentialTransformerInfo
209
+ from zepben.ewb.model.cim.iec61968.infiec61968.infassets.pole import Pole
210
+ from zepben.ewb.model.cim.iec61968.metering.end_device import EndDevice
211
+ from zepben.ewb.model.cim.iec61968.metering.end_device_function import EndDeviceFunction
212
+ from zepben.ewb.model.cim.iec61968.metering.meter import Meter
213
+ from zepben.ewb.model.cim.iec61968.metering.usage_point import UsagePoint
214
+ from zepben.ewb.model.cim.iec61968.operations.operational_restriction import OperationalRestriction
215
+ from zepben.ewb.model.cim.iec61970.base.auxiliaryequipment.auxiliary_equipment import AuxiliaryEquipment
216
+ from zepben.ewb.model.cim.iec61970.base.auxiliaryequipment.current_transformer import CurrentTransformer
217
+ from zepben.ewb.model.cim.iec61970.base.auxiliaryequipment.fault_indicator import FaultIndicator
218
+ from zepben.ewb.model.cim.iec61970.base.auxiliaryequipment.potential_transformer import PotentialTransformer
219
+ from zepben.ewb.model.cim.iec61970.base.auxiliaryequipment.sensor import Sensor
220
+ from zepben.ewb.model.cim.iec61970.base.core.ac_dc_terminal import AcDcTerminal
221
+ from zepben.ewb.model.cim.iec61970.base.core.base_voltage import BaseVoltage
222
+ from zepben.ewb.model.cim.iec61970.base.core.conducting_equipment import ConductingEquipment
223
+ from zepben.ewb.model.cim.iec61970.base.core.connectivity_node import ConnectivityNode
224
+ from zepben.ewb.model.cim.iec61970.base.core.connectivity_node_container import ConnectivityNodeContainer
225
+ from zepben.ewb.model.cim.iec61970.base.core.curve import Curve
226
+ from zepben.ewb.model.cim.iec61970.base.core.curve_data import CurveData
227
+ from zepben.ewb.model.cim.iec61970.base.core.equipment import Equipment
228
+ from zepben.ewb.model.cim.iec61970.base.core.equipment_container import EquipmentContainer
229
+ from zepben.ewb.model.cim.iec61970.base.core.feeder import Feeder
230
+ from zepben.ewb.model.cim.iec61970.base.core.geographical_region import GeographicalRegion
231
+ from zepben.ewb.model.cim.iec61970.base.core.power_system_resource import PowerSystemResource
232
+ from zepben.ewb.model.cim.iec61970.base.core.sub_geographical_region import SubGeographicalRegion
233
+ from zepben.ewb.model.cim.iec61970.base.core.substation import Substation
234
+ from zepben.ewb.model.cim.iec61970.base.core.terminal import Terminal
235
+ from zepben.ewb.model.cim.iec61970.base.equivalents.equivalent_branch import EquivalentBranch
236
+ from zepben.ewb.model.cim.iec61970.base.equivalents.equivalent_equipment import EquivalentEquipment
237
+ from zepben.ewb.model.cim.iec61970.base.generation.production.battery_unit import BatteryUnit
238
+ from zepben.ewb.model.cim.iec61970.base.generation.production.photo_voltaic_unit import PhotoVoltaicUnit
239
+ from zepben.ewb.model.cim.iec61970.base.generation.production.power_electronics_unit import PowerElectronicsUnit
240
+ from zepben.ewb.model.cim.iec61970.base.generation.production.power_electronics_wind_unit import PowerElectronicsWindUnit
241
+ from zepben.ewb.model.cim.iec61970.base.meas.accumulator import Accumulator
242
+ from zepben.ewb.model.cim.iec61970.base.meas.analog import Analog
243
+ from zepben.ewb.model.cim.iec61970.base.meas.control import Control
244
+ from zepben.ewb.model.cim.iec61970.base.meas.discrete import Discrete
245
+ from zepben.ewb.model.cim.iec61970.base.meas.iopoint import IoPoint
246
+ from zepben.ewb.model.cim.iec61970.base.meas.measurement import Measurement
247
+ from zepben.ewb.model.cim.iec61970.base.protection.current_relay import CurrentRelay
248
+ from zepben.ewb.model.cim.iec61970.base.scada.remote_control import RemoteControl
249
+ from zepben.ewb.model.cim.iec61970.base.scada.remote_point import RemotePoint
250
+ from zepben.ewb.model.cim.iec61970.base.scada.remote_source import RemoteSource
251
+ from zepben.ewb.model.cim.iec61970.base.wires.ac_line_segment import AcLineSegment
252
+ from zepben.ewb.model.cim.iec61970.base.wires.breaker import Breaker
253
+ from zepben.ewb.model.cim.iec61970.base.wires.busbar_section import BusbarSection
254
+ from zepben.ewb.model.cim.iec61970.base.wires.clamp import Clamp
255
+ from zepben.ewb.model.cim.iec61970.base.wires.conductor import Conductor
256
+ from zepben.ewb.model.cim.iec61970.base.wires.connector import Connector
257
+ from zepben.ewb.model.cim.iec61970.base.wires.cut import Cut
258
+ from zepben.ewb.model.cim.iec61970.base.wires.disconnector import Disconnector
259
+ from zepben.ewb.model.cim.iec61970.base.wires.earth_fault_compensator import EarthFaultCompensator
260
+ from zepben.ewb.model.cim.iec61970.base.wires.energy_connection import EnergyConnection
261
+ from zepben.ewb.model.cim.iec61970.base.wires.energy_consumer import EnergyConsumer
262
+ from zepben.ewb.model.cim.iec61970.base.wires.energy_consumer_phase import EnergyConsumerPhase
263
+ from zepben.ewb.model.cim.iec61970.base.wires.energy_source import EnergySource
264
+ from zepben.ewb.model.cim.iec61970.base.wires.energy_source_phase import EnergySourcePhase
265
+ from zepben.ewb.model.cim.iec61970.base.wires.fuse import Fuse
266
+ from zepben.ewb.model.cim.iec61970.base.wires.ground import Ground
267
+ from zepben.ewb.model.cim.iec61970.base.wires.ground_disconnector import GroundDisconnector
268
+ from zepben.ewb.model.cim.iec61970.base.wires.grounding_impedance import GroundingImpedance
269
+ from zepben.ewb.model.cim.iec61970.base.wires.jumper import Jumper
270
+ from zepben.ewb.model.cim.iec61970.base.wires.junction import Junction
271
+ from zepben.ewb.model.cim.iec61970.base.wires.line import Line
272
+ from zepben.ewb.model.cim.iec61970.base.wires.linear_shunt_compensator import LinearShuntCompensator
273
+ from zepben.ewb.model.cim.iec61970.base.wires.load_break_switch import LoadBreakSwitch
274
+ from zepben.ewb.model.cim.iec61970.base.wires.per_length_impedance import PerLengthImpedance
275
+ from zepben.ewb.model.cim.iec61970.base.wires.per_length_line_parameter import PerLengthLineParameter
276
+ from zepben.ewb.model.cim.iec61970.base.wires.per_length_phase_impedance import PerLengthPhaseImpedance
277
+ from zepben.ewb.model.cim.iec61970.base.wires.per_length_sequence_impedance import PerLengthSequenceImpedance
278
+ from zepben.ewb.model.cim.iec61970.base.wires.petersen_coil import PetersenCoil
279
+ from zepben.ewb.model.cim.iec61970.base.wires.phase_impedance_data import PhaseImpedanceData
280
+ from zepben.ewb.model.cim.iec61970.base.wires.power_electronics_connection import PowerElectronicsConnection
281
+ from zepben.ewb.model.cim.iec61970.base.wires.power_electronics_connection_phase import PowerElectronicsConnectionPhase
282
+ from zepben.ewb.model.cim.iec61970.base.wires.power_transformer import PowerTransformer
283
+ from zepben.ewb.model.cim.iec61970.base.wires.power_transformer_end import PowerTransformerEnd
284
+ from zepben.ewb.model.cim.iec61970.base.wires.protected_switch import ProtectedSwitch
285
+ from zepben.ewb.model.cim.iec61970.base.wires.ratio_tap_changer import RatioTapChanger
286
+ from zepben.ewb.model.cim.iec61970.base.wires.reactive_capability_curve import ReactiveCapabilityCurve
287
+ from zepben.ewb.model.cim.iec61970.base.wires.recloser import Recloser
288
+ from zepben.ewb.model.cim.iec61970.base.wires.regulating_cond_eq import RegulatingCondEq
289
+ from zepben.ewb.model.cim.iec61970.base.wires.regulating_control import RegulatingControl
290
+ from zepben.ewb.model.cim.iec61970.base.wires.rotating_machine import RotatingMachine
291
+ from zepben.ewb.model.cim.iec61970.base.wires.series_compensator import SeriesCompensator
292
+ from zepben.ewb.model.cim.iec61970.base.wires.shunt_compensator import ShuntCompensator
293
+ from zepben.ewb.model.cim.iec61970.base.wires.static_var_compensator import StaticVarCompensator
294
+ from zepben.ewb.model.cim.iec61970.base.wires.switch import Switch
295
+ from zepben.ewb.model.cim.iec61970.base.wires.synchronous_machine import SynchronousMachine
296
+ from zepben.ewb.model.cim.iec61970.base.wires.tap_changer import TapChanger
297
+ from zepben.ewb.model.cim.iec61970.base.wires.tap_changer_control import TapChangerControl
298
+ from zepben.ewb.model.cim.iec61970.base.wires.transformer_end import TransformerEnd
299
+ from zepben.ewb.model.cim.iec61970.base.wires.transformer_star_impedance import TransformerStarImpedance
300
+ from zepben.ewb.model.cim.iec61970.infiec61970.feeder.circuit import Circuit
301
+
302
+
303
+ class NetworkCimWriter(BaseCimWriter):
304
+ """
305
+ A class for writing the :class:`NetworkService` tables to the database.
306
+
307
+ :param database_tables: The tables available in the database.
308
+ """
309
+
310
+ def __init__(self, database_tables: NetworkDatabaseTables):
311
+ super().__init__(database_tables)
312
+
313
+ #################################
314
+ # Extension IEC61968 Asset Info #
315
+ #################################
316
+
317
+ def save_relay_info(self, relay_info: RelayInfo) -> bool:
318
+ """
319
+ Save the :class:`RelayInfo` fields to :class:`TableRelayInfo`.
320
+
321
+ :param relay_info: The :class:`RelayInfo` instance to write to the database.
322
+ :return: True if the :class:`RelayInfo` was successfully written to the database, otherwise False.
323
+ :raises SqlException: For any errors encountered writing to the database.
324
+ """
325
+ table = self._database_tables.get_table(TableRelayInfo)
326
+ insert = self._database_tables.get_insert(TableRelayInfo)
327
+
328
+ reclose_delay_table = self._database_tables.get_table(TableRecloseDelays)
329
+ reclose_delay_insert = self._database_tables.get_insert(TableRecloseDelays)
330
+ for idx, delay in enumerate(relay_info.reclose_delays):
331
+ reclose_delay_insert.add_value(reclose_delay_table.relay_info_mrid.query_index, relay_info.mrid)
332
+ reclose_delay_insert.add_value(reclose_delay_table.sequence_number.query_index, idx)
333
+ reclose_delay_insert.add_value(reclose_delay_table.reclose_delay.query_index, delay)
334
+ self._try_execute_single_update(reclose_delay_insert, "reclose delay")
335
+
336
+ insert.add_value(table.curve_setting.query_index, relay_info.curve_setting)
337
+ insert.add_value(table.reclose_fast.query_index, relay_info.reclose_fast)
338
+
339
+ return self._save_asset_info(table, insert, relay_info, "relay info")
340
+
341
+ ###############################
342
+ # Extension IEC61968 Metering #
343
+ ###############################
344
+
345
+ def save_pan_demand_response_function(self, pan_demand_response_function: PanDemandResponseFunction) -> bool:
346
+ """
347
+ Save the :class:`PanDemandResponseFunction` fields to :class:`TablePanDemandResponseFunctions`.
348
+
349
+ :param pan_demand_response_function: The :class:`PanDemandResponseFunction` instance to write to the database.
350
+ :return: True if the :class:`PanDemandResponseFunction` was successfully written to the database, otherwise False.
351
+ :raises SqlException: For any errors encountered writing to the database.
352
+ """
353
+ table = self._database_tables.get_table(TablePanDemandResponseFunctions)
354
+ insert = self._database_tables.get_insert(TablePanDemandResponseFunctions)
355
+
356
+ insert.add_value(table.kind.query_index, pan_demand_response_function.kind.short_name)
357
+ insert.add_value(table.appliance.query_index, pan_demand_response_function._appliance_bitmask)
358
+
359
+ return self._save_end_device_function(table, insert, pan_demand_response_function, "pan demand response function")
360
+
361
+ ################################
362
+ # Extension IEC61970 Base Core #
363
+ ################################
364
+
365
+ def save_site(self, site: Site) -> bool:
366
+ """
367
+ Save the :class:`Site` fields to :class:`TableSites`.
368
+
369
+ :param site: The :class:`Site` instance to write to the database.
370
+ :return: True if the :class:`Site` was successfully written to the database, otherwise False.
371
+ :raises SqlException: For any errors encountered writing to the database.
372
+ """
373
+ table = self._database_tables.get_table(TableSites)
374
+ insert = self._database_tables.get_insert(TableSites)
375
+
376
+ return self._save_equipment_container(table, insert, site, "site")
377
+
378
+ ##################################
379
+ # Extension IEC61970 Base Feeder #
380
+ ##################################
381
+
382
+ def save_loop(self, loop: Loop) -> bool:
383
+ """
384
+ Save the :class:`Loop` fields to :class:`TableLoops`.
385
+
386
+ :param loop: The :class:`Loop` instance to write to the database.
387
+ :return: True if the :class:`Loop` was successfully written to the database, otherwise False.
388
+ :raises SqlException: For any errors encountered writing to the database.
389
+ """
390
+ table = self._database_tables.get_table(TableLoops)
391
+ insert = self._database_tables.get_insert(TableLoops)
392
+
393
+ status = True
394
+ for it in loop.energizing_substations:
395
+ status = status and self._save_loop_to_substation_association(loop, it, LoopSubstationRelationship.SUBSTATION_ENERGIZES_LOOP)
396
+ for it in loop.substations:
397
+ status = status and self._save_loop_to_substation_association(loop, it, LoopSubstationRelationship.LOOP_ENERGIZES_SUBSTATION)
398
+
399
+ return status and self._save_identified_object(table, insert, loop, "loop")
400
+
401
+ def save_lv_feeder(self, lv_feeder: LvFeeder) -> bool:
402
+ """
403
+ Save the :class:`LvFeeder` fields to :class:`TableLvFeeders`.
404
+
405
+ :param lv_feeder: The :class:`LvFeeder` instance to write to the database.
406
+ :return: True if the :class:`LvFeeder` was successfully written to the database, otherwise False.
407
+ :raises SqlException: For any errors encountered writing to the database.
408
+ """
409
+ table = self._database_tables.get_table(TableLvFeeders)
410
+ insert = self._database_tables.get_insert(TableLvFeeders)
411
+
412
+ insert.add_value(table.normal_head_terminal_mrid.query_index, self._mrid_or_none(lv_feeder.normal_head_terminal))
413
+
414
+ return self._save_equipment_container(table, insert, lv_feeder, "lv feeder")
415
+
416
+ #################################################
417
+ # Extension IEC61970 Base Generation Production #
418
+ #################################################
419
+
420
+ def save_ev_charging_unit(self, ev_charging_unit: EvChargingUnit) -> bool:
421
+ """
422
+ Save the :class:`EvChargingUnit` fields to :class:`TableEvChargingUnits`.
423
+
424
+ :param ev_charging_unit: The :class:`EvChargingUnit` instance to write to the database.
425
+ :return: True if the :class:`EvChargingUnit` was successfully written to the database, otherwise False.
426
+ :raises SqlException: For any errors encountered writing to the database.
427
+ """
428
+ table = self._database_tables.get_table(TableEvChargingUnits)
429
+ insert = self._database_tables.get_insert(TableEvChargingUnits)
430
+
431
+ return self._save_power_electronics_unit(table, insert, ev_charging_unit, "ev charging unit")
432
+
433
+ ######################################
434
+ # Extension IEC61970 Base Protection #
435
+ ######################################
436
+
437
+ def save_distance_relay(self, distance_relay: DistanceRelay) -> bool:
438
+ """
439
+ Save the :class:`DistanceRelay` fields to :class:`TableDistanceRelays`.
440
+
441
+ :param distance_relay: The :class:`DistanceRelay` instance to write to the database.
442
+ :return: True if the :class:`DistanceRelay` was successfully written to the database, otherwise False.
443
+ :raises SqlException: For any errors encountered writing to the database.
444
+ """
445
+ table = self._database_tables.get_table(TableDistanceRelays)
446
+ insert = self._database_tables.get_insert(TableDistanceRelays)
447
+
448
+ insert.add_value(table.backward_blind.query_index, distance_relay.backward_blind)
449
+ insert.add_value(table.backward_reach.query_index, distance_relay.backward_reach)
450
+ insert.add_value(table.backward_reactance.query_index, distance_relay.backward_reactance)
451
+ insert.add_value(table.forward_blind.query_index, distance_relay.forward_blind)
452
+ insert.add_value(table.forward_reach.query_index, distance_relay.forward_reach)
453
+ insert.add_value(table.forward_reactance.query_index, distance_relay.forward_reactance)
454
+ insert.add_value(table.operation_phase_angle1.query_index, distance_relay.operation_phase_angle1)
455
+ insert.add_value(table.operation_phase_angle2.query_index, distance_relay.operation_phase_angle2)
456
+ insert.add_value(table.operation_phase_angle3.query_index, distance_relay.operation_phase_angle3)
457
+
458
+ return self._save_protection_relay_function(table, insert, distance_relay, "distance relay")
459
+
460
+ def _save_protection_relay_function(
461
+ self,
462
+ table: TableProtectionRelayFunctions,
463
+ insert: PreparedStatement,
464
+ protection_relay_function: ProtectionRelayFunction,
465
+ description: str
466
+ ) -> bool:
467
+ insert.add_value(table.model.query_index, protection_relay_function.model)
468
+ insert.add_value(table.reclosing.query_index, protection_relay_function.reclosing)
469
+ insert.add_value(table.relay_delay_time.query_index, protection_relay_function.relay_delay_time)
470
+ insert.add_value(table.protection_kind.query_index, protection_relay_function.protection_kind.short_name)
471
+ insert.add_value(table.directable.query_index, protection_relay_function.directable)
472
+ insert.add_value(table.power_direction.query_index, protection_relay_function.power_direction.short_name)
473
+ insert.add_value(table.relay_info_mrid.query_index, self._mrid_or_none(protection_relay_function.asset_info))
474
+
475
+ status = True
476
+ for it in protection_relay_function.protected_switches:
477
+ status = status and self._save_protection_relay_function_to_protected_switch_association(protection_relay_function, it)
478
+ for it in protection_relay_function.sensors:
479
+ status = status and self._save_protection_relay_function_to_sensor_association(protection_relay_function, it)
480
+ for sequence_number, threshold in enumerate(protection_relay_function.thresholds):
481
+ status = status and self._save_protection_relay_function_threshold(protection_relay_function, sequence_number, threshold)
482
+ for sequence_number, time_limit in enumerate(protection_relay_function.time_limits):
483
+ status = status and self._save_protection_relay_function_time_limit(protection_relay_function, sequence_number, time_limit)
484
+
485
+ return status and self._save_power_system_resource(table, insert, protection_relay_function, description)
486
+
487
+ def _save_protection_relay_function_threshold(
488
+ self,
489
+ protection_relay_function: ProtectionRelayFunction,
490
+ sequence_number: int,
491
+ threshold: RelaySetting
492
+ ) -> bool:
493
+ table = self._database_tables.get_table(TableProtectionRelayFunctionThresholds)
494
+ insert = self._database_tables.get_insert(TableProtectionRelayFunctionThresholds)
495
+
496
+ insert.add_value(table.protection_relay_function_mrid.query_index, protection_relay_function.mrid)
497
+ insert.add_value(table.sequence_number.query_index, sequence_number)
498
+ insert.add_value(table.unit_symbol.query_index, threshold.unit_symbol.short_name)
499
+ insert.add_value(table.value.query_index, threshold.value)
500
+ insert.add_value(table.name_.query_index, threshold.name)
501
+
502
+ return self._try_execute_single_update(insert, "protection relay function threshold")
503
+
504
+ def _save_protection_relay_function_time_limit(self, protection_relay_function: ProtectionRelayFunction, sequence_number: int, time_limit: float) -> bool:
505
+ table = self._database_tables.get_table(TableProtectionRelayFunctionTimeLimits)
506
+ insert = self._database_tables.get_insert(TableProtectionRelayFunctionTimeLimits)
507
+
508
+ insert.add_value(table.protection_relay_function_mrid.query_index, protection_relay_function.mrid)
509
+ insert.add_value(table.sequence_number.query_index, sequence_number)
510
+ insert.add_value(table.time_limit.query_index, time_limit)
511
+
512
+ return self._try_execute_single_update(insert, "protection relay function time limit")
513
+
514
+ def save_protection_relay_scheme(self, protection_relay_scheme: ProtectionRelayScheme) -> bool:
515
+ """
516
+ Save the :class:`ProtectionRelayScheme` fields to :class:`TableProtectionRelaySchemes`.
517
+
518
+ :param protection_relay_scheme: The :class:`ProtectionRelayScheme` instance to write to the database.
519
+ :return: True if the :class:`ProtectionRelayScheme` was successfully written to the database, otherwise False.
520
+ :raises SqlException: For any errors encountered writing to the database.
521
+ """
522
+ table = self._database_tables.get_table(TableProtectionRelaySchemes)
523
+ insert = self._database_tables.get_insert(TableProtectionRelaySchemes)
524
+
525
+ insert.add_value(table.system_mrid.query_index, self._mrid_or_none(protection_relay_scheme.system))
526
+
527
+ status = True
528
+ for it in protection_relay_scheme.functions:
529
+ status and self._save_protection_relay_scheme_to_protection_relay_function_association(protection_relay_scheme, it)
530
+
531
+ return status and self._save_identified_object(table, insert, protection_relay_scheme, "protection relay scheme")
532
+
533
+ def save_protection_relay_system(self, protection_relay_system: ProtectionRelaySystem) -> bool:
534
+ """
535
+ Save the :class:`ProtectionRelaySystem` fields to :class:`TableProtectionRelaySystems`.
536
+
537
+ :param protection_relay_system: The :class:`ProtectionRelaySystem` instance to write to the database.
538
+ :return: True if the :class:`ProtectionRelaySystem` was successfully written to the database, otherwise False.
539
+ :raises SqlException: For any errors encountered writing to the database.
540
+ """
541
+ table = self._database_tables.get_table(TableProtectionRelaySystems)
542
+ insert = self._database_tables.get_insert(TableProtectionRelaySystems)
543
+
544
+ insert.add_value(table.protection_kind.query_index, protection_relay_system.protection_kind.short_name)
545
+
546
+ return self._save_equipment(table, insert, protection_relay_system, "protection relay system")
547
+
548
+ def save_voltage_relay(self, voltage_relay: VoltageRelay) -> bool:
549
+ """
550
+ Save the :class:`VoltageRelay` fields to :class:`TableVoltageRelays`.
551
+
552
+ :param voltage_relay: The :class:`VoltageRelay` instance to write to the database.
553
+ :return: True if the :class:`VoltageRelay` was successfully written to the database, otherwise False.
554
+ :raises SqlException: For any errors encountered writing to the database.
555
+ """
556
+ table = self._database_tables.get_table(TableVoltageRelays)
557
+ insert = self._database_tables.get_insert(TableVoltageRelays)
558
+
559
+ return self._save_protection_relay_function(table, insert, voltage_relay, "voltage relay")
560
+
561
+ #################################
562
+ # Extension IEC61970 Base Wires #
563
+ #################################
564
+
565
+ def save_battery_control(self, battery_control: BatteryControl) -> bool:
566
+ """
567
+ Save the :class:`BatteryControl` fields to :class:`TableBatteryControls`.
568
+
569
+ :param battery_control: The :class:`BatteryControl` instance to write to the database.
570
+ :return: True if the :class:`BatteryControl` was successfully written to the database, otherwise False.
571
+ :raises SqlException: For any errors encountered writing to the database.
572
+ """
573
+ table = self._database_tables.get_table(TableBatteryControls)
574
+ insert = self._database_tables.get_insert(TableBatteryControls)
575
+
576
+ insert.add_value(table.charging_rate.query_index, battery_control.charging_rate)
577
+ insert.add_value(table.discharging_rate.query_index, battery_control.discharging_rate)
578
+ insert.add_value(table.reserve_percent.query_index, battery_control.reserve_percent)
579
+ insert.add_value(table.control_mode.query_index, battery_control.control_mode.short_name)
580
+
581
+ return self._save_regulating_control(table, insert, battery_control, "battery control")
582
+
583
+ #######################
584
+ # IEC61968 Asset Info #
585
+ #######################
586
+
587
+ def save_cable_info(self, cable_info: CableInfo) -> bool:
588
+ """
589
+ Save the :class:`CableInfo` fields to :class:`TableCableInfo`.
590
+
591
+ :param cable_info: The :class:`CableInfo` instance to write to the database.
592
+ :return: True if the :class:`CableInfo` was successfully written to the database, otherwise False.
593
+ :raises SqlException: For any errors encountered writing to the database.
594
+ """
595
+ table = self._database_tables.get_table(TableCableInfo)
596
+ insert = self._database_tables.get_insert(TableCableInfo)
597
+
598
+ return self._save_wire_info(table, insert, cable_info, "cable info")
599
+
600
+ def save_no_load_test(self, no_load_test: NoLoadTest) -> bool:
601
+ """
602
+ Save the :class:`NoLoadTest` fields to :class:`TableNoLoadTests`.
603
+
604
+ :param no_load_test: The :class:`NoLoadTest` instance to write to the database.
605
+ :return: True if the :class:`NoLoadTest` was successfully written to the database, otherwise False.
606
+ :raises SqlException: For any errors encountered writing to the database.
607
+ """
608
+ table = self._database_tables.get_table(TableNoLoadTests)
609
+ insert = self._database_tables.get_insert(TableNoLoadTests)
610
+
611
+ insert.add_value(table.energised_end_voltage.query_index, no_load_test.energised_end_voltage)
612
+ insert.add_value(table.exciting_current.query_index, no_load_test.exciting_current)
613
+ insert.add_value(table.exciting_current_zero.query_index, no_load_test.exciting_current_zero)
614
+ insert.add_value(table.loss.query_index, no_load_test.loss)
615
+ insert.add_value(table.loss_zero.query_index, no_load_test.loss_zero)
616
+
617
+ return self._save_transformer_test(table, insert, no_load_test, "no load test")
618
+
619
+ def save_open_circuit_test(self, open_circuit_test: OpenCircuitTest) -> bool:
620
+ """
621
+ Save the :class:`OpenCircuitTest` fields to :class:`TableOpenCircuitTests`.
622
+
623
+ :param open_circuit_test: The :class:`OpenCircuitTest` instance to write to the database.
624
+ :return: True if the :class:`OpenCircuitTest` was successfully written to the database, otherwise False.
625
+ :raises SqlException: For any errors encountered writing to the database.
626
+ """
627
+ table = self._database_tables.get_table(TableOpenCircuitTests)
628
+ insert = self._database_tables.get_insert(TableOpenCircuitTests)
629
+
630
+ insert.add_value(table.energised_end_step.query_index, open_circuit_test.energised_end_step)
631
+ insert.add_value(table.energised_end_voltage.query_index, open_circuit_test.energised_end_voltage)
632
+ insert.add_value(table.open_end_step.query_index, open_circuit_test.open_end_step)
633
+ insert.add_value(table.open_end_voltage.query_index, open_circuit_test.open_end_voltage)
634
+ insert.add_value(table.phase_shift.query_index, open_circuit_test.phase_shift)
635
+
636
+ return self._save_transformer_test(table, insert, open_circuit_test, "open circuit test")
637
+
638
+ def save_overhead_wire_info(self, overhead_wire_info: OverheadWireInfo) -> bool:
639
+ """
640
+ Save the :class:`OverheadWireInfo` fields to :class:`TableOverheadWireInfo`.
641
+
642
+ :param overhead_wire_info: The :class:`OverheadWireInfo` instance to write to the database.
643
+ :return: True if the :class:`OverheadWireInfo` was successfully written to the database, otherwise False.
644
+ :raises SqlException: For any errors encountered writing to the database.
645
+ """
646
+ table = self._database_tables.get_table(TableOverheadWireInfo)
647
+ insert = self._database_tables.get_insert(TableOverheadWireInfo)
648
+
649
+ return self._save_wire_info(table, insert, overhead_wire_info, "overhead wire info")
650
+
651
+ def save_power_transformer_info(self, power_transformer_info: PowerTransformerInfo) -> bool:
652
+ """
653
+ Save the :class:`PowerTransformerInfo` fields to :class:`TablePowerTransformerInfo`.
654
+
655
+ :param power_transformer_info: The :class:`PowerTransformerInfo` instance to write to the database.
656
+ :return: True if the :class:`PowerTransformerInfo` was successfully written to the database, otherwise False.
657
+ :raises SqlException: For any errors encountered writing to the database.
658
+ """
659
+ table = self._database_tables.get_table(TablePowerTransformerInfo)
660
+ insert = self._database_tables.get_insert(TablePowerTransformerInfo)
661
+
662
+ return self._save_asset_info(table, insert, power_transformer_info, "power transformer info")
663
+
664
+ def save_short_circuit_test(self, short_circuit_test: ShortCircuitTest) -> bool:
665
+ """
666
+ Save the :class:`ShortCircuitTest` fields to :class:`TableShortCircuitTests`.
667
+
668
+ :param short_circuit_test: The :class:`ShortCircuitTest` instance to write to the database.
669
+ :return: True if the :class:`ShortCircuitTest` was successfully written to the database, otherwise False.
670
+ :raises SqlException: For any errors encountered writing to the database.
671
+ """
672
+ table = self._database_tables.get_table(TableShortCircuitTests)
673
+ insert = self._database_tables.get_insert(TableShortCircuitTests)
674
+
675
+ insert.add_value(table.current.query_index, short_circuit_test.current)
676
+ insert.add_value(table.energised_end_step.query_index, short_circuit_test.energised_end_step)
677
+ insert.add_value(table.grounded_end_step.query_index, short_circuit_test.grounded_end_step)
678
+ insert.add_value(table.leakage_impedance.query_index, short_circuit_test.leakage_impedance)
679
+ insert.add_value(table.leakage_impedance_zero.query_index, short_circuit_test.leakage_impedance_zero)
680
+ insert.add_value(table.loss.query_index, short_circuit_test.loss)
681
+ insert.add_value(table.loss_zero.query_index, short_circuit_test.loss_zero)
682
+ insert.add_value(table.power.query_index, short_circuit_test.power)
683
+ insert.add_value(table.voltage.query_index, short_circuit_test.voltage)
684
+ insert.add_value(table.voltage_ohmic_part.query_index, short_circuit_test.voltage_ohmic_part)
685
+
686
+ return self._save_transformer_test(table, insert, short_circuit_test, "short circuit test")
687
+
688
+ def save_shunt_compensator_info(self, shunt_compensator_info: ShuntCompensatorInfo) -> bool:
689
+ """
690
+ Save the :class:`ShuntCompensatorInfo` fields to :class:`TableShuntCompensatorInfo`.
691
+
692
+ :param shunt_compensator_info: The :class:`ShuntCompensatorInfo` instance to write to the database.
693
+ :return: True if the :class:`ShuntCompensatorInfo` was successfully written to the database, otherwise False.
694
+ :raises SqlException: For any errors encountered writing to the database.
695
+ """
696
+ table = self._database_tables.get_table(TableShuntCompensatorInfo)
697
+ insert = self._database_tables.get_insert(TableShuntCompensatorInfo)
698
+
699
+ insert.add_value(table.max_power_loss.query_index, shunt_compensator_info.max_power_loss)
700
+ insert.add_value(table.rated_current.query_index, shunt_compensator_info.rated_current)
701
+ insert.add_value(table.rated_reactive_power.query_index, shunt_compensator_info.rated_reactive_power)
702
+ insert.add_value(table.rated_voltage.query_index, shunt_compensator_info.rated_voltage)
703
+
704
+ return self._save_asset_info(table, insert, shunt_compensator_info, "shunt compensator info")
705
+
706
+ def save_switch_info(self, switch_info: SwitchInfo) -> bool:
707
+ """
708
+ Save the :class:`SwitchInfo` fields to :class:`TableSwitchInfo`.
709
+
710
+ :param switch_info: The :class:`SwitchInfo` instance to write to the database.
711
+ :return: True if the :class:`SwitchInfo` was successfully written to the database, otherwise False.
712
+ :raises SqlException: For any errors encountered writing to the database.
713
+ """
714
+ table = self._database_tables.get_table(TableSwitchInfo)
715
+ insert = self._database_tables.get_insert(TableSwitchInfo)
716
+
717
+ insert.add_value(table.rated_interrupting_time.query_index, switch_info.rated_interrupting_time)
718
+
719
+ return self._save_asset_info(table, insert, switch_info, "switch info")
720
+
721
+ def save_transformer_end_info(self, transformer_end_info: TransformerEndInfo) -> bool:
722
+ """
723
+ Save the :class:`TransformerEndInfo` fields to :class:`TableTransformerEndInfo`.
724
+
725
+ :param transformer_end_info: The :class:`TransformerEndInfo` instance to write to the database.
726
+ :return: True if the :class:`TransformerEndInfo` was successfully written to the database, otherwise False.
727
+ :raises SqlException: For any errors encountered writing to the database.
728
+ """
729
+ table = self._database_tables.get_table(TableTransformerEndInfo)
730
+ insert = self._database_tables.get_insert(TableTransformerEndInfo)
731
+
732
+ insert.add_value(table.connection_kind.query_index, transformer_end_info.connection_kind.short_name)
733
+ insert.add_value(table.emergency_s.query_index, transformer_end_info.emergency_s)
734
+ insert.add_value(table.end_number.query_index, transformer_end_info.end_number)
735
+ insert.add_value(table.insulation_u.query_index, transformer_end_info.insulation_u)
736
+ insert.add_value(table.phase_angle_clock.query_index, transformer_end_info.phase_angle_clock)
737
+ insert.add_value(table.r.query_index, transformer_end_info.r)
738
+ insert.add_value(table.rated_s.query_index, transformer_end_info.rated_s)
739
+ insert.add_value(table.rated_u.query_index, transformer_end_info.rated_u)
740
+ insert.add_value(table.short_term_s.query_index, transformer_end_info.short_term_s)
741
+ insert.add_value(table.transformer_tank_info_mrid.query_index, self._mrid_or_none(transformer_end_info.transformer_tank_info))
742
+ insert.add_value(table.energised_end_no_load_tests.query_index, self._mrid_or_none(transformer_end_info.energised_end_no_load_tests))
743
+ insert.add_value(table.energised_end_short_circuit_tests.query_index, self._mrid_or_none(transformer_end_info.energised_end_short_circuit_tests))
744
+ insert.add_value(table.grounded_end_short_circuit_tests.query_index, self._mrid_or_none(transformer_end_info.grounded_end_short_circuit_tests))
745
+ insert.add_value(table.open_end_open_circuit_tests.query_index, self._mrid_or_none(transformer_end_info.open_end_open_circuit_tests))
746
+ insert.add_value(table.energised_end_open_circuit_tests.query_index, self._mrid_or_none(transformer_end_info.energised_end_open_circuit_tests))
747
+
748
+ return self._save_asset_info(table, insert, transformer_end_info, "transformer end info")
749
+
750
+ def save_transformer_tank_info(self, transformer_tank_info: TransformerTankInfo) -> bool:
751
+ """
752
+ Save the :class:`TransformerTankInfo` fields to :class:`TableTransformerTankInfo`.
753
+
754
+ :param transformer_tank_info: The :class:`TransformerTankInfo` instance to write to the database.
755
+ :return: True if the :class:`TransformerTankInfo` was successfully written to the database, otherwise False.
756
+ :raises SqlException: For any errors encountered writing to the database.
757
+ """
758
+ table = self._database_tables.get_table(TableTransformerTankInfo)
759
+ insert = self._database_tables.get_insert(TableTransformerTankInfo)
760
+
761
+ insert.add_value(table.power_transformer_info_mrid.query_index, self._mrid_or_none(transformer_tank_info.power_transformer_info))
762
+
763
+ return self._save_asset_info(table, insert, transformer_tank_info, "transformer tank info")
764
+
765
+ def _save_transformer_test(self, table: TableTransformerTest, insert: PreparedStatement, transformer_test: TransformerTest, description: str) -> bool:
766
+ insert.add_value(table.base_power.query_index, transformer_test.base_power)
767
+ insert.add_value(table.temperature.query_index, transformer_test.temperature)
768
+
769
+ return self._save_identified_object(table, insert, transformer_test, description)
770
+
771
+ def _save_wire_info(self, table: TableWireInfo, insert: PreparedStatement, wire_info: WireInfo, description: str) -> bool:
772
+ insert.add_value(table.rated_current.query_index, wire_info.rated_current)
773
+ insert.add_value(table.material.query_index, wire_info.material.short_name)
774
+
775
+ return self._save_asset_info(table, insert, wire_info, description)
776
+
777
+ ###################
778
+ # IEC61968 Assets #
779
+ ###################
780
+
781
+ def _save_asset(self, table: TableAssets, insert: PreparedStatement, asset: Asset, description: str) -> bool:
782
+ status = True
783
+
784
+ insert.add_value(table.location_mrid.query_index, self._mrid_or_none(asset.location))
785
+ for it in asset.organisation_roles:
786
+ status = status and self._save_asset_organisation_role_to_asset_association(it, asset)
787
+ for it in asset.power_system_resources:
788
+ status = status and self._save_asset_to_power_system_resource_association(it, asset)
789
+
790
+ return status and self._save_identified_object(table, insert, asset, description)
791
+
792
+ def _save_asset_container(self, table: TableAssetContainers, insert: PreparedStatement, asset_container: AssetContainer, description: str) -> bool:
793
+ return self._save_asset(table, insert, asset_container, description)
794
+
795
+ def _save_asset_function(self, table: TableAssetFunctions, insert: PreparedStatement, asset_function: AssetFunction, description: str) -> bool:
796
+ return self._save_identified_object(table, insert, asset_function, description)
797
+
798
+ def _save_asset_info(self, table: TableAssetInfo, insert: PreparedStatement, asset_info: AssetInfo, description: str) -> bool:
799
+ return self._save_identified_object(table, insert, asset_info, description)
800
+
801
+ def _save_asset_organisation_role(
802
+ self,
803
+ table: TableAssetOrganisationRoles,
804
+ insert: PreparedStatement,
805
+ asset_organisation_role: AssetOrganisationRole,
806
+ description: str
807
+ ) -> bool:
808
+ return self._save_organisation_role(table, insert, asset_organisation_role, description)
809
+
810
+ def save_asset_owner(self, asset_owner: AssetOwner) -> bool:
811
+ """
812
+ Save the :class:`AssetOwner` fields to :class:`TableAssetOwners`.
813
+
814
+ :param asset_owner: The :class:`AssetOwner` instance to write to the database.
815
+ :return: True if the :class:`AssetOwner` was successfully written to the database, otherwise False.
816
+ :raises SqlException: For any errors encountered writing to the database.
817
+ """
818
+ table = self._database_tables.get_table(TableAssetOwners)
819
+ insert = self._database_tables.get_insert(TableAssetOwners)
820
+
821
+ return self._save_asset_organisation_role(table, insert, asset_owner, "asset owner")
822
+
823
+ def save_streetlight(self, streetlight: Streetlight) -> bool:
824
+ """
825
+ Save the :class:`Streetlight` fields to :class:`TableStreetlights`.
826
+
827
+ :param streetlight: The :class:`Streetlight` instance to write to the database.
828
+ :return: True if the :class:`Streetlight` was successfully written to the database, otherwise False.
829
+ :raises SqlException: For any errors encountered writing to the database.
830
+ """
831
+ table = self._database_tables.get_table(TableStreetlights)
832
+ insert = self._database_tables.get_insert(TableStreetlights)
833
+
834
+ insert.add_value(table.pole_mrid.query_index, self._mrid_or_none(streetlight.pole))
835
+ insert.add_value(table.light_rating.query_index, streetlight.light_rating)
836
+ insert.add_value(table.lamp_kind.query_index, streetlight.lamp_kind.short_name)
837
+ return self._save_asset(table, insert, streetlight, "streetlight")
838
+
839
+ def _save_structure(self, table: TableStructures, insert: PreparedStatement, structure: Structure, description: str) -> bool:
840
+ return self._save_asset_container(table, insert, structure, description)
841
+
842
+ ###################
843
+ # IEC61968 Common #
844
+ ###################
845
+
846
+ def save_location(self, location: Location) -> bool:
847
+ """
848
+ Save the :class:`Location` fields to :class:`TableLocations`.
849
+
850
+ :param location: The :class:`Location` instance to write to the database.
851
+ :return: True if the :class:`Location` was successfully written to the database, otherwise False.
852
+ :raises SqlException: For any errors encountered writing to the database.
853
+ """
854
+ table = self._database_tables.get_table(TableLocations)
855
+ insert = self._database_tables.get_insert(TableLocations)
856
+
857
+ status = self._save_location_street_address(location, TableLocationStreetAddressField.mainAddress, location.main_address, "location main address")
858
+ for sequence_number, point in enumerate(location.points):
859
+ status = status and self._save_position_point(location, sequence_number, point)
860
+
861
+ return status and self._save_identified_object(table, insert, location, "location")
862
+
863
+ def _save_location_street_address(
864
+ self,
865
+ location: Location,
866
+ field: TableLocationStreetAddressField,
867
+ street_address: Optional[StreetAddress],
868
+ description: str
869
+ ) -> bool:
870
+ if street_address is None:
871
+ return True
872
+
873
+ table = self._database_tables.get_table(TableLocationStreetAddresses)
874
+ insert = self._database_tables.get_insert(TableLocationStreetAddresses)
875
+
876
+ insert.add_value(table.location_mrid.query_index, location.mrid)
877
+ insert.add_value(table.address_field.query_index, field.short_name)
878
+
879
+ return self._save_street_address(table, insert, street_address, description)
880
+
881
+ def _save_position_point(self, location: Location, sequence_number: int, position_point: PositionPoint) -> bool:
882
+ table = self._database_tables.get_table(TablePositionPoints)
883
+ insert = self._database_tables.get_insert(TablePositionPoints)
884
+
885
+ insert.add_value(table.location_mrid.query_index, location.mrid)
886
+ insert.add_value(table.sequence_number.query_index, sequence_number)
887
+ insert.add_value(table.x_position.query_index, position_point.x_position)
888
+ insert.add_value(table.y_position.query_index, position_point.y_position)
889
+
890
+ return self._try_execute_single_update(insert, "position point")
891
+
892
+ def _save_street_address(
893
+ self,
894
+ table: TableStreetAddresses,
895
+ insert: PreparedStatement,
896
+ street_address: StreetAddress,
897
+ description: str
898
+ ) -> bool:
899
+ insert.add_value(table.postal_code.query_index, street_address.postal_code)
900
+ insert.add_value(table.po_box.query_index, street_address.po_box)
901
+
902
+ self._insert_town_detail(table, insert, street_address.town_detail)
903
+ self._insert_street_detail(table, insert, street_address.street_detail)
904
+
905
+ return self._try_execute_single_update(insert, description)
906
+
907
+ @staticmethod
908
+ def _insert_street_detail(table: TableStreetAddresses, insert: PreparedStatement, street_detail: Optional[StreetDetail]):
909
+ insert.add_value(table.building_name.query_index, street_detail.building_name if street_detail else None)
910
+ insert.add_value(table.floor_identification.query_index, street_detail.floor_identification if street_detail else None)
911
+ insert.add_value(table.street_name.query_index, street_detail.name if street_detail else None)
912
+ insert.add_value(table.number.query_index, street_detail.number if street_detail else None)
913
+ insert.add_value(table.suite_number.query_index, street_detail.suite_number if street_detail else None)
914
+ insert.add_value(table.type.query_index, street_detail.type if street_detail else None)
915
+ insert.add_value(table.display_address.query_index, street_detail.display_address if street_detail else None)
916
+
917
+ @staticmethod
918
+ def _insert_town_detail(table: TableTownDetails, insert: PreparedStatement, town_detail: Optional[TownDetail]):
919
+ insert.add_value(table.town_name.query_index, town_detail.name if town_detail else None)
920
+ insert.add_value(table.state_or_province.query_index, town_detail.state_or_province if town_detail else None)
921
+
922
+ #####################################
923
+ # IEC61968 InfIEC61968 InfAssetInfo #
924
+ #####################################
925
+
926
+ def save_current_transformer_info(self, current_transformer_info: CurrentTransformerInfo) -> bool:
927
+ """
928
+ Save the :class:`CurrentTransformerInfo` fields to :class:`TableCurrentTransformerInfo`.
929
+
930
+ :param current_transformer_info: The :class:`CurrentTransformerInfo` instance to write to the database.
931
+ :return: True if the :class:`CurrentTransformerInfo` was successfully written to the database, otherwise False.
932
+ :raises SqlException: For any errors encountered writing to the database.
933
+ """
934
+ table = self._database_tables.get_table(TableCurrentTransformerInfo)
935
+ insert = self._database_tables.get_insert(TableCurrentTransformerInfo)
936
+
937
+ insert.add_value(table.accuracy_class.query_index, current_transformer_info.accuracy_class)
938
+ insert.add_value(table.accuracy_limit.query_index, current_transformer_info.accuracy_limit)
939
+ insert.add_value(table.core_count.query_index, current_transformer_info.core_count)
940
+ insert.add_value(table.ct_class.query_index, current_transformer_info.ct_class)
941
+ insert.add_value(table.knee_point_voltage.query_index, current_transformer_info.knee_point_voltage)
942
+ insert.add_ratio(table.max_ratio_numerator.query_index, table.max_ratio_denominator.query_index, current_transformer_info.max_ratio)
943
+ insert.add_ratio(table.nominal_ratio_numerator.query_index, table.nominal_ratio_denominator.query_index, current_transformer_info.nominal_ratio)
944
+ insert.add_value(table.primary_ratio.query_index, current_transformer_info.primary_ratio)
945
+ insert.add_value(table.rated_current.query_index, current_transformer_info.rated_current)
946
+ insert.add_value(table.secondary_fls_rating.query_index, current_transformer_info.secondary_fls_rating)
947
+ insert.add_value(table.secondary_ratio.query_index, current_transformer_info.secondary_ratio)
948
+ insert.add_value(table.usage.query_index, current_transformer_info.usage)
949
+
950
+ return self._save_asset_info(table, insert, current_transformer_info, "current transformer info")
951
+
952
+ def save_potential_transformer_info(self, potential_transformer_info: PotentialTransformerInfo) -> bool:
953
+ """
954
+ Save the :class:`PotentialTransformerInfo` fields to :class:`TablePotentialTransformerInfo`.
955
+
956
+ :param potential_transformer_info: The :class:`PotentialTransformerInfo` instance to write to the database.
957
+ :return: True if the :class:`PotentialTransformerInfo` was successfully written to the database, otherwise False.
958
+ :raises SqlException: For any errors encountered writing to the database.
959
+ """
960
+ table = self._database_tables.get_table(TablePotentialTransformerInfo)
961
+ insert = self._database_tables.get_insert(TablePotentialTransformerInfo)
962
+
963
+ insert.add_value(table.accuracy_class.query_index, potential_transformer_info.accuracy_class)
964
+ insert.add_ratio(table.nominal_ratio_numerator.query_index, table.nominal_ratio_denominator.query_index, potential_transformer_info.nominal_ratio)
965
+ insert.add_value(table.primary_ratio.query_index, potential_transformer_info.primary_ratio)
966
+ insert.add_value(table.pt_class.query_index, potential_transformer_info.pt_class)
967
+ insert.add_value(table.rated_voltage.query_index, potential_transformer_info.rated_voltage)
968
+ insert.add_value(table.secondary_ratio.query_index, potential_transformer_info.secondary_ratio)
969
+
970
+ return self._save_asset_info(table, insert, potential_transformer_info, "potential transformer info")
971
+
972
+ ##################################
973
+ # IEC61968 InfIEC61968 InfAssets #
974
+ ##################################
975
+
976
+ def save_pole(self, pole: Pole) -> bool:
977
+ """
978
+ Save the :class:`Pole` fields to :class:`TablePoles`.
979
+
980
+ :param pole: The :class:`Pole` instance to write to the database.
981
+ :return: True if the :class:`Pole` was successfully written to the database, otherwise False.
982
+ :raises SqlException: For any errors encountered writing to the database.
983
+ """
984
+ table = self._database_tables.get_table(TablePoles)
985
+ insert = self._database_tables.get_insert(TablePoles)
986
+
987
+ insert.add_value(table.classification.query_index, pole.classification)
988
+
989
+ return self._save_structure(table, insert, pole, "pole")
990
+
991
+ #####################
992
+ # IEC61968 Metering #
993
+ #####################
994
+
995
+ def _save_end_device(self, table: TableEndDevices, insert: PreparedStatement, end_device: EndDevice, description: str) -> bool:
996
+ insert.add_value(table.customer_mrid.query_index, end_device.customer_mrid)
997
+ insert.add_value(table.service_location_mrid.query_index, self._mrid_or_none(end_device.service_location))
998
+
999
+ status = True
1000
+ for it in end_device.usage_points:
1001
+ status = status and self._save_usage_point_to_end_device_association(it, end_device)
1002
+ for it in end_device.functions:
1003
+ status = status and self._save_end_device_function_to_end_device_association(it, end_device)
1004
+
1005
+ return status and self._save_asset_container(table, insert, end_device, description)
1006
+
1007
+ def _save_end_device_function(self, table: TableEndDeviceFunctions, insert: PreparedStatement, end_device_function: EndDeviceFunction,
1008
+ description: str) -> bool:
1009
+ insert.add_value(table.enabled.query_index, end_device_function.enabled)
1010
+
1011
+ return self._save_asset_function(table, insert, end_device_function, description)
1012
+
1013
+ def save_meter(self, meter: Meter) -> bool:
1014
+ """
1015
+ Save the :class:`Meter` fields to :class:`TableMeters`.
1016
+
1017
+ :param meter: The :class:`Meter` instance to write to the database.
1018
+ :return: True if the :class:`Meter` was successfully written to the database, otherwise False.
1019
+ :raises SqlException: For any errors encountered writing to the database.
1020
+ """
1021
+ table = self._database_tables.get_table(TableMeters)
1022
+ insert = self._database_tables.get_insert(TableMeters)
1023
+
1024
+ return self._save_end_device(table, insert, meter, "meter")
1025
+
1026
+ def save_usage_point(self, usage_point: UsagePoint) -> bool:
1027
+ """
1028
+ Save the :class:`UsagePoint` fields to :class:`TableUsagePoints`.
1029
+
1030
+ :param usage_point: The :class:`UsagePoint` instance to write to the database.
1031
+ :return: True if the :class:`UsagePoint` was successfully written to the database, otherwise False.
1032
+ :raises SqlException: For any errors encountered writing to the database.
1033
+ """
1034
+ table = self._database_tables.get_table(TableUsagePoints)
1035
+ insert = self._database_tables.get_insert(TableUsagePoints)
1036
+
1037
+ insert.add_value(table.location_mrid.query_index, self._mrid_or_none(usage_point.usage_point_location))
1038
+ insert.add_value(table.is_virtual.query_index, usage_point.is_virtual)
1039
+ insert.add_value(table.connection_category.query_index, usage_point.connection_category)
1040
+ insert.add_value(table.rated_power.query_index, usage_point.rated_power)
1041
+ insert.add_value(table.approved_inverter_capacity.query_index, usage_point.approved_inverter_capacity)
1042
+ insert.add_value(table.phase_code.query_index, usage_point.phase_code.short_name)
1043
+
1044
+ status = True
1045
+ for it in usage_point.equipment:
1046
+ status = status and self._save_equipment_to_usage_point_association(it, usage_point)
1047
+
1048
+ return status and self._save_identified_object(table, insert, usage_point, "usage point")
1049
+
1050
+ #######################
1051
+ # IEC61968 Operations #
1052
+ #######################
1053
+
1054
+ def save_operational_restriction(self, operational_restriction: OperationalRestriction) -> bool:
1055
+ """
1056
+ Save the :class:`OperationalRestriction` fields to :class:`TableOperationalRestrictions`.
1057
+
1058
+ :param operational_restriction: The :class:`OperationalRestriction` instance to write to the database.
1059
+ :return: True if the :class:`OperationalRestriction` was successfully written to the database, otherwise False.
1060
+ :raises SqlException: For any errors encountered writing to the database.
1061
+ """
1062
+ table = self._database_tables.get_table(TableOperationalRestrictions)
1063
+ insert = self._database_tables.get_insert(TableOperationalRestrictions)
1064
+
1065
+ status = True
1066
+ for it in operational_restriction.equipment:
1067
+ status = status and self._save_equipment_to_operational_restriction_association(it, operational_restriction)
1068
+
1069
+ return status and self._save_document(table, insert, operational_restriction, "operational restriction")
1070
+
1071
+ #####################################
1072
+ # IEC61970 Base Auxiliary Equipment #
1073
+ #####################################
1074
+
1075
+ def _save_auxiliary_equipment(
1076
+ self,
1077
+ table: TableAuxiliaryEquipment,
1078
+ insert: PreparedStatement,
1079
+ auxiliary_equipment: AuxiliaryEquipment,
1080
+ description: str
1081
+ ) -> bool:
1082
+ insert.add_value(table.terminal_mrid.query_index, self._mrid_or_none(auxiliary_equipment.terminal))
1083
+
1084
+ return self._save_equipment(table, insert, auxiliary_equipment, description)
1085
+
1086
+ def save_current_transformer(self, current_transformer: CurrentTransformer) -> bool:
1087
+ """
1088
+ Save the :class:`CurrentTransformer` fields to :class:`TableCurrentTransformers`.
1089
+
1090
+ :param current_transformer: The :class:`CurrentTransformer` instance to write to the database.
1091
+ :return: True if the :class:`CurrentTransformer` was successfully written to the database, otherwise False.
1092
+ :raises SqlException: For any errors encountered writing to the database.
1093
+ """
1094
+ table = self._database_tables.get_table(TableCurrentTransformers)
1095
+ insert = self._database_tables.get_insert(TableCurrentTransformers)
1096
+
1097
+ insert.add_value(table.current_transformer_info_mrid.query_index, self._mrid_or_none(current_transformer.current_transformer_info))
1098
+ insert.add_value(table.core_burden.query_index, current_transformer.core_burden)
1099
+
1100
+ return self._save_sensor(table, insert, current_transformer, "current transformer")
1101
+
1102
+ def save_fault_indicator(self, fault_indicator: FaultIndicator) -> bool:
1103
+ """
1104
+ Save the :class:`FaultIndicator` fields to :class:`TableFaultIndicators`.
1105
+
1106
+ :param fault_indicator: The :class:`FaultIndicator` instance to write to the database.
1107
+ :return: True if the :class:`FaultIndicator` was successfully written to the database, otherwise False.
1108
+ :raises SqlException: For any errors encountered writing to the database.
1109
+ """
1110
+ table = self._database_tables.get_table(TableFaultIndicators)
1111
+ insert = self._database_tables.get_insert(TableFaultIndicators)
1112
+
1113
+ return self._save_auxiliary_equipment(table, insert, fault_indicator, "fault indicator")
1114
+
1115
+ def save_potential_transformer(self, potential_transformer: PotentialTransformer) -> bool:
1116
+ """
1117
+ Save the :class:`PotentialTransformer` fields to :class:`TablePotentialTransformers`.
1118
+
1119
+ :param potential_transformer: The :class:`PotentialTransformer` instance to write to the database.
1120
+ :return: True if the :class:`PotentialTransformer` was successfully written to the database, otherwise False.
1121
+ :raises SqlException: For any errors encountered writing to the database.
1122
+ """
1123
+ table = self._database_tables.get_table(TablePotentialTransformers)
1124
+ insert = self._database_tables.get_insert(TablePotentialTransformers)
1125
+
1126
+ insert.add_value(table.potential_transformer_info_mrid.query_index, self._mrid_or_none(potential_transformer.potential_transformer_info))
1127
+ insert.add_value(table.type.query_index, potential_transformer.type.short_name)
1128
+
1129
+ return self._save_sensor(table, insert, potential_transformer, "potential transformer")
1130
+
1131
+ def _save_sensor(self, table: TableSensors, insert: PreparedStatement, sensor: Sensor, description: str) -> bool:
1132
+ return self._save_auxiliary_equipment(table, insert, sensor, description)
1133
+
1134
+ ######################
1135
+ # IEC61970 Base Core #
1136
+ ######################
1137
+
1138
+ def _save_ac_dc_terminal(self, table: TableAcDcTerminals, insert: PreparedStatement, ac_dc_terminal: AcDcTerminal, description: str) -> bool:
1139
+ return self._save_identified_object(table, insert, ac_dc_terminal, description)
1140
+
1141
+ def save_base_voltage(self, base_voltage: BaseVoltage) -> bool:
1142
+ """
1143
+ Save the :class:`BaseVoltage` fields to :class:`TableBaseVoltages`.
1144
+
1145
+ :param base_voltage: The :class:`BaseVoltage` instance to write to the database.
1146
+ :return: True if the :class:`BaseVoltage` was successfully written to the database, otherwise False.
1147
+ :raises SqlException: For any errors encountered writing to the database.
1148
+ """
1149
+ table = self._database_tables.get_table(TableBaseVoltages)
1150
+ insert = self._database_tables.get_insert(TableBaseVoltages)
1151
+
1152
+ insert.add_value(table.nominal_voltage.query_index, base_voltage.nominal_voltage)
1153
+
1154
+ return self._save_identified_object(table, insert, base_voltage, "base voltage")
1155
+
1156
+ def _save_conducting_equipment(
1157
+ self,
1158
+ table: TableConductingEquipment,
1159
+ insert: PreparedStatement,
1160
+ conducting_equipment: ConductingEquipment,
1161
+ description: str
1162
+ ) -> bool:
1163
+ insert.add_value(table.base_voltage_mrid.query_index, self._mrid_or_none(conducting_equipment.base_voltage))
1164
+
1165
+ return self._save_equipment(table, insert, conducting_equipment, description)
1166
+
1167
+ def save_connectivity_node(self, connectivity_node: ConnectivityNode) -> bool:
1168
+ """
1169
+ Save the :class:`ConnectivityNode` fields to :class:`TableConnectivityNodes`.
1170
+
1171
+ :param connectivity_node: The :class:`ConnectivityNode` instance to write to the database.
1172
+ :return: True if the :class:`ConnectivityNode` was successfully written to the database, otherwise False.
1173
+ :raises SqlException: For any errors encountered writing to the database.
1174
+ """
1175
+ table = self._database_tables.get_table(TableConnectivityNodes)
1176
+ insert = self._database_tables.get_insert(TableConnectivityNodes)
1177
+
1178
+ return self._save_identified_object(table, insert, connectivity_node, "connectivity node")
1179
+
1180
+ def _save_connectivity_node_container(
1181
+ self,
1182
+ table: TableConnectivityNodeContainers,
1183
+ insert: PreparedStatement,
1184
+ connectivity_node_container: ConnectivityNodeContainer,
1185
+ description: str
1186
+ ) -> bool:
1187
+ return self._save_power_system_resource(table, insert, connectivity_node_container, description)
1188
+
1189
+ def _save_curve(self, table: TableCurves, insert: PreparedStatement, curve: Curve, description: str) -> bool:
1190
+ status = True
1191
+ for curve_data in curve.data:
1192
+ status = status and self._save_curve_data(curve, curve_data)
1193
+
1194
+ return status and self._save_identified_object(table, insert, curve, description)
1195
+
1196
+ def _save_curve_data(self, curve: Curve, curve_data: CurveData) -> bool:
1197
+ table = self._database_tables.get_table(TableCurveData)
1198
+ insert = self._database_tables.get_insert(TableCurveData)
1199
+
1200
+ insert.add_value(table.curve_mrid.query_index, curve.mrid)
1201
+ insert.add_value(table.x_value.query_index, curve_data.x_value)
1202
+ insert.add_value(table.y1_value.query_index, curve_data.y1_value)
1203
+ insert.add_value(table.y2_value.query_index, curve_data.y2_value)
1204
+ insert.add_value(table.y3_value.query_index, curve_data.y3_value)
1205
+
1206
+ return self._try_execute_single_update(insert, "curve data")
1207
+
1208
+ def _save_equipment(self, table: TableEquipment, insert: PreparedStatement, equipment: Equipment, description: str) -> bool:
1209
+ insert.add_value(table.normally_in_service.query_index, equipment.normally_in_service)
1210
+ insert.add_value(table.in_service.query_index, equipment.in_service)
1211
+ insert.add_value(table.commissioned_date.query_index, f"{equipment.commissioned_date.isoformat()}Z" if equipment.commissioned_date else None)
1212
+
1213
+ status = True
1214
+ for it in equipment.containers:
1215
+ if self._should_export_container_contents(it):
1216
+ status = status and self._save_equipment_to_equipment_container_association(equipment, it)
1217
+
1218
+ return status and self._save_power_system_resource(table, insert, equipment, description)
1219
+
1220
+ def _save_equipment_container(
1221
+ self,
1222
+ table: TableEquipmentContainers,
1223
+ insert: PreparedStatement,
1224
+ equipment_container: EquipmentContainer,
1225
+ description: str
1226
+ ) -> bool:
1227
+ return self._save_connectivity_node_container(table, insert, equipment_container, description)
1228
+
1229
+ def save_feeder(self, feeder: Feeder) -> bool:
1230
+ """
1231
+ Save the :class:`Feeder` fields to :class:`TableFeeders`.
1232
+
1233
+ :param feeder: The :class:`Feeder` instance to write to the database.
1234
+ :return: True if the :class:`Feeder` was successfully written to the database, otherwise False.
1235
+ :raises SqlException: For any errors encountered writing to the database.
1236
+ """
1237
+ table = self._database_tables.get_table(TableFeeders)
1238
+ insert = self._database_tables.get_insert(TableFeeders)
1239
+
1240
+ insert.add_value(table.normal_head_terminal_mrid.query_index, self._mrid_or_none(feeder.normal_head_terminal))
1241
+ insert.add_value(
1242
+ table.normal_energizing_substation_mrid.query_index,
1243
+ self._mrid_or_none(feeder.normal_energizing_substation)
1244
+ )
1245
+
1246
+ return self._save_equipment_container(table, insert, feeder, "feeder")
1247
+
1248
+ def save_geographical_region(self, geographical_region: GeographicalRegion) -> bool:
1249
+ """
1250
+ Save the :class:`GeographicalRegion` fields to :class:`TableGeographicalRegions`.
1251
+
1252
+ :param geographical_region: The :class:`GeographicalRegion` instance to write to the database.
1253
+ :return: True if the :class:`GeographicalRegion` was successfully written to the database, otherwise False.
1254
+ :raises SqlException: For any errors encountered writing to the database.
1255
+ """
1256
+ table = self._database_tables.get_table(TableGeographicalRegions)
1257
+ insert = self._database_tables.get_insert(TableGeographicalRegions)
1258
+
1259
+ return self._save_identified_object(table, insert, geographical_region, "geographical region")
1260
+
1261
+ def _save_power_system_resource(
1262
+ self,
1263
+ table: TablePowerSystemResources,
1264
+ insert: PreparedStatement,
1265
+ power_system_resource: PowerSystemResource,
1266
+ description: str
1267
+ ) -> bool:
1268
+ insert.add_value(table.location_mrid.query_index, self._mrid_or_none(power_system_resource.location))
1269
+ insert.add_value(table.num_controls.query_index, power_system_resource.num_controls)
1270
+
1271
+ return self._save_identified_object(table, insert, power_system_resource, description)
1272
+
1273
+ def save_sub_geographical_region(self, sub_geographical_region: SubGeographicalRegion) -> bool:
1274
+ """
1275
+ Save the :class:`SubGeographicalRegion` fields to :class:`TableSubGeographicalRegions`.
1276
+
1277
+ :param sub_geographical_region: The :class:`SubGeographicalRegion` instance to write to the database.
1278
+ :return: True if the :class:`SubGeographicalRegion` was successfully written to the database, otherwise False.
1279
+ :raises SqlException: For any errors encountered writing to the database.
1280
+ """
1281
+ table = self._database_tables.get_table(TableSubGeographicalRegions)
1282
+ insert = self._database_tables.get_insert(TableSubGeographicalRegions)
1283
+
1284
+ insert.add_value(
1285
+ table.geographical_region_mrid.query_index,
1286
+ self._mrid_or_none(sub_geographical_region.geographical_region)
1287
+ )
1288
+
1289
+ return self._save_identified_object(table, insert, sub_geographical_region, "sub-geographical region")
1290
+
1291
+ def save_substation(self, substation: Substation) -> bool:
1292
+ """
1293
+ Save the :class:`Substation` fields to :class:`TableSubstations`.
1294
+
1295
+ :param substation: The :class:`Substation` instance to write to the database.
1296
+ :return: True if the :class:`Substation` was successfully written to the database, otherwise False.
1297
+ :raises SqlException: For any errors encountered writing to the database.
1298
+ """
1299
+ table = self._database_tables.get_table(TableSubstations)
1300
+ insert = self._database_tables.get_insert(TableSubstations)
1301
+
1302
+ insert.add_value(table.sub_geographical_region_mrid.query_index, self._mrid_or_none(substation.sub_geographical_region))
1303
+
1304
+ return self._save_equipment_container(table, insert, substation, "substation")
1305
+
1306
+ def save_terminal(self, terminal: Terminal) -> bool:
1307
+ """
1308
+ Save the :class:`Terminal` fields to :class:`TableTerminals`.
1309
+
1310
+ :param terminal: The :class:`Terminal` instance to write to the database.
1311
+ :return: True if the :class:`Terminal` was successfully written to the database, otherwise False.
1312
+ :raises SqlException: For any errors encountered writing to the database.
1313
+ """
1314
+ table = self._database_tables.get_table(TableTerminals)
1315
+ insert = self._database_tables.get_insert(TableTerminals)
1316
+
1317
+ insert.add_value(table.conducting_equipment_mrid.query_index, self._mrid_or_none(terminal.conducting_equipment))
1318
+ insert.add_value(table.sequence_number.query_index, terminal.sequence_number)
1319
+ insert.add_value(table.connectivity_node_mrid.query_index, terminal.connectivity_node_id)
1320
+ insert.add_value(table.phases.query_index, terminal.phases.short_name)
1321
+
1322
+ return self._save_ac_dc_terminal(table, insert, terminal, "terminal")
1323
+
1324
+ #############################
1325
+ # IEC61970 Base Equivalents #
1326
+ #############################
1327
+
1328
+ def save_equivalent_branch(self, equivalent_branch: EquivalentBranch) -> bool:
1329
+ """
1330
+ Save the :class:`EquivalentBranch` fields to :class:`TableEquivalentBranches`.
1331
+
1332
+ :param equivalent_branch: The :class:`EquivalentBranch` instance to write to the database.
1333
+ :return: True if the :class:`EquivalentBranch` was successfully written to the database, otherwise False.
1334
+ :raises SqlException: For any errors encountered writing to the database.
1335
+ """
1336
+ table = self._database_tables.get_table(TableEquivalentBranches)
1337
+ insert = self._database_tables.get_insert(TableEquivalentBranches)
1338
+
1339
+ insert.add_value(table.negative_r12.query_index, equivalent_branch.negative_r12)
1340
+ insert.add_value(table.negative_r21.query_index, equivalent_branch.negative_r21)
1341
+ insert.add_value(table.negative_x12.query_index, equivalent_branch.negative_x12)
1342
+ insert.add_value(table.negative_x21.query_index, equivalent_branch.negative_x21)
1343
+ insert.add_value(table.positive_r12.query_index, equivalent_branch.positive_r12)
1344
+ insert.add_value(table.positive_r21.query_index, equivalent_branch.positive_r21)
1345
+ insert.add_value(table.positive_x12.query_index, equivalent_branch.positive_x12)
1346
+ insert.add_value(table.positive_x21.query_index, equivalent_branch.positive_x21)
1347
+ insert.add_value(table.r.query_index, equivalent_branch.r)
1348
+ insert.add_value(table.r21.query_index, equivalent_branch.r21)
1349
+ insert.add_value(table.x.query_index, equivalent_branch.x)
1350
+ insert.add_value(table.x21.query_index, equivalent_branch.x21)
1351
+ insert.add_value(table.zero_r12.query_index, equivalent_branch.zero_r12)
1352
+ insert.add_value(table.zero_r21.query_index, equivalent_branch.zero_r21)
1353
+ insert.add_value(table.zero_x12.query_index, equivalent_branch.zero_x12)
1354
+ insert.add_value(table.zero_x21.query_index, equivalent_branch.zero_x21)
1355
+
1356
+ return self._save_equivalent_equipment(table, insert, equivalent_branch, "equivalent branch")
1357
+
1358
+ def _save_equivalent_equipment(
1359
+ self,
1360
+ table: TableEquivalentEquipment,
1361
+ insert: PreparedStatement,
1362
+ equivalent_equipment: EquivalentEquipment,
1363
+ description: str
1364
+ ) -> bool:
1365
+ return self._save_conducting_equipment(table, insert, equivalent_equipment, description)
1366
+
1367
+ #######################################
1368
+ # IEC61970 Base Generation Production #
1369
+ #######################################
1370
+
1371
+ def save_battery_unit(self, battery_unit: BatteryUnit) -> bool:
1372
+ """
1373
+ Save the :class:`BatteryUnit` fields to :class:`TableBatteryUnits`.
1374
+
1375
+ :param battery_unit: The :class:`BatteryUnit` instance to write to the database.
1376
+ :return: True if the :class:`BatteryUnit` was successfully written to the database, otherwise False.
1377
+ :raises SqlException: For any errors encountered writing to the database.
1378
+ """
1379
+ table = self._database_tables.get_table(TableBatteryUnits)
1380
+ insert = self._database_tables.get_insert(TableBatteryUnits)
1381
+
1382
+ insert.add_value(table.battery_state.query_index, battery_unit.battery_state.short_name)
1383
+ insert.add_value(table.rated_e.query_index, battery_unit.rated_e)
1384
+ insert.add_value(table.stored_e.query_index, battery_unit.stored_e)
1385
+ status = True
1386
+ for control in battery_unit.controls:
1387
+ status = status and self._save_battery_unit_to_battery_control_association(battery_unit, control)
1388
+
1389
+ return status and self._save_power_electronics_unit(table, insert, battery_unit, "battery unit")
1390
+
1391
+ def save_photo_voltaic_unit(self, photo_voltaic_unit: PhotoVoltaicUnit) -> bool:
1392
+ """
1393
+ Save the :class:`PhotoVoltaicUnit` fields to :class:`TablePhotoVoltaicUnits`.
1394
+
1395
+ :param photo_voltaic_unit: The :class:`PhotoVoltaicUnit` instance to write to the database.
1396
+ :return: True if the :class:`PhotoVoltaicUnit` was successfully written to the database, otherwise False.
1397
+ :raises SqlException: For any errors encountered writing to the database.
1398
+ """
1399
+ table = self._database_tables.get_table(TablePhotoVoltaicUnits)
1400
+ insert = self._database_tables.get_insert(TablePhotoVoltaicUnits)
1401
+
1402
+ return self._save_power_electronics_unit(table, insert, photo_voltaic_unit, "photo voltaic unit")
1403
+
1404
+ def _save_power_electronics_unit(
1405
+ self,
1406
+ table: TablePowerElectronicsUnits,
1407
+ insert: PreparedStatement,
1408
+ power_electronics_unit: PowerElectronicsUnit,
1409
+ description: str
1410
+ ) -> bool:
1411
+ insert.add_value(table.power_electronics_connection_mrid.query_index, self._mrid_or_none(power_electronics_unit.power_electronics_connection))
1412
+ insert.add_value(table.max_p.query_index, power_electronics_unit.max_p)
1413
+ insert.add_value(table.min_p.query_index, power_electronics_unit.min_p)
1414
+
1415
+ return self._save_equipment(table, insert, power_electronics_unit, description)
1416
+
1417
+ def save_power_electronics_wind_unit(self, power_electronics_wind_unit: PowerElectronicsWindUnit) -> bool:
1418
+ """
1419
+ Save the :class:`PowerElectronicsWindUnit` fields to :class:`TablePowerElectronicsWindUnits`.
1420
+
1421
+ :param power_electronics_wind_unit: The :class:`PowerElectronicsWindUnit` instance to write to the database.
1422
+ :return: True if the :class:`PowerElectronicsWindUnit` was successfully written to the database, otherwise False.
1423
+ :raises SqlException: For any errors encountered writing to the database.
1424
+ """
1425
+ table = self._database_tables.get_table(TablePowerElectronicsWindUnits)
1426
+ insert = self._database_tables.get_insert(TablePowerElectronicsWindUnits)
1427
+
1428
+ return self._save_power_electronics_unit(table, insert, power_electronics_wind_unit, "power electronics wind unit")
1429
+
1430
+ ######################
1431
+ # IEC61970 Base Meas #
1432
+ ######################
1433
+
1434
+ def save_accumulator(self, accumulator: Accumulator) -> bool:
1435
+ """
1436
+ Save the :class:`Accumulator` fields to :class:`TableAccumulators`.
1437
+
1438
+ :param accumulator: The :class:`Accumulator` instance to write to the database.
1439
+ :return: True if the :class:`Accumulator` was successfully written to the database, otherwise False.
1440
+ :raises SqlException: For any errors encountered writing to the database.
1441
+ """
1442
+ table = self._database_tables.get_table(TableAccumulators)
1443
+ insert = self._database_tables.get_insert(TableAccumulators)
1444
+
1445
+ return self._save_measurement(table, insert, accumulator, "accumulator")
1446
+
1447
+ def save_analog(self, analog: Analog) -> bool:
1448
+ """
1449
+ Save the :class:`Analog` fields to :class:`TableAnalogs`.
1450
+
1451
+ :param analog: The :class:`Analog` instance to write to the database.
1452
+ :return: True if the :class:`Analog` was successfully written to the database, otherwise False.
1453
+ :raises SqlException: For any errors encountered writing to the database.
1454
+ """
1455
+ table = self._database_tables.get_table(TableAnalogs)
1456
+ insert = self._database_tables.get_insert(TableAnalogs)
1457
+
1458
+ insert.add_value(table.positive_flow_in.query_index, analog.positive_flow_in)
1459
+
1460
+ return self._save_measurement(table, insert, analog, "analog")
1461
+
1462
+ def save_discrete(self, discrete: Discrete) -> bool:
1463
+ """
1464
+ Save the :class:`Discrete` fields to :class:`TableDiscretes`.
1465
+
1466
+ :param discrete: The :class:`Discrete` instance to write to the database.
1467
+ :return: True if the :class:`Discrete` was successfully written to the database, otherwise False.
1468
+ :raises SqlException: For any errors encountered writing to the database.
1469
+ """
1470
+ table = self._database_tables.get_table(TableDiscretes)
1471
+ insert = self._database_tables.get_insert(TableDiscretes)
1472
+
1473
+ return self._save_measurement(table, insert, discrete, "discrete")
1474
+
1475
+ def save_control(self, control: Control) -> bool:
1476
+ """
1477
+ Save the :class:`Control` fields to :class:`TableControls`.
1478
+
1479
+ :param control: The :class:`Control` instance to write to the database.
1480
+ :return: True if the :class:`Control` was successfully written to the database, otherwise False.
1481
+ :raises SqlException: For any errors encountered writing to the database.
1482
+ """
1483
+ table = self._database_tables.get_table(TableControls)
1484
+ insert = self._database_tables.get_insert(TableControls)
1485
+
1486
+ insert.add_value(table.power_system_resource_mrid.query_index, control.power_system_resource_mrid)
1487
+
1488
+ return self._save_io_point(table, insert, control, "control")
1489
+
1490
+ def _save_io_point(self, table: TableIoPoints, insert: PreparedStatement, io_point: IoPoint, description: str) -> bool:
1491
+ return self._save_identified_object(table, insert, io_point, description)
1492
+
1493
+ def _save_measurement(
1494
+ self,
1495
+ table: TableMeasurements,
1496
+ insert: PreparedStatement,
1497
+ measurement: Measurement,
1498
+ description: str
1499
+ ) -> bool:
1500
+ insert.add_value(table.power_system_resource_mrid.query_index, measurement.power_system_resource_mrid)
1501
+ insert.add_value(table.remote_source_mrid.query_index, self._mrid_or_none(measurement.remote_source))
1502
+ insert.add_value(table.terminal_mrid.query_index, measurement.terminal_mrid)
1503
+ insert.add_value(table.phases.query_index, measurement.phases.short_name)
1504
+ insert.add_value(table.unit_symbol.query_index, measurement.unit_symbol.short_name)
1505
+
1506
+ return self._save_identified_object(table, insert, measurement, description)
1507
+
1508
+ ############################
1509
+ # IEC61970 Base Protection #
1510
+ ############################
1511
+
1512
+ def save_current_relay(self, current_relay: CurrentRelay) -> bool:
1513
+ """
1514
+ Save the :class:`CurrentRelay` fields to :class:`TableCurrentRelays`.
1515
+
1516
+ :param current_relay: The :class:`CurrentRelay` instance to write to the database.
1517
+ :return: True if the :class:`CurrentRelay` was successfully written to the database, otherwise False.
1518
+ :raises SqlException: For any errors encountered writing to the database.
1519
+ """
1520
+ table = self._database_tables.get_table(TableCurrentRelays)
1521
+ insert = self._database_tables.get_insert(TableCurrentRelays)
1522
+
1523
+ insert.add_value(table.current_limit_1.query_index, current_relay.current_limit_1)
1524
+ insert.add_value(table.inverse_time_flag.query_index, current_relay.inverse_time_flag)
1525
+ insert.add_value(table.time_delay_1.query_index, current_relay.time_delay_1)
1526
+
1527
+ return self._save_protection_relay_function(table, insert, current_relay, "current relay")
1528
+
1529
+ #######################
1530
+ # IEC61970 Base Scada #
1531
+ #######################
1532
+
1533
+ def save_remote_control(self, remote_control: RemoteControl) -> bool:
1534
+ """
1535
+ Save the :class:`RemoteControl` fields to :class:`TableRemoteControls`.
1536
+
1537
+ :param remote_control: The :class:`RemoteControl` instance to write to the database.
1538
+ :return: True if the :class:`RemoteControl` was successfully written to the database, otherwise False.
1539
+ :raises SqlException: For any errors encountered writing to the database.
1540
+ """
1541
+ table = self._database_tables.get_table(TableRemoteControls)
1542
+ insert = self._database_tables.get_insert(TableRemoteControls)
1543
+
1544
+ insert.add_value(table.control_mrid.query_index, self._mrid_or_none(remote_control.control))
1545
+
1546
+ return self._save_remote_point(table, insert, remote_control, "remote control")
1547
+
1548
+ def _save_remote_point(self, table: TableRemotePoints, insert: PreparedStatement, remote_point: RemotePoint, description: str) -> bool:
1549
+ return self._save_identified_object(table, insert, remote_point, description)
1550
+
1551
+ def save_remote_source(self, remote_source: RemoteSource) -> bool:
1552
+ """
1553
+ Save the :class:`RemoteSource` fields to :class:`TableRemoteSources`.
1554
+
1555
+ :param remote_source: The :class:`RemoteSource` instance to write to the database.
1556
+ :return: True if the :class:`RemoteSource` was successfully written to the database, otherwise False.
1557
+ :raises SqlException: For any errors encountered writing to the database.
1558
+ """
1559
+ table = self._database_tables.get_table(TableRemoteSources)
1560
+ insert = self._database_tables.get_insert(TableRemoteSources)
1561
+
1562
+ insert.add_value(table.measurement_mrid.query_index, self._mrid_or_none(remote_source.measurement))
1563
+
1564
+ return self._save_remote_point(table, insert, remote_source, "remote source")
1565
+
1566
+ #######################
1567
+ # IEC61970 Base Wires #
1568
+ #######################
1569
+
1570
+ def save_ac_line_segment(self, ac_line_segment: AcLineSegment) -> bool:
1571
+ """
1572
+ Save the :class:`AcLineSegment` fields to :class:`TableAcLineSegments`.
1573
+
1574
+ :param ac_line_segment: The :class:`AcLineSegment` instance to write to the database.
1575
+ :return: True if the :class:`AcLineSegment` was successfully written to the database, otherwise False.
1576
+ :raises SqlException: For any errors encountered writing to the database.
1577
+ """
1578
+ table = self._database_tables.get_table(TableAcLineSegments)
1579
+ insert = self._database_tables.get_insert(TableAcLineSegments)
1580
+
1581
+ insert.add_value(table.per_length_impedance_mrid.query_index, self._mrid_or_none(ac_line_segment.per_length_impedance))
1582
+
1583
+ return self._save_conductor(table, insert, ac_line_segment, "AC line segment")
1584
+
1585
+ def save_breaker(self, breaker: Breaker) -> bool:
1586
+ """
1587
+ Save the :class:`Breaker` fields to :class:`TableBreakers`.
1588
+
1589
+ :param breaker: The :class:`Breaker` instance to write to the database.
1590
+ :return: True if the :class:`Breaker` was successfully written to the database, otherwise False.
1591
+ :raises SqlException: For any errors encountered writing to the database.
1592
+ """
1593
+ table = self._database_tables.get_table(TableBreakers)
1594
+ insert = self._database_tables.get_insert(TableBreakers)
1595
+
1596
+ insert.add_value(table.in_transit_time.query_index, breaker.in_transit_time)
1597
+
1598
+ return self._save_protected_switch(table, insert, breaker, "breaker")
1599
+
1600
+ def save_busbar_section(self, busbar_section: BusbarSection) -> bool:
1601
+ """
1602
+ Save the :class:`BusbarSection` fields to :class:`TableBusbarSections`.
1603
+
1604
+ :param busbar_section: The :class:`BusbarSection` instance to write to the database.
1605
+ :return: True if the :class:`BusbarSection` was successfully written to the database, otherwise False.
1606
+ :raises SqlException: For any errors encountered writing to the database.
1607
+ """
1608
+ table = self._database_tables.get_table(TableBusbarSections)
1609
+ insert = self._database_tables.get_insert(TableBusbarSections)
1610
+
1611
+ return self._save_connector(table, insert, busbar_section, "busbar section")
1612
+
1613
+ def save_clamp(self, clamp: Clamp) -> bool:
1614
+ """
1615
+ Save the :class:`Clamp` fields to :class:`TableClamps`.
1616
+
1617
+ :param clamp: The :class:`Clamp` instance to write to the database.
1618
+ :return: True if the :class:`Clamp` was successfully written to the database, otherwise False.
1619
+ :raises SqlException: For any errors encountered writing to the database.
1620
+ """
1621
+ table = self._database_tables.get_table(TableClamps)
1622
+ insert = self._database_tables.get_insert(TableClamps)
1623
+
1624
+ insert.add_value(table.length_from_terminal_1.query_index, clamp.length_from_terminal_1)
1625
+ insert.add_value(table.ac_line_segment_mrid.query_index, self._mrid_or_none(clamp.ac_line_segment))
1626
+
1627
+ return self._save_conducting_equipment(table, insert, clamp, "clamp")
1628
+
1629
+ def _save_conductor(self, table: TableConductors, insert: PreparedStatement, conductor: Conductor, description: str) -> bool:
1630
+ insert.add_value(table.length.query_index, conductor.length)
1631
+ insert.add_value(table.design_temperature.query_index, conductor.design_temperature)
1632
+ insert.add_value(table.design_rating.query_index, conductor.design_rating)
1633
+ insert.add_value(table.wire_info_mrid.query_index, self._mrid_or_none(conductor.wire_info))
1634
+
1635
+ return self._save_conducting_equipment(table, insert, conductor, description)
1636
+
1637
+ def _save_connector(self, table: TableConnectors, insert: PreparedStatement, connector: Connector, description: str) -> bool:
1638
+ return self._save_conducting_equipment(table, insert, connector, description)
1639
+
1640
+ def save_cut(self, cut: Cut) -> bool:
1641
+ """
1642
+ Save the :class:`Cut` fields to :class:`TableCuts`.
1643
+
1644
+ :param cut: The :class:`Cut` instance to write to the database.
1645
+ :return: True if the :class:`Cut` was successfully written to the database, otherwise False.
1646
+ :raises SqlException: For any errors encountered writing to the database.
1647
+ """
1648
+ table = self._database_tables.get_table(TableCuts)
1649
+ insert = self._database_tables.get_insert(TableCuts)
1650
+
1651
+ insert.add_value(table.length_from_terminal_1.query_index, cut.length_from_terminal_1)
1652
+ insert.add_value(table.ac_line_segment_mrid.query_index, self._mrid_or_none(cut.ac_line_segment))
1653
+
1654
+ return self._save_switch(table, insert, cut, "cut")
1655
+
1656
+ def save_disconnector(self, disconnector: Disconnector) -> bool:
1657
+ """
1658
+ Save the :class:`Disconnector` fields to :class:`TableDisconnectors`.
1659
+
1660
+ :param disconnector: The :class:`Disconnector` instance to write to the database.
1661
+ :return: True if the :class:`Disconnector` was successfully written to the database, otherwise False.
1662
+ :raises SqlException: For any errors encountered writing to the database.
1663
+ """
1664
+ table = self._database_tables.get_table(TableDisconnectors)
1665
+ insert = self._database_tables.get_insert(TableDisconnectors)
1666
+
1667
+ return self._save_switch(table, insert, disconnector, "disconnector")
1668
+
1669
+ def _save_earth_fault_compensator(
1670
+ self,
1671
+ table: TableEarthFaultCompensators,
1672
+ insert: PreparedStatement,
1673
+ earth_fault_compensator: EarthFaultCompensator,
1674
+ description: str
1675
+ ) -> bool:
1676
+ insert.add_value(table.r.query_index, earth_fault_compensator.r)
1677
+
1678
+ return self._save_conducting_equipment(table, insert, earth_fault_compensator, description)
1679
+
1680
+ def _save_energy_connection(
1681
+ self,
1682
+ table: TableEnergyConnections,
1683
+ insert: PreparedStatement,
1684
+ energy_connection: EnergyConnection,
1685
+ description: str
1686
+ ) -> bool:
1687
+ return self._save_conducting_equipment(table, insert, energy_connection, description)
1688
+
1689
+ def save_energy_consumer(self, energy_consumer: EnergyConsumer) -> bool:
1690
+ """
1691
+ Save the :class:`EnergyConsumer` fields to :class:`TableEnergyConsumers`.
1692
+
1693
+ :param energy_consumer: The :class:`EnergyConsumer` instance to write to the database.
1694
+ :return: True if the :class:`EnergyConsumer` was successfully written to the database, otherwise False.
1695
+ :raises SqlException: For any errors encountered writing to the database.
1696
+ """
1697
+ table = self._database_tables.get_table(TableEnergyConsumers)
1698
+ insert = self._database_tables.get_insert(TableEnergyConsumers)
1699
+
1700
+ insert.add_value(table.customer_count.query_index, energy_consumer.customer_count)
1701
+ insert.add_value(table.grounded.query_index, energy_consumer.grounded)
1702
+ insert.add_value(table.p.query_index, energy_consumer.p)
1703
+ insert.add_value(table.q.query_index, energy_consumer.q)
1704
+ insert.add_value(table.p_fixed.query_index, energy_consumer.p_fixed)
1705
+ insert.add_value(table.q_fixed.query_index, energy_consumer.q_fixed)
1706
+ insert.add_value(table.phase_connection.query_index, energy_consumer.phase_connection.short_name)
1707
+
1708
+ return self._save_energy_connection(table, insert, energy_consumer, "energy consumer")
1709
+
1710
+ def save_energy_consumer_phase(self, energy_consumer_phase: EnergyConsumerPhase) -> bool:
1711
+ """
1712
+ Save the :class:`EnergyConsumerPhase` fields to :class:`TableEnergyConsumerPhases`.
1713
+
1714
+ :param energy_consumer_phase: The :class:`EnergyConsumerPhase` instance to write to the database.
1715
+ :return: True if the :class:`EnergyConsumerPhase` was successfully written to the database, otherwise False.
1716
+ :raises SqlException: For any errors encountered writing to the database.
1717
+ """
1718
+ table = self._database_tables.get_table(TableEnergyConsumerPhases)
1719
+ insert = self._database_tables.get_insert(TableEnergyConsumerPhases)
1720
+
1721
+ insert.add_value(table.energy_consumer_mrid.query_index, self._mrid_or_none(energy_consumer_phase.energy_consumer))
1722
+ insert.add_value(table.phase.query_index, energy_consumer_phase.phase.short_name)
1723
+ insert.add_value(table.p.query_index, energy_consumer_phase.p)
1724
+ insert.add_value(table.q.query_index, energy_consumer_phase.q)
1725
+ insert.add_value(table.p_fixed.query_index, energy_consumer_phase.p_fixed)
1726
+ insert.add_value(table.q_fixed.query_index, energy_consumer_phase.q_fixed)
1727
+
1728
+ return self._save_power_system_resource(table, insert, energy_consumer_phase, "energy consumer phase")
1729
+
1730
+ def save_energy_source(self, energy_source: EnergySource) -> bool:
1731
+ """
1732
+ Save the :class:`EnergySource` fields to :class:`TableEnergySources`.
1733
+
1734
+ :param energy_source: The :class:`EnergySource` instance to write to the database.
1735
+ :return: True if the :class:`EnergySource` was successfully written to the database, otherwise False.
1736
+ :raises SqlException: For any errors encountered writing to the database.
1737
+ """
1738
+ table = self._database_tables.get_table(TableEnergySources)
1739
+ insert = self._database_tables.get_insert(TableEnergySources)
1740
+
1741
+ insert.add_value(table.active_power.query_index, energy_source.active_power)
1742
+ insert.add_value(table.reactive_power.query_index, energy_source.reactive_power)
1743
+ insert.add_value(table.voltage_angle.query_index, energy_source.voltage_angle)
1744
+ insert.add_value(table.voltage_magnitude.query_index, energy_source.voltage_magnitude)
1745
+ insert.add_value(table.p_max.query_index, energy_source.p_max)
1746
+ insert.add_value(table.p_min.query_index, energy_source.p_min)
1747
+ insert.add_value(table.r.query_index, energy_source.r)
1748
+ insert.add_value(table.r0.query_index, energy_source.r0)
1749
+ insert.add_value(table.rn.query_index, energy_source.rn)
1750
+ insert.add_value(table.x.query_index, energy_source.x)
1751
+ insert.add_value(table.x0.query_index, energy_source.x0)
1752
+ insert.add_value(table.xn.query_index, energy_source.xn)
1753
+ insert.add_value(table.is_external_grid.query_index, energy_source.is_external_grid)
1754
+ insert.add_value(table.r_min.query_index, energy_source.r_min)
1755
+ insert.add_value(table.rn_min.query_index, energy_source.rn_min)
1756
+ insert.add_value(table.r0_min.query_index, energy_source.r0_min)
1757
+ insert.add_value(table.x_min.query_index, energy_source.x_min)
1758
+ insert.add_value(table.xn_min.query_index, energy_source.xn_min)
1759
+ insert.add_value(table.x0_min.query_index, energy_source.x0_min)
1760
+ insert.add_value(table.r_max.query_index, energy_source.r_max)
1761
+ insert.add_value(table.rn_max.query_index, energy_source.rn_max)
1762
+ insert.add_value(table.r0_max.query_index, energy_source.r0_max)
1763
+ insert.add_value(table.x_max.query_index, energy_source.x_max)
1764
+ insert.add_value(table.xn_max.query_index, energy_source.xn_max)
1765
+ insert.add_value(table.x0_max.query_index, energy_source.x0_max)
1766
+
1767
+ return self._save_energy_connection(table, insert, energy_source, "energy source")
1768
+
1769
+ def save_energy_source_phase(self, energy_source_phase: EnergySourcePhase) -> bool:
1770
+ """
1771
+ Save the :class:`EnergySourcePhase` fields to :class:`TableEnergySourcePhases`.
1772
+
1773
+ :param energy_source_phase: The :class:`EnergySourcePhase` instance to write to the database.
1774
+ :return: True if the :class:`EnergySourcePhase` was successfully written to the database, otherwise False.
1775
+ :raises SqlException: For any errors encountered writing to the database.
1776
+ """
1777
+ table = self._database_tables.get_table(TableEnergySourcePhases)
1778
+ insert = self._database_tables.get_insert(TableEnergySourcePhases)
1779
+
1780
+ insert.add_value(table.energy_source_mrid.query_index, self._mrid_or_none(energy_source_phase.energy_source))
1781
+ insert.add_value(table.phase.query_index, energy_source_phase.phase.short_name)
1782
+
1783
+ return self._save_power_system_resource(table, insert, energy_source_phase, "energy source phase")
1784
+
1785
+ def save_fuse(self, fuse: Fuse) -> bool:
1786
+ """
1787
+ Save the :class:`Fuse` fields to :class:`TableFuses`.
1788
+
1789
+ :param fuse: The :class:`Fuse` instance to write to the database.
1790
+ :return: True if the :class:`Fuse` was successfully written to the database, otherwise False.
1791
+ :raises SqlException: For any errors encountered writing to the database.
1792
+ """
1793
+ table = self._database_tables.get_table(TableFuses)
1794
+ insert = self._database_tables.get_insert(TableFuses)
1795
+
1796
+ insert.add_value(table.function_mrid.query_index, self._mrid_or_none(fuse.function))
1797
+
1798
+ return self._save_switch(table, insert, fuse, "fuse")
1799
+
1800
+ def save_ground(self, ground: Ground) -> bool:
1801
+ """
1802
+ Save the :class:`Ground` fields to :class:`TableGrounds`.
1803
+
1804
+ :param ground: The :class:`Ground` instance to write to the database.
1805
+ :return: True if the :class:`Ground` was successfully written to the database, otherwise False.
1806
+ :raises SqlException: For any errors encountered writing to the database.
1807
+ """
1808
+ table = self._database_tables.get_table(TableGrounds)
1809
+ insert = self._database_tables.get_insert(TableGrounds)
1810
+
1811
+ return self._save_conducting_equipment(table, insert, ground, "ground")
1812
+
1813
+ def save_ground_disconnector(self, ground_disconnector: GroundDisconnector) -> bool:
1814
+ """
1815
+ Save the :class:`GroundDisconnector` fields to :class:`TableGroundDisconnectors`.
1816
+
1817
+ :param ground_disconnector: The :class:`GroundDisconnector` instance to write to the database.
1818
+ :return: True if the :class:`GroundDisconnector` was successfully written to the database, otherwise False.
1819
+ :raises SqlException: For any errors encountered writing to the database.
1820
+ """
1821
+ table = self._database_tables.get_table(TableGroundDisconnectors)
1822
+ insert = self._database_tables.get_insert(TableGroundDisconnectors)
1823
+
1824
+ return self._save_switch(table, insert, ground_disconnector, "ground disconnector")
1825
+
1826
+ def save_grounding_impedance(self, grounding_impedance: GroundingImpedance) -> bool:
1827
+ """
1828
+ Save the :class:`GroundingImpedance` fields to :class:`TableGroundingImpedances`.
1829
+
1830
+ :param grounding_impedance: The :class:`GroundingImpedance` instance to write to the database.
1831
+
1832
+ :return: True if the :class:`GroundingImpedance` was successfully written to the database, otherwise False.
1833
+ :raises SqlException: For any errors encountered writing to the database.
1834
+ """
1835
+ table = self._database_tables.get_table(TableGroundingImpedances)
1836
+ insert = self._database_tables.get_insert(TableGroundingImpedances)
1837
+
1838
+ insert.add_value(table.x.query_index, grounding_impedance.x)
1839
+
1840
+ return self._save_earth_fault_compensator(table, insert, grounding_impedance, "ground disconnector")
1841
+
1842
+ def save_jumper(self, jumper: Jumper) -> bool:
1843
+ """
1844
+ Save the :class:`Jumper` fields to :class:`TableJumpers`.
1845
+
1846
+ :param jumper: The :class:`Jumper` instance to write to the database.
1847
+ :return: True if the :class:`Jumper` was successfully written to the database, otherwise False.
1848
+ :raises SqlException: For any errors encountered writing to the database.
1849
+ """
1850
+ table = self._database_tables.get_table(TableJumpers)
1851
+ insert = self._database_tables.get_insert(TableJumpers)
1852
+
1853
+ return self._save_switch(table, insert, jumper, "jumper")
1854
+
1855
+ def save_junction(self, junction: Junction) -> bool:
1856
+ """
1857
+ Save the :class:`Junction` fields to :class:`TableJunctions`.
1858
+
1859
+ :param junction: The :class:`Junction` instance to write to the database.
1860
+ :return: True if the :class:`Junction` was successfully written to the database, otherwise False.
1861
+ :raises SqlException: For any errors encountered writing to the database.
1862
+ """
1863
+ table = self._database_tables.get_table(TableJunctions)
1864
+ insert = self._database_tables.get_insert(TableJunctions)
1865
+
1866
+ return self._save_connector(table, insert, junction, "junction")
1867
+
1868
+ def _save_line(self, table: TableLines, insert: PreparedStatement, line: Line, description: str) -> bool:
1869
+ return self._save_equipment_container(table, insert, line, description)
1870
+
1871
+ def save_linear_shunt_compensator(self, linear_shunt_compensator: LinearShuntCompensator) -> bool:
1872
+ """
1873
+ Save the :class:`LinearShuntCompensator` fields to :class:`TableLinearShuntCompensators`.
1874
+
1875
+ :param linear_shunt_compensator: The :class:`LinearShuntCompensator` instance to write to the database.
1876
+ :return: True if the :class:`LinearShuntCompensator` was successfully written to the database, otherwise False.
1877
+ :raises SqlException: For any errors encountered writing to the database.
1878
+ """
1879
+ table = self._database_tables.get_table(TableLinearShuntCompensators)
1880
+ insert = self._database_tables.get_insert(TableLinearShuntCompensators)
1881
+
1882
+ insert.add_value(table.b0_per_section.query_index, linear_shunt_compensator.b0_per_section)
1883
+ insert.add_value(table.b_per_section.query_index, linear_shunt_compensator.b_per_section)
1884
+ insert.add_value(table.g0_per_section.query_index, linear_shunt_compensator.g0_per_section)
1885
+ insert.add_value(table.g_per_section.query_index, linear_shunt_compensator.g_per_section)
1886
+
1887
+ return self._save_shunt_compensator(table, insert, linear_shunt_compensator, "linear shunt compensator")
1888
+
1889
+ def save_load_break_switch(self, load_break_switch: LoadBreakSwitch) -> bool:
1890
+ """
1891
+ Save the :class:`LoadBreakSwitch` fields to :class:`TableLoadBreakSwitches`.
1892
+
1893
+ :param load_break_switch: The :class:`LoadBreakSwitch` instance to write to the database.
1894
+ :return: True if the :class:`LoadBreakSwitch` was successfully written to the database, otherwise False.
1895
+ :raises SqlException: For any errors encountered writing to the database.
1896
+ """
1897
+ table = self._database_tables.get_table(TableLoadBreakSwitches)
1898
+ insert = self._database_tables.get_insert(TableLoadBreakSwitches)
1899
+
1900
+ return self._save_protected_switch(table, insert, load_break_switch, "load break switch")
1901
+
1902
+ def _save_per_length_impedance(
1903
+ self,
1904
+ table: TablePerLengthImpedances,
1905
+ insert: PreparedStatement,
1906
+ per_length_impedance: PerLengthImpedance,
1907
+ description: str
1908
+ ) -> bool:
1909
+ return self._save_per_length_line_parameter(table, insert, per_length_impedance, description)
1910
+
1911
+ def _save_per_length_line_parameter(
1912
+ self,
1913
+ table: TablePerLengthLineParameters,
1914
+ insert: PreparedStatement,
1915
+ per_length_line_parameter: PerLengthLineParameter,
1916
+ description: str
1917
+ ) -> bool:
1918
+ return self._save_identified_object(table, insert, per_length_line_parameter, description)
1919
+
1920
+ def save_per_length_phase_impedance(self, per_length_phase_impedance: PerLengthPhaseImpedance) -> bool:
1921
+ """
1922
+ Save the :class:`PerLengthPhaseImpedance` fields to :class:`TablePerLengthPhaseImpedances`.
1923
+
1924
+ :param per_length_phase_impedance: The :class:`PerLengthPhaseImpedance` instance to write to the database.
1925
+ :return: True if the :class:`PerLengthPhaseImpedance` was successfully written to the database, otherwise False.
1926
+ :raises SqlException: For any errors encountered writing to the database.
1927
+ """
1928
+ table = self._database_tables.get_table(TablePerLengthPhaseImpedances)
1929
+ insert = self._database_tables.get_insert(TablePerLengthPhaseImpedances)
1930
+
1931
+ status = True
1932
+
1933
+ for phase_impedance_data in per_length_phase_impedance.data:
1934
+ status = status and self._save_phase_impedance_data(per_length_phase_impedance, phase_impedance_data)
1935
+
1936
+ return self._save_per_length_impedance(table, insert, per_length_phase_impedance, "per length phase impedance")
1937
+
1938
+ def save_per_length_sequence_impedance(self, per_length_sequence_impedance: PerLengthSequenceImpedance) -> bool:
1939
+ """
1940
+ Save the :class:`PerLengthSequenceImpedance` fields to :class:`TablePerLengthSequenceImpedances`.
1941
+
1942
+ :param per_length_sequence_impedance: The :class:`PerLengthSequenceImpedance` instance to write to the database.
1943
+ :return: True if the :class:`PerLengthSequenceImpedance` was successfully written to the database, otherwise False.
1944
+ :raises SqlException: For any errors encountered writing to the database.
1945
+ """
1946
+ table = self._database_tables.get_table(TablePerLengthSequenceImpedances)
1947
+ insert = self._database_tables.get_insert(TablePerLengthSequenceImpedances)
1948
+
1949
+ insert.add_value(table.r.query_index, per_length_sequence_impedance.r)
1950
+ insert.add_value(table.x.query_index, per_length_sequence_impedance.x)
1951
+ insert.add_value(table.r0.query_index, per_length_sequence_impedance.r0)
1952
+ insert.add_value(table.x0.query_index, per_length_sequence_impedance.x0)
1953
+ insert.add_value(table.bch.query_index, per_length_sequence_impedance.bch)
1954
+ insert.add_value(table.gch.query_index, per_length_sequence_impedance.gch)
1955
+ insert.add_value(table.b0ch.query_index, per_length_sequence_impedance.b0ch)
1956
+ insert.add_value(table.g0ch.query_index, per_length_sequence_impedance.g0ch)
1957
+
1958
+ return self._save_per_length_impedance(table, insert, per_length_sequence_impedance, "per length sequence impedance")
1959
+
1960
+ def save_petersen_coil(self, petersen_coil: PetersenCoil) -> bool:
1961
+ """
1962
+ Save the :class:`PetersenCoil` fields to :class:`TablePetersenCoils`.
1963
+
1964
+ :param petersen_coil: The :class:`PetersenCoil` instance to write to the database.
1965
+
1966
+ :return: True if the :class:`PetersenCoil` was successfully written to the database, otherwise False.
1967
+ :raises SqlException: For any errors encountered writing to the database.
1968
+ """
1969
+ table = self._database_tables.get_table(TablePetersenCoils)
1970
+ insert = self._database_tables.get_insert(TablePetersenCoils)
1971
+
1972
+ insert.add_value(table.x_ground_nominal.query_index, petersen_coil.x_ground_nominal)
1973
+
1974
+ return self._save_earth_fault_compensator(table, insert, petersen_coil, "petersen coil")
1975
+
1976
+ def _save_phase_impedance_data(self, per_length_phase_impedance: PerLengthPhaseImpedance, phase_impedance_data: PhaseImpedanceData) -> bool:
1977
+ table = self._database_tables.get_table(TablePhaseImpedanceData)
1978
+ insert = self._database_tables.get_insert(TablePhaseImpedanceData)
1979
+
1980
+ insert.add_value(table.per_length_phase_impedance_mrid.query_index, per_length_phase_impedance.mrid)
1981
+ insert.add_value(table.from_phase.query_index, phase_impedance_data.from_phase.short_name)
1982
+ insert.add_value(table.to_phase.query_index, phase_impedance_data.to_phase.short_name)
1983
+ insert.add_value(table.b.query_index, phase_impedance_data.b)
1984
+ insert.add_value(table.g.query_index, phase_impedance_data.g)
1985
+ insert.add_value(table.r.query_index, phase_impedance_data.r)
1986
+ insert.add_value(table.x.query_index, phase_impedance_data.x)
1987
+
1988
+ return self._try_execute_single_update(insert, "phase impedance data")
1989
+
1990
+ def save_power_electronics_connection(self, power_electronics_connection: PowerElectronicsConnection) -> bool:
1991
+ """
1992
+ Save the :class:`PowerElectronicsConnection` fields to :class:`TablePowerElectronicsConnections`.
1993
+
1994
+ :param power_electronics_connection: The :class:`PowerElectronicsConnection` instance to write to the database.
1995
+ :return: True if the :class:`PowerElectronicsConnection` was successfully written to the database, otherwise False.
1996
+ :raises SqlException: For any errors encountered writing to the database.
1997
+ """
1998
+ table = self._database_tables.get_table(TablePowerElectronicsConnections)
1999
+ insert = self._database_tables.get_insert(TablePowerElectronicsConnections)
2000
+
2001
+ insert.add_value(table.max_i_fault.query_index, power_electronics_connection.max_i_fault)
2002
+ insert.add_value(table.max_q.query_index, power_electronics_connection.max_q)
2003
+ insert.add_value(table.min_q.query_index, power_electronics_connection.min_q)
2004
+ insert.add_value(table.p.query_index, power_electronics_connection.p)
2005
+ insert.add_value(table.q.query_index, power_electronics_connection.q)
2006
+ insert.add_value(table.rated_s.query_index, power_electronics_connection.rated_s)
2007
+ insert.add_value(table.rated_u.query_index, power_electronics_connection.rated_u)
2008
+ insert.add_value(table.inverter_standard.query_index, power_electronics_connection.inverter_standard)
2009
+ insert.add_value(table.sustain_op_overvolt_limit.query_index, power_electronics_connection.sustain_op_overvolt_limit)
2010
+ insert.add_value(table.stop_at_over_freq.query_index, power_electronics_connection.stop_at_over_freq)
2011
+ insert.add_value(table.stop_at_under_freq.query_index, power_electronics_connection.stop_at_under_freq)
2012
+ insert.add_value(table.inv_volt_watt_resp_mode.query_index, power_electronics_connection.inv_volt_watt_resp_mode)
2013
+ insert.add_value(table.inv_watt_resp_v1.query_index, power_electronics_connection.inv_watt_resp_v1)
2014
+ insert.add_value(table.inv_watt_resp_v2.query_index, power_electronics_connection.inv_watt_resp_v2)
2015
+ insert.add_value(table.inv_watt_resp_v3.query_index, power_electronics_connection.inv_watt_resp_v3)
2016
+ insert.add_value(table.inv_watt_resp_v4.query_index, power_electronics_connection.inv_watt_resp_v4)
2017
+ insert.add_value(table.inv_watt_resp_p_at_v1.query_index, power_electronics_connection.inv_watt_resp_p_at_v1)
2018
+ insert.add_value(table.inv_watt_resp_p_at_v2.query_index, power_electronics_connection.inv_watt_resp_p_at_v2)
2019
+ insert.add_value(table.inv_watt_resp_p_at_v3.query_index, power_electronics_connection.inv_watt_resp_p_at_v3)
2020
+ insert.add_value(table.inv_watt_resp_p_at_v4.query_index, power_electronics_connection.inv_watt_resp_p_at_v4)
2021
+ insert.add_value(table.inv_volt_var_resp_mode.query_index, power_electronics_connection.inv_volt_var_resp_mode)
2022
+ insert.add_value(table.inv_var_resp_v1.query_index, power_electronics_connection.inv_var_resp_v1)
2023
+ insert.add_value(table.inv_var_resp_v2.query_index, power_electronics_connection.inv_var_resp_v2)
2024
+ insert.add_value(table.inv_var_resp_v3.query_index, power_electronics_connection.inv_var_resp_v3)
2025
+ insert.add_value(table.inv_var_resp_v4.query_index, power_electronics_connection.inv_var_resp_v4)
2026
+ insert.add_value(table.inv_var_resp_q_at_v1.query_index, power_electronics_connection.inv_var_resp_q_at_v1)
2027
+ insert.add_value(table.inv_var_resp_q_at_v2.query_index, power_electronics_connection.inv_var_resp_q_at_v2)
2028
+ insert.add_value(table.inv_var_resp_q_at_v3.query_index, power_electronics_connection.inv_var_resp_q_at_v3)
2029
+ insert.add_value(table.inv_var_resp_q_at_v4.query_index, power_electronics_connection.inv_var_resp_q_at_v4)
2030
+ insert.add_value(table.inv_reactive_power_mode.query_index, power_electronics_connection.inv_reactive_power_mode)
2031
+ insert.add_value(table.inv_fix_reactive_power.query_index, power_electronics_connection.inv_fix_reactive_power)
2032
+
2033
+ return self._save_regulating_cond_eq(table, insert, power_electronics_connection, "power electronics connection")
2034
+
2035
+ def save_power_electronics_connection_phase(self, power_electronics_connection_phase: PowerElectronicsConnectionPhase) -> bool:
2036
+ """
2037
+ Save the :class:`PowerElectronicsConnectionPhase` fields to :class:`TablePowerElectronicsConnectionPhases`.
2038
+
2039
+ :param power_electronics_connection_phase: The :class:`PowerElectronicsConnectionPhase` instance to write to the database.
2040
+ :return: True if the :class:`PowerElectronicsConnectionPhase` was successfully written to the database, otherwise False.
2041
+ :raises SqlException: For any errors encountered writing to the database.
2042
+ """
2043
+ table = self._database_tables.get_table(TablePowerElectronicsConnectionPhases)
2044
+ insert = self._database_tables.get_insert(TablePowerElectronicsConnectionPhases)
2045
+
2046
+ insert.add_value(
2047
+ table.power_electronics_connection_mrid.query_index,
2048
+ self._mrid_or_none(power_electronics_connection_phase.power_electronics_connection)
2049
+ )
2050
+ insert.add_value(table.p.query_index, power_electronics_connection_phase.p)
2051
+ insert.add_value(table.phase.query_index, power_electronics_connection_phase.phase.short_name)
2052
+ insert.add_value(table.q.query_index, power_electronics_connection_phase.q)
2053
+
2054
+ return self._save_power_system_resource(table, insert, power_electronics_connection_phase, "power electronics connection phase")
2055
+
2056
+ def save_power_transformer(self, power_transformer: PowerTransformer) -> bool:
2057
+ """
2058
+ Save the :class:`PowerTransformer` fields to :class:`TablePowerTransformers`.
2059
+
2060
+ :param power_transformer: The :class:`PowerTransformer` instance to write to the database.
2061
+ :return: True if the :class:`PowerTransformer` was successfully written to the database, otherwise False.
2062
+ :raises SqlException: For any errors encountered writing to the database.
2063
+ """
2064
+ table = self._database_tables.get_table(TablePowerTransformers)
2065
+ insert = self._database_tables.get_insert(TablePowerTransformers)
2066
+
2067
+ insert.add_value(table.vector_group.query_index, power_transformer.vector_group.short_name)
2068
+ insert.add_value(table.transformer_utilisation.query_index, power_transformer.transformer_utilisation)
2069
+ insert.add_value(table.construction_kind.query_index, power_transformer.construction_kind.short_name)
2070
+ insert.add_value(table.function.query_index, power_transformer.function.short_name)
2071
+ insert.add_value(table.power_transformer_info_mrid.query_index, self._mrid_or_none(power_transformer.power_transformer_info))
2072
+
2073
+ return self._save_conducting_equipment(table, insert, power_transformer, "power transformer")
2074
+
2075
+ def save_power_transformer_end(self, power_transformer_end: PowerTransformerEnd) -> bool:
2076
+ """
2077
+ Save the :class:`PowerTransformerEnd` fields to :class:`TablePowerTransformerEnds`.
2078
+
2079
+ :param power_transformer_end: The :class:`PowerTransformerEnd` instance to write to the database.
2080
+ :return: True if the :class:`PowerTransformerEnd` was successfully written to the database, otherwise False.
2081
+ :raises SqlException: For any errors encountered writing to the database.
2082
+ """
2083
+ table = self._database_tables.get_table(TablePowerTransformerEnds)
2084
+ insert = self._database_tables.get_insert(TablePowerTransformerEnds)
2085
+
2086
+ insert.add_value(table.power_transformer_mrid.query_index, self._mrid_or_none(power_transformer_end.power_transformer))
2087
+ insert.add_value(table.connection_kind.query_index, power_transformer_end.connection_kind.short_name)
2088
+ insert.add_value(table.phase_angle_clock.query_index, power_transformer_end.phase_angle_clock)
2089
+ insert.add_value(table.b.query_index, power_transformer_end.b)
2090
+ insert.add_value(table.b0.query_index, power_transformer_end.b0)
2091
+ insert.add_value(table.g.query_index, power_transformer_end.g)
2092
+ insert.add_value(table.g0.query_index, power_transformer_end.g0)
2093
+ insert.add_value(table.r.query_index, power_transformer_end.r)
2094
+ insert.add_value(table.r0.query_index, power_transformer_end.r0)
2095
+ insert.add_value(table.rated_u.query_index, power_transformer_end.rated_u)
2096
+ insert.add_value(table.x.query_index, power_transformer_end.x)
2097
+ insert.add_value(table.x0.query_index, power_transformer_end.x0)
2098
+
2099
+ ratings_table = self._database_tables.get_table(TablePowerTransformerEndRatings)
2100
+ ratings_insert = self._database_tables.get_insert(TablePowerTransformerEndRatings)
2101
+ for it in power_transformer_end.s_ratings:
2102
+ ratings_insert.add_value(ratings_table.power_transformer_end_mrid.query_index, power_transformer_end.mrid)
2103
+ ratings_insert.add_value(ratings_table.cooling_type.query_index, it.cooling_type.short_name)
2104
+ ratings_insert.add_value(ratings_table.rated_s.query_index, it.rated_s)
2105
+ self._try_execute_single_update(ratings_insert, "transformer end ratedS")
2106
+
2107
+ return self._save_transformer_end(table, insert, power_transformer_end, "power transformer end")
2108
+
2109
+ def _save_protected_switch(self, table: TableProtectedSwitches, insert: PreparedStatement, protected_switch: ProtectedSwitch, description: str) -> bool:
2110
+ insert.add_value(table.breaking_capacity.query_index, protected_switch.breaking_capacity)
2111
+
2112
+ return self._save_switch(table, insert, protected_switch, description)
2113
+
2114
+ def save_ratio_tap_changer(self, ratio_tap_changer: RatioTapChanger) -> bool:
2115
+ """
2116
+ Save the :class:`RatioTapChanger` fields to :class:`TableRatioTapChangers`.
2117
+
2118
+ :param ratio_tap_changer: The :class:`RatioTapChanger` instance to write to the database.
2119
+ :return: True if the :class:`RatioTapChanger` was successfully written to the database, otherwise False.
2120
+ :raises SqlException: For any errors encountered writing to the database.
2121
+ """
2122
+ table = self._database_tables.get_table(TableRatioTapChangers)
2123
+ insert = self._database_tables.get_insert(TableRatioTapChangers)
2124
+
2125
+ insert.add_value(table.transformer_end_mrid.query_index, self._mrid_or_none(ratio_tap_changer.transformer_end))
2126
+ insert.add_value(table.step_voltage_increment.query_index, ratio_tap_changer.step_voltage_increment)
2127
+
2128
+ return self._save_tap_changer(table, insert, ratio_tap_changer, "ratio tap changer")
2129
+
2130
+ def save_reactive_capability_curve(self, reactive_capability_curve: ReactiveCapabilityCurve) -> bool:
2131
+ """
2132
+ Save the :class:`ReactiveCapabilityCurve` fields to :class:`TableReactiveCapabilityCurves`.
2133
+
2134
+ :param reactive_capability_curve: The :class:`ReactiveCapabilityCurve` instance to write to the database.
2135
+
2136
+ :return: True if the :class:`ReactiveCapabilityCurve` was successfully written to the database, otherwise False.
2137
+ :raises SqlException: For any errors encountered writing to the database.
2138
+ """
2139
+ table = self._database_tables.get_table(TableReactiveCapabilityCurves)
2140
+ insert = self._database_tables.get_insert(TableReactiveCapabilityCurves)
2141
+
2142
+ return self._save_curve(table, insert, reactive_capability_curve, "reactive capability curve")
2143
+
2144
+ def save_recloser(self, recloser: Recloser) -> bool:
2145
+ """
2146
+ Save the :class:`Recloser` fields to :class:`TableReclosers`.
2147
+
2148
+ :param recloser: The :class:`Recloser` instance to write to the database.
2149
+ :return: True if the :class:`Recloser` was successfully written to the database, otherwise False.
2150
+ :raises SqlException: For any errors encountered writing to the database.
2151
+ """
2152
+ table = self._database_tables.get_table(TableReclosers)
2153
+ insert = self._database_tables.get_insert(TableReclosers)
2154
+
2155
+ return self._save_protected_switch(table, insert, recloser, "recloser")
2156
+
2157
+ def _save_regulating_cond_eq(
2158
+ self,
2159
+ table: TableRegulatingCondEq,
2160
+ insert: PreparedStatement,
2161
+ regulating_cond_eq: RegulatingCondEq,
2162
+ description: str
2163
+ ) -> bool:
2164
+ insert.add_value(table.control_enabled.query_index, regulating_cond_eq.control_enabled)
2165
+ insert.add_value(table.regulating_control_mrid.query_index, self._mrid_or_none(regulating_cond_eq.regulating_control))
2166
+
2167
+ return self._save_energy_connection(table, insert, regulating_cond_eq, description)
2168
+
2169
+ def _save_regulating_control(
2170
+ self,
2171
+ table: TableRegulatingControls,
2172
+ insert: PreparedStatement,
2173
+ regulating_control: RegulatingControl,
2174
+ description: str
2175
+ ) -> bool:
2176
+ insert.add_value(table.discrete.query_index, regulating_control.discrete)
2177
+ insert.add_value(table.mode.query_index, regulating_control.mode.short_name)
2178
+ insert.add_value(table.monitored_phase.query_index, regulating_control.monitored_phase.short_name)
2179
+ insert.add_value(table.target_deadband.query_index, regulating_control.target_deadband)
2180
+ insert.add_value(table.target_value.query_index, regulating_control.target_value)
2181
+ insert.add_value(table.enabled.query_index, regulating_control.enabled)
2182
+ insert.add_value(table.max_allowed_target_value.query_index, regulating_control.max_allowed_target_value)
2183
+ insert.add_value(table.min_allowed_target_value.query_index, regulating_control.min_allowed_target_value)
2184
+ insert.add_value(table.rated_current.query_index, regulating_control.rated_current)
2185
+ insert.add_value(table.terminal_mrid.query_index, self._mrid_or_none(regulating_control.terminal))
2186
+ insert.add_value(table.ct_primary.query_index, regulating_control.ct_primary)
2187
+ insert.add_value(table.min_target_deadband.query_index, regulating_control.min_target_deadband)
2188
+
2189
+ return self._save_power_system_resource(table, insert, regulating_control, description)
2190
+
2191
+ def _save_rotating_machine(
2192
+ self,
2193
+ table: TableRotatingMachines,
2194
+ insert: PreparedStatement,
2195
+ rotating_machine: RotatingMachine,
2196
+ description: str
2197
+ ) -> bool:
2198
+ insert.add_value(table.rated_power_factor.query_index, rotating_machine.rated_power_factor)
2199
+ insert.add_value(table.rated_s.query_index, rotating_machine.rated_s)
2200
+ insert.add_value(table.rated_u.query_index, rotating_machine.rated_u)
2201
+ insert.add_value(table.p.query_index, rotating_machine.p)
2202
+ insert.add_value(table.q.query_index, rotating_machine.q)
2203
+
2204
+ return self._save_regulating_cond_eq(table, insert, rotating_machine, description)
2205
+
2206
+ def save_series_compensator(self, series_compensator: SeriesCompensator) -> bool:
2207
+ """
2208
+ Save the :class:`SeriesCompensator` fields to :class:`TableSeriesCompensators`.
2209
+
2210
+ :param series_compensator: The :class:`SeriesCompensator` instance to write to the database.
2211
+ :return: True if the :class:`SeriesCompensator` was successfully written to the database, otherwise False.
2212
+ :raises SqlException: For any errors encountered writing to the database.
2213
+ """
2214
+ table = self._database_tables.get_table(TableSeriesCompensators)
2215
+ insert = self._database_tables.get_insert(TableSeriesCompensators)
2216
+
2217
+ insert.add_value(table.r.query_index, series_compensator.r)
2218
+ insert.add_value(table.r0.query_index, series_compensator.r0)
2219
+ insert.add_value(table.x.query_index, series_compensator.x)
2220
+ insert.add_value(table.x0.query_index, series_compensator.x0)
2221
+ insert.add_value(table.varistor_rated_current.query_index, series_compensator.varistor_rated_current)
2222
+ insert.add_value(table.varistor_voltage_threshold.query_index, series_compensator.varistor_voltage_threshold)
2223
+
2224
+ return self._save_conducting_equipment(table, insert, series_compensator, "series compensator")
2225
+
2226
+ def _save_shunt_compensator(
2227
+ self,
2228
+ table: TableShuntCompensators,
2229
+ insert: PreparedStatement,
2230
+ shunt_compensator: ShuntCompensator,
2231
+ description: str
2232
+ ) -> bool:
2233
+ insert.add_value(table.shunt_compensator_info_mrid.query_index, self._mrid_or_none(shunt_compensator.asset_info))
2234
+ insert.add_value(table.grounded.query_index, shunt_compensator.grounded)
2235
+ insert.add_value(table.nom_u.query_index, shunt_compensator.nom_u)
2236
+ insert.add_value(table.phase_connection.query_index, shunt_compensator.phase_connection.short_name)
2237
+ insert.add_value(table.sections.query_index, shunt_compensator.sections)
2238
+
2239
+ return self._save_regulating_cond_eq(table, insert, shunt_compensator, description)
2240
+
2241
+ def save_static_var_compensator(self, static_var_compensator: StaticVarCompensator) -> bool:
2242
+ """
2243
+ Save the :class:`StaticVarCompensator` fields to :class:`TableStaticVarCompensators`.
2244
+
2245
+ :param static_var_compensator: The :class:`StaticVarCompensator` instance to write to the database.
2246
+
2247
+ :return: True if the :class:`StaticVarCompensator` was successfully written to the database, otherwise False.
2248
+ :raises SqlException: For any errors encountered writing to the database.
2249
+ """
2250
+ table = self._database_tables.get_table(TableStaticVarCompensators)
2251
+ insert = self._database_tables.get_insert(TableStaticVarCompensators)
2252
+
2253
+ insert.add_value(table.capacitive_rating.query_index, static_var_compensator.capacitive_rating)
2254
+ insert.add_value(table.inductive_rating.query_index, static_var_compensator.inductive_rating)
2255
+ insert.add_value(table.q.query_index, static_var_compensator.q)
2256
+ insert.add_value(table.svc_control_mode.query_index, static_var_compensator.svc_control_mode.short_name)
2257
+ insert.add_value(table.voltage_set_point.query_index, static_var_compensator.voltage_set_point)
2258
+
2259
+ return self._save_regulating_cond_eq(table, insert, static_var_compensator, "static var compensator")
2260
+
2261
+ def _save_switch(self, table: TableSwitches, insert: PreparedStatement, switch: Switch, description: str) -> bool:
2262
+ # noinspection PyProtectedMember
2263
+ insert.add_value(table.normal_open.query_index, switch._normally_open)
2264
+ # noinspection PyProtectedMember
2265
+ insert.add_value(table.open.query_index, switch._open)
2266
+ insert.add_value(table.rated_current.query_index, switch.rated_current)
2267
+ insert.add_value(table.switch_info_mrid.query_index, self._mrid_or_none(switch.switch_info))
2268
+
2269
+ return self._save_conducting_equipment(table, insert, switch, description)
2270
+
2271
+ def save_synchronous_machine(self, synchronous_machine: SynchronousMachine) -> bool:
2272
+ """
2273
+ Save the :class:`SynchronousMachine` fields to :class:`TableSynchronousMachines`.
2274
+
2275
+ :param synchronous_machine: The :class:`SynchronousMachine` instance to write to the database.
2276
+
2277
+ @return true if the :class:`SynchronousMachine` was successfully written to the database, otherwise false.
2278
+ @throws SQLException For any errors encountered writing to the database.
2279
+ """
2280
+ table = self._database_tables.get_table(TableSynchronousMachines)
2281
+ insert = self._database_tables.get_insert(TableSynchronousMachines)
2282
+
2283
+ insert.add_value(table.base_q.query_index, synchronous_machine.base_q)
2284
+ insert.add_value(table.condenser_p.query_index, synchronous_machine.condenser_p)
2285
+ insert.add_value(table.earthing.query_index, synchronous_machine.earthing)
2286
+ insert.add_value(table.earthing_star_point_r.query_index, synchronous_machine.earthing_star_point_r)
2287
+ insert.add_value(table.earthing_star_point_x.query_index, synchronous_machine.earthing_star_point_x)
2288
+ insert.add_value(table.ikk.query_index, synchronous_machine.ikk)
2289
+ insert.add_value(table.max_q.query_index, synchronous_machine.max_q)
2290
+ insert.add_value(table.max_u.query_index, synchronous_machine.max_u)
2291
+ insert.add_value(table.min_q.query_index, synchronous_machine.min_q)
2292
+ insert.add_value(table.min_u.query_index, synchronous_machine.min_u)
2293
+ insert.add_value(table.mu.query_index, synchronous_machine.mu)
2294
+ insert.add_value(table.r.query_index, synchronous_machine.r)
2295
+ insert.add_value(table.r0.query_index, synchronous_machine.r0)
2296
+ insert.add_value(table.r2.query_index, synchronous_machine.r2)
2297
+ insert.add_value(table.sat_direct_subtrans_x.query_index, synchronous_machine.sat_direct_subtrans_x)
2298
+ insert.add_value(table.sat_direct_sync_x.query_index, synchronous_machine.sat_direct_sync_x)
2299
+ insert.add_value(table.sat_direct_trans_x.query_index, synchronous_machine.sat_direct_trans_x)
2300
+ insert.add_value(table.x0.query_index, synchronous_machine.x0)
2301
+ insert.add_value(table.x2.query_index, synchronous_machine.x2)
2302
+ insert.add_value(table.type.query_index, synchronous_machine.type.short_name)
2303
+ insert.add_value(table.operating_mode.query_index, synchronous_machine.operating_mode.short_name)
2304
+
2305
+ status = True
2306
+ for rcc in synchronous_machine.curves:
2307
+ status = status and self._save_synchronous_machine_to_reactive_capability_curve_association(synchronous_machine, rcc)
2308
+
2309
+ return status and self._save_rotating_machine(table, insert, synchronous_machine, "synchronous machine")
2310
+
2311
+ def _save_tap_changer(self, table: TableTapChangers, insert: PreparedStatement, tap_changer: TapChanger, description: str) -> bool:
2312
+ insert.add_value(table.control_enabled.query_index, tap_changer.control_enabled)
2313
+ insert.add_value(table.high_step.query_index, tap_changer.high_step)
2314
+ insert.add_value(table.low_step.query_index, tap_changer.low_step)
2315
+ insert.add_value(table.neutral_step.query_index, tap_changer.neutral_step)
2316
+ insert.add_value(table.neutral_u.query_index, tap_changer.neutral_u)
2317
+ insert.add_value(table.normal_step.query_index, tap_changer.normal_step)
2318
+ insert.add_value(table.step.query_index, tap_changer.step)
2319
+ insert.add_value(table.tap_changer_control_mrid.query_index, self._mrid_or_none(tap_changer.tap_changer_control))
2320
+
2321
+ return self._save_power_system_resource(table, insert, tap_changer, description)
2322
+
2323
+ def save_tap_changer_control(self, tap_changer_control: TapChangerControl) -> bool:
2324
+ """
2325
+ Save the :class:`TapChangerControl` fields to :class:`TableTapChangerControls`.
2326
+
2327
+ :param tap_changer_control: The :class:`TapChangerControl` instance to write to the database.
2328
+ :return: True if the :class:`TapChangerControl` was successfully written to the database, otherwise False.
2329
+ :raises SqlException: For any errors encountered writing to the database.
2330
+ """
2331
+ table = self._database_tables.get_table(TableTapChangerControls)
2332
+ insert = self._database_tables.get_insert(TableTapChangerControls)
2333
+
2334
+ insert.add_value(table.limit_voltage.query_index, tap_changer_control.limit_voltage)
2335
+ insert.add_value(table.line_drop_compensation.query_index, tap_changer_control.line_drop_compensation)
2336
+ insert.add_value(table.line_drop_r.query_index, tap_changer_control.line_drop_r)
2337
+ insert.add_value(table.line_drop_x.query_index, tap_changer_control.line_drop_x)
2338
+ insert.add_value(table.reverse_line_drop_r.query_index, tap_changer_control.reverse_line_drop_r)
2339
+ insert.add_value(table.reverse_line_drop_x.query_index, tap_changer_control.reverse_line_drop_x)
2340
+ insert.add_value(table.forward_ldc_blocking.query_index, tap_changer_control.forward_ldc_blocking)
2341
+ insert.add_value(table.time_delay.query_index, tap_changer_control.time_delay)
2342
+ insert.add_value(table.co_generation_enabled.query_index, tap_changer_control.co_generation_enabled)
2343
+
2344
+ return self._save_regulating_control(table, insert, tap_changer_control, "tap changer control")
2345
+
2346
+ def _save_transformer_end(
2347
+ self,
2348
+ table: TableTransformerEnds,
2349
+ insert: PreparedStatement,
2350
+ transformer_end: TransformerEnd,
2351
+ description: str
2352
+ ) -> bool:
2353
+ insert.add_value(table.end_number.query_index, transformer_end.end_number)
2354
+ insert.add_value(table.terminal_mrid.query_index, self._mrid_or_none(transformer_end.terminal))
2355
+ insert.add_value(table.base_voltage_mrid.query_index, self._mrid_or_none(transformer_end.base_voltage))
2356
+ insert.add_value(table.grounded.query_index, transformer_end.grounded)
2357
+ insert.add_value(table.r_ground.query_index, transformer_end.r_ground)
2358
+ insert.add_value(table.x_ground.query_index, transformer_end.x_ground)
2359
+ insert.add_value(table.star_impedance_mrid.query_index, self._mrid_or_none(transformer_end.star_impedance))
2360
+
2361
+ return self._save_identified_object(table, insert, transformer_end, description)
2362
+
2363
+ def save_transformer_star_impedance(self, transformer_star_impedance: TransformerStarImpedance) -> bool:
2364
+ """
2365
+ Save the :class:`TransformerStarImpedance` fields to :class:`TableTransformerStarImpedances`.
2366
+
2367
+ :param transformer_star_impedance: The :class:`TransformerStarImpedance` instance to write to the database.
2368
+ :return: True if the :class:`TransformerStarImpedance` was successfully written to the database, otherwise False.
2369
+ :raises SqlException: For any errors encountered writing to the database.
2370
+ """
2371
+ table = self._database_tables.get_table(TableTransformerStarImpedances)
2372
+ insert = self._database_tables.get_insert(TableTransformerStarImpedances)
2373
+
2374
+ insert.add_value(table.r.query_index, transformer_star_impedance.r)
2375
+ insert.add_value(table.r0.query_index, transformer_star_impedance.r0)
2376
+ insert.add_value(table.x.query_index, transformer_star_impedance.x)
2377
+ insert.add_value(table.x0.query_index, transformer_star_impedance.x0)
2378
+ insert.add_value(table.transformer_end_info_mrid.query_index, self._mrid_or_none(transformer_star_impedance.transformer_end_info))
2379
+
2380
+ return self._save_identified_object(table, insert, transformer_star_impedance, "transformer star impedance")
2381
+
2382
+ ###############################
2383
+ # IEC61970 InfIEC61970 Feeder #
2384
+ ###############################
2385
+
2386
+ def save_circuit(self, circuit: Circuit) -> bool:
2387
+ """
2388
+ Save the :class:`Circuit` fields to :class:`TableCircuits`.
2389
+
2390
+ :param circuit: The :class:`Circuit` instance to write to the database.
2391
+ :return: True if the :class:`Circuit` was successfully written to the database, otherwise False.
2392
+ :raises SqlException: For any errors encountered writing to the database.
2393
+ """
2394
+ table = self._database_tables.get_table(TableCircuits)
2395
+ insert = self._database_tables.get_insert(TableCircuits)
2396
+
2397
+ insert.add_value(table.loop_mrid.query_index, self._mrid_or_none(circuit.loop))
2398
+
2399
+ status = True
2400
+ for it in circuit.end_substations:
2401
+ status = status and self._save_circuit_to_substation_association(circuit, it)
2402
+ for it in circuit.end_terminals:
2403
+ status = status and self._save_circuit_to_terminal_association(circuit, it)
2404
+
2405
+ return status and self._save_line(table, insert, circuit, "circuit")
2406
+
2407
+ ################
2408
+ # ASSOCIATIONS #
2409
+ ################
2410
+
2411
+ def _save_asset_organisation_role_to_asset_association(self, asset_organisation_role: AssetOrganisationRole, asset: Asset) -> bool:
2412
+ table = self._database_tables.get_table(TableAssetOrganisationRolesAssets)
2413
+ insert = self._database_tables.get_insert(TableAssetOrganisationRolesAssets)
2414
+
2415
+ insert.add_value(table.asset_organisation_role_mrid.query_index, asset_organisation_role.mrid)
2416
+ insert.add_value(table.asset_mrid.query_index, asset.mrid)
2417
+
2418
+ return self._try_execute_single_update(insert, "asset organisation role to asset association")
2419
+
2420
+ def _save_asset_to_power_system_resource_association(self, power_system_resource: PowerSystemResource, asset: Asset) -> bool:
2421
+ table = self._database_tables.get_table(TableAssetsPowerSystemResources)
2422
+ insert = self._database_tables.get_insert(TableAssetsPowerSystemResources)
2423
+
2424
+ insert.add_value(table.asset_mrid.query_index, asset.mrid)
2425
+ insert.add_value(table.power_system_resource_mrid.query_index, power_system_resource.mrid)
2426
+
2427
+ return self._try_execute_single_update(insert, "asset to power system resource association")
2428
+
2429
+ def _save_battery_unit_to_battery_control_association(self, battery_unit: BatteryUnit, battery_control: BatteryControl) -> bool:
2430
+ table = self._database_tables.get_table(TableBatteryUnitsBatteryControls)
2431
+ insert = self._database_tables.get_insert(TableBatteryUnitsBatteryControls)
2432
+
2433
+ insert.add_value(table.battery_unit_mrid.query_index, battery_unit.mrid)
2434
+ insert.add_value(table.battery_control_mrid.query_index, battery_control.mrid)
2435
+
2436
+ return self._try_execute_single_update(insert, "battery control to battery unit association")
2437
+
2438
+ def _save_circuit_to_substation_association(self, circuit: Circuit, substation: Substation) -> bool:
2439
+ table = self._database_tables.get_table(TableCircuitsSubstations)
2440
+ insert = self._database_tables.get_insert(TableCircuitsSubstations)
2441
+
2442
+ insert.add_value(table.circuit_mrid.query_index, circuit.mrid)
2443
+ insert.add_value(table.substation_mrid.query_index, substation.mrid)
2444
+
2445
+ return self._try_execute_single_update(insert, "circuit to substation association")
2446
+
2447
+ def _save_circuit_to_terminal_association(self, circuit: Circuit, terminal: Terminal) -> bool:
2448
+ table = self._database_tables.get_table(TableCircuitsTerminals)
2449
+ insert = self._database_tables.get_insert(TableCircuitsTerminals)
2450
+
2451
+ insert.add_value(table.circuit_mrid.query_index, circuit.mrid)
2452
+ insert.add_value(table.terminal_mrid.query_index, terminal.mrid)
2453
+
2454
+ return self._try_execute_single_update(insert, "circuit to terminal association")
2455
+
2456
+ def _save_end_device_function_to_end_device_association(self, end_device_function: EndDeviceFunction, end_device: EndDevice) -> bool:
2457
+ table = self._database_tables.get_table(TableEndDevicesEndDeviceFunctions)
2458
+ insert = self._database_tables.get_insert(TableEndDevicesEndDeviceFunctions)
2459
+
2460
+ insert.add_value(table.end_device_function_mrid.query_index, end_device_function.mrid)
2461
+ insert.add_value(table.end_device_mrid.query_index, end_device.mrid)
2462
+
2463
+ return self._try_execute_single_update(insert, "end device function to end device association")
2464
+
2465
+ def _save_equipment_to_equipment_container_association(self, equipment: Equipment, equipment_container: EquipmentContainer) -> bool:
2466
+ table = self._database_tables.get_table(TableEquipmentEquipmentContainers)
2467
+ insert = self._database_tables.get_insert(TableEquipmentEquipmentContainers)
2468
+
2469
+ insert.add_value(table.equipment_mrid.query_index, equipment.mrid)
2470
+ insert.add_value(table.equipment_container_mrid.query_index, equipment_container.mrid)
2471
+
2472
+ return self._try_execute_single_update(insert, "equipment to equipment container association")
2473
+
2474
+ def _save_equipment_to_operational_restriction_association(self, equipment: Equipment, operational_restriction: OperationalRestriction) -> bool:
2475
+ table = self._database_tables.get_table(TableEquipmentOperationalRestrictions)
2476
+ insert = self._database_tables.get_insert(TableEquipmentOperationalRestrictions)
2477
+
2478
+ insert.add_value(table.equipment_mrid.query_index, equipment.mrid)
2479
+ insert.add_value(table.operational_restriction_mrid.query_index, operational_restriction.mrid)
2480
+
2481
+ return self._try_execute_single_update(insert, "equipment to operational restriction association")
2482
+
2483
+ def _save_equipment_to_usage_point_association(self, equipment: Equipment, usage_point: UsagePoint) -> bool:
2484
+ table = self._database_tables.get_table(TableEquipmentUsagePoints)
2485
+ insert = self._database_tables.get_insert(TableEquipmentUsagePoints)
2486
+
2487
+ insert.add_value(table.equipment_mrid.query_index, equipment.mrid)
2488
+ insert.add_value(table.usage_point_mrid.query_index, usage_point.mrid)
2489
+
2490
+ return self._try_execute_single_update(insert, "equipment to usage point association")
2491
+
2492
+ def _save_loop_to_substation_association(self, loop: Loop, substation: Substation, relationship: LoopSubstationRelationship) -> bool:
2493
+ table = self._database_tables.get_table(TableLoopsSubstations)
2494
+ insert = self._database_tables.get_insert(TableLoopsSubstations)
2495
+
2496
+ insert.add_value(table.loop_mrid.query_index, loop.mrid)
2497
+ insert.add_value(table.substation_mrid.query_index, substation.mrid)
2498
+ insert.add_value(table.relationship.query_index, relationship.short_name)
2499
+
2500
+ return self._try_execute_single_update(insert, "loop to substation association")
2501
+
2502
+ def _save_protection_relay_function_to_protected_switch_association(
2503
+ self,
2504
+ protection_relay_function: ProtectionRelayFunction,
2505
+ protected_switch: ProtectedSwitch
2506
+ ) -> bool:
2507
+ table = self._database_tables.get_table(TableProtectionRelayFunctionsProtectedSwitches)
2508
+ insert = self._database_tables.get_insert(TableProtectionRelayFunctionsProtectedSwitches)
2509
+
2510
+ insert.add_value(table.protection_relay_function_mrid.query_index, protection_relay_function.mrid)
2511
+ insert.add_value(table.protected_switch_mrid.query_index, protected_switch.mrid)
2512
+
2513
+ return self._try_execute_single_update(insert, "protection relay function to protected switch association")
2514
+
2515
+ def _save_protection_relay_function_to_sensor_association(self, protection_relay_function: ProtectionRelayFunction, sensor: Sensor) -> bool:
2516
+ table = self._database_tables.get_table(TableProtectionRelayFunctionsSensors)
2517
+ insert = self._database_tables.get_insert(TableProtectionRelayFunctionsSensors)
2518
+
2519
+ insert.add_value(table.protection_relay_function_mrid.query_index, protection_relay_function.mrid)
2520
+ insert.add_value(table.sensor_mrid.query_index, sensor.mrid)
2521
+
2522
+ return self._try_execute_single_update(insert, "protection relay function to sensor association")
2523
+
2524
+ def _save_protection_relay_scheme_to_protection_relay_function_association(
2525
+ self,
2526
+ protection_relay_scheme: ProtectionRelayScheme,
2527
+ protection_relay_function: ProtectionRelayFunction
2528
+ ) -> bool:
2529
+ table = self._database_tables.get_table(TableProtectionRelaySchemesProtectionRelayFunctions)
2530
+ insert = self._database_tables.get_insert(TableProtectionRelaySchemesProtectionRelayFunctions)
2531
+
2532
+ insert.add_value(table.protection_relay_scheme_mrid.query_index, protection_relay_scheme.mrid)
2533
+ insert.add_value(table.protection_relay_function_mrid.query_index, protection_relay_function.mrid)
2534
+
2535
+ return self._try_execute_single_update(insert, "protection relay function to protection relay function association")
2536
+
2537
+ def _save_synchronous_machine_to_reactive_capability_curve_association(
2538
+ self,
2539
+ synchronous_machine: SynchronousMachine,
2540
+ reactive_capability_curve: ReactiveCapabilityCurve
2541
+ ) -> bool:
2542
+ table = self._database_tables.get_table(TableSynchronousMachinesReactiveCapabilityCurves)
2543
+ insert = self._database_tables.get_insert(TableSynchronousMachinesReactiveCapabilityCurves)
2544
+
2545
+ insert.add_value(table.synchronous_machine_mrid.query_index, synchronous_machine.mrid)
2546
+ insert.add_value(table.reactive_capability_curve_mrid.query_index, reactive_capability_curve.mrid)
2547
+
2548
+ return self._try_execute_single_update(insert, "synchronous machine to reactivity curve association")
2549
+
2550
+ def _save_usage_point_to_end_device_association(self, usage_point: UsagePoint, end_device: EndDevice) -> bool:
2551
+ table = self._database_tables.get_table(TableUsagePointsEndDevices)
2552
+ insert = self._database_tables.get_insert(TableUsagePointsEndDevices)
2553
+
2554
+ insert.add_value(table.usage_point_mrid.query_index, usage_point.mrid)
2555
+ insert.add_value(table.end_device_mrid.query_index, end_device.mrid)
2556
+
2557
+ return self._try_execute_single_update(insert, "usage point to end device association")
2558
+
2559
+ @staticmethod
2560
+ def _should_export_container_contents(ec: EquipmentContainer) -> bool:
2561
+ return isinstance(ec, Site) or isinstance(ec, Substation) or isinstance(ec, Circuit)