Skip to main content

PYORPS - (Python for Optimal Routes in Power Systems)

Project description

PYORPS - Python for Optimal Routes in Power Systems

PyPI version Python Versions Documentation Status codecov Codacy Badge License Binder

PYORPS is an open-source tool designed to automate route planning for underground cables in power systems. It uses high-resolution raster geodata to perform least-cost path analyses, optimizing routes based on economic and environmental factors.

Overview

Power line route planning is a complex and time-consuming process traditionally neglected in early grid planning. PYORPS addresses this by:

  • Finding optimal routes between connection points using least-cost path analysis
  • Supporting high-resolution raster data for precise planning
  • Considering both economic costs and environmental constraints
  • Allowing customization of neighborhood selection and search parameters
  • Enabling easy integration into existing planning workflows

While tailored for distribution grids, it can be adapted for various infrastructures, optimizing routes for cost and environmental impact.

ex.
Figure 1: Parallel computation of 21 paths from single source to multiple targets.
332 s total runtime on laptop with Intel(R) Core(TM) i7-8850H CPU @ 2.6 GHz and 32 GB memory

Features

  • Flexible Input Data: Use local raster files directly or create custom rasterized geodata from WFS services or local vector files
  • Customizable Costs: Define terrain-specific cost values based on installation expenses or environmental impacts
  • Multiple Path Finding: Calculate optimal routes between multiple sources and targets in parallel
  • Performance Optimization: Control search space parameters to balance accuracy and computational efficiency
  • Environmental Consideration: Add cost modifiers for nature reserves, water protection zones, and other sensitive regions
  • GIS Integration: Export results as GeoJSON for further analysis in GIS applications

Quick Start

Here's a minimal example to get you started:

from pyorps import PathFinder

# Define a file path to a raster file! 
raster_path = r"<PATH>\<TO>\<YOUR>\<RASTER_FILE>.tiff" 

# Define your source and target coordinates (must be in the same CRS)
source = (..., ...)
target = (..., ...)

# Create PathFinder instance
path_finder = PathFinder(
    dataset_source=raster_path,
    source_coords=source,
    target_coords=target,
)

# Find optimal route
path_finder.find_route()

# Visualize results
path_finder.plot_paths()

# Export to GeoJSON
path_finder.save_paths(r"<PATH>\<TO>\<YOUR>\<RESULTS>.geojson" )

Please check out the example for creating and setting up a dedicated raster dataset for your planning task.

Binder - Run Examples

You can quickly start testing the functionalities of PYORPS using Binder. Click the badge below to launch an interactive environment where you can run the example notebooks directly in your browser.

Binder

This Binder connection allows you to explore the examples provided in the examples directory without needing to install anything on your local machine. It's a great way to get a hands-on experience with PYORPS and see how it can optimize route planning for power systems.

Installation

You can easily install PYORPS from the Python Package Index (PyPI) using pip or other package management tools.

Using pip

You can install the base package using pip:

pip install pyorps

This command will install the core functionality of PYORPS along with its essential dependencies, including:

Optional Dependencies

PYORPS offers several optional dependencies that enhance its functionality. You can install these extras by specifying them in square brackets:

  • Examples: To include all dependencies for examples and case-studies:

    pip install pyorps[examples]
    
  • Case Studies: To include case study scripts:

    pip install pyorps[case_studies]
    
  • Development and Testing: To include testing tools and the tests directory:

    pip install pyorps[dev]
    
  • Full Installation: To install all optional dependencies at once:

    pip install pyorps[full]
    

How It Works

PYORPS performs route planning through these key steps:

  1. Data Preparation: Categorizes continuous land use data using GeoPandas
  2. Rasterization: Converts categorized geodata to raster format with cost values using Rasterio
  3. Graph Creation: Transforms rasterized dataset into a graph structure using NetworKit
  4. Path Analysis: Performs least-cost path analysis on the graph to find optimal routes
  5. Result Export: Exports results in GeoJSON format for further use in GIS applications

The process can be configured with different neighborhood selections (R0-R3) and search space parameters to balance accuracy and performance.

