import base64ToArrayBuffer from 'base64-arraybuffer'; import { decimalToBitfield, obisCodeValueToNumeric, numericObisFormat, unitConversion } from './binary'; import { ParserError } from './errors'; import { HexingParserBase } from './HexingParserBase'; import { ObisParser } from './ObisParser'; import { ParserResult } from './ParserResult'; import { RegisterModel, SerialNumberModel, TotalActiveEnergyAbsoluteModel, TotalInductiveReactiveEnergyImportModel, TotalActiveEnergyExportModel, } from './registers'; export class HX110HexingParser extends HexingParserBase { hexingHX110CodeToObisMap: [RegisterModel, string][] = [ [SerialNumberModel, 'C.1.0'], [TotalActiveEnergyAbsoluteModel, '15.8.0'], [TotalActiveEnergyExportModel, '2.8.0'], [TotalInductiveReactiveEnergyImportModel, '5.8.0'], ]; anotherPossibleObis: object = { 'C.1.0': 'C.1.0.2', '15.8.0': '1.8.0', }; obisNeedsUnitTransformationOrValidation(aObisCode) { return { obises: ['2.8.0', '5.8.0', '15.8.0'].includes(aObisCode), conversion: 1000, }; } getCodeMapper() { switch (this.interpretationCode) { case 1: return this.hexingHX110CodeToObisMap; default: throw new ParserError('Invalid interpretation code'); } } parse(aBase64String: string, recoverMeterNumber?: Function): ParserResult { const arrayBuffer = new Uint8Array(base64ToArrayBuffer.decode(aBase64String)); const arraySlice = arrayBuffer; const obisParser = new ObisParser(); const obisRegisters = obisParser.parse(arraySlice); if (recoverMeterNumber && obisRegisters.getMeterNumber()) { return recoverMeterNumber(numericObisFormat(obisRegisters.getMeterNumber())); } const result = new ParserResult(); const addValue = (entry: [RegisterModel, string]) => { const [recordModel, targetObis] = entry; let rawValue = obisRegisters.getValueOfObis(targetObis); if (rawValue == null) { const anotherPossibleValue = obisRegisters.getValueOfObis(this.anotherPossibleObis[targetObis]); if (anotherPossibleValue) { rawValue = anotherPossibleValue; } else { result.add(recordModel, null); return; } } let finalValue: any = rawValue; if (recordModel.format === 'numeric') { finalValue = obisCodeValueToNumeric(rawValue); if (this.obisNeedsUnitTransformationOrValidation(targetObis).obises) { const decimals = parseFloat(finalValue) === 0 ? 0 : 4; finalValue = unitConversion( finalValue, this.obisNeedsUnitTransformationOrValidation(targetObis).conversion, decimals, ); } } if (recordModel.format === 'bitfield') { finalValue = decimalToBitfield(rawValue); } if (recordModel.format === 'text') { finalValue = rawValue.trim(); } result.add(recordModel, finalValue); }; const mapperToUse = this.getCodeMapper(); for (const entry of mapperToUse) { addValue(entry); } return result; } }