Compare commits

..

6 Commits

Author SHA1 Message Date
b9a7c04db9 Add compute_next_timestep() computing timesteps if PaymentMethod = Steps.
Add additional code for computing time steps dynamically if PaymentMethod = Linear.
2023-12-07 16:28:17 +01:00
5b8d9c62cc Add and implement utilities:
int getMinimalParkingTime(Configuration const *cfg, PaymentMethod methodId);
    int getMaximalParkingTime(Configuration const *cfg, PaymentMethod methodId);
    uint32_t getMinimalParkingPrice(Configuration const *cfg, PaymentMethod methodId);
    uint32_t getFirstDurationStep(Configuration const *cfg, PaymentMethod methodId);
2023-12-07 16:27:09 +01:00
56e2843ddb Add compute_next_timestep(). 2023-12-07 16:26:09 +01:00
6b76c4c2dd Add test cases for neuhauser. 2023-12-06 10:52:35 +01:00
54e9a0f86d Minor: add debug ouput (and commnt it out) 2023-12-06 10:51:46 +01:00
d7beb3b41b Fix: replace 'continue' with 'break' to return first fitting time-range
in findNextWorkTimeRange().
2023-12-06 10:49:33 +01:00
6 changed files with 164 additions and 5 deletions

View File

@ -109,6 +109,8 @@ CalcState CALCULATE_LIBRARY_API init_tariff(parking_tariff_t **tariff,
void CALCULATE_LIBRARY_API free_tariff(parking_tariff_t *tariff);
int CALCULATE_LIBRARY_API get_zone_nr(int zone = -1);
int CALCULATE_LIBRARY_API compute_next_timestep(parking_tariff_t *tariff, int currentTimeMinutes, int UpDown);
CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( // deprecated
parking_tariff_t *tariff,
time_t start_parking_time,

View File

@ -82,4 +82,9 @@ namespace Utilities {
bool isCarryOverSet(Configuration const *cfg, PaymentMethod paymentMethodId);
bool isCarryOverNotSet(Configuration const *cfg, PaymentMethod paymentMethodId);
PaymentMethod getPaymentMethodId(Configuration const *cfg);
int getMinimalParkingTime(Configuration const *cfg, PaymentMethod methodId);
int getMaximalParkingTime(Configuration const *cfg, PaymentMethod methodId);
uint32_t getMinimalParkingPrice(Configuration const *cfg, PaymentMethod methodId);
uint32_t getFirstDurationStep(Configuration const *cfg, PaymentMethod methodId);
}

View File

@ -2,6 +2,7 @@
#include "configuration.h"
#include "calculator_functions.h"
#include "payment_option.h"
#include "utilities.h"
#include <QFile>
#include <QFileInfo>
@ -92,6 +93,77 @@ void CALCULATE_LIBRARY_API free_tariff(parking_tariff_t *tariff) {
}
}
//
// UpDown 1 -> up; 0 -> down
int CALCULATE_LIBRARY_API compute_next_timestep(parking_tariff_t *tariff, int currentTimeMinutes, int UpDown)
{
// use tariff with structure as for instance Schnau, Koenigsee:
// without given YearPeriod, SpecialDays and SpecialDaysWorktime
if (tariff->YearPeriod.size() == 0
&& tariff->SpecialDays.size() == 0
&& tariff->SpecialDaysWorktime.size() == 0)
{
static const QList<int> stepList = calculator.GetTimeSteps(tariff);
int currentStepIndex = stepList.indexOf(currentTimeMinutes);
if (currentStepIndex == -1) {
qCritical() << "compute_next_timestep() *NO STEP* for currentTimeMinutes (" << currentTimeMinutes << ")";
return currentTimeMinutes;
}
if (UpDown == 1) { // UP
if (stepList[currentStepIndex] == stepList.last()) {
qCritical() << "compute_next_timestep() *NO NEXT STEP* for currentTimeMinutes (" << currentTimeMinutes << ")";
return currentTimeMinutes;
}
else {
return stepList[currentStepIndex + 1];
}
}
if (UpDown == 0) { // DOWN
if (stepList[currentStepIndex] == stepList.first()) {
qCritical() << "compute_next_timestep() *NO PREVIOUS STEP* for currentTimeMinutes (" << currentTimeMinutes << ")";
return currentTimeMinutes;
}
else {
return stepList[currentStepIndex - 1];
}
}
} else {
Configuration const *cfg = tariff;
// currentTimeMinutes is the number of minutes actually used. This
// value is an offset from the start time and cannot be used as a
// QDateTime.
qCritical() << "compute_next_timestep() currentTimeMinutes:" << currentTimeMinutes;
// compute payment method id (e.g. Linear=3, Steps=4)
PaymentMethod paymentMethodId = Utilities::getPaymentMethodId(cfg);
qCritical() << " compute_next_timestep() paymentMethodId:" << paymentMethodId;
// get minimal and maximal parking times
int const minParkingTime = Utilities::getMinimalParkingTime(cfg, paymentMethodId);
int const maxParkingTime = Utilities::getMaximalParkingTime(cfg, paymentMethodId);
qCritical() << " compute_next_timestep() maxParkingTime:" << paymentMethodId;
qCritical() << " compute_next_timestep() minParkingTime:" << paymentMethodId;
// use the first (i.e. main duration step contained in the tariff json-file)
int firstDurationStep = Utilities::getFirstDurationStep(cfg, paymentMethodId);
qCritical() << " compute_next_timestep() firstDurationStep:" << paymentMethodId;
int nextTimeStep = currentTimeMinutes + firstDurationStep;
if (currentTimeMinutes >= minParkingTime && nextTimeStep <= maxParkingTime) {
qCritical() << " compute_next_timestep() nextTimeStep:" << nextTimeStep;
return nextTimeStep;
}
}
qCritical() << "compute_next_timestep() *CAN NOT COMPUTE* for currentTimeMinutes (" << currentTimeMinutes << ")";
return currentTimeMinutes;
}
// this is currently not used
CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(

View File

@ -265,7 +265,7 @@ int Calculator::findNextWorkTimeRange(QDateTime const &dt,
if (dt.time() < worktime_from) {
nextWorkTimeRange = w;
continue;
break;
}
}
return nextWorkTimeRange;
@ -364,6 +364,9 @@ Ticket Calculator::private_GetCostFromDuration(Configuration const* cfg,
QTime const &lastWorktimeTo = worktime[ranges-1].getTimeUntil();
// qCritical() << "start" << start.toString(Qt::ISODate)
// << "current" << current.toString(Qt::ISODate) << lastWorktimeTo;
// find worktime range to start with
int currentRange = 0;
if (!isSpecialDay) {
@ -386,6 +389,8 @@ Ticket Calculator::private_GetCostFromDuration(Configuration const* cfg,
}
}
// qCritical() << "current" << current.toString(Qt::ISODate);
for (int w = currentRange; w < ranges; ++w, ++totalTimeRanges) {
if (durationMinutes > 0) {
QTime const &worktime_from = worktime[w].getTimeFrom();
@ -416,12 +421,13 @@ Ticket Calculator::private_GetCostFromDuration(Configuration const* cfg,
return Ticket();
}
} else {
qDebug() << "* PREPAID MODE ACTIVE *";
//qDebug() << "* PREPAID MODE ACTIVE *";
//qCritical() << "current" << current.toString(Qt::ISODate) << worktime_from << lastWorktimeTo;
if (current.time() < worktime_from) {
current.setTime(worktime_from);
end = current;
} else if(current.time() > lastWorktimeTo) {
qDebug() << " *** PREPAID *** Current time is past the time range end, searching for next available day";
//qDebug() << " *** PREPAID *** Current time is past the time range end, searching for next available day";
end = current;
current.setTime(QTime());
continue;
@ -442,6 +448,7 @@ Ticket Calculator::private_GetCostFromDuration(Configuration const* cfg,
current.setTime(QTime());
break; // stop while, and continue in outer loop
} else {
//qCritical() << "current" << current.toString(Qt::ISODate) << worktime_to;
if(current.time() < worktime_to) {
// Increment input date minutes for each monetary unit
current = current.addSecs(60);
@ -449,6 +456,7 @@ Ticket Calculator::private_GetCostFromDuration(Configuration const* cfg,
durationMinutes -= 1;
//costFromDuration += price_per_unit;
costFromDuration += price;
//qCritical() << "current" << current.toString(Qt::ISODate);
} else break;
}
} // while(durationMinutes > 0) {

View File

@ -373,3 +373,21 @@ PaymentMethod Utilities::getPaymentMethodId(Configuration const *cfg) {
return PaymentMethod::Undefined;
}
int Utilities::getMinimalParkingTime(Configuration const *cfg, PaymentMethod methodId) {
return std::max((int)cfg->PaymentOption.find(methodId)->second.pop_min_time, 0);
}
int Utilities::getMaximalParkingTime(Configuration const *cfg, PaymentMethod methodId) {
return std::max((int)cfg->PaymentOption.find(methodId)->second.pop_max_time, 0);
}
uint32_t Utilities::getMinimalParkingPrice(Configuration const *cfg, PaymentMethod methodId) {
return std::max((int)cfg->PaymentOption.find(methodId)->second.pop_min_price, 0);
}
uint32_t Utilities::getFirstDurationStep(Configuration const *cfg, PaymentMethod methodId) {
int popId = cfg->PaymentOption.find(methodId)->second.pop_id;
int punId = cfg->PaymentRate.find(popId)->second.pra_payment_unit_id;
return cfg->Duration.find(punId)->second.pun_id;
}

View File

@ -33,13 +33,66 @@ extern "C" char* strptime(const char* s,
#include "calculator_functions.h"
#include <calculate_price.h>
#define SZEGED (1)
#define NEUHAUSER_KORNEUBURG (0)
int main() {
//std::ifstream input("/tmp/tariff_korneuburg.json");
#if NEUHAUSER_KORNEUBURG==1
std::ifstream input("/tmp/tariff_korneuburg.json");
int pop_max_time;
std::stringstream sstr;
while(input >> sstr.rdbuf());
std::string json(sstr.str());
Calculator calculator;
Configuration cfg;
bool isParsed = cfg.ParseJson(&cfg, json.c_str());
cout << endl;
if (isParsed) {
{
pop_max_time = 3*60;
bool nextDay = false;
bool prePaid = true;
// zone 1 (lila)
QDateTime s(QDate(2023, 11, 30), QTime());
QDateTime end;
for (int duration = 30; duration <= pop_max_time; duration += 5) {
for (int offset = 420; offset < 1140; ++offset) {
if (offset > 720 && offset < 840) {
continue;
}
QDateTime start = s.addSecs(offset * 60);
//qCritical() << "start" << start.toString(Qt::ISODate);
double cost = calculator.GetCostFromDuration(&cfg, 3, start, end, duration, nextDay, prePaid);
//Q_ASSERT(cost == duration*2.5);
//qCritical() << "";
//qCritical() << "start" << start.toString(Qt::ISODate)
// << "end" << end.toString(Qt::ISODate)
// << "duration" << duration
// << "cost" << cost;
std::string duration = calculator.GetDurationFromCost(&cfg, 3, start.toString(Qt::ISODate).toStdString().c_str(), cost);
//Q_ASSERT(cost == duration*2.5);
qCritical() << "start" << start.toString(Qt::ISODate)
<< "cost" << cost
<< "until" << duration.c_str() << start.secsTo(QDateTime::fromString(duration.c_str(), Qt::ISODate)) / 60;
}
}
}
}
return 0;
#elif SZEGED==1
std::ifstream input;
for (int t=1; t < 7; t+=20) {
int pop_max_time;
for (int t=6; t < 7; t+=20) {
switch (t) {
case 1: {
input.open("/opt/ptu5/opt/customer_281/etc/psa_tariff/tariff01.json");
@ -123,6 +176,7 @@ int main() {
return 0;
#endif
#if 0