95 lines
2.9 KiB
JavaScript
Executable File
95 lines
2.9 KiB
JavaScript
Executable File
// src/mqtt/handlers/meter.handler.js
|
|
async function handleStateMeter(ctx, mqttTopic, payload, meterKind /* 'evse'|'grid' */) {
|
|
const charger = await ctx.getChargerByMqttTopic(mqttTopic);
|
|
if (!charger) {
|
|
console.warn(`[MQTT] Charger não encontrado para topic: ${mqttTopic}`);
|
|
return;
|
|
}
|
|
|
|
const chargerId = charger.id;
|
|
const now = new Date();
|
|
|
|
const vrms = ctx.toArr3(payload?.vrms); // 2 casas
|
|
const irms = ctx.toArr3(payload?.irms); // 2 casas
|
|
|
|
// watt em W -> kW com 2 casas
|
|
const wattKw = ctx.toArr3Kw2(payload?.watt);
|
|
|
|
const totalEnergy = ctx.round2(payload?.totalEnergy); // kWh acumulado (2 casas)
|
|
const source = String(payload?.source || meterKind || '').toUpperCase();
|
|
|
|
if (Number.isFinite(totalEnergy) && totalEnergy >= 0) {
|
|
ctx.lastTotalEnergyByChargerId.set(chargerId, totalEnergy);
|
|
}
|
|
|
|
if (meterKind === 'evse' || source === 'EVSE') {
|
|
const dbUpdate = {
|
|
consumption: totalEnergy,
|
|
charging_current: ctx.round2(irms[0]),
|
|
|
|
power_l1: wattKw[0],
|
|
power_l2: wattKw[1],
|
|
power_l3: wattKw[2],
|
|
|
|
voltage_l1: vrms[0],
|
|
voltage_l2: vrms[1],
|
|
voltage_l3: vrms[2],
|
|
|
|
current_l1: irms[0],
|
|
current_l2: irms[1],
|
|
current_l3: irms[2],
|
|
|
|
updated_at: now.toISOString(),
|
|
};
|
|
|
|
await ctx.updateChargerDbIfChanged(chargerId, dbUpdate);
|
|
|
|
// atualiza sessão ativa com delta (sem fechar)
|
|
const currentlyEnabled = ctx.lastEnabled[chargerId] || false;
|
|
if (currentlyEnabled) {
|
|
const session = await ctx.db('charger_sessions')
|
|
.where({ charger_id: chargerId })
|
|
.whereNull('ended_at')
|
|
.first();
|
|
|
|
if (session) {
|
|
const startEnergy = ctx.sessionStartEnergyByChargerId.get(chargerId) ?? 0;
|
|
const delta = Math.max(
|
|
0,
|
|
ctx.round2((ctx.lastTotalEnergyByChargerId.get(chargerId) ?? 0) - startEnergy)
|
|
);
|
|
|
|
await ctx.db('charger_sessions').where({ id: session.id }).update({ kwh: delta });
|
|
}
|
|
}
|
|
|
|
const meta = ctx.lastMetaByChargerId.get(chargerId) || { status: '—', stateCode: undefined };
|
|
ctx.emitter.emit('charging-status', {
|
|
charger_id: chargerId,
|
|
mqtt_topic: mqttTopic,
|
|
status: meta.status,
|
|
stateCode: meta.stateCode,
|
|
consumption: totalEnergy,
|
|
chargingTime: 0,
|
|
power: wattKw,
|
|
voltage: vrms,
|
|
current: irms,
|
|
raw: payload,
|
|
});
|
|
}
|
|
|
|
ctx.emitter.emit('meter-live', {
|
|
charger_id: chargerId,
|
|
mqtt_topic: mqttTopic,
|
|
meter: meterKind,
|
|
vrms,
|
|
irms,
|
|
watt: wattKw,
|
|
totalEnergy,
|
|
raw: payload,
|
|
updated_at: now.toISOString(),
|
|
});
|
|
}
|
|
|
|
module.exports = { handleStateMeter };
|