Add new schema support to solar-server

This commit is contained in:
2022-09-14 19:40:58 +02:00
parent aeedd58bf0
commit ba6ed5da1a

View File

@@ -2,6 +2,7 @@
#include <cmath>
#include <iomanip>
#include <solar/server/database/connection.hpp>
#include <spdlog/spdlog.h>
#include <sstream>
#include <vector>
@@ -26,30 +27,42 @@ namespace Database
}
public:
bool AddRecord(long const epoch, char const * watt, char const * kwh)
bool AddRecord(long const epoch, char const * currentWatts, double const kwh)
{
++insertions;
jsonStream << "{\"time\":" << epoch << ",\"watt\":" << watt << ",\"kwh\":" << kwh << "},";
jsonStream << "{\"time\":" << epoch << ",\"currentWatts\":" << currentWatts << ",\"kwh\":" << kwh << "},";
return true;
}
bool AddRecord(char const * timeUtc, char const * watt, char const * kwh)
bool AddRecord(long const epoch, char const * currentWatts, char const * totalWatts)
{
auto const totalWattsInt = std::atoi(totalWatts);
auto const kwh = static_cast<double>(totalWattsInt) / 1000;
return AddRecord(epoch, currentWatts, kwh);
}
bool AddRecord(char const * timeUtc, char const * currentWatts, char const * totalWatts)
{
auto const timeInSeconds = Util::ToSecondsFromTimeString(timeUtc);
if(timeInSeconds < 0)
{
std::printf("AddRecord: cannot parse %s to hours, minutes and seconds\n", timeUtc);
spdlog::error("AddRecord: cannot parse {0} to hours, minutes and seconds", timeUtc);
return false;
}
return AddRecord(timeInSeconds + dateEpoch, watt, kwh);
return AddRecord(timeInSeconds + dateEpoch, currentWatts, totalWatts);
}
bool
AddRecord(unsigned const year, unsigned const month, unsigned const day, char const * watt, char const * kwh)
bool AddRecord(
unsigned const year,
unsigned const month,
unsigned const day,
char const * currentWatts,
char const * totalWatts)
{
return AddRecord(Util::GetEpoch(year, month, day), watt, kwh);
return AddRecord(Util::GetEpoch(year, month, day), currentWatts, totalWatts);
}
// Returns the records added thus far as JSON array and resets
@@ -80,7 +93,7 @@ namespace Database
// TimeUtc, Watt and KilowattHour
if(argc != 3)
{
std::printf("DetailedCallback: unexpected number of arguments %i\n", argc);
spdlog::error("DetailedCallback: unexpected number of arguments {0}", argc);
return -1;
}
@@ -93,7 +106,7 @@ namespace Database
std::string Connection::GetEntireDay(Util::Date const & date)
{
std::stringstream queryStream;
queryStream << "SELECT TimeUtc, Watts, KilowattHour FROM SolarPanelOutput WHERE Date = " << '\''
queryStream << "SELECT TimeUtc, CurrentWatts, TotalWatts FROM ZeverLogs WHERE Date = " << '\''
<< date.ToISOString() << '\'' << " ORDER BY TimeUtc ASC;";
JsonResult result(date.ToEpoch());
@@ -101,7 +114,7 @@ namespace Database
= sqlite3_exec(connectionPtr, queryStream.str().c_str(), DetailedCallback, &result, nullptr);
if(sqlResult)
{
std::printf("GetEntireDay: SQLite error code %i, returning empty JSON array.\n", sqlResult);
spdlog::error("GetEntireDay: SQLite error code {0}, returning empty JSON array", sqlResult);
return "[]";
}
@@ -113,7 +126,7 @@ namespace Database
// Date and KilowattHour
if(argc != 2)
{
std::printf("SummaryCallback: unexpected number of arguments %i\n", argc);
spdlog::error("SummaryCallback: unexpected number of arguments {0}", argc);
return -1;
}
@@ -127,7 +140,7 @@ namespace Database
std::string Connection::GetSummarizedPerDayRecords(Util::Date const & startDate, Util::Date const & endDate)
{
std::stringstream queryStream;
queryStream << "SELECT Date, KilowattHour FROM SolarPanelSummary"
queryStream << "SELECT Date, TotalWatts FROM ZeverSummary"
<< " WHERE Date >= '" << startDate.ToISOString() << '\'' << " AND Date <= '"
<< endDate.ToISOString() << '\'' << " ORDER BY Date;";
@@ -136,7 +149,7 @@ namespace Database
= sqlite3_exec(connectionPtr, queryStream.str().c_str(), SummaryCallback, &result, nullptr);
if(sqlResult)
{
std::printf("GetSummarizedPerDayRecords: SQLite error code %i, returning empty JSON array.\n", sqlResult);
spdlog::error("GetSummarizedPerDayRecords: SQLite error code {0}, returning empty JSON array", sqlResult);
return "[]";
}
@@ -146,10 +159,10 @@ namespace Database
struct YearResult
{
int year;
std::array<double, 12> monthValues;
std::array<int, 12> monthValues;
// month is in range 1 to 12
void AddMonthValue(int month, double value) { monthValues[month - 1] += value; }
void AddMonthValue(int month, int value) { monthValues[month - 1] += value; }
YearResult(int _year) : year(_year), monthValues() { }
};
@@ -159,23 +172,23 @@ namespace Database
// Date and KilowattHour
if(argc != 2)
{
std::printf("MonthSummaryCallback: unexpected number of arguments %i\n", argc);
spdlog::error("MonthSummaryCallback: unexpected number of arguments {0}", argc);
return -1;
}
Util::Date recordDate;
if(!recordDate.TryParse(argv[0]))
{
std::printf("MonthSummaryCallback: error parsing date %s\n", argv[0]);
spdlog::error("MonthSummaryCallback: error parsing date {0}", argv[0]);
return -1;
}
std::vector<YearResult> & yearResults = *reinterpret_cast<std::vector<YearResult> *>(data);
double const kwh = std::atof(argv[1]);
if(std::isnan(kwh) || kwh < 0.0)
auto const totalWatts = std::atoi(argv[1]);
if(std::isnan(totalWatts) || totalWatts < 0)
{
// This value makes no sense, ignore it
std::printf("MonthSummaryCallback: ignoring bogus value for year month %s\n", argv[1]);
spdlog::warn("MonthSummaryCallback: ignoring bogus value for year month {0}", argv[1]);
return 0;
}
@@ -183,19 +196,19 @@ namespace Database
{
if(yearResults[i].year == recordDate.Year())
{
yearResults[i].AddMonthValue(recordDate.Month(), kwh);
yearResults[i].AddMonthValue(recordDate.Month(), totalWatts);
return 0;
}
if(yearResults[i].year > recordDate.Year())
{
yearResults.insert(yearResults.begin() + i, YearResult(recordDate.Year()));
yearResults[i].AddMonthValue(recordDate.Month(), kwh);
yearResults[i].AddMonthValue(recordDate.Month(), totalWatts);
return 0;
}
}
yearResults.push_back(YearResult(recordDate.Year()));
yearResults[yearResults.size() - 1].AddMonthValue(recordDate.Month(), kwh);
yearResults[yearResults.size() - 1].AddMonthValue(recordDate.Month(), totalWatts);
return 0;
}
@@ -203,7 +216,7 @@ namespace Database
std::string Connection::GetSummarizedPerMonthRecords(Util::Date const & startDate, Util::Date const & endDate)
{
std::stringstream queryStream;
queryStream << "SELECT Date, KilowattHour FROM SolarPanelSummary"
queryStream << "SELECT Date, TotalWatts FROM ZeverSummary"
<< " WHERE Date >= '" << startDate.ToISOString() << '\'' << " AND Date <= '"
<< endDate.ToISOString() << "';";
@@ -212,8 +225,8 @@ namespace Database
= sqlite3_exec(connectionPtr, queryStream.str().c_str(), MonthSummaryCallback, &yearResults, nullptr);
if(sqlResult || yearResults.size() == 0)
{
std::printf(
"GetSummarizedPerMonthRecords: SQLite return code %i and %lu years retrieved, returning empty JSON array.\n",
spdlog::error(
"GetSummarizedPerMonthRecords: SQLite return code {0} and {0} years retrieved, returning empty JSON array",
sqlResult,
yearResults.size());
return "[]";
@@ -231,8 +244,8 @@ namespace Database
}
auto const epoch = Util::GetEpoch(year, month + 1, 1);
auto const kwh = yearResults[i].monthValues[month];
result.AddRecord(epoch, "0", std::to_string(kwh).c_str());
auto const totalWatts = yearResults[i].monthValues[month];
result.AddRecord(epoch, "0", totalWatts);
}
}