Add new schema support to solar-server
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user