This robot syncs case data from PEZ (henstillinger/parking tickets) and Vejman (road/equipment permissions) into an Azure Cosmos DB container (aak-tilsyn / TilsynItems), which serves as the backend for the AAK Tilsyn app.
The main orchestration. It runs a single unified sync that:
- Retrieves credentials for PEZ, Vejman, and Cosmos DB from OpenOrchestrator.
- Connects to the
TilsynItemsCosmos DB container. - Fetches cases from PEZ and Vejman (see below).
- For each case, builds a document and checks whether it already exists in Cosmos:
- New document — inserts it with app-field defaults (e.g.
FakturaStatus: "Ny"). - Existing document with changes — patches only sync-owned fields (never overwrites app fields like
FakturaStatus). Uses batched patch operations (Cosmos limits patches to 10 ops per call) withcontent_hashalways last so a partial failure triggers a retry on the next run. - Existing document, unchanged — skipped (compared via
content_hash).
- New document — inserts it with app-field defaults (e.g.
- Coordinates are resolved through a pipeline: source coordinates are used if valid and not suspiciously close to the depot (Blixens), otherwise the address is geocoded via Nominatim, and finally any existing coordinates are kept as a fallback.
- Company names for PEZ cases are looked up via the CVR API when not provided by PEZ itself.
- Logs a summary of created, updated, and unchanged documents.
Handles authentication and data extraction from the PEZ parking ticket system (pez.giantleap.net):
- Logs in via OAuth (username/password) and obtains an access token.
- Paginates through all cases of type
PARKING_TICKETin a specific workflow step. - For each case, fetches the detail view and the vehicle owner info.
- Filters violations (forseelser) to only those with allowed codes (e.g.
1B.,2B., etc.) that map to specific invoice line types (fakturalinje). - Validates the CVR number using a mod-11 check.
- Returns a list of cases with address, coordinates, CVR, violations, and dates.
- Provides
add_sent_to_tilsyn_comment()which posts an internal comment back on the PEZ case when it is first synced to Tilsyn, listing which violations were sent.
Fetches road permission cases from the Vejman API (vejman.vd.dk):
- Queries three separate case lists: expired permissions (state 3), completed permissions (state 8), and new permissions (states 3/6/8/12) — filtered to yesterday/today date ranges.
- Deduplicates by case number and filters to cases belonging to allowed caseworkers (by initials).
- For each case, fetches the detail view to get site/building info for a more precise address.
- Extracts coordinates from LINESTRING geometry data and converts from EPSG:25832 (UTM zone 32N) to WGS84 (lat/lon).
- Returns a list of cases with address, coordinates, applicant, equipment type, dates, and case metadata.
This repo is meant to be used as a template for robots made for OpenOrchestrator v2.
-
To use this template simply use this repo as a template (see Creating a repository from a template). Don't include all branches.
-
Go to
robot_framework/__main__.pyand choose between the linear framework or queue based framework. -
Implement all functions in the files:
robot_framework/initialize.pyrobot_framework/reset.pyrobot_framework/process.py
-
Change
config.pyto your needs. -
Fill out the dependencies in the
pyproject.tomlfile with all packages needed by the robot. -
Feel free to add more files as needed. Remember that any additional python files must be located in the folder
robot_frameworkor a subfolder of it.
When the robot is run from OpenOrchestrator the main.py file is run which results
in the following:
- The working directory is changed to where
main.pyis located. - A virtual environment is automatically setup with the required packages.
- The framework is called passing on all arguments needed by OpenOrchestrator.
Minimum python version 3.11
This framework contains two different flows: A linear and a queue based.
You should only ever use one at a time. You choose which one by going into robot_framework/__main__.py
and uncommenting the framework you want. They are both disabled by default and an error will be
raised to remind you if you don't choose.
The linear framework is used when a robot is just going from A to Z without fetching jobs from an OpenOrchestrator queue. The flow of the linear framework is sketched up in the following illustration:
The queue framework is used when the robot is doing multiple bite-sized tasks defined in an OpenOrchestrator queue. The flow of the queue framework is sketched up in the following illustration:
This template is also setup with flake8 and pylint linting in Github Actions.
This workflow will trigger whenever you push your code to Github.
The workflow is defined under .github/workflows/Linting.yml.