Files
energy_storage/src/app/Station.cpp

678 lines
28 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "Station.h"
#include "database/DAO.h"
#include "database/SQL.h"
#include "common/fields.h"
#include "app/Device.h"
#include "common/Spdlogger.h"
#include "common/Utils.h"
#include "protocol/MqttEntity.h"
#include "common/JsonN.h"
#include "app/Config.h"
#include "common/Snowflake.h"
#include "app/DataStruct.h"
#include "app/Application.h"
Station::Station() : stationId(0)
{
mqttCli = std::make_shared<MqttClient>();
}
void Station::setFields(Fields& fields)
{
this->stationId = fields.get<int>(DMStation::STATION_ID);
this->name = fields.value(DMStation::NAME);
this->capacity = fields.get<double>(DMStation::CAPACITY);
this->workMode = fields.get<int>(DMStation::WORK_MODE);
this->code = fields.value(DMStation::CODE);
this->status = fields.get<int>(DMStation::STATUS);
this->operationDate = fields.value(DMStation::OPERATION_DATE);
this->launchDate = fields.value("operation_date");
//this->policy.setFields(fields);
}
void Station::addDevice(int deviceId, std::shared_ptr<Device> device)
{
mapDevice[deviceId] = device;
}
void Station::addDevice(Fields& fields)
{
int deviceId = fields.get<int>(DMDevice::DEVICE_ID);
int stationId = fields.get<int>(DMDevice::STATION_ID);
if (mapDevice.find(deviceId) != mapDevice.end())
{
mapDevice[deviceId]->setFields(fields);
}
else
{
auto device = Device::create(fields);
mapDevice[deviceId] = device;
}
}
std::shared_ptr<Device> Station::getDevice(int deviceId)
{
auto iter = mapDevice.find(deviceId);
if (iter!=mapDevice.end())
{
return iter->second;
}
return nullptr;
}
void Station::groupDevice()
{
for (auto iter = mapDevice.begin(); iter!=mapDevice.end(); ++iter)
{
auto& device = iter->second;
char key[20] = {};
sprintf(key, "%03d_%03d_%04d", device->stationId, device->sortNo, device->deviceId);
mapDeviceGroup[device->category][key] = device;
}
}
std::shared_ptr<Device> Station::getDeviceByType(int deviceType, std::string code)
{
for (auto iter = mapDevice.begin(); iter!=mapDevice.end(); ++iter)
{
auto device = iter->second;
if (device->type == deviceType && device->code == code)
{
return device;
}
}
return nullptr;
}
void Station::getDeviceByType(int deviceType, std::vector<std::shared_ptr<Device>>& res)
{
for (auto iter = mapDevice.begin(); iter!=mapDevice.end(); ++iter)
{
auto device = iter->second;
if (device->type == deviceType)
{
res.push_back(device);
}
}
}
int Station::getDeviceCount(int category)
{
auto iter = mapDeviceGroup.find(category);
if (iter != mapDeviceGroup.end())
{
return iter->second.size();
}
return 0;
}
void Station::getDeviceByCategory(int category, std::vector<std::shared_ptr<Device>>& res)
{
auto iter = mapDeviceGroup.find(category);
if (iter != mapDeviceGroup.end())
{
res.resize(iter->second.size());
int i = 0;
for (auto& item: iter->second)
{
res[i++] = item.second;
}
}
}
void Station::setWorkMode(int modeId)
{
this->workMode = modeId;
std::string sql = SQL(SQL::TYPE::update).table(DMStation::TABLENAME)
.update(DMStation::WORK_MODE, std::to_string(modeId))
.where(DMStation::STATION_ID + "=" + std::to_string(stationId)).str();
Errcode err = DAO::exec(NULL, sql);
if (err != Errcode::OK)
{
spdlog::error("set station work mode failed.");
}
}
void Station::initMqtt()
{
if (status!=0 && mqttCli)
{
auto& optionMqtt = Config::option.mqtt;
mqttCli->init(optionMqtt.host, code, optionMqtt.username, optionMqtt.password);
}
}
void Station::polling()
{
if (status > 0 && mqttCli)
{
if (mqttCli->isConnected)
{
mqttCli->polling();
}
//else
//{
// // 该函数检查连接状态,若已经连接,则无操作;若未连接,则进行连接操作
// this->initMqtt();
//}
}
}
int64_t Station::getPollingTS()
{
return (mqttCli != nullptr) ? mqttCli->tsPolling : 0;
}
void Station::setGarewayWorkMode()
{
if (!mqttCli)
{
return;
}
auto policy = Application::data().getPolicyByType(this->workMode);
njson json;
json["ts"] = Utils::time();
json["no"] = 1; // 设备编号
json["40001"] = this->workMode;
if (policy)
{
if (policy->type == 1)
{
json["40002"] = njson::array(); // 峰谷套利
policy->getGatewayJsonPeriods(json["40002"]);
}
else if (policy->type == 5)
{
json["40021"] = njson::array(); // 自定时段
policy->getGatewayJsonPeriods(json["40021"]);
}
}
json["40038"] = {gatewayParam.socMin, gatewayParam.socMax, gatewayParam.capacity, gatewayParam.powerSafe, gatewayParam.powerDischarge, gatewayParam.powerCharge};
json["40058"] = {gatewayParam.backflow, gatewayParam.overload};
std::string text = json.dump();
spdlog::info(text);
mqttCli->publish("Gateway_YT", text);
}
string Station::getGatewayMode()
{
// 0手动1峰谷套利2增网配容3应急供电4并网保电5自定时段
if (gatewayParam.mode == 0) { return "手动"; }
else if (gatewayParam.mode == 1) { return "峰谷套利"; }
else if (gatewayParam.mode == 2) { return "增网配容"; }
else if (gatewayParam.mode == 3) { return "应急供电"; }
else if (gatewayParam.mode == 4) { return "并网保电"; }
else if (gatewayParam.mode == 5) { return "自定时段"; }
else { return "--"; };
}
static map<int, string> mapPeriodType =
{
{1, ""}, {2, ""}, {3, ""}, {4, ""}
};
static map<int, string> mapPeriodOper =
{
{0, ""}, {1, ""}, {2, ""}, {3, ""}, {4, ""}
};
string Station::getGatewayParam()
{
stringstream ss;
std::string str1 = "峰谷套利时段:<br>";
{
njson json;
if (JSON::parse(gatewayParam.param1, json))
{
for (int i = 0; i<json.size(); ++i)
{
str1 += "&nbsp&nbsp&nbsp&nbsp" + std::to_string(i+1) + "月: ";
ss.str("");
for (auto& jsonitem : json[i])
{
ss << "(" << setw(2) << setfill('0') << jsonitem[0].get<int>();
ss << ":" << setw(2) << setfill('0') << jsonitem[1].get<int>() << " ";
ss << mapPeriodType[jsonitem[2].get<int>()] << ") ";
}
str1 += ss.str() + "<br>";
}
}
}
std::string str2 = "自定时段:<br>";
{
njson json;
if (JSON::parse(gatewayParam.param2, json))
{
for (int i = 0; i<json.size(); ++i)
{
str2 += "&nbsp&nbsp&nbsp&nbsp时段" + std::to_string(i+1) + ": ";
ss.str("");
for (auto& jsonitem : json[i])
{
ss << "(" << setw(2) << setfill('0') << jsonitem[0].get<int>();
ss << ":" << setw(2) << setfill('0') << jsonitem[1].get<int>() << " ";
ss << mapPeriodOper[jsonitem[2].get<int>()] << ") ";
}
str2 += ss.str() + "<br>";
}
}
}
std::string str3 = "其它参数:<br>";
{
njson json;
if (JSON::parse(gatewayParam.param3, json))
{
for (int i = 0; i<json.size(); ++i)
{
int val = json[i].get<int>();
if (i==0) { str3 += "&nbsp&nbsp&nbsp&nbsp储能放电下限值SOC: " + std::to_string(val) + "<br>"; } //储能放电下限值 SOC : 40038 (%:0-99 且小于充电上限值)
else if (i==1) { str3 += "&nbsp&nbsp&nbsp&nbsp储能充电上限值SOC: " + std::to_string(val) + "<br>"; }//储能充电上限值 SOC : 40039 (%:1-100 且大于放电下限值)
else if (i==2) { str3 += "&nbsp&nbsp&nbsp&nbsp台区变压器容量: " + std::to_string(val) + "<br>"; }//台区变压器容量 : 40040 (KVVA 160-1600)
else if (i==3) { str3 += "&nbsp&nbsp&nbsp&nbsp安全输入功率: " + std::to_string(val) + "<br>"; }//安全输入功率 : 40041 (KW 0-400)
else if (i==4) { str3 += "&nbsp&nbsp&nbsp&nbsp储能最大放电功率: " + std::to_string(val) + "<br>"; }//储能最大放电功率 : 40042 (1KW0-150)
else if (i==5) { str3 += "&nbsp&nbsp&nbsp&nbsp储能最大充电功率: " + std::to_string(val) + "<br>"; }//储能最大充电功率::40043 (1KW0-150)
else if (i==6) { str3 += "&nbsp&nbsp&nbsp&nbsp运行状态: " + std::to_string(val) + "<br>"; }//运行状态 : 40044 (只读不写0:无 1:高峰放电 2:低谷充电)
else if (i==7) { str3 += "&nbsp&nbsp&nbsp&nbsp台区电表变比: " + std::to_string(val) + "<br>"; }//台区电表变比:40045
//else if (i==8) { str3 += "&nbsp&nbsp&nbsp&nbsp对时(年): " + std::to_string(val) + "<br>"; }//对时(年) : 40051
//else if (i==9) { str3 += "&nbsp&nbsp&nbsp&nbsp对时(月): " + std::to_string(val) + "<br>"; }//对时(月) : 40052
//else if (i==10) { str3 += "&nbsp&nbsp&nbsp&nbsp对时(日): " + std::to_string(val) + "<br>"; }//对时(日) : 40053
//else if (i==11) { str3 += "&nbsp&nbsp&nbsp&nbsp对时(时): " + std::to_string(val) + "<br>"; }//对时(时) : 40054
//else if (i==12) { str3 += "&nbsp&nbsp&nbsp&nbsp对时(分): " + std::to_string(val) + "<br>"; }//对时(分) : 40055
//else if (i==13) { str3 += "&nbsp&nbsp&nbsp&nbsp对时(秒): " + std::to_string(val) + "<br>"; }//对时(秒) : 40056
//else if (i==19) { str3 += "&nbsp&nbsp&nbsp&nbsp时间段月份: " + std::to_string(val) + "<br>"; }//时间段月份 : 40057(1-12 对应1月-12月)
else if (i==20) { str3 += "&nbsp&nbsp&nbsp&nbsp防逆流回差: " + std::to_string(val) + "<br>"; }//防逆流回差 : 40058(1KW 10-300)
else if (i==21) { str3 += "&nbsp&nbsp&nbsp&nbsp防过载回差: " + std::to_string(val) + "<br>"; }//防过载回差 : 40059(1KW 10-300)
}
}
}
return str1 + "<br/>" + str2 + "<br/>" + str3;
}
void Station::checkDevice()
{
for (auto& item: mapDevice)
{
auto& device = item.second;
if (device)
{
if (Utils::time() - device->ts > 60*6)
{
device->online = 0;
}
}
}
}
void Station::readAlert(std::shared_ptr<Device> device, std::string addr, int v, std::string text)
{
int64_t ts = Utils::time();
std::string alertId = std::to_string(device->deviceId) + "_" + addr;
int tsCache = mapAlertCache[alertId];
if (ts - tsCache > 60*30)
{
Fields fields;
fields.set("log_id", Snowflake::instance().getIdStr());
if (device) { fields.set("device_id", device->deviceId); }
fields.set("type", int(EAlertType::DEVICE));
fields.set("content", text + ":故障(" + std::to_string(v) + ")");
fields.set("status", 1);
auto dao = DaoEntity::create("log_alert");
dao->insertFields(fields);
mapAlertCache[alertId] = ts;
}
}
void Station::readRuntimeData(int deviceNo, string addr, int val)
{
if (deviceNo == 1)
{
if (addr == "0x000B") { this->voltage = val; } // A相电压 R uint32 1V 0x000B
if (addr == "0x0011") { this->current = val; } // A相电流 R int32 1A 0x0011
if (addr == "0x0011") { this->power = val; } // 三相总有功 R int32 1kW 0x0023
}
else if (deviceNo == 2)
{
statData.ts = Utils::time();
if (addr == "0x002F") { statData.dayElectIn = val; } //日充电电量 R uint32 1kWh 0x002F
else if (addr == "0x0031") { statData.dayElectOut = val; } //日放电电量 R uint32 1kWh 0x0031
else if (addr == "0x0033") { statData.dayFeeIn = val; } //日充电费用 R uint32 1RMB 0x0033
else if (addr == "0x0035") { statData.dayFeeOut = val; } //日放电费用 R uint32 1RMB 0x0035
else if (addr == "0x0037") { statData.dayIncome = val; } //日收益 R int32 1RMB 0x0037
else if (addr == "0x004D") { statData.totalElectIn = val; } //总充电电量 R uint32 1kWh 0x004D
else if (addr == "0x004F") { statData.totalElectOut = val; } //总放电电量 R uint32 1kWh 0x004F
else if (addr == "0x0051") { statData.totalFeeIn = val; } //总充电费用 R uint32 1RMB 0x0051
else if (addr == "0x0053") { statData.totalFeeOut = val; } //总放电费用 R uint32 1RMB 0x0053
else if (addr == "0x0055") { statData.totalIncome = val; } //总收益 R int32 1RMB 0x0055
else if (addr == "0x0039") { statData.dayElectIn_J = val; } //日正向尖有功电能 R uint32 1kWh 0x0039
else if (addr == "0x003B") { statData.dayElectIn_F = val; } //日正向峰有功电能 R uint32 1kWh 0x003B
else if (addr == "0x003D") { statData.dayElectIn_P = val; } //日正向平有功电能 R uint32 1kWh 0x003D
else if (addr == "0x003F") { statData.dayElectIn_G = val; } //日正向谷有功电能 R uint32 1kWh 0x003F
else if (addr == "0x0041") { statData.dayElectIn_Total = val; } //日正向总有功电能 R uint32 1kWh 0x0041
else if (addr == "0x0043") { statData.dayElectOut_J = val; } //日反向尖有功电能 R uint32 1kWh 0x0043
else if (addr == "0x0045") { statData.dayElectOut_F = val; } //日反向峰有功电能 R uint32 1kWh 0x0045
else if (addr == "0x0047") { statData.dayElectOut_P = val; } //日反向平有功电能 R uint32 1kWh 0x0047
else if (addr == "0x0049") { statData.dayElectOut_G = val; } //日反向谷有功电能 R uint32 1kWh 0x0049
else if (addr == "0x004B") { statData.dayElectOut_Total = val; } //日反向总有功电能 R uint32 1kWh 0x004B
else if (addr == "0x0057") { statData.totalElectIn_J = val; } //总正向尖有功电能 R uint32 1kWh 0x0057
else if (addr == "0x0059") { statData.totalElectIn_F = val; } //总正向峰有功电能 R uint32 1kWh 0x0059
else if (addr == "0x005B") { statData.totalElectIn_P = val; } //总正向平有功电能 R uint32 1kWh 0x005B
else if (addr == "0x005D") { statData.totalElectIn_G = val; } //总正向谷有功电能 R uint32 1kWh 0x005D
else if (addr == "0x005F") { statData.totalElectIn_Total = val; } //总正向总有功电能 R uint32 1kWh 0x005F
else if (addr == "0x0061") { statData.totalElectOut_J = val; } //总反向尖有功电能 R uint32 1kWh 0x0061
else if (addr == "0x0063") { statData.totalElectOut_F = val; } //总反向峰有功电能 R uint32 1kWh 0x0063
else if (addr == "0x0065") { statData.totalElectOut_P = val; } //总反向平有功电能 R uint32 1kWh 0x0065
else if (addr == "0x0067") { statData.totalElectOut_G = val; } //总反向谷有功电能 R uint32 1kWh 0x0067
else if (addr == "0x0069") { statData.totalElectOut_Total = val; } //总反向总有功电能 R uint32 1kWh 0x0069
}
}
void Station::readTHData(int deviceNo, string addr, int val)
{
auto& unit = mapTempHumUnit[deviceNo];
if (addr == "0x0001") { ; } //所属通道号 R uint16 1 0x0001
else if (addr == "0x0002") { ; } //所属温湿度号 R uint16 1~10 0x0002
else if (addr == "0x0003") //温度 R int16 0.1℃ 0x0003
{
unit.temp = float(val) * 0.1;
if (deviceNo == 1) temperature = unit.temp;
}
else if (addr == "0x0004") //湿度 R int16 0.1℃ 0x0004
{
unit.hum = float(val) * 0.1;
if (deviceNo == 1) humidity = unit.hum;
}
}
void Station::readFire40Data(int deviceNo, string addr, int val)
{
auto& unit = mapFire40Unit[deviceNo];
if (addr == "0x0001") { ; } //所属通道号 R uint16 1~10 0x0001
else if (addr == "0x0002") { ; } //主控数量 R uint16 1 0x0002
else if (addr == "0x0003") { ; } //主控ID R uint16 1 0x0003
else if (addr == "0x0004") { unit.statusMain = val; } //主控状态 R uint16 0正常 1预警 2火警 0x0004
else if (addr == "0x0005") { ; } //主控硬件版本 R uint16[2] 主控硬件版本 0x0005
else if (addr == "0x0007") { ; } //主控软件版本 R uint16[2] 主控软件版本 0x0007
else if (addr == "0x0009") { ; } //主电状态 R uint16 0使用市电 1使用备电 0x0009
else if (addr == "0x000A") { ; } //备电电流 R uint32 0.1A 0x000A
else if (addr == "0x000C") { ; } //备电电压 R uint32 0.1V 0x000C
else if (addr == "0x000E") { ; } //可用容量 R uint32 0.01Ah 0x000E
else if (addr == "0x0010") { ; } //可充放容量 R uint32 0.01Ah 0x0010
else if (addr == "0x0012") { unit.usedAlarm = val; } //警铃是否使用 R uint16 0x0012
else if (addr == "0x0013") { unit.statusAlarm = val; } //警铃状态 R uint16 0无效 1掉线 2正常 3启动 0x0013
else if (addr == "0x0014") { unit.usedValve = val; } //瓶头阀是否使用 R uint16 0x0014
else if (addr == "0x0015") { unit.statusValve = val; } //瓶头阀状态 R uint16 0无效 1掉线 2正常 3启动 0x0015
else if (addr == "0x0016") { unit.usedMCP = val; } //手报是否使用 R uint16 0x0016
else if (addr == "0x0017") { unit.statusMCP = val; } //手报状态 R uint16 0无效 1掉线 2正常 3启动 0x0017
else if (addr == "0x0018") { ; } //簇控制器数量 R uint16 0x0018
else if (addr == "0x0019") { ; } //复合探测器总数量 R uint16 0x0019
else if (addr == "0x001A") { ; } //烟雾探测器总数量 R uint16 0x001A
else if (addr == "0x001B") { ; } //压力探测器总数量 R uint16 0x001B
else if (addr == "0x001C") { ; } //吸气式探测器总数量 R uint16 0x001C
else if (addr == "0x001D") { ; } //PACK探测器总数量 R uint16 0x001D
else if (addr == "0x001E") { ; } //电池总数量 R uint16 0x001E
}
void Station::readCoolingData(int deviceNo, string addr, int val)
{
auto& unit = mapCoolingUnit[deviceNo];
if (addr == "0x1001") { ; } //所属通道号 R uint16 1 0x1001
else if (addr == "0x1002") { ; }// 所属冷机号 R uint16 1~10 0x1002
else if (addr == "0x1003") { coolingStatus = unit.powerOn = val; }// 开关 R uint16 0关机1开机 0x1003
else if (addr == "0x1004") { unit.mode = val; }// 采样模式 R uint16 0-出水温度 1-电芯温度 0x1004
else if (addr == "0x1005") { unit.cooling = val; }// 制冷状态 R uint16 0关闭, 1启动 0x1005
else if (addr == "0x1006") { unit.heating = val; }// 制热状态 R uint16 0关闭, 1启动 0x1006
else if (addr == "0x1007") { unit.highTemp = val; }// 高温告警 R uint16 0正常1告警 0x1007
else if (addr == "0x1008") { unit.lowTemp = val; }// 低温告警 R uint16 0正常1告警 0x1008
else if (addr == "0x1009") { unit.highPressure = val; }// 高压告警 R uint16 0正常1告警 0x1009
else if (addr == "0x100A") { unit.lowPressure = val; }// 低压告警 R uint16 0正常1告警 0x100A
else if (addr == "0x100B") { ; }// 进水温度传感器 R uint16 0正常1告警 0x100B
else if (addr == "0x100C") { ; }// 出水温度传感器 R uint16 0正常1告警 0x100C
else if (addr == "0x100D") { ; }// 进水压力传感器 R uint16 0正常1告警 0x100D
else if (addr == "0x100E") { ; }// 出水压力传感器 R uint16 0正常1告警 0x100E
}
static void JSONReadArrayItem(njson& json, int i, int& v)
{
if (json.is_array() && i < json.size())
{
v = json[i].get<int>();
}
}
void Station::readGatewayMode(int mode, string p1, string p2, string p3)
{
this->gatewayParam.mode = mode;
this->gatewayParam.param1 = p1;
this->gatewayParam.param2 = p2;
this->gatewayParam.param3 = p3;
if (mode != this->workMode)
{
//this->setGarewayWorkMode();
}
njson json;
if (JSON::parse(gatewayParam.param3, json))
{
JSONReadArrayItem(json, 0, gatewayParam.socMin); //储能放电下限值 SOC : 40038 (%:0-99 且小于充电上限值)
JSONReadArrayItem(json, 1, gatewayParam.socMax); //储能充电上限值 SOC : 40039 (%:1-100 且大于放电下限值)
JSONReadArrayItem(json, 2, gatewayParam.capacity); //台区变压器容量 : 40040 (KVVA 160-1600)
JSONReadArrayItem(json, 3, gatewayParam.powerSafe); //安全输入功率 : 40041 (KW 0-400)
JSONReadArrayItem(json, 4, gatewayParam.powerDischarge); //储能最大放电功率 : 40042 (1KW0-150)
JSONReadArrayItem(json, 5, gatewayParam.powerCharge); //储能最大充电功率::40043 (1KW0-150)
JSONReadArrayItem(json, 6, gatewayParam.status); //运行状态 : 40044 (只读不写0:无 1:高峰放电 2:低谷充电)
JSONReadArrayItem(json, 7, gatewayParam.vtRatio); //台区电表变比:40045
JSONReadArrayItem(json, 20, gatewayParam.backflow); //防逆流回差 : 40058(1KW 10-300)
JSONReadArrayItem(json, 21, gatewayParam.overload); //防过载回差 : 40059(1KW 10-300)
}
}
void Station::readGatewayStatus(int cdzStatus, int emuStatus)
{
//充电桩 1在线0离线
if (cdzStatus >= 0)
{
if (cdzStatus != this->cdzStatus)
{
std::string text = "场站[" + name + "(" + std::to_string(stationId) + ")]充电桩状态变化:" + (cdzStatus>0 ? "在线" : "离线");
if (this->cdzStatus < 0) { text = "系统启动," + text; }
DAO::insertSystemLogDevice(stationId, 0, text, cdzStatus);
this->cdzStatus = cdzStatus;
}
}
//储能 1在线0离线
if (emuStatus >= 0)
{
if (emuStatus != this->emuStatus)
{
std::string text = "场站[" + name + "(" + std::to_string(stationId) + ")]储能EMU状态变化" + (emuStatus>0 ? "在线" : "离线");
if (this->emuStatus < 0) { text = "系统启动," + text; }
DAO::insertSystemLogDevice(stationId, 0, text, emuStatus);
this->emuStatus = emuStatus;
}
}
}
static std::string MapValueToJson(int npos, std::map<int, float>& mapV)
{
njson jsonarray = njson::array();
for (int i = 0; i<=npos; i++)
{
jsonarray.push_back(int(mapV[i]));
}
return jsonarray.dump();
}
void Station::setCache(int datatype, std::vector<float>& vd)
{
std::map<int, float>* mapptr = NULL;
if (datatype == 1) { mapptr = &mapCacheElectIn; }
else if (datatype == 2) { mapptr = &mapCacheElectOut; }
else if (datatype == 3) { mapptr = &mapCacheElectCharger; }
if (mapptr)
{
const int step = 600;
const int N = 86400/step;
int64_t tsSeconds = Utils::timeDaySeconds();
int npos = tsSeconds / step;
for (int i = 0; i<N; ++i)
{
if (i < vd.size()) { (*mapptr)[i] = vd[i]; }
else if (i <= npos) { (*mapptr)[i] = 0; }
}
}
}
void Station::cache()
{
int64_t tDaySeconds = Utils::timeDaySeconds();
int npos = tDaySeconds / 600;
int offset = tDaySeconds % 600;
bool save = false;
if (offset >= (600-180) && npos + 1 < 144)
{
npos += 1;
save = true;
}
else if (offset <= 180 && posCache < npos)
{
save = true;
posCache = npos;
}
if (save)
{
mapCacheElectIn[npos] = Utils::random(100, 800); // dayElectIn
mapCacheElectOut[npos] = Utils::random(100, 800); // dayElectOut
mapCacheElectCharger[npos] = Utils::random(100, 800); // 暂无数据源
}
}
void Station::writeStatistic()
{
auto dao = DaoEntity::create("history_day");
std::string dt = Utils::dateStr();
int64_t tTime = Utils::time();
int64_t tDate = Utils::date();
int64_t tDelta = tTime - tDate;
int npos = (tTime-tDate) / 600;
for (auto iter = mapDevice.begin(); iter!=mapDevice.end(); ++iter)
{
auto device = iter->second;
if (device->cache(npos))
{
Fields fields;
fields.set("dt", dt);
fields.set("station_id", this->stationId);
fields.set("device_id", device->deviceId);
fields.set("datatype", 1);
fields.set("value", MapValueToJson(npos, device->mapCacheVoltage));
DAO::insertRuntimeData(dao, fields);
fields.set("datatype", 2);
fields.set("value", MapValueToJson(npos, device->mapCacheCurrent));
DAO::insertRuntimeData(dao, fields);
fields.set("datatype", 3);
fields.set("value", MapValueToJson(npos, device->mapCachePower));
DAO::insertRuntimeData(dao, fields);
//spdlog::info("[device] write runtime date to database, deviceId={}", device->deviceId);
}
}
if (statData.ts > 0)
{
{ // stat_day
Fields fields;
fields.set("dt", Utils::dateStr(statData.ts));
fields.set("station_id", this->stationId);
fields.set("storage_elect_in", statData.dayElectIn);
fields.set("storage_elect_out", statData.dayElectOut);
fields.set("income_elect", statData.dayIncome);
DAO::insertStatDay(dao, fields);
}
{
Fields fields;
fields.set("dt", Utils::dateStr(statData.ts));
fields.set("station_id", this->stationId);
fields.set("E_in", statData.totalElectIn);
fields.set("E_in_J", statData.totalElectIn_J);
fields.set("E_in_F", statData.totalElectIn_F);
fields.set("E_in_P", statData.totalElectIn_P);
fields.set("E_in_G", statData.totalElectIn_G);
fields.set("E_out", statData.totalElectOut);
fields.set("E_out_J", statData.totalElectOut_J);
fields.set("E_out_F", statData.totalElectOut_F);
fields.set("E_out_P", statData.totalElectOut_P);
fields.set("E_out_G", statData.totalElectOut_G);
fields.set("fee_in", statData.totalFeeIn);
fields.set("fee_Out", statData.totalFeeOut);
fields.set("income", statData.totalIncome);
dao->setTableName("stat_total");
dao->duplicateUpdate(fields, {
"E_in", "E_in_J", "E_in_F", "E_in_P", "E_in_G",
"E_out", "E_out_J", "E_out_F", "E_out_P", "E_out_G",
"fee_in", "fee_Out", "income"
});
}
{
Fields fields;
fields.set("dt", Utils::dateStr(statData.ts));
fields.set("station_id", this->stationId);
fields.set("E_in", statData.dayElectIn);
fields.set("E_in_J", statData.dayElectIn_J);
fields.set("E_in_F", statData.dayElectIn_F);
fields.set("E_in_P", statData.dayElectIn_P);
fields.set("E_in_G", statData.dayElectIn_G);
fields.set("E_out", statData.dayElectOut);
fields.set("E_out_J", statData.dayElectOut_J);
fields.set("E_out_F", statData.dayElectOut_F);
fields.set("E_out_P", statData.dayElectOut_P);
fields.set("E_out_G", statData.dayElectOut_G);
fields.set("fee_in", statData.dayFeeIn);
fields.set("fee_Out", statData.dayFeeOut);
fields.set("income", statData.dayIncome);
dao->setTableName("stat_total_day");
dao->duplicateUpdate(fields, {
"E_in", "E_in_J", "E_in_F", "E_in_P", "E_in_G",
"E_out", "E_out_J", "E_out_F", "E_out_P", "E_out_G",
"fee_in", "fee_Out", "income"
});
}
}
{
// 预测数据源记录
dao->setTableName("predict_day");
Fields fields;
fields.set("dt", dt);
fields.set("station_id", stationId);
fields.set("datatype", 1); // 1储能充电2储能放电3充电桩充电4发电
fields.set("value", MapValueToJson(npos, mapCacheElectIn));
dao->duplicateUpdate(fields, {"value"});
fields.set("datatype", 2); // 1储能充电2储能放电3充电桩充电4发电
fields.set("value", MapValueToJson(npos, mapCacheElectOut));
dao->duplicateUpdate(fields, {"value"});
fields.set("datatype", 3); // 1储能充电2储能放电3充电桩充电4发电
fields.set("value", MapValueToJson(npos, mapCacheElectCharger));
dao->duplicateUpdate(fields, {"value"});
}
}