Compare commits

..

22 Commits

Author SHA1 Message Date
1173732172 removed typo 2024-01-23 11:03:42 +01:00
1b933c05a6 Remove static instance of calculator. Replaced with use of Calculator-singleton-calss. 2024-01-23 10:55:00 +01:00
ac45ebb926 GetTimeSteps(): compute time step only once, when calling get_minimal_parkingprice().
Otherwise use timeSteps-member in Calculator.
2024-01-23 10:53:26 +01:00
9af39fa83f Turn Calculator into a singletome and move the list of timesteps inside calculator. 2024-01-23 10:51:25 +01:00
17ae11212a Test cases 2024-01-23 10:50:42 +01:00
89b7589600 Minor: add debug output 2024-01-23 09:02:55 +01:00
179d3348b9 Minor: Fixed typo 2024-01-22 15:44:13 +01:00
b43fa274bd Implement get_minimal_parkingtime() and get_time_steps(). 2024-01-22 15:41:20 +01:00
0ce630dfa3 Add get_minimum_parkingtime() 2024-01-22 15:39:47 +01:00
0671a6dde6 Add get_time_steps(). 2024-01-22 14:46:40 +01:00
d7757773bd Implement get_calculator() 2024-01-22 14:29:02 +01:00
99a3c34d53 forward declare class Calculator 2024-01-22 14:28:22 +01:00
6ce8a86c5f Added get_calculator(): access for Calculator instance 2024-01-22 14:26:57 +01:00
bcd5aaf932 Minor: add debug output 2024-01-22 13:41:50 +01:00
acb88efc5a re-add 'private' 2024-01-22 13:37:44 +01:00
e9b10166d2 Minor: implement getPaymentOptions() for const. Add getPaymentOptions() for non-const 2024-01-22 13:33:23 +01:00
33731faba9 GetTimeSteps(): compute minimal parking time and set pop_min_time. 2024-01-22 13:31:00 +01:00
15700a363d Remove m_start member.
Add defualt parameter start for GetTimeSteps().
2024-01-22 13:28:38 +01:00
506a665592 provide GetPaymentOptions() with two signatures. 2024-01-22 13:27:21 +01:00
7679eb9481 Remove 'VERSION' in project file ...
'VERSION' conflicts with 'EXTRA_QMAKEVARS_PRE' in yocto recipe.
2024-01-22 10:50:59 +01:00
a8de97a528 Initialize TimeBase multimap. 2024-01-22 10:24:32 +01:00
ed6592c273 Add:
multimap<int, ATBTimeBase> TimeBase
2024-01-22 10:23:41 +01:00
8 changed files with 100 additions and 64 deletions

View File

