@citrineos/data
Version:
The OCPP data module which includes all persistence layer implementation.
168 lines • 7.94 kB
JavaScript
// SPDX-FileCopyrightText: 2025 Contributors to the CitrineOS Project
//
// SPDX-License-Identifier: Apache-2.0
import { SequelizeRepository } from './Base.js';
import { Component, EventData, Variable, VariableMonitoring, VariableMonitoringStatus, } from '../model/index.js';
import { CrudRepository, OCPP2_0_1, OCPP2_0_1_CallAction } from '@citrineos/base';
import { Sequelize } from 'sequelize-typescript';
import { Logger } from 'tslog';
export class SequelizeVariableMonitoringRepository extends SequelizeRepository {
eventData;
variableMonitoringStatus;
constructor(config, logger, sequelizeInstance, eventData, variableMonitoringStatus) {
super(config, VariableMonitoring.MODEL_NAME, logger, sequelizeInstance);
this.eventData = eventData
? eventData
: new SequelizeRepository(config, EventData.MODEL_NAME, logger, sequelizeInstance);
this.variableMonitoringStatus = variableMonitoringStatus
? variableMonitoringStatus
: new SequelizeRepository(config, VariableMonitoringStatus.MODEL_NAME, logger, sequelizeInstance);
}
async createOrUpdateByMonitoringDataTypeAndStationId(tenantId, value, componentId, variableId, stationId) {
return await Promise.all(value.variableMonitoring.map(async (variableMonitoring) => {
const savedVariableMonitoring = await this.s.transaction(async (transaction) => {
const existingVariableMonitoring = await this.s.models[VariableMonitoring.MODEL_NAME].findOne({
where: { stationId, variableId, componentId },
transaction,
});
if (!existingVariableMonitoring) {
// If the record does not exist, build and save a new instance
const vm = VariableMonitoring.build({
tenantId,
stationId,
variableId,
componentId,
...variableMonitoring,
});
const createdVariableMonitoring = await vm.save({ transaction });
this.emit('created', [createdVariableMonitoring]);
return createdVariableMonitoring;
}
else {
// If the record exists, update it
return (await this.updateByKey(tenantId, { ...variableMonitoring }, existingVariableMonitoring.dataValues.databaseId));
}
});
await this.createVariableMonitoringStatus(tenantId, OCPP2_0_1.SetMonitoringStatusEnumType.Accepted, OCPP2_0_1_CallAction.NotifyMonitoringReport, savedVariableMonitoring.get('databaseId'));
return savedVariableMonitoring;
}));
}
async createVariableMonitoringStatus(tenantId, status, action, variableMonitoringId) {
await this.variableMonitoringStatus.create(tenantId, VariableMonitoringStatus.build({
tenantId,
status,
statusInfo: { reasonCode: action },
variableMonitoringId,
}));
}
async createOrUpdateBySetMonitoringDataTypeAndStationId(tenantId, value, componentId, variableId, stationId) {
let result = null;
await this.s.transaction(async (transaction) => {
const savedVariableMonitoring = await this.s.models[VariableMonitoring.MODEL_NAME].findOne({
where: { stationId, variableId, componentId },
transaction,
});
if (!savedVariableMonitoring) {
const variableMonitoring = VariableMonitoring.build({
tenantId,
stationId,
variableId,
componentId,
...value,
});
result = await variableMonitoring.save({ transaction });
this.emit('created', [result]);
}
else {
const updatedVariableMonitoring = await savedVariableMonitoring.update(value, {
transaction,
returning: true,
});
result = updatedVariableMonitoring;
this.emit('updated', [result]);
}
});
if (!result) {
throw new Error('VariableMonitoring could not be created or updated');
}
return result;
}
async rejectAllVariableMonitoringsByStationId(tenantId, action, stationId) {
await this.readAllByQuery(tenantId, {
where: {
stationId,
},
}).then(async (variableMonitorings) => {
for (const variableMonitoring of variableMonitorings) {
await this.createVariableMonitoringStatus(tenantId, OCPP2_0_1.SetMonitoringStatusEnumType.Rejected, action, variableMonitoring.databaseId);
}
});
}
async rejectVariableMonitoringByIdAndStationId(tenantId, action, id, stationId) {
await this.readAllByQuery(tenantId, {
where: {
id,
stationId,
},
}).then(async (variableMonitorings) => {
for (const variableMonitoring of variableMonitorings) {
await this.createVariableMonitoringStatus(tenantId, OCPP2_0_1.SetMonitoringStatusEnumType.Rejected, action, variableMonitoring.databaseId);
}
});
}
async updateResultByStationId(tenantId, result, stationId) {
const savedVariableMonitoring = await super
.readAllByQuery(tenantId, {
where: { stationId, type: result.type, severity: result.severity },
include: [
{
model: Component,
where: {
name: result.component.name,
instance: result.component.instance ? result.component.instance : null,
},
},
{
model: Variable,
where: {
name: result.variable.name,
instance: result.variable.instance ? result.variable.instance : null,
},
},
],
})
.then((variableMonitorings) => variableMonitorings[0]); // TODO: Make sure this uniqueness constraint is actually enforced.
if (savedVariableMonitoring) {
// The Id is only returned from Charging Station when status is accepted.
if (result.status === OCPP2_0_1.SetMonitoringStatusEnumType.Accepted && result.id) {
await this.updateByKey(tenantId, {
id: result.id,
}, savedVariableMonitoring.get('databaseId').toString());
}
await this.variableMonitoringStatus.create(tenantId, VariableMonitoringStatus.build({
tenantId,
status: result.status,
statusInfo: result.statusInfo,
variableMonitoringId: savedVariableMonitoring.get('databaseId'),
}));
// Reload in order to include the statuses
return await this.readAllByQuery(tenantId, {
where: { databaseId: savedVariableMonitoring.get('databaseId') },
include: [VariableMonitoringStatus],
}).then((variableMonitorings) => variableMonitorings[0]);
}
else {
throw new Error(`Unable to update set monitoring result: ${result}`);
}
}
async createEventDatumByComponentIdAndVariableIdAndStationId(tenantId, event, componentId, variableId, stationId) {
return await this.eventData.create(tenantId, EventData.build({
tenantId,
stationId,
variableId,
componentId,
...event,
}));
}
}
//# sourceMappingURL=VariableMonitoring.js.map