Optimized some JSONs

This commit is contained in:
Gunnar Skjold
2024-03-21 08:57:56 +01:00
parent b8ac1a9565
commit f2e7879974
7 changed files with 49 additions and 445 deletions

View File

@@ -13,7 +13,6 @@
#include "json/ha3_json.h"
#include "json/ha4_json.h"
#include "json/jsonsys_json.h"
#include "json/jsonprices_json.h"
#include "json/hadiscover_json.h"
#include "json/realtime_json.h"
#include "FirmwareVersion.h"
@@ -277,52 +276,24 @@ bool HomeAssistantMqttHandler::publishPrices(PriceService* ps) {
breakTime(ts, tm);
sprintf_P(ts6hr, PSTR("%04d-%02d-%02dT%02d:00:00Z"), tm.Year+1970, tm.Month, tm.Day, tm.Hour);
}
snprintf_P(json, BufferSize, JSONPRICES_JSON,
WiFi.macAddress().c_str(),
values[0] == PRICE_NO_VALUE ? "null" : String(values[0], 4).c_str(),
values[1] == PRICE_NO_VALUE ? "null" : String(values[1], 4).c_str(),
values[2] == PRICE_NO_VALUE ? "null" : String(values[2], 4).c_str(),
values[3] == PRICE_NO_VALUE ? "null" : String(values[3], 4).c_str(),
values[4] == PRICE_NO_VALUE ? "null" : String(values[4], 4).c_str(),
values[5] == PRICE_NO_VALUE ? "null" : String(values[5], 4).c_str(),
values[6] == PRICE_NO_VALUE ? "null" : String(values[6], 4).c_str(),
values[7] == PRICE_NO_VALUE ? "null" : String(values[7], 4).c_str(),
values[8] == PRICE_NO_VALUE ? "null" : String(values[8], 4).c_str(),
values[9] == PRICE_NO_VALUE ? "null" : String(values[9], 4).c_str(),
values[10] == PRICE_NO_VALUE ? "null" : String(values[10], 4).c_str(),
values[11] == PRICE_NO_VALUE ? "null" : String(values[11], 4).c_str(),
values[12] == PRICE_NO_VALUE ? "null" : String(values[12], 4).c_str(),
values[13] == PRICE_NO_VALUE ? "null" : String(values[13], 4).c_str(),
values[14] == PRICE_NO_VALUE ? "null" : String(values[14], 4).c_str(),
values[15] == PRICE_NO_VALUE ? "null" : String(values[15], 4).c_str(),
values[16] == PRICE_NO_VALUE ? "null" : String(values[16], 4).c_str(),
values[17] == PRICE_NO_VALUE ? "null" : String(values[17], 4).c_str(),
values[18] == PRICE_NO_VALUE ? "null" : String(values[18], 4).c_str(),
values[19] == PRICE_NO_VALUE ? "null" : String(values[19], 4).c_str(),
values[20] == PRICE_NO_VALUE ? "null" : String(values[20], 4).c_str(),
values[21] == PRICE_NO_VALUE ? "null" : String(values[21], 4).c_str(),
values[22] == PRICE_NO_VALUE ? "null" : String(values[22], 4).c_str(),
values[23] == PRICE_NO_VALUE ? "null" : String(values[23], 4).c_str(),
values[24] == PRICE_NO_VALUE ? "null" : String(values[24], 4).c_str(),
values[25] == PRICE_NO_VALUE ? "null" : String(values[25], 4).c_str(),
values[26] == PRICE_NO_VALUE ? "null" : String(values[26], 4).c_str(),
values[27] == PRICE_NO_VALUE ? "null" : String(values[27], 4).c_str(),
values[28] == PRICE_NO_VALUE ? "null" : String(values[28], 4).c_str(),
values[29] == PRICE_NO_VALUE ? "null" : String(values[29], 4).c_str(),
values[30] == PRICE_NO_VALUE ? "null" : String(values[30], 4).c_str(),
values[31] == PRICE_NO_VALUE ? "null" : String(values[31], 4).c_str(),
values[32] == PRICE_NO_VALUE ? "null" : String(values[32], 4).c_str(),
values[33] == PRICE_NO_VALUE ? "null" : String(values[33], 4).c_str(),
values[34] == PRICE_NO_VALUE ? "null" : String(values[34], 4).c_str(),
values[35] == PRICE_NO_VALUE ? "null" : String(values[35], 4).c_str(),
values[36] == PRICE_NO_VALUE ? "null" : String(values[36], 4).c_str(),
values[37] == PRICE_NO_VALUE ? "null" : String(values[37], 4).c_str(),
uint16_t pos = snprintf_P(json, BufferSize, PSTR("{\"id\":\"%s\",\"prices\":{"), WiFi.macAddress().c_str());
for(uint8_t i = 0;i < 38; i++) {
if(values[i] == PRICE_NO_VALUE) {
pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"%d\":null,"), i);
} else {
pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"%d\":%.4f,"), i, values[i]);
}
}
snprintf_P(json+pos, BufferSize-pos, PSTR("\"min\":%.4f,\"max\":%.4f,\"cheapest1hr\":\"%s\",\"cheapest3hr\":\"%s\",\"cheapest6hr\":\"%s\"}}"),
min == INT16_MAX ? 0.0 : min,
max == INT16_MIN ? 0.0 : max,
ts1hr,
ts3hr,
ts6hr
);
bool ret = mqtt.publish(topic + "/prices", json, true, 0);
loop();
return ret;

