Compare commits

2 Commits

2 changed files with 50 additions and 2 deletions

View File

@@ -130,6 +130,17 @@ async function updateTransportState(
.where(eq(chargePoint.chargePointIdentifier, chargePointIdentifier)) .where(eq(chargePoint.chargePointIdentifier, chargePointIdentifier))
} }
async function getRegistrationStatus(chargePointIdentifier: string) {
const db = useDrizzle()
const [cp] = await db
.select({ registrationStatus: chargePoint.registrationStatus })
.from(chargePoint)
.where(eq(chargePoint.chargePointIdentifier, chargePointIdentifier))
.limit(1)
return cp?.registrationStatus ?? null
}
function getCommandChannelStatus(chargePointIdentifier: string): CommandChannelStatus { function getCommandChannelStatus(chargePointIdentifier: string): CommandChannelStatus {
return ocppConnections.has(chargePointIdentifier) ? 'online' : 'unavailable' return ocppConnections.has(chargePointIdentifier) ? 'online' : 'unavailable'
} }
@@ -211,6 +222,19 @@ export function createOcppHandler(chargePointIdentifier: string, remoteAddr?: st
ws.close(1002, 'Unsupported subprotocol') ws.close(1002, 'Unsupported subprotocol')
return return
} }
const registrationStatus = await getRegistrationStatus(chargePointIdentifier)
ctx.isRegistered = registrationStatus === 'Accepted'
const previous = ocppConnections.get(chargePointIdentifier)
if (previous && previous.sessionId !== sessionId) {
try {
previous.ws.close(1012, 'Replaced by newer connection')
} catch {
// Ignore close race when the old socket is already gone.
}
}
ocppConnections.set(chargePointIdentifier, { ocppConnections.set(chargePointIdentifier, {
ws, ws,
sessionId, sessionId,
@@ -226,15 +250,24 @@ export function createOcppHandler(chargePointIdentifier: string, remoteAddr?: st
`[OCPP] ${chargePointIdentifier} connected` + `[OCPP] ${chargePointIdentifier} connected` +
(remoteAddr ? ` from ${remoteAddr}` : ''), (remoteAddr ? ` from ${remoteAddr}` : ''),
) )
if (previous && previous.sessionId !== sessionId) {
console.log(`[OCPP] ${chargePointIdentifier} replaced previous connection`)
}
}, },
async onMessage(evt: MessageEvent, ws: WSContext) { async onMessage(evt: MessageEvent, ws: WSContext) {
let uniqueId = '(unknown)' let uniqueId = '(unknown)'
try { try {
const current = ocppConnections.get(chargePointIdentifier) const current = ocppConnections.get(chargePointIdentifier)
if (current) { if (!current || current.sessionId !== sessionId) {
current.lastMessageAt = new Date() try {
ws.close(1008, 'Stale connection')
} catch {
// Ignore close errors on stale sockets.
} }
return
}
current.lastMessageAt = new Date()
const raw = evt.data const raw = evt.data
if (typeof raw !== 'string') return if (typeof raw !== 'string') return

View File

@@ -8,6 +8,7 @@
#include <MicroOcpp.h> #include <MicroOcpp.h>
#include <MicroOcppMongooseClient.h> #include <MicroOcppMongooseClient.h>
#include <MicroOcpp/Core/Context.h> #include <MicroOcpp/Core/Context.h>
#include <MicroOcpp/Core/Configuration.h>
#include <Adafruit_SSD1306.h> #include <Adafruit_SSD1306.h>
#include <SmartLeds.h> #include <SmartLeds.h>
@@ -1201,6 +1202,20 @@ void setup()
{ return s_meter_data_ready ? s_meter_b.powerFactor : 0.0f; }, { return s_meter_data_ready ? s_meter_b.powerFactor : 0.0f; },
"Power.Factor", nullptr, nullptr, nullptr, 2); "Power.Factor", nullptr, nullptr, nullptr, 2);
// MicroOcpp defaults MeterValuesSampledData to Energy + Power only.
// Expand sampled measurands so CSMS can receive voltage/current/PF/frequency/temperature.
static const char *kMeterValuesSampledData =
"Energy.Active.Import.Register,Power.Active.Import,Voltage,Current.Import,Power.Factor,Frequency,Temperature";
if (auto *cfg = MicroOcpp::getConfigurationPublic("MeterValuesSampledData"))
{
cfg->setString(kMeterValuesSampledData);
}
if (auto *cfg = MicroOcpp::getConfigurationPublic("MeterValuesAlignedData"))
{
cfg->setString(kMeterValuesSampledData);
}
MicroOcpp::configuration_save();
// 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(