Use Cases

  • Distribution Grid Planning: Optimize new underground cable connections to increase grid capacity
  • Grid Integration of Renewable Energies: Determine optimal point of common coupling (PCC) and find the most economical route for grid integration
  • Environmental Impact Reduction: Route underground cables to minimize impact on protected areas
  • Cost Optimization: Balance construction costs with environmental considerations and other aspects
  • General Infrastructure Planning: Adapt for other linear infrastructure planning tasks (e.g. fiber optic cables or pipes)

Technical Details

Search Space Control: Buffering & Masking

Efficient path finding in large rasters requires limiting the search space. PYORPS provides:

  • Buffering: Define a buffer (in meters) around the source/target line or polygon, restricting the raster window and graph to relevant areas. Buffer size can be set manually or estimated automatically based on terrain complexity.
  • Masking: Apply geometric masks (e.g., polygons, convex hulls) to further restrict the area considered for routing. Pixels outside the mask are not considered.

This dramatically reduces memory and computation time, especially for high-resolution data.

search spaces
Figure 2: Various optimal paths for different search spaces on rasterised geodata with 1 m² resolution

Neighborhoods: Fine-Grained Connectivity

The raster-to-graph conversion supports customizable neighborhood definitions:

  • Predefined and tested neighborhoods:
    • R0 (4-connectivity), R1 (8-connectivity), R2 (16-connectivity), R3 (32-connectivity),
  • Custom neighborhoods:
    • Specify arbitrary step sets for advanced use cases or anisotropic cost surfaces.
  • High-order neighborhoods:
    • For k > 3, arbitrary neighborhoods are supported, enabling long-range or non-local connections.

This allows you to balance accuracy (following real-world paths) and performance (sparser graphs).

R3 complete
Figure 3a: Steps for neighbourhoods R0 (blue), R1 (green), R2 (yellow), and R3 (red)
intermediates
Figure 3b: Intermediate elements Ik for selected edges of vertex v5,5.

Data Input: Raster & Vector, Local & Remote

PYORPS is agnostic to data source and format:

  • Raster data:
    • Directly use high-resolution GeoTIFFs or similar formats (tested up to 0.25 m² per pixel).
  • Vector data:
    • Shapefiles, GeoJSON, GPKG, or remote WFS layers (e.g., land registry, nature reserves, water protection zones).
  • Hybrid workflows:
    • Rasterize vector data with custom cost assumptions, overlay multiple datasets, and apply complex modifications.

All data is internally harmonized to a common CRS and resolution.

Cost Assumptions: From Simple to Complex

Routing is driven by a cost raster. PYORPS supports:

  • Simple costs:
    • Assign a single cost per land use class or feature.
  • Hierarchical/multi-attribute costs:
    • Use CSV, Excel, or JSON files to define costs based on multiple attributes (e.g., land use + soil type).
  • Dynamic overlays:
    • Overlay additional datasets (e.g., protected areas) with additive or multiplicative cost modifiers, or set areas as forbidden.
  • Custom logic:
    • Apply buffers, ignore fields, or use complex rules for cost assignment.

Example: Cost Assumptions Table

land_use category cost
Forest Coniferous 365
Forest Mixed Deciduous/Coniferous 402
Forest Deciduous 438
Forest 365
Road traffic State road 196
Road traffic Federal road 231
Road traffic Highway 267
Path Footpath 107
Agriculture Arable land 107
Agriculture Grassland 107
Agriculture Orchard meadow 139
Flowing water 186
Sports, leisure, recreation area 65535
Standing water 155
Square Parking lot 178
Square Rest area 178
Rail traffic 415
Residential building area 65535
Industrial and commercial area 65535
... ... ...

How to use:

  • Use as a CSV file with columns (e.g. land_use, category, cost)
  • The cost value can be interpreted as €/m or as a relative score.
  • Use uint16 and set 65535 to indicate forbidden areas.

