feat(firmware): 添加 IM1281C 轮询间隔和电表数据处理逻辑
This commit is contained in:
@@ -37,6 +37,7 @@ static volatile bool s_blink_on = false;
|
|||||||
static const unsigned long BLINK_INTERVAL = 200; // 200ms blink interval
|
static const unsigned long BLINK_INTERVAL = 200; // 200ms blink interval
|
||||||
static const unsigned long CC_DEBOUNCE_MS = 30;
|
static const unsigned long CC_DEBOUNCE_MS = 30;
|
||||||
static const unsigned long AUTH_WINDOW_MS = 30000;
|
static const unsigned long AUTH_WINDOW_MS = 30000;
|
||||||
|
static const unsigned long IM1281C_POLL_INTERVAL_MS = 5000;
|
||||||
|
|
||||||
static bool s_cc1_plugged = false;
|
static bool s_cc1_plugged = false;
|
||||||
static bool s_cc2_plugged = false;
|
static bool s_cc2_plugged = false;
|
||||||
@@ -98,6 +99,25 @@ SmartLed leds(LED_WS2812B, LED_COUNT, LED_PIN, 0, DoubleBuffer);
|
|||||||
MFRC522 rfid(PIN_RC_CS, PIN_RC_RST);
|
MFRC522 rfid(PIN_RC_CS, PIN_RC_RST);
|
||||||
IM1281C im1281c;
|
IM1281C im1281c;
|
||||||
|
|
||||||
|
static IM1281CAData s_meter_a;
|
||||||
|
static IM1281CBData s_meter_b;
|
||||||
|
static bool s_meter_data_ready = false;
|
||||||
|
|
||||||
|
static int energyKwhToWh(float energyKwh)
|
||||||
|
{
|
||||||
|
if (energyKwh <= 0.0f)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float energyWh = energyKwh * 1000.0f;
|
||||||
|
if (energyWh > 2147483000.0f)
|
||||||
|
{
|
||||||
|
energyWh = 2147483000.0f;
|
||||||
|
}
|
||||||
|
return static_cast<int>(energyWh + 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
static bool isConnectorPlugged(unsigned int connectorId)
|
static bool isConnectorPlugged(unsigned int connectorId)
|
||||||
{
|
{
|
||||||
if (connectorId == 1)
|
if (connectorId == 1)
|
||||||
@@ -309,7 +329,7 @@ static void pollIm1281c()
|
|||||||
{
|
{
|
||||||
static unsigned long s_last_poll_ms = 0;
|
static unsigned long s_last_poll_ms = 0;
|
||||||
const unsigned long now = millis();
|
const unsigned long now = millis();
|
||||||
if ((now - s_last_poll_ms) < 1000)
|
if ((now - s_last_poll_ms) < IM1281C_POLL_INTERVAL_MS)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -323,6 +343,10 @@ static void pollIm1281c()
|
|||||||
|
|
||||||
const IM1281CAData &a = im1281c.a();
|
const IM1281CAData &a = im1281c.a();
|
||||||
const IM1281CBData &b = im1281c.b();
|
const IM1281CBData &b = im1281c.b();
|
||||||
|
s_meter_a = a;
|
||||||
|
s_meter_b = b;
|
||||||
|
s_meter_data_ready = true;
|
||||||
|
|
||||||
Serial.printf("[IM1281C] A: U=%.4fV I=%.4fA P=%.4fW E=%.4fkWh PF=%.3f CO2=%.4fkg T=%.2fC F=%.2fHz\n",
|
Serial.printf("[IM1281C] A: U=%.4fV I=%.4fA P=%.4fW E=%.4fkWh PF=%.3f CO2=%.4fkg T=%.2fC F=%.2fHz\n",
|
||||||
a.voltage,
|
a.voltage,
|
||||||
a.current,
|
a.current,
|
||||||
@@ -731,6 +755,45 @@ void setup()
|
|||||||
{ return s_cc2_plugged; },
|
{ return s_cc2_plugged; },
|
||||||
2);
|
2);
|
||||||
|
|
||||||
|
// Bind IM1281C metering values to OCPP connector 1 / 2
|
||||||
|
setEnergyMeterInput([]()
|
||||||
|
{ return s_meter_data_ready ? energyKwhToWh(s_meter_a.energy) : 0; },
|
||||||
|
1);
|
||||||
|
setPowerMeterInput([]()
|
||||||
|
{ return s_meter_data_ready ? s_meter_a.power : 0.0f; },
|
||||||
|
1);
|
||||||
|
addMeterValueInput([]()
|
||||||
|
{ return s_meter_data_ready ? s_meter_a.voltage : 0.0f; },
|
||||||
|
"Voltage", "V", nullptr, nullptr, 1);
|
||||||
|
addMeterValueInput([]()
|
||||||
|
{ return s_meter_data_ready ? s_meter_a.current : 0.0f; },
|
||||||
|
"Current.Import", "A", nullptr, nullptr, 1);
|
||||||
|
addMeterValueInput([]()
|
||||||
|
{ return s_meter_data_ready ? s_meter_a.powerFactor : 0.0f; },
|
||||||
|
"Power.Factor", nullptr, nullptr, nullptr, 1);
|
||||||
|
addMeterValueInput([]()
|
||||||
|
{ return s_meter_data_ready ? s_meter_a.frequency : 0.0f; },
|
||||||
|
"Frequency", "Hz", nullptr, nullptr, 1);
|
||||||
|
addMeterValueInput([]()
|
||||||
|
{ return s_meter_data_ready ? s_meter_a.temperature : 0.0f; },
|
||||||
|
"Temperature", "Celsius", nullptr, nullptr, 1);
|
||||||
|
|
||||||
|
setEnergyMeterInput([]()
|
||||||
|
{ return s_meter_data_ready ? energyKwhToWh(s_meter_b.energy) : 0; },
|
||||||
|
2);
|
||||||
|
setPowerMeterInput([]()
|
||||||
|
{ return s_meter_data_ready ? s_meter_b.power : 0.0f; },
|
||||||
|
2);
|
||||||
|
addMeterValueInput([]()
|
||||||
|
{ return s_meter_data_ready ? s_meter_b.voltage : 0.0f; },
|
||||||
|
"Voltage", "V", nullptr, nullptr, 2);
|
||||||
|
addMeterValueInput([]()
|
||||||
|
{ return s_meter_data_ready ? s_meter_b.current : 0.0f; },
|
||||||
|
"Current.Import", "A", nullptr, nullptr, 2);
|
||||||
|
addMeterValueInput([]()
|
||||||
|
{ return s_meter_data_ready ? s_meter_b.powerFactor : 0.0f; },
|
||||||
|
"Power.Factor", nullptr, nullptr, nullptr, 2);
|
||||||
|
|
||||||
// Custom RemoteStartTransaction policy:
|
// Custom RemoteStartTransaction policy:
|
||||||
// accept only when target connector is idle + operative + plugged.
|
// accept only when target connector is idle + operative + plugged.
|
||||||
setRequestHandler(
|
setRequestHandler(
|
||||||
|
|||||||
Reference in New Issue
Block a user