mirror of
https://gitee.com/js-yhsec/energy_storage.git
synced 2026-05-28 03:09:24 +08:00
1.新增服务端UI界面,显示服务基础信息。2.修改设备显示配置。3.监控页面储能系统显示储能模式,模式设置新增'手动'
This commit is contained in:
@@ -195,19 +195,17 @@ bool AppData::initFromDB()
|
||||
auto station = this->getStation(stationId);
|
||||
if (station)
|
||||
{
|
||||
station->storageIn = fields.get<double>(DMStatStation::STORAGE_ELECT_IN);
|
||||
station->storageOut = fields.get<double>(DMStatStation::STORAGE_ELECT_OUT);
|
||||
//station->storageIn = fields.get<double>(DMStatStation::STORAGE_ELECT_IN);
|
||||
//station->storageOut = fields.get<double>(DMStatStation::STORAGE_ELECT_OUT);
|
||||
//station->storageNumIn = fields.getFloat(DMStatStation::STORAGE_NUM);
|
||||
//station->storageNumOut = fields.getFloat(DMStatStation::STORAGE_NUM);
|
||||
station->storageNumErr = fields.get<int>(DMStatStation::STORAGE_NUM_ERR);
|
||||
|
||||
station->solarGen = fields.get<double>(DMStatStation::SOLAR_ELECT_GEN);
|
||||
station->solarGrid = fields.get<double>(DMStatStation::SOLAR_ELECT_GRID);
|
||||
station->solarNumErr = fields.get<int>(DMStatStation::SOLAR_NUM_ERR);
|
||||
|
||||
station->chargeElect = fields.get<double>(DMStatStation::CHARGE_ELECT);
|
||||
station->chargeNum = fields.get<int>(DMStatStation::CHARGE_NUM);
|
||||
station->chargeNumErr = fields.get<int>(DMStatStation::CHARGE_NUM_ERR);
|
||||
//station->storageNumErr = fields.get<int>(DMStatStation::STORAGE_NUM_ERR);
|
||||
//station->solarGen = fields.get<double>(DMStatStation::SOLAR_ELECT_GEN);
|
||||
//station->solarGrid = fields.get<double>(DMStatStation::SOLAR_ELECT_GRID);
|
||||
//station->solarNumErr = fields.get<int>(DMStatStation::SOLAR_NUM_ERR);
|
||||
//station->chargeElect = fields.get<double>(DMStatStation::CHARGE_ELECT);
|
||||
//station->chargeNum = fields.get<int>(DMStatStation::CHARGE_NUM);
|
||||
//station->chargeNumErr = fields.get<int>(DMStatStation::CHARGE_NUM_ERR);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -216,30 +214,38 @@ bool AppData::initFromDB()
|
||||
}
|
||||
}
|
||||
|
||||
{ // 初始化场站设备的历史监测数据
|
||||
|
||||
{ // 初始化场站设备的历史监测数据(当天)
|
||||
vector<Fields> result;
|
||||
DAO::queryRuntimeData(dao, Utils::dateStr(), result);
|
||||
DAO::queryRuntimeDataHistory(dao, Utils::dateStr(), result);
|
||||
for (auto& item : result)
|
||||
{
|
||||
int stationId = item.get<int>("station_id");
|
||||
int deviceId = item.get<int>("device_id");
|
||||
int datatype = item.get<int>("datatype");
|
||||
auto device = this->getDevice(stationId, deviceId);
|
||||
if (device)
|
||||
{
|
||||
int datatype = item.get<int>("datatype");
|
||||
std::string value = item.value("value");
|
||||
|
||||
njson json;
|
||||
if (JSON::parse(value, json))
|
||||
{
|
||||
std::vector<double> vecVal(json.size());
|
||||
for (int i=0; i<json.size(); ++i)
|
||||
{
|
||||
vecVal[i] = JSON::get<double>(json[i]);
|
||||
}
|
||||
device->setCache(datatype, vecVal);
|
||||
}
|
||||
std::vector<float> vd;
|
||||
JSON::parseArray(value, vd);
|
||||
device->setCache(datatype, vd);
|
||||
}
|
||||
}
|
||||
}
|
||||
{ // 初始化预测数据源的历史数据(当天)
|
||||
vector<Fields> result;
|
||||
DAO::queryPredictHistory(dao, Utils::dateStr(), result);
|
||||
for (auto& item : result)
|
||||
{
|
||||
int stationId = item.get<int>("station_id");
|
||||
int datatype = item.get<int>("datatype");
|
||||
auto station = this->getStation(stationId);
|
||||
if (station)
|
||||
{
|
||||
std::string value = item.value("value");
|
||||
std::vector<float> vd;
|
||||
JSON::parseArray(value, vd);
|
||||
station->setCache(datatype, vd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,12 +98,13 @@ void Application::runThreadMain()
|
||||
}
|
||||
|
||||
static TimeTick ttMqttPolling; // 召测
|
||||
if (!Config::option.mqtt.host.empty() && ttMqttPolling.elapse(10))
|
||||
int mqttInterval = Config::option.mqtt.interval;
|
||||
if (!Config::option.mqtt.host.empty() && mqttInterval > 0 && ttMqttPolling.elapse(10))
|
||||
{
|
||||
for (auto& item : appdata.mapStation)
|
||||
{
|
||||
auto& station = item.second;
|
||||
if (Utils::time() - station->getPollingTS() > Config::option.mqtt.interval)
|
||||
if (Utils::time() - station->getPollingTS() > mqttInterval)
|
||||
{
|
||||
item.second->polling();
|
||||
}
|
||||
|
||||
@@ -187,22 +187,9 @@ void Device::getCachePower(std::vector<std::string>& vec)
|
||||
}
|
||||
}
|
||||
|
||||
int64_t GetCurrentTimePos(int step)
|
||||
void Device::setCache(int datatype, std::vector<float>& vd)
|
||||
{
|
||||
auto tp = chrono::system_clock::now();
|
||||
int64_t tTime = chrono::time_point_cast<chrono::seconds>(tp).time_since_epoch().count();
|
||||
std::time_t t = chrono::system_clock::to_time_t(tp);
|
||||
std::tm* tmlocal = localtime(&t);
|
||||
tmlocal->tm_hour = 0;
|
||||
tmlocal->tm_min = 0;
|
||||
tmlocal->tm_sec = 0;
|
||||
int64_t tDate = chrono::time_point_cast<chrono::seconds>(chrono::system_clock::from_time_t(mktime(tmlocal))).time_since_epoch().count();
|
||||
return (tTime - tDate) / step;
|
||||
}
|
||||
|
||||
void Device::setCache(int datatype, std::vector<double>& vec)
|
||||
{
|
||||
std::map<int, double>* mapptr = NULL;
|
||||
std::map<int, float>* mapptr = NULL;
|
||||
if (datatype == 1) { mapptr = &mapCacheVoltage; }
|
||||
else if (datatype == 2) { mapptr = &mapCacheCurrent; }
|
||||
else if (datatype == 3) { mapptr = &mapCachePower; }
|
||||
@@ -211,12 +198,12 @@ void Device::setCache(int datatype, std::vector<double>& vec)
|
||||
{
|
||||
const int step = 600;
|
||||
const int N = 86400/step;
|
||||
|
||||
int n = GetCurrentTimePos(step);
|
||||
int64_t tsSeconds = Utils::timeDaySeconds();
|
||||
int npos = tsSeconds / step;
|
||||
for (int i = 0; i<N; ++i)
|
||||
{
|
||||
if (i < vec.size()) { (*mapptr)[i] = vec[i]; }
|
||||
else if (i <= n) { (*mapptr)[i] = 0; }
|
||||
if (i < vd.size()) { (*mapptr)[i] = vd[i]; }
|
||||
else if (i <= npos) { (*mapptr)[i] = 0; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -402,10 +389,10 @@ void Device::getRuntimeParams(std::vector<std::pair<std::string, std::string>>&
|
||||
if (v == "0") v = "并网";
|
||||
else if (v == "1") v = "离网";
|
||||
}
|
||||
if (item.addr == "0x1008") // 模块状态 R uint16 1开机,0待机 0x1008
|
||||
if (item.addr == "0x1006") // 启停状态 R uint16 1开机,0关机 0x1008
|
||||
{
|
||||
if (v == "0") v = "开机";
|
||||
else if (v == "1") v = "待机";
|
||||
if (v == "1") v = "开机";
|
||||
else if (v == "0") v = "关机";
|
||||
}
|
||||
}
|
||||
else if (type == int(EDeviceType::PCS))
|
||||
@@ -466,7 +453,7 @@ void Device::setBCUUnit(std::string k, int pos, int v, int count)
|
||||
if (k == "0x0056") { bcuUnit[0] = float(v) * 0.1f; }
|
||||
else if (k == "0x043E") { bcuUnit[1] = float(v) * 0.1f; }
|
||||
else if (k == "0x0826") { bcuUnit[2] = float(v) * 0.001f; }
|
||||
else if (k == "0x0C0E") { bcuUnit[3] = float(v); } // * 0.01f
|
||||
else if (k == "0x0C0E") { bcuUnit[3] = float(v) * 0.01f; } // * 0.01f
|
||||
else if (k == "0x0FF6") { bcuUnit[4] = float(v); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
void getCachePower(std::vector<std::string>& vec);
|
||||
|
||||
// int datatype: 1: 电压,2:电流,3:功率
|
||||
void setCache(int datatype, std::vector<double>& vec);
|
||||
void setCache(int datatype, std::vector<float>& vec);
|
||||
|
||||
bool cache(int npos);
|
||||
void storeDB(int npos);
|
||||
@@ -87,9 +87,9 @@ public:
|
||||
std::shared_ptr<CommEntity> commEntity;
|
||||
|
||||
int64_t tsDataDate {};
|
||||
std::map<int, double> mapCacheVoltage;
|
||||
std::map<int, double> mapCacheCurrent;
|
||||
std::map<int, double> mapCachePower;
|
||||
std::map<int, float> mapCacheVoltage;
|
||||
std::map<int, float> mapCacheCurrent;
|
||||
std::map<int, float> mapCachePower;
|
||||
std::map<std::string, std::string> mapParams;
|
||||
|
||||
std::map<std::string, DeviceParamAddr*> mapMyParams;
|
||||
|
||||
@@ -203,6 +203,19 @@ void Station::setGarewayWorkMode()
|
||||
mqttCli->publish("Gateway_YT", text);
|
||||
}
|
||||
|
||||
|
||||
string Station::getGatewayMode()
|
||||
{
|
||||
// 0:手动,1:峰谷套利,2:增网配容,3:应急供电,4:并网保电,5:自定时段
|
||||
if (workModeGateway == 0) { return "手动"; }
|
||||
else if (workModeGateway == 1) { return "峰谷套利"; }
|
||||
else if (workModeGateway == 2) { return "增网配容"; }
|
||||
else if (workModeGateway == 3) { return "应急供电"; }
|
||||
else if (workModeGateway == 4) { return "并网保电"; }
|
||||
else if (workModeGateway == 5) { return "自定时段"; }
|
||||
else { return "--"; };
|
||||
}
|
||||
|
||||
void Station::checkDevice()
|
||||
{
|
||||
for (auto& item: mapDevice)
|
||||
@@ -331,6 +344,7 @@ void Station::readCoolingData(int deviceNo, string addr, int val)
|
||||
|
||||
void Station::readGatewayMode(int mode)
|
||||
{
|
||||
this->workModeGateway = mode;
|
||||
if (mode != this->workMode)
|
||||
{
|
||||
//this->setGarewayWorkMode();
|
||||
@@ -363,20 +377,61 @@ void Station::readGatewayStatus(int cdzStatus, int emuStatus)
|
||||
}
|
||||
}
|
||||
|
||||
static std::string MapValueToJson(int npos, std::map<int, double>& mapV)
|
||||
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(mapV[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();
|
||||
@@ -386,7 +441,7 @@ void Station::writeStatistic()
|
||||
for (auto iter = mapDevice.begin(); iter!=mapDevice.end(); ++iter)
|
||||
{
|
||||
auto device = iter->second;
|
||||
if (device->cache(npos) && device->type == int(EDeviceType::BMS))
|
||||
if (device->cache(npos))
|
||||
{
|
||||
Fields fields;
|
||||
fields.set("dt", dt);
|
||||
@@ -407,7 +462,7 @@ void Station::writeStatistic()
|
||||
}
|
||||
}
|
||||
|
||||
if (statData.ts != 0)
|
||||
if (statData.ts > 0)
|
||||
{
|
||||
Fields fields;
|
||||
fields.set("dt", Utils::dateStr(statData.ts));
|
||||
@@ -437,15 +492,14 @@ void Station::writeStatistic()
|
||||
};
|
||||
dao->duplicateUpdate(fields, vecKeys);
|
||||
|
||||
{
|
||||
{ // stat_day
|
||||
Fields fields;
|
||||
fields.set("dt", Utils::dateStr(statData.ts));
|
||||
fields.set("station_id", this->stationId);
|
||||
fields.set("device_id", 0);
|
||||
fields.set("storage_elect_in", statData.dayElectIn);
|
||||
fields.set("storage_elect_out", statData.dayElectOut);
|
||||
fields.set("income_elect", statData.dayIncome);
|
||||
DAO::insertStatStation(dao, fields);
|
||||
DAO::insertStatDay(dao, fields);
|
||||
}
|
||||
{
|
||||
Fields fields;
|
||||
@@ -458,4 +512,25 @@ void Station::writeStatistic()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
// 预测数据源记录
|
||||
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"});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -115,6 +115,8 @@ public:
|
||||
void setGarewayWorkMode();
|
||||
void checkDevice();
|
||||
|
||||
string getGatewayMode();
|
||||
|
||||
void readAlert(std::shared_ptr<Device> device, std::string addr, int v, std::string text);
|
||||
void readRuntimeData(int deviceNo, string addr, int val);
|
||||
void readTHData(int deviceNo, string addr, int val);
|
||||
@@ -123,6 +125,10 @@ public:
|
||||
void readGatewayMode(int mode);
|
||||
void readGatewayStatus(int cdzStatus, int emuStatus);
|
||||
|
||||
void setCache(int datatype, std::vector<float>& vd);
|
||||
void cache();
|
||||
int posCache {0};
|
||||
|
||||
void writeStatistic();
|
||||
int posDayStat {0};
|
||||
|
||||
@@ -138,6 +144,7 @@ public:
|
||||
bool isConnected {false};
|
||||
|
||||
int workMode {}; // 运行模式
|
||||
int workModeGateway { -1 }; // 运行模式
|
||||
int runPolicyId {}; // 运行策略
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -158,23 +165,19 @@ public:
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// === 日统计 ===
|
||||
double storageIn {}; // 储能充电电量
|
||||
double storageOut {}; // 储能放电电量
|
||||
|
||||
int storageNumIn {}; // 储能充电次数
|
||||
int storageNumOut {}; // 储能放电次数
|
||||
int storageNumErr {}; // 储能故障次数
|
||||
|
||||
double solarGen {}; // 光伏发电电量
|
||||
double solarGrid {}; // 光伏入网电量
|
||||
int solarNumErr {}; // 光伏故障次数
|
||||
|
||||
double chargeElect {}; // 充电设备充电电量
|
||||
int chargeNum {}; // 充电设备充电次数
|
||||
int chargeNumErr {}; // 充电设备故障次数
|
||||
|
||||
double incomeElect {}; // 发电收益金额
|
||||
double incomeCharge {}; // 充电收益金额
|
||||
//double storageIn {}; // 储能充电电量
|
||||
//double storageOut {}; // 储能放电电量
|
||||
//int storageNumIn {}; // 储能充电次数
|
||||
//int storageNumOut {}; // 储能放电次数
|
||||
//int storageNumErr {}; // 储能故障次数
|
||||
//double solarGen {}; // 光伏发电电量
|
||||
//double solarGrid {}; // 光伏入网电量
|
||||
//int solarNumErr {}; // 光伏故障次数
|
||||
//double chargeElect {}; // 充电设备充电电量
|
||||
//int chargeNum {}; // 充电设备充电次数
|
||||
//int chargeNumErr {}; // 充电设备故障次数
|
||||
//double incomeElect {}; // 发电收益金额
|
||||
//double incomeCharge {}; // 充电收益金额
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// === 环境 ===
|
||||
@@ -200,7 +203,6 @@ public:
|
||||
std::unordered_map<int, std::shared_ptr<Device>> mapDevice;
|
||||
std::map<int, std::map<std::string, std::shared_ptr<Device>>> mapDeviceGroup;
|
||||
|
||||
|
||||
// 温湿度信息
|
||||
std::map<int, TempHumUnit> mapTempHumUnit;
|
||||
// 消防4.0信息
|
||||
@@ -269,4 +271,14 @@ public:
|
||||
int emuStatus {-1};
|
||||
|
||||
std::map<std::string, int64_t> mapAlertCache;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// 说明:从电表中读取对应数据:每间隔600秒(10分钟)缓存一个点位,存储到数据库,用于绘制一天的电曲线
|
||||
// 储能充电量缓存,key:位置索引(0->144),val:电量
|
||||
std::map<int, float> mapCacheElectIn;
|
||||
// 储能放电量缓存,key:位置索引(0->144),val:电量
|
||||
std::map<int, float> mapCacheElectOut;
|
||||
// 充电桩充电量缓存,key:位置索引(0->144),val:电量
|
||||
std::map<int, float> mapCacheElectCharger;
|
||||
};
|
||||
Reference in New Issue
Block a user