Rasterization: High-Resolution, Multi-Layer, and Overlay

  • High-resolution rasterization:
    • Rasterize vector data at arbitrary resolutions (tested up to 0.25 m² per pixel) using Rasterio.
  • Buffering and overlays:
    • Apply geometric buffers to features before rasterization.
    • Overlay multiple datasets, each with its own cost logic.
  • Selective masking:
    • Mask out fields or regions, set forbidden values, or combine multiple masks.

Supported Data Types

  • Vector formats: Shapefile, GeoJSON, GPKG, GML, KML, WFS (remote)
  • Raster formats: GeoTIFF, IMG, JP2, BIL, DEM, in-memory numpy arrays
  • Data sources: Land registry, nature reserves, water protection areas, custom user data

Various Graph Backends & Path-Finding Algorithms

PYORPS supports multiple high-performance graph libraries as interchangeable backends for path finding:

  • Cython: In PYORPS, specialized Cython implementations of path-finding algorithms are integrated for efficient processing of raster data. This backend offers the highest performance, as it operates directly on raster structures without requiring conversion to graph representations.
  • NetworKit: Fast C++/Python library for large-scale network analysis.
  • Rustworkx: Pythonic, Rust-powered graph algorithms.
  • NetworkX: Widely-used, pure Python graph library.
  • iGraph: Efficient C-based graph library.
  • (Upcoming): GPU-accelerated backends (e.g., cuGraph, Dask-cuGraph).

You can select the backend via the graph_api parameter in PathFinder. Each backend exposes a unified interface for shortest path computation, supporting:

  • Δ-stepping: Parallel path-finding algorithm - highest performance on multicore CPUs
  • Dijkstra: Robust and efficient.
  • A*: Heuristic-based, faster for spatial graphs with good heuristics.
  • Bellman-Ford: Handles negative weights (where supported).
  • Bidirectional Dijkstra: Available in some backends for further speedup.

Documentation

The documentation for PYORPS, including detailed explanations and usage instructions, can be found on https://pyorps.readthedocs.io. Examples demonstrating the functionality of PYORPS, along with practical use cases, are included as jupyter notebooks in the examples directory.

Contributing

Contributions are welcome! If you want to contribute, please check out the PYORPS contribution guidelines.

License

This project is licensed under the MIT License.

Citation

If you use PYORPS in your research, please cite:

Hofmann, M., Stetz, T., Kammer, F., Repo, S.: 'PYORPS: An Open-Source Tool for Automated Power Line Routing', CIRED 
2025 - 28th Conference and Exhibition on Electricity Distribution, 16 - 19 June 2025, Geneva, Switzerland

Contact

