| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998 |
- 'use strict';
- const {
- parseXML,
- childAttr,
- required,
- boolean,
- dateTime,
- duration,
- number,
- } = require('../parser');
- const { create, fragment } = require('xmlbuilder2');
- const xsiNs = 'http://www.w3.org/2001/XMLSchema-instance';
- const oadrPayloadNs = 'http://www.w3.org/2000/09/xmldsig#';
- const oadrNs = 'http://openadr.org/oadr-2.0b/2012/07';
- const emixNs = 'http://docs.oasis-open.org/ns/emix/2011/06';
- const powerNs = 'http://docs.oasis-open.org/ns/emix/2011/06/power';
- const energyInteropNs = 'http://docs.oasis-open.org/ns/energyinterop/201110';
- const energyInteropPayloadsNs =
- 'http://docs.oasis-open.org/ns/energyinterop/201110/payloads';
- const calendarNs = 'urn:ietf:params:xml:ns:icalendar-2.0';
- const calendarStreamNs = 'urn:ietf:params:xml:ns:icalendar-2.0:stream';
- const siScaleNs = 'http://docs.oasis-open.org/ns/emix/2011/06/siscale';
- const eiTargetMappings = [
- {
- xmlNs: 'power',
- xmlNsUri: powerNs,
- xmlElement: 'endDeviceAsset',
- xmlChildElement: 'mrid',
- json: 'endDeviceAsset',
- },
- {
- xmlNs: 'power',
- xmlNsUri: powerNs,
- xmlElement: 'aggregatedPnode',
- xmlChildElement: 'node',
- json: 'aggregatedPnode',
- },
- {
- xmlNs: 'power',
- xmlNsUri: powerNs,
- xmlElement: 'meterAsset',
- xmlChildElement: 'mrid',
- json: 'meterAsset',
- },
- {
- xmlNs: 'power',
- xmlNsUri: powerNs,
- xmlElement: 'pnode',
- xmlChildElement: 'node',
- json: 'pNode',
- },
- {
- xmlNs: 'power',
- xmlNsUri: powerNs,
- xmlElement: 'serviceDeliveryPoint',
- xmlChildElement: 'node',
- json: 'serviceDeliveryPoint',
- },
- {
- xmlNs: 'ei',
- xmlNsUri: energyInteropNs,
- xmlElement: 'groupID',
- json: 'groupId',
- },
- {
- xmlNs: 'ei',
- xmlNsUri: energyInteropNs,
- xmlElement: 'groupName',
- json: 'groupName',
- },
- {
- xmlNs: 'ei',
- xmlNsUri: energyInteropNs,
- xmlElement: 'resourceID',
- json: 'resourceId',
- },
- {
- xmlNs: 'ei',
- xmlNsUri: energyInteropNs,
- xmlElement: 'venID',
- json: 'venId',
- },
- {
- xmlNs: 'ei',
- xmlNsUri: energyInteropNs,
- xmlElement: 'partyID',
- json: 'partyId',
- },
- ];
- const itemBaseMappings = [
- {
- xmlNs: 'power',
- xmlNsUri: powerNs,
- xmlElement: 'powerReal',
- additionalAttributes: [
- {
- xmlElement: 'powerAttributes',
- json: 'powerAttributes',
- },
- ],
- json: 'powerReal',
- },
- {
- xmlNs: 'power',
- xmlNsUri: powerNs,
- xmlElement: 'powerReactive',
- additionalAttributes: [
- {
- xmlElement: 'powerAttributes',
- json: 'powerAttributes',
- },
- ],
- json: 'powerReactive',
- },
- {
- xmlNs: 'power',
- xmlNsUri: powerNs,
- xmlElement: 'powerApparent',
- additionalAttributes: [
- {
- xmlElement: 'powerAttributes',
- json: 'powerAttributes',
- },
- ],
- json: 'powerApparent',
- },
- {
- xmlNs: 'power',
- xmlNsUri: powerNs,
- xmlElement: 'voltage',
- json: 'voltage',
- },
- {
- xmlNs: 'power',
- xmlNsUri: powerNs,
- xmlElement: 'energyApparent',
- json: 'energyApparent',
- },
- {
- xmlNs: 'power',
- xmlNsUri: powerNs,
- xmlElement: 'energyReactive',
- json: 'energyReactive',
- },
- {
- xmlNs: 'power',
- xmlNsUri: powerNs,
- xmlElement: 'energyReal',
- json: 'energyReal',
- },
- {
- xmlNs: 'oadr',
- xmlNsUri: oadrNs,
- xmlElement: 'currencyPerKWh',
- json: 'currencyPerKWh',
- },
- {
- xmlNs: 'oadr',
- xmlNsUri: oadrNs,
- xmlElement: 'currencyPerKW',
- json: 'currencyPerKW',
- },
- {
- xmlNs: 'oadr',
- xmlNsUri: oadrNs,
- xmlElement: 'currencyPerThm',
- json: 'currencyPerThm',
- },
- {
- xmlNs: 'oadr',
- xmlNsUri: oadrNs,
- xmlElement: 'currency',
- json: 'currency',
- },
- {
- xmlNs: 'oadr',
- xmlNsUri: oadrNs,
- xmlElement: 'current',
- json: 'current',
- },
- {
- xmlNs: 'oadr',
- xmlNsUri: oadrNs,
- xmlElement: 'frequency',
- json: 'frequency',
- },
- {
- xmlNs: 'oadr',
- xmlNsUri: oadrNs,
- xmlElement: 'Therm',
- json: 'therm',
- },
- {
- xmlNs: 'oadr',
- xmlNsUri: oadrNs,
- xmlElement: 'temperature',
- json: 'temperature',
- },
- {
- xmlNs: 'oadr',
- xmlNsUri: oadrNs,
- xmlElement: 'pulseCount',
- json: 'pulseCount',
- },
- {
- xmlNs: 'oadr',
- xmlNsUri: oadrNs,
- xmlElement: 'customUnit',
- json: 'customUnit',
- },
- ];
- function parseItemBase(x) {
- for (const itemBaseMapping of itemBaseMappings) {
- const { json, xmlElement, additionalAttributes } = itemBaseMapping;
- const itemBaseList = x[xmlElement];
- if (itemBaseList) {
- const itemBase = itemBaseList[0]['$$'];
- const result = {
- type: json,
- description: required(
- childAttr(itemBase, 'itemDescription'),
- 'itemDescription',
- ),
- units: required(childAttr(itemBase, 'itemUnits'), 'itemUnits'),
- siScaleCode: required(
- childAttr(itemBase, 'siScaleCode'),
- 'siScaleCode',
- ),
- };
- for (const additionalMapping of additionalAttributes || []) {
- const unNamespacedAdditionalAttribute = additionalMapping.xmlElement;
- const attributesList = itemBase[unNamespacedAdditionalAttribute];
- if (attributesList) {
- const xmlAttributes = attributesList[0]['$$'];
- const attributes = {};
- Object.keys(xmlAttributes).forEach(key => {
- attributes[key] = required(childAttr(xmlAttributes, key), key);
- });
- result[additionalMapping.json] = attributes;
- }
- }
- return result;
- }
- }
- }
- function serializeItemBase(x) {
- for (const itemBaseMapping of itemBaseMappings) {
- const {
- xmlNs,
- xmlNsUri,
- json,
- xmlElement,
- additionalAttributes,
- } = itemBaseMapping;
- if (x.type === json) {
- const result = fragment();
- const innerResult = result.ele(xmlNsUri, `${xmlNs}:${xmlElement}`);
- innerResult.ele(xmlNsUri, xmlNs + ':itemDescription').txt(x.description);
- innerResult.ele(xmlNsUri, xmlNs + ':itemUnits').txt(x.units);
- innerResult.ele(siScaleNs, 'scale:siScaleCode').txt(x.siScaleCode);
- if (additionalAttributes) {
- additionalAttributes.forEach(additionalAttribute => {
- const additionalResult = innerResult.ele(
- xmlNsUri,
- `${xmlNs}:${additionalAttribute.xmlElement}`,
- );
- const additionalJson = x[additionalAttribute.json];
- Object.keys(additionalJson).forEach(key => {
- additionalResult
- .ele(xmlNsUri, `${xmlNs}:${key}`)
- .txt(additionalJson[key]);
- });
- });
- }
- return result;
- }
- }
- }
- function parseEiResponse(response) {
- return {
- code: required(childAttr(response, 'responseCode'), 'responseCode'),
- description: childAttr(response, 'responseDescription'),
- requestId: required(childAttr(response, 'requestID'), 'requestID'),
- };
- }
- function parseEventDescriptor(eventDescriptor) {
- const result = {
- eventId: required(childAttr(eventDescriptor, 'eventID'), 'eventID'),
- modificationNumber: required(
- number(childAttr(eventDescriptor, 'modificationNumber')),
- 'modificationNumber',
- ),
- marketContext: childAttr(
- eventDescriptor.eiMarketContext[0]['$$'],
- 'marketContext',
- ),
- createdDateTime: required(
- childAttr(eventDescriptor, 'createdDateTime'),
- 'createdDateTime',
- ),
- eventStatus: required(
- childAttr(eventDescriptor, 'eventStatus'),
- 'eventStatus',
- ),
- };
- const testEvent = boolean(childAttr(eventDescriptor, 'testEvent'));
- if (testEvent != null) {
- result.testEvent = testEvent;
- }
- const modificationDateTime = childAttr(
- eventDescriptor,
- 'modificationDateTime',
- );
- if (modificationDateTime != null)
- result.modificationDateTime = modificationDateTime;
- const modificationReason = childAttr(eventDescriptor, 'modificationReason');
- if (modificationReason != null)
- result.modificationReason = modificationReason;
- const priority = number(childAttr(eventDescriptor, 'priority'));
- if (priority != null) result.priority = priority;
- const vtnComment = childAttr(eventDescriptor, 'vtnComment');
- if (vtnComment != null) result.vtnComment = vtnComment;
- return result;
- }
- function serializeEventDescriptor(eventDescriptor) {
- const result = fragment();
- const eventDescriptorResult = result.ele(
- energyInteropNs,
- 'ei:eventDescriptor',
- );
- eventDescriptorResult
- .ele(energyInteropNs, 'ei:eventID')
- .txt(eventDescriptor.eventId)
- .up()
- .ele(energyInteropNs, 'ei:modificationNumber')
- .txt(eventDescriptor.modificationNumber)
- .up()
- .ele(energyInteropNs, 'ei:eiMarketContext')
- .ele(emixNs, 'emix:marketContext')
- .txt(eventDescriptor.marketContext)
- .up()
- .up()
- .ele(energyInteropNs, 'ei:createdDateTime')
- .txt(eventDescriptor.createdDateTime)
- .up()
- .ele(energyInteropNs, 'ei:eventStatus')
- .txt(eventDescriptor.eventStatus);
- if (eventDescriptor.testEvent != null) {
- eventDescriptorResult
- .ele(energyInteropNs, 'ei:testEvent')
- .txt(eventDescriptor.testEvent);
- }
- if (eventDescriptor.modificationDateTime != null) {
- eventDescriptorResult
- .ele(energyInteropNs, 'ei:modificationDateTime')
- .txt(eventDescriptor.modificationDateTime);
- }
- if (eventDescriptor.modificationReason != null) {
- eventDescriptorResult
- .ele(energyInteropNs, 'ei:modificationReason')
- .txt(eventDescriptor.modificationReason);
- }
- if (eventDescriptor.priority != null) {
- eventDescriptorResult
- .ele(energyInteropNs, 'ei:priority')
- .txt(eventDescriptor.priority);
- }
- if (eventDescriptor.vtnComment != null) {
- eventDescriptorResult
- .ele(energyInteropNs, 'ei:vtnComment')
- .txt(eventDescriptor.vtnComment);
- }
- return result;
- }
- function parseToleranceTolerateStartAfter(tolerance) {
- if (tolerance) {
- const tolerate = childAttr(tolerance['$$'], 'tolerate');
- if (tolerate) {
- return duration(tolerate, 'startafter');
- }
- }
- }
- function parsePayloadFloat(payloadFloatInput) {
- const payloadFloat = required(
- childAttr(payloadFloatInput, 'payloadFloat'),
- 'payloadFloat',
- )['$$'];
- return required(number(childAttr(payloadFloat, 'value')), 'value');
- }
- function serializePayloadFloat(payloadFloat) {
- const result = fragment();
- result
- .ele(energyInteropNs, 'ei:payloadFloat')
- .ele(energyInteropNs, 'ei:value')
- .txt(payloadFloat);
- return result;
- }
- function serializeSignalPayload(signalPayload) {
- const result = fragment();
- result
- .ele(energyInteropNs, 'ei:signalPayload')
- .import(serializePayloadFloat(signalPayload));
- return result;
- }
- function parseSignalPayloads(signalPayloads) {
- return signalPayloads.map(x => parsePayloadFloat(x['$$']));
- }
- function serializeSignalPayloads(signalPayloads) {
- return signalPayloads.map(x => serializeSignalPayload(x));
- }
- function parseEventSignalInterval(eventSignalInterval) {
- const result = {
- signalPayloads: parseSignalPayloads(eventSignalInterval.signalPayload),
- };
- const durationValue = duration(
- childAttr(eventSignalInterval, 'duration'),
- 'duration',
- );
- if (durationValue != null) result.duration = durationValue;
- const dtStartValue = dateTime(
- childAttr(eventSignalInterval, 'dtstart'),
- 'date-time',
- );
- if (dtStartValue != null) {
- result.startDate = dtStartValue;
- }
- const uidHolder = childAttr(eventSignalInterval, 'uid');
- if (uidHolder != null) {
- result.uid = required(childAttr(uidHolder['$$'], 'text'));
- }
- return result;
- }
- function serializeEventSignalInterval(eventSignalInterval) {
- const result = fragment();
- const interval = result.ele(energyInteropNs, 'ei:interval');
- if (eventSignalInterval.duration) {
- interval
- .ele(calendarNs, 'cal:duration')
- .import(serializeDuration(eventSignalInterval.duration));
- }
- if (eventSignalInterval.startDate) {
- interval
- .ele(calendarNs, 'cal:dtstart')
- .import(serializeDateTime(eventSignalInterval.startDate));
- }
- if (eventSignalInterval.uid) {
- interval
- .ele(calendarNs, 'cal:uid')
- .ele(calendarNs, 'cal:text')
- .txt(eventSignalInterval.uid);
- }
- serializeSignalPayloads(eventSignalInterval.signalPayloads).forEach(payload =>
- interval.import(payload),
- );
- return result;
- }
- function parseEventSignalIntervals(eventSignalIntervals) {
- if (!eventSignalIntervals) {
- return [];
- }
- return eventSignalIntervals['interval'].map(x =>
- parseEventSignalInterval(x['$$']),
- );
- }
- function serializeEventSignalIntervals(eventSignalIntervals) {
- return eventSignalIntervals.map(x => serializeEventSignalInterval(x));
- }
- function parseEiTarget(eiTarget) {
- const result = {};
- for (const eiTargetMapping of eiTargetMappings) {
- const unNamespacedAttribute = eiTargetMapping.xmlElement;
- if (eiTarget[unNamespacedAttribute]) {
- const eiTargetValue = eiTarget[unNamespacedAttribute];
- let newValues;
- if (eiTargetMapping.xmlChildElement) {
- const unNamespacedChildAttribute = eiTargetMapping.xmlChildElement;
- newValues = eiTargetValue[0]['$$'][unNamespacedChildAttribute];
- } else {
- newValues = eiTargetValue;
- }
- const existing = result[eiTargetMapping.json] || [];
- result[eiTargetMapping.json] = [...existing, ...newValues];
- }
- }
- return result;
- }
- function serializeEiTarget(eiTarget) {
- const result = fragment();
- const targetElement = result.ele(energyInteropNs, 'ei:eiTarget');
- for (const eiTargetMapping of eiTargetMappings) {
- if (eiTarget[eiTargetMapping.json]) {
- eiTarget[eiTargetMapping.json].forEach(target => {
- const {
- xmlNs,
- xmlNsUri,
- xmlElement,
- xmlChildElement,
- } = eiTargetMapping;
- if (xmlChildElement) {
- targetElement
- .ele(xmlNsUri, `${xmlNs}:${xmlElement}`)
- .ele(xmlNsUri, `${xmlNs}:${xmlChildElement}`)
- .txt(target);
- } else {
- targetElement.ele(xmlNsUri, `${xmlNs}:${xmlElement}`).txt(target);
- }
- });
- }
- }
- return result;
- }
- function parseEventSignal(eventSignal) {
- const result = {
- intervals: parseEventSignalIntervals(eventSignal['intervals'][0]['$$']),
- signalName: required(childAttr(eventSignal, 'signalName'), 'signalName'),
- signalType: required(childAttr(eventSignal, 'signalType'), 'signalType'),
- signalId: required(childAttr(eventSignal, 'signalID'), 'signalID'),
- };
- const eiTarget = childAttr(eventSignal, 'eiTarget');
- if (eiTarget != null) {
- result.target = parseEiTarget(eiTarget['$$']);
- }
- const currentValue = childAttr(eventSignal, 'currentValue');
- if (currentValue != null)
- result.currentValue = parsePayloadFloat(currentValue['$$']);
- const itemBase = parseItemBase(eventSignal);
- if (itemBase != null) result.itemBase = itemBase;
- return result;
- }
- function serializeEventSignal(eventSignal) {
- const result = fragment();
- const eiEventSignal = result.ele(energyInteropNs, 'ei:eiEventSignal');
- const intervals = eiEventSignal.ele(calendarStreamNs, 'strm:intervals');
- serializeEventSignalIntervals(eventSignal.intervals).forEach(interval =>
- intervals.import(interval),
- );
- eiEventSignal.ele(energyInteropNs, 'ei:signalID').txt(eventSignal.signalId);
- eiEventSignal
- .ele(energyInteropNs, 'ei:signalName')
- .txt(eventSignal.signalName);
- eiEventSignal
- .ele(energyInteropNs, 'ei:signalType')
- .txt(eventSignal.signalType);
- if (eventSignal.target) {
- eiEventSignal.import(serializeEiTarget(eventSignal.target));
- }
- if (eventSignal.currentValue != null) {
- eiEventSignal
- .ele(energyInteropNs, 'ei:currentValue')
- .import(serializePayloadFloat(eventSignal.currentValue));
- }
- if (eventSignal.itemBase != null) {
- eiEventSignal.import(serializeItemBase(eventSignal.itemBase));
- }
- return result;
- }
- function parseEventBaseline(eventSignal) {
- const result = {
- startDate: required(
- dateTime(childAttr(eventSignal, 'dtstart'), 'date-time'),
- 'dtstart',
- ),
- duration: required(
- duration(childAttr(eventSignal, 'duration'), 'duration'),
- 'duration',
- ),
- intervals: parseEventSignalIntervals(eventSignal['intervals'][0]['$$']),
- baselineId: required(childAttr(eventSignal, 'baselineID'), 'baselineID'),
- baselineName: required(
- childAttr(eventSignal, 'baselineName'),
- 'baselineName',
- ),
- };
- const itemBase = parseItemBase(eventSignal);
- if (itemBase != null) result.itemBase = itemBase;
- return result;
- }
- function serializeEventBaseline(eventBaseline) {
- const result = fragment();
- const eiEventBaseline = result.ele(energyInteropNs, 'ei:eiEventBaseline');
- eiEventBaseline
- .ele(energyInteropNs, 'ei:baselineID')
- .txt(eventBaseline.baselineId);
- eiEventBaseline
- .ele(energyInteropNs, 'ei:baselineName')
- .txt(eventBaseline.baselineName);
- if (eventBaseline.duration) {
- eiEventBaseline
- .ele(calendarNs, 'cal:duration')
- .import(serializeDuration(eventBaseline.duration));
- }
- if (eventBaseline.startDate) {
- eiEventBaseline
- .ele(calendarNs, 'cal:dtstart')
- .import(serializeDateTime(eventBaseline.startDate));
- }
- const intervals = eiEventBaseline.ele(calendarStreamNs, 'strm:intervals');
- serializeEventSignalIntervals(eventBaseline.intervals).forEach(interval =>
- intervals.import(interval),
- );
- if (eventBaseline.itemBase != null) {
- eiEventBaseline.import(serializeItemBase(eventBaseline.itemBase));
- }
- return result;
- }
- function parseEiEventSignals(eiEventSignals) {
- const wrappedEventSignals = eiEventSignals.eiEventSignal;
- const wrappedBaselines = eiEventSignals.eiEventBaseline;
- const result = {};
- if (wrappedEventSignals) {
- result.event = wrappedEventSignals.map(x => parseEventSignal(x['$$']));
- }
- if (wrappedBaselines) {
- result.baseline = wrappedBaselines.map(x => parseEventBaseline(x['$$']));
- }
- return result;
- }
- function serializeEiEventSignals(eiEventSignals) {
- const eventSignals = eiEventSignals.event.map(x => serializeEventSignal(x));
- const eventBaselines = eiEventSignals.baseline
- ? eiEventSignals.baseline.map(x => serializeEventBaseline(x))
- : [];
- return [...eventSignals, ...eventBaselines];
- }
- function parseEiActivePeriod(activePeriod) {
- const properties = activePeriod['properties'][0]['$$'];
- const result = {
- startDate: required(
- dateTime(childAttr(properties, 'dtstart'), 'date-time'),
- 'dtstart',
- ),
- duration: required(
- duration(childAttr(properties, 'duration'), 'duration'),
- 'duration',
- ),
- };
- const toleranceTolerateStartAfter = parseToleranceTolerateStartAfter(
- childAttr(properties, 'tolerance'),
- );
- if (toleranceTolerateStartAfter != null) {
- result.toleranceTolerateStartAfter = toleranceTolerateStartAfter;
- }
- const notificationDuration = duration(
- childAttr(properties, 'x-eiNotification'),
- 'duration',
- );
- if (notificationDuration != null) {
- result.notificationDuration = notificationDuration;
- }
- const rampUpDuration = duration(
- childAttr(properties, 'x-eiRampUp'),
- 'duration',
- );
- if (rampUpDuration != null) {
- result.rampUpDuration = rampUpDuration;
- }
- const recoveryDuration = duration(
- childAttr(properties, 'x-eiRecovery'),
- 'duration',
- );
- if (recoveryDuration != null) {
- result.recoveryDuration = recoveryDuration;
- }
- return result;
- }
- function serializeDateTime(dateTime) {
- return fragment()
- .ele(calendarNs, 'cal:date-time')
- .txt(dateTime)
- .up();
- }
- function serializeToleranceTolerateStartAfter(duration) {
- const result = fragment();
- result
- .ele(calendarNs, 'cal:tolerance')
- .ele(calendarNs, 'cal:tolerate')
- .ele(calendarNs, 'cal:startafter')
- .txt(duration);
- return result;
- }
- function serializeActivePeriod(activePeriod) {
- const result = fragment();
- const activePeriodResult = result.ele(energyInteropNs, 'ei:eiActivePeriod');
- const properties = activePeriodResult.ele(calendarNs, 'cal:properties');
- const components = activePeriodResult.ele(calendarNs, 'cal:components');
- components.att(xsiNs, 'xsi:nil', 'true');
- properties
- .ele(calendarNs, 'cal:dtstart')
- .import(serializeDateTime(activePeriod.startDate))
- .up()
- .ele(calendarNs, 'cal:duration')
- .import(serializeDuration(activePeriod.duration))
- .up();
- if (activePeriod.toleranceTolerateStartAfter) {
- properties.import(
- serializeToleranceTolerateStartAfter(
- activePeriod.toleranceTolerateStartAfter,
- ),
- );
- }
- if (activePeriod.notificationDuration) {
- properties
- .ele(energyInteropNs, 'ei:x-eiNotification')
- .import(serializeDuration(activePeriod.notificationDuration));
- }
- if (activePeriod.rampUpDuration) {
- properties
- .ele(energyInteropNs, 'ei:x-eiRampUp')
- .import(serializeDuration(activePeriod.rampUpDuration));
- }
- if (activePeriod.recoveryDuration) {
- properties
- .ele(energyInteropNs, 'ei:x-eiRecovery')
- .import(serializeDuration(activePeriod.recoveryDuration));
- }
- return result;
- }
- function parseEiEvent(eiEvent) {
- return {
- eventDescriptor: parseEventDescriptor(eiEvent.eventDescriptor[0]['$$']),
- activePeriod: parseEiActivePeriod(eiEvent.eiActivePeriod[0]['$$']),
- signals: parseEiEventSignals(eiEvent.eiEventSignals[0]['$$']),
- target: parseEiTarget(eiEvent.eiTarget[0]['$$']),
- };
- }
- function serializeEiEvent(eiEvent) {
- const result = fragment();
- const eiEventResult = result.ele(energyInteropNs, 'ei:eiEvent');
- eiEventResult.import(serializeEventDescriptor(eiEvent.eventDescriptor));
- eiEventResult.import(serializeActivePeriod(eiEvent.activePeriod));
- const eiEventSignals = eiEventResult.ele(
- energyInteropNs,
- 'ei:eiEventSignals',
- );
- serializeEiEventSignals(eiEvent.signals).forEach(signal =>
- eiEventSignals.import(signal),
- );
- if (eiEvent.target) {
- eiEventResult.import(serializeEiTarget(eiEvent.target));
- }
- return result;
- }
- function parseEvents(eventList) {
- const events = [];
- for (const wrappedEvent of eventList) {
- const event = wrappedEvent['$$'];
- const parsedEiEvent = parseEiEvent(event.eiEvent[0]['$$']);
- parsedEiEvent.responseRequired = childAttr(event, 'oadrResponseRequired');
- events.push(parsedEiEvent);
- }
- return events;
- }
- async function parse(input) {
- const json = await parseXML(input);
- const o =
- json['oadrPayload']['$$']['oadrSignedObject'][0]['$$'][
- 'oadrDistributeEvent'
- ][0]['$$'];
- const result = {
- _type: 'oadrDistributeEvent',
- };
- if (o['eiResponse']) {
- const { code, description, requestId } = parseEiResponse(
- o['eiResponse'][0]['$$'],
- );
- result.responseCode = code;
- result.responseRequestId = requestId;
- if (description != null) result.responseDescription = description;
- if (code < 200 || code >= 300) {
- return result;
- }
- }
- const payloadRequestId = childAttr(o, 'requestID');
- if (payloadRequestId != null) result.requestId = payloadRequestId;
- result.vtnId = required(childAttr(o, 'vtnID'), 'vtnID');
- const events = parseEvents(o['oadrEvent'] || []);
- result.events = events;
- return result;
- }
- function serializeEiResponse(code, description, requestId) {
- const descriptionFrag =
- description != null
- ? fragment()
- .ele(energyInteropNs, 'ei:responseDescription')
- .txt(description)
- : fragment();
- return fragment()
- .ele(energyInteropNs, 'ei:responseCode')
- .txt(code)
- .up()
- .import(descriptionFrag)
- .ele(energyInteropPayloadsNs, 'pyld:requestID')
- .txt(requestId)
- .up();
- }
- function serializeDuration(duration) {
- return duration != null
- ? fragment()
- .ele(calendarNs, 'cal:duration')
- .txt(duration)
- : fragment();
- }
- function validate(obj) {
- if (obj.responseCode == null) {
- throw new Error('Missing responseCode');
- }
- if (obj.responseRequestId == null) {
- throw new Error('Missing responseRequestId');
- }
- }
- function serializeOadrEvent(event) {
- const result = fragment();
- const oadrEvent = result.ele(oadrNs, 'oadr2b:oadrEvent');
- oadrEvent.import(serializeEiEvent(event));
- oadrEvent
- .ele(oadrNs, 'oadr2b:oadrResponseRequired')
- .txt(event.responseRequired);
- return result;
- }
- function serializeEvents(events) {
- const result = fragment();
- events.forEach(event => {
- result.import(serializeOadrEvent(event));
- });
- return result;
- }
- function serialize(obj) {
- validate(obj);
- const vtnId =
- obj.vtnId != null
- ? fragment()
- .ele(energyInteropNs, 'ei:vtnID')
- .txt(obj.vtnId)
- : fragment();
- const requestId =
- obj.requestId != null
- ? fragment()
- .ele(oadrPayloadNs, 'pyld:requestID')
- .txt(obj.requestId)
- : fragment();
- const doc = create({
- namespaceAlias: {
- ns: oadrPayloadNs,
- oadr2b: oadrNs,
- ei: energyInteropNs,
- pyld: energyInteropPayloadsNs,
- cal: calendarNs,
- },
- })
- .ele('@oadr2b', 'oadr2b:oadrPayload')
- .ele('oadr2b:oadrSignedObject')
- .ele('oadr2b:oadrDistributeEvent')
- .att('@ei', 'ei:schemaVersion', '2.0b')
- .ele('@ei', 'ei:eiResponse')
- .import(
- serializeEiResponse(
- obj.responseCode,
- obj.responseDescription,
- obj.responseRequestId,
- ),
- )
- .up()
- .import(vtnId)
- .import(requestId)
- .import(serializeEvents(obj.events))
- .doc();
- return doc.end({ headless: true, prettyPrint: false });
- }
- async function canParse(input) {
- const json = await parseXML(input);
- const o = json['oadrPayload']['$$']['oadrSignedObject'][0]['$$'];
- return o['oadrDistributeEvent'] != null;
- }
- module.exports = {
- parse,
- serialize,
- canParse,
- };
|