View File

@@ -1,48 +0,0 @@
{
"id" : "%s",
"prices" : {
"0" : %s,
"1" : %s,
"2" : %s,
"3" : %s,
"4" : %s,
"5" : %s,
"6" : %s,
"7" : %s,
"8" : %s,
"9" : %s,
"10" : %s,
"11" : %s,
"12" : %s,
"13" : %s,
"14" : %s,
"15" : %s,
"16" : %s,
"17" : %s,
"18" : %s,
"19" : %s,
"20" : %s,
"21" : %s,
"22" : %s,
"23" : %s,
"24" : %s,
"25" : %s,
"26" : %s,
"27" : %s,
"28" : %s,
"29" : %s,
"30" : %s,
"31" : %s,
"32" : %s,
"33" : %s,
"34" : %s,
"35" : %s,
"36" : %s,
"37" : %s,
"min" : %.4f,
"max" : %.4f,
"cheapest1hr" : "%s",
"cheapest3hr" : "%s",
"cheapest6hr" : "%s"
}
}

View File

@@ -13,7 +13,6 @@
#include "json/json3_json.h"
#include "json/json4_json.h"
#include "json/jsonsys_json.h"
#include "json/jsonprices_json.h"
bool JsonMqttHandler::publish(AmsData* data, AmsData* previousState, EnergyAccounting* ea, PriceService* ps) {
if(strlen(mqttConfig.publishTopic) == 0) {
@@ -298,46 +297,16 @@ bool JsonMqttHandler::publishPrices(PriceService* ps) {
sprintf_P(ts6hr, PSTR("%04d-%02d-%02dT%02d:00:00Z"), tm.Year+1970, tm.Month, tm.Day, tm.Hour);
}
snprintf_P(json, BufferSize, JSONPRICES_JSON,
WiFi.macAddress().c_str(),
values[0] == PRICE_NO_VALUE ? "null" : String(values[0], 4).c_str(),
values[1] == PRICE_NO_VALUE ? "null" : String(values[1], 4).c_str(),
values[2] == PRICE_NO_VALUE ? "null" : String(values[2], 4).c_str(),
values[3] == PRICE_NO_VALUE ? "null" : String(values[3], 4).c_str(),
values[4] == PRICE_NO_VALUE ? "null" : String(values[4], 4).c_str(),
values[5] == PRICE_NO_VALUE ? "null" : String(values[5], 4).c_str(),
values[6] == PRICE_NO_VALUE ? "null" : String(values[6], 4).c_str(),
values[7] == PRICE_NO_VALUE ? "null" : String(values[7], 4).c_str(),
values[8] == PRICE_NO_VALUE ? "null" : String(values[8], 4).c_str(),
values[9] == PRICE_NO_VALUE ? "null" : String(values[9], 4).c_str(),
values[10] == PRICE_NO_VALUE ? "null" : String(values[10], 4).c_str(),
values[11] == PRICE_NO_VALUE ? "null" : String(values[11], 4).c_str(),
values[12] == PRICE_NO_VALUE ? "null" : String(values[12], 4).c_str(),
values[13] == PRICE_NO_VALUE ? "null" : String(values[13], 4).c_str(),
values[14] == PRICE_NO_VALUE ? "null" : String(values[14], 4).c_str(),
values[15] == PRICE_NO_VALUE ? "null" : String(values[15], 4).c_str(),
values[16] == PRICE_NO_VALUE ? "null" : String(values[16], 4).c_str(),
values[17] == PRICE_NO_VALUE ? "null" : String(values[17], 4).c_str(),
values[18] == PRICE_NO_VALUE ? "null" : String(values[18], 4).c_str(),
values[19] == PRICE_NO_VALUE ? "null" : String(values[19], 4).c_str(),
values[20] == PRICE_NO_VALUE ? "null" : String(values[20], 4).c_str(),
values[21] == PRICE_NO_VALUE ? "null" : String(values[21], 4).c_str(),
values[22] == PRICE_NO_VALUE ? "null" : String(values[22], 4).c_str(),
values[23] == PRICE_NO_VALUE ? "null" : String(values[23], 4).c_str(),
values[24] == PRICE_NO_VALUE ? "null" : String(values[24], 4).c_str(),
values[25] == PRICE_NO_VALUE ? "null" : String(values[25], 4).c_str(),
values[26] == PRICE_NO_VALUE ? "null" : String(values[26], 4).c_str(),
values[27] == PRICE_NO_VALUE ? "null" : String(values[27], 4).c_str(),
values[28] == PRICE_NO_VALUE ? "null" : String(values[28], 4).c_str(),
values[29] == PRICE_NO_VALUE ? "null" : String(values[29], 4).c_str(),
values[30] == PRICE_NO_VALUE ? "null" : String(values[30], 4).c_str(),
values[31] == PRICE_NO_VALUE ? "null" : String(values[31], 4).c_str(),
values[32] == PRICE_NO_VALUE ? "null" : String(values[32], 4).c_str(),
values[33] == PRICE_NO_VALUE ? "null" : String(values[33], 4).c_str(),
values[34] == PRICE_NO_VALUE ? "null" : String(values[34], 4).c_str(),
values[35] == PRICE_NO_VALUE ? "null" : String(values[35], 4).c_str(),
values[36] == PRICE_NO_VALUE ? "null" : String(values[36], 4).c_str(),
values[37] == PRICE_NO_VALUE ? "null" : String(values[37], 4).c_str(),
uint16_t pos = snprintf_P(json, BufferSize, PSTR("{\"id\":\"%s\",\"prices\":{"), WiFi.macAddress().c_str());
for(uint8_t i = 0;i < 38; i++) {
if(values[i] == PRICE_NO_VALUE) {
pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"%d\":null,"), i);
} else {
pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"%d\":%.4f,"), i, values[i]);
}
}
snprintf_P(json+pos, BufferSize-pos, PSTR("\"min\":%.4f,\"max\":%.4f,\"cheapest1hr\":\"%s\",\"cheapest3hr\":\"%s\",\"cheapest6hr\":\"%s\"}}"),
min == INT16_MAX ? 0.0 : min,
max == INT16_MIN ? 0.0 : max,
ts1hr,

View File

@@ -1,50 +0,0 @@
{
"i00" : %.2f,
"i01" : %.2f,
"i02" : %.2f,
"i03" : %.2f,
"i04" : %.2f,
"i05" : %.2f,
"i06" : %.2f,
"i07" : %.2f,
"i08" : %.2f,
"i09" : %.2f,
"i10" : %.2f,
"i11" : %.2f,
"i12" : %.2f,
"i13" : %.2f,
"i14" : %.2f,
"i15" : %.2f,
"i16" : %.2f,
"i17" : %.2f,
"i18" : %.2f,
"i19" : %.2f,
"i20" : %.2f,
"i21" : %.2f,
"i22" : %.2f,
"i23" : %.2f,
"e00" : %.2f,
"e01" : %.2f,
"e02" : %.2f,
"e03" : %.2f,
"e04" : %.2f,
"e05" : %.2f,
"e06" : %.2f,
"e07" : %.2f,
"e08" : %.2f,
"e09" : %.2f,
"e10" : %.2f,
"e11" : %.2f,
"e12" : %.2f,
"e13" : %.2f,
"e14" : %.2f,
"e15" : %.2f,
"e16" : %.2f,
"e17" : %.2f,
"e18" : %.2f,
"e19" : %.2f,
"e20" : %.2f,
"e21" : %.2f,
"e22" : %.2f,
"e23" : %.2f
}

View File

@@ -1,40 +0,0 @@
{
"currency" : "%s",
"source" : "%s",
"00" : %s,
"01" : %s,
"02" : %s,
"03" : %s,
"04" : %s,
"05" : %s,
"06" : %s,
"07" : %s,
"08" : %s,
"09" : %s,
"10" : %s,
"11" : %s,
"12" : %s,
"13" : %s,
"14" : %s,
"15" : %s,
"16" : %s,
"17" : %s,
"18" : %s,
"19" : %s,
"20" : %s,
"21" : %s,
"22" : %s,
"23" : %s,
"24" : %s,
"25" : %s,
"26" : %s,
"27" : %s,
"28" : %s,
"29" : %s,
"30" : %s,
"31" : %s,
"32" : %s,
"33" : %s,
"34" : %s,
"35" : %s
}

View File

@@ -1,64 +0,0 @@
{
"i01" : %.2f,
"i02" : %.2f,
"i03" : %.2f,
"i04" : %.2f,
"i05" : %.2f,
"i06" : %.2f,
"i07" : %.2f,
"i08" : %.2f,
"i09" : %.2f,
"i10" : %.2f,
"i11" : %.2f,
"i12" : %.2f,
"i13" : %.2f,
"i14" : %.2f,
"i15" : %.2f,
"i16" : %.2f,
"i17" : %.2f,
"i18" : %.2f,
"i19" : %.2f,
"i20" : %.2f,
"i21" : %.2f,
"i22" : %.2f,
"i23" : %.2f,
"i24" : %.2f,
"i25" : %.2f,
"i26" : %.2f,
"i27" : %.2f,
"i28" : %.2f,
"i29" : %.2f,
"i30" : %.2f,
"i31" : %.2f,
"e01" : %.2f,
"e02" : %.2f,
"e03" : %.2f,
"e04" : %.2f,
"e05" : %.2f,
"e06" : %.2f,
"e07" : %.2f,
"e08" : %.2f,
"e09" : %.2f,
"e10" : %.2f,
"e11" : %.2f,
"e12" : %.2f,
"e13" : %.2f,
"e14" : %.2f,
"e15" : %.2f,
"e16" : %.2f,
"e17" : %.2f,
"e18" : %.2f,
"e19" : %.2f,
"e20" : %.2f,
"e21" : %.2f,
"e22" : %.2f,
"e23" : %.2f,
"e24" : %.2f,
"e25" : %.2f,
"e26" : %.2f,
"e27" : %.2f,
"e28" : %.2f,
"e29" : %.2f,
"e30" : %.2f,
"e31" : %.2f
}

View File

@@ -15,9 +15,6 @@
#include "html/index_js.h"
#include "html/favicon_svg.h"
#include "html/data_json.h"
#include "html/dayplot_json.h"
#include "html/monthplot_json.h"
#include "html/energyprice_json.h"
#include "html/tempsensor_json.h"
#include "html/response_json.h"
#include "html/sysinfo_json.h"
@@ -602,60 +599,15 @@ void AmsWebServer::dayplotJson() {
if(ds == NULL) {
notFound();
} else {
snprintf_P(buf, BufferSize, DAYPLOT_JSON,
ds->getHourImport(0) / 1000.0,
ds->getHourImport(1) / 1000.0,
ds->getHourImport(2) / 1000.0,
ds->getHourImport(3) / 1000.0,
ds->getHourImport(4) / 1000.0,
ds->getHourImport(5) / 1000.0,
ds->getHourImport(6) / 1000.0,
ds->getHourImport(7) / 1000.0,
ds->getHourImport(8) / 1000.0,
ds->getHourImport(9) / 1000.0,
ds->getHourImport(10) / 1000.0,
ds->getHourImport(11) / 1000.0,
ds->getHourImport(12) / 1000.0,
ds->getHourImport(13) / 1000.0,
ds->getHourImport(14) / 1000.0,
ds->getHourImport(15) / 1000.0,
ds->getHourImport(16) / 1000.0,
ds->getHourImport(17) / 1000.0,
ds->getHourImport(18) / 1000.0,
ds->getHourImport(19) / 1000.0,
ds->getHourImport(20) / 1000.0,
ds->getHourImport(21) / 1000.0,
ds->getHourImport(22) / 1000.0,
ds->getHourImport(23) / 1000.0,
ds->getHourExport(0) / 1000.0,
ds->getHourExport(1) / 1000.0,
ds->getHourExport(2) / 1000.0,
ds->getHourExport(3) / 1000.0,
ds->getHourExport(4) / 1000.0,
ds->getHourExport(5) / 1000.0,
ds->getHourExport(6) / 1000.0,
ds->getHourExport(7) / 1000.0,
ds->getHourExport(8) / 1000.0,
ds->getHourExport(9) / 1000.0,
ds->getHourExport(10) / 1000.0,
ds->getHourExport(11) / 1000.0,
ds->getHourExport(12) / 1000.0,
ds->getHourExport(13) / 1000.0,
ds->getHourExport(14) / 1000.0,
ds->getHourExport(15) / 1000.0,
ds->getHourExport(16) / 1000.0,
ds->getHourExport(17) / 1000.0,
ds->getHourExport(18) / 1000.0,
ds->getHourExport(19) / 1000.0,
ds->getHourExport(20) / 1000.0,
ds->getHourExport(21) / 1000.0,
ds->getHourExport(22) / 1000.0,
ds->getHourExport(23) / 1000.0
);
uint16_t pos = snprintf_P(buf, BufferSize, PSTR("{\"unit\":\"kwh\""));
for(uint8_t i = 0; i < 24; i++) {
pos += snprintf_P(buf+pos, BufferSize-pos, PSTR(",\"i%02d\":%.2f,\"e%02d\":%.2f"), i, ds->getHourImport(i) / 1000.0, i, ds->getHourExport(i) / 1000.0);
}
snprintf_P(buf+pos, BufferSize-pos, PSTR("}"));
server.sendHeader(HEADER_CACHE_CONTROL, CACHE_CONTROL_NO_CACHE);
server.sendHeader(HEADER_PRAGMA, PRAGMA_NO_CACHE);
server.sendHeader(HEADER_EXPIRES, EXPIRES_OFF);
server.sendHeader(HEADER_CACHE_CONTROL, CACHE_CONTROL_NO_CACHE);
server.sendHeader(HEADER_PRAGMA, PRAGMA_NO_CACHE);
server.sendHeader(HEADER_EXPIRES, EXPIRES_OFF);
server.setContentLength(strlen(buf));
server.send(200, MIME_JSON, buf);
@@ -669,74 +621,15 @@ void AmsWebServer::monthplotJson() {
if(ds == NULL) {
notFound();
} else {
snprintf_P(buf, BufferSize, MONTHPLOT_JSON,
ds->getDayImport(1) / 1000.0,
ds->getDayImport(2) / 1000.0,
ds->getDayImport(3) / 1000.0,
ds->getDayImport(4) / 1000.0,
ds->getDayImport(5) / 1000.0,
ds->getDayImport(6) / 1000.0,
ds->getDayImport(7) / 1000.0,
ds->getDayImport(8) / 1000.0,
ds->getDayImport(9) / 1000.0,
ds->getDayImport(10) / 1000.0,
ds->getDayImport(11) / 1000.0,
ds->getDayImport(12) / 1000.0,
ds->getDayImport(13) / 1000.0,
ds->getDayImport(14) / 1000.0,
ds->getDayImport(15) / 1000.0,
ds->getDayImport(16) / 1000.0,
ds->getDayImport(17) / 1000.0,
ds->getDayImport(18) / 1000.0,
ds->getDayImport(19) / 1000.0,
ds->getDayImport(20) / 1000.0,
ds->getDayImport(21) / 1000.0,
ds->getDayImport(22) / 1000.0,
ds->getDayImport(23) / 1000.0,
ds->getDayImport(24) / 1000.0,
ds->getDayImport(25) / 1000.0,
ds->getDayImport(26) / 1000.0,
ds->getDayImport(27) / 1000.0,
ds->getDayImport(28) / 1000.0,
ds->getDayImport(29) / 1000.0,
ds->getDayImport(30) / 1000.0,
ds->getDayImport(31) / 1000.0,
ds->getDayExport(1) / 1000.0,
ds->getDayExport(2) / 1000.0,
ds->getDayExport(3) / 1000.0,
ds->getDayExport(4) / 1000.0,
ds->getDayExport(5) / 1000.0,
ds->getDayExport(6) / 1000.0,
ds->getDayExport(7) / 1000.0,
ds->getDayExport(8) / 1000.0,
ds->getDayExport(9) / 1000.0,
ds->getDayExport(10) / 1000.0,
ds->getDayExport(11) / 1000.0,
ds->getDayExport(12) / 1000.0,
ds->getDayExport(13) / 1000.0,
ds->getDayExport(14) / 1000.0,
ds->getDayExport(15) / 1000.0,
ds->getDayExport(16) / 1000.0,
ds->getDayExport(17) / 1000.0,
ds->getDayExport(18) / 1000.0,
ds->getDayExport(19) / 1000.0,
ds->getDayExport(20) / 1000.0,
ds->getDayExport(21) / 1000.0,
ds->getDayExport(22) / 1000.0,
ds->getDayExport(23) / 1000.0,
ds->getDayExport(24) / 1000.0,
ds->getDayExport(25) / 1000.0,
ds->getDayExport(26) / 1000.0,
ds->getDayExport(27) / 1000.0,
ds->getDayExport(28) / 1000.0,
ds->getDayExport(29) / 1000.0,
ds->getDayExport(30) / 1000.0,
ds->getDayExport(31) / 1000.0
);
uint16_t pos = snprintf_P(buf, BufferSize, PSTR("{\"unit\":\"kwh\""));
for(uint8_t i = 1; i < 32; i++) {
pos += snprintf_P(buf+pos, BufferSize-pos, PSTR(",\"i%02d\":%.2f,\"e%02d\":%.2f"), i, ds->getDayImport(i) / 1000.0, i, ds->getDayExport(i) / 1000.0);
}
snprintf_P(buf+pos, BufferSize-pos, PSTR("}"));
server.sendHeader(HEADER_CACHE_CONTROL, CACHE_CONTROL_NO_CACHE);
server.sendHeader(HEADER_PRAGMA, PRAGMA_NO_CACHE);
server.sendHeader(HEADER_EXPIRES, EXPIRES_OFF);
server.sendHeader(HEADER_CACHE_CONTROL, CACHE_CONTROL_NO_CACHE);
server.sendHeader(HEADER_PRAGMA, PRAGMA_NO_CACHE);
server.sendHeader(HEADER_EXPIRES, EXPIRES_OFF);
server.setContentLength(strlen(buf));
server.send(200, MIME_JSON, buf);
@@ -752,47 +645,20 @@ void AmsWebServer::energyPriceJson() {
prices[i] = ps == NULL ? PRICE_NO_VALUE : ps->getValueForHour(PRICE_DIRECTION_IMPORT, i);
}
snprintf_P(buf, BufferSize, ENERGYPRICE_JSON,
uint16_t pos = snprintf_P(buf, BufferSize, PSTR("{\"currency\":\"%s\",\"source\":\"%s\""),
ps == NULL ? "" : ps->getCurrency(),
ps == NULL ? "" : ps->getSource(),
prices[0] == PRICE_NO_VALUE ? "null" : String(prices[0], 4).c_str(),
prices[1] == PRICE_NO_VALUE ? "null" : String(prices[1], 4).c_str(),
prices[2] == PRICE_NO_VALUE ? "null" : String(prices[2], 4).c_str(),
prices[3] == PRICE_NO_VALUE ? "null" : String(prices[3], 4).c_str(),
prices[4] == PRICE_NO_VALUE ? "null" : String(prices[4], 4).c_str(),
prices[5] == PRICE_NO_VALUE ? "null" : String(prices[5], 4).c_str(),
prices[6] == PRICE_NO_VALUE ? "null" : String(prices[6], 4).c_str(),
prices[7] == PRICE_NO_VALUE ? "null" : String(prices[7], 4).c_str(),
prices[8] == PRICE_NO_VALUE ? "null" : String(prices[8], 4).c_str(),
prices[9] == PRICE_NO_VALUE ? "null" : String(prices[9], 4).c_str(),
prices[10] == PRICE_NO_VALUE ? "null" : String(prices[10], 4).c_str(),
prices[11] == PRICE_NO_VALUE ? "null" : String(prices[11], 4).c_str(),
prices[12] == PRICE_NO_VALUE ? "null" : String(prices[12], 4).c_str(),
prices[13] == PRICE_NO_VALUE ? "null" : String(prices[13], 4).c_str(),
prices[14] == PRICE_NO_VALUE ? "null" : String(prices[14], 4).c_str(),
prices[15] == PRICE_NO_VALUE ? "null" : String(prices[15], 4).c_str(),
prices[16] == PRICE_NO_VALUE ? "null" : String(prices[16], 4).c_str(),
prices[17] == PRICE_NO_VALUE ? "null" : String(prices[17], 4).c_str(),
prices[18] == PRICE_NO_VALUE ? "null" : String(prices[18], 4).c_str(),
prices[19] == PRICE_NO_VALUE ? "null" : String(prices[19], 4).c_str(),
prices[20] == PRICE_NO_VALUE ? "null" : String(prices[20], 4).c_str(),
prices[21] == PRICE_NO_VALUE ? "null" : String(prices[21], 4).c_str(),
prices[22] == PRICE_NO_VALUE ? "null" : String(prices[22], 4).c_str(),
prices[23] == PRICE_NO_VALUE ? "null" : String(prices[23], 4).c_str(),
prices[24] == PRICE_NO_VALUE ? "null" : String(prices[24], 4).c_str(),
prices[25] == PRICE_NO_VALUE ? "null" : String(prices[25], 4).c_str(),
prices[26] == PRICE_NO_VALUE ? "null" : String(prices[26], 4).c_str(),
prices[27] == PRICE_NO_VALUE ? "null" : String(prices[27], 4).c_str(),
prices[28] == PRICE_NO_VALUE ? "null" : String(prices[28], 4).c_str(),
prices[29] == PRICE_NO_VALUE ? "null" : String(prices[29], 4).c_str(),
prices[30] == PRICE_NO_VALUE ? "null" : String(prices[30], 4).c_str(),
prices[31] == PRICE_NO_VALUE ? "null" : String(prices[31], 4).c_str(),
prices[32] == PRICE_NO_VALUE ? "null" : String(prices[32], 4).c_str(),
prices[33] == PRICE_NO_VALUE ? "null" : String(prices[33], 4).c_str(),
prices[34] == PRICE_NO_VALUE ? "null" : String(prices[34], 4).c_str(),
prices[35] == PRICE_NO_VALUE ? "null" : String(prices[35], 4).c_str()
ps == NULL ? "" : ps->getSource()
);
for(uint8_t i = 0;i < 36; i++) {
if(prices[i] == PRICE_NO_VALUE) {
pos += snprintf_P(buf+pos, BufferSize-pos, PSTR(",\"%02d\":null"), i);
} else {
pos += snprintf_P(buf+pos, BufferSize-pos, PSTR(",\"%02d\":%.4f"), i, prices[i]);
}
}
snprintf_P(buf+pos, BufferSize-pos, PSTR("}"));
server.sendHeader(HEADER_CACHE_CONTROL, CACHE_CONTROL_NO_CACHE);
server.sendHeader(HEADER_PRAGMA, PRAGMA_NO_CACHE);
server.sendHeader(HEADER_EXPIRES, EXPIRES_OFF);