Files
helios-evcs/apps/csms/src/ocpp/actions/boot-notification.ts

74 lines
2.6 KiB
TypeScript

import { useDrizzle } from '@/lib/db.js'
import dayjs from 'dayjs'
import { chargePoint } from '@/db/schema.js'
import { getOcpp16jSettings } from '@/lib/system-settings.js'
import type {
BootNotificationRequest,
BootNotificationResponse,
OcppConnectionContext,
} from '../types.ts'
export async function handleBootNotification(
payload: BootNotificationRequest,
ctx: OcppConnectionContext,
): Promise<BootNotificationResponse> {
console.info(
`[OCPP][ACTION][BootNotification][BEGIN] cp=${ctx.chargePointIdentifier} vendor=${payload.chargePointVendor} model=${payload.chargePointModel} fw=${payload.firmwareVersion ?? 'n/a'}`,
)
const db = useDrizzle()
const { heartbeatInterval } = await getOcpp16jSettings()
const [cp] = await db
.insert(chargePoint)
.values({
id: crypto.randomUUID(),
chargePointIdentifier: ctx.chargePointIdentifier,
chargePointVendor: payload.chargePointVendor,
chargePointModel: payload.chargePointModel,
chargePointSerialNumber: payload.chargePointSerialNumber ?? null,
firmwareVersion: payload.firmwareVersion ?? null,
iccid: payload.iccid ?? null,
imsi: payload.imsi ?? null,
meterType: payload.meterType ?? null,
meterSerialNumber: payload.meterSerialNumber ?? null,
// New, unknown devices start as Pending — admin must manually accept them
registrationStatus: 'Pending',
heartbeatInterval,
lastBootNotificationAt: dayjs().toDate(),
transportStatus: 'online',
})
.onConflictDoUpdate({
target: chargePoint.chargePointIdentifier,
set: {
chargePointVendor: payload.chargePointVendor,
chargePointModel: payload.chargePointModel,
chargePointSerialNumber: payload.chargePointSerialNumber ?? null,
firmwareVersion: payload.firmwareVersion ?? null,
iccid: payload.iccid ?? null,
imsi: payload.imsi ?? null,
meterType: payload.meterType ?? null,
meterSerialNumber: payload.meterSerialNumber ?? null,
// Do NOT override registrationStatus — preserve whatever the admin set
heartbeatInterval,
lastBootNotificationAt: dayjs().toDate(),
transportStatus: 'online',
updatedAt: dayjs().toDate(),
},
})
.returning()
const status = cp.registrationStatus
ctx.isRegistered = status === 'Accepted'
console.info(
`[OCPP][ACTION][BootNotification][END] cp=${ctx.chargePointIdentifier} status=${status} heartbeatInterval=${heartbeatInterval}`,
)
return {
currentTime: dayjs().toISOString(),
interval: heartbeatInterval,
status,
}
}