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,237 @@
|
|
|
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__ = ['EwbDataFilePaths']
|
|
7
|
+
|
|
8
|
+
from datetime import date, timedelta
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Callable, Iterator, Optional, List
|
|
11
|
+
|
|
12
|
+
from zepben.ewb import require
|
|
13
|
+
from zepben.ewb.database.paths.database_type import DatabaseType
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class EwbDataFilePaths:
|
|
17
|
+
"""Provides paths to all the various data files / folders used by EWB."""
|
|
18
|
+
|
|
19
|
+
def __init__(self, base_dir: Path,
|
|
20
|
+
create_path: bool = False,
|
|
21
|
+
create_directories_func: Callable[[Path], None] = lambda it: it.mkdir(parents=True),
|
|
22
|
+
is_directory: Callable[[Path], bool] = Path.is_dir,
|
|
23
|
+
exists: Callable[[Path], bool] = Path.exists,
|
|
24
|
+
list_files: Callable[[Path], Iterator[Path]] = Path.iterdir):
|
|
25
|
+
"""
|
|
26
|
+
:param base_dir: The root directory of the EWB data structure.
|
|
27
|
+
:param create_path: Create the root directory (and any missing parent folders) if it does not exist.
|
|
28
|
+
"""
|
|
29
|
+
self.create_directories_func = create_directories_func
|
|
30
|
+
self.is_directory = is_directory
|
|
31
|
+
self.exists = exists
|
|
32
|
+
self.list_files = list_files
|
|
33
|
+
self._base_dir = base_dir
|
|
34
|
+
|
|
35
|
+
if create_path:
|
|
36
|
+
self.create_directories_func(base_dir)
|
|
37
|
+
|
|
38
|
+
require(self.is_directory(base_dir), lambda: f"base_dir must be a directory")
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def base_dir(self):
|
|
42
|
+
"""The root directory of the EWB data structure."""
|
|
43
|
+
return self._base_dir
|
|
44
|
+
|
|
45
|
+
def customer(self, database_date: date) -> Path:
|
|
46
|
+
"""
|
|
47
|
+
Determine the path to the "customers" database for the specified date.
|
|
48
|
+
|
|
49
|
+
:param database_date: The :class:`date` to use for the "customers" database.
|
|
50
|
+
:return: The :class:`path` to the "customers" database for the specified date.
|
|
51
|
+
"""
|
|
52
|
+
return self._to_dated_path(database_date, DatabaseType.CUSTOMER.file_descriptor)
|
|
53
|
+
|
|
54
|
+
def diagram(self, database_date: date) -> Path:
|
|
55
|
+
"""
|
|
56
|
+
Determine the path to the "diagrams" database for the specified date.
|
|
57
|
+
|
|
58
|
+
:param database_date: The :class:`date` to use for the "diagrams" database.
|
|
59
|
+
:return: The :class:`path` to the "diagrams" database for the specified date.
|
|
60
|
+
"""
|
|
61
|
+
return self._to_dated_path(database_date, DatabaseType.DIAGRAM.file_descriptor)
|
|
62
|
+
|
|
63
|
+
def measurement(self, database_date: date) -> Path:
|
|
64
|
+
"""
|
|
65
|
+
Determine the path to the "measurements" database for the specified date.
|
|
66
|
+
|
|
67
|
+
:param database_date: The :class:`date` to use for the "measurements" database.
|
|
68
|
+
:return: The :class:`path` to the "measurements" database for the specified date.
|
|
69
|
+
"""
|
|
70
|
+
return self._to_dated_path(database_date, DatabaseType.MEASUREMENT.file_descriptor)
|
|
71
|
+
|
|
72
|
+
def network_model(self, database_date: date) -> Path:
|
|
73
|
+
"""
|
|
74
|
+
Determine the path to the "network model" database for the specified date.
|
|
75
|
+
|
|
76
|
+
:param database_date: The :class:`date` to use for the "network model" database.
|
|
77
|
+
:return: The :class:`path` to the "network model" database for the specified date.
|
|
78
|
+
"""
|
|
79
|
+
return self._to_dated_path(database_date, DatabaseType.NETWORK_MODEL.file_descriptor)
|
|
80
|
+
|
|
81
|
+
def tile_cache(self, database_date: date) -> Path:
|
|
82
|
+
"""
|
|
83
|
+
Determine the path to the "tile cache" database for the specified date.
|
|
84
|
+
|
|
85
|
+
:param database_date: The :class:`date` to use for the "tile cache" database.
|
|
86
|
+
:return: The :class:`path` to the "tile cache" database for the specified date.
|
|
87
|
+
"""
|
|
88
|
+
return self._to_dated_path(database_date, DatabaseType.TILE_CACHE.file_descriptor)
|
|
89
|
+
|
|
90
|
+
def energy_reading(self, database_date: date) -> Path:
|
|
91
|
+
"""
|
|
92
|
+
Determine the path to the "energy readings" database for the specified date.
|
|
93
|
+
|
|
94
|
+
:param database_date: The :class:`date` to use for the "energy readings" database.
|
|
95
|
+
:return: The :class:`path` to the "energy readings" database for the specified date.
|
|
96
|
+
"""
|
|
97
|
+
return self._to_dated_path(database_date, DatabaseType.ENERGY_READING.file_descriptor)
|
|
98
|
+
|
|
99
|
+
def energy_readings_index(self) -> Path:
|
|
100
|
+
"""
|
|
101
|
+
Determine the path to the "energy readings index" database.
|
|
102
|
+
|
|
103
|
+
:return: The :class:`path` to the "energy readings index" database.
|
|
104
|
+
"""
|
|
105
|
+
return self._base_dir.joinpath(f"{DatabaseType.ENERGY_READINGS_INDEX.file_descriptor}.sqlite")
|
|
106
|
+
|
|
107
|
+
def load_aggregator_meters_by_date(self) -> Path:
|
|
108
|
+
"""
|
|
109
|
+
Determine the path to the "load aggregator meters-by-date" database.
|
|
110
|
+
|
|
111
|
+
:return: The :class:`path` to the "load aggregator meters-by-date" database.
|
|
112
|
+
"""
|
|
113
|
+
return self._base_dir.joinpath(f"{DatabaseType.LOAD_AGGREGATOR_METERS_BY_DATE.file_descriptor}.sqlite")
|
|
114
|
+
|
|
115
|
+
def weather_reading(self) -> Path:
|
|
116
|
+
"""
|
|
117
|
+
Determine the path to the "weather readings" database.
|
|
118
|
+
|
|
119
|
+
:return: The :class:`path` to the "weather readings" database.
|
|
120
|
+
"""
|
|
121
|
+
return self._base_dir.joinpath(f"{DatabaseType.WEATHER_READING.file_descriptor}.sqlite")
|
|
122
|
+
|
|
123
|
+
def results_cache(self) -> Path:
|
|
124
|
+
"""
|
|
125
|
+
Determine the path to the "results cache" database.
|
|
126
|
+
|
|
127
|
+
:return: The :class:`path` to the "results cache" database.
|
|
128
|
+
"""
|
|
129
|
+
return self._base_dir.joinpath(f"{DatabaseType.RESULTS_CACHE.file_descriptor}.sqlite")
|
|
130
|
+
|
|
131
|
+
def create_directories(self, database_date: date) -> Path:
|
|
132
|
+
"""
|
|
133
|
+
Create the directories required to have a valid path for the specified date.
|
|
134
|
+
|
|
135
|
+
:param database_date: The :class:`date` required in the path.
|
|
136
|
+
:return: The :class:`path` to the directory for the `database_date`.
|
|
137
|
+
"""
|
|
138
|
+
date_path = self._base_dir.joinpath(str(database_date))
|
|
139
|
+
if self.exists(date_path):
|
|
140
|
+
return date_path
|
|
141
|
+
else:
|
|
142
|
+
self.create_directories_func(date_path)
|
|
143
|
+
return date_path
|
|
144
|
+
|
|
145
|
+
def _to_dated_path(self, database_date: date, file: str) -> Path:
|
|
146
|
+
return self._base_dir.joinpath(str(database_date), f"{database_date}-{file}.sqlite")
|
|
147
|
+
|
|
148
|
+
def _check_exists(self, database_type: DatabaseType, database_date: date) -> bool:
|
|
149
|
+
"""
|
|
150
|
+
Check if a database of the specified type and date exists.
|
|
151
|
+
|
|
152
|
+
:param database_type: The type of database to search for.
|
|
153
|
+
:param database_date: The date to check.
|
|
154
|
+
:return: `True` if a database of the specified `database_type` and `database_date` exists in the date path.
|
|
155
|
+
"""
|
|
156
|
+
if not database_type.per_date:
|
|
157
|
+
raise ValueError("INTERNAL ERROR: Should only be calling `checkExists` for `perDate` files.")
|
|
158
|
+
|
|
159
|
+
if database_type == DatabaseType.CUSTOMER:
|
|
160
|
+
model_path = self.customer(database_date)
|
|
161
|
+
elif database_type == DatabaseType.DIAGRAM:
|
|
162
|
+
model_path = self.diagram(database_date)
|
|
163
|
+
elif database_type == DatabaseType.MEASUREMENT:
|
|
164
|
+
model_path = self.measurement(database_date)
|
|
165
|
+
elif database_type == DatabaseType.NETWORK_MODEL:
|
|
166
|
+
model_path = self.network_model(database_date)
|
|
167
|
+
elif database_type == DatabaseType.TILE_CACHE:
|
|
168
|
+
model_path = self.tile_cache(database_date)
|
|
169
|
+
elif database_type == DatabaseType.ENERGY_READING:
|
|
170
|
+
model_path = self.energy_reading(database_date)
|
|
171
|
+
else:
|
|
172
|
+
raise ValueError(
|
|
173
|
+
"INTERNAL ERROR: Should only be calling `check_exists` for `per_date` files, which should all be covered above, so go ahead and add it.")
|
|
174
|
+
return self.exists(model_path)
|
|
175
|
+
|
|
176
|
+
def find_closest(self, database_type: DatabaseType, max_days_to_search: int = 999, target_date: date = date.today(), search_forwards: bool = False) -> \
|
|
177
|
+
Optional[date]:
|
|
178
|
+
"""
|
|
179
|
+
Find the closest date with a usable database of the specified type.
|
|
180
|
+
|
|
181
|
+
:param database_type: The type of database to search for.
|
|
182
|
+
:param max_days_to_search: The maximum number of days to search for a valid database.
|
|
183
|
+
:param target_date: The target :class:`date`. Defaults to today.
|
|
184
|
+
:param search_forwards: Indicates the search should also look forwards in time from `start_date` for a valid file. Defaults to reverse search only.
|
|
185
|
+
:return: The closest :class:`date` to `database_date` with a valid database of `database_type` within the search parameters, or `None` if no valid database was found.
|
|
186
|
+
"""
|
|
187
|
+
if not database_type.per_date:
|
|
188
|
+
return None
|
|
189
|
+
|
|
190
|
+
if self._check_exists(database_type, target_date):
|
|
191
|
+
return target_date
|
|
192
|
+
|
|
193
|
+
offset = 1
|
|
194
|
+
|
|
195
|
+
while offset <= max_days_to_search:
|
|
196
|
+
offset_days = timedelta(offset)
|
|
197
|
+
try:
|
|
198
|
+
previous_date = target_date - offset_days
|
|
199
|
+
if self._check_exists(database_type, previous_date):
|
|
200
|
+
return previous_date
|
|
201
|
+
except OverflowError:
|
|
202
|
+
pass
|
|
203
|
+
|
|
204
|
+
if search_forwards:
|
|
205
|
+
try:
|
|
206
|
+
forward_date = target_date + offset_days
|
|
207
|
+
if self._check_exists(database_type, forward_date):
|
|
208
|
+
return forward_date
|
|
209
|
+
except OverflowError:
|
|
210
|
+
pass
|
|
211
|
+
offset += 1
|
|
212
|
+
return None
|
|
213
|
+
|
|
214
|
+
def _get_available_dates_for(self, database_type: DatabaseType) -> List[date]:
|
|
215
|
+
if not database_type.per_date:
|
|
216
|
+
raise ValueError(
|
|
217
|
+
"INTERNAL ERROR: Should only be calling `_get_available_dates_for` for `per_date` files.")
|
|
218
|
+
|
|
219
|
+
to_return = list()
|
|
220
|
+
|
|
221
|
+
for file in self.list_files(self._base_dir):
|
|
222
|
+
if self.is_directory(file):
|
|
223
|
+
try:
|
|
224
|
+
database_date = date.fromisoformat(file.name)
|
|
225
|
+
if self.exists(self._to_dated_path(database_date, database_type.file_descriptor)):
|
|
226
|
+
to_return.append(database_date)
|
|
227
|
+
except ValueError:
|
|
228
|
+
pass
|
|
229
|
+
return sorted(to_return)
|
|
230
|
+
|
|
231
|
+
def get_network_model_databases(self) -> List[date]:
|
|
232
|
+
"""
|
|
233
|
+
Find available network-model databases in data path.
|
|
234
|
+
|
|
235
|
+
:return: A list of :class:`date`'s for which network-model databases exist in the data path.
|
|
236
|
+
"""
|
|
237
|
+
return self._get_available_dates_for(DatabaseType.NETWORK_MODEL)
|
|
@@ -0,0 +1,212 @@
|
|
|
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__ = ["BaseCimReader"]
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
from abc import ABC
|
|
10
|
+
from typing import Callable, Optional, Type
|
|
11
|
+
|
|
12
|
+
from zepben.ewb.database.sqlite.common.reader_exceptions import DuplicateMRIDException
|
|
13
|
+
from zepben.ewb.database.sqlite.extensions.result_set import ResultSet
|
|
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, TIdentifiedObject
|
|
24
|
+
from zepben.ewb.model.cim.iec61970.base.core.name_type import NameType
|
|
25
|
+
from zepben.ewb.services.common.base_service import BaseService
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class BaseCimReader(ABC):
|
|
29
|
+
"""
|
|
30
|
+
A base class for reading CIM objects from a database.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
def __init__(self, service: BaseService):
|
|
34
|
+
super().__init__()
|
|
35
|
+
self._logger: logging.Logger = logging.getLogger(self.__class__.__name__)
|
|
36
|
+
"""The `Logger` to use for this reader."""
|
|
37
|
+
|
|
38
|
+
self._service = service
|
|
39
|
+
"""The `BaseService` used to store any items read from the database."""
|
|
40
|
+
|
|
41
|
+
###################
|
|
42
|
+
# IEC61968 Common #
|
|
43
|
+
###################
|
|
44
|
+
|
|
45
|
+
def _load_document(self, document: Document, table: TableDocuments, result_set: ResultSet) -> bool:
|
|
46
|
+
"""
|
|
47
|
+
Populate the `Document` fields from `TableDocuments`.
|
|
48
|
+
|
|
49
|
+
:param document: The `Document` instance to populate.
|
|
50
|
+
:param table: The database table to read the `Document` fields from.
|
|
51
|
+
:param result_set: The record in the database table containing the fields for this `Document`.
|
|
52
|
+
|
|
53
|
+
:return: True if the `Document` was successfully read from the database and added to the service.
|
|
54
|
+
:raises SQLException: For any errors encountered reading from the database.
|
|
55
|
+
"""
|
|
56
|
+
document.title = result_set.get_string(table.title.query_index, on_none="")
|
|
57
|
+
document.created_date_time = result_set.get_instant(table.created_date_time.query_index, on_none=None)
|
|
58
|
+
document.author_name = result_set.get_string(table.author_name.query_index, on_none="")
|
|
59
|
+
document.type = result_set.get_string(table.type.query_index, on_none="")
|
|
60
|
+
document.status = result_set.get_string(table.status.query_index, on_none="")
|
|
61
|
+
document.comment = result_set.get_string(table.comment.query_index, on_none="")
|
|
62
|
+
|
|
63
|
+
return self._load_identified_object(document, table, result_set)
|
|
64
|
+
|
|
65
|
+
def load_organisations(self, table: TableOrganisations, result_set: ResultSet, set_identifier: Callable[[str], str]) -> bool:
|
|
66
|
+
"""
|
|
67
|
+
Create an `Organisation` and populate its fields from `TableOrganisations`.
|
|
68
|
+
|
|
69
|
+
:param table: The database table to read the `Organisation` fields from.
|
|
70
|
+
:param result_set: The record in the database table containing the fields for this `Organisation`.
|
|
71
|
+
:param set_identifier: A callback to register the mRID of this `Organisation` for logging purposes.
|
|
72
|
+
|
|
73
|
+
:return: True if the `Organisation` was successfully read from the database and added to the service.
|
|
74
|
+
:raises SQLException: For any errors encountered reading from the database.
|
|
75
|
+
"""
|
|
76
|
+
organisation = Organisation(mrid=set_identifier(result_set.get_string(table.mrid.query_index)))
|
|
77
|
+
|
|
78
|
+
return self._load_identified_object(organisation, table, result_set) and self._add_or_throw(organisation)
|
|
79
|
+
|
|
80
|
+
def _load_organisation_role(self, organisation_role: OrganisationRole, table: TableOrganisationRoles, result_set: ResultSet) -> bool:
|
|
81
|
+
"""
|
|
82
|
+
Populate the `OrganisationRole` fields from `TableOrganisationRoles`.
|
|
83
|
+
|
|
84
|
+
:param organisation_role: The `OrganisationRole` instance to populate.
|
|
85
|
+
:param table: The database table to read the `OrganisationRole` fields from.
|
|
86
|
+
:param result_set: The record in the database table containing the fields for this `OrganisationRole`.
|
|
87
|
+
|
|
88
|
+
:return: True if the `OrganisationRole` was successfully read from the database and added to the service.
|
|
89
|
+
:raises SQLException: For any errors encountered reading from the database.
|
|
90
|
+
"""
|
|
91
|
+
organisation_role.organisation = self._ensure_get(
|
|
92
|
+
result_set.get_string(table.organisation_mrid.query_index, on_none=None),
|
|
93
|
+
Organisation
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
return self._load_identified_object(organisation_role, table, result_set)
|
|
97
|
+
|
|
98
|
+
######################
|
|
99
|
+
# IEC61970 Base Core #
|
|
100
|
+
######################
|
|
101
|
+
|
|
102
|
+
@staticmethod
|
|
103
|
+
def _load_identified_object(identified_object: IdentifiedObject, table: TableIdentifiedObjects, result_set: ResultSet) -> bool:
|
|
104
|
+
"""
|
|
105
|
+
Populate the `IdentifiedObject` fields from `TableIdentifiedObjects`.
|
|
106
|
+
|
|
107
|
+
:param identified_object: The `IdentifiedObject` instance to populate.
|
|
108
|
+
:param table: The database table to read the `IdentifiedObject` fields from.
|
|
109
|
+
:param result_set: The record in the database table containing the fields for this `IdentifiedObject`.
|
|
110
|
+
|
|
111
|
+
:return: True if the `IdentifiedObject` was successfully read from the database and added to the service.
|
|
112
|
+
:raises SQLException: For any errors encountered reading from the database.
|
|
113
|
+
"""
|
|
114
|
+
identified_object.name = result_set.get_string(table.name_.query_index, on_none="")
|
|
115
|
+
identified_object.description = result_set.get_string(table.description.query_index, on_none="")
|
|
116
|
+
# Currently unused
|
|
117
|
+
# identified_object.num_diagram_objects = result_set.get_int(table.num_diagram_objects.query_index)
|
|
118
|
+
|
|
119
|
+
return True
|
|
120
|
+
|
|
121
|
+
def load_names(self, table: TableNames, result_set: ResultSet, set_last_name: Callable[[str], str]) -> bool:
|
|
122
|
+
"""
|
|
123
|
+
Create a `Name` and populate its fields from `TableNames`.
|
|
124
|
+
|
|
125
|
+
:param table: The database table to read the `Name` fields from.
|
|
126
|
+
:param result_set: The record in the database table containing the fields for this `Name`.
|
|
127
|
+
:param set_last_name: A callback to register the name of this `Name` for logging purposes.
|
|
128
|
+
|
|
129
|
+
:return: True if the `Name` was successfully read from the database and added to the service.
|
|
130
|
+
:raises SQLException: For any errors encountered reading from the database.
|
|
131
|
+
"""
|
|
132
|
+
name_type_name = result_set.get_string(table.name_type_name.query_index)
|
|
133
|
+
name_name = result_set.get_string(table.name_.query_index)
|
|
134
|
+
set_last_name(f"{name_type_name}:{name_name}")
|
|
135
|
+
|
|
136
|
+
name_type = self._service.get_name_type(name_type_name)
|
|
137
|
+
self._service.get(
|
|
138
|
+
result_set.get_string(table.identified_object_mrid.query_index),
|
|
139
|
+
IdentifiedObject,
|
|
140
|
+
generate_error=lambda mrid, typ: f"Failed to find {typ} with mRID {mrid} for Name {name_name} [{name_type_name}]"
|
|
141
|
+
).add_name(name_type, name_name)
|
|
142
|
+
|
|
143
|
+
return True
|
|
144
|
+
|
|
145
|
+
def load_name_types(self, table: TableNameTypes, result_set: ResultSet, set_last_name_type: Callable[[str], str]) -> bool:
|
|
146
|
+
"""
|
|
147
|
+
Create a `NameType` and populate its fields from `TableNameTypes`.
|
|
148
|
+
|
|
149
|
+
:param table: The database table to read the `NameType` fields from.
|
|
150
|
+
:param result_set: The record in the database table containing the fields for this `NameType`.
|
|
151
|
+
:param set_last_name_type: A callback to register the name of this `NameType` for logging purposes.
|
|
152
|
+
|
|
153
|
+
:return: True if the `NameType` was successfully read from the database and added to the service.
|
|
154
|
+
:raises SQLException: For any errors encountered reading from the database.
|
|
155
|
+
"""
|
|
156
|
+
# noinspection PyArgumentList
|
|
157
|
+
name_type = NameType(set_last_name_type(result_set.get_string(table.name_.query_index)))
|
|
158
|
+
name_type.description = result_set.get_string(table.description.query_index)
|
|
159
|
+
|
|
160
|
+
return self._add_or_throw_name_type(name_type)
|
|
161
|
+
|
|
162
|
+
def _add_or_throw(self, identified_object: IdentifiedObject) -> bool:
|
|
163
|
+
"""
|
|
164
|
+
Try and add the `identified_object` to the `service`, and throw an `Exception` if unsuccessful.
|
|
165
|
+
|
|
166
|
+
:param identified_object: The `IdentifiedObject` to add to the `service`.
|
|
167
|
+
|
|
168
|
+
:return: True in all instances, otherwise it throws.
|
|
169
|
+
:raises DuplicateMRIDException: If the `IdentifiedObject.mRID` has already been used.
|
|
170
|
+
:raises UnsupportedIdentifiedObjectException: If the `IdentifiedObject` is not supported by the `service`. This is an indication of an internal coding
|
|
171
|
+
issue, rather than a problem with the data being read, and in a correctly configured system will never occur.
|
|
172
|
+
"""
|
|
173
|
+
if self._service.add(identified_object):
|
|
174
|
+
return True
|
|
175
|
+
else:
|
|
176
|
+
duplicate = self._service.get(identified_object.mrid)
|
|
177
|
+
raise DuplicateMRIDException(
|
|
178
|
+
f"Failed to load {identified_object}. " +
|
|
179
|
+
f"Unable to add to service '{self._service.name}': duplicate MRID ({duplicate})"
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
def _add_or_throw_name_type(self, name_type: NameType) -> bool:
|
|
183
|
+
"""
|
|
184
|
+
Try and add the `name_type` to the `service`, and throw an `Exception` if unsuccessful.
|
|
185
|
+
|
|
186
|
+
:param name_type: The `NameType` to add to the `service`.
|
|
187
|
+
|
|
188
|
+
:return: True in all instances, otherwise it throws.
|
|
189
|
+
:raises DuplicateMRIDException: If the `NameType.name` has already been used.
|
|
190
|
+
"""
|
|
191
|
+
if self._service.add_name_type(name_type):
|
|
192
|
+
return True
|
|
193
|
+
else:
|
|
194
|
+
raise DuplicateMRIDException(
|
|
195
|
+
f"Failed to load NameType {name_type.name}. " +
|
|
196
|
+
f"Unable to add to service '{self._service.name}': duplicate NameType)"
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
def _ensure_get(self, mrid: Optional[str], type_: Type[TIdentifiedObject] = IdentifiedObject) -> Optional[TIdentifiedObject]:
|
|
200
|
+
"""
|
|
201
|
+
Optionally get an object associated with this service and throw if it is not found.
|
|
202
|
+
|
|
203
|
+
:param mrid: The mRID of the object to find.
|
|
204
|
+
:param type_: The type of object to look for. If this is a base class it will search all subclasses.
|
|
205
|
+
|
|
206
|
+
:return: The object identified by `mrid` as `type_` if it was found, or null if no `mrid` was supplied.
|
|
207
|
+
:raises MRIDLookupException: if no objects of type `type_` are found with the specified `mrid`
|
|
208
|
+
"""
|
|
209
|
+
if (mrid is None) or (len(mrid) == 0):
|
|
210
|
+
return None
|
|
211
|
+
else:
|
|
212
|
+
return self._service.get(mrid, type_)
|
|
@@ -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
|