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.
- zepben/ewb/__init__.py +601 -0
- zepben/ewb/auth/__init__.py +10 -0
- zepben/ewb/auth/client/__init__.py +5 -0
- zepben/ewb/auth/client/zepben_token_fetcher.py +273 -0
- zepben/ewb/auth/common/__init__.py +5 -0
- zepben/ewb/auth/common/auth_exception.py +16 -0
- zepben/ewb/auth/common/auth_method.py +28 -0
- zepben/ewb/auth/common/auth_provider_config.py +96 -0
- zepben/ewb/database/__init__.py +4 -0
- zepben/ewb/database/paths/__init__.py +4 -0
- zepben/ewb/database/paths/database_type.py +34 -0
- zepben/ewb/database/paths/ewb_data_file_paths.py +237 -0
- zepben/ewb/database/sql/__init__.py +4 -0
- zepben/ewb/database/sql/column.py +37 -0
- zepben/ewb/database/sql/sql_table.py +142 -0
- zepben/ewb/database/sqlite/__init__.py +4 -0
- zepben/ewb/database/sqlite/common/__init__.py +4 -0
- zepben/ewb/database/sqlite/common/base_cim_reader.py +212 -0
- zepben/ewb/database/sqlite/common/base_cim_writer.py +159 -0
- zepben/ewb/database/sqlite/common/base_collection_reader.py +96 -0
- zepben/ewb/database/sqlite/common/base_collection_writer.py +73 -0
- zepben/ewb/database/sqlite/common/base_database_reader.py +127 -0
- zepben/ewb/database/sqlite/common/base_database_tables.py +137 -0
- zepben/ewb/database/sqlite/common/base_database_writer.py +195 -0
- zepben/ewb/database/sqlite/common/base_entry_writer.py +34 -0
- zepben/ewb/database/sqlite/common/base_service_reader.py +50 -0
- zepben/ewb/database/sqlite/common/base_service_writer.py +104 -0
- zepben/ewb/database/sqlite/common/metadata_collection_reader.py +39 -0
- zepben/ewb/database/sqlite/common/metadata_collection_writer.py +38 -0
- zepben/ewb/database/sqlite/common/metadata_entry_reader.py +45 -0
- zepben/ewb/database/sqlite/common/metadata_entry_writer.py +41 -0
- zepben/ewb/database/sqlite/common/reader_exceptions.py +30 -0
- zepben/ewb/database/sqlite/customer/__init__.py +4 -0
- zepben/ewb/database/sqlite/customer/customer_cim_reader.py +169 -0
- zepben/ewb/database/sqlite/customer/customer_cim_writer.py +137 -0
- zepben/ewb/database/sqlite/customer/customer_database_reader.py +44 -0
- zepben/ewb/database/sqlite/customer/customer_database_tables.py +37 -0
- zepben/ewb/database/sqlite/customer/customer_database_writer.py +45 -0
- zepben/ewb/database/sqlite/customer/customer_service_reader.py +57 -0
- zepben/ewb/database/sqlite/customer/customer_service_writer.py +47 -0
- zepben/ewb/database/sqlite/diagram/__init__.py +4 -0
- zepben/ewb/database/sqlite/diagram/diagram_cim_reader.py +105 -0
- zepben/ewb/database/sqlite/diagram/diagram_cim_writer.py +81 -0
- zepben/ewb/database/sqlite/diagram/diagram_database_reader.py +45 -0
- zepben/ewb/database/sqlite/diagram/diagram_database_tables.py +29 -0
- zepben/ewb/database/sqlite/diagram/diagram_database_writer.py +44 -0
- zepben/ewb/database/sqlite/diagram/diagram_service_reader.py +49 -0
- zepben/ewb/database/sqlite/diagram/diagram_service_writer.py +41 -0
- zepben/ewb/database/sqlite/extensions/__init__.py +4 -0
- zepben/ewb/database/sqlite/extensions/prepared_statement.py +112 -0
- zepben/ewb/database/sqlite/extensions/result_set.py +153 -0
- zepben/ewb/database/sqlite/network/__init__.py +4 -0
- zepben/ewb/database/sqlite/network/network_cim_reader.py +3167 -0
- zepben/ewb/database/sqlite/network/network_cim_writer.py +2561 -0
- zepben/ewb/database/sqlite/network/network_database_reader.py +175 -0
- zepben/ewb/database/sqlite/network/network_database_tables.py +242 -0
- zepben/ewb/database/sqlite/network/network_database_writer.py +43 -0
- zepben/ewb/database/sqlite/network/network_service_reader.py +265 -0
- zepben/ewb/database/sqlite/network/network_service_writer.py +209 -0
- zepben/ewb/database/sqlite/tables/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/associations/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/associations/loop_substation_relationship.py +17 -0
- zepben/ewb/database/sqlite/tables/associations/table_asset_organisation_roles_assets.py +40 -0
- zepben/ewb/database/sqlite/tables/associations/table_assets_power_system_resources.py +41 -0
- zepben/ewb/database/sqlite/tables/associations/table_battery_units_battery_controls.py +40 -0
- zepben/ewb/database/sqlite/tables/associations/table_circuits_substations.py +40 -0
- zepben/ewb/database/sqlite/tables/associations/table_circuits_terminals.py +40 -0
- zepben/ewb/database/sqlite/tables/associations/table_customer_agreements_pricing_structures.py +40 -0
- zepben/ewb/database/sqlite/tables/associations/table_end_devices_end_device_functions.py +40 -0
- zepben/ewb/database/sqlite/tables/associations/table_equipment_equipment_containers.py +40 -0
- zepben/ewb/database/sqlite/tables/associations/table_equipment_operational_restrictions.py +40 -0
- zepben/ewb/database/sqlite/tables/associations/table_equipment_usage_points.py +40 -0
- zepben/ewb/database/sqlite/tables/associations/table_loops_substations.py +43 -0
- zepben/ewb/database/sqlite/tables/associations/table_pricing_structures_tariffs.py +40 -0
- zepben/ewb/database/sqlite/tables/associations/table_protection_relay_functions_protected_switches.py +40 -0
- zepben/ewb/database/sqlite/tables/associations/table_protection_relay_functions_sensors.py +40 -0
- zepben/ewb/database/sqlite/tables/associations/table_protection_relay_schemes_protection_relay_functions.py +40 -0
- zepben/ewb/database/sqlite/tables/associations/table_synchronous_machines_reactive_capability_curves.py +39 -0
- zepben/ewb/database/sqlite/tables/associations/table_usage_points_end_devices.py +40 -0
- zepben/ewb/database/sqlite/tables/exceptions.py +10 -0
- zepben/ewb/database/sqlite/tables/extensions/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61968/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61968/assetinfo/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61968/assetinfo/table_reclose_delays.py +38 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61968/assetinfo/table_relay_info.py +21 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61968/metering/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61968/metering/table_pan_demand_response_functions.py +21 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/core/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/core/table_sites.py +15 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/feeder/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/feeder/table_loops.py +15 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/feeder/table_lv_feeders.py +20 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/generation/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/generation/production/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/generation/production/table_ev_charging_units.py +15 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/table_distance_relays.py +28 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/table_protection_relay_function_thresholds.py +36 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/table_protection_relay_function_time_limits.py +34 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/table_protection_relay_functions.py +24 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/table_protection_relay_schemes.py +20 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/table_protection_relay_systems.py +20 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/protection/table_voltage_relays.py +15 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/wires/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/wires/table_battery_controls.py +23 -0
- zepben/ewb/database/sqlite/tables/extensions/iec61970/base/wires/table_power_transformer_end_ratings.py +34 -0
- zepben/ewb/database/sqlite/tables/iec61968/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61968/assetinfo/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_cable_info.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_no_load_tests.py +24 -0
- zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_open_circuit_tests.py +24 -0
- zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_overhead_wire_info.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_power_transformer_info.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_short_circuit_tests.py +29 -0
- zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_shunt_compensator_info.py +23 -0
- zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_switch_info.py +20 -0
- zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_transformer_end_info.py +46 -0
- zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_transformer_tank_info.py +27 -0
- zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_transformer_test.py +19 -0
- zepben/ewb/database/sqlite/tables/iec61968/assetinfo/table_wire_info.py +19 -0
- zepben/ewb/database/sqlite/tables/iec61968/assets/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61968/assets/table_asset_containers.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61968/assets/table_asset_functions.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61968/assets/table_asset_info.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61968/assets/table_asset_organisation_roles.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61968/assets/table_asset_owners.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61968/assets/table_assets.py +18 -0
- zepben/ewb/database/sqlite/tables/iec61968/assets/table_streetlights.py +22 -0
- zepben/ewb/database/sqlite/tables/iec61968/assets/table_structures.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61968/common/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61968/common/table_agreements.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61968/common/table_documents.py +23 -0
- zepben/ewb/database/sqlite/tables/iec61968/common/table_location_street_address_field.py +18 -0
- zepben/ewb/database/sqlite/tables/iec61968/common/table_location_street_addresses.py +33 -0
- zepben/ewb/database/sqlite/tables/iec61968/common/table_locations.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61968/common/table_organisation_roles.py +18 -0
- zepben/ewb/database/sqlite/tables/iec61968/common/table_organisations.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61968/common/table_position_points.py +30 -0
- zepben/ewb/database/sqlite/tables/iec61968/common/table_street_addresses.py +26 -0
- zepben/ewb/database/sqlite/tables/iec61968/common/table_town_details.py +19 -0
- zepben/ewb/database/sqlite/tables/iec61968/customers/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61968/customers/table_customer_agreements.py +27 -0
- zepben/ewb/database/sqlite/tables/iec61968/customers/table_customers.py +22 -0
- zepben/ewb/database/sqlite/tables/iec61968/customers/table_pricing_structures.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61968/customers/table_tariffs.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61968/infiec61968/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61968/infiec61968/infassetinfo/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61968/infiec61968/infassetinfo/table_current_transformer_info.py +33 -0
- zepben/ewb/database/sqlite/tables/iec61968/infiec61968/infassetinfo/table_potential_transformer_info.py +26 -0
- zepben/ewb/database/sqlite/tables/iec61968/infiec61968/infassets/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61968/infiec61968/infassets/table_poles.py +20 -0
- zepben/ewb/database/sqlite/tables/iec61968/metering/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61968/metering/table_end_device_functions.py +18 -0
- zepben/ewb/database/sqlite/tables/iec61968/metering/table_end_devices.py +19 -0
- zepben/ewb/database/sqlite/tables/iec61968/metering/table_meters.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61968/metering/table_usage_points.py +23 -0
- zepben/ewb/database/sqlite/tables/iec61968/operations/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61968/operations/table_operational_restrictions.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/auxiliaryequipment/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/auxiliaryequipment/table_auxiliary_equipment.py +18 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/auxiliaryequipment/table_current_transformers.py +21 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/auxiliaryequipment/table_fault_indicators.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/auxiliaryequipment/table_potential_transformers.py +21 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/auxiliaryequipment/table_sensors.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_ac_dc_terminals.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_base_voltages.py +20 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_conducting_equipment.py +18 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_connectivity_node_containers.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_connectivity_nodes.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_curve_data.py +46 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_curves.py +17 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_equipment.py +20 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_equipment_containers.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_feeders.py +28 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_geographical_regions.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_identified_objects.py +29 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_name_types.py +28 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_names.py +36 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_power_system_resources.py +19 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_sub_geographical_regions.py +27 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_substations.py +27 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/core/table_terminals.py +35 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/diagramlayout/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/diagramlayout/table_diagram_object_points.py +35 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/diagramlayout/table_diagram_objects.py +31 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/diagramlayout/table_diagrams.py +21 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/equivalents/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/equivalents/table_equivalent_branches.py +35 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/equivalents/table_equivalent_equipment.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/generation/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/generation/production/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/generation/production/table_battery_units.py +22 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/generation/production/table_photo_voltaic_units.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/generation/production/table_power_electronics_units.py +26 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/generation/production/table_power_electronics_wind_units.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/meas/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/meas/table_accumulators.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/meas/table_analogs.py +20 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/meas/table_controls.py +20 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/meas/table_discretes.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/meas/table_io_points.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/meas/table_measurements.py +30 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/protection/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/protection/table_current_relays.py +22 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/scada/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/scada/table_remote_controls.py +20 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/scada/table_remote_points.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/scada/table_remote_sources.py +20 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_ac_line_segments.py +20 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_breakers.py +20 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_busbar_sections.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_clamps.py +23 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_conductors.py +21 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_connectors.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_cuts.py +23 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_disconnectors.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_earth_fault_compensators.py +22 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_energy_connections.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_energy_consumer_phases.py +37 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_energy_consumers.py +26 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_energy_source_phases.py +33 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_energy_sources.py +44 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_fuses.py +20 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_ground_disconnectors.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_grounding_impedances.py +24 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_grounds.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_jumpers.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_junctions.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_linear_shunt_compensators.py +23 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_lines.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_load_break_switches.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_per_length_impedances.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_per_length_line_parameters.py +14 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_per_length_phase_impedances.py +18 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_per_length_sequence_impedances.py +27 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_petersen_coils.py +27 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_phase_impedance_data.py +52 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_power_electronics_connection_phases.py +30 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_power_electronics_connections.py +50 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_power_transformer_ends.py +43 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_power_transformers.py +24 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_protected_switches.py +18 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_ratio_tap_changers.py +28 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_reactive_capability_curves.py +18 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_reclosers.py +15 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_regulating_cond_eq.py +19 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_regulating_controls.py +29 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_rotating_machines.py +36 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_series_compensators.py +25 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_shunt_compensators.py +22 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_static_var_compensator.py +24 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_switches.py +21 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_synchronous_machines.py +95 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_tap_changer_controls.py +28 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_tap_changers.py +25 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_transformer_ends.py +30 -0
- zepben/ewb/database/sqlite/tables/iec61970/base/wires/table_transformer_star_impedances.py +32 -0
- zepben/ewb/database/sqlite/tables/iec61970/infiec61970/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61970/infiec61970/feeder/__init__.py +4 -0
- zepben/ewb/database/sqlite/tables/iec61970/infiec61970/feeder/table_circuits.py +27 -0
- zepben/ewb/database/sqlite/tables/sqlite_table.py +45 -0
- zepben/ewb/database/sqlite/tables/table_metadata_data_sources.py +21 -0
- zepben/ewb/database/sqlite/tables/table_version.py +39 -0
- zepben/ewb/dataclassy/__init__.py +15 -0
- zepben/ewb/dataclassy/dataclass.py +192 -0
- zepben/ewb/dataclassy/decorator.py +35 -0
- zepben/ewb/dataclassy/functions.py +80 -0
- zepben/ewb/examples/__init__.py +6 -0
- zepben/ewb/examples/simple_test_network.py +158 -0
- zepben/ewb/exceptions.py +52 -0
- zepben/ewb/model/__init__.py +4 -0
- zepben/ewb/model/busbranch/__init__.py +4 -0
- zepben/ewb/model/busbranch/bus_branch.py +1051 -0
- zepben/ewb/model/cim/__init__.py +4 -0
- zepben/ewb/model/cim/extensions/__init__.py +4 -0
- zepben/ewb/model/cim/extensions/iec61968/__init__.py +4 -0
- zepben/ewb/model/cim/extensions/iec61968/assetinfo/__init__.py +4 -0
- zepben/ewb/model/cim/extensions/iec61968/assetinfo/relay_info.py +128 -0
- zepben/ewb/model/cim/extensions/iec61968/metering/__init__.py +4 -0
- zepben/ewb/model/cim/extensions/iec61968/metering/pan_demand_reponse_function.py +112 -0
- zepben/ewb/model/cim/extensions/iec61970/__init__.py +4 -0
- zepben/ewb/model/cim/extensions/iec61970/base/__init__.py +4 -0
- zepben/ewb/model/cim/extensions/iec61970/base/core/__init__.py +4 -0
- zepben/ewb/model/cim/extensions/iec61970/base/core/site.py +37 -0
- zepben/ewb/model/cim/extensions/iec61970/base/feeder/__init__.py +4 -0
- zepben/ewb/model/cim/extensions/iec61970/base/feeder/loop.py +207 -0
- zepben/ewb/model/cim/extensions/iec61970/base/feeder/lv_feeder.py +258 -0
- zepben/ewb/model/cim/extensions/iec61970/base/generation/__init__.py +4 -0
- zepben/ewb/model/cim/extensions/iec61970/base/generation/production/__init__.py +4 -0
- zepben/ewb/model/cim/extensions/iec61970/base/generation/production/ev_charging_unit.py +18 -0
- zepben/ewb/model/cim/extensions/iec61970/base/protection/__init__.py +4 -0
- zepben/ewb/model/cim/extensions/iec61970/base/protection/distance_relay.py +69 -0
- zepben/ewb/model/cim/extensions/iec61970/base/protection/power_direction_kind.py +36 -0
- zepben/ewb/model/cim/extensions/iec61970/base/protection/protection_kind.py +112 -0
- zepben/ewb/model/cim/extensions/iec61970/base/protection/protection_relay_function.py +448 -0
- zepben/ewb/model/cim/extensions/iec61970/base/protection/protection_relay_scheme.py +97 -0
- zepben/ewb/model/cim/extensions/iec61970/base/protection/protection_relay_system.py +97 -0
- zepben/ewb/model/cim/extensions/iec61970/base/protection/relay_setting.py +35 -0
- zepben/ewb/model/cim/extensions/iec61970/base/protection/voltage_relay.py +20 -0
- zepben/ewb/model/cim/extensions/iec61970/base/wires/__init__.py +4 -0
- zepben/ewb/model/cim/extensions/iec61970/base/wires/battery_control.py +36 -0
- zepben/ewb/model/cim/extensions/iec61970/base/wires/battery_control_mode.py +83 -0
- zepben/ewb/model/cim/extensions/iec61970/base/wires/transformer_cooling_type.py +57 -0
- zepben/ewb/model/cim/extensions/iec61970/base/wires/transformer_end_rated_s.py +26 -0
- zepben/ewb/model/cim/extensions/iec61970/base/wires/vector_group.py +293 -0
- zepben/ewb/model/cim/extensions/zbex.py +17 -0
- zepben/ewb/model/cim/iec61968/__init__.py +4 -0
- zepben/ewb/model/cim/iec61968/assetinfo/__init__.py +4 -0
- zepben/ewb/model/cim/iec61968/assetinfo/cable_info.py +15 -0
- zepben/ewb/model/cim/iec61968/assetinfo/no_load_test.py +42 -0
- zepben/ewb/model/cim/iec61968/assetinfo/open_circuit_test.py +42 -0
- zepben/ewb/model/cim/iec61968/assetinfo/overhead_wire_info.py +15 -0
- zepben/ewb/model/cim/iec61968/assetinfo/power_transformer_info.py +103 -0
- zepben/ewb/model/cim/iec61968/assetinfo/short_circuit_test.py +67 -0
- zepben/ewb/model/cim/iec61968/assetinfo/shunt_compensator_info.py +26 -0
- zepben/ewb/model/cim/iec61968/assetinfo/switch_info.py +17 -0
- zepben/ewb/model/cim/iec61968/assetinfo/transformer_end_info.py +137 -0
- zepben/ewb/model/cim/iec61968/assetinfo/transformer_tank_info.py +108 -0
- zepben/ewb/model/cim/iec61968/assetinfo/transformer_test.py +26 -0
- zepben/ewb/model/cim/iec61968/assetinfo/wire_info.py +24 -0
- zepben/ewb/model/cim/iec61968/assetinfo/wire_material_kind.py +57 -0
- zepben/ewb/model/cim/iec61968/assets/__init__.py +4 -0
- zepben/ewb/model/cim/iec61968/assets/asset.py +154 -0
- zepben/ewb/model/cim/iec61968/assets/asset_container.py +16 -0
- zepben/ewb/model/cim/iec61968/assets/asset_function.py +15 -0
- zepben/ewb/model/cim/iec61968/assets/asset_info.py +19 -0
- zepben/ewb/model/cim/iec61968/assets/asset_organisation_role.py +13 -0
- zepben/ewb/model/cim/iec61968/assets/asset_owner.py +13 -0
- zepben/ewb/model/cim/iec61968/assets/streetlight.py +29 -0
- zepben/ewb/model/cim/iec61968/assets/structure.py +16 -0
- zepben/ewb/model/cim/iec61968/common/__init__.py +4 -0
- zepben/ewb/model/cim/iec61968/common/agreement.py +16 -0
- zepben/ewb/model/cim/iec61968/common/document.py +36 -0
- zepben/ewb/model/cim/iec61968/common/location.py +129 -0
- zepben/ewb/model/cim/iec61968/common/organisation.py +15 -0
- zepben/ewb/model/cim/iec61968/common/organisation_role.py +22 -0
- zepben/ewb/model/cim/iec61968/common/position_point.py +44 -0
- zepben/ewb/model/cim/iec61968/common/street_address.py +28 -0
- zepben/ewb/model/cim/iec61968/common/street_detail.py +46 -0
- zepben/ewb/model/cim/iec61968/common/town_detail.py +25 -0
- zepben/ewb/model/cim/iec61968/customers/__init__.py +4 -0
- zepben/ewb/model/cim/iec61968/customers/customer.py +93 -0
- zepben/ewb/model/cim/iec61968/customers/customer_agreement.py +107 -0
- zepben/ewb/model/cim/iec61968/customers/customer_kind.py +69 -0
- zepben/ewb/model/cim/iec61968/customers/pricing_structure.py +88 -0
- zepben/ewb/model/cim/iec61968/customers/tariff.py +18 -0
- zepben/ewb/model/cim/iec61968/infiec61968/__init__.py +4 -0
- zepben/ewb/model/cim/iec61968/infiec61968/infassetinfo/__init__.py +4 -0
- zepben/ewb/model/cim/iec61968/infiec61968/infassetinfo/current_transformer_info.py +51 -0
- zepben/ewb/model/cim/iec61968/infiec61968/infassetinfo/potential_transformer_info.py +33 -0
- zepben/ewb/model/cim/iec61968/infiec61968/infassetinfo/transformer_construction_kind.py +69 -0
- zepben/ewb/model/cim/iec61968/infiec61968/infassetinfo/transformer_function_kind.py +45 -0
- zepben/ewb/model/cim/iec61968/infiec61968/infassets/__init__.py +4 -0
- zepben/ewb/model/cim/iec61968/infiec61968/infassets/pole.py +87 -0
- zepben/ewb/model/cim/iec61968/infiec61968/infassets/streetlight_lamp_kind.py +27 -0
- zepben/ewb/model/cim/iec61968/infiec61968/infcommon/__init__.py +4 -0
- zepben/ewb/model/cim/iec61968/infiec61968/infcommon/ratio.py +34 -0
- zepben/ewb/model/cim/iec61968/metering/__init__.py +4 -0
- zepben/ewb/model/cim/iec61968/metering/controlled_appliance.py +152 -0
- zepben/ewb/model/cim/iec61968/metering/end_device.py +165 -0
- zepben/ewb/model/cim/iec61968/metering/end_device_function.py +17 -0
- zepben/ewb/model/cim/iec61968/metering/end_device_function_kind.py +48 -0
- zepben/ewb/model/cim/iec61968/metering/meter.py +28 -0
- zepben/ewb/model/cim/iec61968/metering/usage_point.py +186 -0
- zepben/ewb/model/cim/iec61968/operations/__init__.py +4 -0
- zepben/ewb/model/cim/iec61968/operations/operational_restriction.py +92 -0
- zepben/ewb/model/cim/iec61970/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/base/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/base/auxiliaryequipment/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/base/auxiliaryequipment/auxiliary_equipment.py +24 -0
- zepben/ewb/model/cim/iec61970/base/auxiliaryequipment/current_transformer.py +37 -0
- zepben/ewb/model/cim/iec61970/base/auxiliaryequipment/fault_indicator.py +18 -0
- zepben/ewb/model/cim/iec61970/base/auxiliaryequipment/potential_transformer.py +38 -0
- zepben/ewb/model/cim/iec61970/base/auxiliaryequipment/potential_transformer_kind.py +30 -0
- zepben/ewb/model/cim/iec61970/base/auxiliaryequipment/sensor.py +92 -0
- zepben/ewb/model/cim/iec61970/base/core/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/base/core/ac_dc_terminal.py +16 -0
- zepben/ewb/model/cim/iec61970/base/core/base_voltage.py +17 -0
- zepben/ewb/model/cim/iec61970/base/core/conducting_equipment.py +198 -0
- zepben/ewb/model/cim/iec61970/base/core/connectivity_node.py +105 -0
- zepben/ewb/model/cim/iec61970/base/core/connectivity_node_container.py +15 -0
- zepben/ewb/model/cim/iec61970/base/core/curve.py +125 -0
- zepben/ewb/model/cim/iec61970/base/core/curve_data.py +29 -0
- zepben/ewb/model/cim/iec61970/base/core/equipment.py +366 -0
- zepben/ewb/model/cim/iec61970/base/core/equipment_container.py +199 -0
- zepben/ewb/model/cim/iec61970/base/core/feeder.py +260 -0
- zepben/ewb/model/cim/iec61970/base/core/geographical_region.py +82 -0
- zepben/ewb/model/cim/iec61970/base/core/identified_object.py +239 -0
- zepben/ewb/model/cim/iec61970/base/core/name.py +36 -0
- zepben/ewb/model/cim/iec61970/base/core/name_type.py +203 -0
- zepben/ewb/model/cim/iec61970/base/core/phase_code.py +202 -0
- zepben/ewb/model/cim/iec61970/base/core/power_system_resource.py +106 -0
- zepben/ewb/model/cim/iec61970/base/core/sub_geographical_region.py +93 -0
- zepben/ewb/model/cim/iec61970/base/core/substation.py +277 -0
- zepben/ewb/model/cim/iec61970/base/core/terminal.py +171 -0
- zepben/ewb/model/cim/iec61970/base/diagramlayout/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/base/diagramlayout/diagram.py +109 -0
- zepben/ewb/model/cim/iec61970/base/diagramlayout/diagram_object.py +160 -0
- zepben/ewb/model/cim/iec61970/base/diagramlayout/diagram_object_point.py +25 -0
- zepben/ewb/model/cim/iec61970/base/diagramlayout/diagram_style.py +28 -0
- zepben/ewb/model/cim/iec61970/base/diagramlayout/orientation_kind.py +29 -0
- zepben/ewb/model/cim/iec61970/base/domain/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/base/domain/unit_symbol.py +494 -0
- zepben/ewb/model/cim/iec61970/base/equivalents/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/base/equivalents/equivalent_branch.py +113 -0
- zepben/ewb/model/cim/iec61970/base/equivalents/equivalent_equipment.py +15 -0
- zepben/ewb/model/cim/iec61970/base/generation/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/base/generation/production/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/base/generation/production/battery_state_kind.py +39 -0
- zepben/ewb/model/cim/iec61970/base/generation/production/battery_unit.py +108 -0
- zepben/ewb/model/cim/iec61970/base/generation/production/photo_voltaic_unit.py +13 -0
- zepben/ewb/model/cim/iec61970/base/generation/production/power_electronics_unit.py +28 -0
- zepben/ewb/model/cim/iec61970/base/generation/production/power_electronics_wind_unit.py +13 -0
- zepben/ewb/model/cim/iec61970/base/meas/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/base/meas/accumulator.py +13 -0
- zepben/ewb/model/cim/iec61970/base/meas/accumulator_value.py +20 -0
- zepben/ewb/model/cim/iec61970/base/meas/analog.py +18 -0
- zepben/ewb/model/cim/iec61970/base/meas/analog_value.py +20 -0
- zepben/ewb/model/cim/iec61970/base/meas/control.py +26 -0
- zepben/ewb/model/cim/iec61970/base/meas/discrete.py +13 -0
- zepben/ewb/model/cim/iec61970/base/meas/discrete_value.py +20 -0
- zepben/ewb/model/cim/iec61970/base/meas/iopoint.py +16 -0
- zepben/ewb/model/cim/iec61970/base/meas/measurement.py +60 -0
- zepben/ewb/model/cim/iec61970/base/meas/measurement_value.py +21 -0
- zepben/ewb/model/cim/iec61970/base/protection/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/base/protection/current_relay.py +23 -0
- zepben/ewb/model/cim/iec61970/base/scada/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/base/scada/remote_control.py +22 -0
- zepben/ewb/model/cim/iec61970/base/scada/remote_point.py +16 -0
- zepben/ewb/model/cim/iec61970/base/scada/remote_source.py +22 -0
- zepben/ewb/model/cim/iec61970/base/wires/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/base/wires/ac_line_segment.py +214 -0
- zepben/ewb/model/cim/iec61970/base/wires/breaker.py +32 -0
- zepben/ewb/model/cim/iec61970/base/wires/busbar_section.py +19 -0
- zepben/ewb/model/cim/iec61970/base/wires/clamp.py +32 -0
- zepben/ewb/model/cim/iec61970/base/wires/conductor.py +49 -0
- zepben/ewb/model/cim/iec61970/base/wires/connector.py +16 -0
- zepben/ewb/model/cim/iec61970/base/wires/cut.py +36 -0
- zepben/ewb/model/cim/iec61970/base/wires/disconnector.py +17 -0
- zepben/ewb/model/cim/iec61970/base/wires/earth_fault_compensator.py +21 -0
- zepben/ewb/model/cim/iec61970/base/wires/energy_connection.py +15 -0
- zepben/ewb/model/cim/iec61970/base/wires/energy_consumer.py +107 -0
- zepben/ewb/model/cim/iec61970/base/wires/energy_consumer_phase.py +56 -0
- zepben/ewb/model/cim/iec61970/base/wires/energy_source.py +172 -0
- zepben/ewb/model/cim/iec61970/base/wires/energy_source_phase.py +45 -0
- zepben/ewb/model/cim/iec61970/base/wires/fuse.py +23 -0
- zepben/ewb/model/cim/iec61970/base/wires/ground.py +15 -0
- zepben/ewb/model/cim/iec61970/base/wires/ground_disconnector.py +15 -0
- zepben/ewb/model/cim/iec61970/base/wires/grounding_impedance.py +19 -0
- zepben/ewb/model/cim/iec61970/base/wires/jumper.py +16 -0
- zepben/ewb/model/cim/iec61970/base/wires/junction.py +15 -0
- zepben/ewb/model/cim/iec61970/base/wires/line.py +13 -0
- zepben/ewb/model/cim/iec61970/base/wires/linear_shunt_compensator.py +26 -0
- zepben/ewb/model/cim/iec61970/base/wires/load_break_switch.py +14 -0
- zepben/ewb/model/cim/iec61970/base/wires/per_length_impedance.py +13 -0
- zepben/ewb/model/cim/iec61970/base/wires/per_length_line_parameter.py +13 -0
- zepben/ewb/model/cim/iec61970/base/wires/per_length_phase_impedance.py +99 -0
- zepben/ewb/model/cim/iec61970/base/wires/per_length_sequence_impedance.py +43 -0
- zepben/ewb/model/cim/iec61970/base/wires/petersen_coil.py +22 -0
- zepben/ewb/model/cim/iec61970/base/wires/phase_impedance_data.py +37 -0
- zepben/ewb/model/cim/iec61970/base/wires/phase_shunt_connection_kind.py +40 -0
- zepben/ewb/model/cim/iec61970/base/wires/power_electronics_connection.py +524 -0
- zepben/ewb/model/cim/iec61970/base/wires/power_electronics_connection_phase.py +34 -0
- zepben/ewb/model/cim/iec61970/base/wires/power_transformer.py +217 -0
- zepben/ewb/model/cim/iec61970/base/wires/power_transformer_end.py +208 -0
- zepben/ewb/model/cim/iec61970/base/wires/protected_switch.py +96 -0
- zepben/ewb/model/cim/iec61970/base/wires/ratio_tap_changer.py +30 -0
- zepben/ewb/model/cim/iec61970/base/wires/reactive_capability_curve.py +16 -0
- zepben/ewb/model/cim/iec61970/base/wires/recloser.py +15 -0
- zepben/ewb/model/cim/iec61970/base/wires/regulating_cond_eq.py +45 -0
- zepben/ewb/model/cim/iec61970/base/wires/regulating_control.py +173 -0
- zepben/ewb/model/cim/iec61970/base/wires/regulating_control_mode_kind.py +48 -0
- zepben/ewb/model/cim/iec61970/base/wires/rotating_machine.py +36 -0
- zepben/ewb/model/cim/iec61970/base/wires/series_compensator.py +42 -0
- zepben/ewb/model/cim/iec61970/base/wires/shunt_compensator.py +59 -0
- zepben/ewb/model/cim/iec61970/base/wires/single_phase_kind.py +107 -0
- zepben/ewb/model/cim/iec61970/base/wires/static_var_compensator.py +40 -0
- zepben/ewb/model/cim/iec61970/base/wires/svc_control_mode.py +30 -0
- zepben/ewb/model/cim/iec61970/base/wires/switch.py +119 -0
- zepben/ewb/model/cim/iec61970/base/wires/synchronous_machine.py +168 -0
- zepben/ewb/model/cim/iec61970/base/wires/synchronous_machine_kind.py +46 -0
- zepben/ewb/model/cim/iec61970/base/wires/tap_changer.py +150 -0
- zepben/ewb/model/cim/iec61970/base/wires/tap_changer_control.py +49 -0
- zepben/ewb/model/cim/iec61970/base/wires/transformer_end.py +73 -0
- zepben/ewb/model/cim/iec61970/base/wires/transformer_star_impedance.py +48 -0
- zepben/ewb/model/cim/iec61970/base/wires/winding_connection.py +45 -0
- zepben/ewb/model/cim/iec61970/infiec61970/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/infiec61970/feeder/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/infiec61970/feeder/circuit.py +144 -0
- zepben/ewb/model/phases.py +168 -0
- zepben/ewb/model/resistance_reactance.py +40 -0
- zepben/ewb/services/__init__.py +4 -0
- zepben/ewb/services/common/__init__.py +16 -0
- zepben/ewb/services/common/base_service.py +383 -0
- zepben/ewb/services/common/base_service_comparator.py +394 -0
- zepben/ewb/services/common/difference.py +47 -0
- zepben/ewb/services/common/enum_mapper.py +55 -0
- zepben/ewb/services/common/meta/__init__.py +4 -0
- zepben/ewb/services/common/meta/data_source.py +16 -0
- zepben/ewb/services/common/meta/metadata_collection.py +28 -0
- zepben/ewb/services/common/meta/metadata_translations.py +47 -0
- zepben/ewb/services/common/meta/service_info.py +22 -0
- zepben/ewb/services/common/reference_resolvers.py +374 -0
- zepben/ewb/services/common/resolver.py +597 -0
- zepben/ewb/services/common/translator/__init__.py +4 -0
- zepben/ewb/services/common/translator/base_cim2proto.py +115 -0
- zepben/ewb/services/common/translator/base_proto2cim.py +146 -0
- zepben/ewb/services/common/translator/service_differences.py +81 -0
- zepben/ewb/services/common/translator/util.py +75 -0
- zepben/ewb/services/customer/__init__.py +4 -0
- zepben/ewb/services/customer/customer_service_comparator.py +52 -0
- zepben/ewb/services/customer/customers.py +23 -0
- zepben/ewb/services/customer/translator/__init__.py +21 -0
- zepben/ewb/services/customer/translator/customer_cim2proto.py +71 -0
- zepben/ewb/services/customer/translator/customer_enum_mappers.py +18 -0
- zepben/ewb/services/customer/translator/customer_proto2cim.py +87 -0
- zepben/ewb/services/diagram/__init__.py +4 -0
- zepben/ewb/services/diagram/diagram_service_comparator.py +39 -0
- zepben/ewb/services/diagram/diagrams.py +107 -0
- zepben/ewb/services/diagram/translator/__init__.py +11 -0
- zepben/ewb/services/diagram/translator/diagram_cim2proto.py +51 -0
- zepben/ewb/services/diagram/translator/diagram_enum_mappers.py +21 -0
- zepben/ewb/services/diagram/translator/diagram_proto2cim.py +61 -0
- zepben/ewb/services/measurement/__init__.py +4 -0
- zepben/ewb/services/measurement/measurements.py +35 -0
- zepben/ewb/services/measurement/translator/__init__.py +6 -0
- zepben/ewb/services/measurement/translator/measurement_cim2proto.py +42 -0
- zepben/ewb/services/measurement/translator/measurement_proto2cim.py +52 -0
- zepben/ewb/services/network/__init__.py +4 -0
- zepben/ewb/services/network/network_extensions.py +119 -0
- zepben/ewb/services/network/network_service.py +302 -0
- zepben/ewb/services/network/network_service_comparator.py +1322 -0
- zepben/ewb/services/network/network_state.py +36 -0
- zepben/ewb/services/network/tracing/__init__.py +4 -0
- zepben/ewb/services/network/tracing/busbranch_trace.py +36 -0
- zepben/ewb/services/network/tracing/connectivity/__init__.py +4 -0
- zepben/ewb/services/network/tracing/connectivity/connectivity_result.py +105 -0
- zepben/ewb/services/network/tracing/connectivity/nominal_phase_path.py +23 -0
- zepben/ewb/services/network/tracing/connectivity/phase_paths.py +70 -0
- zepben/ewb/services/network/tracing/connectivity/terminal_connectivity_connected.py +226 -0
- zepben/ewb/services/network/tracing/connectivity/terminal_connectivity_internal.py +64 -0
- zepben/ewb/services/network/tracing/connectivity/transformer_phase_paths.py +202 -0
- zepben/ewb/services/network/tracing/connectivity/xy_candidate_phase_paths.py +235 -0
- zepben/ewb/services/network/tracing/connectivity/xy_phase_step.py +24 -0
- zepben/ewb/services/network/tracing/feeder/__init__.py +4 -0
- zepben/ewb/services/network/tracing/feeder/assign_to_feeders.py +202 -0
- zepben/ewb/services/network/tracing/feeder/assign_to_lv_feeders.py +202 -0
- zepben/ewb/services/network/tracing/feeder/clear_direction.py +80 -0
- zepben/ewb/services/network/tracing/feeder/direction_status.py +133 -0
- zepben/ewb/services/network/tracing/feeder/feeder_direction.py +107 -0
- zepben/ewb/services/network/tracing/feeder/set_direction.py +143 -0
- zepben/ewb/services/network/tracing/find_swer_equipment.py +175 -0
- zepben/ewb/services/network/tracing/networktrace/__init__.py +4 -0
- zepben/ewb/services/network/tracing/networktrace/actions/__init__.py +4 -0
- zepben/ewb/services/network/tracing/networktrace/actions/equipment_tree_builder.py +104 -0
- zepben/ewb/services/network/tracing/networktrace/actions/tree_node.py +35 -0
- zepben/ewb/services/network/tracing/networktrace/compute_data.py +60 -0
- zepben/ewb/services/network/tracing/networktrace/conditions/__init__.py +4 -0
- zepben/ewb/services/network/tracing/networktrace/conditions/conditions.py +73 -0
- zepben/ewb/services/network/tracing/networktrace/conditions/direction_condition.py +63 -0
- zepben/ewb/services/network/tracing/networktrace/conditions/equipment_step_limit_condition.py +26 -0
- zepben/ewb/services/network/tracing/networktrace/conditions/equipment_type_step_limit_condition.py +44 -0
- zepben/ewb/services/network/tracing/networktrace/conditions/network_trace_queue_condition.py +67 -0
- zepben/ewb/services/network/tracing/networktrace/conditions/network_trace_stop_condition.py +65 -0
- zepben/ewb/services/network/tracing/networktrace/conditions/open_condition.py +39 -0
- zepben/ewb/services/network/tracing/networktrace/network_trace.py +433 -0
- zepben/ewb/services/network/tracing/networktrace/network_trace_action_type.py +42 -0
- zepben/ewb/services/network/tracing/networktrace/network_trace_queue_next.py +84 -0
- zepben/ewb/services/network/tracing/networktrace/network_trace_step.py +128 -0
- zepben/ewb/services/network/tracing/networktrace/network_trace_step_path_provider.py +351 -0
- zepben/ewb/services/network/tracing/networktrace/network_trace_tracker.py +39 -0
- zepben/ewb/services/network/tracing/networktrace/operators/__init__.py +14 -0
- zepben/ewb/services/network/tracing/networktrace/operators/equipment_container_state_operators.py +264 -0
- zepben/ewb/services/network/tracing/networktrace/operators/feeder_direction_state_operations.py +181 -0
- zepben/ewb/services/network/tracing/networktrace/operators/in_service_state_operators.py +76 -0
- zepben/ewb/services/network/tracing/networktrace/operators/network_state_operators.py +120 -0
- zepben/ewb/services/network/tracing/networktrace/operators/open_state_operators.py +104 -0
- zepben/ewb/services/network/tracing/networktrace/operators/phase_state_operators.py +56 -0
- zepben/ewb/services/network/tracing/networktrace/tracing.py +132 -0
- zepben/ewb/services/network/tracing/phases/__init__.py +4 -0
- zepben/ewb/services/network/tracing/phases/phase_inferrer.py +205 -0
- zepben/ewb/services/network/tracing/phases/phase_status.py +101 -0
- zepben/ewb/services/network/tracing/phases/remove_phases.py +143 -0
- zepben/ewb/services/network/tracing/phases/set_phases.py +490 -0
- zepben/ewb/services/network/tracing/traversal/__init__.py +4 -0
- zepben/ewb/services/network/tracing/traversal/context_value_computer.py +63 -0
- zepben/ewb/services/network/tracing/traversal/debug_logging.py +124 -0
- zepben/ewb/services/network/tracing/traversal/queue.py +112 -0
- zepben/ewb/services/network/tracing/traversal/queue_condition.py +75 -0
- zepben/ewb/services/network/tracing/traversal/step_action.py +83 -0
- zepben/ewb/services/network/tracing/traversal/step_context.py +59 -0
- zepben/ewb/services/network/tracing/traversal/stop_condition.py +57 -0
- zepben/ewb/services/network/tracing/traversal/traversal.py +634 -0
- zepben/ewb/services/network/tracing/traversal/traversal_condition.py +22 -0
- zepben/ewb/services/network/tracing/traversal/weighted_priority_queue.py +85 -0
- zepben/ewb/services/network/tracing/util.py +93 -0
- zepben/ewb/services/network/translator/__init__.py +392 -0
- zepben/ewb/services/network/translator/network_cim2proto.py +1867 -0
- zepben/ewb/services/network/translator/network_enum_mappers.py +78 -0
- zepben/ewb/services/network/translator/network_proto2cim.py +2201 -0
- zepben/ewb/services/services.py +48 -0
- zepben/ewb/streaming/__init__.py +4 -0
- zepben/ewb/streaming/data/__init__.py +4 -0
- zepben/ewb/streaming/data/current_state_event.py +314 -0
- zepben/ewb/streaming/data/current_state_event_batch.py +25 -0
- zepben/ewb/streaming/data/set_current_states_status.py +286 -0
- zepben/ewb/streaming/exceptions.py +14 -0
- zepben/ewb/streaming/get/__init__.py +4 -0
- zepben/ewb/streaming/get/consumer.py +209 -0
- zepben/ewb/streaming/get/customer_consumer.py +111 -0
- zepben/ewb/streaming/get/diagram_consumer.py +107 -0
- zepben/ewb/streaming/get/hierarchy/__init__.py +4 -0
- zepben/ewb/streaming/get/hierarchy/data.py +27 -0
- zepben/ewb/streaming/get/included_energized_containers.py +36 -0
- zepben/ewb/streaming/get/included_energizing_containers.py +36 -0
- zepben/ewb/streaming/get/network_consumer.py +870 -0
- zepben/ewb/streaming/get/query_network_state_client.py +64 -0
- zepben/ewb/streaming/get/query_network_state_service.py +94 -0
- zepben/ewb/streaming/grpc/__init__.py +4 -0
- zepben/ewb/streaming/grpc/auth_token_plugin.py +24 -0
- zepben/ewb/streaming/grpc/connect.py +209 -0
- zepben/ewb/streaming/grpc/grpc.py +107 -0
- zepben/ewb/streaming/grpc/grpc_channel_builder.py +190 -0
- zepben/ewb/streaming/mutations/__init__.py +4 -0
- zepben/ewb/streaming/mutations/update_network_state_client.py +80 -0
- zepben/ewb/streaming/mutations/update_network_state_service.py +61 -0
- zepben/ewb/testing/__init__.py +4 -0
- zepben/ewb/testing/test_network_builder.py +816 -0
- zepben/ewb/types.py +17 -0
- zepben/ewb/util.py +200 -0
- zepben_ewb-1.0.0.dist-info/METADATA +90 -0
- zepben_ewb-1.0.0.dist-info/RECORD +641 -0
- zepben_ewb-1.0.0.dist-info/WHEEL +5 -0
- zepben_ewb-1.0.0.dist-info/licenses/LICENSE +374 -0
- zepben_ewb-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,159 @@
|
|
|
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__ = ["BaseCimWriter"]
|
|
7
|
+
|
|
8
|
+
from abc import ABC
|
|
9
|
+
from typing import Optional
|
|
10
|
+
|
|
11
|
+
from zepben.ewb.database.sqlite.common.base_database_tables import BaseDatabaseTables
|
|
12
|
+
from zepben.ewb.database.sqlite.common.base_entry_writer import BaseEntryWriter
|
|
13
|
+
from zepben.ewb.database.sqlite.extensions.prepared_statement import PreparedStatement
|
|
14
|
+
from zepben.ewb.database.sqlite.tables.iec61968.common.table_documents import TableDocuments
|
|
15
|
+
from zepben.ewb.database.sqlite.tables.iec61968.common.table_organisation_roles import TableOrganisationRoles
|
|
16
|
+
from zepben.ewb.database.sqlite.tables.iec61968.common.table_organisations import TableOrganisations
|
|
17
|
+
from zepben.ewb.database.sqlite.tables.iec61970.base.core.table_identified_objects import TableIdentifiedObjects
|
|
18
|
+
from zepben.ewb.database.sqlite.tables.iec61970.base.core.table_name_types import TableNameTypes
|
|
19
|
+
from zepben.ewb.database.sqlite.tables.iec61970.base.core.table_names import TableNames
|
|
20
|
+
from zepben.ewb.model.cim.iec61968.common.document import Document
|
|
21
|
+
from zepben.ewb.model.cim.iec61968.common.organisation import Organisation
|
|
22
|
+
from zepben.ewb.model.cim.iec61968.common.organisation_role import OrganisationRole
|
|
23
|
+
from zepben.ewb.model.cim.iec61970.base.core.identified_object import IdentifiedObject
|
|
24
|
+
from zepben.ewb.model.cim.iec61970.base.core.name import Name
|
|
25
|
+
from zepben.ewb.model.cim.iec61970.base.core.name_type import NameType
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class BaseCimWriter(BaseEntryWriter, ABC):
|
|
29
|
+
"""
|
|
30
|
+
A base class for writing CIM objects to a database.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
def __init__(self, database_tables: BaseDatabaseTables):
|
|
34
|
+
super().__init__()
|
|
35
|
+
self._database_tables = database_tables
|
|
36
|
+
|
|
37
|
+
###################
|
|
38
|
+
# IEC61968 Common #
|
|
39
|
+
###################
|
|
40
|
+
|
|
41
|
+
def _save_document(self, table: TableDocuments, insert: PreparedStatement, document: Document, description: str) -> bool:
|
|
42
|
+
"""
|
|
43
|
+
Save the `Document` fields to `TableDocuments`.
|
|
44
|
+
|
|
45
|
+
:param table: The database table to write the `Document` fields to.
|
|
46
|
+
:param insert: The `PreparedStatement` to bind the field values to.
|
|
47
|
+
:param document: The `Document` instance to write to the database.
|
|
48
|
+
:param description: A readable version of the type of object being written for logging purposes.
|
|
49
|
+
|
|
50
|
+
:return: True if the `Document` was successfully written to the database, otherwise false.
|
|
51
|
+
:raises SQLException: For any errors encountered writing to the database.
|
|
52
|
+
"""
|
|
53
|
+
insert.add_value(table.title.query_index, document.title)
|
|
54
|
+
# The timestamp in the database uses Z for UTC while python uses +HH:mm format, so convert between them.
|
|
55
|
+
insert.add_value(table.created_date_time.query_index, f"{document.created_date_time.isoformat()}Z" if document.created_date_time else None)
|
|
56
|
+
insert.add_value(table.author_name.query_index, document.author_name)
|
|
57
|
+
insert.add_value(table.type.query_index, document.type)
|
|
58
|
+
insert.add_value(table.status.query_index, document.status)
|
|
59
|
+
insert.add_value(table.comment.query_index, document.comment)
|
|
60
|
+
|
|
61
|
+
return self._save_identified_object(table, insert, document, description)
|
|
62
|
+
|
|
63
|
+
def save_organisation(self, organisation: Organisation) -> bool:
|
|
64
|
+
"""
|
|
65
|
+
Save the `Organisation` fields to `TableOrganisations`.
|
|
66
|
+
|
|
67
|
+
:param organisation: The `Organisation` instance to write to the database.
|
|
68
|
+
|
|
69
|
+
:return: True if the `Organisation` was successfully written to the database, otherwise false.
|
|
70
|
+
:raises SQLException: For any errors encountered writing to the database.
|
|
71
|
+
"""
|
|
72
|
+
table = self._database_tables.get_table(TableOrganisations)
|
|
73
|
+
insert = self._database_tables.get_insert(TableOrganisations)
|
|
74
|
+
|
|
75
|
+
return self._save_identified_object(table, insert, organisation, "organisation")
|
|
76
|
+
|
|
77
|
+
def _save_organisation_role(self, table: TableOrganisationRoles, insert: PreparedStatement, organisation_role: OrganisationRole, description: str) -> bool:
|
|
78
|
+
"""
|
|
79
|
+
Save the `OrganisationRole` fields to `TableOrganisationRoles`.
|
|
80
|
+
|
|
81
|
+
:param table: The database table to write the `OrganisationRole` fields to.
|
|
82
|
+
:param insert: The `PreparedStatement` to bind the field values to.
|
|
83
|
+
:param organisation_role: The `OrganisationRole` instance to write to the database.
|
|
84
|
+
:param description: A readable version of the type of object being written for logging purposes.
|
|
85
|
+
|
|
86
|
+
:return: True if the `OrganisationRole` was successfully written to the database, otherwise false.
|
|
87
|
+
:raises SQLException: For any errors encountered writing to the database.
|
|
88
|
+
"""
|
|
89
|
+
insert.add_value(table.organisation_mrid.query_index, self._mrid_or_none(organisation_role.organisation))
|
|
90
|
+
|
|
91
|
+
return self._save_identified_object(table, insert, organisation_role, description)
|
|
92
|
+
|
|
93
|
+
######################
|
|
94
|
+
# IEC61970 Base Core #
|
|
95
|
+
######################
|
|
96
|
+
|
|
97
|
+
def _save_identified_object(
|
|
98
|
+
self,
|
|
99
|
+
table: TableIdentifiedObjects,
|
|
100
|
+
insert: PreparedStatement,
|
|
101
|
+
identified_object: IdentifiedObject,
|
|
102
|
+
description: str
|
|
103
|
+
) -> bool:
|
|
104
|
+
"""
|
|
105
|
+
Save the `IdentifiedObject` fields to `TableIdentifiedObjects`.
|
|
106
|
+
|
|
107
|
+
:param table: The database table to write the `IdentifiedObject` fields to.
|
|
108
|
+
:param insert: The `PreparedStatement` to bind the field values to.
|
|
109
|
+
:param identified_object: The `IdentifiedObject` instance to write to the database.
|
|
110
|
+
:param description: A readable version of the type of object being written for logging purposes.
|
|
111
|
+
|
|
112
|
+
:return: True if the `IdentifiedObject` was successfully written to the database, otherwise false.
|
|
113
|
+
:raises SQLException: For any errors encountered writing to the database.
|
|
114
|
+
"""
|
|
115
|
+
insert.add_value(table.mrid.query_index, identified_object.mrid)
|
|
116
|
+
insert.add_value(table.name_.query_index, identified_object.name)
|
|
117
|
+
insert.add_value(table.description.query_index, identified_object.description)
|
|
118
|
+
insert.add_value(table.num_diagram_objects.query_index, 0) # Currently unused
|
|
119
|
+
|
|
120
|
+
return self._try_execute_single_update(insert, description)
|
|
121
|
+
|
|
122
|
+
def save_name_type(self, name_type: NameType) -> bool:
|
|
123
|
+
"""
|
|
124
|
+
Save the `NameType` fields to `TableNameTypes`.
|
|
125
|
+
|
|
126
|
+
:param name_type: The `NameType` instance to write to the database.
|
|
127
|
+
|
|
128
|
+
:return: True if the `NameType` was successfully written to the database, otherwise false.
|
|
129
|
+
:raises SQLException: For any errors encountered writing to the database.
|
|
130
|
+
"""
|
|
131
|
+
table = self._database_tables.get_table(TableNameTypes)
|
|
132
|
+
insert = self._database_tables.get_insert(TableNameTypes)
|
|
133
|
+
|
|
134
|
+
insert.add_value(table.name_.query_index, name_type.name)
|
|
135
|
+
insert.add_value(table.description.query_index, name_type.description)
|
|
136
|
+
|
|
137
|
+
return self._try_execute_single_update(insert, "name type")
|
|
138
|
+
|
|
139
|
+
def save_name(self, name: Name) -> bool:
|
|
140
|
+
"""
|
|
141
|
+
Save the `Name` fields to `TableNames`.
|
|
142
|
+
|
|
143
|
+
:param name: The `Name` instance to write to the database.
|
|
144
|
+
|
|
145
|
+
:return: True if the `Name` was successfully written to the database, otherwise false.
|
|
146
|
+
:raises SQLException: For any errors encountered writing to the database.
|
|
147
|
+
"""
|
|
148
|
+
table = self._database_tables.get_table(TableNames)
|
|
149
|
+
insert = self._database_tables.get_insert(TableNames)
|
|
150
|
+
|
|
151
|
+
insert.add_value(table.name_.query_index, name.name)
|
|
152
|
+
insert.add_value(table.name_type_name.query_index, name.type.name)
|
|
153
|
+
insert.add_value(table.identified_object_mrid.query_index, name.identified_object.mrid)
|
|
154
|
+
|
|
155
|
+
return self._try_execute_single_update(insert, "name")
|
|
156
|
+
|
|
157
|
+
@staticmethod
|
|
158
|
+
def _mrid_or_none(io: Optional[IdentifiedObject]) -> Optional[str]:
|
|
159
|
+
return io.mrid if io is not None else None
|
|
@@ -0,0 +1,96 @@
|
|
|
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__ = ["BaseCollectionReader"]
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
from abc import ABC, abstractmethod
|
|
10
|
+
from contextlib import closing
|
|
11
|
+
from sqlite3 import Connection
|
|
12
|
+
from typing import Callable, Type, Optional
|
|
13
|
+
|
|
14
|
+
from zepben.ewb.database.sqlite.common.base_database_tables import BaseDatabaseTables, TSqliteTable
|
|
15
|
+
from zepben.ewb.database.sqlite.common.reader_exceptions import MRIDLookupException, DuplicateMRIDException
|
|
16
|
+
from zepben.ewb.database.sqlite.extensions.prepared_statement import SqlException
|
|
17
|
+
from zepben.ewb.database.sqlite.extensions.result_set import ResultSet
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class BaseCollectionReader(ABC):
|
|
21
|
+
"""
|
|
22
|
+
A base class for reading collections of object collections from a database.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def __init__(self, tables: BaseDatabaseTables, connection: Connection):
|
|
26
|
+
super().__init__()
|
|
27
|
+
self._logger: logging.Logger = logging.getLogger(self.__class__.__name__)
|
|
28
|
+
"""
|
|
29
|
+
The logger to use for this collection reader.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
self.base_database_tables: BaseDatabaseTables = tables
|
|
33
|
+
"""
|
|
34
|
+
The tables that are available in the database.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
self._connection: Connection = connection
|
|
38
|
+
"""
|
|
39
|
+
The connection to the database to read.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
@abstractmethod
|
|
43
|
+
def load(self) -> bool:
|
|
44
|
+
"""
|
|
45
|
+
Load all the objects for the available collections.
|
|
46
|
+
|
|
47
|
+
:return: True if the load was successful, otherwise False.
|
|
48
|
+
"""
|
|
49
|
+
pass
|
|
50
|
+
|
|
51
|
+
def _load_each(self, type_: Type[TSqliteTable], process_row: Callable[[TSqliteTable, ResultSet, Callable[[str], str]], bool]) -> bool:
|
|
52
|
+
"""
|
|
53
|
+
Load each row of a table.
|
|
54
|
+
|
|
55
|
+
:param type_: The `SqliteTable` to read the objects from.
|
|
56
|
+
:param process_row: A callback for processing each row in the table. The callback will be provided with the table, the results for the row and a
|
|
57
|
+
callback to set the identifier for the row, which returns the same value, so it can be used fluently.
|
|
58
|
+
"""
|
|
59
|
+
table = self.base_database_tables.get_table(type_)
|
|
60
|
+
|
|
61
|
+
def process_rows(results: ResultSet):
|
|
62
|
+
last_identifier: Optional[str] = None
|
|
63
|
+
|
|
64
|
+
def set_identifier(identifier: str) -> str:
|
|
65
|
+
nonlocal last_identifier
|
|
66
|
+
last_identifier = identifier
|
|
67
|
+
return identifier
|
|
68
|
+
|
|
69
|
+
try:
|
|
70
|
+
count = 0
|
|
71
|
+
while results.next():
|
|
72
|
+
if process_row(table, results, set_identifier):
|
|
73
|
+
count = count + 1
|
|
74
|
+
|
|
75
|
+
return count
|
|
76
|
+
except SqlException as e:
|
|
77
|
+
self._logger.error(f"Failed to load '{last_identifier}' from '{table.name}': {e}")
|
|
78
|
+
raise e
|
|
79
|
+
|
|
80
|
+
return self._load_all(table, process_rows)
|
|
81
|
+
|
|
82
|
+
def _load_all(self, table: TSqliteTable, process_rows: Callable[[ResultSet], int]) -> bool:
|
|
83
|
+
"""
|
|
84
|
+
You really shouldn't need to use this function directly, use `load_each` instead.
|
|
85
|
+
"""
|
|
86
|
+
self._logger.info(f"Loading {table.describe()}...")
|
|
87
|
+
|
|
88
|
+
try:
|
|
89
|
+
with closing(self._connection.cursor()) as cur:
|
|
90
|
+
cur.execute(table.select_sql)
|
|
91
|
+
count = process_rows(ResultSet(cur.fetchall()))
|
|
92
|
+
self._logger.info(f"Successfully loaded {count} {table.describe()}.")
|
|
93
|
+
return True
|
|
94
|
+
except (SqlException, ValueError, MRIDLookupException, DuplicateMRIDException) as ex:
|
|
95
|
+
self._logger.exception(f"Failed to read the {table.describe()} from '{table.name}': {ex}")
|
|
96
|
+
return False
|
|
@@ -0,0 +1,73 @@
|
|
|
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__ = ["BaseCollectionWriter"]
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
from abc import ABC, abstractmethod
|
|
10
|
+
from typing import Callable, TypeVar, Iterable
|
|
11
|
+
|
|
12
|
+
from zepben.ewb.database.sqlite.extensions.prepared_statement import SqlException
|
|
13
|
+
|
|
14
|
+
T = TypeVar("T")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class BaseCollectionWriter(ABC):
|
|
18
|
+
"""
|
|
19
|
+
A base class for writing collections of object collections to a database.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(self):
|
|
23
|
+
super().__init__()
|
|
24
|
+
self._logger: logging.Logger = logging.getLogger(self.__class__.__name__)
|
|
25
|
+
"""
|
|
26
|
+
The logger to use for this collection writer.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
@abstractmethod
|
|
30
|
+
def save(self) -> bool:
|
|
31
|
+
"""
|
|
32
|
+
Save all the objects for the available collections.
|
|
33
|
+
|
|
34
|
+
:return: True if the save was successful, otherwise False.
|
|
35
|
+
"""
|
|
36
|
+
pass
|
|
37
|
+
|
|
38
|
+
def _save_each(self, items: Iterable[T], saver: Callable[[T], bool], on_save_failure: Callable[[T, Exception], None]) -> bool:
|
|
39
|
+
"""
|
|
40
|
+
Save each of the [items] to the database.
|
|
41
|
+
|
|
42
|
+
NOTE: This function does not short circuit and all items will be attempted, even if one fails.
|
|
43
|
+
|
|
44
|
+
:param items: The collection of items to save.
|
|
45
|
+
:param saver: A callback for saving each object to the database.
|
|
46
|
+
:param on_save_failure: A callback that should be used to indicate there was a failure in the `saver`. You should pass the object that was being saved,
|
|
47
|
+
and the exception that caused the failure.
|
|
48
|
+
|
|
49
|
+
:return: True if all `items` were successfully saved, otherwise False.
|
|
50
|
+
"""
|
|
51
|
+
status = True
|
|
52
|
+
|
|
53
|
+
for it in items:
|
|
54
|
+
status = self._validate_save(it, saver, lambda e: on_save_failure(it, e)) and status
|
|
55
|
+
|
|
56
|
+
return status
|
|
57
|
+
|
|
58
|
+
@staticmethod
|
|
59
|
+
def _validate_save(it: T, saver: [[T], bool], on_save_failure: [[Exception], None]) -> bool:
|
|
60
|
+
"""
|
|
61
|
+
Validate that a save actually works, and convert all exceptions into failures with a callback.
|
|
62
|
+
|
|
63
|
+
:param it: The object instance to save.
|
|
64
|
+
:param saver: The callback that will save the object to the database.
|
|
65
|
+
:param on_save_failure: A callback if an exception was thrown by the [saver].
|
|
66
|
+
|
|
67
|
+
:return: True if the saver successfully saved the object to the database, otherwise False.
|
|
68
|
+
"""
|
|
69
|
+
try:
|
|
70
|
+
return saver(it)
|
|
71
|
+
except SqlException as e:
|
|
72
|
+
on_save_failure(e)
|
|
73
|
+
return False
|
|
@@ -0,0 +1,127 @@
|
|
|
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__ = ["BaseDatabaseReader"]
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
from abc import ABC
|
|
10
|
+
from contextlib import closing
|
|
11
|
+
from sqlite3 import Connection
|
|
12
|
+
from typing import Optional
|
|
13
|
+
|
|
14
|
+
from zepben.ewb.database.sqlite.common.base_service_reader import BaseServiceReader
|
|
15
|
+
from zepben.ewb.database.sqlite.common.metadata_collection_reader import MetadataCollectionReader
|
|
16
|
+
from zepben.ewb.database.sqlite.tables.table_version import TableVersion
|
|
17
|
+
from zepben.ewb.services.common.base_service import BaseService
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class BaseDatabaseReader(ABC):
|
|
21
|
+
"""
|
|
22
|
+
A base class for reading objects from one of our databases.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def __init__(
|
|
26
|
+
self,
|
|
27
|
+
connection: Connection,
|
|
28
|
+
metadata_reader: MetadataCollectionReader,
|
|
29
|
+
service_reader: BaseServiceReader,
|
|
30
|
+
service: BaseService,
|
|
31
|
+
database_description: str,
|
|
32
|
+
table_version: TableVersion
|
|
33
|
+
):
|
|
34
|
+
super().__init__()
|
|
35
|
+
self._logger: logging.Logger = logging.getLogger(self.__class__.__name__)
|
|
36
|
+
"""
|
|
37
|
+
The logger to use for this reader.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
self._connection: Connection = connection
|
|
41
|
+
"""
|
|
42
|
+
The connection to the database.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
self._metadata_reader: MetadataCollectionReader = metadata_reader
|
|
46
|
+
"""
|
|
47
|
+
The reader for the [MetadataCollection] included in the database.
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
self._service_reader: BaseServiceReader = service_reader
|
|
51
|
+
"""
|
|
52
|
+
The reader for the [BaseService] supported by the database.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
self._service: BaseService = service
|
|
56
|
+
"""
|
|
57
|
+
The [BaseService] that will be populated by the [BaseServiceReader]. Used for post-processing.
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
self._database_description: str = database_description
|
|
61
|
+
"""
|
|
62
|
+
The description of the database for logging (e.g. filename).
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
self._table_version: TableVersion = table_version
|
|
66
|
+
"""
|
|
67
|
+
The version table object for checking the database version number.
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
self._has_been_used: bool = False
|
|
71
|
+
self._supported_version: int = table_version.SUPPORTED_VERSION
|
|
72
|
+
|
|
73
|
+
async def _post_load(self) -> bool:
|
|
74
|
+
"""
|
|
75
|
+
Customisable function for performing actions after the database has been loaded.
|
|
76
|
+
"""
|
|
77
|
+
self._logger.info("Ensuring all references resolved...")
|
|
78
|
+
for it in self._service.unresolved_references():
|
|
79
|
+
raise ValueError(
|
|
80
|
+
f"Unresolved references found in {self._service.name} service after load - this should not occur. Failing reference was from " +
|
|
81
|
+
f"{it.from_ref} resolving {it.resolver.to_class.__name__} {it.to_mrid}"
|
|
82
|
+
)
|
|
83
|
+
self._logger.info("Unresolved references were all resolved during load.")
|
|
84
|
+
|
|
85
|
+
return True
|
|
86
|
+
|
|
87
|
+
async def load(self) -> bool:
|
|
88
|
+
"""
|
|
89
|
+
Load the database.
|
|
90
|
+
"""
|
|
91
|
+
try:
|
|
92
|
+
if self._has_been_used:
|
|
93
|
+
raise ValueError("You can only use the database reader once.")
|
|
94
|
+
self._has_been_used = True
|
|
95
|
+
|
|
96
|
+
return self._pre_load() and self._load_from_readers() and await self._post_load()
|
|
97
|
+
except Exception as e:
|
|
98
|
+
self._logger.exception(f"Unable to load database: {e}")
|
|
99
|
+
return False
|
|
100
|
+
|
|
101
|
+
def _pre_load(self) -> bool:
|
|
102
|
+
try:
|
|
103
|
+
with closing(self._connection.cursor()) as cur:
|
|
104
|
+
version = self._table_version.get_version(cur)
|
|
105
|
+
if version == self._supported_version:
|
|
106
|
+
self._logger.info(f"Loading from database version v{version}")
|
|
107
|
+
return True
|
|
108
|
+
else:
|
|
109
|
+
self._logger.error(self._format_version_error(version))
|
|
110
|
+
return False
|
|
111
|
+
except Exception as e:
|
|
112
|
+
self._logger.exception(f"Failed to connect to the database for reading: {e}")
|
|
113
|
+
return False
|
|
114
|
+
|
|
115
|
+
def _load_from_readers(self):
|
|
116
|
+
return self._metadata_reader.load() and self._service_reader.load()
|
|
117
|
+
|
|
118
|
+
def _format_version_error(self, version: Optional[int]) -> str:
|
|
119
|
+
if version is None:
|
|
120
|
+
return "Failed to read the version number form the selected database. Are you sure it is a EWB database?"
|
|
121
|
+
elif version < self._supported_version:
|
|
122
|
+
return self._unexpected_version(version, "Consider using the UpgradeRunner if you wish to support this database.")
|
|
123
|
+
else:
|
|
124
|
+
return self._unexpected_version(version, "You need to use a newer version of the SDK to load this database.")
|
|
125
|
+
|
|
126
|
+
def _unexpected_version(self, version: Optional[int], action: str):
|
|
127
|
+
return f"Unable to load from database {self._database_description} [found v{version}, expected v{self._supported_version}]. {action}"
|
|
@@ -0,0 +1,137 @@
|
|
|
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__ = ["TSqliteTable", "BaseDatabaseTables"]
|
|
7
|
+
|
|
8
|
+
from abc import ABC
|
|
9
|
+
from sqlite3 import Connection, Cursor, ProgrammingError
|
|
10
|
+
from typing import Dict, TypeVar, Type, Generator, Callable, Optional
|
|
11
|
+
|
|
12
|
+
from zepben.ewb.database.sqlite.extensions.prepared_statement import PreparedStatement
|
|
13
|
+
from zepben.ewb.database.sqlite.tables.exceptions import MissingTableConfigException
|
|
14
|
+
from zepben.ewb.database.sqlite.tables.iec61970.base.core.table_name_types import *
|
|
15
|
+
from zepben.ewb.database.sqlite.tables.iec61970.base.core.table_names import *
|
|
16
|
+
from zepben.ewb.database.sqlite.tables.sqlite_table import *
|
|
17
|
+
from zepben.ewb.database.sqlite.tables.table_metadata_data_sources import TableMetadataDataSources
|
|
18
|
+
from zepben.ewb.database.sqlite.tables.table_version import TableVersion
|
|
19
|
+
|
|
20
|
+
TSqliteTable = TypeVar("TSqliteTable", bound=SqliteTable)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class BaseDatabaseTables(ABC):
|
|
24
|
+
"""
|
|
25
|
+
The base collection of tables for all our databases.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def __init__(self):
|
|
29
|
+
super().__init__()
|
|
30
|
+
self._tables: Optional[Dict[Type[TSqliteTable], SqliteTable]] = None
|
|
31
|
+
self._insert_statements: Optional[Dict[Type[TSqliteTable], PreparedStatement]] = None
|
|
32
|
+
self._insert_cursor: Optional[Cursor] = None
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def tables(self) -> Generator[SqliteTable, None, None]:
|
|
36
|
+
"""
|
|
37
|
+
The tables that are available in this database, keyed on the table class. You should use `get_table` to access individual tables.
|
|
38
|
+
"""
|
|
39
|
+
self._ensure_tables()
|
|
40
|
+
for t in self._tables.values():
|
|
41
|
+
yield t
|
|
42
|
+
|
|
43
|
+
@property
|
|
44
|
+
def insert_statements(self) -> Generator[PreparedStatement, None, None]:
|
|
45
|
+
"""
|
|
46
|
+
A collection of `PreparedStatement` for each table. You should use `get_insert` to access individual inserts.
|
|
47
|
+
"""
|
|
48
|
+
if self._insert_statements is not None:
|
|
49
|
+
for s in self._insert_statements.values():
|
|
50
|
+
yield s
|
|
51
|
+
|
|
52
|
+
@property
|
|
53
|
+
def _included_tables(self) -> Generator[SqliteTable, None, None]:
|
|
54
|
+
"""
|
|
55
|
+
A sequence of `SqliteTable` indicating which tables are included in this database, which will be consumed to build the `tables` collection.
|
|
56
|
+
|
|
57
|
+
NOTE: You should always append your tables to `super()._included_tables` when overriding.
|
|
58
|
+
"""
|
|
59
|
+
yield TableMetadataDataSources()
|
|
60
|
+
yield TableVersion()
|
|
61
|
+
yield TableNameTypes()
|
|
62
|
+
yield TableNames()
|
|
63
|
+
|
|
64
|
+
def get_table(self, type_: Type[TSqliteTable]) -> TSqliteTable:
|
|
65
|
+
"""
|
|
66
|
+
Helper function for getting the table of the specified type.
|
|
67
|
+
|
|
68
|
+
:param type_: The type of table to get.
|
|
69
|
+
:return: The requested table if it belongs to this database.
|
|
70
|
+
:raises MissingTableConfigException: If the requested table doesn't belong to this database.
|
|
71
|
+
"""
|
|
72
|
+
self._ensure_tables()
|
|
73
|
+
try:
|
|
74
|
+
return self._tables[type_]
|
|
75
|
+
except KeyError:
|
|
76
|
+
raise MissingTableConfigException(f"INTERNAL ERROR: No table has been registered for {type_}. You might want to consider fixing that.")
|
|
77
|
+
|
|
78
|
+
def get_insert(self, type_: Type[TSqliteTable]) -> PreparedStatement:
|
|
79
|
+
"""
|
|
80
|
+
Helper function for getting the insert statement for the specified table.
|
|
81
|
+
|
|
82
|
+
:param type_: The type of table to get.
|
|
83
|
+
:return: The insert statement for the requested table if it belongs to this database.
|
|
84
|
+
:raises MissingTableConfigException: If the requested table doesn't belong to this database.
|
|
85
|
+
"""
|
|
86
|
+
try:
|
|
87
|
+
return self._insert_statements[type_]
|
|
88
|
+
except KeyError:
|
|
89
|
+
raise MissingTableConfigException(f"INTERNAL ERROR: No prepared statement has been registered for {type_}. You might want to consider fixing that.")
|
|
90
|
+
except TypeError:
|
|
91
|
+
raise MissingTableConfigException("INTERNAL ERROR: Statements have not been prepared. You must call `prepare_insert_statements` first.")
|
|
92
|
+
|
|
93
|
+
def for_each_table(self, action: Callable[[SqliteTable], None]):
|
|
94
|
+
"""
|
|
95
|
+
Call the `action` on each table.
|
|
96
|
+
|
|
97
|
+
:param action: A callback invoked on each table.
|
|
98
|
+
"""
|
|
99
|
+
for t in self.tables:
|
|
100
|
+
action(t)
|
|
101
|
+
|
|
102
|
+
def prepare_insert_statements(self, connection: Connection):
|
|
103
|
+
"""
|
|
104
|
+
Create a `PreparedStatement` for inserting into each table.
|
|
105
|
+
|
|
106
|
+
:param connection: The `Connection` to prepare the statements on.
|
|
107
|
+
"""
|
|
108
|
+
self._close_insert_statements()
|
|
109
|
+
|
|
110
|
+
# Make sure the underlying collection has been populated.
|
|
111
|
+
self._ensure_tables()
|
|
112
|
+
|
|
113
|
+
self._insert_cursor = connection.cursor()
|
|
114
|
+
self._insert_statements = dict()
|
|
115
|
+
for t, table in self._tables.items():
|
|
116
|
+
self._insert_statements[t] = PreparedStatement(table.prepared_insert_sql, self._insert_cursor)
|
|
117
|
+
|
|
118
|
+
def close(self):
|
|
119
|
+
self._close_insert_statements()
|
|
120
|
+
|
|
121
|
+
def _close_insert_statements(self):
|
|
122
|
+
try:
|
|
123
|
+
if self._insert_cursor:
|
|
124
|
+
self._insert_cursor.close()
|
|
125
|
+
self._insert_cursor = None
|
|
126
|
+
except ProgrammingError:
|
|
127
|
+
# Can be thrown when the database is closed
|
|
128
|
+
pass
|
|
129
|
+
|
|
130
|
+
if self.insert_statements:
|
|
131
|
+
for s in self.insert_statements:
|
|
132
|
+
s.close()
|
|
133
|
+
self._insert_statements = None
|
|
134
|
+
|
|
135
|
+
def _ensure_tables(self):
|
|
136
|
+
if not self._tables:
|
|
137
|
+
self._tables = {type(it): it for it in self._included_tables}
|