3148 lines
95 KiB
TeX
3148 lines
95 KiB
TeX
\documentclass[fontsize=11
|
||
pt,a4paper,draft]{scrartcl}[2003/01/01]
|
||
\usepackage[english]{babel}
|
||
\usepackage[T1]{fontenc}
|
||
\usepackage[utf8]{inputenc}
|
||
\usepackage{textcomp}
|
||
\usepackage{blindtext}
|
||
\usepackage{mathpazo}
|
||
\usepackage{amsmath}
|
||
\usepackage{listings}
|
||
\usepackage{minted}
|
||
\usepackage{setspace}
|
||
\usepackage[acronym]{glossaries}
|
||
\usepackage{euler}
|
||
\usepackage[]{mdframed}
|
||
\usepackage{tabularx}
|
||
\usepackage{hyperref}
|
||
\usepackage{pifont}
|
||
\usepackage{float}
|
||
\usepackage{multirow}
|
||
\usepackage{uml}
|
||
\usepackage{tikz,pgfplots}
|
||
\usetikzlibrary{math}
|
||
|
||
|
||
\global\mdfdefinestyle{default}{%
|
||
linecolor=black,linewidth=1pt,%
|
||
innertopmargin=20,innerbottommargin=20
|
||
}
|
||
|
||
\lstset{emph={any-of,all-off},emphstyle=\textbf}
|
||
|
||
\title{Tariff File Structure}
|
||
|
||
%\author{Gerhard Hoffmann}
|
||
\date{\today\\\normalsize Version 0.8.0}
|
||
|
||
\newacronym{pnd}{PND}{\textbf{p}ay \textbf{and} \textbf{d}isplay machine}
|
||
\newacronym{psa}{PSA}{pay and display machine}
|
||
|
||
\newglossaryentry{customer}{
|
||
name=customer,
|
||
description={is either an operator of PND machines or a person buying
|
||
tickets using a PND.
|
||
Usually, it will be clear from the context, what kind of customer is meant}
|
||
}
|
||
|
||
\newglossaryentry{short-term-parking}{
|
||
name=short-term-parking,
|
||
description={mode for buying tickets using a PND.
|
||
Several tariff-steps are used to compute parking-price and
|
||
parking-time}
|
||
}
|
||
|
||
\newglossaryentry{tariff-file}{
|
||
name=tariff-file,
|
||
description={is a JSON formatted file defining a tariff and controlling
|
||
the tariff calculator for a certain product}
|
||
}
|
||
|
||
\newglossaryentry{tariff-calculator}{%
|
||
name=tariff-calculator,
|
||
description={%
|
||
software module implemented as a shared library.
|
||
Responsible to compute for parking times corresponding prices and
|
||
vice versa}%
|
||
}%
|
||
|
||
\newglossaryentry{tariff-step}{
|
||
name=tariff-step,
|
||
description={a step during the flow of a selling process.
|
||
Also known as time-step
|
||
Minimal duration: 1 minute.
|
||
}%
|
||
}
|
||
|
||
\newglossaryentry{prepaid tariff-step}{
|
||
name=prepaid tariff-step,
|
||
description={buy a product before
|
||
actual service tariff-step}
|
||
}
|
||
|
||
\newglossaryentry{prepaid-setting}{%
|
||
name=prepaid-setting,
|
||
description={settings for a prepaid tariff-step}
|
||
}%
|
||
|
||
\newglossaryentry{service time}{
|
||
name=service time,
|
||
description={union of all possible service tariff-steps}
|
||
}
|
||
|
||
\newglossaryentry{service tariff-step}{
|
||
name=service tariff-step,
|
||
description={tariff-step to buy products.
|
||
Possibly follows some prepaid and/or carry-over tariff-steps}
|
||
}
|
||
|
||
\newglossaryentry{carry-over tariff-step}{
|
||
name=carry-over tariff-step,
|
||
description={if carry-over setting is on, transition to next available
|
||
service tariff-step.
|
||
Otherwise, if carry-over setting is off, equals out-of-service tariff-step}
|
||
}
|
||
|
||
\newglossaryentry{carry-over time-step}{
|
||
name=carry-over time-step,
|
||
description={tariff-step within it is not possible to buy products.
|
||
If carry-over is off, identical to out-of-service tariff-step range}
|
||
}
|
||
|
||
\newglossaryentry{out-of-service tariff-step}{
|
||
name=out-of-service tariff-step,
|
||
description={tariff-step within it is not possible to buy products.
|
||
Opposite of service tariff-step.
|
||
If carry-over is on, identical to carry-over tariff-step}
|
||
}
|
||
|
||
\newglossaryentry{payment-setting}{
|
||
name=payment-setting,
|
||
description={include min-time, max-time, min-price, max-price}
|
||
}
|
||
|
||
\newglossaryentry{prepaid-if}{
|
||
name=prepaid-if,
|
||
description={conditions for prepaid}
|
||
}
|
||
|
||
\newglossaryentry{carry-over-if}{
|
||
name=carry-over-if,
|
||
description={conditions for carry-over}
|
||
}
|
||
|
||
\newglossaryentry{carry-over}{
|
||
name=carry-over,
|
||
description={boolean flag. Defined implicitly. True if carry-over
|
||
tariff-steps are defined,
|
||
false otherwise}
|
||
}%
|
||
|
||
\newglossaryentry{prepaid}{
|
||
name=prepaid,
|
||
description={boolean flag. Defined implicitly. True if prepaid tariff-steps
|
||
are defined,
|
||
otherwise false}
|
||
}
|
||
|
||
\newglossaryentry{time range}{
|
||
name=time range,
|
||
description={intervals of minutes. Minimal length: 1 minute. Written as
|
||
closed intervals. Right value does not belong to interval. Tariff-steps have
|
||
time ranges.
|
||
Example: [08:00 - 20:00]. Timepoint 20:00 does not belong to time range}
|
||
}%
|
||
|
||
\newglossaryentry{arrival-time}{%
|
||
name=arrival-time,
|
||
description={Time point of a customer's arrival at a \gls{pnd}.
|
||
Possibly different from start-time in case prepaid is set}
|
||
}%
|
||
|
||
\newglossaryentry{start-time}{%
|
||
name=start-time,
|
||
description={Time point of a customer's start of a selling process
|
||
at a \gls{pnd}}
|
||
}%
|
||
|
||
\newglossaryentry{wallclock-arrival-time}{
|
||
name=wallclock-arrival-time,
|
||
description={Time point of a customer's arrival at a \gls{pnd}, expressed as
|
||
wallclock time}
|
||
}%
|
||
|
||
\newglossaryentry{exit-time}{
|
||
name=exit-time,
|
||
description={Time point of a customer's leave at a PND}
|
||
}
|
||
|
||
\newglossaryentry{net-parking-time}{
|
||
name=net-parking-time,
|
||
description={charged part of the gross-parking-time}
|
||
}
|
||
|
||
\newglossaryentry{current-wallclock-parking-time}{
|
||
name=current-wallclock-parking-time,
|
||
description={current time point of selling process, expressed as wallclock
|
||
time}
|
||
}
|
||
|
||
\newglossaryentry{gross-parking-time}{
|
||
name=gross-parking-time,
|
||
description={complete parking time, including net-parking-time,
|
||
possible prepaid tariff-steps and carry-over tariff-steps.
|
||
Expressed i minutes. Also known as pre-tax-parking-time}
|
||
}
|
||
|
||
\newglossaryentry{product}{
|
||
name=product,
|
||
description={sold by a PND-machine. Possible values include:
|
||
usual parking ticket SHORT\_TERM\_PARKING}
|
||
}
|
||
|
||
\newglossaryentry{interpolate-last-tariff-step}{
|
||
name=interpolate-last-tariff-step,
|
||
description={termination mode for tariff-calculator. compute fractional
|
||
price for tariff-step on per minute basis}
|
||
}
|
||
|
||
\newglossaryentry{customer-overpay}{
|
||
name=customer-overpay,
|
||
description={termination mode for tariff-calculator. customer overpays,
|
||
but receives an replacement voucher to reclaim the overpaid amount}
|
||
}
|
||
|
||
\newglossaryentry{customer-unfairness}{
|
||
name=customer-unfairness,
|
||
description={termination mode for tariff-calculator. customer has to pay for
|
||
the complete last tariff-step}
|
||
}
|
||
|
||
\newglossaryentry{customer-fairness}{
|
||
name=customer-fairness,
|
||
description={termination mode for tariff-calculator. customer has not to pay
|
||
for
|
||
the last tariff-step}
|
||
}
|
||
|
||
|
||
\newglossaryentry{end-of-last-tariff-step}{
|
||
name=end-of-last-tariff-step,
|
||
description={termination mode for tariff-calculator. end of
|
||
the last tariff-step is the termination time-point}
|
||
}
|
||
|
||
\newglossaryentry{end-of-unique-tariff-step}{
|
||
name=end-of-unique-tariff-step,
|
||
description={termination mode for tariff-calculator. end of
|
||
unique tariff-step (e.g. day-ticket) is the termination time-point}
|
||
}
|
||
|
||
\newglossaryentry{tariff-step single}{
|
||
name=single,
|
||
description={tariff-step is not followed by other tariff-steps}
|
||
}
|
||
|
||
\newglossaryentry{cond}{
|
||
name=cond,
|
||
description={conditional modelling sequence of if, else if, else if, \dots,
|
||
else}
|
||
}
|
||
|
||
\newglossaryentry{allof}{
|
||
name=all-of,
|
||
description={synonym for a conventional \textbf(and) }
|
||
}
|
||
|
||
\newglossaryentry{anyof}{
|
||
name=any-of,
|
||
description={synonym for a conventional \textbf(or) }
|
||
}
|
||
|
||
\newglossaryentry{direct-coin-insertion}{
|
||
name=direct coin insertion,
|
||
description={preselection of parking-price or
|
||
parking-time by direct insertion of coins \textbf{only} }
|
||
}
|
||
|
||
\newglossaryentry{pre-selection}{
|
||
name=preselection,
|
||
description={preselection of parking-price or
|
||
parking-time using the GUI of a \gls{pnd}}
|
||
}
|
||
|
||
\newglossaryentry{overpay}{
|
||
name=overpay,
|
||
description={customer insert coins with an amount higher than actual ticket
|
||
price}
|
||
}
|
||
|
||
\newglossaryentry{missing-receipt-declaration}{
|
||
name=missing receipt declaration,
|
||
description={a \gls{pnd} could not return change, but a document a customer
|
||
can use to get the remaining money back}
|
||
}
|
||
|
||
|
||
\makeglossaries
|
||
|
||
\begin{document}
|
||
\maketitle
|
||
\tableofcontents
|
||
|
||
|
||
\section*{History}
|
||
\begin{table}[htbp]
|
||
\centering
|
||
|
||
\begin{tabularx}{\textwidth}{|>{\hsize=.15\hsize}c|>{\hsize=.25\hsize}X|>{\hsize
|
||
=.6\hsize}X|}
|
||
\hline
|
||
\textbf{Version} & \textbf{Date} & \textbf{Comment} \\
|
||
\hline
|
||
0.8.0 & \today & \\ \hline
|
||
\end{tabularx}
|
||
\end{table}
|
||
|
||
\pagebreak
|
||
|
||
\section{Introduction}
|
||
|
||
|
||
|
||
\subsection[Some background about the tariff calculation]{
|
||
Some background about the tariff calculation}
|
||
|
||
\subsubsection[Conceptual view]{Conceptual view}
|
||
|
||
If a customer wants to buy a ticket at a usual \gls{pnd}, there are
|
||
several options available:
|
||
|
||
\paragraph{
|
||
Pay with coins
|
||
}
|
||
The first option is \textbf{\gls{direct-coin-insertion}}. A
|
||
customer inserts coins, and the \gls{tariff-calculator} computes the
|
||
corresponding parking-price resp. parking-time on the fly while coins are
|
||
inserted.
|
||
|
||
The other option is \textbf{\gls{pre-selection}}. Using
|
||
Plus/Minus-buttons, a customer is displayed the current parking-time resp.
|
||
parking-price (again computed by the \gls{tariff-calculator} on the fly). In
|
||
case the customer doesn't have the matching coins available, he might be asked
|
||
for \textbf{\gls{overpay}}:
|
||
|
||
If the \gls{pnd} is equipped with a money changer and the customer confirms the
|
||
\gls{overpay} and the money changer can return the change, there will be no
|
||
problem. Otherwise, the customer will receive a
|
||
\gls{missing-receipt-declaration} to be able to collect the drawback. If the
|
||
customer denies the \gls{overpay}, the money will be returned.
|
||
|
||
If the \gls{pnd} is not equipped with a money changer, and the customer still
|
||
confirms, then the money will be lost.
|
||
|
||
|
||
\paragraph{
|
||
Pay with credit card
|
||
}
|
||
|
||
In this case the customer always uses \gls{pre-selection}. Using
|
||
Plus/Minus-buttons of the \gls{pnd}-display,
|
||
the customer chooses parking-time/-price (computed by the
|
||
\gls{tariff-calculator} on the fly) and buys the ticket
|
||
using a built-in credit-card terminal.
|
||
|
||
\paragraph{}
|
||
The tariff-calculation is controlled by two different main settings:
|
||
|
||
\begin{enumerate}
|
||
\item \textbf{Service time ranges}, usually given as fixed wall clock time
|
||
ranges.
|
||
For instance, a possible setting might be $08:00 – 20:00$, on every day
|
||
during a week. Other such time ranges are for instance
|
||
\textbf{carry-over} time ranges or \textbf{prepaid} time ranges.
|
||
\item The operator of some \gls{pnd}-machine may decide that the customer
|
||
has to pay in
|
||
\gls{tariff-step}s of 60 minutes per step.
|
||
Such 60 minute intervals are usually intertwined with the fixed service
|
||
time ranges.
|
||
The \gls{tariff-file} must contain settings which allow the calculation
|
||
to cope with such a requirement.
|
||
\end{enumerate}
|
||
|
||
To configure the behaviour of the \gls{tariff-calculator}, a so-called
|
||
\gls{tariff-file} is used.
|
||
It has the follwing properties:
|
||
%\begin{mdframed}[style=exampledefault]%
|
||
\begin{enumerate}
|
||
\item For historical reasons, its syntax is
|
||
\href{https://www.json.org/json-en.html}{JSON}.
|
||
\item It is generated using an external tool (tariff editor) (Audivo).
|
||
\item \Gls{tariff-file}s are kept in customer-specific git repositories.
|
||
\end{enumerate}
|
||
%\end{mdframed}
|
||
|
||
The \gls{tariff-calculator} uses a \gls{tariff-file} in a two-step process:
|
||
First, parse the \gls{tariff-file} into internal C/C++ data structures.
|
||
Then, using these structures, generate a sequence of \gls{tariff-step}s,
|
||
which are used as internal representation of the flow of a selling process.
|
||
\newline
|
||
\par{
|
||
This document defines the structure of a \gls{tariff-file} in an
|
||
incremental way. After the description of some settings,
|
||
there will be an example of mapping a tariff provided by some
|
||
\gls{pnd}-operator into a \gls{tariff-file} using these settings.
|
||
At the end of this document, several complete examples will be given.
|
||
}
|
||
\newline
|
||
\par{
|
||
Each day of the week is divided in \gls{service tariff-step}s (complementary
|
||
in \gls{out-of-service tariff-step}s).
|
||
There can be several of them for each day.
|
||
}
|
||
\newline
|
||
\par{
|
||
By definition, it is not possible to buy products during \gls{out-of-service
|
||
tariff-step}s. There are two exceptions to this rule: the special
|
||
\gls{out-of-service tariff-step}s \textbf{\gls{prepaid}} and
|
||
\textbf{carry-over} tariff-steps. \Gls{prepaid tariff-step}s allow to buy
|
||
products before actual \gls{service tariff-step}s whereas
|
||
\gls{carry-over tariff-step}s allow the transition to the next available
|
||
\gls{service tariff-step}.
|
||
}
|
||
|
||
\Gls{prepaid tariff-step}s can occur only at the beginning of a selling process,
|
||
whereas \gls{carry-over tariff-step}s can occur more often between
|
||
\gls{service tariff-step}s.
|
||
|
||
\subsubsection[Example]{%
|
||
Example}
|
||
Let carry\_over $($co$)$ and prepaid $($pp$)$ be set.
|
||
\begin{table}[h!]
|
||
\begin{center}
|
||
\label{tab:table1}
|
||
\begin{tabular}{|c|c|c|c|c|}
|
||
\hline
|
||
\textbf{00:00 - 08:00} & \textbf{08:00 - 12:00} & \textbf{12:00 - 14:00}
|
||
&
|
||
\textbf{14:00 - 20:00} & \textbf{20:00 - 24:00}\\
|
||
\hline
|
||
co / pp & service & co / pp & service & co / pp\\
|
||
\hline
|
||
\end{tabular}
|
||
\end{center}
|
||
\end{table}
|
||
If a customer arrives at 07:00, then the \gls{prepaid tariff-step} is
|
||
07:00-08:00
|
||
and the actual parking time starts at 08:00.
|
||
The next \gls{carry-over tariff-step} is from 12:00 – 14:00.
|
||
The customer does not have to pay for the \gls{prepaid tariff-step}.
|
||
|
||
\subsubsection[A more technical view]{A more technical view}
|
||
|
||
The steps of a tariff are represented as step-function. The discrete
|
||
values of the step-function are the prices of the various
|
||
\gls{tariff-step}s. The \gls{tariff-calculator} integrates this
|
||
step-function over the \gls{tariff-step}s (see figure below).
|
||
|
||
\begin{figure}[!h]
|
||
\begin{center}
|
||
\caption{Tariff as step-function}
|
||
\vspace{0.5cm}
|
||
\begin{tikzpicture}[scale=0.8]
|
||
% Definitions
|
||
\tikzmath{
|
||
\r0 = 0;
|
||
\r1 = 0.2;
|
||
\r2 = 0.3;
|
||
\r3 = 0.4;
|
||
\r4 = 0.1;
|
||
\r5 = 0.6;
|
||
\r6 = 0.5;
|
||
\t0 = 1;
|
||
\t1 = 2;
|
||
\t2 = 6;
|
||
\t3 = 10;
|
||
\t4 = 11;
|
||
\t5 = 12;
|
||
\t6 = 13;
|
||
\x0 = \t0; \y0 = \r0;
|
||
\x1 = \t1; \y1 = \r1;
|
||
\x2 = \t2; \y2 = \r2;
|
||
\x3 = \t3; \y3 = \r3;
|
||
\x4 = \t4; \y4 = \r4;
|
||
\x5 = \t5; \y5 = \r5;
|
||
\x6 = \t6; \y6 = \r6;
|
||
}
|
||
% Axis
|
||
\begin{axis}[
|
||
axis x line=middle,
|
||
axis y line=middle,
|
||
ylabel=Price,
|
||
%xlabel style={at={(10,10)},above right,yshift=10pt},
|
||
%xlabel style={at={(axis description cs:0.5,-0.1)},anchor=east},
|
||
%xlabel=Time,
|
||
xtick={0,\x0,\x1,\x2,\x3,\x4,\x5,\x6},
|
||
xticklabels={0,$t_0$,$t_1$, $t_2$, $t_3$,$t_4$,$t_5$,$t_6$,{ }},
|
||
xlabel near ticks,
|
||
extra x ticks={2, 6, 10, 14},
|
||
extra x tick labels={$08:00$,$09:00$,$10:00$,$11:00$},
|
||
extra x tick style={yshift={-30.0}},
|
||
ytick={0,\y0,\y1,\y2,\y3,\y5,\y6},
|
||
yticklabels={0,$p_0$,$p_1$, $p_2$, $p_3$,$p_5$,$p_4$},
|
||
ylabel near ticks,
|
||
xmax=\x6+2,
|
||
ymax=\y5+0.1,
|
||
xmin=0,
|
||
ymin=0
|
||
]
|
||
% Plots
|
||
%\addplot[domain=0:\t1] {\r1*x};
|
||
%\addplot[domain=\t1:\t2] {\r2*x};
|
||
%\addplot[domain=\t2:\t3] {\r3*x};
|
||
\draw[ultra thick] (axis cs:\x0,\y0) -- (axis cs:\x1, \y0);
|
||
\draw[thick] (axis cs:\x1,\y1) -- (axis cs:\x2, \y1);
|
||
\draw[ultra thick] (axis cs:\x2,0) -- (axis cs:\x3, 0);
|
||
\draw[thick] (axis cs:\x3,\y3) -- (axis cs:\x4, \y3);
|
||
\draw[ultra thick] (axis cs:\x4,\y5) -- (axis cs:\x5, \y5);
|
||
\draw[ultra thick] (axis cs:\x5,\y6) -- (axis cs:\x6, \y6);
|
||
|
||
\draw[dotted] (axis cs:\x1,0) -- (axis cs:\x1, \y1);
|
||
\draw[dotted] (axis cs:\x2,\y1) -- (axis cs:\x2, 0);
|
||
\draw[dotted] (axis cs:\x3,0) -- (axis cs:\x3, \y3);
|
||
\draw[dotted] (axis cs:\x4,\y3) -- (axis cs:\x4, \y5);
|
||
\draw[dotted] (axis cs:\x5,\y5) -- (axis cs:\x5, \y6);
|
||
|
||
\addplot[fill=white,only marks,mark=*]
|
||
coordinates{(\x1,\y0)(\x2,\y1)(\x3,0)(\x4,\y3)(\x5,\y5)(\x6,\y6)};
|
||
\end{axis}
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
\end{figure}
|
||
|
||
\begin{enumerate}
|
||
\item The \gls{tariff-step} $[t_{0}, t_{1}]$ is a prepaid step having a
|
||
price of $0$ by definition. \Gls{arrival-time} is $t_0$, \gls{start-time}
|
||
is $t_1$. The price for the first \gls{tariff-step} is $p_1$ and its
|
||
duration is $60$ minutes.
|
||
\item The \gls{tariff-step} $[t_{2}, t_{3}]$ is a carry-over step;
|
||
price is $0$ as well, again by definition.
|
||
\item Note: \gls{tariff-step}s can have any price: they don't have to be
|
||
equal, increasing or decreasing. Additionally, they don't have to have the same
|
||
duration (i.e. length). The minimal duration of the various \gls{tariff-step}s
|
||
is one minute (for any possible tariff):
|
||
|
||
\[
|
||
\mid t_{i} - t_{j} \mid \; \geq 1
|
||
\]
|
||
|
||
for the time points $t_i$ above. The maximal duration is not limited,
|
||
but the typical maximal value is $24$ hours.
|
||
\end{enumerate}
|
||
|
||
|
||
\subsubsection[\Gls{tariff-step} notation]{%
|
||
\Gls{tariff-step} notation}
|
||
\Gls{tariff-step}s are written as closed intervals ($[00:00-08:00]$,
|
||
$[08:00-24:00]$, \dots).
|
||
Note that the time point $08:00$ is not included in the first interval.
|
||
Rather, it denotes the first minute of the interval $[08:00-24:00]$.
|
||
In the same manner $24:00$ denotes the first minute of the next day,
|
||
whereas $00:00$ denotes the first minute of the current day.
|
||
The same holds for intervals given in time point notation $[t_1,t_2]$
|
||
as above.
|
||
|
||
\subsubsection{%
|
||
Basic workflow of the tariff calculator}
|
||
The \gls{tariff-calculator} just integrates over the \gls{tariff-step}s.
|
||
The only exception is if a last \gls{tariff-step} has to be refined to a
|
||
higher (minute) resolution.
|
||
|
||
The effect of the Plus/Minus-buttons is basically to move the calculator
|
||
forward / backward by one step.
|
||
|
||
%Carry-over \gls{tariff-step}s or prepaid time ranges are not included
|
||
%in the step-function.
|
||
|
||
|
||
\subsubsection[Interpolation]{%
|
||
Interpolation
|
||
}
|
||
|
||
\paragraph{%
|
||
How to interpolate into \gls{tariff-step}s
|
||
}
|
||
It is quite common that all \gls{tariff-step}s have the same duration,
|
||
say $5$ minutes. Now, if \gls{service time} ends at $20:00$ and there is no
|
||
carry-over allowed, this raises a problem if the last \gls{tariff-step} ends
|
||
closer to $t = 20:00$ than $5$ minutes:
|
||
\[
|
||
\mid t_{last} - t \mid \; < 5
|
||
\]
|
||
|
||
What shall happen with these last minutes? Several options are possible:
|
||
|
||
% manchmal egal: bei tagesticket oder 24h-ticket
|
||
|
||
\paragraph{%
|
||
Use minute resolution
|
||
}
|
||
Compute the price for $1$ minute based on the price for the
|
||
last \gls{tariff-step}. If applicable, this resolves the issue.
|
||
But sometimes this option is not possible:
|
||
|
||
\paragraph{%
|
||
Rounding problems
|
||
}
|
||
This problem arises if the price of the last $5$ minutes from above is not a
|
||
multiple of $5$. Dividing by $5$ might result in a fractional, i.e. non-integer
|
||
value.
|
||
|
||
\paragraph{%
|
||
(Direct) coin insertion
|
||
}
|
||
In this case it might be possible to ask the customer for \gls{overpay}.
|
||
|
||
|
||
\paragraph{%
|
||
Preselection using Plus/Minus
|
||
}
|
||
Using the Plus/Minus-buttons a user can preselect parking-time and
|
||
parking-price. "Plus" means to go forward in time by a certain amount of
|
||
\gls{tariff-step}s, "Minus" means to go backward to the
|
||
previous \gls{tariff-step}.
|
||
|
||
Thus "Plus" allows to move forward much faster
|
||
than backward with "Minus". The reason is user convenience. As the customer
|
||
must be able to select any possible price, the backward move must have the
|
||
finest possible resolution.
|
||
|
||
TODO: configure forward step-size.
|
||
|
||
|
||
\subsection[Interface of the \gls{tariff-calculator}]{%
|
||
Interface of the tariff calculator}
|
||
|
||
\subsubsection{%
|
||
Dependency to existing software components}
|
||
|
||
The tariff-calculator is used by the main application ATBQT
|
||
with the help of a special wrapper around the actual tariff-calculator.
|
||
|
||
\begin{center}
|
||
\framebox[250pt][c]{ATBQT | Tariff Simulator | Tariff Editor }\\
|
||
\framebox[250pt][c]{wrapper for tariff-calculator (plugin)}\\
|
||
\framebox[250pt][c]{tariff-calculator (library)}
|
||
\end{center}
|
||
|
||
|
||
The \gls{tariff-calculator} is basically about computing two values:
|
||
\begin{enumerate}
|
||
\item Given \gls{net-parking-time}, compute the corresponding parking
|
||
price (any prepaid-/carry-over time ranges are excluded).
|
||
\item Given a price, compute the corresponding net- and
|
||
\gls{gross-parking-time}s.
|
||
\item Additionally, it has to return error states to the caller for
|
||
(direct) coin insertion: the customer might have inserted
|
||
an amount greater than the allowed max-price (error state overpaid).
|
||
\end{enumerate}
|
||
|
||
\subsubsection{%
|
||
C Interface of the tariff calculator (in progress)}
|
||
|
||
Although the \gls{tariff-calculator} is written in C\texttt{++}, there will
|
||
be a C interface to be used by external software written in a
|
||
different language like for instance C\texttt{\#}.
|
||
|
||
\paragraph{Tariff calculator}
|
||
\label{tariff-calculator-interface}
|
||
\begin{minted}[frame=single,
|
||
framesep=3mm,
|
||
linenos=true,
|
||
xleftmargin=21pt,
|
||
tabsize=4]{c}
|
||
|
||
TariffCalculator *allocTariffCalculator(char const *tariff_file);
|
||
// allocate tariff-calculator based on tariff-file.
|
||
// note that a tariff-file is for a single product:
|
||
// if there are several products to be handled
|
||
// at the same time, allocate multiple tariff-calculators.
|
||
|
||
freeTariffCalculator(TariffCalculator *tc);
|
||
// free a previously allocated tariff-calculator.
|
||
|
||
TariffCalculatorState *forward(TariffCalculator *tc);
|
||
// move the tc forward by a configured number of tariff-steps.
|
||
|
||
TariffCalculatorState *backward(TariffCalculator *tc);
|
||
// move the tc backward by one tariff-step.
|
||
|
||
TariffCalculatorState *currentState(TariffCalculator const *tc);
|
||
// get current state of the tariff-calculator.
|
||
|
||
TariffCalculatorState *priceGrossDTime(TariffCaculator const *tc,
|
||
char gross_datetime[]);
|
||
// compute price using tariff-calculator and gross_datetime,
|
||
// which is given in ISO-format: '2024-01-01T12:00:00'.
|
||
// Refer to TariffCalculatorState for possible result.
|
||
|
||
TariffCalculatorState *priceNetTime(TariffCaculator const *tc,
|
||
uint32_t net_parking_time);
|
||
// compute price using tariff-calculator and net_parking_time,
|
||
// given in minutes.
|
||
// Refer to TariffCalculatorState for possible result.
|
||
|
||
TariffCalculatorState *priceGrossTime(TariffCaculator const *tc,
|
||
uint32_t gross_parking_time);
|
||
// compute price using tariff-calculator and gross_parking_time,
|
||
// given in minutes.
|
||
// Refer to TariffCalculatorState for possible result.
|
||
|
||
TariffCalculatorState *timeForPrice(TariffCaculator const *tc,
|
||
unsigned int price);
|
||
// compute parking-time for given price.
|
||
// Refer to TariffCalculatorState for possible result.
|
||
};
|
||
|
||
\end{minted}
|
||
|
||
\paragraph{Tariff calculator state}
|
||
\label{tariff-calculator-state}
|
||
\begin{minted}[frame=single,
|
||
framesep=3mm,
|
||
linenos=true,
|
||
xleftmargin=21pt,
|
||
tabsize=4]{c}
|
||
typedef struct TimePoint {
|
||
char tp[20];
|
||
// time point given in ISO-format: '2024-01-01T12:00'
|
||
} TimePoint;
|
||
|
||
struct TariffCalculatorState {
|
||
char start[20];
|
||
// start time of the tariff-calculation, given
|
||
// in ISO-format: '2024-01-01T12:00'
|
||
|
||
unsigned int net_parking_time;
|
||
// net parking time so far, given in minutes
|
||
|
||
char net_parking_time_date[20];
|
||
// net parking time so far, given as date in
|
||
// ISO-format: '2024-01-01T12:00'
|
||
|
||
unsigned int gross_parking_time;
|
||
// net parking time so far, given in minutes
|
||
|
||
char gross_parking_time_date[20];
|
||
// net parking time so far, given as date in
|
||
// ISO-format: '2024-01-01T12:00' */
|
||
|
||
unsigned int price;
|
||
// price so far
|
||
};
|
||
|
||
\end{minted}
|
||
|
||
|
||
\subsection[Conditional Expressions in a Tariff File]{%
|
||
Conditional Expressions in a Tariff File}
|
||
Sometimes it is necessary to encode conditionals in JSON. Here the
|
||
following approach is used: assume for example some pseudo-code like this:
|
||
|
||
\begin{minted}[frame=single,
|
||
framesep=3mm,
|
||
linenos=true,
|
||
xleftmargin=21pt,
|
||
tabsize=4]{c}
|
||
(("A" < 10 && "B" > 100) || "C" == 0)
|
||
\end{minted}
|
||
|
||
|
||
\subsubsection[any-of and all-of]{%
|
||
any-of and all-of}
|
||
|
||
In order to model such an expression, use the conditionals
|
||
\textbf{\gls{anyof}} and \textbf{\gls{allof}}.
|
||
|
||
\begin{minted}[frame=single,
|
||
framesep=3mm,
|
||
linenos=true,
|
||
xleftmargin=21pt,
|
||
tabsize=4]{js}
|
||
"any-of": [
|
||
{
|
||
"all-of": [
|
||
{ "A": { "lt": 10}},
|
||
{ "B": { "gt": 100}}
|
||
]
|
||
},
|
||
{
|
||
"C": { "eq": 0}
|
||
}
|
||
]
|
||
\end{minted}
|
||
|
||
"any-of" plays the role of the operator OR, whereas "all-of" is for modeling
|
||
the operator AND.
|
||
|
||
\subsubsection[cond]{%
|
||
\gls{cond}}
|
||
In order to model "if, else if, else if, \dots, else" use
|
||
\textbf{\gls{cond}}.
|
||
|
||
The objects of a \gls{cond}-array consist of two entries: the first one
|
||
is a test, the second line some kind of expression, typically just a
|
||
value.
|
||
If the test evaluates to true, then the evaluation of the expression
|
||
is returned, and \gls{cond} stops. Otherwise, then next object
|
||
is tried. If all tests fail, then there is an (optional) else-object
|
||
and its evaluation is returned. If there is no such an else-object, then
|
||
false will be returned.
|
||
|
||
\begin{minted}[frame=single,
|
||
framesep=3mm,
|
||
linenos=true,
|
||
xleftmargin=21pt,
|
||
tabsize=4]{js}
|
||
"cond": [
|
||
{
|
||
"current-wallclock-parking-time": {
|
||
"<": "14:00",
|
||
"then": "14:00"
|
||
}
|
||
},
|
||
{
|
||
"current-wallclock-parking-time": {
|
||
"<": "18:00",
|
||
"then": "18:00"
|
||
}
|
||
},
|
||
{
|
||
"else": "24:00"
|
||
}
|
||
]
|
||
\end{minted}
|
||
|
||
\section{The header of the tariff file}
|
||
A tariff file starts with some general entries.
|
||
|
||
\begin{minted}[frame=single,
|
||
framesep=3mm,
|
||
linenos=true,
|
||
xleftmargin=21pt,
|
||
tabsize=4]{js}
|
||
{
|
||
"project": "project-name",
|
||
"version": "1.0.0",
|
||
"info": "",
|
||
"product": "short-term-parking"
|
||
}
|
||
\end{minted}
|
||
|
||
\begin{enumerate}
|
||
\item \textbf{project}
|
||
Optional. A string in free format describing the project. Typically
|
||
includes a location.
|
||
\item \textbf{version}
|
||
Optional. Version of the tariff file. Should follow Semantic
|
||
Versioning.
|
||
\item \textbf{info}
|
||
Optional. Free format string for own use.
|
||
\item \textbf{product}
|
||
Optional. A string describing the product in use for this tariff file.
|
||
Available products are:
|
||
\begin{enumerate}
|
||
\item short-term-parking
|
||
\item day-ticket
|
||
\item 24-h-ticket
|
||
\item \dots
|
||
\end{enumerate}
|
||
\Gls{product} is always implicitly defined, as there is exactly one
|
||
\gls{tariff-file} for each \gls{product}.
|
||
|
||
\end{enumerate}
|
||
|
||
Following the initial entries, the tariff file is divided in a top and bottom
|
||
half.
|
||
The top part includes general settings, which can be overwritten in the bottom
|
||
part on a per-day basis, which is similar to the inheritance
|
||
in object-oriented programming.
|
||
|
||
\section{The top half of the tariff file}
|
||
|
||
The top part consists of \textbf{payment-setting}, \textbf{prepaid settings},
|
||
\textbf{service settings} and \textbf{carry-over settings}. For example, a
|
||
payment-setting might be a simple as
|
||
|
||
\begin{minted}[frame=single,
|
||
framesep=3mm,
|
||
linenos=true,
|
||
xleftmargin=21pt,
|
||
tabsize=4]{js}
|
||
{
|
||
"payment-settings”: [
|
||
{
|
||
"min-time": 30,
|
||
"max-time": 840,
|
||
"min-price": 50,
|
||
"max-price": 1400,
|
||
"allow-overpay": true
|
||
}
|
||
]
|
||
}
|
||
\end{minted}
|
||
|
||
\subsection{payment-settings}
|
||
Defines the general settings for a buying a \gls{product}.
|
||
|
||
\begin{enumerate}
|
||
\item \textbf{min-time}:
|
||
Mandatory. Minimal parking time. Never bigger than maximal parking
|
||
time.\\
|
||
Possible values:
|
||
\begin{enumerate}
|
||
\item a non-negative integer: minimal parking time in minutes.
|
||
\item string (format "h:m"): e.g. "$24:00$": minimal parking time is
|
||
supposed to last until $24:00$ (next midnight).
|
||
\item settable using \textbf{cond}-conditional.
|
||
|
||
Example: If \gls{current-wallclock-parking-time} is before $14:00$,
|
||
then min-time is until $14:00$. Otherwise it is $24:00$
|
||
(next midnight).
|
||
|
||
\begin{minted}[frame=single,
|
||
framesep=3mm,
|
||
linenos=true,
|
||
xleftmargin=21pt,
|
||
tabsize=4]{js}
|
||
{
|
||
"min-time": {
|
||
"cond": [
|
||
{
|
||
"current-wallclock-parking-time": {
|
||
"<": "14:00",
|
||
"then": "14:00"
|
||
}
|
||
},
|
||
{
|
||
"else": "24:00"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
\end{minted}
|
||
\end{enumerate}
|
||
|
||
\item \textbf{max-time}:
|
||
Maximal parking time. Never smaller than minimal parking time.
|
||
Possible values:
|
||
\begin{enumerate}
|
||
\item a non-negative integer: maximal parking time in minutes.
|
||
\item string (format "h:m"): e.g. "$24:00$" maximal parking time is
|
||
supposed to last until $24:00$ (next midnight).
|
||
\item string: "unlimited".
|
||
\item settable using \textbf{cond}-conditional.
|
||
|
||
Example: If \gls{current-wallclock-parking-time} is before $14:00$,
|
||
then max-time is until $14:00$. Otherwise it is $24:00$
|
||
(next midnight).
|
||
\begin{minted}[frame=single,
|
||
framesep=3mm,
|
||
linenos=true,
|
||
xleftmargin=21pt,
|
||
tabsize=4]{js}
|
||
{
|
||
"max-time": {
|
||
"cond": [
|
||
{
|
||
"current-wallclock-parking-time": {
|
||
"<": "14:00",
|
||
"then": "14:00"
|
||
}
|
||
},
|
||
{
|
||
"else": "24:00"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
\end{minted}
|
||
\end{enumerate}
|
||
|
||
\item \textbf{min-price:}
|
||
Mandatory. Minimal parking price. Never bigger than maximal parking
|
||
price.\\
|
||
\begin{enumerate}
|
||
\item a non-negative integer: minimal parking price.
|
||
\item settable using \textbf{cond}-conditional.
|
||
|
||
Example: If \gls{current-wallclock-parking-time} is before $14:00$,
|
||
then min-price is until $800$. Otherwise it is $500$.
|
||
\begin{minted}[frame=single,
|
||
framesep=3mm,
|
||
linenos=true,
|
||
xleftmargin=21pt,
|
||
tabsize=4]{js}
|
||
{
|
||
"min-price": {
|
||
"cond": [
|
||
{
|
||
"current-wallclock-parking-time": {
|
||
"<": "14:00",
|
||
"then": 800
|
||
}
|
||
},
|
||
{
|
||
"else": 500
|
||
}
|
||
]
|
||
}
|
||
}
|
||
\end{minted}
|
||
\end{enumerate}
|
||
|
||
\item \textbf{max-price}:
|
||
Mandatory. Maximal parking price.
|
||
\begin{enumerate}
|
||
\item a non-negative integer: maximal parking price.
|
||
\item settable using \textbf{cond}-conditional. See min-price.
|
||
\end{enumerate}
|
||
|
||
\item \textbf{price-scaling-factor}:
|
||
Scaling factor to prevent rounding errors.
|
||
|
||
\item \textbf{allow-overpay}:
|
||
Allow overpay, e.g. if the customer does not
|
||
have the coins to pay the exact price.
|
||
Possible values: true/false.
|
||
|
||
% \item \textbf{accumulate\_step\_prices}: If \textbf{true}, accumulate
|
||
% prices in payment rate (todo).
|
||
% \item \textbf{accumulate\_step\_durations}: If \textbf{true},
|
||
% accumulate durations in duration (todo).
|
||
\end{enumerate}
|
||
|
||
\subsubsection*{Implicit settings}
|
||
\begin{enumerate}
|
||
\item \textbf{carry\_over}:
|
||
If the selling process runs beyond a certain time point (usually
|
||
midnight),
|
||
then:
|
||
\begin{enumerate}
|
||
\item if \textbf{true}, continue tariff calculation with the current
|
||
price / parking time.
|
||
\item if \textbf{false}, stop tariff calculation. Return current
|
||
price
|
||
and parking time.
|
||
\end{enumerate}
|
||
|
||
\item \textbf{prepaid:} allow a customer to by a product before an actual
|
||
service time.
|
||
\begin{enumerate}
|
||
\item if \textbf{true}, continue tariff calculation with the next
|
||
possible \gls{start-time}.
|
||
\item if \textbf{false}, stop tariff calculation. Return error,
|
||
because inside \gls{out-of-service tariff-step} range.
|
||
\end{enumerate}
|
||
\end{enumerate}
|
||
|
||
\subsection{prepaid-settings}
|
||
“Prepaid” (“Vorkauf”) is a special operation mode, which makes it possible
|
||
to buy some product before service time.
|
||
There can be several \gls{prepaid tariff-step}s per day (depending on how
|
||
many \gls{service tariff-step}s exist).
|
||
\Gls{prepaid} is optional. If not given in the tariff file, no \gls{prepaid}
|
||
is possible, i.e. the implicit \gls{prepaid}-flag is not set.
|
||
|
||
\begin{enumerate}
|
||
\item \textbf{prepaid-ranges}
|
||
\begin{enumerate}
|
||
\item[] \textbf{prepaid-duration}: Conditional. If prepaid-start and
|
||
prepaid-end are given,
|
||
it can be computed.
|
||
\item[] \textbf{prepaid-start}: Mandatory. Start of prepaid time
|
||
range.
|
||
\item[] \textbf{prepaid-end}: Conditional. If prepaid-duration is
|
||
given, it can be computed.
|
||
\end{enumerate}
|
||
\end{enumerate}
|
||
|
||
\subsubsection*{Example}
|
||
A customer has an appointment with her doctor at 7:00,
|
||
and service time starts at 8:00. Parking is free before 8:00.
|
||
If the appointment would take more than one hour, then the customer
|
||
could not buy a parking-ticket before 8:00 without the prepaid-mode.
|
||
|
||
\begin{minted}[frame=single,
|
||
framesep=3mm,
|
||
linenos=true,
|
||
xleftmargin=21pt,
|
||
tabsize=4]{js}
|
||
{
|
||
"prepaid-settings": [
|
||
{
|
||
"prepaid-ranges": [
|
||
{
|
||
"prepaid-duration": 480,
|
||
"prepaid-start": "00:00",
|
||
"prepaid-end": "08:00"
|
||
},
|
||
{
|
||
"prepaid-duration": 240,
|
||
"prepaid-start": "20:00",
|
||
"prepaid-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
|
||
\end{minted}
|
||
|
||
\subsection{service-settings}
|
||
\Gls{service tariff-step}sare (in most cases) not free,
|
||
and there can be more than one such \gls{tariff-step} per day.
|
||
|
||
\begin{minted}[frame=single,
|
||
framesep=3mm,
|
||
linenos=true,
|
||
xleftmargin=21pt,
|
||
tabsize=4]{js}
|
||
{
|
||
"service-settings": [
|
||
{
|
||
"service-ranges": [
|
||
{
|
||
"service-duration": 720,
|
||
"service-start": "08:00",
|
||
"service-end": "20:00"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
\end{minted}
|
||
|
||
\begin{enumerate}
|
||
\item \textbf{service-ranges}
|
||
\begin{enumerate}
|
||
\item[] \textbf{service-duration:} Conditional. If service-start and
|
||
service\_end are given,
|
||
it can be computed.
|
||
\item[] \textbf{service-start:} Mandatory. Start of \gls{service
|
||
tariff-step} range.
|
||
\item[] \textbf{service-end:} Conditional. If service-duration is
|
||
given, it can be computed.
|
||
\end{enumerate}
|
||
\end{enumerate}
|
||
|
||
\subsection{out-of-service-settings}
|
||
During \gls{out-of-service tariff-step} parking is forbidden.
|
||
The exception to this rule is in case the general
|
||
\textbf{carry\_over}-flag is true, where \gls{out-of-service tariff-step}s
|
||
are in fact \gls{carry-over tariff-step}s. Indeed, defining
|
||
\gls{carry-over tariff-step}s in the \gls{tariff-file} means
|
||
that the \gls{carry-over}-flag is implicitly defined. In such
|
||
a case, it is possible to jump across a \gls{carry-over tariff-step}
|
||
and and to continue with the next available \gls{service tariff-step}.
|
||
The same holds true for the textbf{prepaid}-flag and \gls{prepaid tariff-step}s.
|
||
\subsubsection*{Remark}
|
||
It might happen that all \gls{service tariff-step}s stretch always
|
||
full days. Hence, there are no \gls{out-of-service tariff-step}s
|
||
and no \gls{carry-over tariff-step}s: the \gls{carry-over}-flag is
|
||
implicitly set to \textbf{false} in this case, as there is no carry-over.
|
||
|
||
|
||
\subsection{tariff-steps}
|
||
One of the most important objects in the \gls{tariff-file}.
|
||
|
||
\begin{minted}[frame=single,
|
||
framesep=3mm,
|
||
linenos=true,
|
||
xleftmargin=21pt,
|
||
tabsize=4]{js}
|
||
{
|
||
"tariff-steps": [
|
||
{
|
||
|
||
|
||
}
|
||
]
|
||
}
|
||
\end{minted}
|
||
|
||
\begin{enumerate}
|
||
\item \textbf{\gls{tariff-step}s}
|
||
Some variables of a \gls{tariff-step} can be given statically,
|
||
i.e. at load-time of the \gls{tariff-file}. Others may be
|
||
set only at runtime as \textbf{step\_start} below.
|
||
Depending on the context, different values of a \gls{tariff-step}
|
||
will be defined.
|
||
\begin{enumerate}
|
||
\item[] \textbf{step-duration-in-minutes}: if defined, the
|
||
length of a \gls{tariff-step} in minutes.
|
||
\item[] \textbf{step-start:} may be set to
|
||
\begin{enumerate}
|
||
\item \textbf{anytime}: the \gls{tariff-step} starts at an
|
||
arbitrary time-point. Can only be set at runtime.
|
||
\item \textbf{now}: synonymous for \textbf{anytime}
|
||
\item explicitly given time-point as \textbf{12:00}
|
||
\end{enumerate}
|
||
\item[] \textbf{step-start-after:} explicitly given
|
||
time-point as \textbf{12:00}.
|
||
Take step into account if start of price calculation
|
||
is after this time-point.
|
||
\item[] \textbf{step-start-before:} explicitly given
|
||
time-point as \textbf{12:00}.
|
||
Take step into account if start of price calculation
|
||
is before this time-point.
|
||
\item[] \textbf{step-end:} may be set to
|
||
\begin{enumerate}
|
||
\item explicitly given time-point as \textbf{20:00}
|
||
\item \textbf{midnight}: the \gls{tariff-step} ends at midnight.
|
||
Same as time-point setting 24:00.
|
||
\end{enumerate}
|
||
\item[] \textbf{step-price-per-minute:} used for interpolating
|
||
the price of the \gls{tariff-step} in case the \gls{tariff-step}
|
||
is not fully used.
|
||
\item[] \textbf{step-price} full price of the \gls{tariff-step}.
|
||
\item[] \textbf{step-type} type of \gls{tariff-step}. Possible values:
|
||
\begin{enumerate}
|
||
\item \gls{tariff-step single}
|
||
\item cont
|
||
\end{enumerate}
|
||
\end{enumerate}
|
||
\end{enumerate}
|
||
|
||
\subsection{special days}
|
||
TODO.
|
||
Settings for public holidays and open for sale days
|
||
|
||
\subsection{carry-over-if}
|
||
TODO.
|
||
Basically describe under what conditions a carry-over
|
||
might take place.
|
||
|
||
\subsection{prepaid-if}
|
||
|
||
\subsection{Example: tariff file using top half}
|
||
The tariff is given by the PND-operator as follows:
|
||
|
||
\begin{enumerate}
|
||
\item 24/7 service time ranges for all parking machines on all weekdays.
|
||
\item No exceptions (for example for holidays).
|
||
\item Each weekday is handled the same way.
|
||
\item Customer can buy ticket valid for up to 7 days. For each began day,
|
||
the price is 7 euros.
|
||
\item Do not allow overpay: if the customer pays with coins, paying 51 euros
|
||
means 2 euros lost.
|
||
\end{enumerate}
|
||
|
||
These requirements mean that the maximal parking time is 7 days (or 10080
|
||
minutes), minimal price is 7 euros and maximal price is 49 euros. Further, there
|
||
is no prepaid and no carry-over (because 24/7 service time). Because the is
|
||
no difference between the weekdays, there is no need to override some settings
|
||
in a bottom half of the tariff file.
|
||
|
||
The mapping of the tariff to a JSON file results in:
|
||
|
||
\begin{minted}[frame=single,
|
||
framesep=3mm,
|
||
linenos=true,
|
||
xleftmargin=21pt,
|
||
tabsize=4]{js}
|
||
{
|
||
"project": "project-name",
|
||
"version": "1.0.0",
|
||
"product": "short-term-parking",
|
||
"payment-settings": {
|
||
"min-time": "24:00",
|
||
"max-time": 10080,
|
||
"min-price": 700,
|
||
"max-price": 4900,
|
||
"allow-overpay": false
|
||
|
||
},
|
||
"service-settings": {
|
||
"service-ranges": [
|
||
{
|
||
"service-start": "00:00",
|
||
"service-end": "24:00"
|
||
}
|
||
]
|
||
},
|
||
"tariff-steps": [
|
||
{
|
||
"step-start": "now",
|
||
"step-end": "24:00",
|
||
"step-price": 700,
|
||
"comment": "first tariff-step",
|
||
"comment": "customer can buy anytime (now)",
|
||
"comment": "step ends at midnight"
|
||
},
|
||
{
|
||
"step-duration": 1440,
|
||
"comment": "step-duration given for clarity",
|
||
"step-start": "00",
|
||
"step-end": "24:00",
|
||
"step-repetition-count": 6,
|
||
"step-price": 700,
|
||
"comment": "the following (max. 6) tariff-steps",
|
||
"comment": "price uniformly 7 euros for each day"
|
||
}
|
||
]
|
||
}
|
||
\end{minted}
|
||
|
||
\section{The bottom half of the tariff file}
|
||
The bottom part of the tariff file is for overriding the general settings in the
|
||
top half of the tariff file. For each week day,
|
||
settings can be overridden separately. If a day is not mentioned, the settings
|
||
from the top half apply.
|
||
The general layout of the bottom half therefore looks like this:
|
||
\begin{minted}[frame=single,
|
||
framesep=3mm,
|
||
linenos=true,
|
||
xleftmargin=21pt,
|
||
tabsize=4]{js}
|
||
{
|
||
"monday": [{
|
||
"default": {
|
||
}
|
||
}],
|
||
"tuesday": [{
|
||
"default": {
|
||
}
|
||
}],
|
||
"wednesday": [{
|
||
"default": {
|
||
}
|
||
}],
|
||
"thursday": [{
|
||
}],
|
||
"friday": [{
|
||
"default": {
|
||
}
|
||
}],
|
||
"saturday": [{
|
||
"default": {
|
||
}
|
||
}],
|
||
"sunday": [{
|
||
"default": {
|
||
}
|
||
}]
|
||
}
|
||
\end{minted}
|
||
|
||
Some days are special, though, for instance holidays or open for sale sundays.
|
||
They are mapped into their corresponding weekdays using their date.
|
||
Special days are handled with higher priority.
|
||
|
||
\subsection*{Example}
|
||
Christmas Day in 2024 will be at 2024-12-25, a Wednesday. The same holds for New
|
||
Year’s Day. This results in the following setting:
|
||
\begin{minted}[frame=single,
|
||
framesep=3mm,
|
||
linenos=true,
|
||
xleftmargin=21pt,
|
||
tabsize=4]{js}
|
||
{
|
||
"wednesday": [{
|
||
"2025-01-01": {
|
||
"comment": "New Year’s Day"
|
||
},
|
||
"2024-12-25": {
|
||
"comment": "Christmas Day"
|
||
},
|
||
"default": {
|
||
"comment": "usual wednesday"
|
||
}
|
||
}]
|
||
}
|
||
\end{minted}
|
||
|
||
\subsection{Example: tariff file using top and bottom half}
|
||
\label{top-and-bottom}
|
||
The tariff is given as follows:
|
||
|
||
\begin{enumerate}
|
||
\item Service time ranges: Monday – Sunday: $08:00 – 18:00$.
|
||
\item Holidays are handled as Sundays.
|
||
\item The first $20$ minutes are free for each weekday.
|
||
\item Cost for every other $20$ minutes: $40$ cent.
|
||
\item Maximal parking time for Monday-Saturday: 1 hour. Cost: $80$ cent.
|
||
For Sunday: $3$ hours. Cost: $3,20$ euros.
|
||
\item Prepaid: Yes. No restriction on prepaid time ranges.
|
||
\item Carry-over: Yes.
|
||
\item Plus/Minus: step forward every $20$ minutes, step backward every $5$
|
||
minutes.
|
||
\item Service time restriction: carry-over from Sunday/Holiday to next day
|
||
results in service time range of $08:00-09:00$ on next day. Even if the next day
|
||
is a holiday.
|
||
\end{enumerate}
|
||
\paragraph{Note}
|
||
Due to this specification, $1$ minute costs $2$ cent. Thus, paying by
|
||
credit-card is not a problem. Because overpay is allowed, there is also no
|
||
problem for a
|
||
transition from Sunday to Monday when reaching $09:00$.
|
||
|
||
|
||
\begin{minted}[frame=single,
|
||
framesep=3mm,
|
||
linenos=true,
|
||
xleftmargin=21pt,
|
||
tabsize=4]{js}
|
||
{
|
||
"project": "project-name",
|
||
"version": "1.0.0",
|
||
"product": "short-term-parking",
|
||
"payment-settings": [
|
||
{
|
||
"min-time": 20,
|
||
"max-time": 60,
|
||
"min-price": 0,
|
||
"max-price": 80,
|
||
"allow-overpay": true
|
||
}
|
||
],
|
||
"service-settings": [
|
||
{
|
||
"service-ranges": [
|
||
{
|
||
"service-start": "08:00",
|
||
"service-end": "18:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"prepaid-settings": [
|
||
{
|
||
"prepaid-ranges": [
|
||
{
|
||
"prepaid-start": "00:00",
|
||
"prepaid-end": "08:00"
|
||
},
|
||
{
|
||
"prepaid-start": "18:00",
|
||
"prepaid-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"carry-over-settings": [
|
||
"carry-over-if": {
|
||
"cond": [
|
||
{
|
||
"max-remaining-net-parking-time": {
|
||
"<=": 60,
|
||
"then": true
|
||
}
|
||
},
|
||
{
|
||
"max-remaining-parking-price": {
|
||
"<=": 120,
|
||
"then": true
|
||
}
|
||
},
|
||
{
|
||
"else": false
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"tariff-steps": [
|
||
{
|
||
"step-start": "now",
|
||
"step-duration": 20,
|
||
"step-price": 0
|
||
},
|
||
{
|
||
"step-duration": 5,
|
||
"step-repetition-count": 32,
|
||
"step-price": 10,
|
||
"comment": "repetition count controlled by max-time"
|
||
}
|
||
],
|
||
...
|
||
"wednesday": [{
|
||
"2025-01-01": {
|
||
"comment": "New Year’s Day",
|
||
"type": "holiday",
|
||
"payment-settings": [
|
||
{
|
||
"min-time": 20,
|
||
"max-time": 180,
|
||
"min-price": 0,
|
||
"max-price": 320,
|
||
"allow-overpay": true
|
||
}
|
||
]
|
||
}
|
||
}]
|
||
...
|
||
}
|
||
\end{minted}
|
||
|
||
|
||
\section{Use Cases}
|
||
In this section, several complete examples will be listed.
|
||
|
||
\subsection{Prepaid. Carry over. Weekend free. Price scaling.}
|
||
\subsubsection{Szeged (Hungary)}
|
||
The tariff (for Zone 1) is given as follows (special days for 2024):
|
||
|
||
\begin{enumerate}
|
||
\item[$\bullet$] Service time ranges: Monday – Friday: 08:00 – 18:00.
|
||
\item[$\bullet$] Saturday and Sunday and public holidays are free
|
||
except PND-operator says otherwise.
|
||
\item[$\bullet$] Special open for sale days during the year (e.g. Saturdays
|
||
which are not free).
|
||
\item[$\bullet$] Price per hour: 150 Forint.
|
||
\item[$\bullet$] Minimal parking time: 15 minutes.
|
||
\item[$\bullet$] Minimal parking price: 38 Forint.
|
||
\item[$\bullet$] Maximal parking time: 6 hours.
|
||
\item[$\bullet$] Maximal parking price: 900 Forint.
|
||
|
||
\item[$\bullet$] Prepaid: Yes. No restriction on \gls{prepaid
|
||
tariff-step}(s).
|
||
\item[$\bullet$] Carry-over: yes.
|
||
\item[$\bullet$] Interpolate: no.
|
||
\item[$\bullet$] Allow overpay: yes.
|
||
\end{enumerate}
|
||
|
||
\subsubsection*{Remark: price-scaling-factor}
|
||
The settings for Szeged shows that the price for 15 minutes is
|
||
\begin{equation*}
|
||
(150 / 60) * 15 = 2,5 * 15 = 37,5
|
||
\end{equation*}
|
||
possibly introducing rounding errors. To fix this problem, scale the
|
||
price setting such that the division by $60$ never produces some rest:
|
||
|
||
price-scaling-factor $= LCM(150, 60) / 150 = 300 / 150 = 2$
|
||
|
||
where $LCM(x,y)$ is the least common multiple of the integers $x, y$.
|
||
The price for 15 minutes is then internally
|
||
|
||
$37,5\; *$ price-scaling-factor $= 75$
|
||
|
||
and the computed price has to be divided by the price-scaling-factor
|
||
to get the correct result, of course.
|
||
|
||
\paragraph{Remark}
|
||
The smallest possible coin in Szeged is 5 Forint.
|
||
According to the scaled setting, 5 Forint (HUF) are exactly 1 minute
|
||
parking-time: $5 * 60 = 300$, the scaled price.
|
||
\paragraph{Remark}
|
||
Such a scaling would be possible for the time-dimension only for cases where
|
||
there is full service time (no carry over or prepaid). Usually the duration
|
||
must be computed for every \gls{tariff-step}, see section \ref{Stockerau}.
|
||
|
||
\begin{minted}[frame=single,
|
||
framesep=3mm,
|
||
linenos=true,
|
||
xleftmargin=21pt,
|
||
tabsize=4]{js}
|
||
{
|
||
"project": "Szeged",
|
||
"version": "1.0.0",
|
||
"product": "short-term-parking",
|
||
"payment-settings": [
|
||
{
|
||
"min-time": 15,
|
||
"max-time": 360,
|
||
"min-price": 75,
|
||
"max-price": 1800,
|
||
"comment": "prices already scaled",
|
||
"price-scaling-factor": 2,
|
||
"allow-overpay": true
|
||
}
|
||
],
|
||
"service-settings": [
|
||
{
|
||
"service-ranges": [
|
||
{
|
||
"service-start": "08:00",
|
||
"service-end": "18:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"prepaid-settings": [
|
||
{
|
||
"prepaid-ranges": [
|
||
{
|
||
"prepaid-start": "00:00",
|
||
"prepaid-end": "08:00"
|
||
},
|
||
{
|
||
"prepaid-start": "18:00",
|
||
"prepaid-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"carry-over-settings": [
|
||
{
|
||
"carry-over-ranges": [
|
||
{
|
||
"carry-over-start": "00:00",
|
||
"carry-over-end": "08:00"
|
||
},
|
||
{
|
||
"carry-over-start": "18:00",
|
||
"carry-over-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"tariff-steps": [
|
||
{
|
||
"step-start": "now",
|
||
"step-duration": 15,
|
||
"step-price": 75
|
||
},
|
||
{
|
||
"step-duration": 15,
|
||
"step-repetition-count": 23,
|
||
"step-price": 75,
|
||
"comment": "in total 345 minutes and cost 1725 HUF"
|
||
}
|
||
],
|
||
"monday": [{
|
||
"default": {
|
||
"comment": "settings from top half apply"
|
||
}
|
||
}],
|
||
"tuesday": [{
|
||
"default": {
|
||
"comment": "settings from top half apply"
|
||
}
|
||
}],
|
||
"wednesday": [{
|
||
"2024-12-25": {
|
||
"comment": "Christmas Day",
|
||
"comment": "Public Holidays are free",
|
||
"prepaid-settings": [
|
||
{
|
||
"prepaid-ranges": [
|
||
{
|
||
"prepaid-start": "00:00",
|
||
"prepaid-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"carry-over-settings": [
|
||
{
|
||
"carry-over-ranges": [
|
||
{
|
||
"carry-over-start": "00:00",
|
||
"carry-over-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
},
|
||
"default": {
|
||
"comment": "settings from top half apply"
|
||
}
|
||
}],
|
||
"thursday": [{
|
||
"2024-12-26": {
|
||
"comment": "2nd day of Christmas",
|
||
"comment": "Public Holidays are free",
|
||
"prepaid-settings": [
|
||
{
|
||
"prepaid-ranges": [
|
||
{
|
||
"prepaid-start": "00:00",
|
||
"prepaid-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"carry-over-settings": [
|
||
{
|
||
"carry-over-ranges": [
|
||
{
|
||
"carry-over-start": "00:00",
|
||
"carry-over-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
},
|
||
"default": {
|
||
"comment": "settings from top half apply"
|
||
}
|
||
}],
|
||
"friday": [{
|
||
"default": {
|
||
"comment": "settings from top half apply"
|
||
}
|
||
}],
|
||
"saturday": [{
|
||
"2024-12-07": {
|
||
"comment": "Open For Sale",
|
||
"comment": "settings from top half apply"
|
||
},
|
||
"default": {
|
||
"comment": "Saturday is free",
|
||
"prepaid-settings": [
|
||
{
|
||
"prepaid-ranges": [
|
||
{
|
||
"prepaid-start": "00:00",
|
||
"prepaid-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"carry-over-settings": [
|
||
{
|
||
"carry-over-ranges": [
|
||
{
|
||
"carry-over-start": "00:00",
|
||
"carry-over-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
}],
|
||
"sunday": [{
|
||
"default": {
|
||
"comment": "Sunday is free",
|
||
"prepaid-settings": [
|
||
{
|
||
"prepaid-ranges": [
|
||
{
|
||
"prepaid-start": "00:00",
|
||
"prepaid-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"carry-over-settings": [
|
||
{
|
||
"carry-over-ranges": [
|
||
{
|
||
"carry-over-start": "00:00",
|
||
"carry-over-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
}]
|
||
}
|
||
}
|
||
\end{minted}
|
||
|
||
\subsection{Full time service. No overpay.}
|
||
\subsubsection{Galtür}
|
||
|
||
\begin{enumerate}
|
||
\item[$\bullet$] Service time ranges: Monday – Sunday: 00:00 – 24:00.
|
||
\item[$\bullet$] Price per day: 7 euros.
|
||
\item[$\bullet$] Minimal parking time: 1 day.
|
||
\item[$\bullet$] Minimal parking price: 7 euros.
|
||
\item[$\bullet$] Maximal parking time: 7 days.
|
||
\item[$\bullet$] Maximal parking price: 49 euros.
|
||
\item[$\bullet$] Allow overpay: no.
|
||
\item[$\bullet$] Prepaid: no.
|
||
\item[$\bullet$] Carry over: no.
|
||
\end{enumerate}
|
||
|
||
\begin{minted}[frame=single,
|
||
framesep=3mm,
|
||
linenos=true,
|
||
xleftmargin=21pt,
|
||
tabsize=4]{js}
|
||
{
|
||
"project": "Galtuer",
|
||
"version": "1.0.0",
|
||
"product": "short-term-parking",
|
||
"payment-settings": [
|
||
{
|
||
"min-time": "24:00",
|
||
"max-time": 10080,
|
||
"min-price": 700,
|
||
"max-price": 4900,
|
||
"allow-overpay": false
|
||
}
|
||
],
|
||
"service-settings": [
|
||
{
|
||
"service-ranges": [
|
||
{
|
||
"service-start": "00:00",
|
||
"service-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"comment": "no prepaid-settings",
|
||
"comment": "no carry-over-settings",
|
||
"tariff-steps": [
|
||
{
|
||
"step-start": "now",
|
||
"step-end": "24:00",
|
||
"step-price": 700,
|
||
"comment": "first tariff-step",
|
||
"comment": "customer can buy anytime (now)",
|
||
"comment": "step ends at midnight (next day)"
|
||
},
|
||
{
|
||
"step-duration": 1440,
|
||
"comment": "step-duration given for clarity",
|
||
"step-start": "00:00",
|
||
"step-end": "24:00",
|
||
"step-repetition-count": 6,
|
||
"step-price": 700,
|
||
"comment": "the following (max. 6) tariff-steps",
|
||
"comment": "price uniformly 7 euros for each day"
|
||
}
|
||
],
|
||
"comment": "not mentioning monday-sunday means that",
|
||
"comment": "for monday-sunday apply settings from top-half",
|
||
"comment": "of tariff-file"
|
||
}
|
||
}
|
||
\end{minted}
|
||
|
||
\subsection{Decreasing price the later \gls{start-time}}
|
||
\subsubsection{Pernegg an der Mur}
|
||
|
||
\begin{enumerate}
|
||
\item[$\bullet$] Service time ranges: Monday – Sunday: 06:00 – 17:00.
|
||
\item[$\bullet$] Product: day-ticket.
|
||
\item[$\bullet$] Price per day:
|
||
\begin{enumerate}
|
||
\item 2 euros if \gls{start-time} after $16:00$
|
||
\item 3 euros if \gls{start-time} after $15:00$
|
||
\item 3 euros if \gls{start-time} after $06:00$
|
||
\end{enumerate}
|
||
\item[$\bullet$] Minimal parking time: 60 minutes.
|
||
\item[$\bullet$] Minimal parking price: 2 euros.
|
||
\item[$\bullet$] Maximal parking time: 11 hours (660 minutes).
|
||
\item[$\bullet$] Maximal parking price: 6 euros.
|
||
\item[$\bullet$] No special days..
|
||
\item[$\bullet$] Allow overpay: no.
|
||
\item[$\bullet$] Carry over: no.
|
||
\item[$\bullet$] Prepaid: no.
|
||
\end{enumerate}
|
||
|
||
\begin{minted}[frame=single,
|
||
framesep=3mm,
|
||
linenos=true,
|
||
xleftmargin=21pt,
|
||
tabsize=4]{js}
|
||
{
|
||
"project": "Pernegg an der Mur",
|
||
"version": "1.0.0",
|
||
"product": "day-ticket",
|
||
"payment-settings": [
|
||
{
|
||
"min-time": "17:00",
|
||
"max-time": "17:00",
|
||
"min-price": 200,
|
||
"max-price": 600,
|
||
"allow-overpay": false
|
||
}
|
||
],
|
||
"service-settings": [
|
||
{
|
||
"service-ranges": [
|
||
{
|
||
"service-start": "06:00",
|
||
"service-end": "17:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"comment": "no prepaid-settings",
|
||
"comment": "no carry-over-settings",
|
||
"comment": "implicit out-of-service time",
|
||
"comment": "i.e. complement of service time",
|
||
"tariff-steps": [
|
||
{
|
||
"step-start-after": "06:00",
|
||
"step-start-before": "15:00",
|
||
"step-end": "17:00",
|
||
"step-price": 600,
|
||
"comment": "unique tariff-step"
|
||
},
|
||
{
|
||
"step-start-after": "15:00",
|
||
"step-start-before": "16:00",
|
||
"step-end": "17:00",
|
||
"step-price": 300,
|
||
"comment": "unique tariff-step"
|
||
},
|
||
{
|
||
"step-start-after": "16:00",
|
||
"step-end": "17:00",
|
||
"step-price": 200,
|
||
"comment": "unique tariff-step"
|
||
}
|
||
],
|
||
"comment": "not mentioning monday-sunday means that",
|
||
"comment": "for monday-sunday apply settings from top-half",
|
||
"comment": "of tariff-file"
|
||
}
|
||
}
|
||
\end{minted}
|
||
|
||
%\subsection{Linsinger Maschinenbau}
|
||
%\subsection{Nordisches Ausbildungszentrum (NAZ)}
|
||
|
||
\subsection{Full time service. Variable \gls{tariff-step}s.}
|
||
\subsubsection{Christoph Reisen}
|
||
|
||
\begin{enumerate}
|
||
\item[$\bullet$] Service time ranges: Monday – Sunday: 00 – 24:00.
|
||
\item[$\bullet$] Prices:
|
||
\begin{enumerate}
|
||
\item 0-6 hours: 6 euros
|
||
\item 7 hours: 7 euros
|
||
\item 24 hours: 8 euros
|
||
\item 48 hours: 16 euros
|
||
\item 72 hours: 24 euros
|
||
\item 90 hours: 32 euros
|
||
\item 124 hours: 40 euros
|
||
\end{enumerate}
|
||
\item[$\bullet$] Minimal parking time: 360 minutes.
|
||
\item[$\bullet$] Minimal parking price: 6 euros.
|
||
\item[$\bullet$] Maximal parking time: $124 * 60 = 7440$ minutes.
|
||
\item[$\bullet$] Maximal parking price: 40 euros.
|
||
\item[$\bullet$] Allow overpay: yes.
|
||
\end{enumerate}
|
||
|
||
\begin{minted}[frame=single,
|
||
framesep=3mm,
|
||
linenos=true,
|
||
xleftmargin=21pt,
|
||
tabsize=4]{js}
|
||
{
|
||
"project": "Christoph Reisen",
|
||
"version": "1.0.0",
|
||
"product": "day-ticket",
|
||
"payment-settings": [
|
||
{
|
||
"min-time": 360,
|
||
"max-time": 7440,
|
||
"min-price": 600,
|
||
"max-price": 4000,
|
||
"price-scaling-factor": 1,
|
||
"allow-overpay": true
|
||
}
|
||
],
|
||
"service-settings": [
|
||
{
|
||
"service-ranges": [
|
||
{
|
||
"service-start": "00:00",
|
||
"service-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"comment": "no prepaid-settings",
|
||
"comment": "no carry-over-settings",
|
||
"comment": "implicit out-of-service time",
|
||
"comment": "i.e. complement of service time",
|
||
"tariff-steps": [
|
||
{
|
||
"step-start": "now",
|
||
"step-duration": 360,
|
||
"step-price": 600,
|
||
"step_type": "single",
|
||
"comment": "single tariff-step"
|
||
},
|
||
{
|
||
"step-start": "now",
|
||
"step-duration": 420,
|
||
"step-price": 700,
|
||
"step_type": "single"
|
||
},
|
||
{
|
||
"step-start": "now",
|
||
"step-duration": 1440,
|
||
"step-price": 800,
|
||
"step_type": "single"
|
||
},
|
||
{
|
||
"step-start": "now",
|
||
"step-duration": 2880,
|
||
"step-price": 1600,
|
||
"step_type": "single"
|
||
},
|
||
{
|
||
"step-start": "now",
|
||
"step-duration": 4320,
|
||
"step-price": 2400,
|
||
"step_type": "single"
|
||
},
|
||
{
|
||
"step-start": "now",
|
||
"step-duration": 5400,
|
||
"step-price": 3200,
|
||
"step_type": "single"
|
||
},
|
||
{
|
||
"step-start": "now",
|
||
"step-duration": 7440,
|
||
"step-price": 4000,
|
||
"step_type": "single"
|
||
}
|
||
],
|
||
"comment": "not mentioning monday-sunday means that",
|
||
"comment": "for monday-sunday apply settings from top-half",
|
||
"comment": "of tariff-file"
|
||
}
|
||
}
|
||
\end{minted}
|
||
|
||
\subsection{Several service time ranges per day. Scaling factor}
|
||
\subsubsection{Stockerau}
|
||
\label{Stockerau}
|
||
\begin{enumerate}
|
||
\item[$\bullet$] Service time ranges:
|
||
\begin{enumerate}
|
||
\item Monday – Friday: $08:00–12:00$ and $13:30-18:00$
|
||
\item Saturday: $08:00-12:00$
|
||
\item Sunday and special days (holidays, open for sale days)
|
||
are free.
|
||
\end{enumerate}
|
||
\item[$\bullet$] Prices:
|
||
\begin{enumerate}
|
||
\item first 30 minutes: 70 cent
|
||
\item 60 minutes: 1,40 euros
|
||
\item 120 minutes: 2,80 euros
|
||
\item 180 minutes: 4,20 euros
|
||
\item 240 minutes: 5,60 euros
|
||
\end{enumerate}
|
||
\item[$\bullet$] Minimal parking time: 30 minutes.
|
||
\item[$\bullet$] Minimal parking price: 70 cent.
|
||
\item[$\bullet$] Maximal parking time: 257 minutes.
|
||
\item[$\bullet$] Maximal parking price: 6 euros.
|
||
\item[$\bullet$] Allow overpay: no.
|
||
\item[$\bullet$] Carry over: yes.
|
||
\item[$\bullet$] Prepaid: yes.
|
||
\item[$\bullet$] Smallest possible coin: 10 cent.
|
||
\end{enumerate}
|
||
|
||
|
||
\begin{minted}[frame=single,
|
||
framesep=3mm,
|
||
linenos=true,
|
||
xleftmargin=21pt,
|
||
tabsize=4]{js}
|
||
{
|
||
"project": "Stockerau",
|
||
"version": "1.0.0",
|
||
"product": "short-term-parking",
|
||
"payment-settings": [
|
||
{
|
||
"min-time": 30,
|
||
"max-time": 257,
|
||
"min-price": 70,
|
||
"max-price": 600,
|
||
"allow-overpay": true
|
||
}
|
||
],
|
||
"service-settings": [
|
||
{
|
||
"service-ranges": [
|
||
{
|
||
"service-start": "08:00",
|
||
"service-end": "12:00"
|
||
},
|
||
{
|
||
"service-start": "13:30",
|
||
"service-end": "18:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"prepaid-settings": [
|
||
{
|
||
"prepaid-ranges": [
|
||
{
|
||
"prepaid-start": "00:00",
|
||
"prepaid-end": "08:00"
|
||
},
|
||
{
|
||
"prepaid-start": "12:00",
|
||
"prepaid-end": "13:30"
|
||
},
|
||
{
|
||
"prepaid-start": "18:00",
|
||
"prepaid-end": "24:00"
|
||
},
|
||
}
|
||
],
|
||
"carry-over-settings": [
|
||
{
|
||
"carry-over-ranges": [
|
||
{
|
||
"carry-over-start": "00:00",
|
||
"carry-over-end": "08:00"
|
||
},
|
||
{
|
||
"carry-over-start": "12:00",
|
||
"carry-over-end": "13:30"
|
||
},
|
||
{
|
||
"carry-over-start": "18:00",
|
||
"carry-over-end": "24:00"
|
||
},
|
||
]
|
||
}
|
||
],
|
||
"tariff-steps": [
|
||
{
|
||
"step-start": "now",
|
||
"step-duration": 30,
|
||
"step-price": 70
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 34
|
||
},
|
||
{
|
||
"step-duration": 5,
|
||
"step-price": 10
|
||
"comment": 39
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 43
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 47
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 51
|
||
},
|
||
{
|
||
"step-duration": 5,
|
||
"step-price": 10
|
||
"comment": 56
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 60
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 64
|
||
},
|
||
{
|
||
"step-duration": 5,
|
||
"step-price": 10
|
||
"comment": 69
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 73
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 77
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 81
|
||
},
|
||
{
|
||
"step-duration": 5,
|
||
"step-price": 10
|
||
"comment": 86
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 90
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 94
|
||
},
|
||
{
|
||
"step-duration": 5,
|
||
"step-price": 10
|
||
"comment": 99
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 103
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 107
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 111
|
||
},
|
||
{
|
||
"step-duration": 5,
|
||
"step-price": 10
|
||
"comment": 116
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 120
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 124
|
||
},
|
||
{
|
||
"step-duration": 5,
|
||
"step-price": 10
|
||
"comment": 129
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 133
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 137
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 141
|
||
},
|
||
{
|
||
"step-duration": 5,
|
||
"step-price": 10
|
||
"comment": 146
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 150
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 154
|
||
},
|
||
{
|
||
"step-duration": 5,
|
||
"step-price": 10
|
||
"comment": 159
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 163
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 167
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 171
|
||
},
|
||
{
|
||
"step-duration": 5,
|
||
"step-price": 10
|
||
"comment": 176
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 180
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 184
|
||
},
|
||
{
|
||
"step-duration": 5,
|
||
"step-price": 10
|
||
"comment": 189
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 193
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 197
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 201
|
||
},
|
||
{
|
||
"step-duration": 5,
|
||
"step-price": 10
|
||
"comment": 206
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 210
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 214
|
||
},
|
||
{
|
||
"step-duration": 5,
|
||
"step-price": 10
|
||
"comment": 219
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 223
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 227
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 231
|
||
},
|
||
{
|
||
"step-duration": 5,
|
||
"step-price": 10
|
||
"comment": 236
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 240
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 244
|
||
},
|
||
{
|
||
"step-duration": 5,
|
||
"step-price": 10
|
||
"comment": 249
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 253
|
||
},
|
||
{
|
||
"step-duration": 4,
|
||
"step-price": 10
|
||
"comment": 257
|
||
}
|
||
],
|
||
"comment": "monday-friday not really necessary",
|
||
"monday": [{
|
||
"default": {
|
||
"comment": "settings from top half apply"
|
||
}
|
||
}],
|
||
"tuesday": [{
|
||
"2024-12-24": {
|
||
"comment": "Christmas",
|
||
"comment": "Public Holidays are free",
|
||
"prepaid-settings": [
|
||
{
|
||
"prepaid-ranges": [
|
||
{
|
||
"prepaid-start": "00:00",
|
||
"prepaid-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"carry-over-settings": [
|
||
{
|
||
"carry-over-ranges": [
|
||
{
|
||
"carry-over-start": "00:00",
|
||
"carry-over-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
},
|
||
"default": {
|
||
"comment": "settings from top half apply"
|
||
}
|
||
}],
|
||
"wednesday": [{
|
||
"2024-12-25": {
|
||
"comment": "1st day of Christmas",
|
||
"comment": "Public Holidays are free",
|
||
"prepaid-settings": [
|
||
{
|
||
"prepaid-ranges": [
|
||
{
|
||
"prepaid-start": "00:00",
|
||
"prepaid-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"carry-over-settings": [
|
||
{
|
||
"carry-over-ranges": [
|
||
{
|
||
"carry-over-start": "00:00",
|
||
"carry-over-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
},
|
||
"default": {
|
||
"comment": "settings from top half apply"
|
||
}
|
||
}],
|
||
"thursday": [{
|
||
"2024-12-26": {
|
||
"comment": "2nd day of Christmas",
|
||
"comment": "Public Holidays are free",
|
||
"prepaid-settings": [
|
||
{
|
||
"prepaid-ranges": [
|
||
{
|
||
"prepaid-start": "00:00",
|
||
"prepaid-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"carry-over-settings": [
|
||
{
|
||
"carry-over-ranges": [
|
||
{
|
||
"carry-over-start": "00:00",
|
||
"carry-over-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
},
|
||
"default": {
|
||
"comment": "settings from top half apply"
|
||
}
|
||
}],
|
||
"friday": [{
|
||
"default": {
|
||
"comment": "settings from top half apply"
|
||
}
|
||
}],
|
||
"saturday": [{
|
||
"default": {
|
||
"prepaid-settings": [
|
||
{
|
||
"prepaid-ranges": [
|
||
{
|
||
"prepaid-start": "00:00",
|
||
"prepaid-end": "08:00"
|
||
},
|
||
{
|
||
"prepaid-start": "12:00",
|
||
"prepaid-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"carry-over-settings": [
|
||
{
|
||
"carry-over-ranges": [
|
||
{
|
||
"carry-over-start": "00:00",
|
||
"carry-over-end": "08:00"
|
||
},
|
||
{
|
||
"carry-over-start": "12:00",
|
||
"carry-over-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"service-settings": [
|
||
{
|
||
"service-ranges": [
|
||
{
|
||
"service-start": "08:00",
|
||
"service-end": "12:00"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
}],
|
||
"sunday": [{
|
||
"default": {
|
||
"comment": "Sunday is free",
|
||
"prepaid-settings": [
|
||
{
|
||
"prepaid-ranges": [
|
||
{
|
||
"prepaid-start": "00:00",
|
||
"prepaid-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"prepaid-settings": [
|
||
{
|
||
"prepaid-ranges": [
|
||
{
|
||
"prepaid-start": "00:00",
|
||
"prepaid-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
}]
|
||
}
|
||
}
|
||
\end{minted}
|
||
|
||
|
||
\subsection{Several service time ranges per day. Free special days.}
|
||
\subsubsection{Korneuburg}
|
||
|
||
\begin{enumerate}
|
||
\item[$\bullet$] Service time ranges:
|
||
\begin{enumerate}
|
||
\item Monday – Friday: $08:00–12:00$ and $14:00-18:00$
|
||
\item Saturday: $08:00-12:00$
|
||
\item Sunday and special days (holidays, open for sale days)
|
||
are free.
|
||
\end{enumerate}
|
||
\item[$\bullet$] Prices:
|
||
\begin{enumerate}
|
||
\item first 30 minutes: 60 cent
|
||
\item each following 5 minutes: 10 cent
|
||
\end{enumerate}
|
||
\item[$\bullet$] Minimal parking time: 30 minutes.
|
||
\item[$\bullet$] Minimal parking price: 60 euros.
|
||
\item[$\bullet$] Maximal parking time: 180 minutes.
|
||
\item[$\bullet$] Maximal parking price: 3,60 euros.
|
||
\item[$\bullet$] Allow overpay: yes.
|
||
\item[$\bullet$] Carry over: yes.
|
||
\item[$\bullet$] Prepaid: no.
|
||
\end{enumerate}
|
||
|
||
\begin{minted}[frame=single,
|
||
framesep=3mm,
|
||
linenos=true,
|
||
xleftmargin=21pt,
|
||
tabsize=4]{js}
|
||
{
|
||
"project": "Korneuburg",
|
||
"version": "1.0.0",
|
||
"product": "short-term-parking",
|
||
"payment-settings": [
|
||
{
|
||
"min-time": 30,
|
||
"max-time": 180,
|
||
"min-price": 60,
|
||
"max-price": 360,
|
||
"allow-overpay": true
|
||
}
|
||
],
|
||
"service-settings": [
|
||
{
|
||
"service-ranges": [
|
||
{
|
||
"service-start": "08:00",
|
||
"service-end": "12:00"
|
||
},
|
||
{
|
||
"service-start": "14:00",
|
||
"service-end": "18:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"comment": "no prepaid-settings",
|
||
"carry-over-settings": [
|
||
{
|
||
"carry-over-ranges": [
|
||
{
|
||
"carry-over-start": "12:00",
|
||
"carry-over-end": "14:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"tariff-steps": [
|
||
{
|
||
"step-start": "now",
|
||
"step-duration": 30,
|
||
"step-price": 60
|
||
},
|
||
{
|
||
"step-duration": 5,
|
||
"step-repetition-count": 30,
|
||
"step-price": 10,
|
||
"comment": "in total 150 minutes and cost 3 euros"
|
||
}
|
||
],
|
||
"comment": "monday-friday not really necessary",
|
||
"monday": [{
|
||
"default": {
|
||
"comment": "settings from top half apply"
|
||
}
|
||
}],
|
||
"tuesday": [{
|
||
"2024-12-24": {
|
||
"comment": "Christmas",
|
||
"comment": "Public Holidays are free",
|
||
"prepaid-settings": [
|
||
{
|
||
"prepaid-ranges": [
|
||
{
|
||
"prepaid-start": "00:00",
|
||
"prepaid-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"carry-over-settings": [
|
||
{
|
||
"carry-over-ranges": [
|
||
{
|
||
"carry-over-start": "00:00",
|
||
"carry-over-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
},
|
||
"default": {
|
||
"comment": "settings from top half apply"
|
||
}
|
||
}],
|
||
"wednesday": [{
|
||
"2024-12-25": {
|
||
"comment": "1st day of Christmas",
|
||
"comment": "Public Holidays are free",
|
||
"prepaid-settings": [
|
||
{
|
||
"prepaid-ranges": [
|
||
{
|
||
"prepaid-start": "00:00",
|
||
"prepaid-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"carry-over-settings": [
|
||
{
|
||
"carry-over-ranges": [
|
||
{
|
||
"carry-over-start": "00:00",
|
||
"carry-over-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
},
|
||
"default": {
|
||
"comment": "settings from top half apply"
|
||
}
|
||
}],
|
||
"thursday": [{
|
||
"2024-12-26": {
|
||
"comment": "2nd day of Christmas",
|
||
"comment": "Public Holidays are free",
|
||
"prepaid-settings": [
|
||
{
|
||
"prepaid-ranges": [
|
||
{
|
||
"prepaid-start": "00:00",
|
||
"prepaid-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"carry-over-settings": [
|
||
{
|
||
"carry-over-ranges": [
|
||
{
|
||
"carry-over-start": "00:00",
|
||
"carry-over-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
},
|
||
"default": {
|
||
"comment": "settings from top half apply"
|
||
}
|
||
}],
|
||
"friday": [{
|
||
"default": {
|
||
"comment": "settings from top half apply"
|
||
}
|
||
}],
|
||
"saturday": [{
|
||
"default": {
|
||
"carry-over-settings": [
|
||
{
|
||
"carry-over-ranges": [
|
||
{
|
||
"carry-over-start": "00:00",
|
||
"carry-over-end": "08:00"
|
||
},
|
||
{
|
||
"carry-over-start": "12:00",
|
||
"carry-over-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"service-settings": [
|
||
{
|
||
"service-ranges": [
|
||
{
|
||
"service-start": "08:00",
|
||
"service-end": "12:00"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
}],
|
||
"sunday": [{
|
||
"default": {
|
||
"comment": "Sunday is free",
|
||
"carry-over-settings": [
|
||
{
|
||
"carry-over-ranges": [
|
||
{
|
||
"carry-over-start": "00:00",
|
||
"carry-over-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
}]
|
||
}
|
||
}
|
||
\end{minted}
|
||
|
||
\subsection{Several service time ranges per day. Free special days. No prepaid.}
|
||
\subsubsection{Kirchdorf}
|
||
|
||
\begin{enumerate}
|
||
\item[$\bullet$] Service time ranges:
|
||
\begin{enumerate}
|
||
\item Monday – Friday: 08:00 – 12:00 and 14:00 - 18:00
|
||
\item Saturday: 08:00 - 12:00
|
||
\item Sunday and special days (holidays, open for sale days)
|
||
are free.
|
||
\end{enumerate}
|
||
\item[$\bullet$] Prices:
|
||
\begin{enumerate}
|
||
\item first 30 minutes: 30 cent
|
||
\item each following 5 minutes: 10 cent
|
||
\end{enumerate}
|
||
\item[$\bullet$] Minimal parking time: 30 minutes.
|
||
\item[$\bullet$] Minimal parking price: 30 cent.
|
||
\item[$\bullet$] Maximal parking time: 90 minutes.
|
||
\item[$\bullet$] Maximal parking price: 1,50 euros.
|
||
\item[$\bullet$] Allow overpay: yes.
|
||
\item[$\bullet$] Carry over: yes.
|
||
\item[$\bullet$] Prepaid: yes.
|
||
\end{enumerate}
|
||
|
||
\begin{minted}[frame=single,
|
||
framesep=3mm,
|
||
linenos=true,
|
||
xleftmargin=21pt,
|
||
tabsize=4]{js}
|
||
{
|
||
"project": "Korneuburg",
|
||
"version": "1.0.0",
|
||
"product": "short-term-parking",
|
||
"payment-settings": [
|
||
{
|
||
"min-time": 30,
|
||
"max-time": 90,
|
||
"min-price": 30,
|
||
"max-price": 150,
|
||
"allow-overpay": true
|
||
}
|
||
],
|
||
"service-settings": [
|
||
{
|
||
"service-ranges": [
|
||
{
|
||
"service-start": "08:00",
|
||
"service-end": "12:00"
|
||
},
|
||
{
|
||
"service-start": "14:00",
|
||
"service-end": "18:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"prepaid-settings": [
|
||
{
|
||
"prepaid-ranges": [
|
||
{
|
||
"prepaid-start": "00:00",
|
||
"prepaid-end": "08:00"
|
||
},
|
||
{
|
||
"prepaid-start": "12:00",
|
||
"prepaid-end": "14:00"
|
||
},
|
||
{
|
||
"prepaid-start": "18:00",
|
||
"prepaid-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"comment": "no carry-over-settings",
|
||
"tariff-steps": [
|
||
{
|
||
"step-start": "now",
|
||
"step-duration": 30,
|
||
"step-price": 60
|
||
},
|
||
{
|
||
"step-duration": 5,
|
||
"step-repetition-count": 30,
|
||
"step-price": 10,
|
||
"comment": "in total 150 minutes and cost 3 euros"
|
||
}
|
||
],
|
||
"comment": "monday-friday not really necessary",
|
||
"monday": [{
|
||
"default": {
|
||
"comment": "settings from top half apply"
|
||
}
|
||
}],
|
||
"tuesday": [{
|
||
"2024-12-24": {
|
||
"comment": "Christmas",
|
||
"comment": "Public Holidays are free",
|
||
"prepaid-settings": [
|
||
{
|
||
"prepaid-ranges": [
|
||
{
|
||
"prepaid-start": "00:00",
|
||
"prepaid-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"carry-over-settings": [
|
||
{
|
||
"carry-over-ranges": [
|
||
{
|
||
"carry-over-start": "00:00",
|
||
"carry-over-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
},
|
||
"default": {
|
||
"comment": "settings from top half apply"
|
||
}
|
||
}],
|
||
"wednesday": [{
|
||
"2024-12-25": {
|
||
"comment": "1st day of Christmas",
|
||
"comment": "Public Holidays are free",
|
||
"prepaid-settings": [
|
||
{
|
||
"prepaid-ranges": [
|
||
{
|
||
"prepaid-start": "00:00",
|
||
"prepaid-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"carry-over-settings": [
|
||
{
|
||
"carry-over-ranges": [
|
||
{
|
||
"carry-over-start": "00:00",
|
||
"carry-over-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
},
|
||
"default": {
|
||
"comment": "settings from top half apply"
|
||
}
|
||
}],
|
||
"thursday": [{
|
||
"2024-12-25": {
|
||
"comment": "2nd day of Christmas",
|
||
"comment": "Public Holidays are free",
|
||
"prepaid-settings": [
|
||
{
|
||
"prepaid-ranges": [
|
||
{
|
||
"prepaid-start": "00:00",
|
||
"prepaid-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"carry-over-settings": [
|
||
{
|
||
"carry-over-ranges": [
|
||
{
|
||
"carry-over-start": "00:00",
|
||
"carry-over-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
},
|
||
"default": {
|
||
"comment": "settings from top half apply"
|
||
}
|
||
}],
|
||
"friday": [{
|
||
"default": {
|
||
"comment": "settings from top half apply"
|
||
}
|
||
}],
|
||
"saturday": [{
|
||
"default": {
|
||
"prepaid-settings": [
|
||
{
|
||
"prepaid-ranges": [
|
||
{
|
||
"prepaid-start": "00:00",
|
||
"prepaid-end": "08:00"
|
||
},
|
||
{
|
||
"prepaid-start": "12:00",
|
||
"prepaid-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"service-settings": [
|
||
{
|
||
"service-ranges": [
|
||
{
|
||
"service-start": "08:00",
|
||
"service-end": "12:00"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
}],
|
||
"sunday": [{
|
||
"default": {
|
||
"comment": "Sunday is free",
|
||
"prepaid-settings": [
|
||
{
|
||
"prepaid-ranges": [
|
||
{
|
||
"prepaid-start": "00:00",
|
||
"prepaid-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
|
||
}
|
||
}]
|
||
}
|
||
}
|
||
\end{minted}
|
||
|
||
\subsection{Different max-price for Sunday. 1 minute resolution for
|
||
last tariff-step}
|
||
\subsubsection{Bad Neuenahr}
|
||
See section \ref{top-and-bottom}.
|
||
|
||
%\subsection{Weiden}
|
||
%\subsection{Forchach}
|
||
%\subsection{Schnals}
|
||
|
||
\subsection{Set min-time and/or min-price at runtime}
|
||
\subsubsection{Valser Alm: Fane}
|
||
|
||
\begin{enumerate}
|
||
\item[$\bullet$] Service time ranges: Monday – Sunday: 00:00 – 24:00.
|
||
\item[$\bullet$] Minimal parking time: until 14:00 if arrival time is
|
||
before 14:00. Otherwise until 24:00.
|
||
\item[$\bullet$] Minimal parking price: 8 euros if arrival time is
|
||
before 14:00. Otherwise 5 euros.
|
||
\item[$\bullet$] Maximal parking time: unlimited.
|
||
\item[$\bullet$] Maximal parking price: unlimited.
|
||
\item[$\bullet$] Allow overpay: no.
|
||
\item[$\bullet$] Prepaid: no.
|
||
\end{enumerate}
|
||
|
||
\begin{minted}[frame=single,
|
||
framesep=3mm,
|
||
linenos=true,
|
||
xleftmargin=21pt,
|
||
tabsize=4]{js}
|
||
{
|
||
"header" : {
|
||
"project": "Valser Alm (Fane)",
|
||
"version": "1.0.0",
|
||
"product": "short-term-parking",
|
||
"info": ""
|
||
},
|
||
"top" : {
|
||
"payment-settings": {
|
||
"min-time": {
|
||
"cond": [
|
||
{
|
||
"current-wallclock-parking-time": {
|
||
"<": "14:00",
|
||
"then": "14:00"
|
||
}
|
||
},
|
||
{
|
||
"else": "24:00"
|
||
}
|
||
]
|
||
},
|
||
"min-price": {
|
||
"cond": [
|
||
{
|
||
"current-wallclock-parking-time": {
|
||
"<": "14:00",
|
||
"then": 800
|
||
}
|
||
},
|
||
{
|
||
"else": 500
|
||
}
|
||
]
|
||
},
|
||
"max-time": "unlimited",
|
||
"max-price": "unlimited",
|
||
"allow-overpay": true,
|
||
"prepaid": false
|
||
},
|
||
"service-settings": [
|
||
{
|
||
"service-ranges": [
|
||
{
|
||
"service-start": "00:00",
|
||
"service-end": "24:00"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"comment": "no prepaid-settings",
|
||
"comment": "no carry-over-settings",
|
||
"tariff-steps": [
|
||
{
|
||
"step-start": "now",
|
||
"step-duration": "min-time"
|
||
"step-price": "min-price"
|
||
},
|
||
{
|
||
"step-duration": 1440,
|
||
"step-start": "00:00",
|
||
"step-end": "24:00",
|
||
"step-repetition-count": "unlimited",
|
||
"step-price": 800
|
||
}
|
||
]
|
||
},
|
||
"bottom" : {
|
||
"comment": "monday-sunday not necessary",
|
||
"comment": "take implicitly settings from top half"
|
||
}
|
||
}
|
||
}
|
||
\end{minted}
|
||
|
||
\subsubsection{Valser Alm: Specker}
|
||
Two different \gls{tariff-file}s for this site: \textbf{PKW} and \textbf{BUS}.
|
||
|
||
% TODO: eine aufspaltung zwichen arrival-time und start-time. insbesondere
|
||
% bei prepaid ist das wichti.
|
||
|
||
\begin{enumerate}
|
||
\item[$\bullet$] Service time ranges: Monday – Sunday: 07:00 – 19:00.
|
||
\item[$\bullet$] Minimal parking time: 12 hours.
|
||
\item[$\bullet$] Maximal parking time: 7 days.
|
||
\item[$\bullet$] Allow overpay: no.
|
||
\item[$\bullet$] Prepaid: yes.
|
||
\item[$\bullet$] Carry over: yes.
|
||
\item[] \textbf{PKW}
|
||
\begin{enumerate}
|
||
\item[$\bullet$] Minimal parking price: 6 euros.
|
||
\item[$\bullet$] Maximal parking price: 42 euros.
|
||
\end{enumerate}
|
||
\item[] \textbf{BUS}
|
||
\begin{enumerate}
|
||
\item[$\bullet$] Minimal parking price: 30 euros.
|
||
\item[$\bullet$] Maximal parking price: 210 euros.
|
||
\end{enumerate}
|
||
|
||
\end{enumerate}
|
||
|
||
%\subsection{Sexten}
|
||
%\subsection{Wolkenstein}
|
||
|
||
\section{Known issues}
|
||
|
||
\pagebreak
|
||
% Print the glossary
|
||
\printglossaries
|
||
|
||
\end{document}
|