@@ -111,6 +111,9 @@ 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); int CALCULATE_LIBRARY_API compute_next_timestep(parking_tariff_t *tariff, int currentTimeMinutes, int UpDown);
QList<int> CALCULATE_LIBRARY_API get_time_steps(Configuration *cfg);
int CALCULATE_LIBRARY_API get_minimal_parkingtime(Configuration *cfg);
CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( // deprecated CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket( // deprecated
parking_tariff_t *tariff, parking_tariff_t *tariff,
time_t start_parking_time, time_t start_parking_time,

View File

@@ -13,36 +13,22 @@
using namespace std; using namespace std;
class Calculator { class Calculator {
QDateTime m_start; mutable QList<int> m_timeSteps;
mutable uint16_t m_timeStepCompensation = 0;
public: protected:
explicit Calculator() = default; explicit Calculator() = default;
explicit Calculator(QDateTime const start) : m_start(start) {
m_start.setTime(QTime(start.time().hour(), start.time().minute(), 0)); public:
qCritical() << "init m_start time:" << m_start.toString(Qt::ISODate); Calculator(Calculator const &other) = delete;
void operator=(Calculator const &) = delete;
static Calculator &GetInstance() {
static Calculator c;
return c;
} }
void setStartDateTime(QDateTime const &start) { void ResetTimeSteps() { m_timeSteps.clear(); }
m_start = start; QList<int> timeSteps() const { return m_timeSteps; }
m_start.setTime(QTime(start.time().hour(), start.time().minute(), 0));
qCritical() << "set m_start time:" << m_start.toString(Qt::ISODate);
}
QDateTime const &getStartDateTime() const {
return m_start;
}
QDateTime &getStartDateTime() {
return m_start;
}
void setTimeStepCompensation(uint16_t timeStepCompensation) {
m_timeStepCompensation = timeStepCompensation;
}
uint16_t getTimeStepCompensation() const {
return m_timeStepCompensation;
}
/// <summary> /// <summary>
/// Gets duration in seconds from cost /// Gets duration in seconds from cost

View File

@@ -30,6 +30,7 @@
using namespace std; using namespace std;
using namespace rapidjson; using namespace rapidjson;
class Calculator;
class Configuration class Configuration
{ {
public: public:
@@ -49,6 +50,7 @@ public:
multimap<int, ATBDailyTicket> DailyTicket; multimap<int, ATBDailyTicket> DailyTicket;
multimap<int, ATBTimeRange> TimeRange; multimap<int, ATBTimeRange> TimeRange;
multimap<int, ATBTimeStepConfig> TimeStepConfig; multimap<int, ATBTimeStepConfig> TimeStepConfig;
multimap<int, ATBTimeBase> TimeBase;
/// <summary> /// <summary>
/// Parse JSON string /// Parse JSON string
@@ -57,7 +59,8 @@ public:
/// <returns>Returns operation status bool (OK | FAIL) </returns> /// <returns>Returns operation status bool (OK | FAIL) </returns>
bool ParseJson(Configuration* cfg, const char* json); bool ParseJson(Configuration* cfg, const char* json);
ATBPaymentOption const &getPaymentOptions(); ATBPaymentOption &getPaymentOptions();
ATBPaymentOption const &getPaymentOptions() const;
QVector<ATBDailyTicket> const &getDailyTickets() const; QVector<ATBDailyTicket> const &getDailyTickets() const;
private: private:

View File

@@ -9,7 +9,8 @@ INCLUDEPATH += $$_PRO_FILE_PWD_/include/mobilisis
INCLUDEPATH += $$_PRO_FILE_PWD_/include/rapidjson INCLUDEPATH += $$_PRO_FILE_PWD_/include/rapidjson
#start version with project neuhauser/galtuer #start version with project neuhauser/galtuer
VERSION=1.0.0 #Version is set in yocto recipe with "EXTRA_QMAKEVARS_PRE"
#VERSION=1.0.0
CONFIG(debug, debug|release) { CONFIG(debug, debug|release) {
win32 { win32 {

View File

@@ -8,8 +8,19 @@
#include <QFileInfo> #include <QFileInfo>
#include <QDateTime> #include <QDateTime>
#include <QDebug> #include <QDebug>
#include <QList>
static Calculator calculator; QList<int> CALCULATE_LIBRARY_API get_time_steps(Configuration *cfg) {
return Calculator::GetInstance().GetTimeSteps(cfg);
}
int CALCULATE_LIBRARY_API get_minimal_parkingtime(Configuration *cfg) {
// for each new sell-procedure, recomute the timesteps. implicitly, set
// the minimal parking time.
Calculator::GetInstance().ResetTimeSteps();
Calculator::GetInstance().GetTimeSteps(cfg);
return qRound(cfg->getPaymentOptions().pop_min_time);
}
int CALCULATE_LIBRARY_API get_zone_nr(int zone) int CALCULATE_LIBRARY_API get_zone_nr(int zone)
{ {
@@ -97,7 +108,9 @@ void CALCULATE_LIBRARY_API free_tariff(parking_tariff_t *tariff) {
// UpDown 1 -> up; 0 -> down // UpDown 1 -> up; 0 -> down
int CALCULATE_LIBRARY_API compute_next_timestep(parking_tariff_t *tariff, int currentTimeMinutes, int UpDown) int CALCULATE_LIBRARY_API compute_next_timestep(parking_tariff_t *tariff, int currentTimeMinutes, int UpDown)
{ {
qCritical() << " compute_next_timestep() currentTimeMinutes: " << currentTimeMinutes; qCritical() << " compute_next_timestep() currentTimeMinutes: " << currentTimeMinutes;
qCritical() << " compute_next_timestep() up/down (1=up, 0=down): " << UpDown;
Configuration const *cfg = tariff; Configuration const *cfg = tariff;
// compute payment method id (e.g. Linear=3, Steps=4) // compute payment method id (e.g. Linear=3, Steps=4)
@@ -124,7 +137,8 @@ int CALCULATE_LIBRARY_API compute_next_timestep(parking_tariff_t *tariff, int cu
// without given YearPeriod, SpecialDays and SpecialDaysWorktime // without given YearPeriod, SpecialDays and SpecialDaysWorktime
if (paymentMethodId == PaymentMethod::Steps) if (paymentMethodId == PaymentMethod::Steps)
{ {
static const QList<int> stepList = calculator.GetTimeSteps(tariff); const QList<int> stepList = Calculator::GetInstance().GetTimeSteps(tariff);
qCritical() << " compute_next_timestep() timeSteps:" << stepList;
int currentStepIndex = stepList.indexOf(currentTimeMinutes); int currentStepIndex = stepList.indexOf(currentTimeMinutes);
@@ -225,7 +239,7 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
start = start.toLocalTime().addSecs(start_parking_time * 60); start = start.toLocalTime().addSecs(start_parking_time * 60);
QDateTime end(start); QDateTime end(start);
if (start.isValid()) { if (start.isValid()) {
double cost = calculator.GetCostFromDuration( double cost = Calculator::GetInstance().GetCostFromDuration(
tariff, tariff,
tariff->getPaymentOptions().pop_payment_method_id, tariff->getPaymentOptions().pop_payment_method_id,
start, start,
@@ -284,7 +298,7 @@ CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
} }
if (start_parking_time.isValid()) { if (start_parking_time.isValid()) {
double cost = calculator.GetCostFromDuration( double cost = Calculator::GetInstance().GetCostFromDuration(
tariff, tariff,
tariff->getPaymentOptions().pop_payment_method_id, tariff->getPaymentOptions().pop_payment_method_id,
start_parking_time, // starting time start_parking_time, // starting time
@@ -327,7 +341,7 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
qCritical() << " start (cs): " << cs; qCritical() << " start (cs): " << cs;
qCritical() << " price: " << price; qCritical() << " price: " << price;
duration = calculator.GetDurationFromCost(tariff, duration = Calculator::GetInstance().GetDurationFromCost(tariff,
tariff->getPaymentOptions().pop_payment_method_id, tariff->getPaymentOptions().pop_payment_method_id,
cs.toLocal8Bit().constData(), cs.toLocal8Bit().constData(),
price, false, true).c_str(); price, false, true).c_str();
@@ -352,7 +366,7 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_parking_ticket(
CalcState calcState; CalcState calcState;
if (start_parking_time.isValid()) { if (start_parking_time.isValid()) {
QString cs = start_parking_time.toString(Qt::ISODate); QString cs = start_parking_time.toString(Qt::ISODate);
QString endTime = calculator.GetDurationFromCost( QString endTime = Calculator::GetInstance().GetDurationFromCost(
tariff, tariff,
tariff->getPaymentOptions().pop_payment_method_id, tariff->getPaymentOptions().pop_payment_method_id,
cs.toLocal8Bit().constData(), cs.toLocal8Bit().constData(),
@@ -380,7 +394,7 @@ CalcState CALCULATE_LIBRARY_API compute_duration_for_daily_ticket(parking_tariff
CalcState calcState; CalcState calcState;
if (start_parking_time.isValid()) { if (start_parking_time.isValid()) {
ticketEndTime = calculator.GetDailyTicketDuration(tariff, ticketEndTime = Calculator::GetInstance().GetDailyTicketDuration(tariff,
start_parking_time, start_parking_time,
tariff->getPaymentOptions().pop_payment_method_id, tariff->getPaymentOptions().pop_payment_method_id,
false); // carry over false); // carry over

View File

@@ -696,13 +696,27 @@ Ticket Calculator::private_GetDurationFromCost(Configuration *cfg,
} }
QList<int> Calculator::GetTimeSteps(Configuration *cfg) const { QList<int> Calculator::GetTimeSteps(Configuration *cfg) const {
QList<int> timeSteps; if (m_timeSteps.size() > 0) {
//qCritical() << __PRETTY_FUNCTION__ << "timeSteps:" << m_timeSteps;
return m_timeSteps;
}
QDateTime start = QDateTime::currentDateTime();
start.setTime(QTime(start.time().hour(), start.time().minute(), 0));
int const pop_id = cfg->getPaymentOptions().pop_id; int const pop_id = cfg->getPaymentOptions().pop_id;
int const pop_carry_over = cfg->getPaymentOptions().pop_carry_over; int const pop_carry_over = cfg->getPaymentOptions().pop_carry_over;
int const pop_time_step_config = cfg->getPaymentOptions().pop_time_step_config; int const pop_time_step_config = cfg->getPaymentOptions().pop_time_step_config;
qCritical() << __PRETTY_FUNCTION__ << " start parking time:" << start.toString(Qt::ISODate);
qCritical() << __PRETTY_FUNCTION__ << " payment option id:" << pop_id;
qCritical() << __PRETTY_FUNCTION__ << " payment option carry over:" << pop_carry_over;
if (pop_time_step_config == (int)ATBTimeStepConfig::TimeStepConfig::DYNAMIC) { if (pop_time_step_config == (int)ATBTimeStepConfig::TimeStepConfig::DYNAMIC) {
//qCritical() << __PRETTY_FUNCTION__ << "payment option time step config:" << "TimeStepConfig::DYNAMIC";
uint16_t timeStepCompensation = 0;
if (pop_carry_over) { if (pop_carry_over) {
int const pop_carry_over_time_range_id = cfg->getPaymentOptions().pop_carry_over_time_range_id; int const pop_carry_over_time_range_id = cfg->getPaymentOptions().pop_carry_over_time_range_id;
QTime const carryOverTimeRangeFrom = cfg->TimeRange.find(pop_carry_over_time_range_id)->second.time_range_from; QTime const carryOverTimeRangeFrom = cfg->TimeRange.find(pop_carry_over_time_range_id)->second.time_range_from;
@@ -716,14 +730,11 @@ QList<int> Calculator::GetTimeSteps(Configuration *cfg) const {
if (search != cfg->Duration.end()) { if (search != cfg->Duration.end()) {
ATBDuration duration = search->second; ATBDuration duration = search->second;
if (durationId == 1) { if (durationId == 1) {
//duration.pun_duration_min = search->second.pun_duration_min; QDateTime carryOver = start;
//duration.pun_duration_max = search->second.pun_duration_max;
QDateTime carryOver = m_start;
carryOver = carryOver.addDays(1); carryOver = carryOver.addDays(1);
carryOver.setTime(QTime(0, 0, 0)); carryOver.setTime(QTime(0, 0, 0));
int const timeStep = std::ceil(m_start.secsTo(carryOver) / 60.0); int const timeStep = std::ceil(start.secsTo(carryOver) / 60.0);
if (timeStep < duration.pun_duration_min || timeStep > duration.pun_duration_max) { if (timeStep < duration.pun_duration_min || timeStep > duration.pun_duration_max) {
qCritical() qCritical()
<< QString("ERROR timeStep (%1) < durationMin (%2) || timeStep (%3)) > durationMax (%4)") << QString("ERROR timeStep (%1) < durationMin (%2) || timeStep (%3)) > durationMax (%4)")
@@ -731,12 +742,19 @@ QList<int> Calculator::GetTimeSteps(Configuration *cfg) const {
.arg(timeStep).arg(duration.pun_duration_max); .arg(timeStep).arg(duration.pun_duration_max);
break; break;
} }
qCritical() << __PRETTY_FUNCTION__ << "configured minimal parking time:" << cfg->getPaymentOptions().pop_min_time;
// set dynamic minimal parking time
cfg->getPaymentOptions().pop_min_time = timeStep;
qCritical() << __PRETTY_FUNCTION__ << " computed minimal parking time:" << cfg->getPaymentOptions().pop_min_time;
duration.pun_duration = timeStep; duration.pun_duration = timeStep;
m_timeStepCompensation = duration.pun_duration_max - duration.pun_duration; timeStepCompensation = duration.pun_duration_max - duration.pun_duration;
timeSteps << duration.pun_duration; m_timeSteps << duration.pun_duration;
} else { } else {
duration.pun_duration = duration.pun_duration_max - m_timeStepCompensation; duration.pun_duration = duration.pun_duration_max - timeStepCompensation;
timeSteps << duration.pun_duration;; m_timeSteps << duration.pun_duration;;
} }
cfg->Duration.erase(search); cfg->Duration.erase(search);
@@ -756,15 +774,19 @@ QList<int> Calculator::GetTimeSteps(Configuration *cfg) const {
// TODO // TODO
} }
} else { } else {
qCritical() << __PRETTY_FUNCTION__ << "payment option time step config:" << "TimeStepConfig::STATIC";
for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr) for (auto[itr, rangeEnd] = cfg->PaymentRate.equal_range(pop_id); itr != rangeEnd; ++itr)
{ {
int const durationId = itr->second.pra_payment_unit_id; int const durationId = itr->second.pra_payment_unit_id;
int const durationUnit = cfg->Duration.find(durationId)->second.pun_duration; int const durationUnit = cfg->Duration.find(durationId)->second.pun_duration;
timeSteps << durationUnit; m_timeSteps << durationUnit;
} }
} }
return timeSteps; qCritical() << __PRETTY_FUNCTION__ << "NEW timeSteps:" << m_timeSteps;
return m_timeSteps;
} }
uint32_t Calculator::GetPriceForTimeStep(Configuration *cfg, int timeStep) const { uint32_t Calculator::GetPriceForTimeStep(Configuration *cfg, int timeStep) const {

View File

@@ -416,15 +416,15 @@ bool Configuration::ParseJson(Configuration* cfg, const char* json)
// qCritical() << Customer; // qCritical() << Customer;
break; break;
case MemberType::TimeBaseType: case MemberType::TimeBaseType:
// qCritical() << TimeBase; qCritical() << TimeBase;
cfg->TimeBase.insert(pair<int, ATBTimeRange>(TimeBase.tbase_id, TimeBase)); cfg->TimeBase.insert(pair<int, ATBTimeBase>(TimeBase.tbase_id, TimeBase));
break; break;
case MemberType::TimeRangeType: case MemberType::TimeRangeType:
// qCritical() << TimeRange; qCritical() << TimeRange;
cfg->TimeRange.insert(pair<int, ATBTimeRange>(TimeRange.time_range_id, TimeRange)); cfg->TimeRange.insert(pair<int, ATBTimeRange>(TimeRange.time_range_id, TimeRange));
break; break;
case MemberType::TimeStepConfigType: case MemberType::TimeStepConfigType:
// qCritical() << TimeStepConfig; qCritical() << TimeStepConfig;
cfg->TimeStepConfig.insert(pair<int, ATBTimeStepConfig>(TimeStepConfig.tsconfig_id, TimeStepConfig)); cfg->TimeStepConfig.insert(pair<int, ATBTimeStepConfig>(TimeStepConfig.tsconfig_id, TimeStepConfig));
break; break;
default: default:
@@ -442,7 +442,10 @@ bool Configuration::ParseJson(Configuration* cfg, const char* json)
const ATBPaymentOption & Configuration::getPaymentOptions() ATBPaymentOption const &Configuration::getPaymentOptions() const {
{ return this->currentPaymentOptions;
}
ATBPaymentOption &Configuration::getPaymentOptions() {
return this->currentPaymentOptions; return this->currentPaymentOptions;
} }

View File

@@ -54,18 +54,22 @@ int main() {
cout << endl; cout << endl;
if (isParsed) { if (isParsed) {
QDateTime start = QDateTime::currentDateTime(); int minParkingTime = get_minimal_parkingtime(&cfg);
start.setTime(QTime(start.time().hour(), start.time().minute(), 0)); QList<int> timeSteps = Calculator::GetInstance().GetTimeSteps(&cfg);
Calculator calculator(start);
QList<int> timeSteps = calculator.GetTimeSteps(&cfg);
qCritical() << timeSteps; qCritical() << timeSteps;
int Down = 0;
int Up = 1;
//compute_next_timestep(&cfg, )
for (int i=0; i<timeSteps.size(); ++i) { for (int i=0; i<timeSteps.size(); ++i) {
uint32_t price = calculator.GetPriceForTimeStep(&cfg, timeSteps.at(i)); int nextTimeStep = compute_next_timestep(&cfg, timeSteps.at(i), Up);
uint32_t duration = calculator.GetDurationForPrice(&cfg, price); qCritical() << "nextTimeStep" << nextTimeStep;
qCritical() << "nextTimeStep relative to start:"
<< duration << start.addSecs(duration * 60) // uint32_t price = calculator.GetPriceForTimeStep(&cfg, timeSteps.at(i));
<< "(price so far:" << price << ")"; // uint32_t duration = calculator.GetDurationForPrice(&cfg, price);
// qCritical() << "nextTimeStep relative to start:"
// << duration << start.addSecs(duration * 60)
// << "(price so far:" << price << ")";
} }
} }
#endif #endif