Compare commits
2 Commits
79a91745c5
...
d688a8497d
| Author | SHA1 | Date | |
|---|---|---|---|
| d688a8497d | |||
| 3bdb3d7351 |
@@ -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
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
Reference in New Issue
Block a user