oadr-response.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. 'use strict';
  2. const { parseXML, childAttr, required } = 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. const result = {
  11. code: required(childAttr(response, 'responseCode'), 'responseCode'),
  12. description: childAttr(response, 'responseDescription'),
  13. };
  14. const requestId = childAttr(response, 'requestID');
  15. if (requestId != null) {
  16. result.requestId = requestId;
  17. }
  18. return result;
  19. }
  20. async function parse(input) {
  21. const json = await parseXML(input);
  22. const o =
  23. json['oadrPayload']['$$']['oadrSignedObject'][0]['$$']['oadrResponse'][0][
  24. '$$'
  25. ];
  26. const { code, description, requestId } = parseEiResponse(
  27. o['eiResponse'][0]['$$'],
  28. );
  29. const result = {
  30. _type: 'oadrResponse',
  31. responseCode: code,
  32. responseDescription: description,
  33. responseRequestId: requestId,
  34. };
  35. if (code < 200 || code >= 300) {
  36. return result;
  37. }
  38. const venId = childAttr(o, 'venID');
  39. if (venId != null) result.venId = venId;
  40. return result;
  41. }
  42. function serializeEiResponse(code, description, requestId) {
  43. const descriptionFrag =
  44. description != null
  45. ? fragment()
  46. .ele(energyInteropNs, 'ei:responseDescription')
  47. .txt(description)
  48. : fragment();
  49. return fragment()
  50. .ele(energyInteropNs, 'ei:responseCode')
  51. .txt(code)
  52. .up()
  53. .import(descriptionFrag)
  54. .ele(energyInteropPayloadsNs, 'pyld:requestID')
  55. .txt(requestId || '')
  56. .up();
  57. }
  58. function validate(obj) {
  59. if (!obj.responseCode) {
  60. throw new Error('Missing responseCode');
  61. }
  62. }
  63. function serialize(obj) {
  64. validate(obj);
  65. const venId =
  66. obj.venId != null
  67. ? fragment()
  68. .ele(energyInteropNs, 'ei:venID')
  69. .txt(obj.venId)
  70. : fragment();
  71. const doc = create({
  72. namespaceAlias: {
  73. ns: oadrPayloadNs,
  74. oadr2b: oadrNs,
  75. ei: energyInteropNs,
  76. pyld: energyInteropPayloadsNs,
  77. },
  78. })
  79. .ele('@oadr2b', 'oadr2b:oadrPayload')
  80. .ele('oadr2b:oadrSignedObject')
  81. .ele('oadr2b:oadrResponse')
  82. .att('@ei', 'ei:schemaVersion', '2.0b')
  83. .ele('@ei', 'ei:eiResponse')
  84. .import(
  85. serializeEiResponse(
  86. obj.responseCode,
  87. obj.responseDescription,
  88. obj.responseRequestId,
  89. ),
  90. )
  91. .up()
  92. .import(venId)
  93. .doc();
  94. return doc.end({ headless: true, prettyPrint: false });
  95. }
  96. module.exports = {
  97. parse,
  98. serialize,
  99. };