zepben.ewb 1.0.0b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/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 +173 -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/column.py +37 -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 +142 -0
- zepben/ewb/database/sqlite/tables/table_metadata_data_sources.py +21 -0
- zepben/ewb/database/sqlite/tables/table_version.py +38 -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 +35 -0
- zepben/ewb/model/cim/extensions/iec61970/base/protection/protection_kind.py +113 -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 +82 -0
- zepben/ewb/model/cim/extensions/iec61970/base/wires/transformer_cooling_type.py +56 -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 +292 -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 +55 -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 +45 -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 +67 -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 +67 -0
- zepben/ewb/model/cim/iec61968/infiec61968/infassetinfo/transformer_function_kind.py +43 -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 +25 -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 +150 -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 +46 -0
- zepben/ewb/model/cim/iec61968/metering/meter.py +26 -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 +28 -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 +124 -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 +234 -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 +201 -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 +26 -0
- zepben/ewb/model/cim/iec61970/base/diagramlayout/orientation_kind.py +27 -0
- zepben/ewb/model/cim/iec61970/base/domain/__init__.py +4 -0
- zepben/ewb/model/cim/iec61970/base/domain/unit_symbol.py +492 -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 +37 -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 +16 -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 +38 -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 +46 -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 +105 -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 +28 -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 +44 -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 +43 -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 +92 -0
- zepben/ewb/services/common/translator/base_proto2cim.py +112 -0
- zepben/ewb/services/common/translator/service_differences.py +81 -0
- zepben/ewb/services/common/translator/util.py +78 -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 +34 -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 +71 -0
- zepben/ewb/services/network/tracing/networktrace/actions/tree_node.py +37 -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 +450 -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 +125 -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 +1782 -0
- zepben/ewb/services/network/translator/network_enum_mappers.py +78 -0
- zepben/ewb/services/network/translator/network_proto2cim.py +2147 -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 +34 -0
- zepben/ewb/streaming/get/included_energizing_containers.py +34 -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 +185 -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 +189 -0
- zepben_ewb-1.0.0b1.dist-info/METADATA +102 -0
- zepben_ewb-1.0.0b1.dist-info/RECORD +639 -0
- zepben_ewb-1.0.0b1.dist-info/WHEEL +5 -0
- zepben_ewb-1.0.0b1.dist-info/licenses/LICENSE +374 -0
- zepben_ewb-1.0.0b1.dist-info/top_level.txt +1 -0
|
@@ -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}
|
|
@@ -0,0 +1,195 @@
|
|
|
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__ = ["BaseDatabaseWriter"]
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
import os
|
|
10
|
+
from abc import ABC
|
|
11
|
+
from contextlib import closing
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
from sqlite3 import Connection, Cursor, OperationalError
|
|
14
|
+
from typing import Callable, Union
|
|
15
|
+
|
|
16
|
+
from zepben.ewb.database.sqlite.common.base_database_tables import BaseDatabaseTables
|
|
17
|
+
from zepben.ewb.database.sqlite.common.base_service_writer import BaseServiceWriter
|
|
18
|
+
from zepben.ewb.database.sqlite.common.metadata_collection_writer import MetadataCollectionWriter
|
|
19
|
+
from zepben.ewb.database.sqlite.extensions.prepared_statement import SqlException, PreparedStatement
|
|
20
|
+
from zepben.ewb.database.sqlite.tables.exceptions import MissingTableConfigException
|
|
21
|
+
from zepben.ewb.database.sqlite.tables.sqlite_table import SqliteTable
|
|
22
|
+
from zepben.ewb.database.sqlite.tables.table_version import TableVersion
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class BaseDatabaseWriter(ABC):
|
|
26
|
+
"""
|
|
27
|
+
A base class for writing objects to one of our databases.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def __init__(
|
|
31
|
+
self,
|
|
32
|
+
database_file: Union[Path, str],
|
|
33
|
+
database_tables: BaseDatabaseTables,
|
|
34
|
+
create_metadata_writer: Callable[[], MetadataCollectionWriter],
|
|
35
|
+
create_service_writer: Callable[[], BaseServiceWriter],
|
|
36
|
+
get_connection: Callable[[str], Connection]
|
|
37
|
+
):
|
|
38
|
+
super().__init__()
|
|
39
|
+
self._logger: logging.Logger = logging.getLogger(self.__class__.__name__)
|
|
40
|
+
"""
|
|
41
|
+
The logger to use for this database writer.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
self._database_file: str = str(database_file)
|
|
45
|
+
"""
|
|
46
|
+
The filename of the database to write.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
self._database_tables: BaseDatabaseTables = database_tables
|
|
50
|
+
"""
|
|
51
|
+
The tables to create in the database.
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
self._create_metadata_writer: Callable[[], MetadataCollectionWriter] = create_metadata_writer
|
|
55
|
+
"""
|
|
56
|
+
Create a [MetadataCollectionWriter] that uses the provided [Connection].
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
self._create_service_writer: Callable[[], BaseServiceWriter] = create_service_writer
|
|
60
|
+
"""
|
|
61
|
+
Create a [BaseServiceWriter] that uses the provided [Connection].
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
self._get_connection: Callable[[str], Connection] = get_connection
|
|
65
|
+
"""
|
|
66
|
+
Provider of the connection to the specified database.
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
self._save_connection: Connection
|
|
70
|
+
self._has_been_used: bool = False
|
|
71
|
+
|
|
72
|
+
def save(self) -> bool:
|
|
73
|
+
"""
|
|
74
|
+
Save the database using the [MetadataCollectionWriter] and [BaseServiceWriter].
|
|
75
|
+
|
|
76
|
+
@return True if the database was successfully saved, otherwise False.
|
|
77
|
+
"""
|
|
78
|
+
if self._has_been_used:
|
|
79
|
+
self._logger.error(f"You can only use the database writer once.")
|
|
80
|
+
return False
|
|
81
|
+
self._has_been_used = True
|
|
82
|
+
|
|
83
|
+
if not self._pre_save():
|
|
84
|
+
self._close_connection()
|
|
85
|
+
return False
|
|
86
|
+
|
|
87
|
+
status: bool
|
|
88
|
+
try:
|
|
89
|
+
status = all([
|
|
90
|
+
self._create_metadata_writer().save(),
|
|
91
|
+
self._create_service_writer().save()
|
|
92
|
+
])
|
|
93
|
+
except MissingTableConfigException as e:
|
|
94
|
+
self._logger.exception(f"Unable to save database: {e}")
|
|
95
|
+
status = False
|
|
96
|
+
|
|
97
|
+
return all([status, self._post_save()])
|
|
98
|
+
|
|
99
|
+
def _pre_save(self) -> bool:
|
|
100
|
+
return (self._remove_existing()
|
|
101
|
+
and self._connect()
|
|
102
|
+
and self._create()
|
|
103
|
+
and self._prepare_insert_statements())
|
|
104
|
+
|
|
105
|
+
def _remove_existing(self) -> bool:
|
|
106
|
+
try:
|
|
107
|
+
if os.path.isfile(self._database_file):
|
|
108
|
+
os.remove(self._database_file)
|
|
109
|
+
return True
|
|
110
|
+
except Exception as e:
|
|
111
|
+
self._logger.exception(f"Unable to save database, failed to remove previous instance: {e}")
|
|
112
|
+
return False
|
|
113
|
+
|
|
114
|
+
def _connect(self) -> bool:
|
|
115
|
+
try:
|
|
116
|
+
self._save_connection = self._get_connection(self._database_file)
|
|
117
|
+
|
|
118
|
+
cur: Cursor
|
|
119
|
+
with closing(self._save_connection.cursor()) as cur:
|
|
120
|
+
cur.execute("PRAGMA journal_mode = OFF")
|
|
121
|
+
cur.execute("PRAGMA synchronous = OFF")
|
|
122
|
+
|
|
123
|
+
self._save_connection.isolation_level = None # autocommit off
|
|
124
|
+
|
|
125
|
+
return True
|
|
126
|
+
except (SqlException, OperationalError) as e:
|
|
127
|
+
self._logger.exception(f"Failed to connect to the database for saving: {e}")
|
|
128
|
+
self._close_connection()
|
|
129
|
+
return False
|
|
130
|
+
|
|
131
|
+
def _prepare_insert_statements(self) -> bool:
|
|
132
|
+
try:
|
|
133
|
+
self._database_tables.prepare_insert_statements(self._save_connection)
|
|
134
|
+
return True
|
|
135
|
+
except SqlException as e:
|
|
136
|
+
self._logger.exception(f"Failed to prepare insert statements: {e}")
|
|
137
|
+
self._close_connection()
|
|
138
|
+
return False
|
|
139
|
+
|
|
140
|
+
def _create(self) -> bool:
|
|
141
|
+
try:
|
|
142
|
+
version_table = self._database_tables.get_table(TableVersion)
|
|
143
|
+
self._logger.info(f"Creating database schema v{version_table.SUPPORTED_VERSION}...")
|
|
144
|
+
|
|
145
|
+
cur: Cursor
|
|
146
|
+
with closing(self._save_connection.cursor()) as cur:
|
|
147
|
+
def create_table(it: SqliteTable):
|
|
148
|
+
cur.execute(it.create_table_sql)
|
|
149
|
+
|
|
150
|
+
self._database_tables.for_each_table(create_table)
|
|
151
|
+
|
|
152
|
+
# Add the version number to the database.
|
|
153
|
+
insert = PreparedStatement(version_table.prepared_insert_sql, cur)
|
|
154
|
+
insert.add_value(version_table.version.query_index, version_table.SUPPORTED_VERSION)
|
|
155
|
+
insert.execute()
|
|
156
|
+
|
|
157
|
+
self._save_connection.commit()
|
|
158
|
+
self._logger.info("Schema created.")
|
|
159
|
+
|
|
160
|
+
return True
|
|
161
|
+
except SqlException as e:
|
|
162
|
+
self._logger.exception(f"Failed to create database schema: {e}")
|
|
163
|
+
return False
|
|
164
|
+
|
|
165
|
+
def _close_connection(self):
|
|
166
|
+
try:
|
|
167
|
+
if self._save_connection is not None:
|
|
168
|
+
self._save_connection.close()
|
|
169
|
+
except SqlException as e:
|
|
170
|
+
self._logger.exception(f"Failed to close connection to database: {e}")
|
|
171
|
+
|
|
172
|
+
def _post_save(self) -> bool:
|
|
173
|
+
try:
|
|
174
|
+
self._logger.info("Adding indexes...")
|
|
175
|
+
|
|
176
|
+
cur: Cursor
|
|
177
|
+
with closing(self._save_connection.cursor()) as cur:
|
|
178
|
+
def create_indexes(it: SqliteTable):
|
|
179
|
+
for sql in it.create_indexes_sql:
|
|
180
|
+
cur.execute(sql)
|
|
181
|
+
|
|
182
|
+
self._database_tables.for_each_table(create_indexes)
|
|
183
|
+
|
|
184
|
+
self._logger.info("Indexes added.")
|
|
185
|
+
self._logger.info("Committing...")
|
|
186
|
+
|
|
187
|
+
self._save_connection.commit()
|
|
188
|
+
|
|
189
|
+
self._logger.info("Done.")
|
|
190
|
+
return True
|
|
191
|
+
except SqlException as e:
|
|
192
|
+
self._logger.exception(f"Failed to finalise the database: {e}")
|
|
193
|
+
return False
|
|
194
|
+
finally:
|
|
195
|
+
self._close_connection()
|
|
@@ -0,0 +1,34 @@
|
|
|
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__ = ["BaseEntryWriter"]
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
from abc import ABC
|
|
10
|
+
|
|
11
|
+
from zepben.ewb.database.sqlite.extensions.prepared_statement import PreparedStatement
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BaseEntryWriter(ABC):
|
|
15
|
+
"""
|
|
16
|
+
A base class for writing entries into tables of the database.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def __init__(self):
|
|
20
|
+
self._logger = logging.getLogger(self.__class__.__name__)
|
|
21
|
+
|
|
22
|
+
def _try_execute_single_update(self, prepared_statement: PreparedStatement, description: str) -> bool:
|
|
23
|
+
"""
|
|
24
|
+
Helper function for writing the entry to the database and logging any failures.
|
|
25
|
+
|
|
26
|
+
:param prepared_statement: The `PreparedStatement` to execute.
|
|
27
|
+
:param description: A description of the object being written to use for logging of failures.
|
|
28
|
+
:return: True if the entry was successfully written to the database, otherwise False.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def log_failure(ex: Exception):
|
|
32
|
+
prepared_statement.log_failure(self._logger, description, ex)
|
|
33
|
+
|
|
34
|
+
return prepared_statement.try_execute_single_update(log_failure)
|