@machinemetrics/io-adapter-lib 2.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. package/.circleci/config.yml +141 -0
  2. package/.eslintrc.json +36 -0
  3. package/.gitattributes +12 -0
  4. package/CHANGELOG.md +544 -0
  5. package/README.md +2 -0
  6. package/index.js +17 -0
  7. package/lib/config/adapterConfig.js +535 -0
  8. package/lib/config/common/allowDenyList.js +58 -0
  9. package/lib/config/common/jsonPath.js +44 -0
  10. package/lib/config/common/labjackU3T4Common.js +227 -0
  11. package/lib/config/common/validations.js +142 -0
  12. package/lib/config/configError.js +32 -0
  13. package/lib/config/device/adam-6052Config.js +103 -0
  14. package/lib/config/device/brotherHTTPConfig.js +215 -0
  15. package/lib/config/device/ethernetIPConfig.js +191 -0
  16. package/lib/config/device/ifmIotConfig.js +245 -0
  17. package/lib/config/device/jsonHttpConfig.js +76 -0
  18. package/lib/config/device/labjackT4Config.js +39 -0
  19. package/lib/config/device/labjackT7Config.js +192 -0
  20. package/lib/config/device/labjackU3Config.js +32 -0
  21. package/lib/config/device/modbusTcpConfig.js +336 -0
  22. package/lib/config/device/mqttBaseConfig.js +70 -0
  23. package/lib/config/device/mqttConfig.js +113 -0
  24. package/lib/config/device/mqttLincolnConfig.js +62 -0
  25. package/lib/config/device/mtconnectAdapterConfig.js +42 -0
  26. package/lib/config/device/mtconnectBaseConfig.js +136 -0
  27. package/lib/config/device/mtconnectConfig.js +52 -0
  28. package/lib/config/device/mtconnectHaasConfig.js +15 -0
  29. package/lib/config/device/nullConfig.js +81 -0
  30. package/lib/config/device/opcuaConfig.js +205 -0
  31. package/lib/config/device/pcccConfig.js +88 -0
  32. package/lib/config/engineConfigV1.js +382 -0
  33. package/lib/config/engineConfigV2.js +106 -0
  34. package/lib/config/generator/counterGenConfig.js +15 -0
  35. package/lib/config/generator/cronGenConfig.js +33 -0
  36. package/lib/config/generator/dateTimeGenConfig.js +33 -0
  37. package/lib/config/index.js +339 -0
  38. package/lib/config/transformConfigUtil.js +296 -0
  39. package/lib/engine/dataOutput.js +357 -0
  40. package/lib/engine/deviceOutput.js +186 -0
  41. package/lib/engine/engineV1.js +480 -0
  42. package/lib/engine/engineV2.js +719 -0
  43. package/lib/engine/index.js +34 -0
  44. package/lib/engine/transformBuilderV1.js +111 -0
  45. package/lib/engine/transformBuilderV2.js +74 -0
  46. package/lib/expressionService.js +330 -0
  47. package/lib/math.js +142 -0
  48. package/lib/transform/accumulate.js +98 -0
  49. package/lib/transform/average.js +56 -0
  50. package/lib/transform/debounce.js +152 -0
  51. package/lib/transform/downsample.js +69 -0
  52. package/lib/transform/edge.js +34 -0
  53. package/lib/transform/expression.js +91 -0
  54. package/lib/transform/fallingEdge.js +70 -0
  55. package/lib/transform/fromBuffer.js +89 -0
  56. package/lib/transform/hash.js +41 -0
  57. package/lib/transform/ignoreValue.js +118 -0
  58. package/lib/transform/index.js +93 -0
  59. package/lib/transform/invert.js +25 -0
  60. package/lib/transform/latch.js +99 -0
  61. package/lib/transform/latchValue.js +115 -0
  62. package/lib/transform/logicAnd.js +67 -0
  63. package/lib/transform/logicOr.js +67 -0
  64. package/lib/transform/map.js +115 -0
  65. package/lib/transform/max.js +57 -0
  66. package/lib/transform/maxLength.js +39 -0
  67. package/lib/transform/min.js +57 -0
  68. package/lib/transform/minDelta.js +40 -0
  69. package/lib/transform/offDelay.js +89 -0
  70. package/lib/transform/onDelay.js +89 -0
  71. package/lib/transform/patternEscape.js +24 -0
  72. package/lib/transform/patternMatch.js +194 -0
  73. package/lib/transform/patternReplace.js +170 -0
  74. package/lib/transform/patternTest.js +85 -0
  75. package/lib/transform/rateOfChange.js +56 -0
  76. package/lib/transform/reject.js +115 -0
  77. package/lib/transform/resample.js +96 -0
  78. package/lib/transform/risingEdge.js +90 -0
  79. package/lib/transform/risingEdgeCounter.js +179 -0
  80. package/lib/transform/sampleInterval.js +12 -0
  81. package/lib/transform/source.js +116 -0
  82. package/lib/transform/state.js +201 -0
  83. package/lib/transform/threshold.js +52 -0
  84. package/lib/transform/toBuffer.js +159 -0
  85. package/lib/transform/toggle.js +118 -0
  86. package/lib/transform/transformState.js +193 -0
  87. package/lib/transform/trim.js +27 -0
  88. package/lib/transform/util/chainSource.js +96 -0
  89. package/lib/transform/util/ringBuffer.js +34 -0
  90. package/lib/transform/valueChange.js +34 -0
  91. package/lib/transform/valueDecrease.js +38 -0
  92. package/lib/transform/valueIncrease.js +38 -0
  93. package/lib/transform/valueIncreaseDiff.js +66 -0
  94. package/lib/transform/whenUnavailable.js +73 -0
  95. package/lib/transform/windowCount.js +86 -0
  96. package/lib/util/fileUtil.js +44 -0
  97. package/package.json +38 -0
  98. package/test/.eslintrc.json +15 -0
  99. package/test/chainedTransform.test.js +88 -0
  100. package/test/conditions.test.js +118 -0
  101. package/test/config/ab-pccc.test.js +41 -0
  102. package/test/config/adam-6052.test.js +16 -0
  103. package/test/config/adapter.test.js +109 -0
  104. package/test/config/brother-http.test.js +19 -0
  105. package/test/config/ethernet-ip.test.js +19 -0
  106. package/test/config/ifm-iot.test.js +20 -0
  107. package/test/config/json-http.test.js +47 -0
  108. package/test/config/labjack-t4.test.js +78 -0
  109. package/test/config/labjack-t7.test.js +18 -0
  110. package/test/config/labjack-u3.test.js +17 -0
  111. package/test/config/modbusTcp.test.js +87 -0
  112. package/test/config/mqtt.test.js +19 -0
  113. package/test/config/mqttLincoln.test.js +29 -0
  114. package/test/config/mtconnect.test.js +63 -0
  115. package/test/config/mtconnectAdapter.test.js +124 -0
  116. package/test/config/mtconnectHaas.test.js +15 -0
  117. package/test/config/null.test.js +16 -0
  118. package/test/config/opcua.test.js +97 -0
  119. package/test/config-tests.js +102 -0
  120. package/test/configFiles/conditions.yml +37 -0
  121. package/test/configFiles/data-items-legacy.yml +24 -0
  122. package/test/configFiles/data-items-shorthand.yml +14 -0
  123. package/test/configFiles/data-items.yml +12 -0
  124. package/test/configFiles/device/ab-pccc-default.yml +3 -0
  125. package/test/configFiles/device/ab-pccc-full.yml +13 -0
  126. package/test/configFiles/device/adam-6052-default.yml +2 -0
  127. package/test/configFiles/device/brother-http-default.yml +3 -0
  128. package/test/configFiles/device/ethernet-ip-default.yml +2 -0
  129. package/test/configFiles/device/ifm-iot-default.yml +2 -0
  130. package/test/configFiles/device/json-http-bad-prop.yml +13 -0
  131. package/test/configFiles/device/json-http-bad-prop2.yml +13 -0
  132. package/test/configFiles/device/json-http-default.yml +3 -0
  133. package/test/configFiles/device/json-http-std.yml +13 -0
  134. package/test/configFiles/device/labjack-t4-condition-exprs.yaml +46 -0
  135. package/test/configFiles/device/labjack-t4-default.yml +3 -0
  136. package/test/configFiles/device/labjack-t4-pins-alt.yaml +41 -0
  137. package/test/configFiles/device/labjack-t4-pins.yaml +40 -0
  138. package/test/configFiles/device/labjack-t4-v1.yaml +29 -0
  139. package/test/configFiles/device/labjack-t7-default.yml +2 -0
  140. package/test/configFiles/device/labjack-u3-default.yml +2 -0
  141. package/test/configFiles/device/modbus-partial.yml +4 -0
  142. package/test/configFiles/device/modbus-std-extended.yaml +23 -0
  143. package/test/configFiles/device/modbus-std.yaml +34 -0
  144. package/test/configFiles/device/modbus-tcp-default.yml +3 -0
  145. package/test/configFiles/device/mqtt-default.yml +2 -0
  146. package/test/configFiles/device/mqtt-lincoln-default.yml +3 -0
  147. package/test/configFiles/device/mqtt-lincoln-full.yml +7 -0
  148. package/test/configFiles/device/mtconnect-adapter-default.yml +3 -0
  149. package/test/configFiles/device/mtconnect-adapter-keys.yaml +18 -0
  150. package/test/configFiles/device/mtconnect-complex-keys.yaml +17 -0
  151. package/test/configFiles/device/mtconnect-default.yml +3 -0
  152. package/test/configFiles/device/mtconnect-duplicate-allow-keys.yaml +10 -0
  153. package/test/configFiles/device/mtconnect-duplicate-declare-keys.yaml +8 -0
  154. package/test/configFiles/device/mtconnect-duplicate-deny-keys.yaml +10 -0
  155. package/test/configFiles/device/mtconnect-haas-default.yml +3 -0
  156. package/test/configFiles/device/mtconnect-std.yaml +18 -0
  157. package/test/configFiles/device/null-default.yml +1 -0
  158. package/test/configFiles/device/opcua-bad-tag.yml +18 -0
  159. package/test/configFiles/device/opcua-bad-tag2.yml +18 -0
  160. package/test/configFiles/device/opcua-default.yml +3 -0
  161. package/test/configFiles/device/opcua-std.yml +18 -0
  162. package/test/configFiles/dump-test.yml +11 -0
  163. package/test/configFiles/expressionCond.yml +46 -0
  164. package/test/configFiles/min-config-t4.yaml +4 -0
  165. package/test/configFiles/min-config-u3.yaml +3 -0
  166. package/test/configFiles/missing-device.yaml +2 -0
  167. package/test/configFiles/parse-error1.yml +9 -0
  168. package/test/configFiles/parse-error2.yml +9 -0
  169. package/test/configFiles/repro/buffer-convert-repro.yml +15 -0
  170. package/test/configFiles/repro/chained-delay-timing-repro.yml +13 -0
  171. package/test/configFiles/repro/count-init-repro.yml +45 -0
  172. package/test/configFiles/repro/cycle-break-repro.yml +44 -0
  173. package/test/configFiles/repro/debounce-repro.yml +46 -0
  174. package/test/configFiles/repro/diff-count-repro.yml +34 -0
  175. package/test/configFiles/repro/engine-hang-repro.yml +9 -0
  176. package/test/configFiles/repro/latch-apm-repro.yml +26 -0
  177. package/test/configFiles/repro/lockout-count-repro.yml +33 -0
  178. package/test/configFiles/repro/program-extract-repro.yml +38 -0
  179. package/test/configFiles/repro/state-latch-repro.yml +47 -0
  180. package/test/configFiles/repro/ternary-repro.yml +26 -0
  181. package/test/configFiles/transform/debounce.yml +12 -0
  182. package/test/configFiles/transform/expression.yml +34 -0
  183. package/test/configFiles/transform/ignoreValue.yml +31 -0
  184. package/test/configFiles/transform/latch.yml +11 -0
  185. package/test/configFiles/transform/latchValue.yml +31 -0
  186. package/test/configFiles/transform/logicAnd.yml +14 -0
  187. package/test/configFiles/transform/logicOr.yml +14 -0
  188. package/test/configFiles/transform/map.yml +19 -0
  189. package/test/configFiles/transform/maxLength.yml +13 -0
  190. package/test/configFiles/transform/offDelay.yml +12 -0
  191. package/test/configFiles/transform/pattern-escape.yml +10 -0
  192. package/test/configFiles/transform/pattern-match.yml +57 -0
  193. package/test/configFiles/transform/pattern-replace.yml +34 -0
  194. package/test/configFiles/transform/pattern-test.yml +25 -0
  195. package/test/configFiles/transform/reject.yml +24 -0
  196. package/test/configFiles/transform/risingEdgeCounter.yml +36 -0
  197. package/test/configFiles/transform/source.yml +20 -0
  198. package/test/configFiles/transform/state.yml +56 -0
  199. package/test/configFiles/transform/toggle.yml +19 -0
  200. package/test/configFiles/transform/whenUnavailable.yml +19 -0
  201. package/test/dataFiles/noisy-pulse.txt +11330 -0
  202. package/test/dataItems.test.js +140 -0
  203. package/test/engine-v1-tests.js +418 -0
  204. package/test/engine-v2-tests.js +284 -0
  205. package/test/expression-tests.js +171 -0
  206. package/test/expressionService.test.js +154 -0
  207. package/test/expressionServiceCondition.test.js +130 -0
  208. package/test/repro/buffer-convert-repro.test.js +38 -0
  209. package/test/repro/chained-delay-timing-repro.test.js +34 -0
  210. package/test/repro/count-init-repro.test.js +46 -0
  211. package/test/repro/cylce-break-repro.test.js +57 -0
  212. package/test/repro/debounce-repro.test.js +65 -0
  213. package/test/repro/diff-count-repro.test.js +79 -0
  214. package/test/repro/engine-hang-repro.test.js +38 -0
  215. package/test/repro/latch-apm-repro.test.js +119 -0
  216. package/test/repro/lockout-count-repro.test.js +84 -0
  217. package/test/repro/program-extract-repro.test.js +40 -0
  218. package/test/repro/state-latch-repro.test.js +63 -0
  219. package/test/repro/ternary-repro.test.js +43 -0
  220. package/test/transform/accumulte.test.js +18 -0
  221. package/test/transform/average.test.js +22 -0
  222. package/test/transform/debounce.test.js +70 -0
  223. package/test/transform/downsample.test.js +30 -0
  224. package/test/transform/edge.test.js +27 -0
  225. package/test/transform/expression.test.js +189 -0
  226. package/test/transform/fallingEdge.test.js +59 -0
  227. package/test/transform/fromBuffer.test.js +60 -0
  228. package/test/transform/hash.test.js +34 -0
  229. package/test/transform/ignoreValue.test.js +123 -0
  230. package/test/transform/invert.test.js +26 -0
  231. package/test/transform/latch.test.js +33 -0
  232. package/test/transform/latchValue.test.js +126 -0
  233. package/test/transform/logicAnd.test.js +80 -0
  234. package/test/transform/logicOr.test.js +80 -0
  235. package/test/transform/map.test.js +42 -0
  236. package/test/transform/max.test.js +30 -0
  237. package/test/transform/maxLength.test.js +32 -0
  238. package/test/transform/min.test.js +30 -0
  239. package/test/transform/minDelta.test.js +14 -0
  240. package/test/transform/offDelay.test.js +123 -0
  241. package/test/transform/onDelay.test.js +105 -0
  242. package/test/transform/patternEscape.test.js +18 -0
  243. package/test/transform/patternMatch.test.js +177 -0
  244. package/test/transform/patternReplace.test.js +95 -0
  245. package/test/transform/patternTest.test.js +105 -0
  246. package/test/transform/rateOfChange.test.js +34 -0
  247. package/test/transform/reject.test.js +56 -0
  248. package/test/transform/resample.test.js +193 -0
  249. package/test/transform/risingEdge.test.js +60 -0
  250. package/test/transform/risingEdgeCounter.test.js +227 -0
  251. package/test/transform/sampleInterval.test.js +22 -0
  252. package/test/transform/source.test.js +137 -0
  253. package/test/transform/state.test.js +248 -0
  254. package/test/transform/threshold.test.js +78 -0
  255. package/test/transform/toBuffer.test.js +60 -0
  256. package/test/transform/toggle.test.js +92 -0
  257. package/test/transform/trim.test.js +30 -0
  258. package/test/transform/valueChange.test.js +14 -0
  259. package/test/transform/valueDecrease.test.js +32 -0
  260. package/test/transform/valueIncrease.test.js +32 -0
  261. package/test/transform/valueIncreaseDiff.test.js +32 -0
  262. package/test/transform/whenUnavailable.test.js +93 -0
  263. package/test/transform/windowCount.test.js +26 -0
  264. package/test/util/testUtils.js +405 -0
