created-event.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. 'use strict';
  2. const { parseXML, childAttr, required, number } = require('../parser');
  3. const { create, fragment } = require('xmlbuilder2');
  4. const oadrPayloadNs = 'http://www.w3.org/2000/09/xmldsig#';
  5. const oadrNs = 'http://openadr.org/oadr-2.0b/2012/07';
  6. const energyInteropNs = 'http://docs.oasis-open.org/ns/energyinterop/201110';
  7. const energyInteropPayloadsNs =
  8. 'http://docs.oasis-open.org/ns/energyinterop/201110/payloads';
  9. function parseEiResponse(response) {
  10. return {
  11. code: required(childAttr(response, 'responseCode'), 'responseCode'),
  12. description: childAttr(response, 'responseDescription'),
  13. requestId: required(childAttr(response, 'requestID'), 'requestID'),
  14. };
  15. }
  16. function parseEventResponse(eventResponse) {
  17. const result = {
  18. responseCode: required(
  19. childAttr(eventResponse, 'responseCode'),
  20. 'responseCode',
  21. ),
  22. responseRequestId: required(
  23. childAttr(eventResponse, 'requestID'),
  24. 'requestID',
  25. ),
  26. optType: required(childAttr(eventResponse, 'optType'), 'optType'),
  27. eventId: required(
  28. childAttr(eventResponse['qualifiedEventID'][0]['$$'], 'eventID'),
  29. 'qualifiedEventID.eventID',
  30. ),
  31. modificationNumber: required(
  32. number(
  33. childAttr(
  34. eventResponse['qualifiedEventID'][0]['$$'],
  35. 'modificationNumber',
  36. ),
  37. ),
  38. 'qualifiedEventID.modificationNumber',
  39. ),
  40. };
  41. const responseDescription = childAttr(eventResponse, 'responseDescription');
  42. if (responseDescription != null)
  43. result.responseDescription = responseDescription;
  44. return result;
  45. }
  46. function parseEventResponses(eventResponses) {
  47. if (eventResponses['$$'] == null) {
  48. return [];
  49. }
  50. const unwrappedEventResponses = eventResponses['$$']['eventResponse'];
  51. return unwrappedEventResponses.map(x => parseEventResponse(x['$$']));
  52. }
  53. function parseEiCreatedEvent(eiCreatedEvent) {
  54. const { code, description, requestId } = parseEiResponse(
  55. eiCreatedEvent['eiResponse'][0]['$$'],
  56. );
  57. const result = {
  58. _type: 'oadrCreatedEvent',
  59. responseCode: code,
  60. responseRequestId: requestId,
  61. venId: required(childAttr(eiCreatedEvent, 'venID'), 'venID'),
  62. };
  63. if (description != null) result.responseDescription = description;
  64. const eventResponses = childAttr(eiCreatedEvent, 'eventResponses');
  65. if (eventResponses != null)
  66. result.eventResponses = parseEventResponses(eventResponses);
  67. return result;
  68. }
  69. async function parse(input) {
  70. const json = await parseXML(input);
  71. const o =
  72. json['oadrPayload']['$$']['oadrSignedObject'][0]['$$'][
  73. 'oadrCreatedEvent'
  74. ][0]['$$'];
  75. return parseEiCreatedEvent(o['eiCreatedEvent'][0]['$$']);
  76. }
  77. function serializeEiResponse(eiCreatedEvent) {
  78. const descriptionFrag =
  79. eiCreatedEvent.responseDescription != null
  80. ? fragment()
  81. .ele(energyInteropNs, 'ei:responseDescription')
  82. .txt(eiCreatedEvent.responseDescription)
  83. : fragment();
  84. return fragment()
  85. .ele(energyInteropNs, 'ei:eiResponse')
  86. .ele(energyInteropNs, 'ei:responseCode')
  87. .txt(eiCreatedEvent.responseCode)
  88. .up()
  89. .import(descriptionFrag)
  90. .ele(energyInteropPayloadsNs, 'pyld:requestID')
  91. .txt(eiCreatedEvent.responseRequestId)
  92. .up()
  93. .up();
  94. }
  95. function serializeEventResponse(eventResponse) {
  96. const descriptionFrag =
  97. eventResponse.responseDescription != null
  98. ? fragment()
  99. .ele(energyInteropNs, 'ei:responseDescription')
  100. .txt(eventResponse.responseDescription)
  101. : fragment();
  102. return fragment()
  103. .ele(energyInteropNs, 'ei:eventResponse')
  104. .ele(energyInteropNs, 'ei:responseCode')
  105. .txt(eventResponse.responseCode)
  106. .up()
  107. .import(descriptionFrag)
  108. .ele(energyInteropPayloadsNs, 'pyld:requestID')
  109. .txt(eventResponse.responseRequestId)
  110. .up()
  111. .ele(energyInteropNs, 'ei:optType')
  112. .txt(eventResponse.optType)
  113. .up()
  114. .ele(energyInteropNs, 'ei:qualifiedEventID')
  115. .ele(energyInteropNs, 'ei:eventID')
  116. .txt(eventResponse.eventId)
  117. .up()
  118. .ele(energyInteropNs, 'ei:modificationNumber')
  119. .txt(eventResponse.modificationNumber)
  120. .up()
  121. .up();
  122. }
  123. function serializeEventResponses(eventResponses) {
  124. const result = fragment();
  125. const responsesHolder = result.ele(energyInteropNs, 'ei:eventResponses');
  126. eventResponses.forEach(x =>
  127. responsesHolder.import(serializeEventResponse(x)),
  128. );
  129. return result;
  130. }
  131. function serializeEiCreatedEvent(eiCreatedEvent) {
  132. const result = fragment();
  133. const eiCreatedEventHolder = result.ele(oadrPayloadNs, 'pyld:eiCreatedEvent');
  134. eiCreatedEventHolder.import(serializeEiResponse(eiCreatedEvent));
  135. eiCreatedEventHolder.import(
  136. serializeEventResponses(eiCreatedEvent.eventResponses),
  137. );
  138. if (eiCreatedEvent.venId != null) {
  139. eiCreatedEventHolder
  140. .ele(energyInteropNs, 'ei:venID')
  141. .txt(eiCreatedEvent.venId);
  142. }
  143. return result;
  144. }
  145. function serialize(obj) {
  146. const doc = create({
  147. namespaceAlias: {
  148. ns: oadrPayloadNs,
  149. oadr2b: oadrNs,
  150. ei: energyInteropNs,
  151. pyld: energyInteropPayloadsNs,
  152. },
  153. })
  154. .ele('@oadr2b', 'oadr2b:oadrPayload')
  155. .ele('oadr2b:oadrSignedObject')
  156. .ele('oadr2b:oadrCreatedEvent')
  157. .import(serializeEiCreatedEvent(obj))
  158. .doc();
  159. return doc.end({ headless: true, prettyPrint: false });
  160. }
  161. async function canParse(input) {
  162. const json = await parseXML(input);
  163. const o = json['oadrPayload']['$$']['oadrSignedObject'][0]['$$'];
  164. return o['oadrCreatedEvent'] != null;
  165. }
  166. module.exports = {
  167. parse,
  168. serialize,
  169. canParse,
  170. };