For questions and feedback, please open an issue on our GitHub repository.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyorps-0.3.2.tar.gz (940.1 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pyorps-0.3.2-cp313-cp313-win_amd64.whl (1.4 MB view details)

Uploaded CPython 3.13Windows x86-64

pyorps-0.3.2-cp313-cp313-musllinux_1_2_x86_64.whl (5.4 MB view details)

Uploaded CPython 3.13musllinux: musl 1.2+ x86-64

pyorps-0.3.2-cp313-cp313-manylinux_2_28_x86_64.whl (4.3 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ x86-64

pyorps-0.3.2-cp313-cp313-macosx_14_0_arm64.whl (1.6 MB view details)

Uploaded CPython 3.13macOS 14.0+ ARM64

pyorps-0.3.2-cp312-cp312-win_amd64.whl (1.4 MB view details)

Uploaded CPython 3.12Windows x86-64

pyorps-0.3.2-cp312-cp312-musllinux_1_2_x86_64.whl (5.4 MB view details)

Uploaded CPython 3.12musllinux: musl 1.2+ x86-64

pyorps-0.3.2-cp312-cp312-manylinux_2_28_x86_64.whl (4.4 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

pyorps-0.3.2-cp312-cp312-macosx_14_0_arm64.whl (1.6 MB view details)

Uploaded CPython 3.12macOS 14.0+ ARM64

pyorps-0.3.2-cp311-cp311-win_amd64.whl (1.4 MB view details)

Uploaded CPython 3.11Windows x86-64

pyorps-0.3.2-cp311-cp311-musllinux_1_2_x86_64.whl (5.5 MB view details)

Uploaded CPython 3.11musllinux: musl 1.2+ x86-64

pyorps-0.3.2-cp311-cp311-manylinux_2_28_x86_64.whl (4.4 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

pyorps-0.3.2-cp311-cp311-macosx_14_0_arm64.whl (1.6 MB view details)

Uploaded CPython 3.11macOS 14.0+ ARM64

File details

Details for the file pyorps-0.3.2.tar.gz.

File metadata

  • Download URL: pyorps-0.3.2.tar.gz
  • Upload date:
  • Size: 940.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyorps-0.3.2.tar.gz
Algorithm Hash digest
SHA256 2962bbc893e89c1ceaa59b0a430360d45f24420392b7d0d735e872eae1b05cb3
MD5 e598878ab30d8e0cbc09ea6c1e751540
BLAKE2b-256 496d8f44fc89910bc228d251ff7f48310b9a197ce22b2223f197d4c7054065ea

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyorps-0.3.2.tar.gz:

Publisher: build_and_publish_to_pypi.yml on marhofmann/pyorps

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyorps-0.3.2-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: pyorps-0.3.2-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 1.4 MB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyorps-0.3.2-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 44655779ff35dd123a5ba9c4c89589c3dcf3fd88024048b4c54a6f683b84a44a
MD5 cfae5949290db4544351b6a066eaa151
BLAKE2b-256 4b8c74293022bc315e4b81eaf5c0c8b343d31418936a48c6f15d1665014d376d

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyorps-0.3.2-cp313-cp313-win_amd64.whl:

Publisher: build_and_publish_to_pypi.yml on marhofmann/pyorps

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyorps-0.3.2-cp313-cp313-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for pyorps-0.3.2-cp313-cp313-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 64536b3a1cedbda9ec19aec781d10e111f938a0dff3ee76ec63ade325751d9ea
MD5 372276e9b96f444ddbc9b0cab90398be
BLAKE2b-256 61411f3e34c0ca5a658b180bb16527d333fc476669a7589684837d5fbed11f74

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyorps-0.3.2-cp313-cp313-musllinux_1_2_x86_64.whl:

Publisher: build_and_publish_to_pypi.yml on marhofmann/pyorps

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyorps-0.3.2-cp313-cp313-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pyorps-0.3.2-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 2bb97fc1501144b2e36cae2ae64e4c7d3c0289af4c1b62c8aa7a93e8ee71b90c
MD5 1f736fbed6f5822d48f57db76b993ca1
BLAKE2b-256 0fdaaedfb9b20116ea93537d392d8091f7f510210dcf2fa5fc5731ce9f3873bd

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyorps-0.3.2-cp313-cp313-manylinux_2_28_x86_64.whl:

Publisher: build_and_publish_to_pypi.yml on marhofmann/pyorps

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyorps-0.3.2-cp313-cp313-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for pyorps-0.3.2-cp313-cp313-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 71e5b5b75781fd474d7811886ae52b394bfb4304c7cbbbfe619b907c9228f4d1
MD5 6d61374aab05a48e05516a410639d061
BLAKE2b-256 6e013fa4a52531f945f200b1c64ed4df9fb8ab4871c499accfe7ffc06b7f916e

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyorps-0.3.2-cp313-cp313-macosx_14_0_arm64.whl:

Publisher: build_and_publish_to_pypi.yml on marhofmann/pyorps

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyorps-0.3.2-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: pyorps-0.3.2-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 1.4 MB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyorps-0.3.2-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 7cd298f342e593d09254db414d38db4e812a0f7a8490c9503fc1a6a12c8ce024
MD5 ee8e029ed4189a91e620c2f02d535614
BLAKE2b-256 16b47fe5c10fdae5ac5958253ca6a9b23192110e3bff966ccb0ff707c4a1a748

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyorps-0.3.2-cp312-cp312-win_amd64.whl:

Publisher: build_and_publish_to_pypi.yml on marhofmann/pyorps

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyorps-0.3.2-cp312-cp312-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for pyorps-0.3.2-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 766d8e5f7c535f2dd3b1f8cfd648cedf868b610b9e44d9db09e840a6ca5890c7
MD5 b6db867eb1e6502c3d84fb366001210b
BLAKE2b-256 28ea47f16ae3c883d25b3f7f55f612efdc00a23df3da5bcf2f42efa0dd4b1432

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyorps-0.3.2-cp312-cp312-musllinux_1_2_x86_64.whl:

Publisher: build_and_publish_to_pypi.yml on marhofmann/pyorps

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyorps-0.3.2-cp312-cp312-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pyorps-0.3.2-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 ce705707b54a718cd19deb23608496d83466cdc32e7326eef050c6a7314b3ec8
MD5 f9f57567b76367d40236af5276d1c7ca
BLAKE2b-256 f0426a3eb14d2bf647232b4179a4c2fe30973cffceed82a38f75772edd61098f

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyorps-0.3.2-cp312-cp312-manylinux_2_28_x86_64.whl:

Publisher: build_and_publish_to_pypi.yml on marhofmann/pyorps

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyorps-0.3.2-cp312-cp312-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for pyorps-0.3.2-cp312-cp312-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 b417bff4501e8b7df929225d85e7710e87f1322193454f64981137d181e5108c
MD5 d468c9e5f1728bdded2445e48956b4d8
BLAKE2b-256 dc7f16fd832611716963652b15721231f508b97301adcbb0bd7a916694cbdcdc

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyorps-0.3.2-cp312-cp312-macosx_14_0_arm64.whl:

Publisher: build_and_publish_to_pypi.yml on marhofmann/pyorps

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyorps-0.3.2-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: pyorps-0.3.2-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 1.4 MB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyorps-0.3.2-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 02e93454b1326765ecf2fb693fccc9668cee801c281d17ffd0876243a3ba7cf8
MD5 8935107345163afa1ab5a157252ba6c1
BLAKE2b-256 4370d00ea28849f3cb9499e1ed1b52c03e4013191b9ddac4b5df612be4790b73

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyorps-0.3.2-cp311-cp311-win_amd64.whl:

Publisher: build_and_publish_to_pypi.yml on marhofmann/pyorps

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyorps-0.3.2-cp311-cp311-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for pyorps-0.3.2-cp311-cp311-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 fe20750ecb6aba8b8db93cf66f74955077d23f0baf3f36c7097b209f0e030a2d
MD5 769c86b087bb7b84bf062bbcebb74af6
BLAKE2b-256 b7646cf4d580d1f19dc2486e484e479215457f2466454fd61cf8d6a3a7f473d1

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyorps-0.3.2-cp311-cp311-musllinux_1_2_x86_64.whl:

Publisher: build_and_publish_to_pypi.yml on marhofmann/pyorps

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyorps-0.3.2-cp311-cp311-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pyorps-0.3.2-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 19be4ff287f778c318aa01345c63761319cb86a4f85b792011267e3f38930977
MD5 d7c47e58df1fe5f340e4c0c716456d71
BLAKE2b-256 08c1cf564c8db1a208ff4fbbbbf00e0c2b61850f672bec87f45c0826b86d41ba

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyorps-0.3.2-cp311-cp311-manylinux_2_28_x86_64.whl:

Publisher: build_and_publish_to_pypi.yml on marhofmann/pyorps

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyorps-0.3.2-cp311-cp311-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for pyorps-0.3.2-cp311-cp311-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 038728631f6b47706b7841e2469ff38ffdfa6327074c63fff0a6740bec57381b
MD5 743dfa40a902df51845af7f64a2baf5c
BLAKE2b-256 b067c2499d6842d4a6e158d76763d374ab082b56581b5700d68896fdca8c5d7f

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyorps-0.3.2-cp311-cp311-macosx_14_0_arm64.whl:

Publisher: build_and_publish_to_pypi.yml on marhofmann/pyorps

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page