@@ -0,0 +1,130 @@
1
+ 'use strict';
2
+
3
+ const Builder = require('../lib/engine/transformBuilderV2');
4
+ const EngineV2 = require('../lib/engine/engineV2');
5
+ const testUtils = require('./util/testUtils');
6
+
7
+ describe('ExpressionService condition tests', function () {
8
+ let config;
9
+ before(async () => {
10
+ config = await testUtils.loadConfig('expressionCond.yml');
11
+ });
12
+
13
+ const playCond1 = (source) => {
14
+ source.sendCondition('cond1', { level: 'NORMAL' }, 0);
15
+ source.sendCondition('cond1', { code: 'X01', level: 'WARNING', message: 'Warning X01' }, 2000);
16
+ source.sendCondition('cond1', { code: 'X01', level: 'NORMAL' }, 4000);
17
+ source.sendCondition('cond1', { code: 'X01', level: 'FAULT', message: 'Fault X01' }, 6000);
18
+ source.sendCondition('cond1', { level: 'NORMAL' }, 8000);
19
+ source.sendCondition('cond1', { level: 'UNAVAILABLE' }, 10000);
20
+ };
21
+
22
+ const makeSource = (attach) => {
23
+ const engine = new EngineV2(config);
24
+ const builder = new Builder(config);
25
+ builder.build(engine);
26
+
27
+ const source = testUtils.mtconnectSource(config.device.keys);
28
+ testUtils.attachEngineTransformValidator(engine, engine.variablePool[attach], source);
29
+
30
+ return { engine, source };
31
+ };
32
+
33
+ it('supports code level lookup', function () {
34
+ const { engine, source } = makeSource('level1');
35
+
36
+ playCond1(source);
37
+ engine.validateFilter([
38
+ ['NORMAL', 0],
39
+ ['WARNING', 2],
40
+ ['NORMAL', 4],
41
+ ['FAULT', 6],
42
+ ['NORMAL', 8],
43
+ ['UNAVAILABLE', 10],
44
+ ]);
45
+ });
46
+
47
+ it('supports code level lookup not seen', function () {
48
+ const { engine, source } = makeSource('level2');
49
+
50
+ playCond1(source);
51
+ engine.validateFilter([
52
+ ['NORMAL', 0],
53
+ ['NORMAL', 2],
54
+ ['NORMAL', 4],
55
+ ['NORMAL', 6],
56
+ ['NORMAL', 8],
57
+ ['UNAVAILABLE', 10],
58
+ ]);
59
+ });
60
+
61
+ it('supports code level lookup square brackets', function () {
62
+ const { engine, source } = makeSource('level3');
63
+
64
+ playCond1(source);
65
+ engine.validateFilter([
66
+ ['NORMAL', 0],
67
+ ['WARNING', 2],
68
+ ['NORMAL', 4],
69
+ ['FAULT', 6],
70
+ ['NORMAL', 8],
71
+ ['UNAVAILABLE', 10],
72
+ ]);
73
+ });
74
+
75
+ it('supports seen code', function () {
76
+ const { engine, source } = makeSource('seen1');
77
+
78
+ playCond1(source);
79
+ engine.validateFilter([
80
+ [false, 0],
81
+ [true, 2],
82
+ [true, 4],
83
+ [true, 6],
84
+ [true, 8],
85
+ [true, 10],
86
+ ]);
87
+ });
88
+
89
+ it('supports unseen code', function () {
90
+ const { engine, source } = makeSource('seen2');
91
+
92
+ playCond1(source);
93
+ engine.validateFilter([
94
+ [false, 0],
95
+ [false, 2],
96
+ [false, 4],
97
+ [false, 6],
98
+ [false, 8],
99
+ [false, 10],
100
+ ]);
101
+ });
102
+
103
+ it('supports code message lookup', function () {
104
+ const { engine, source } = makeSource('message1');
105
+
106
+ playCond1(source);
107
+ engine.validateFilter([
108
+ ['', 0],
109
+ ['Warning X01', 2],
110
+ ['', 4],
111
+ ['Fault X01', 6],
112
+ ['', 8],
113
+ ['', 10],
114
+ ]);
115
+ });
116
+
117
+ it('supports code message lookup not seen', function () {
118
+ const { engine, source } = makeSource('message2');
119
+
120
+ playCond1(source);
121
+ engine.validateFilter([
122
+ ['', 0],
123
+ ['', 2],
124
+ ['', 4],
125
+ ['', 6],
126
+ ['', 8],
127
+ ['', 10],
128
+ ]);
129
+ });
130
+ });
@@ -0,0 +1,38 @@
1
+ 'use strict';
2
+
3
+ const EngineV2 = require('../../lib/engine/engineV2');
4
+ const Builder = require('../../lib/engine/transformBuilderV2');
5
+ const testUtils = require('../util/testUtils');
6
+
7
+ describe('repro convert data through buffer', async function () {
8
+ let config;
9
+ before(async () => {
10
+ config = await testUtils.loadConfig('repro/buffer-convert-repro.yml');
11
+ });
12
+
13
+ const replayStream = (source) => {
14
+ source.sendValue('color1', 0x4C42, normalizeTime('2020-08-25T17:48:02.594+00:00'));
15
+ source.sendValue('color2', 0x4555, normalizeTime('2020-08-25T17:48:02.594+00:00'));
16
+ };
17
+
18
+ // Tests that a value is returned from the ternary expression with the options are named variables.
19
+ // Previously they were not matched due to being adjacent to a colon
20
+ it('emits result of ternary operation', async function () {
21
+ const engine = new EngineV2(config);
22
+ const builder = new Builder(config);
23
+ builder.build(engine);
24
+
25
+ const source = testUtils.valueSource();
26
+ testUtils.attachEngineTransformValidator(engine, null, source);
27
+
28
+ replayStream(source);
29
+
30
+ engine.validateEngine('color', [
31
+ ['BLUE', normalizeTime('2020-08-25T17:48:02.594+00:00')],
32
+ ]);
33
+ });
34
+ });
35
+
36
+ function normalizeTime(time) {
37
+ return Date.parse(time) / 1000.0;
38
+ }
@@ -0,0 +1,34 @@
1
+ 'use strict';
2
+
3
+ const _ = require('lodash');
4
+ const EngineV2 = require('../../lib/engine/engineV2');
5
+ const Builder = require('../../lib/engine/transformBuilderV2');
6
+ const testUtils = require('../util/testUtils');
7
+
8
+ describe('repro missing time delay in chained delay', async function () {
9
+ let config;
10
+ before(async () => {
11
+ config = await testUtils.loadConfig('repro/chained-delay-timing-repro.yml');
12
+ });
13
+
14
+ it('completes successfully', async function () {
15
+ const engine = new EngineV2(config);
16
+ const builder = new Builder(config);
17
+ builder.build(engine);
18
+
19
+ const source = testUtils.valueSource();
20
+ testUtils.attachEngineTransformValidator(engine, null, source);
21
+
22
+ const ain0 = [0, 0, 0, 2, 5, 5, 0, 0, 0, 0];
23
+ const times = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
24
+ _.each(_.zip(ain0, times), ([val, time]) => {
25
+ source.sendValue('AIN0', val, time);
26
+ });
27
+
28
+ engine.validateEngine('delay', [
29
+ [false, 0],
30
+ [true, 6],
31
+ [false, 8],
32
+ ]);
33
+ });
34
+ });
@@ -0,0 +1,46 @@
1
+ 'use strict';
2
+
3
+ const EngineV2 = require('../../lib/engine/engineV2');
4
+ const Builder = require('../../lib/engine/transformBuilderV2');
5
+ const testUtils = require('../util/testUtils');
6
+
7
+ describe('repro count skipping first event', async function () {
8
+ let config;
9
+ before(async () => {
10
+ config = await testUtils.loadConfig('repro/count-init-repro.yml');
11
+ });
12
+
13
+ const replayStream = (source) => {
14
+ source.sendValue('Fovr', '100', normalizeTime('2020-08-25T17:48:02.594+00:00'));
15
+ source.sendValue('part_count', '2312478', normalizeTime('2020-08-25T17:48:02.594+00:00'));
16
+ source.sendValue('program', '1289', normalizeTime('2020-08-25T17:48:02.594+00:00'));
17
+ source.sendValue('execution', 'ACTIVE', normalizeTime('2020-08-25T17:48:02.594+00:00'));
18
+
19
+ source.sendValue('part_count', '2312479', normalizeTime('2020-08-25T17:50:04.712+00:00'));
20
+ source.sendValue('part_count', '2312480', normalizeTime('2020-08-25T17:52:42.712+00:00'));
21
+ };
22
+
23
+ // Tests that the modified-part-count variable appropriately responds to change in
24
+ // dependent variable in-warmup, so the count is initialized to 0 as soon as the program
25
+ // is set.
26
+ it('emits part count at first part change', async function () {
27
+ const engine = new EngineV2(config);
28
+ const builder = new Builder(config);
29
+ builder.build(engine);
30
+
31
+ const source = testUtils.valueSource();
32
+ testUtils.attachEngineTransformValidator(engine, null, source);
33
+
34
+ replayStream(source);
35
+
36
+ engine.validateEngine('modified-part-count', [
37
+ [0, normalizeTime('2020-08-25T17:48:02.594+00:00')],
38
+ [1, normalizeTime('2020-08-25T17:50:04.712+00:00')],
39
+ [2, normalizeTime('2020-08-25T17:52:42.712+00:00')],
40
+ ]);
41
+ });
42
+ });
43
+
44
+ function normalizeTime(time) {
45
+ return Date.parse(time) / 1000.0;
46
+ }
@@ -0,0 +1,57 @@
1
+ 'use strict';
2
+
3
+ const expect = require('chai').expect;
4
+ const EngineV2 = require('../../lib/engine/engineV2');
5
+ const Builder = require('../../lib/engine/transformBuilderV2');
6
+ const testUtils = require('../util/testUtils');
7
+
8
+ describe('repro engine breaking script cycles', async function () {
9
+ let config;
10
+ before(async () => {
11
+ config = await testUtils.loadConfig('repro/cycle-break-repro.yml');
12
+ });
13
+
14
+ it('completes successfully', async function () {
15
+ const engine = new EngineV2(config);
16
+ const builder = new Builder(config);
17
+ builder.build(engine);
18
+
19
+ const source = testUtils.valueSource();
20
+ testUtils.attachEngineTransformValidator(engine, null, source);
21
+
22
+ source.sendValue('AIN0', 0, 0);
23
+ source.sendValue('AIN1', 0, 0);
24
+
25
+ source.sendValue('AIN0', 8, 1);
26
+ source.sendValue('AIN1', 0, 1);
27
+ source.sendValue('AIN0', 0, 1);
28
+
29
+ source.sendValue('AIN0', 8, 2);
30
+ source.sendValue('AIN1', 0, 2);
31
+ source.sendValue('AIN0', 0, 2);
32
+
33
+ source.sendValue('AIN0', 8, 3);
34
+ source.sendValue('AIN1', 8, 3);
35
+ source.sendValue('AIN0', 0, 3);
36
+ source.sendValue('AIN1', 0, 3);
37
+
38
+ // engine.printEngineUpdates();
39
+
40
+ expect(engine.stats.unavailCyclesDetected).to.be.greaterThan(0);
41
+ expect(engine.stats.updateCyclesDetected).to.be.greaterThan(0);
42
+
43
+ expect(engine.pool['latch-1'].available).to.eq(false);
44
+ expect(engine.pool['latch-2'].available).to.eq(false);
45
+ expect(engine.pool['latch-3'].available).to.eq(true);
46
+ expect(engine.pool['latch-4'].available).to.eq(true);
47
+
48
+ engine.validateEngine('latch-3', [
49
+ [false, 0],
50
+ [true, 1],
51
+ ]);
52
+
53
+ engine.validateEngine('latch-4', [
54
+ [false, 0],
55
+ ]);
56
+ });
57
+ });
@@ -0,0 +1,65 @@
1
+ 'use strict';
2
+
3
+ const EngineV2 = require('../../lib/engine/engineV2');
4
+ const Builder = require('../../lib/engine/transformBuilderV2');
5
+ const testUtils = require('../util/testUtils');
6
+
7
+ describe('repro debounce not triggering correctly', async function () {
8
+ let config;
9
+ before(async () => {
10
+ config = await testUtils.loadConfig('repro/debounce-repro.yml');
11
+ });
12
+
13
+ const replayStream = (source) => {
14
+ source.sendValue('Fovr', '100', normalizeTime('2020-08-13T10:35:38.165+00:00'));
15
+ source.sendValue('program', '1582', normalizeTime('2020-08-13T10:35:38.165+00:00'));
16
+ source.sendValue('execution', 'READY', normalizeTime('2020-08-13T10:35:38.165+00:00'));
17
+ source.sendValue('Fovr', '0', normalizeTime('2020-08-13T10:35:38.165+00:00'));
18
+ source.sendValue('Fovr', '0', normalizeTime('2020-08-13T10:35:38.165+00:00'));
19
+ source.sendValue('execution', 'ACTIVE', normalizeTime('2020-08-13T10:35:38.165+00:00'));
20
+ source.sendValue('execution', 'ACTIVE', normalizeTime('2020-08-13T10:35:38.165+00:00'));
21
+ source.sendValue('Fovr', '110', normalizeTime('2020-08-13T10:35:38.165+00:00'));
22
+ };
23
+
24
+ it('triggers change after event update', async function () {
25
+ const engine = new EngineV2(config);
26
+ const builder = new Builder(config);
27
+ builder.build(engine);
28
+
29
+ const source = testUtils.valueSource();
30
+ testUtils.attachEngineTransformValidator(engine, null, source);
31
+
32
+ replayStream(source);
33
+ source.sendValue('part_count', '100', normalizeTime('2020-08-13T10:36:38.165+00:00'));
34
+
35
+ engine.validateEngine('f_override_low', [
36
+ [false, normalizeTime('2020-08-13T10:35:38.165+00:00')],
37
+ ]);
38
+ engine.validateEngine('f_override_high', [
39
+ [false, normalizeTime('2020-08-13T10:35:38.165+00:00')], [true, normalizeTime('2020-08-13T10:35:58.165+00:00')],
40
+ ]);
41
+ });
42
+
43
+ it('triggers change after unavailable', async function () {
44
+ const engine = new EngineV2(config);
45
+ const builder = new Builder(config);
46
+ builder.build(engine);
47
+
48
+ const source = testUtils.valueSource();
49
+ testUtils.attachEngineTransformValidator(engine, null, source);
50
+
51
+ replayStream(source);
52
+ source.unavailable(normalizeTime('2020-08-13T10:36:38.165+00:00'));
53
+
54
+ engine.validateEngine('f_override_low', [
55
+ [false, normalizeTime('2020-08-13T10:35:38.165+00:00')],
56
+ ]);
57
+ engine.validateEngine('f_override_high', [
58
+ [false, normalizeTime('2020-08-13T10:35:38.165+00:00')], [true, normalizeTime('2020-08-13T10:35:58.165+00:00')],
59
+ ]);
60
+ });
61
+ });
62
+
63
+ function normalizeTime(time) {
64
+ return Date.parse(time) / 1000.0;
65
+ }
@@ -0,0 +1,79 @@
1
+ 'use strict';
2
+
3
+ const EngineV2 = require('../../lib/engine/engineV2');
4
+ const Builder = require('../../lib/engine/transformBuilderV2');
5
+ const testUtils = require('../util/testUtils');
6
+
7
+ describe('repro count by diff', async function () {
8
+ let config;
9
+ before(async () => {
10
+ config = await testUtils.loadConfig('repro/diff-count-repro.yml');
11
+ });
12
+
13
+ const replayStream = (source) => {
14
+ source.sendValue('mode', 'AUTOMATIC', normalizeTime('2020-08-25T17:48:02.594+00:00'));
15
+ source.sendValue('partcount', '100', normalizeTime('2020-08-25T17:48:02.594+00:00'));
16
+ source.sendValue('mode', 'AUTOMATIC', normalizeTime('2020-08-25T17:49:02.594+00:00'));
17
+ source.sendValue('partcount', '103', normalizeTime('2020-08-25T17:49:02.594+00:00'));
18
+ source.sendValue('mode', 'AUTOMATIC', normalizeTime('2020-08-25T17:49:02.594+00:00'));
19
+ source.sendValue('mode', 'MANUAL', normalizeTime('2020-08-25T17:49:32.594+00:00'));
20
+ source.sendValue('partcount', '106', normalizeTime('2020-08-25T17:50:02.594+00:00'));
21
+ source.sendValue('mode', 'AUTOMATIC', normalizeTime('2020-08-25T17:50:32.594+00:00'));
22
+ source.sendValue('partcount', '109', normalizeTime('2020-08-25T17:51:02.594+00:00'));
23
+ };
24
+
25
+ // Tests that the modified-part-count variable appropriately responds to change in
26
+ // dependent variable in-warmup, so the count is initialized to 0 as soon as the program
27
+ // is set.
28
+ it('conditionally filters diff part counts', async function () {
29
+ const engine = new EngineV2(config);
30
+ const builder = new Builder(config);
31
+ builder.build(engine);
32
+
33
+ const source = testUtils.valueSource();
34
+ testUtils.attachEngineTransformValidator(engine, null, source);
35
+
36
+ replayStream(source);
37
+
38
+ engine.validateEngine('modified1', [
39
+ [0, normalizeTime('2020-08-25T17:48:02.594+00:00')],
40
+ [3, normalizeTime('2020-08-25T17:49:02.594+00:00')],
41
+ [6, normalizeTime('2020-08-25T17:50:02.594+00:00')],
42
+ [9, normalizeTime('2020-08-25T17:51:02.594+00:00')],
43
+ ]);
44
+
45
+ engine.validateEngine('modified2', [
46
+ [0, normalizeTime('2020-08-25T17:48:02.594+00:00')],
47
+ [3, normalizeTime('2020-08-25T17:49:02.594+00:00')],
48
+ [6, normalizeTime('2020-08-25T17:51:02.594+00:00')],
49
+ ]);
50
+ });
51
+
52
+ const replayStream2 = (source) => {
53
+ source.sendValue('partcount', '100', normalizeTime('2020-08-25T17:48:02.594+00:00'));
54
+ source.sendValue('partcount', '101', normalizeTime('2020-08-25T17:58:02.594+00:00'));
55
+ source.sendValue('partcount', '102', normalizeTime('2020-08-25T18:01:02.594+00:00'));
56
+ source.sendValue('partcount', '103', normalizeTime('2020-08-25T18:09:02.594+00:00'));
57
+ };
58
+
59
+ it('conditionally filters diff part counts 2', async function () {
60
+ const engine = new EngineV2(config);
61
+ const builder = new Builder(config);
62
+ builder.build(engine);
63
+
64
+ const source = testUtils.valueSource();
65
+ testUtils.attachEngineTransformValidator(engine, null, source);
66
+
67
+ replayStream2(source);
68
+
69
+ engine.validateEngine('modified3', [
70
+ [0, normalizeTime('2020-08-25T17:48:02.594+00:00')],
71
+ [1, normalizeTime('2020-08-25T17:58:02.594+00:00')],
72
+ [2, normalizeTime('2020-08-25T18:09:02.594+00:00')],
73
+ ]);
74
+ });
75
+ });
76
+
77
+ function normalizeTime(time) {
78
+ return Date.parse(time) / 1000.0;
79
+ }
@@ -0,0 +1,38 @@
1
+ 'use strict';
2
+
3
+ const _ = require('lodash');
4
+ const EngineV2 = require('../../lib/engine/engineV2');
5
+ const Builder = require('../../lib/engine/transformBuilderV2');
6
+ const testUtils = require('../util/testUtils');
7
+
8
+ describe('repro engine hanging processing data', async function () {
9
+ let config;
10
+ let data;
11
+ before(async () => {
12
+ config = await testUtils.loadConfig('repro/engine-hang-repro.yml');
13
+ data = await testUtils.loadData('noisy-pulse.txt');
14
+ });
15
+
16
+ it('completes successfully', async function () {
17
+ const engine = new EngineV2(config);
18
+ const builder = new Builder(config);
19
+ builder.build(engine);
20
+
21
+ const source = testUtils.valueSource();
22
+ testUtils.attachEngineTransformValidator(engine, null, source);
23
+
24
+ _.each(data, ({ value, time }) => {
25
+ source.sendValue('AIN0', value, time);
26
+ });
27
+
28
+ engine.validateEngine('exec-raw', [
29
+ [false, 1584975134.744],
30
+ [true, 1584975138.744],
31
+ [false, 1584975141.744],
32
+ [true, 1584975148.744],
33
+ [false, 1584975151.744],
34
+ [true, 1584975152.744],
35
+ [false, 1584975155.744],
36
+ ]);
37
+ });
38
+ });
@@ -0,0 +1,119 @@
1
+ 'use strict';
2
+
3
+ const EngineV2 = require('../../lib/engine/engineV2');
4
+ const Builder = require('../../lib/engine/transformBuilderV2');
5
+ const testUtils = require('../util/testUtils');
6
+
7
+ describe('repro latch apm', async function () {
8
+ let config;
9
+ before(async () => {
10
+ config = await testUtils.loadConfig('repro/latch-apm-repro.yml');
11
+ });
12
+
13
+ it('emits extracted program name', async function () {
14
+ const engine = new EngineV2(config);
15
+ const builder = new Builder(config);
16
+ builder.build(engine);
17
+
18
+ const source = testUtils.valueSource();
19
+ testUtils.attachEngineTransformValidator(engine, null, source);
20
+
21
+ source.sendValue(
22
+ 'execution1',
23
+ 'ACTIVE',
24
+ normalizeTime('2020-08-25T17:48:02.000+00:00')
25
+ );
26
+ source.sendValue(
27
+ 'block1',
28
+ 'G62',
29
+ normalizeTime('2020-08-25T17:48:02.000+00:00')
30
+ );
31
+ source.sendValue(
32
+ 'block1',
33
+ 'O1608(301608 SOFT REV 2 HEAD 1 KG 61421 HE)',
34
+ normalizeTime('2020-08-25T17:48:03.000+00:00')
35
+ );
36
+ source.sendValue(
37
+ 'execution1',
38
+ 'READY',
39
+ normalizeTime('2020-08-25T17:48:03.000+00:00')
40
+ );
41
+ source.sendValue(
42
+ 'execution1',
43
+ 'ACTIVE',
44
+ normalizeTime('2020-08-25T17:48:06.000+00:00')
45
+ );
46
+ source.sendValue(
47
+ 'block1',
48
+ 'G45',
49
+ normalizeTime('2020-08-25T17:48:07.000+00:00')
50
+ );
51
+
52
+ engine.validateEngine('program_comment', [
53
+ ['UNAVAILABLE', normalizeTime('2020-08-25T17:48:02.000+00:00')],
54
+ ['(301608 SOFT REV 2 HEAD 1 KG 61421 HE)', normalizeTime('2020-08-25T17:48:03.000+00:00')],
55
+ ['UNAVAILABLE', normalizeTime('2020-08-25T17:48:06.000+00:00')],
56
+ ]);
57
+ engine.validateEngine('operation_name', [
58
+ ['301608', normalizeTime('2020-08-25T17:48:03.000+00:00')],
59
+ ]);
60
+ });
61
+
62
+ it('emits extracted program name block priority order', async function () {
63
+ const engine = new EngineV2(config);
64
+ const builder = new Builder(config);
65
+ builder.build(engine);
66
+
67
+ const source = testUtils.valueSource();
68
+ testUtils.attachEngineTransformValidator(engine, null, source);
69
+
70
+ source.sendValue(
71
+ 'execution1',
72
+ 'ACTIVE',
73
+ normalizeTime('2020-08-25T17:48:02.000+00:00')
74
+ );
75
+ source.sendValue(
76
+ 'block1',
77
+ 'G62',
78
+ normalizeTime('2020-08-25T17:48:02.000+00:00')
79
+ );
80
+ source.sendValue(
81
+ 'block1',
82
+ 'O1608(301608 SOFT REV 2 HEAD 1 KG 61421 HE)',
83
+ normalizeTime('2020-08-25T17:48:03.000+00:00')
84
+ );
85
+ source.sendValue(
86
+ 'execution1',
87
+ 'READY',
88
+ normalizeTime('2020-08-25T17:48:03.000+00:00')
89
+ );
90
+ source.sendValue(
91
+ 'block1',
92
+ 'O1608(301608 SOFT REV 2 HEAD 1 KG 61421 HE)',
93
+ normalizeTime('2020-08-25T17:48:06.000+00:00')
94
+ );
95
+ source.sendValue(
96
+ 'execution1',
97
+ 'ACTIVE',
98
+ normalizeTime('2020-08-25T17:48:06.000+00:00')
99
+ );
100
+ source.sendValue(
101
+ 'block1',
102
+ 'G45',
103
+ normalizeTime('2020-08-25T17:48:07.000+00:00')
104
+ );
105
+
106
+ engine.validateEngine('program_comment', [
107
+ ['UNAVAILABLE', normalizeTime('2020-08-25T17:48:02.000+00:00')],
108
+ ['(301608 SOFT REV 2 HEAD 1 KG 61421 HE)', normalizeTime('2020-08-25T17:48:03.000+00:00')],
109
+ ['UNAVAILABLE', normalizeTime('2020-08-25T17:48:06.000+00:00')],
110
+ ]);
111
+ engine.validateEngine('operation_name', [
112
+ ['301608', normalizeTime('2020-08-25T17:48:03.000+00:00')],
113
+ ]);
114
+ });
115
+ });
116
+
117
+ function normalizeTime(time) {
118
+ return Date.parse(time) / 1000.0;
119
+ }