node-opcua-address-space 2.97.0 → 2.98.1

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 (342) hide show
  1. package/dist/source/address_space_ts.d.ts +118 -118
  2. package/dist/source/address_space_ts.js +17 -17
  3. package/dist/source/continuation_points/continuation_point_manager.d.ts +91 -91
  4. package/dist/source/continuation_points/continuation_point_manager.js +200 -200
  5. package/dist/source/helpers/adjust_browse_direction.d.ts +5 -5
  6. package/dist/source/helpers/adjust_browse_direction.js +11 -11
  7. package/dist/source/helpers/argument_list.d.ts +33 -33
  8. package/dist/source/helpers/argument_list.js +254 -254
  9. package/dist/source/helpers/call_helpers.d.ts +6 -6
  10. package/dist/source/helpers/call_helpers.js +71 -71
  11. package/dist/source/helpers/coerce_enum_value.d.ts +6 -6
  12. package/dist/source/helpers/coerce_enum_value.js +33 -33
  13. package/dist/source/helpers/dump_tools.d.ts +14 -14
  14. package/dist/source/helpers/dump_tools.js +78 -78
  15. package/dist/source/helpers/ensure_secure_access.d.ts +9 -9
  16. package/dist/source/helpers/ensure_secure_access.js +76 -76
  17. package/dist/source/helpers/make_optionals_map.d.ts +21 -21
  18. package/dist/source/helpers/make_optionals_map.js +29 -29
  19. package/dist/source/helpers/multiform_func.d.ts +11 -11
  20. package/dist/source/helpers/multiform_func.js +75 -75
  21. package/dist/source/helpers/resolve_opaque_on_address_space.d.ts +3 -3
  22. package/dist/source/helpers/resolve_opaque_on_address_space.js +36 -36
  23. package/dist/source/index.d.ts +61 -61
  24. package/dist/source/index.js +89 -89
  25. package/dist/source/interfaces/alarms_and_conditions/condition_info_i.d.ts +19 -19
  26. package/dist/source/interfaces/alarms_and_conditions/condition_info_i.js +2 -2
  27. package/dist/source/interfaces/alarms_and_conditions/condition_snapshot.d.ts +193 -193
  28. package/dist/source/interfaces/alarms_and_conditions/condition_snapshot.js +2 -2
  29. package/dist/source/interfaces/alarms_and_conditions/deviation_stuff.d.ts +12 -12
  30. package/dist/source/interfaces/alarms_and_conditions/deviation_stuff.js +2 -2
  31. package/dist/source/interfaces/alarms_and_conditions/install_setpoint_options.d.ts +10 -10
  32. package/dist/source/interfaces/alarms_and_conditions/install_setpoint_options.js +2 -2
  33. package/dist/source/interfaces/alarms_and_conditions/instantiate_alarm_condition_options.d.ts +7 -7
  34. package/dist/source/interfaces/alarms_and_conditions/instantiate_alarm_condition_options.js +2 -2
  35. package/dist/source/interfaces/alarms_and_conditions/instantiate_condition_options.d.ts +7 -7
  36. package/dist/source/interfaces/alarms_and_conditions/instantiate_condition_options.js +2 -2
  37. package/dist/source/interfaces/alarms_and_conditions/instantiate_exclusive_deviation_alarm_options.d.ts +4 -4
  38. package/dist/source/interfaces/alarms_and_conditions/instantiate_exclusive_deviation_alarm_options.js +2 -2
  39. package/dist/source/interfaces/alarms_and_conditions/instantiate_exclusive_limit_alarm_options.d.ts +4 -4
  40. package/dist/source/interfaces/alarms_and_conditions/instantiate_exclusive_limit_alarm_options.js +2 -2
  41. package/dist/source/interfaces/alarms_and_conditions/instantiate_limit_alarm_options.d.ts +9 -9
  42. package/dist/source/interfaces/alarms_and_conditions/instantiate_limit_alarm_options.js +2 -2
  43. package/dist/source/interfaces/alarms_and_conditions/instantiate_non_exclusive_deviation_alarm_options.d.ts +4 -4
  44. package/dist/source/interfaces/alarms_and_conditions/instantiate_non_exclusive_deviation_alarm_options.js +2 -2
  45. package/dist/source/interfaces/alarms_and_conditions/instantiate_non_exclusive_limit_alarm_options.d.ts +4 -4
  46. package/dist/source/interfaces/alarms_and_conditions/instantiate_non_exclusive_limit_alarm_options.js +2 -2
  47. package/dist/source/interfaces/alarms_and_conditions/instantiate_off_normal_alarm_options.d.ts +20 -20
  48. package/dist/source/interfaces/alarms_and_conditions/instantiate_off_normal_alarm_options.js +2 -2
  49. package/dist/source/interfaces/alarms_and_conditions/ua_acknowledgeable_condition_ex.d.ts +23 -23
  50. package/dist/source/interfaces/alarms_and_conditions/ua_acknowledgeable_condition_ex.js +2 -2
  51. package/dist/source/interfaces/alarms_and_conditions/ua_alarm_condition_ex.d.ts +32 -32
  52. package/dist/source/interfaces/alarms_and_conditions/ua_alarm_condition_ex.js +2 -2
  53. package/dist/source/interfaces/alarms_and_conditions/ua_certificate_expiration_alarm_ex.d.ts +19 -19
  54. package/dist/source/interfaces/alarms_and_conditions/ua_certificate_expiration_alarm_ex.js +2 -2
  55. package/dist/source/interfaces/alarms_and_conditions/ua_condition_ex.d.ts +45 -42
  56. package/dist/source/interfaces/alarms_and_conditions/ua_condition_ex.js +2 -2
  57. package/dist/source/interfaces/alarms_and_conditions/ua_discrete_alarm_ex.d.ts +7 -7
  58. package/dist/source/interfaces/alarms_and_conditions/ua_discrete_alarm_ex.js +25 -25
  59. package/dist/source/interfaces/alarms_and_conditions/ua_exclusive_deviation_alarm_ex.d.ts +5 -5
  60. package/dist/source/interfaces/alarms_and_conditions/ua_exclusive_deviation_alarm_ex.js +2 -2
  61. package/dist/source/interfaces/alarms_and_conditions/ua_exclusive_limit_alarm_ex.d.ts +20 -20
  62. package/dist/source/interfaces/alarms_and_conditions/ua_exclusive_limit_alarm_ex.js +2 -2
  63. package/dist/source/interfaces/alarms_and_conditions/ua_limit_alarm_ex.d.ts +26 -26
  64. package/dist/source/interfaces/alarms_and_conditions/ua_limit_alarm_ex.js +2 -2
  65. package/dist/source/interfaces/alarms_and_conditions/ua_non_exclusive_deviation_alarm_ex.d.ts +8 -8
  66. package/dist/source/interfaces/alarms_and_conditions/ua_non_exclusive_deviation_alarm_ex.js +2 -2
  67. package/dist/source/interfaces/alarms_and_conditions/ua_non_exclusive_limit_alarm_ex.d.ts +10 -10
  68. package/dist/source/interfaces/alarms_and_conditions/ua_non_exclusive_limit_alarm_ex.js +2 -2
  69. package/dist/source/interfaces/data_access/ua_multistate_discrete_ex.d.ts +21 -21
  70. package/dist/source/interfaces/data_access/ua_multistate_discrete_ex.js +2 -2
  71. package/dist/source/interfaces/data_access/ua_multistate_value_discrete_ex.d.ts +24 -24
  72. package/dist/source/interfaces/data_access/ua_multistate_value_discrete_ex.js +2 -2
  73. package/dist/source/interfaces/data_access/ua_two_state_discrete_ex.d.ts +12 -12
  74. package/dist/source/interfaces/data_access/ua_two_state_discrete_ex.js +2 -2
  75. package/dist/source/interfaces/data_access/ua_y_array_item_ex.d.ts +8 -8
  76. package/dist/source/interfaces/data_access/ua_y_array_item_ex.js +2 -2
  77. package/dist/source/interfaces/extension_object_constructor.d.ts +10 -10
  78. package/dist/source/interfaces/extension_object_constructor.js +2 -2
  79. package/dist/source/interfaces/nodeset_loader_options.d.ts +4 -4
  80. package/dist/source/interfaces/nodeset_loader_options.js +2 -2
  81. package/dist/source/interfaces/state_machine/ua_exclusive_limit_state_machine_type_ex.d.ts +12 -12
  82. package/dist/source/interfaces/state_machine/ua_exclusive_limit_state_machine_type_ex.js +2 -2
  83. package/dist/source/interfaces/state_machine/ua_finite_state_machine_type.d.ts +49 -49
  84. package/dist/source/interfaces/state_machine/ua_finite_state_machine_type.js +2 -2
  85. package/dist/source/interfaces/state_machine/ua_program_state_machine_type.d.ts +11 -11
  86. package/dist/source/interfaces/state_machine/ua_program_state_machine_type.js +2 -2
  87. package/dist/source/interfaces/state_machine/ua_shelved_state_machine_ex.d.ts +30 -30
  88. package/dist/source/interfaces/state_machine/ua_shelved_state_machine_ex.js +2 -2
  89. package/dist/source/interfaces/state_machine/ua_state_machine_type.d.ts +234 -234
  90. package/dist/source/interfaces/state_machine/ua_state_machine_type.js +2 -2
  91. package/dist/source/interfaces/state_machine/ua_transition_ex.d.ts +6 -6
  92. package/dist/source/interfaces/state_machine/ua_transition_ex.js +2 -2
  93. package/dist/source/interfaces/ua_subscription_diagnostics_variable_ex.d.ts +8 -8
  94. package/dist/source/interfaces/ua_subscription_diagnostics_variable_ex.js +2 -2
  95. package/dist/source/loader/decode_xml_extension_object.d.ts +6 -6
  96. package/dist/source/loader/decode_xml_extension_object.js +71 -71
  97. package/dist/source/loader/ensure_datatype_extracted.d.ts +5 -5
  98. package/dist/source/loader/ensure_datatype_extracted.js +70 -70
  99. package/dist/source/loader/generateAddressSpaceRaw.d.ts +11 -11
  100. package/dist/source/loader/generateAddressSpaceRaw.js +45 -45
  101. package/dist/source/loader/load_nodeset2.d.ts +17 -17
  102. package/dist/source/loader/load_nodeset2.js +1483 -1483
  103. package/dist/source/loader/make_semver_compatible.d.ts +6 -6
  104. package/dist/source/loader/make_semver_compatible.js +25 -25
  105. package/dist/source/loader/make_xml_extension_object_parser.d.ts +28 -28
  106. package/dist/source/loader/make_xml_extension_object_parser.js +326 -326
  107. package/dist/source/loader/namespace_post_step.d.ts +10 -10
  108. package/dist/source/loader/namespace_post_step.js +61 -61
  109. package/dist/source/loader/register_node_promoter.d.ts +2 -2
  110. package/dist/source/loader/register_node_promoter.js +9 -9
  111. package/dist/source/namespace.d.ts +6 -6
  112. package/dist/source/namespace.js +2 -2
  113. package/dist/source/namespace_alarm_and_condition.d.ts +32 -32
  114. package/dist/source/namespace_alarm_and_condition.js +2 -2
  115. package/dist/source/namespace_data_access.d.ts +42 -42
  116. package/dist/source/namespace_data_access.js +2 -2
  117. package/dist/source/namespace_machine_state.d.ts +8 -8
  118. package/dist/source/namespace_machine_state.js +2 -2
  119. package/dist/source/pseudo_session.d.ts +72 -72
  120. package/dist/source/pseudo_session.js +254 -254
  121. package/dist/source/session_context.d.ts +111 -111
  122. package/dist/source/session_context.js +264 -264
  123. package/dist/source/session_context.js.map +1 -1
  124. package/dist/source/set_namespace_meta_data.d.ts +2 -2
  125. package/dist/source/set_namespace_meta_data.js +59 -59
  126. package/dist/source/ua_root_folder.d.ts +9 -9
  127. package/dist/source/ua_root_folder.js +2 -2
  128. package/dist/source/ua_two_state_variable_ex.d.ts +23 -23
  129. package/dist/source/ua_two_state_variable_ex.js +2 -2
  130. package/dist/source/xml_writer.d.ts +18 -18
  131. package/dist/source/xml_writer.js +2 -2
  132. package/dist/src/address_space.d.ts +387 -387
  133. package/dist/src/address_space.js +1385 -1385
  134. package/dist/src/address_space.js.map +1 -1
  135. package/dist/src/address_space_change_event_tools.d.ts +6 -6
  136. package/dist/src/address_space_change_event_tools.js +152 -152
  137. package/dist/src/address_space_private.d.ts +43 -43
  138. package/dist/src/address_space_private.js +2 -2
  139. package/dist/src/alarms_and_conditions/condition.d.ts +5 -5
  140. package/dist/src/alarms_and_conditions/condition.js +78 -78
  141. package/dist/src/alarms_and_conditions/condition_info_impl.d.ts +26 -26
  142. package/dist/src/alarms_and_conditions/condition_info_impl.js +54 -54
  143. package/dist/src/alarms_and_conditions/condition_snapshot_impl.d.ts +222 -222
  144. package/dist/src/alarms_and_conditions/condition_snapshot_impl.js +657 -657
  145. package/dist/src/alarms_and_conditions/condition_snapshot_impl.js.map +1 -1
  146. package/dist/src/alarms_and_conditions/deviation_alarm_helper.d.ts +9 -9
  147. package/dist/src/alarms_and_conditions/deviation_alarm_helper.js +60 -60
  148. package/dist/src/alarms_and_conditions/index.d.ts +16 -16
  149. package/dist/src/alarms_and_conditions/index.js +32 -32
  150. package/dist/src/alarms_and_conditions/ua_acknowledgeable_condition_impl.d.ts +44 -44
  151. package/dist/src/alarms_and_conditions/ua_acknowledgeable_condition_impl.js +244 -244
  152. package/dist/src/alarms_and_conditions/ua_alarm_condition_impl.d.ts +93 -93
  153. package/dist/src/alarms_and_conditions/ua_alarm_condition_impl.js +418 -418
  154. package/dist/src/alarms_and_conditions/ua_alarm_condition_impl.js.map +1 -1
  155. package/dist/src/alarms_and_conditions/ua_base_event_impl.d.ts +26 -26
  156. package/dist/src/alarms_and_conditions/ua_base_event_impl.js +38 -38
  157. package/dist/src/alarms_and_conditions/ua_certificate_expiration_alarm_impl.d.ts +44 -44
  158. package/dist/src/alarms_and_conditions/ua_certificate_expiration_alarm_impl.js +183 -183
  159. package/dist/src/alarms_and_conditions/ua_condition_impl.d.ts +155 -153
  160. package/dist/src/alarms_and_conditions/ua_condition_impl.js +1028 -1028
  161. package/dist/src/alarms_and_conditions/ua_condition_impl.js.map +1 -1
  162. package/dist/src/alarms_and_conditions/ua_discrete_alarm_impl.d.ts +14 -14
  163. package/dist/src/alarms_and_conditions/ua_discrete_alarm_impl.js +34 -34
  164. package/dist/src/alarms_and_conditions/ua_exclusive_deviation_alarm_impl.d.ts +24 -24
  165. package/dist/src/alarms_and_conditions/ua_exclusive_deviation_alarm_impl.js +56 -56
  166. package/dist/src/alarms_and_conditions/ua_exclusive_level_alarm_impl.d.ts +11 -11
  167. package/dist/src/alarms_and_conditions/ua_exclusive_level_alarm_impl.js +11 -11
  168. package/dist/src/alarms_and_conditions/ua_exclusive_limit_alarm_impl.d.ts +23 -23
  169. package/dist/src/alarms_and_conditions/ua_exclusive_limit_alarm_impl.js +86 -86
  170. package/dist/src/alarms_and_conditions/ua_exclusive_rate_of_change_alarm_impl.d.ts +11 -11
  171. package/dist/src/alarms_and_conditions/ua_exclusive_rate_of_change_alarm_impl.js +7 -7
  172. package/dist/src/alarms_and_conditions/ua_limit_alarm_impl.d.ts +79 -79
  173. package/dist/src/alarms_and_conditions/ua_limit_alarm_impl.js +250 -250
  174. package/dist/src/alarms_and_conditions/ua_non_exclusive_deviation_alarm_impl.d.ts +24 -24
  175. package/dist/src/alarms_and_conditions/ua_non_exclusive_deviation_alarm_impl.js +50 -50
  176. package/dist/src/alarms_and_conditions/ua_non_exclusive_limit_alarm_impl.d.ts +19 -19
  177. package/dist/src/alarms_and_conditions/ua_non_exclusive_limit_alarm_impl.js +162 -162
  178. package/dist/src/alarms_and_conditions/ua_off_normal_alarm_impl.d.ts +46 -46
  179. package/dist/src/alarms_and_conditions/ua_off_normal_alarm_impl.js +165 -165
  180. package/dist/src/alarms_and_conditions/ua_system_off_normal_alarm_impl.d.ts +18 -18
  181. package/dist/src/alarms_and_conditions/ua_system_off_normal_alarm_impl.js +17 -17
  182. package/dist/src/apply_condition_refresh.d.ts +6 -6
  183. package/dist/src/apply_condition_refresh.js +27 -27
  184. package/dist/src/base_node_impl.d.ts +284 -284
  185. package/dist/src/base_node_impl.js +1454 -1454
  186. package/dist/src/base_node_private.d.ts +81 -81
  187. package/dist/src/base_node_private.js +832 -803
  188. package/dist/src/base_node_private.js.map +1 -1
  189. package/dist/src/check_value_rank_compatibility.d.ts +15 -15
  190. package/dist/src/check_value_rank_compatibility.js +81 -81
  191. package/dist/src/data_access/add_dataItem_stuff.d.ts +11 -11
  192. package/dist/src/data_access/add_dataItem_stuff.js +61 -61
  193. package/dist/src/data_access/check_variant_compatibility_ua_analog_item.d.ts +1 -1
  194. package/dist/src/data_access/check_variant_compatibility_ua_analog_item.js +34 -34
  195. package/dist/src/data_access/ua_multistate_discrete_impl.d.ts +32 -32
  196. package/dist/src/data_access/ua_multistate_discrete_impl.js +130 -130
  197. package/dist/src/data_access/ua_multistate_value_discrete_impl.d.ts +52 -52
  198. package/dist/src/data_access/ua_multistate_value_discrete_impl.js +253 -253
  199. package/dist/src/data_access/ua_two_state_discrete_impl.d.ts +25 -25
  200. package/dist/src/data_access/ua_two_state_discrete_impl.js +155 -155
  201. package/dist/src/event_data.d.ts +34 -34
  202. package/dist/src/event_data.js +64 -64
  203. package/dist/src/extension_object_array_node.d.ts +23 -23
  204. package/dist/src/extension_object_array_node.js +248 -248
  205. package/dist/src/historical_access/address_space_historical_data_node.d.ts +26 -26
  206. package/dist/src/historical_access/address_space_historical_data_node.js +652 -652
  207. package/dist/src/idx_iterator.d.ts +8 -8
  208. package/dist/src/idx_iterator.js +50 -50
  209. package/dist/src/index_current.d.ts +46 -46
  210. package/dist/src/index_current.js +77 -77
  211. package/dist/src/namespace_impl.d.ts +456 -456
  212. package/dist/src/namespace_impl.js +1762 -1762
  213. package/dist/src/namespace_impl.js.map +1 -1
  214. package/dist/src/namespace_private.d.ts +23 -23
  215. package/dist/src/namespace_private.js +32 -32
  216. package/dist/src/nodeid_manager.d.ts +37 -37
  217. package/dist/src/nodeid_manager.js +183 -183
  218. package/dist/src/nodeset_tools/adjust_namespace_array.d.ts +2 -2
  219. package/dist/src/nodeset_tools/adjust_namespace_array.js +13 -13
  220. package/dist/src/nodeset_tools/construct_namespace_dependency.d.ts +18 -18
  221. package/dist/src/nodeset_tools/construct_namespace_dependency.js +140 -140
  222. package/dist/src/nodeset_tools/dump_to_bsd.d.ts +2 -2
  223. package/dist/src/nodeset_tools/dump_to_bsd.js +164 -164
  224. package/dist/src/nodeset_tools/nodeset_to_xml.d.ts +10 -10
  225. package/dist/src/nodeset_tools/nodeset_to_xml.js +1287 -1287
  226. package/dist/src/private_namespace.d.ts +5 -5
  227. package/dist/src/private_namespace.js +19 -19
  228. package/dist/src/reference_impl.d.ts +43 -43
  229. package/dist/src/reference_impl.js +139 -139
  230. package/dist/src/role_permissions.d.ts +2 -2
  231. package/dist/src/role_permissions.js +10 -10
  232. package/dist/src/state_machine/finite_state_machine.d.ts +81 -81
  233. package/dist/src/state_machine/finite_state_machine.js +388 -388
  234. package/dist/src/state_machine/ua_shelving_state_machine_ex.d.ts +38 -38
  235. package/dist/src/state_machine/ua_shelving_state_machine_ex.js +250 -250
  236. package/dist/src/state_machine/ua_two_state_variable.d.ts +61 -61
  237. package/dist/src/state_machine/ua_two_state_variable.js +331 -331
  238. package/dist/src/tool_isSubtypeOf.d.ts +18 -18
  239. package/dist/src/tool_isSubtypeOf.js +124 -124
  240. package/dist/src/ua_condition_type.d.ts +8 -8
  241. package/dist/src/ua_condition_type.js +2 -2
  242. package/dist/src/ua_data_type_impl.d.ts +89 -89
  243. package/dist/src/ua_data_type_impl.js +368 -368
  244. package/dist/src/ua_method_impl.d.ts +42 -42
  245. package/dist/src/ua_method_impl.js +217 -217
  246. package/dist/src/ua_object_impl.d.ts +35 -35
  247. package/dist/src/ua_object_impl.js +168 -168
  248. package/dist/src/ua_object_type_impl.d.ts +50 -50
  249. package/dist/src/ua_object_type_impl.js +126 -126
  250. package/dist/src/ua_reference_type_impl.d.ts +45 -45
  251. package/dist/src/ua_reference_type_impl.js +141 -141
  252. package/dist/src/ua_variable_impl.d.ts +380 -380
  253. package/dist/src/ua_variable_impl.js +1738 -1738
  254. package/dist/src/ua_variable_impl_ext_obj.d.ts +23 -23
  255. package/dist/src/ua_variable_impl_ext_obj.js +670 -670
  256. package/dist/src/ua_variable_type_impl.d.ts +74 -74
  257. package/dist/src/ua_variable_type_impl.js +597 -581
  258. package/dist/src/ua_variable_type_impl.js.map +1 -1
  259. package/dist/src/ua_view_impl.d.ts +19 -19
  260. package/dist/src/ua_view_impl.js +43 -43
  261. package/dist/tsconfig_common.tsbuildinfo +1 -0
  262. package/distHelpers/add_event_generator_object.d.ts +3 -3
  263. package/distHelpers/add_event_generator_object.js +64 -64
  264. package/distHelpers/alarms_and_conditions_demo.d.ts +9 -9
  265. package/distHelpers/alarms_and_conditions_demo.js +115 -115
  266. package/distHelpers/assertHasMatchingReference.d.ts +19 -19
  267. package/distHelpers/assertHasMatchingReference.js +40 -40
  268. package/distHelpers/boiler_system.d.ts +113 -113
  269. package/distHelpers/boiler_system.js +395 -395
  270. package/distHelpers/create_minimalist_address_space_nodeset.d.ts +5 -5
  271. package/distHelpers/create_minimalist_address_space_nodeset.js +171 -171
  272. package/distHelpers/date_utils.d.ts +3 -3
  273. package/distHelpers/date_utils.js +9 -9
  274. package/distHelpers/dump_statemachine.js +127 -127
  275. package/distHelpers/get_address_space_fixture.d.ts +1 -1
  276. package/distHelpers/get_address_space_fixture.js +30 -30
  277. package/distHelpers/get_mini_address_space.d.ts +7 -7
  278. package/distHelpers/get_mini_address_space.js +36 -36
  279. package/distHelpers/index.d.ts +12 -12
  280. package/distHelpers/index.js +28 -28
  281. package/distHelpers/mock_session.d.ts +10 -10
  282. package/distHelpers/mock_session.js +25 -25
  283. package/distNodeJS/generate_address_space.d.ts +6 -6
  284. package/distNodeJS/generate_address_space.js +52 -52
  285. package/distNodeJS/index.d.ts +1 -1
  286. package/distNodeJS/index.js +17 -17
  287. package/package.json +51 -40
  288. package/source/interfaces/alarms_and_conditions/ua_condition_ex.ts +4 -3
  289. package/src/alarms_and_conditions/ua_condition_impl.ts +14 -9
  290. package/src/base_node_private.ts +73 -28
  291. package/src/ua_variable_type_impl.ts +35 -17
  292. package/.mocharc.yml +0 -12
  293. package/dist/src/tool_isSupertypeOf.d.ts +0 -18
  294. package/dist/src/tool_isSupertypeOf.js +0 -125
  295. package/dist/src/tool_isSupertypeOf.js.map +0 -1
  296. package/generate.js +0 -1
  297. package/source_nodejs/generate_address_space.ts +0 -60
  298. package/source_nodejs/index.ts +0 -1
  299. package/test_helpers/add_event_generator_object.ts +0 -71
  300. package/test_helpers/alarms_and_conditions_demo.ts +0 -151
  301. package/test_helpers/assertHasMatchingReference.ts +0 -43
  302. package/test_helpers/boiler_system.ts +0 -610
  303. package/test_helpers/create_minimalist_address_space_nodeset.ts +0 -208
  304. package/test_helpers/date_utils.ts +0 -5
  305. package/test_helpers/dump_statemachine.ts +0 -155
  306. package/test_helpers/get_address_space_fixture.ts +0 -30
  307. package/test_helpers/get_mini_address_space.ts +0 -42
  308. package/test_helpers/index.ts +0 -12
  309. package/test_helpers/mock_session.ts +0 -34
  310. package/test_helpers/test_fixtures/dataType_in_separateNamespace.xml +0 -150
  311. package/test_helpers/test_fixtures/dataType_in_separateNamespace_basic.xml +0 -57
  312. package/test_helpers/test_fixtures/dataType_in_separateNamespace_mix.xml +0 -136
  313. package/test_helpers/test_fixtures/dataType_issue.xml +0 -80
  314. package/test_helpers/test_fixtures/dataType_withEnumeration.xml +0 -82
  315. package/test_helpers/test_fixtures/dataType_with_isOptionSet.xml +0 -194
  316. package/test_helpers/test_fixtures/dataType_with_qualifiedname.xml +0 -71
  317. package/test_helpers/test_fixtures/dataType_with_recursive_structure.xml +0 -155
  318. package/test_helpers/test_fixtures/dataType_with_structures.xml +0 -605
  319. package/test_helpers/test_fixtures/dataType_with_union.xml +0 -90
  320. package/test_helpers/test_fixtures/datatype_as_per_1.04.xml +0 -118
  321. package/test_helpers/test_fixtures/datatype_with_allow_subtype.xml +0 -104
  322. package/test_helpers/test_fixtures/eurange_issue.xml +0 -74
  323. package/test_helpers/test_fixtures/example_issue1096.xml +0 -267
  324. package/test_helpers/test_fixtures/fixture_empty_nodeset2.xml +0 -106
  325. package/test_helpers/test_fixtures/fixture_simple_statemachine_nodeset2.xml +0 -1305
  326. package/test_helpers/test_fixtures/fixuture_nodeset_objects_with_some_methods.xml +0 -370
  327. package/test_helpers/test_fixtures/issue_1132_variable_with_nodeid_value.xml +0 -68
  328. package/test_helpers/test_fixtures/issue_846.xml +0 -3172
  329. package/test_helpers/test_fixtures/issue_899_variable_with_nodeid_value.xml +0 -33
  330. package/test_helpers/test_fixtures/mini.Node.Set2.xml +0 -4736
  331. package/test_helpers/test_fixtures/mini.nodeset.withVariousVariables.xml +0 -196
  332. package/test_helpers/test_fixtures/minimalist_nodeset_with_models.xml +0 -8
  333. package/test_helpers/test_fixtures/minimalist_nodeset_with_models_more_complex.xml +0 -20
  334. package/test_helpers/test_fixtures/nodeset_no_aliases.xml +0 -30
  335. package/test_helpers/test_fixtures/nodeset_no_aliases_with_aliases.xml +0 -31
  336. package/test_helpers/test_fixtures/nodeset_with_analog_items.xml +0 -45
  337. package/test_helpers/test_fixtures/nodeset_with_guid.xml +0 -1442
  338. package/test_helpers/test_fixtures/nodeset_with_int64_values.xml +0 -31
  339. package/test_helpers/test_fixtures/nodeset_with_special_char.xml +0 -34
  340. package/test_helpers/test_fixtures/nodeset_with_utf8_special_characters.xml +0 -20
  341. package/test_helpers/test_fixtures/variable_with_value.xml +0 -143
  342. package/test_helpers/test_fixtures/variabletype_with_value.xml +0 -324
@@ -1,1739 +1,1739 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.UAVariableImplT = exports.UAVariableImpl = exports.adjust_userAccessLevel = exports.adjust_accessLevel = void 0;
4
- /* eslint-disable max-statements */
5
- /* eslint-disable complexity */
6
- /**
7
- * @module node-opcua-address-space
8
- */
9
- // tslint:disable:no-bitwise
10
- // tslint:disable:no-console
11
- // tslint:disable:max-line-length
12
- const chalk = require("chalk");
13
- const node_opcua_address_space_base_1 = require("node-opcua-address-space-base");
14
- const node_opcua_assert_1 = require("node-opcua-assert");
15
- const node_opcua_data_model_1 = require("node-opcua-data-model");
16
- const node_opcua_data_value_1 = require("node-opcua-data-value");
17
- const node_opcua_date_time_1 = require("node-opcua-date-time");
18
- const node_opcua_debug_1 = require("node-opcua-debug");
19
- const node_opcua_extension_object_1 = require("node-opcua-extension-object");
20
- const node_opcua_nodeid_1 = require("node-opcua-nodeid");
21
- const node_opcua_numeric_range_1 = require("node-opcua-numeric-range");
22
- const node_opcua_service_write_1 = require("node-opcua-service-write");
23
- const node_opcua_status_code_1 = require("node-opcua-status-code");
24
- const node_opcua_types_1 = require("node-opcua-types");
25
- const utils = require("node-opcua-utils");
26
- const node_opcua_variant_1 = require("node-opcua-variant");
27
- const session_context_1 = require("../source/session_context");
28
- const multiform_func_1 = require("../source/helpers/multiform_func");
29
- const base_node_impl_1 = require("./base_node_impl");
30
- const base_node_private_1 = require("./base_node_private");
31
- const ua_data_type_impl_1 = require("./ua_data_type_impl");
32
- const apply_condition_refresh_1 = require("./apply_condition_refresh");
33
- const ua_variable_impl_ext_obj_1 = require("./ua_variable_impl_ext_obj");
34
- const debugLog = (0, node_opcua_debug_1.make_debugLog)(__filename);
35
- const warningLog = (0, node_opcua_debug_1.make_warningLog)(__filename);
36
- const doDebug = (0, node_opcua_debug_1.checkDebugFlag)(__filename);
37
- const errorLog = (0, node_opcua_debug_1.make_errorLog)(__filename);
38
- function adjust_accessLevel(accessLevel) {
39
- accessLevel = utils.isNullOrUndefined(accessLevel) ? "CurrentRead | CurrentWrite" : accessLevel;
40
- accessLevel = (0, node_opcua_data_model_1.makeAccessLevelFlag)(accessLevel);
41
- (0, node_opcua_assert_1.assert)(isFinite(accessLevel));
42
- return accessLevel;
43
- }
44
- exports.adjust_accessLevel = adjust_accessLevel;
45
- function adjust_userAccessLevel(userAccessLevel, accessLevel) {
46
- if (userAccessLevel === undefined) {
47
- return undefined;
48
- }
49
- userAccessLevel = adjust_accessLevel(userAccessLevel);
50
- accessLevel = adjust_accessLevel(accessLevel);
51
- return (0, node_opcua_data_model_1.makeAccessLevelFlag)(accessLevel & userAccessLevel);
52
- }
53
- exports.adjust_userAccessLevel = adjust_userAccessLevel;
54
- function adjust_samplingInterval(minimumSamplingInterval) {
55
- (0, node_opcua_assert_1.assert)(isFinite(minimumSamplingInterval));
56
- if (minimumSamplingInterval < 0) {
57
- return -1; // only -1 is a valid negative value for samplingInterval and means "unspecified"
58
- }
59
- return minimumSamplingInterval;
60
- }
61
- function is_Variant(v) {
62
- return v instanceof node_opcua_variant_1.Variant;
63
- }
64
- function is_StatusCode(v) {
65
- return (v &&
66
- v.constructor &&
67
- (v instanceof node_opcua_status_code_1.StatusCode ||
68
- v.constructor.name === "ConstantStatusCode" ||
69
- v.constructor.name === "StatusCode" ||
70
- v.constructor.name === "ModifiableStatusCode"));
71
- }
72
- function is_Variant_or_StatusCode(v) {
73
- if (is_Variant(v)) {
74
- // /@@assert(v.isValid());
75
- }
76
- return is_Variant(v) || is_StatusCode(v);
77
- }
78
- function _dataType_toUADataType(addressSpace, dataType) {
79
- (0, node_opcua_assert_1.assert)(addressSpace);
80
- (0, node_opcua_assert_1.assert)(dataType !== node_opcua_variant_1.DataType.Null);
81
- const dataTypeNode = addressSpace.findDataType(node_opcua_variant_1.DataType[dataType]);
82
- /* istanbul ignore next */
83
- if (!dataTypeNode) {
84
- throw new Error(" Cannot find DataType " + node_opcua_variant_1.DataType[dataType] + " in address Space");
85
- }
86
- return dataTypeNode;
87
- }
88
- /*=
89
- *
90
- * @param addressSpace
91
- * @param dataTypeNodeId : the nodeId matching the dataType of the destination variable.
92
- * @param variantDataType: the dataType of the variant to write to the destination variable
93
- * @param nodeId
94
- * @return {boolean} true if the variant dataType is compatible with the Variable DataType
95
- */
96
- function validateDataType(addressSpace, dataTypeNodeId, variantDataType, nodeId, allowNulls) {
97
- if (variantDataType === node_opcua_variant_1.DataType.ExtensionObject) {
98
- return true;
99
- }
100
- if (variantDataType === node_opcua_variant_1.DataType.Null && allowNulls) {
101
- return true;
102
- }
103
- if (variantDataType === node_opcua_variant_1.DataType.Null && !allowNulls) {
104
- return false;
105
- }
106
- let builtInType;
107
- let builtInUADataType;
108
- const destUADataType = addressSpace.findDataType(dataTypeNodeId);
109
- (0, node_opcua_assert_1.assert)(destUADataType instanceof ua_data_type_impl_1.UADataTypeImpl);
110
- if (destUADataType.isAbstract || destUADataType.nodeId.namespace !== 0) {
111
- builtInUADataType = destUADataType;
112
- }
113
- else {
114
- builtInType = addressSpace.findCorrespondingBasicDataType(destUADataType);
115
- builtInUADataType = addressSpace.findDataType(builtInType);
116
- }
117
- (0, node_opcua_assert_1.assert)(builtInUADataType instanceof ua_data_type_impl_1.UADataTypeImpl);
118
- const enumerationUADataType = addressSpace.findDataType("Enumeration");
119
- if (!enumerationUADataType) {
120
- throw new Error("cannot find Enumeration DataType node in standard address space");
121
- }
122
- if (destUADataType.isSubtypeOf(enumerationUADataType)) {
123
- // istanbul ignore next
124
- if (doDebug) {
125
- debugLog("destUADataType.", destUADataType.browseName.toString(), destUADataType.nodeId.toString());
126
- debugLog("enumerationUADataType.", enumerationUADataType.browseName.toString(), enumerationUADataType.nodeId.toString());
127
- }
128
- return true;
129
- }
130
- // The value supplied for the attribute is not of the same type as the value.
131
- const variantUADataType = _dataType_toUADataType(addressSpace, variantDataType);
132
- (0, node_opcua_assert_1.assert)(variantUADataType instanceof ua_data_type_impl_1.UADataTypeImpl);
133
- const dest_isSubTypeOf_variant = variantUADataType.isSubtypeOf(builtInUADataType);
134
- /* istanbul ignore next */
135
- if (doDebug) {
136
- if (dest_isSubTypeOf_variant) {
137
- /* istanbul ignore next*/
138
- debugLog(chalk.green(" ---------- Type match !!! "), " on ", nodeId.toString());
139
- }
140
- else {
141
- /* istanbul ignore next*/
142
- debugLog(chalk.red(" ---------- Type mismatch "), " on ", nodeId.toString());
143
- }
144
- debugLog(chalk.cyan(" Variable data Type is = "), destUADataType.browseName.toString());
145
- debugLog(chalk.cyan(" which matches basic Type = "), builtInUADataType.browseName.toString());
146
- debugLog(chalk.yellow(" Actual dataType = "), variantUADataType.browseName.toString());
147
- }
148
- return dest_isSubTypeOf_variant;
149
- }
150
- function default_func(dataValue1, callback1) {
151
- return _default_writable_timestamped_set_func.call(this, dataValue1, callback1);
152
- }
153
- /**
154
- * A OPCUA Variable Node
155
- *
156
- * @class UAVariable
157
- * @constructor
158
- * @extends BaseNode
159
- * The AccessLevel Attribute is used to indicate how the Value of a Variable can be accessed (read/write) and if it
160
- * contains current and/or historic data. The AccessLevel does not take any user access rights into account,
161
- * i.e. although the Variable is writable this may be restricted to a certain user / user group.
162
- * The AccessLevel is an 8-bit unsigned integer with the structure defined in the following table:
163
- *
164
- * Field Bit Description
165
- * CurrentRead 0 Indicates if the current value is readable
166
- * (0 means not readable, 1 means readable).
167
- * CurrentWrite 1 Indicates if the current value is writable
168
- * (0 means not writable, 1 means writable).
169
- * HistoryRead 2 Indicates if the history of the value is readable
170
- * (0 means not readable, 1 means readable).
171
- * HistoryWrite 3 Indicates if the history of the value is writable (0 means not writable, 1 means writable).
172
- * SemanticChange 4 Indicates if the Variable used as Property generates SemanticChangeEvents (see 9.31).
173
- * Reserved 5:7 Reserved for future use. Shall always be zero.
174
- *
175
- * The first two bits also indicate if a current value of this Variable is available and the second two bits
176
- * indicates if the history of the Variable is available via the OPC UA server.
177
- *
178
- */
179
- class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
180
- get typeDefinitionObj() {
181
- // istanbul ignore next
182
- if (super.typeDefinitionObj && super.typeDefinitionObj.nodeClass !== node_opcua_data_model_1.NodeClass.VariableType) {
183
- console.log(super.typeDefinitionObj.toString());
184
- throw new Error("Invalid type definition node class , expecting a VariableType got " + node_opcua_data_model_1.NodeClass[super.typeDefinitionObj.nodeClass]);
185
- }
186
- return super.typeDefinitionObj;
187
- }
188
- get typeDefinition() {
189
- return super.typeDefinition;
190
- }
191
- constructor(options) {
192
- super(options);
193
- this.nodeClass = node_opcua_data_model_1.NodeClass.Variable;
194
- (0, node_opcua_variant_1.verifyRankAndDimensions)(options);
195
- this.valueRank = options.valueRank;
196
- this.arrayDimensions = options.arrayDimensions;
197
- this.dataType = this.resolveNodeId(options.dataType); // DataType (NodeId)
198
- this.accessLevel = adjust_accessLevel(options.accessLevel);
199
- this.userAccessLevel = adjust_userAccessLevel(options.userAccessLevel, this.accessLevel);
200
- this.minimumSamplingInterval = adjust_samplingInterval(options.minimumSamplingInterval || 0);
201
- this.historizing = !!options.historizing; // coerced to boolean"
202
- this.$dataValue = new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.UncertainInitialValue, value: { dataType: node_opcua_variant_1.DataType.Null } });
203
- if (options.value) {
204
- this.bindVariable(options.value);
205
- }
206
- this.setMaxListeners(5000);
207
- this.semantic_version = 0;
208
- }
209
- checkAccessLevelPrivate(_context, accessLevel) {
210
- if (this.userAccessLevel === undefined) {
211
- return true;
212
- }
213
- return (this.userAccessLevel & accessLevel) === accessLevel;
214
- }
215
- checkPermissionPrivate(context, permission) {
216
- if (!context)
217
- return true;
218
- (0, node_opcua_assert_1.assert)(context instanceof session_context_1.SessionContext);
219
- if (context.checkPermission) {
220
- if (!(context.checkPermission instanceof Function)) {
221
- errorLog("context checkPermission is not a function");
222
- return false;
223
- }
224
- if (!context.checkPermission(this, permission)) {
225
- return false;
226
- }
227
- }
228
- return true;
229
- }
230
- checkPermissionAndAccessLevelPrivate(context, permission, accessLevel) {
231
- if (!this.checkPermissionPrivate(context, permission)) {
232
- return false;
233
- }
234
- return this.checkAccessLevelPrivate(context, accessLevel);
235
- }
236
- isReadable(context) {
237
- return (this.accessLevel & node_opcua_data_model_1.AccessLevelFlag.CurrentRead) === node_opcua_data_model_1.AccessLevelFlag.CurrentRead;
238
- }
239
- isUserReadable(context) {
240
- if (!this.isReadable(context)) {
241
- return false;
242
- }
243
- if (!this.checkPermissionPrivate(context, node_opcua_types_1.PermissionType.Read)) {
244
- return false;
245
- }
246
- return this.checkAccessLevelPrivate(context, node_opcua_data_model_1.AccessLevelFlag.CurrentRead);
247
- }
248
- isWritable(context) {
249
- return (this.accessLevel & node_opcua_data_model_1.AccessLevelFlag.CurrentWrite) === node_opcua_data_model_1.AccessLevelFlag.CurrentWrite;
250
- }
251
- isUserWritable(context) {
252
- if (!this.isWritable(context)) {
253
- return false;
254
- }
255
- return this.checkPermissionAndAccessLevelPrivate(context, node_opcua_types_1.PermissionType.Write, node_opcua_data_model_1.AccessLevelFlag.CurrentWrite);
256
- }
257
- canUserReadHistory(context) {
258
- return this.checkPermissionAndAccessLevelPrivate(context, node_opcua_types_1.PermissionType.ReadHistory, node_opcua_data_model_1.AccessLevelFlag.HistoryRead);
259
- }
260
- canUserWriteHistorizingAttribute(context) {
261
- if (context && !context.checkPermission(this, node_opcua_types_1.PermissionType.WriteHistorizing)) {
262
- return false;
263
- }
264
- return true;
265
- }
266
- canUserInsertHistory(context) {
267
- return this.checkPermissionAndAccessLevelPrivate(context, node_opcua_types_1.PermissionType.InsertHistory, node_opcua_data_model_1.AccessLevelFlag.HistoryWrite);
268
- }
269
- canUserModifyHistory(context) {
270
- return this.checkPermissionAndAccessLevelPrivate(context, node_opcua_types_1.PermissionType.ModifyHistory, node_opcua_data_model_1.AccessLevelFlag.HistoryWrite);
271
- }
272
- canUserDeleteHistory(context) {
273
- return this.checkPermissionAndAccessLevelPrivate(context, node_opcua_types_1.PermissionType.DeleteHistory, node_opcua_data_model_1.AccessLevelFlag.HistoryWrite);
274
- }
275
- /**
276
- *
277
- *
278
- * from OPC.UA.Spec 1.02 part 4
279
- * 5.10.2.4 StatusCodes
280
- * Table 51 defines values for the operation level statusCode contained in the DataValue structure of
281
- * each values element. Common StatusCodes are defined in Table 166.
282
- *
283
- * Table 51 Read Operation Level Result Codes
284
- *
285
- * | Symbolic Id | Description
286
- * |-----------------------------|---------------------------------------------------------------------------------------------|
287
- * |BadNodeIdInvalid | The syntax of the node id is not valid.|
288
- * |BadNodeIdUnknown |The node id refers to a node that does not exist in the server address space.|
289
- * |BadAttributeIdInvalid | BadAttributeIdInvalid The attribute is not supported for the specified node.|
290
- * |BadIndexRangeInvalid | The syntax of the index range parameter is invalid.|
291
- * |BadIndexRangeNoData | No data exists within the range of indexes specified.|
292
- * |BadDataEncodingInvalid | The data encoding is invalid.|
293
- * | | This result is used if no dataEncoding can be applied because an Attribute other|
294
- * | | than Value was requested or the DataType of the Value Attribute is not a subtype|
295
- * | | of the Structure DataType.|
296
- * |BadDataEncodingUnsupported | The server does not support the requested data encoding for the node. |
297
- * | | This result is used if a dataEncoding can be applied but the passed data encoding |
298
- * | | is not known to the Server. |
299
- * |BadNotReadable | The access level does not allow reading or subscribing to the Node.|
300
- * |BadUserAccessDenied | User does not have permission to perform the requested operation. (table 165)|
301
- */
302
- readValue(context, indexRange, dataEncoding) {
303
- if (!context) {
304
- context = session_context_1.SessionContext.defaultContext;
305
- }
306
- if (context.isAccessRestricted(this)) {
307
- return new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.BadSecurityModeInsufficient });
308
- }
309
- if (!this.isReadable(context)) {
310
- return new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.BadNotReadable });
311
- }
312
- if (!this.checkPermissionPrivate(context, node_opcua_types_1.PermissionType.Read)) {
313
- return new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.BadUserAccessDenied });
314
- }
315
- if (!this.isUserReadable(context)) {
316
- return new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.BadNotReadable });
317
- }
318
- if (!(0, node_opcua_data_model_1.isValidDataEncoding)(dataEncoding)) {
319
- return new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.BadDataEncodingInvalid });
320
- }
321
- if (this._timestamped_get_func) {
322
- if (this._timestamped_get_func.length === 0) {
323
- const dataValueOrPromise = this._timestamped_get_func();
324
- if (!Object.prototype.hasOwnProperty.call(dataValueOrPromise, "then")) {
325
- if (dataValueOrPromise !== this.$dataValue) {
326
- // TO DO : is this necessary ? this may interfere with current use of $dataValue
327
- this.$dataValue = dataValueOrPromise;
328
- this.verifyVariantCompatibility(this.$dataValue.value);
329
- }
330
- }
331
- else {
332
- errorLog("Unsupported: _timestamped_get_func returns a Promise !");
333
- }
334
- }
335
- }
336
- let dataValue = this.$dataValue;
337
- if (dataValue.statusCode.isGoodish()) {
338
- // note : extractRange will clone the dataValue
339
- dataValue = (0, node_opcua_data_value_1.extractRange)(dataValue, indexRange);
340
- }
341
- /* istanbul ignore next */
342
- if (dataValue.statusCode.equals(node_opcua_status_code_1.StatusCodes.BadWaitingForInitialData) ||
343
- dataValue.statusCode.equals(node_opcua_status_code_1.StatusCodes.UncertainInitialValue)) {
344
- debugLog(chalk.red(" Warning: UAVariable#readValue ") +
345
- chalk.cyan(this.browseName.toString()) +
346
- " (" +
347
- chalk.yellow(this.nodeId.toString()) +
348
- ") exists but dataValue has not been defined");
349
- }
350
- return dataValue;
351
- }
352
- isEnumeration() {
353
- return this.addressSpacePrivate.isEnumeration(this.dataType);
354
- }
355
- /**
356
- * return true if the DataType is of type Extension object
357
- * this is not taking into account the valueRank of the variable
358
- */
359
- isExtensionObject() {
360
- // DataType must be one of Structure
361
- if (this.dataType.isEmpty())
362
- return false;
363
- const dataTypeNode = this.addressSpace.findDataType(this.dataType);
364
- if (!dataTypeNode) {
365
- throw new Error(" Cannot find DataType " + this.dataType.toString() + " in standard address Space");
366
- }
367
- const structureNode = this.addressSpace.findDataType("Structure");
368
- if (!structureNode) {
369
- throw new Error(" Cannot find 'Structure' DataType in standard address Space");
370
- }
371
- return dataTypeNode.isSubtypeOf(structureNode);
372
- }
373
- _getEnumerationInfo() {
374
- // DataType must be one of Enumeration
375
- (0, node_opcua_assert_1.assert)(this.isEnumeration(), "Variable is not an enumeration");
376
- const dataTypeNode = this.addressSpace.findDataType(this.dataType);
377
- return dataTypeNode._getEnumerationInfo();
378
- }
379
- asyncRefresh(...args) {
380
- if (this.$dataValue.statusCode.isGoodish()) {
381
- this.verifyVariantCompatibility(this.$dataValue.value);
382
- }
383
- const oldestDate = args[0];
384
- (0, node_opcua_assert_1.assert)(oldestDate instanceof Date);
385
- const callback = args[1];
386
- if (!this.refreshFunc) {
387
- // no refresh func
388
- const dataValue = this.readValue();
389
- dataValue.serverTimestamp = oldestDate;
390
- dataValue.serverPicoseconds = 0;
391
- if (oldestDate.getTime() <= dataValue.serverTimestamp.getTime()) {
392
- return callback(null, dataValue);
393
- }
394
- else {
395
- // fake
396
- return callback(null, dataValue);
397
- }
398
- }
399
- if (this.$dataValue.serverTimestamp && oldestDate.getTime() <= this.$dataValue.serverTimestamp.getTime()) {
400
- const dataValue = this.readValue().clone();
401
- dataValue.serverTimestamp = oldestDate;
402
- dataValue.serverPicoseconds = 0;
403
- return callback(null, dataValue);
404
- }
405
- try {
406
- this.refreshFunc.call(this, (err, dataValue) => {
407
- // istanbul ignore next
408
- if (err || !dataValue) {
409
- errorLog("-------------- refresh call failed", this.browseName.toString(), this.nodeId.toString(), err === null || err === void 0 ? void 0 : err.message);
410
- dataValue = { statusCode: node_opcua_status_code_1.StatusCodes.BadNoDataAvailable };
411
- }
412
- if (dataValue && dataValue !== this.$dataValue) {
413
- this._internal_set_dataValue(coerceDataValue(dataValue), null);
414
- }
415
- callback(err, this.$dataValue);
416
- });
417
- }
418
- catch (err) {
419
- errorLog("-------------- refresh call failed 2", this.browseName.toString(), this.nodeId.toString());
420
- errorLog(err);
421
- const dataValue = new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.BadInternalError });
422
- this._internal_set_dataValue(dataValue, null);
423
- callback(err, this.$dataValue);
424
- }
425
- }
426
- readEnumValue() {
427
- const value = this.readValue().value.value;
428
- const enumInfo = this._getEnumerationInfo();
429
- const enumV = enumInfo.valueIndex[value];
430
- return { value, name: enumV ? enumV.name : "?????" };
431
- }
432
- writeEnumValue(value) {
433
- const enumInfo = this._getEnumerationInfo();
434
- if (typeof value === "string") {
435
- if (!Object.prototype.hasOwnProperty.call(enumInfo.nameIndex, value)) {
436
- const possibleValues = Object.keys(enumInfo.nameIndex).join(",");
437
- throw new Error("UAVariable#writeEnumValue: cannot find value " + value + " in [" + possibleValues + "]");
438
- }
439
- const valueIndex = enumInfo.nameIndex[value].value;
440
- value = valueIndex;
441
- }
442
- if (isFinite(value)) {
443
- const possibleValues = Object.keys(enumInfo.nameIndex).join(",");
444
- if (!enumInfo.valueIndex[value]) {
445
- throw new Error("UAVariable#writeEnumValue : value out of range " + value + " in [" + possibleValues + "]");
446
- }
447
- this.setValueFromSource({
448
- dataType: node_opcua_variant_1.DataType.Int32,
449
- value
450
- });
451
- }
452
- else {
453
- throw new Error("UAVariable#writeEnumValue: value type mismatch");
454
- }
455
- }
456
- readAttribute(context, attributeId, indexRange, dataEncoding) {
457
- context = context || session_context_1.SessionContext.defaultContext;
458
- (0, node_opcua_assert_1.assert)(context instanceof session_context_1.SessionContext);
459
- const options = {};
460
- if (attributeId !== node_opcua_data_model_1.AttributeIds.Value) {
461
- if (indexRange && indexRange.isDefined()) {
462
- options.statusCode = node_opcua_status_code_1.StatusCodes.BadIndexRangeNoData;
463
- return new node_opcua_data_value_1.DataValue(options);
464
- }
465
- if ((0, node_opcua_data_model_1.isDataEncoding)(dataEncoding)) {
466
- options.statusCode = node_opcua_status_code_1.StatusCodes.BadDataEncodingInvalid;
467
- return new node_opcua_data_value_1.DataValue(options);
468
- }
469
- }
470
- switch (attributeId) {
471
- case node_opcua_data_model_1.AttributeIds.Value:
472
- return this.readValue(context, indexRange, dataEncoding);
473
- case node_opcua_data_model_1.AttributeIds.DataType:
474
- return this._readDataType();
475
- case node_opcua_data_model_1.AttributeIds.ValueRank:
476
- return this._readValueRank();
477
- case node_opcua_data_model_1.AttributeIds.ArrayDimensions:
478
- return this._readArrayDimensions();
479
- case node_opcua_data_model_1.AttributeIds.AccessLevel:
480
- return this._readAccessLevel(context);
481
- case node_opcua_data_model_1.AttributeIds.UserAccessLevel:
482
- return this._readUserAccessLevel(context);
483
- case node_opcua_data_model_1.AttributeIds.MinimumSamplingInterval:
484
- return this._readMinimumSamplingInterval();
485
- case node_opcua_data_model_1.AttributeIds.Historizing:
486
- return this._readHistorizing();
487
- case node_opcua_data_model_1.AttributeIds.AccessLevelEx:
488
- return this._readAccessLevelEx(context);
489
- default:
490
- return base_node_impl_1.BaseNodeImpl.prototype.readAttribute.call(this, context, attributeId);
491
- }
492
- }
493
- getBasicDataType() {
494
- if (this._basicDataType) {
495
- return this._basicDataType;
496
- }
497
- if (this.dataType.namespace === 0 && this.dataType.value === 0) {
498
- return node_opcua_variant_1.DataType.Null;
499
- }
500
- const addressSpace = this.addressSpace;
501
- if (!addressSpace) {
502
- // may be node has been deleted already
503
- return node_opcua_variant_1.DataType.Null;
504
- }
505
- const dataTypeNode = addressSpace.findDataType(this.dataType);
506
- const basicDataType = dataTypeNode && dataTypeNode.nodeClass === node_opcua_data_model_1.NodeClass.DataType ? dataTypeNode.getBasicDataType() : node_opcua_variant_1.DataType.Null;
507
- // const basicDataType = addressSpace.findCorrespondingBasicDataType(this.dataType);
508
- this._basicDataType = basicDataType;
509
- return basicDataType;
510
- }
511
- adjustVariant(variant) {
512
- return (0, node_opcua_variant_1.adjustVariant)(variant, this.valueRank, this.getBasicDataType());
513
- }
514
- verifyVariantCompatibility(variant) {
515
- try {
516
- // istanbul ignore next
517
- if (Object.prototype.hasOwnProperty.call(variant, "value")) {
518
- if (variant.dataType === null || variant.dataType === undefined) {
519
- throw new Error("Variant must provide a valid dataType : variant = " +
520
- variant.toString() +
521
- " this.dataType= " +
522
- this.dataType.toString());
523
- }
524
- if (variant.dataType === node_opcua_variant_1.DataType.Boolean &&
525
- (this.dataType.namespace !== 0 || this.dataType.value !== node_opcua_variant_1.DataType.Boolean)) {
526
- throw new Error("Variant must provide a valid Boolean : variant = " +
527
- variant.toString() +
528
- " this.dataType= " +
529
- this.dataType.toString());
530
- }
531
- if (this.dataType.namespace === 0 &&
532
- this.dataType.value === node_opcua_variant_1.DataType.LocalizedText &&
533
- variant.dataType !== node_opcua_variant_1.DataType.LocalizedText &&
534
- variant.dataType !== node_opcua_variant_1.DataType.Null) {
535
- throw new Error("Variant must provide a valid LocalizedText : variant = " +
536
- variant.toString() +
537
- " this.dataType= " +
538
- this.dataType.toString());
539
- }
540
- }
541
- const basicType = this.getBasicDataType();
542
- if (basicType === node_opcua_variant_1.DataType.String && variant.dataType === node_opcua_variant_1.DataType.ByteString) {
543
- return; // this is allowed
544
- }
545
- if (basicType === node_opcua_variant_1.DataType.ByteString && variant.dataType === node_opcua_variant_1.DataType.String) {
546
- return; // this is allowed
547
- }
548
- if (basicType !== node_opcua_variant_1.DataType.Null &&
549
- basicType !== node_opcua_variant_1.DataType.Variant &&
550
- variant.dataType !== node_opcua_variant_1.DataType.Null &&
551
- variant.dataType !== basicType) {
552
- const message = "UAVariable.setValueFromSource " +
553
- this.browseName.toString() +
554
- " nodeId:" +
555
- this.nodeId.toString() +
556
- " dataType:" +
557
- this.dataType.toString() +
558
- ":\n" +
559
- "the provided variant must have the expected dataType!\n" +
560
- " - the expected dataType is " +
561
- chalk.cyan(node_opcua_variant_1.DataType[basicType]) +
562
- "\n" +
563
- " - the actual dataType is " +
564
- chalk.magenta(node_opcua_variant_1.DataType[variant.dataType]) +
565
- "\n" +
566
- " - " +
567
- variant.toString();
568
- throw new Error(message);
569
- }
570
- }
571
- catch (err) {
572
- errorLog("UAVariable ", err === null || err === void 0 ? void 0 : err.message, this.browseName.toString(), " nodeId=", this.nodeId.toString());
573
- errorLog(err.message);
574
- errorLog(err.stack);
575
- throw err;
576
- }
577
- }
578
- /**
579
- * setValueFromSource is used to let the device sets the variable values
580
- * this method also records the current time as sourceTimestamp and serverTimestamp.
581
- . *
582
- * The method will raise an exception if the value is not compatible with the dataType and expected dimension
583
- *
584
- * @method setValueFromSource
585
- * @param variant {Variant}
586
- * @param [statusCode {StatusCode} = StatusCodes.Good]
587
- * @param [sourceTimestamp= Now]
588
- */
589
- setValueFromSource(variant, statusCode, sourceTimestamp) {
590
- var _a;
591
- try {
592
- statusCode = statusCode || node_opcua_status_code_1.StatusCodes.Good;
593
- const variant1 = node_opcua_variant_1.Variant.coerce(variant);
594
- this.verifyVariantCompatibility(variant1);
595
- const now = (0, node_opcua_date_time_1.coerceClock)(sourceTimestamp, 0);
596
- const dataValue = new node_opcua_data_value_1.DataValue(null);
597
- dataValue.serverPicoseconds = now.picoseconds;
598
- dataValue.serverTimestamp = now.timestamp;
599
- dataValue.sourcePicoseconds = now.picoseconds;
600
- dataValue.sourceTimestamp = now.timestamp;
601
- dataValue.statusCode = statusCode;
602
- dataValue.value = variant1;
603
- if (dataValue.value.dataType === node_opcua_variant_1.DataType.ExtensionObject) {
604
- const valueIsCorrect = this.checkExtensionObjectIsCorrect(dataValue.value.value);
605
- if (!valueIsCorrect) {
606
- errorLog("setValueFromSource Invalid value !");
607
- errorLog(this.toString());
608
- errorLog(dataValue.toString());
609
- this.checkExtensionObjectIsCorrect(dataValue.value.value);
610
- }
611
- // ----------------------------------
612
- if (this.$extensionObject || this.$$extensionObjectArray) {
613
- // we have an extension object already bound to this node
614
- // the client is asking us to replace the object entierly by a new one
615
- // const ext = dataValue.value.value;
616
- this._internal_set_dataValue(dataValue);
617
- return;
618
- }
619
- else {
620
- this.$dataValue = dataValue;
621
- }
622
- }
623
- else {
624
- this._internal_set_dataValue(dataValue);
625
- }
626
- }
627
- catch (err) {
628
- errorLog("UAVariable#setValueFromString Error : ", this.browseName.toString(), this.nodeId.toString());
629
- errorLog(err.message);
630
- errorLog((_a = this.parent) === null || _a === void 0 ? void 0 : _a.toString());
631
- throw err;
632
- }
633
- }
634
- writeValue(context, dataValue, ...args) {
635
- context = context || session_context_1.SessionContext.defaultContext;
636
- (0, node_opcua_assert_1.assert)(context instanceof session_context_1.SessionContext);
637
- if (!dataValue.sourceTimestamp) {
638
- // source timestamp was not specified by the caller
639
- // we will set the timestamp ourself with the current clock
640
- if (context.currentTime) {
641
- dataValue.sourceTimestamp = context.currentTime.timestamp;
642
- dataValue.sourcePicoseconds = context.currentTime.picoseconds;
643
- }
644
- else {
645
- const { timestamp, picoseconds } = (0, node_opcua_date_time_1.getCurrentClock)();
646
- dataValue.sourceTimestamp = timestamp;
647
- dataValue.sourcePicoseconds = picoseconds;
648
- }
649
- }
650
- if (context.currentTime && !dataValue.serverTimestamp) {
651
- dataValue.serverTimestamp = context.currentTime.timestamp;
652
- dataValue.serverPicoseconds = context.currentTime.picoseconds;
653
- }
654
- // adjust arguments if optional indexRange Parameter is not given
655
- let indexRange = null;
656
- let callback;
657
- if (args.length === 1) {
658
- indexRange = new node_opcua_numeric_range_1.NumericRange();
659
- callback = args[0];
660
- }
661
- else if (args.length === 2) {
662
- indexRange = args[0];
663
- callback = args[1];
664
- }
665
- else {
666
- throw new Error("Invalid Number of args");
667
- }
668
- (0, node_opcua_assert_1.assert)(typeof callback === "function");
669
- (0, node_opcua_assert_1.assert)(dataValue instanceof node_opcua_data_value_1.DataValue);
670
- // index range could be string
671
- indexRange = node_opcua_numeric_range_1.NumericRange.coerce(indexRange);
672
- // test write permission
673
- if (!this.isWritable(context)) {
674
- return callback(null, node_opcua_status_code_1.StatusCodes.BadNotWritable);
675
- }
676
- if (!this.checkPermissionPrivate(context, node_opcua_types_1.PermissionType.Write)) {
677
- return new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.BadUserAccessDenied });
678
- }
679
- if (!this.isUserWritable(context)) {
680
- return callback(null, node_opcua_status_code_1.StatusCodes.BadWriteNotSupported);
681
- }
682
- // adjust special case
683
- const variant = adjustVariant2.call(this, dataValue.value);
684
- const statusCode = this.checkVariantCompatibility(variant);
685
- if (statusCode.isNot(node_opcua_status_code_1.StatusCodes.Good)) {
686
- return callback(null, statusCode);
687
- }
688
- const write_func = this._timestamped_set_func || default_func;
689
- if (!write_func) {
690
- warningLog(" warning " + this.nodeId.toString() + " " + this.browseName.toString() + " has no setter. \n");
691
- warningLog("Please make sure to bind the variable or to pass a valid value: new Variant({}) during construction time");
692
- return callback(null, node_opcua_status_code_1.StatusCodes.BadNotWritable);
693
- }
694
- (0, node_opcua_assert_1.assert)(write_func);
695
- write_func.call(this, dataValue, (err, statusCode1) => {
696
- if (!err) {
697
- dataValue && this.verifyVariantCompatibility(dataValue.value);
698
- if (indexRange && !indexRange.isEmpty()) {
699
- if (!indexRange.isValid()) {
700
- return callback(null, node_opcua_status_code_1.StatusCodes.BadIndexRangeInvalid);
701
- }
702
- const newArrayOrMatrix = dataValue.value.value;
703
- if (dataValue.value.arrayType === node_opcua_variant_1.VariantArrayType.Array) {
704
- if (this.$dataValue.value.arrayType !== node_opcua_variant_1.VariantArrayType.Array) {
705
- return callback(null, node_opcua_status_code_1.StatusCodes.BadTypeMismatch);
706
- }
707
- // check that destination data is also an array
708
- (0, node_opcua_assert_1.assert)(check_valid_array(this.$dataValue.value.dataType, this.$dataValue.value.value));
709
- const destArr = this.$dataValue.value.value;
710
- const result = indexRange.set_values(destArr, newArrayOrMatrix);
711
- if (result.statusCode.isNot(node_opcua_status_code_1.StatusCodes.Good)) {
712
- return callback(null, result.statusCode);
713
- }
714
- dataValue.value.value = result.array;
715
- // scrap original array so we detect range
716
- this.$dataValue.value.value = null;
717
- }
718
- else if (dataValue.value.arrayType === node_opcua_variant_1.VariantArrayType.Matrix) {
719
- const dimensions = this.$dataValue.value.dimensions;
720
- if (this.$dataValue.value.arrayType !== node_opcua_variant_1.VariantArrayType.Matrix || !dimensions) {
721
- // not a matrix !
722
- return callback(null, node_opcua_status_code_1.StatusCodes.BadTypeMismatch);
723
- }
724
- const matrix = this.$dataValue.value.value;
725
- const result = indexRange.set_values_matrix({
726
- matrix,
727
- dimensions
728
- }, newArrayOrMatrix);
729
- if (result.statusCode.isNot(node_opcua_status_code_1.StatusCodes.Good)) {
730
- return callback(null, result.statusCode);
731
- }
732
- dataValue.value.dimensions = this.$dataValue.value.dimensions;
733
- dataValue.value.value = result.matrix;
734
- // scrap original array so we detect range
735
- this.$dataValue.value.value = null;
736
- }
737
- else {
738
- return callback(null, node_opcua_status_code_1.StatusCodes.BadTypeMismatch);
739
- }
740
- }
741
- try {
742
- this._internal_set_dataValue(dataValue, indexRange);
743
- }
744
- catch (err) {
745
- if (err instanceof Error) {
746
- warningLog(err.message);
747
- }
748
- return callback(null, node_opcua_status_code_1.StatusCodes.BadInternalError);
749
- }
750
- }
751
- callback(err || null, statusCode1);
752
- });
753
- }
754
- writeAttribute(context, writeValueOptions, callback) {
755
- // istanbul ignore next
756
- if (!callback) {
757
- throw new Error("Internal error");
758
- }
759
- if (!this.canUserWriteAttribute(context, writeValueOptions.attributeId)) {
760
- return callback(null, node_opcua_status_code_1.StatusCodes.BadUserAccessDenied);
761
- }
762
- const writeValue = writeValueOptions instanceof node_opcua_service_write_1.WriteValue ? writeValueOptions : new node_opcua_service_write_1.WriteValue(writeValueOptions);
763
- context = context || session_context_1.SessionContext.defaultContext;
764
- (0, node_opcua_assert_1.assert)(context instanceof session_context_1.SessionContext);
765
- (0, node_opcua_assert_1.assert)(writeValue instanceof node_opcua_service_write_1.WriteValue);
766
- (0, node_opcua_assert_1.assert)(writeValue.value instanceof node_opcua_data_value_1.DataValue);
767
- (0, node_opcua_assert_1.assert)(writeValue.value.value instanceof node_opcua_variant_1.Variant);
768
- (0, node_opcua_assert_1.assert)(typeof callback === "function");
769
- // Spec 1.0.2 Part 4 page 58
770
- // If the SourceTimestamp or the ServerTimestamp is specified, the Server shall
771
- // use these values.
772
- // xx _apply_default_timestamps(writeValue.value);
773
- switch (writeValue.attributeId) {
774
- case node_opcua_data_model_1.AttributeIds.Value:
775
- this.writeValue(context, writeValue.value, writeValue.indexRange, callback);
776
- break;
777
- case node_opcua_data_model_1.AttributeIds.Historizing:
778
- if (writeValue.value.value.dataType !== node_opcua_variant_1.DataType.Boolean) {
779
- return callback(null, node_opcua_status_code_1.StatusCodes.BadTypeMismatch);
780
- }
781
- if (!this.checkPermissionPrivate(context, node_opcua_types_1.PermissionType.WriteHistorizing)) {
782
- return callback(null, node_opcua_status_code_1.StatusCodes.BadUserAccessDenied);
783
- }
784
- if (!this.canUserWriteHistorizingAttribute(context)) {
785
- return callback(null, node_opcua_status_code_1.StatusCodes.BadHistoryOperationUnsupported);
786
- }
787
- // if the variable has no historizing in place reject
788
- if (!this.getChildByName("HA Configuration")) {
789
- return callback(null, node_opcua_status_code_1.StatusCodes.BadNotSupported);
790
- }
791
- // check if user is allowed to do that !
792
- // TODO
793
- this.historizing = !!writeValue.value.value.value; // yes ! indeed !
794
- return callback(null, node_opcua_status_code_1.StatusCodes.Good);
795
- default:
796
- super.writeAttribute(context, writeValue, callback);
797
- break;
798
- }
799
- }
800
- /**
801
- * @method checkVariantCompatibility
802
- * note:
803
- * this method is overridden in address-space-data-access
804
- * @return {StatusCode}
805
- */
806
- checkVariantCompatibility(value) {
807
- // test dataType
808
- if (!this._validate_DataType(value.dataType)) {
809
- return node_opcua_status_code_1.StatusCodes.BadTypeMismatch;
810
- }
811
- try {
812
- this.verifyVariantCompatibility(value);
813
- }
814
- catch (err) {
815
- return node_opcua_status_code_1.StatusCodes.BadTypeMismatch;
816
- }
817
- return node_opcua_status_code_1.StatusCodes.Good;
818
- }
819
- /**
820
- * touch the source timestamp of a Variable and cascade up the change
821
- * to the parent variable if any.
822
- */
823
- touchValue(optionalNow) {
824
- const now = optionalNow || (0, node_opcua_date_time_1.getCurrentClock)();
825
- (0, ua_variable_impl_ext_obj_1.propagateTouchValueUpward)(this, now);
826
- }
827
- /**
828
- * bind a variable with a get and set functions.
829
- *
830
- * properties:
831
- * - value: a Variant or a status code
832
- * - sourceTimestamp
833
- * - sourcePicoseconds
834
- * @param [options.timestamped_set]
835
- * @param [options.refreshFunc] the variable asynchronous getter function.
836
- * @param [overwrite {Boolean} = false] set overwrite to true to overwrite existing binding
837
- * @return void
838
- *
839
- *
840
- * ### Providing read access to the underlying value
841
- *
842
- * #### Variation 1
843
- *
844
- * In this variation, the user provides a function that returns a Variant with the current value.
845
- *
846
- * The sourceTimestamp will be set automatically.
847
- *
848
- * The get function is called synchronously.
849
- *
850
- * @example
851
- *
852
- *
853
- * ```javascript
854
- * ...
855
- * var options = {
856
- * get : () => {
857
- * return new Variant({...});
858
- * },
859
- * set : function(variant) {
860
- * // store the variant somewhere
861
- * return StatusCodes.Good;
862
- * }
863
- * };
864
- * ...
865
- * engine.bindVariable(nodeId,options):
866
- * ...
867
- * ```
868
- *
869
- *
870
- * #### Variation 2:
871
- *
872
- * This variation can be used when the user wants to specify a specific '''sourceTimestamp''' associated
873
- * with the current value of the UAVariable.
874
- *
875
- * The provided ```timestamped_get``` function should return an object with three properties:
876
- * * value: containing the variant value or a error StatusCode,
877
- * * sourceTimestamp
878
- * * sourcePicoseconds
879
- *
880
- * ```javascript
881
- * ...
882
- * var myDataValue = new DataValue({
883
- * value: {dataType: DataType.Double , value: 10.0},
884
- * sourceTimestamp : new Date(),
885
- * sourcePicoseconds: 0
886
- * });
887
- * ...
888
- * var options = {
889
- * timestamped_get : () => { return myDataValue; }
890
- * };
891
- * ...
892
- * engine.bindVariable(nodeId,options):
893
- * ...
894
- * // record a new value
895
- * myDataValue.value.value = 5.0;
896
- * myDataValue.sourceTimestamp = new Date();
897
- * ...
898
- * ```
899
- *
900
- *
901
- * #### Variation 3:
902
- *
903
- * This variation can be used when the value associated with the variables requires a asynchronous function call to be
904
- * extracted. In this case, the user should provide an async method ```refreshFunc```.
905
- *
906
- *
907
- * The ```refreshFunc``` shall do whatever is necessary to fetch the most up to date version of the variable value, and
908
- * call the ```callback``` function when the data is ready.
909
- *
910
- *
911
- * The ```callback``` function follow the standard callback function signature:
912
- * * the first argument shall be **null** or **Error**, depending of the outcome of the fetch operation,
913
- * * the second argument shall be a DataValue with the new UAVariable Value, a StatusCode, and time stamps.
914
- *
915
- *
916
- * Optionally, it is possible to pass a sourceTimestamp and a sourcePicoseconds value as a third and fourth arguments
917
- * of the callback. When sourceTimestamp and sourcePicoseconds are missing, the system will set their default value
918
- * to the current time..
919
- *
920
- *
921
- * ```javascript
922
- * ...
923
- * var options = {
924
- * refreshFunc : function(callback) {
925
- * ... do_some_async_stuff_to_get_the_new_variable_value
926
- * var dataValue = new DataValue({
927
- * value: new Variant({...}),
928
- * statusCode: StatusCodes.Good,
929
- * sourceTimestamp: new Date()
930
- * });
931
- * callback(null,dataValue);
932
- * }
933
- * };
934
- * ...
935
- * variable.bindVariable(nodeId,options):
936
- * ...
937
- * ```
938
- *
939
- * ### Providing write access to the underlying value
940
- *
941
- * #### Variation1 - provide a simple synchronous set function
942
- *
943
- *
944
- * #### Notes
945
- * to do : explain return StatusCodes.GoodCompletesAsynchronously;
946
- *
947
- */
948
- bindVariable(options, overwrite) {
949
- if (overwrite) {
950
- this._timestamped_set_func = null;
951
- this._timestamped_get_func = null;
952
- this._get_func = null;
953
- this._set_func = null;
954
- this.refreshFunc = undefined;
955
- this._historyRead = UAVariableImpl.prototype._historyRead;
956
- }
957
- options = options || {};
958
- (0, node_opcua_assert_1.assert)(typeof this._timestamped_set_func !== "function", "UAVariable already bound");
959
- (0, node_opcua_assert_1.assert)(typeof this._timestamped_get_func !== "function", "UAVariable already bound");
960
- bind_getter.call(this, options);
961
- bind_setter.call(this, options);
962
- const _historyRead = options.historyRead;
963
- if (_historyRead) {
964
- (0, node_opcua_assert_1.assert)(typeof this._historyRead !== "function" || this._historyRead === UAVariableImpl.prototype._historyRead);
965
- (0, node_opcua_assert_1.assert)(typeof _historyRead === "function");
966
- this._historyRead = _historyRead;
967
- (0, node_opcua_assert_1.assert)(this._historyRead.length === 6);
968
- }
969
- // post conditions
970
- (0, node_opcua_assert_1.assert)(typeof this._timestamped_set_func === "function");
971
- (0, node_opcua_assert_1.assert)(this._timestamped_set_func.length === 2, "expecting 2 parameters");
972
- }
973
- readValueAsync(context, callback) {
974
- (0, node_opcua_assert_1.assert)(typeof callback === "function");
975
- context = context || session_context_1.SessionContext.defaultContext;
976
- this.__waiting_callbacks = this.__waiting_callbacks || [];
977
- this.__waiting_callbacks.push(callback);
978
- const _readValueAsync_in_progress = this.__waiting_callbacks.length >= 2;
979
- if (_readValueAsync_in_progress) {
980
- return;
981
- }
982
- if (this.isDisposed()) {
983
- return callback(null, new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.BadNodeIdUnknown }));
984
- }
985
- const readImmediate = (innerCallback) => {
986
- (0, node_opcua_assert_1.assert)(this.$dataValue instanceof node_opcua_data_value_1.DataValue);
987
- const dataValue = this.readValue();
988
- innerCallback(null, dataValue);
989
- };
990
- let func;
991
- if (!this.isReadable(context)) {
992
- func = (innerCallback) => {
993
- const dataValue = new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.BadNotReadable });
994
- innerCallback(null, dataValue);
995
- };
996
- }
997
- else if (!this.checkPermissionPrivate(context, node_opcua_types_1.PermissionType.Read)) {
998
- func = (innerCallback) => {
999
- const dataValue = new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.BadUserAccessDenied });
1000
- innerCallback(null, dataValue);
1001
- };
1002
- }
1003
- else if (!this.isUserReadable(context)) {
1004
- func = (innerCallback) => {
1005
- const dataValue = new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.BadNotReadable });
1006
- innerCallback(null, dataValue);
1007
- };
1008
- }
1009
- else {
1010
- func = typeof this.refreshFunc === "function" ? this.asyncRefresh.bind(this, new Date()) : readImmediate;
1011
- }
1012
- const satisfy_callbacks = (err, dataValue) => {
1013
- // now call all pending callbacks
1014
- const callbacks = this.__waiting_callbacks || [];
1015
- this.__waiting_callbacks = [];
1016
- const n = callbacks.length;
1017
- for (const callback1 of callbacks) {
1018
- callback1.call(this, err, dataValue);
1019
- }
1020
- };
1021
- try {
1022
- func.call(this, satisfy_callbacks);
1023
- }
1024
- catch (err) {
1025
- // istanbul ignore next
1026
- if (doDebug) {
1027
- debugLog(chalk.red("func readValueAsync has failed "));
1028
- if (err instanceof Error) {
1029
- debugLog(" stack", err.stack);
1030
- }
1031
- }
1032
- satisfy_callbacks(err);
1033
- }
1034
- }
1035
- getWriteMask() {
1036
- return super.getWriteMask();
1037
- }
1038
- getUserWriteMask() {
1039
- return super.getUserWriteMask();
1040
- }
1041
- clone(options, optionalFilter, extraInfo) {
1042
- options = Object.assign(Object.assign({}, options), {
1043
- // check this eventNotifier: this.eventNotifier,
1044
- // check this symbolicName: this.symbolicName,
1045
- accessLevel: this.accessLevel, arrayDimensions: this.arrayDimensions, dataType: this.dataType, historizing: this.historizing, minimumSamplingInterval: this.minimumSamplingInterval, userAccessLevel: this.userAccessLevel, valueRank: this.valueRank });
1046
- const newVariable = base_node_private_1._clone.call(this, UAVariableImpl, options, optionalFilter || node_opcua_address_space_base_1.defaultCloneFilter, extraInfo || node_opcua_address_space_base_1.defaultCloneExtraInfo);
1047
- newVariable.bindVariable();
1048
- (0, node_opcua_assert_1.assert)(typeof newVariable._timestamped_set_func === "function");
1049
- (0, node_opcua_assert_1.assert)(newVariable.dataType === this.dataType);
1050
- newVariable.$dataValue = this.$dataValue.clone();
1051
- // also bind extension object
1052
- const v = newVariable.$dataValue.value;
1053
- if (v.dataType === node_opcua_variant_1.DataType.ExtensionObject && v.value && v.arrayType === node_opcua_variant_1.VariantArrayType.Scalar) {
1054
- try {
1055
- newVariable.bindExtensionObject(newVariable.$dataValue.value.value);
1056
- }
1057
- catch (err) {
1058
- errorLog("Errro binding extension objects");
1059
- errorLog(err.message);
1060
- errorLog(this.toString());
1061
- errorLog("---------------------------------------");
1062
- errorLog(this.$dataValue.toString());
1063
- errorLog("---------------------------------------");
1064
- errorLog(newVariable.$dataValue.toString());
1065
- throw err;
1066
- }
1067
- }
1068
- return newVariable;
1069
- }
1070
- getDataTypeNode() {
1071
- const addressSpace = this.addressSpace;
1072
- const dt = addressSpace.findNode(this.dataType);
1073
- // istanbul ignore next
1074
- if (!dt) {
1075
- throw new Error("getDataTypeNode: cannot find dataType " + this.dataType.toString());
1076
- }
1077
- return dt;
1078
- }
1079
- get dataTypeObj() {
1080
- return this.getDataTypeNode();
1081
- }
1082
- checkExtensionObjectIsCorrect(extObj) {
1083
- if (!extObj) {
1084
- return true;
1085
- }
1086
- const addressSpace = this.addressSpace;
1087
- const dataType = addressSpace.findDataType(this.dataType);
1088
- if (!dataType) {
1089
- // may be we are in the process of loading a xml file and the corresponding dataType
1090
- // has not yet been loaded !
1091
- return true;
1092
- }
1093
- const Constructor = addressSpace.getExtensionObjectConstructor(this.dataType);
1094
- if (this.valueRank === -1) {
1095
- /** Scalar */
1096
- if (extObj instanceof Array) {
1097
- return false;
1098
- }
1099
- return checkExtensionObjectIsCorrectScalar.call(this, extObj);
1100
- }
1101
- else if (this.valueRank >= 1) {
1102
- /** array */
1103
- if (!(extObj instanceof Array)) {
1104
- // let's coerce this scalar into an 1-element array if it is a valid extension object
1105
- if (checkExtensionObjectIsCorrectScalar.call(this, extObj)) {
1106
- warningLog(`warning: checkExtensionObjectIsCorrect : expecting a array but got a scalar (value rank of '${this.browseName.toString()}' is 1)\nautomatic conversion from scalar to array with 1 element is taking place.`);
1107
- extObj = [extObj];
1108
- }
1109
- else {
1110
- return false;
1111
- }
1112
- }
1113
- return checkExtensionObjectIsCorrectArray.call(this, extObj);
1114
- }
1115
- else if (this.valueRank === 0) {
1116
- // Scalar or Array
1117
- const isCorrectScalar = !Array.isArray(extObj) && checkExtensionObjectIsCorrectScalar.call(this, extObj);
1118
- const isCorrectArray = Array.isArray(extObj) && checkExtensionObjectIsCorrectArray.call(this, extObj);
1119
- return isCorrectArray || isCorrectScalar;
1120
- }
1121
- else {
1122
- throw new Error(`checkExtensionObjectIsCorrect: Not Implemented case, please contact sterfive : this.valueRank =${this.valueRank}`);
1123
- }
1124
- function checkExtensionObjectIsCorrectScalar(extObj) {
1125
- // istanbul ignore next
1126
- if (!(extObj && extObj.constructor)) {
1127
- errorLog(extObj);
1128
- throw new Error("expecting an valid extension object");
1129
- }
1130
- return extObj.constructor.name === Constructor.name;
1131
- }
1132
- function checkExtensionObjectIsCorrectArray(extObjArray) {
1133
- // istanbul ignore next
1134
- for (const extObj of extObjArray) {
1135
- if (!(extObj && extObj.constructor)) {
1136
- errorLog(extObj);
1137
- throw new Error("expecting an valid extension object");
1138
- }
1139
- }
1140
- try {
1141
- for (const e of extObjArray) {
1142
- if (!e) {
1143
- continue;
1144
- }
1145
- if (e.constructor.name !== Constructor.name) {
1146
- debugLog("extObj.constructor.name ", e.constructor.name, "expected", Constructor.name);
1147
- return false;
1148
- }
1149
- }
1150
- return true;
1151
- }
1152
- catch (err) {
1153
- errorLog(err);
1154
- return false;
1155
- }
1156
- }
1157
- }
1158
- /**
1159
- * @private
1160
- * install UAVariable to exposed th
1161
- *
1162
- * precondition:
1163
- */
1164
- installExtensionObjectVariables() {
1165
- (0, ua_variable_impl_ext_obj_1._installExtensionObjectBindingOnProperties)(this, { createMissingProp: true });
1166
- }
1167
- /**
1168
- * @method bindExtensionObject
1169
- * @return {ExtensionObject}
1170
- */
1171
- bindExtensionObjectScalar(optionalExtensionObject, options) {
1172
- (0, node_opcua_assert_1.assert)(this.valueRank === -1, "expecting an Scalar variable here");
1173
- return (0, ua_variable_impl_ext_obj_1._bindExtensionObject)(this, optionalExtensionObject, options);
1174
- }
1175
- bindExtensionObjectArray(optionalExtensionObject, options) {
1176
- (0, node_opcua_assert_1.assert)(this.valueRank >= 1, "expecting an Array or a Matrix variable here");
1177
- return (0, ua_variable_impl_ext_obj_1._bindExtensionObjectArrayOrMatrix)(this, optionalExtensionObject, options);
1178
- }
1179
- bindExtensionObject(optionalExtensionObject, options) {
1180
- // coerce to ExtensionObject[] when this.valueRank === 1
1181
- if (optionalExtensionObject && this.valueRank === 1 && !Array.isArray(optionalExtensionObject) && optionalExtensionObject instanceof node_opcua_extension_object_1.ExtensionObject) {
1182
- warningLog("bindExtensionObject: coerce to ExtensionObject[] when valueRank === 1 and value is a scalar extension object");
1183
- optionalExtensionObject = [optionalExtensionObject];
1184
- }
1185
- if (optionalExtensionObject) {
1186
- if (optionalExtensionObject instanceof Array) {
1187
- (0, node_opcua_assert_1.assert)(this.valueRank >= 1, "bindExtensionObject: expecting an Array of Matrix variable here");
1188
- return (0, ua_variable_impl_ext_obj_1._bindExtensionObjectArrayOrMatrix)(this, optionalExtensionObject, options);
1189
- }
1190
- else {
1191
- if (this.valueRank !== -1 && this.valueRank !== 0) {
1192
- throw new Error("bindExtensionObject: expecting an Scalar variable here but got value rank " + this.valueRank);
1193
- }
1194
- return (0, ua_variable_impl_ext_obj_1._bindExtensionObject)(this, optionalExtensionObject, options);
1195
- }
1196
- }
1197
- (0, node_opcua_assert_1.assert)(optionalExtensionObject === undefined);
1198
- if (this.valueRank === -1) {
1199
- return (0, ua_variable_impl_ext_obj_1._bindExtensionObject)(this, undefined, options);
1200
- }
1201
- else if (this.valueRank === 1) {
1202
- return (0, ua_variable_impl_ext_obj_1._bindExtensionObjectArrayOrMatrix)(this, undefined, options);
1203
- }
1204
- else if (this.valueRank > 1) {
1205
- return (0, ua_variable_impl_ext_obj_1._bindExtensionObjectArrayOrMatrix)(this, undefined, options);
1206
- }
1207
- // unsupported case ...
1208
- return null;
1209
- }
1210
- updateExtensionObjectPartial(partialExtensionObject) {
1211
- (0, ua_variable_impl_ext_obj_1.setExtensionObjectPartialValue)(this, partialExtensionObject);
1212
- return this.$extensionObject;
1213
- }
1214
- incrementExtensionObjectPartial(path) {
1215
- const extensionObject = this.readValue().value.value;
1216
- const partialData = (0, ua_variable_impl_ext_obj_1.extractPartialData)(path, extensionObject);
1217
- (0, ua_variable_impl_ext_obj_1.incrementElement)(path, partialData);
1218
- (0, ua_variable_impl_ext_obj_1.setExtensionObjectPartialValue)(this, partialData);
1219
- }
1220
- toString() {
1221
- const options = new base_node_private_1.ToStringBuilder();
1222
- base_node_private_1.UAVariable_toString.call(this, options);
1223
- return options.toString();
1224
- }
1225
- historyRead(context, historyReadDetails, indexRange, dataEncoding, continuationData, callback) {
1226
- (0, node_opcua_assert_1.assert)(context instanceof session_context_1.SessionContext);
1227
- (0, node_opcua_assert_1.assert)(typeof callback === "function");
1228
- if (typeof this._historyRead !== "function") {
1229
- return callback(null, new node_opcua_types_1.HistoryReadResult({ statusCode: node_opcua_status_code_1.StatusCodes.BadNotReadable }));
1230
- }
1231
- this._historyRead(context, historyReadDetails, indexRange, dataEncoding, continuationData, callback);
1232
- }
1233
- _historyReadRaw(context, historyReadRawModifiedDetails, indexRange, dataEncoding, continuationData, callback) {
1234
- throw new Error("");
1235
- }
1236
- _historyReadRawModify(context, historyReadRawModifiedDetails, indexRange, dataEncoding, continuationData, callback) {
1237
- throw new Error("");
1238
- }
1239
- _historyRead(context, historyReadDetails, indexRange, dataEncoding, continuationData, callback) {
1240
- if (!this.checkPermissionPrivate(context, node_opcua_types_1.PermissionType.ReadHistory)) {
1241
- const result = new node_opcua_types_1.HistoryReadResult({
1242
- statusCode: node_opcua_status_code_1.StatusCodes.BadUserAccessDenied
1243
- });
1244
- callback(null, result);
1245
- }
1246
- if (!this.canUserReadHistory(context)) {
1247
- const result = new node_opcua_types_1.HistoryReadResult({
1248
- statusCode: node_opcua_status_code_1.StatusCodes.BadHistoryOperationUnsupported
1249
- });
1250
- callback(null, result);
1251
- }
1252
- const result = new node_opcua_types_1.HistoryReadResult({
1253
- statusCode: node_opcua_status_code_1.StatusCodes.BadHistoryOperationUnsupported
1254
- });
1255
- callback(null, result);
1256
- }
1257
- _historyPush(newDataValue) {
1258
- throw new Error("");
1259
- }
1260
- _historyReadRawAsync(historyReadRawModifiedDetails, maxNumberToExtract, isReversed, reverseDataValue, callback) {
1261
- throw new Error("");
1262
- }
1263
- _historyReadModify(context, historyReadRawModifiedDetails, indexRange, dataEncoding, continuationData, callback) {
1264
- throw new Error("");
1265
- }
1266
- _update_startOfOnlineArchive(newDate) {
1267
- // please install
1268
- throw new Error("");
1269
- }
1270
- _update_startOfArchive(newDate) {
1271
- throw new Error("");
1272
- }
1273
- _validate_DataType(variantDataType) {
1274
- return validateDataType(this.addressSpace, this.dataType, variantDataType, this.nodeId, /* allow Nulls */ false);
1275
- }
1276
- _internal_set_value(value) {
1277
- if (value.dataType !== node_opcua_variant_1.DataType.Null) {
1278
- this.verifyVariantCompatibility(value);
1279
- }
1280
- this.$dataValue.value = value;
1281
- }
1282
- _internal_set_dataValue(dataValue, indexRange) {
1283
- (0, node_opcua_assert_1.assert)(dataValue, "expecting a dataValue");
1284
- (0, node_opcua_assert_1.assert)(dataValue instanceof node_opcua_data_value_1.DataValue, "expecting dataValue to be a DataValue");
1285
- (0, node_opcua_assert_1.assert)(dataValue !== this.$dataValue, "expecting dataValue to be different from previous DataValue instance");
1286
- const addressSpace = this.addressSpace;
1287
- // istanbul ignore next
1288
- if (!addressSpace) {
1289
- warningLog("UAVariable#_internal_set_dataValue : no addressSpace ! may be node has already been deleted ?");
1290
- return;
1291
- }
1292
- // istanbul ignore next
1293
- if (dataValue.value.arrayType === node_opcua_variant_1.VariantArrayType.Matrix) {
1294
- if (!dataValue.value.dimensions) {
1295
- throw new Error("missing dimensions: a Matrix Variant needs a dimension");
1296
- }
1297
- const nbElements = dataValue.value.dimensions.reduce((acc, x) => acc * x, 1);
1298
- if (dataValue.value.value.length !== 0 && dataValue.value.value.length !== nbElements) {
1299
- throw new Error(`Internal Error: matrix dimension doesn't match the number of element in the array : ${dataValue.toString()} "\n expecting ${nbElements} elements but got ${dataValue.value.value.length}`);
1300
- }
1301
- }
1302
- // istanbul ignore next
1303
- if (dataValue.value.dataType === node_opcua_variant_1.DataType.ExtensionObject) {
1304
- // istanbul ignore next
1305
- if (!this.checkExtensionObjectIsCorrect(dataValue.value.value)) {
1306
- warningLog(dataValue.toString());
1307
- throw new Error("Invalid Extension Object on nodeId =" + this.nodeId.toString());
1308
- }
1309
- }
1310
- this.verifyVariantCompatibility(dataValue.value);
1311
- this._inner_replace_dataValue(dataValue, indexRange);
1312
- }
1313
- /**
1314
- * @private
1315
- */
1316
- _inner_replace_dataValue(dataValue, indexRange) {
1317
- (0, node_opcua_assert_1.assert)(this.$dataValue.value instanceof node_opcua_variant_1.Variant);
1318
- const old_dataValue = this.$dataValue.clone();
1319
- if (this.$$extensionObjectArray && dataValue.value.arrayType !== node_opcua_variant_1.VariantArrayType.Scalar) {
1320
- // we have a bounded array or matrix
1321
- (0, node_opcua_assert_1.assert)(Array.isArray(dataValue.value.value));
1322
- if (this.$$extensionObjectArray !== this.$dataValue.value.value) {
1323
- throw new Error("internal error");
1324
- }
1325
- this.$$extensionObjectArray = dataValue.value.value;
1326
- this.$dataValue.value.value = dataValue.value.value;
1327
- this.$dataValue.statusCode = dataValue.statusCode || node_opcua_status_code_1.StatusCodes.Good;
1328
- this.$dataValue.serverTimestamp = dataValue.serverTimestamp;
1329
- this.$dataValue.serverPicoseconds = dataValue.serverPicoseconds;
1330
- this.$dataValue.sourceTimestamp = dataValue.sourceTimestamp;
1331
- this.$dataValue.sourcePicoseconds = dataValue.sourcePicoseconds;
1332
- }
1333
- else if (this._basicDataType === node_opcua_variant_1.DataType.ExtensionObject && this.valueRank === -1 && this.$set_ExtensionObject && dataValue.value.arrayType === node_opcua_variant_1.VariantArrayType.Scalar) {
1334
- // the entire extension object is changed.
1335
- this.$dataValue.statusCode = this.$dataValue.statusCode || node_opcua_status_code_1.StatusCodes.Good;
1336
- const preciseClock = (0, node_opcua_date_time_1.coerceClock)(this.$dataValue.sourceTimestamp, this.$dataValue.sourcePicoseconds);
1337
- this.$set_ExtensionObject(dataValue.value.value, preciseClock, new Set());
1338
- }
1339
- else {
1340
- this.$dataValue = dataValue;
1341
- this.$dataValue.statusCode = this.$dataValue.statusCode || node_opcua_status_code_1.StatusCodes.Good;
1342
- }
1343
- // repair missing timestamps
1344
- const now = new Date();
1345
- if (!dataValue.serverTimestamp) {
1346
- this.$dataValue.serverTimestamp = old_dataValue.serverTimestamp || now;
1347
- this.$dataValue.serverPicoseconds = old_dataValue.serverPicoseconds || 0;
1348
- }
1349
- if (!dataValue.sourceTimestamp) {
1350
- this.$dataValue.sourceTimestamp = old_dataValue.sourceTimestamp || now;
1351
- this.$dataValue.sourcePicoseconds = old_dataValue.sourcePicoseconds || 0;
1352
- }
1353
- if (!(0, node_opcua_data_value_1.sameDataValue)(old_dataValue, dataValue)) {
1354
- if (this.getBasicDataType() === node_opcua_variant_1.DataType.ExtensionObject) {
1355
- const preciseClock = (0, node_opcua_date_time_1.coerceClock)(this.$dataValue.sourceTimestamp, this.$dataValue.sourcePicoseconds);
1356
- const cache = new Set();
1357
- if (this.$$extensionObjectArray) {
1358
- this.touchValue(preciseClock);
1359
- (0, ua_variable_impl_ext_obj_1.propagateTouchValueDownwardArray)(this, preciseClock, cache);
1360
- }
1361
- else {
1362
- this.touchValue(preciseClock);
1363
- (0, ua_variable_impl_ext_obj_1.propagateTouchValueDownward)(this, preciseClock, cache);
1364
- }
1365
- }
1366
- else {
1367
- this.emit("value_changed", this.$dataValue.clone(), indexRange);
1368
- }
1369
- }
1370
- }
1371
- _conditionRefresh(_cache) {
1372
- apply_condition_refresh_1.apply_condition_refresh.call(this, _cache);
1373
- }
1374
- handle_semantic_changed() {
1375
- this.semantic_version = this.semantic_version + 1;
1376
- this.emit("semantic_changed");
1377
- }
1378
- _readDataType() {
1379
- (0, node_opcua_assert_1.assert)(this.dataType instanceof node_opcua_nodeid_1.NodeId);
1380
- const options = {
1381
- statusCode: node_opcua_status_code_1.StatusCodes.Good,
1382
- value: {
1383
- dataType: node_opcua_variant_1.DataType.NodeId,
1384
- value: this.dataType
1385
- }
1386
- };
1387
- return new node_opcua_data_value_1.DataValue(options);
1388
- }
1389
- _readValueRank() {
1390
- (0, node_opcua_assert_1.assert)(typeof this.valueRank === "number");
1391
- const options = {
1392
- statusCode: node_opcua_status_code_1.StatusCodes.Good,
1393
- value: { dataType: node_opcua_variant_1.DataType.Int32, value: this.valueRank }
1394
- };
1395
- return new node_opcua_data_value_1.DataValue(options);
1396
- }
1397
- _readArrayDimensions() {
1398
- (0, node_opcua_assert_1.assert)(Array.isArray(this.arrayDimensions) || this.arrayDimensions === null);
1399
- (0, node_opcua_assert_1.assert)(!this.arrayDimensions || this.valueRank > 0, "arrayDimension must be null if valueRank <0");
1400
- const options = {
1401
- statusCode: node_opcua_status_code_1.StatusCodes.Good,
1402
- value: { dataType: node_opcua_variant_1.DataType.UInt32, arrayType: node_opcua_variant_1.VariantArrayType.Array, value: this.arrayDimensions }
1403
- };
1404
- return new node_opcua_data_value_1.DataValue(options);
1405
- }
1406
- _readAccessLevel(context) {
1407
- (0, node_opcua_assert_1.assert)(context instanceof session_context_1.SessionContext);
1408
- const options = {
1409
- statusCode: node_opcua_status_code_1.StatusCodes.Good,
1410
- value: { dataType: node_opcua_variant_1.DataType.Byte, value: (0, node_opcua_data_model_1.convertAccessLevelFlagToByte)(this.accessLevel) }
1411
- };
1412
- return new node_opcua_data_value_1.DataValue(options);
1413
- }
1414
- _readAccessLevelEx(context) {
1415
- (0, node_opcua_assert_1.assert)(context instanceof session_context_1.SessionContext);
1416
- const options = {
1417
- statusCode: node_opcua_status_code_1.StatusCodes.Good,
1418
- // Extra flags are not supported yet. to do:
1419
- value: { dataType: node_opcua_variant_1.DataType.UInt32, value: (0, node_opcua_data_model_1.convertAccessLevelFlagToByte)(this.accessLevel) }
1420
- };
1421
- return new node_opcua_data_value_1.DataValue(options);
1422
- }
1423
- _readUserAccessLevel(context) {
1424
- (0, node_opcua_assert_1.assert)(context instanceof session_context_1.SessionContext);
1425
- const effectiveUserAccessLevel = _calculateEffectiveUserAccessLevelFromPermission(this, context, this.userAccessLevel);
1426
- const options = {
1427
- value: {
1428
- dataType: node_opcua_variant_1.DataType.Byte,
1429
- statusCode: node_opcua_status_code_1.StatusCodes.Good,
1430
- value: (0, node_opcua_data_model_1.convertAccessLevelFlagToByte)(effectiveUserAccessLevel)
1431
- }
1432
- };
1433
- return new node_opcua_data_value_1.DataValue(options);
1434
- }
1435
- _readMinimumSamplingInterval() {
1436
- // expect a Duration => Double
1437
- const options = {};
1438
- if (this.minimumSamplingInterval === undefined) {
1439
- options.statusCode = node_opcua_status_code_1.StatusCodes.BadAttributeIdInvalid;
1440
- }
1441
- else {
1442
- options.value = { dataType: node_opcua_variant_1.DataType.Double, value: this.minimumSamplingInterval };
1443
- options.statusCode = node_opcua_status_code_1.StatusCodes.Good;
1444
- }
1445
- return new node_opcua_data_value_1.DataValue(options);
1446
- }
1447
- _readHistorizing() {
1448
- (0, node_opcua_assert_1.assert)(typeof this.historizing === "boolean");
1449
- const options = {
1450
- statusCode: node_opcua_status_code_1.StatusCodes.Good,
1451
- value: { dataType: node_opcua_variant_1.DataType.Boolean, value: !!this.historizing }
1452
- };
1453
- return new node_opcua_data_value_1.DataValue(options);
1454
- }
1455
- }
1456
- exports.UAVariableImpl = UAVariableImpl;
1457
- // tslint:disable:no-var-requires
1458
- const thenify = require("thenify");
1459
- UAVariableImpl.prototype.asyncRefresh = thenify.withCallback(UAVariableImpl.prototype.asyncRefresh);
1460
- UAVariableImpl.prototype.writeValue = thenify.withCallback(UAVariableImpl.prototype.writeValue);
1461
- UAVariableImpl.prototype.writeAttribute = thenify.withCallback(UAVariableImpl.prototype.writeAttribute);
1462
- UAVariableImpl.prototype.historyRead = thenify.withCallback(UAVariableImpl.prototype.historyRead);
1463
- UAVariableImpl.prototype.readValueAsync = thenify.withCallback(UAVariableImpl.prototype.readValueAsync);
1464
- function check_valid_array(dataType, array) {
1465
- if (Array.isArray(array)) {
1466
- return true;
1467
- }
1468
- switch (dataType) {
1469
- case node_opcua_variant_1.DataType.Double:
1470
- return array instanceof Float64Array;
1471
- case node_opcua_variant_1.DataType.Float:
1472
- return array instanceof Float32Array;
1473
- case node_opcua_variant_1.DataType.Int32:
1474
- return array instanceof Int32Array;
1475
- case node_opcua_variant_1.DataType.Int16:
1476
- return array instanceof Int16Array;
1477
- case node_opcua_variant_1.DataType.SByte:
1478
- return array instanceof Int8Array;
1479
- case node_opcua_variant_1.DataType.UInt32:
1480
- return array instanceof Uint32Array;
1481
- case node_opcua_variant_1.DataType.UInt16:
1482
- return array instanceof Uint16Array;
1483
- case node_opcua_variant_1.DataType.Byte:
1484
- return array instanceof Uint8Array || array instanceof Buffer;
1485
- }
1486
- return false;
1487
- }
1488
- function _apply_default_timestamps(dataValue) {
1489
- const now = (0, node_opcua_date_time_1.getCurrentClock)();
1490
- (0, node_opcua_assert_1.assert)(dataValue instanceof node_opcua_data_value_1.DataValue);
1491
- if (!dataValue.sourceTimestamp) {
1492
- dataValue.sourceTimestamp = now.timestamp;
1493
- dataValue.sourcePicoseconds = now.picoseconds;
1494
- }
1495
- if (!dataValue.serverTimestamp) {
1496
- dataValue.serverTimestamp = now.timestamp;
1497
- dataValue.serverPicoseconds = now.picoseconds;
1498
- }
1499
- }
1500
- function unsetFlag(flags, mask) {
1501
- return flags & ~mask;
1502
- }
1503
- function setFlag(flags, mask) {
1504
- return flags | mask;
1505
- }
1506
- function _calculateEffectiveUserAccessLevelFromPermission(node, context, userAccessLevel) {
1507
- function __adjustFlag(permissionType, access, userAccessLevel1) {
1508
- if ((node.accessLevel & access) === 0 || (userAccessLevel1 & access) === 0) {
1509
- userAccessLevel1 = unsetFlag(userAccessLevel1, access);
1510
- }
1511
- else {
1512
- if (!context.checkPermission(node, permissionType)) {
1513
- userAccessLevel1 = unsetFlag(userAccessLevel1, access);
1514
- }
1515
- }
1516
- return userAccessLevel1;
1517
- }
1518
- userAccessLevel = node.userAccessLevel === undefined ? node.accessLevel : node.userAccessLevel & node.accessLevel;
1519
- if (context.checkPermission) {
1520
- (0, node_opcua_assert_1.assert)(context.checkPermission instanceof Function);
1521
- userAccessLevel = __adjustFlag(node_opcua_types_1.PermissionType.Read, node_opcua_data_model_1.AccessLevelFlag.CurrentRead, userAccessLevel);
1522
- userAccessLevel = __adjustFlag(node_opcua_types_1.PermissionType.Write, node_opcua_data_model_1.AccessLevelFlag.CurrentWrite, userAccessLevel);
1523
- userAccessLevel = __adjustFlag(node_opcua_types_1.PermissionType.Write, node_opcua_data_model_1.AccessLevelFlag.StatusWrite, userAccessLevel);
1524
- userAccessLevel = __adjustFlag(node_opcua_types_1.PermissionType.Write, node_opcua_data_model_1.AccessLevelFlag.TimestampWrite, userAccessLevel);
1525
- userAccessLevel = __adjustFlag(node_opcua_types_1.PermissionType.ReadHistory, node_opcua_data_model_1.AccessLevelFlag.HistoryRead, userAccessLevel);
1526
- userAccessLevel = __adjustFlag(node_opcua_types_1.PermissionType.DeleteHistory, node_opcua_data_model_1.AccessLevelFlag.HistoryWrite, userAccessLevel);
1527
- return userAccessLevel;
1528
- }
1529
- else {
1530
- return userAccessLevel;
1531
- }
1532
- }
1533
- function adjustVariant2(variant) {
1534
- // convert Variant( Scalar|ByteString) => Variant(Array|ByteArray)
1535
- const addressSpace = this.addressSpace;
1536
- const basicType = this.getBasicDataType();
1537
- variant = (0, node_opcua_variant_1.adjustVariant)(variant, this.valueRank, basicType);
1538
- return variant;
1539
- }
1540
- function _not_writable_timestamped_set_func(dataValue, callback) {
1541
- (0, node_opcua_assert_1.assert)(dataValue instanceof node_opcua_data_value_1.DataValue);
1542
- callback(null, node_opcua_status_code_1.StatusCodes.BadNotWritable, null);
1543
- }
1544
- function _default_writable_timestamped_set_func(dataValue, callback) {
1545
- (0, node_opcua_assert_1.assert)(dataValue instanceof node_opcua_data_value_1.DataValue);
1546
- callback(null, node_opcua_status_code_1.StatusCodes.Good, dataValue);
1547
- }
1548
- function turn_sync_to_async(f, numberOfArgs) {
1549
- if (f.length <= numberOfArgs) {
1550
- return function (data, callback) {
1551
- const r = f.call(this, data);
1552
- setImmediate(() => {
1553
- return callback(null, r);
1554
- });
1555
- };
1556
- }
1557
- else {
1558
- (0, node_opcua_assert_1.assert)(f.length === numberOfArgs + 1);
1559
- return f;
1560
- }
1561
- }
1562
- const _default_minimumSamplingInterval = 1000;
1563
- function coerceDataValue(dataValue) {
1564
- if (dataValue instanceof node_opcua_data_value_1.DataValue) {
1565
- return dataValue;
1566
- }
1567
- return new node_opcua_data_value_1.DataValue(dataValue);
1568
- }
1569
- // variation #3 :
1570
- function _Variable_bind_with_async_refresh(options) {
1571
- /* jshint validthis: true */
1572
- (0, node_opcua_assert_1.assert)(this instanceof UAVariableImpl);
1573
- (0, node_opcua_assert_1.assert)(typeof options.refreshFunc === "function");
1574
- (0, node_opcua_assert_1.assert)(!options.get, "a getter shall not be specified when refreshFunc is set");
1575
- (0, node_opcua_assert_1.assert)(!options.timestamped_get, "a getter shall not be specified when refreshFunc is set");
1576
- (0, node_opcua_assert_1.assert)(!this.refreshFunc);
1577
- this.refreshFunc = options.refreshFunc;
1578
- // TO DO : REVISIT THIS ASSUMPTION
1579
- if (false && this.minimumSamplingInterval === 0) {
1580
- // when a getter /timestamped_getter or async_getter is provided
1581
- // samplingInterval cannot be 0, as the item value must be scanned to be updated.
1582
- this.minimumSamplingInterval = _default_minimumSamplingInterval; // MonitoredItem.minimumSamplingInterval;
1583
- debugLog("adapting minimumSamplingInterval on " + this.browseName.toString() + " to " + this.minimumSamplingInterval);
1584
- }
1585
- }
1586
- // variation 2
1587
- function _Variable_bind_with_timestamped_get(options) {
1588
- /* jshint validthis: true */
1589
- (0, node_opcua_assert_1.assert)(this instanceof UAVariableImpl);
1590
- (0, node_opcua_assert_1.assert)(typeof options.timestamped_get === "function");
1591
- (0, node_opcua_assert_1.assert)(!options.get, "should not specify 'get' when 'timestamped_get' exists ");
1592
- (0, node_opcua_assert_1.assert)(!this._timestamped_get_func);
1593
- const async_refresh_func = (callback) => {
1594
- Promise.resolve(this._timestamped_get_func.call(this))
1595
- .then((dataValue) => callback(null, dataValue))
1596
- .catch((err) => {
1597
- errorLog("asyncRefresh error: Variable is ", this.nodeId.toString(), this.browseName.toString());
1598
- callback(err);
1599
- });
1600
- };
1601
- const pThis = this;
1602
- if (options.timestamped_get.length === 0) {
1603
- const timestamped_get = options.timestamped_get;
1604
- // sync version | Promise version
1605
- this._timestamped_get_func = timestamped_get;
1606
- const dataValue_verify = timestamped_get.call(pThis);
1607
- // dataValue_verify should be a DataValue or a Promise
1608
- /* istanbul ignore next */
1609
- if (!(dataValue_verify instanceof node_opcua_data_value_1.DataValue) && typeof dataValue_verify.then !== "function") {
1610
- errorLog(chalk.red(" Bind variable error: "), " the timestamped_get function must return a DataValue or a Promise<DataValue>" +
1611
- "\n value_check.constructor.name ", dataValue_verify ? dataValue_verify.constructor.name : "null");
1612
- throw new Error(" Bind variable error: " + " the timestamped_get function must return a DataValue");
1613
- }
1614
- _Variable_bind_with_async_refresh.call(this, { refreshFunc: async_refresh_func });
1615
- }
1616
- else if (options.timestamped_get.length === 1) {
1617
- _Variable_bind_with_async_refresh.call(this, { refreshFunc: options.timestamped_get });
1618
- }
1619
- else {
1620
- errorLog("timestamped_get has a invalid number of argument , should be 0 or 1 ");
1621
- throw new Error("timestamped_get has a invalid number of argument , should be 0 or 1 ");
1622
- }
1623
- }
1624
- // variation 1
1625
- function _Variable_bind_with_simple_get(options) {
1626
- /* jshint validthis: true */
1627
- (0, node_opcua_assert_1.assert)(this instanceof UAVariableImpl);
1628
- (0, node_opcua_assert_1.assert)(typeof options.get === "function", "should specify get function");
1629
- (0, node_opcua_assert_1.assert)(options.get.length === 0, "get function should not have arguments");
1630
- (0, node_opcua_assert_1.assert)(!options.timestamped_get, "should not specify a timestamped_get function when get is specified");
1631
- (0, node_opcua_assert_1.assert)(!this._timestamped_get_func);
1632
- (0, node_opcua_assert_1.assert)(!this._get_func);
1633
- this._get_func = options.get;
1634
- const timestamped_get_func_from__Variable_bind_with_simple_get = () => {
1635
- const value = this._get_func();
1636
- /* istanbul ignore next */
1637
- if (!is_Variant_or_StatusCode(value)) {
1638
- errorLog(chalk.red(" Bind variable error: "), " : the getter must return a Variant or a StatusCode" + "\nvalue_check.constructor.name ", value ? value.constructor.name : "null");
1639
- throw new Error(" bindVariable : the value getter function returns a invalid result ( expecting a Variant or a StatusCode !!!");
1640
- }
1641
- if (is_StatusCode(value)) {
1642
- return new node_opcua_data_value_1.DataValue({ statusCode: value });
1643
- }
1644
- else {
1645
- if (!this.$dataValue || !this.$dataValue.statusCode.isGoodish() || !(0, node_opcua_variant_1.sameVariant)(this.$dataValue.value, value)) {
1646
- this._inner_replace_dataValue(new node_opcua_data_value_1.DataValue({ value }));
1647
- }
1648
- return this.$dataValue;
1649
- }
1650
- };
1651
- _Variable_bind_with_timestamped_get.call(this, {
1652
- get: undefined,
1653
- timestamped_get: timestamped_get_func_from__Variable_bind_with_simple_get
1654
- });
1655
- }
1656
- function _Variable_bind_with_simple_set(options) {
1657
- (0, node_opcua_assert_1.assert)(this instanceof UAVariableImpl);
1658
- (0, node_opcua_assert_1.assert)(typeof options.set === "function", "should specify set function");
1659
- (0, node_opcua_assert_1.assert)(!options.timestamped_set, "should not specify a timestamped_set function");
1660
- (0, node_opcua_assert_1.assert)(!this._timestamped_set_func);
1661
- (0, node_opcua_assert_1.assert)(!this._set_func);
1662
- this._set_func = turn_sync_to_async(options.set, 1);
1663
- (0, node_opcua_assert_1.assert)(this._set_func.length === 2, " set function must have 2 arguments ( variant, callback)");
1664
- this._timestamped_set_func = (timestamped_value, callback) => {
1665
- (0, node_opcua_assert_1.assert)(timestamped_value instanceof node_opcua_data_value_1.DataValue);
1666
- this._set_func(timestamped_value.value, (err, statusCode) => {
1667
- // istanbul ignore next
1668
- if (!err && !statusCode) {
1669
- errorLog(chalk.red("UAVariable Binding Error _set_func must return a StatusCode, check the bindVariable parameters"));
1670
- errorLog(chalk.yellow("StatusCode.Good is assumed"));
1671
- return callback(err, node_opcua_status_code_1.StatusCodes.Good, timestamped_value);
1672
- }
1673
- callback(err, statusCode, timestamped_value);
1674
- });
1675
- };
1676
- }
1677
- function _Variable_bind_with_timestamped_set(options) {
1678
- (0, node_opcua_assert_1.assert)(options.timestamped_set.length === 2 || options.timestamped_set.length === 1, "timestamped_set must have 2 parameters timestamped_set: function(dataValue,callback){} or one paramater timestamped_set: function(dataValue): Promise<StatusCode>{}");
1679
- (0, node_opcua_assert_1.assert)(!options.set, "should not specify set when timestamped_set_func exists ");
1680
- this._timestamped_set_func = (0, multiform_func_1.convertToCallbackFunction1)(options.timestamped_set);
1681
- }
1682
- function bind_setter(options) {
1683
- if (typeof options.set === "function") {
1684
- // variation 1
1685
- _Variable_bind_with_simple_set.call(this, options);
1686
- }
1687
- else if (typeof options.timestamped_set === "function") {
1688
- // variation 2
1689
- (0, node_opcua_assert_1.assert)(typeof options.timestamped_get === "function", "timestamped_set must be used with timestamped_get ");
1690
- _Variable_bind_with_timestamped_set.call(this, {
1691
- set: undefined,
1692
- timestamped_set: options.timestamped_set
1693
- });
1694
- }
1695
- else if (typeof options.timestamped_get === "function") {
1696
- // timestamped_get is specified but timestamped_set is not
1697
- // => Value is read-only
1698
- _Variable_bind_with_timestamped_set.call(this, {
1699
- set: undefined,
1700
- timestamped_set: _not_writable_timestamped_set_func
1701
- });
1702
- }
1703
- else {
1704
- _Variable_bind_with_timestamped_set.call(this, {
1705
- set: undefined,
1706
- timestamped_set: _default_writable_timestamped_set_func
1707
- });
1708
- }
1709
- }
1710
- function bind_getter(options) {
1711
- if (typeof options.get === "function") {
1712
- // variation 1
1713
- _Variable_bind_with_simple_get.call(this, options);
1714
- }
1715
- else if (typeof options.timestamped_get === "function") {
1716
- // variation 2
1717
- _Variable_bind_with_timestamped_get.call(this, {
1718
- get: undefined,
1719
- timestamped_get: options.timestamped_get
1720
- });
1721
- }
1722
- else if (typeof options.refreshFunc === "function") {
1723
- // variation 3
1724
- _Variable_bind_with_async_refresh.call(this, options);
1725
- }
1726
- else {
1727
- (0, node_opcua_assert_1.assert)(!Object.prototype.hasOwnProperty.call(options, "set"), "getter is missing : a getter must be provided if a setter is provided");
1728
- // xx bind_variant.call(this,options);
1729
- if (options.dataType !== undefined) {
1730
- // if (options.dataType !== DataType.ExtensionObject) {
1731
- this.setValueFromSource(options);
1732
- // }
1733
- }
1734
- }
1735
- }
1736
- class UAVariableImplT extends UAVariableImpl {
1737
- }
1738
- exports.UAVariableImplT = UAVariableImplT;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UAVariableImplT = exports.UAVariableImpl = exports.adjust_userAccessLevel = exports.adjust_accessLevel = void 0;
4
+ /* eslint-disable max-statements */
5
+ /* eslint-disable complexity */
6
+ /**
7
+ * @module node-opcua-address-space
8
+ */
9
+ // tslint:disable:no-bitwise
10
+ // tslint:disable:no-console
11
+ // tslint:disable:max-line-length
12
+ const chalk = require("chalk");
13
+ const node_opcua_address_space_base_1 = require("node-opcua-address-space-base");
14
+ const node_opcua_assert_1 = require("node-opcua-assert");
15
+ const node_opcua_data_model_1 = require("node-opcua-data-model");
16
+ const node_opcua_data_value_1 = require("node-opcua-data-value");
17
+ const node_opcua_date_time_1 = require("node-opcua-date-time");
18
+ const node_opcua_debug_1 = require("node-opcua-debug");
19
+ const node_opcua_extension_object_1 = require("node-opcua-extension-object");
20
+ const node_opcua_nodeid_1 = require("node-opcua-nodeid");
21
+ const node_opcua_numeric_range_1 = require("node-opcua-numeric-range");
22
+ const node_opcua_service_write_1 = require("node-opcua-service-write");
23
+ const node_opcua_status_code_1 = require("node-opcua-status-code");
24
+ const node_opcua_types_1 = require("node-opcua-types");
25
+ const utils = require("node-opcua-utils");
26
+ const node_opcua_variant_1 = require("node-opcua-variant");
27
+ const session_context_1 = require("../source/session_context");
28
+ const multiform_func_1 = require("../source/helpers/multiform_func");
29
+ const base_node_impl_1 = require("./base_node_impl");
30
+ const base_node_private_1 = require("./base_node_private");
31
+ const ua_data_type_impl_1 = require("./ua_data_type_impl");
32
+ const apply_condition_refresh_1 = require("./apply_condition_refresh");
33
+ const ua_variable_impl_ext_obj_1 = require("./ua_variable_impl_ext_obj");
34
+ const debugLog = (0, node_opcua_debug_1.make_debugLog)(__filename);
35
+ const warningLog = (0, node_opcua_debug_1.make_warningLog)(__filename);
36
+ const doDebug = (0, node_opcua_debug_1.checkDebugFlag)(__filename);
37
+ const errorLog = (0, node_opcua_debug_1.make_errorLog)(__filename);
38
+ function adjust_accessLevel(accessLevel) {
39
+ accessLevel = utils.isNullOrUndefined(accessLevel) ? "CurrentRead | CurrentWrite" : accessLevel;
40
+ accessLevel = (0, node_opcua_data_model_1.makeAccessLevelFlag)(accessLevel);
41
+ (0, node_opcua_assert_1.assert)(isFinite(accessLevel));
42
+ return accessLevel;
43
+ }
44
+ exports.adjust_accessLevel = adjust_accessLevel;
45
+ function adjust_userAccessLevel(userAccessLevel, accessLevel) {
46
+ if (userAccessLevel === undefined) {
47
+ return undefined;
48
+ }
49
+ userAccessLevel = adjust_accessLevel(userAccessLevel);
50
+ accessLevel = adjust_accessLevel(accessLevel);
51
+ return (0, node_opcua_data_model_1.makeAccessLevelFlag)(accessLevel & userAccessLevel);
52
+ }
53
+ exports.adjust_userAccessLevel = adjust_userAccessLevel;
54
+ function adjust_samplingInterval(minimumSamplingInterval) {
55
+ (0, node_opcua_assert_1.assert)(isFinite(minimumSamplingInterval));
56
+ if (minimumSamplingInterval < 0) {
57
+ return -1; // only -1 is a valid negative value for samplingInterval and means "unspecified"
58
+ }
59
+ return minimumSamplingInterval;
60
+ }
61
+ function is_Variant(v) {
62
+ return v instanceof node_opcua_variant_1.Variant;
63
+ }
64
+ function is_StatusCode(v) {
65
+ return (v &&
66
+ v.constructor &&
67
+ (v instanceof node_opcua_status_code_1.StatusCode ||
68
+ v.constructor.name === "ConstantStatusCode" ||
69
+ v.constructor.name === "StatusCode" ||
70
+ v.constructor.name === "ModifiableStatusCode"));
71
+ }
72
+ function is_Variant_or_StatusCode(v) {
73
+ if (is_Variant(v)) {
74
+ // /@@assert(v.isValid());
75
+ }
76
+ return is_Variant(v) || is_StatusCode(v);
77
+ }
78
+ function _dataType_toUADataType(addressSpace, dataType) {
79
+ (0, node_opcua_assert_1.assert)(addressSpace);
80
+ (0, node_opcua_assert_1.assert)(dataType !== node_opcua_variant_1.DataType.Null);
81
+ const dataTypeNode = addressSpace.findDataType(node_opcua_variant_1.DataType[dataType]);
82
+ /* istanbul ignore next */
83
+ if (!dataTypeNode) {
84
+ throw new Error(" Cannot find DataType " + node_opcua_variant_1.DataType[dataType] + " in address Space");
85
+ }
86
+ return dataTypeNode;
87
+ }
88
+ /*=
89
+ *
90
+ * @param addressSpace
91
+ * @param dataTypeNodeId : the nodeId matching the dataType of the destination variable.
92
+ * @param variantDataType: the dataType of the variant to write to the destination variable
93
+ * @param nodeId
94
+ * @return {boolean} true if the variant dataType is compatible with the Variable DataType
95
+ */
96
+ function validateDataType(addressSpace, dataTypeNodeId, variantDataType, nodeId, allowNulls) {
97
+ if (variantDataType === node_opcua_variant_1.DataType.ExtensionObject) {
98
+ return true;
99
+ }
100
+ if (variantDataType === node_opcua_variant_1.DataType.Null && allowNulls) {
101
+ return true;
102
+ }
103
+ if (variantDataType === node_opcua_variant_1.DataType.Null && !allowNulls) {
104
+ return false;
105
+ }
106
+ let builtInType;
107
+ let builtInUADataType;
108
+ const destUADataType = addressSpace.findDataType(dataTypeNodeId);
109
+ (0, node_opcua_assert_1.assert)(destUADataType instanceof ua_data_type_impl_1.UADataTypeImpl);
110
+ if (destUADataType.isAbstract || destUADataType.nodeId.namespace !== 0) {
111
+ builtInUADataType = destUADataType;
112
+ }
113
+ else {
114
+ builtInType = addressSpace.findCorrespondingBasicDataType(destUADataType);
115
+ builtInUADataType = addressSpace.findDataType(builtInType);
116
+ }
117
+ (0, node_opcua_assert_1.assert)(builtInUADataType instanceof ua_data_type_impl_1.UADataTypeImpl);
118
+ const enumerationUADataType = addressSpace.findDataType("Enumeration");
119
+ if (!enumerationUADataType) {
120
+ throw new Error("cannot find Enumeration DataType node in standard address space");
121
+ }
122
+ if (destUADataType.isSubtypeOf(enumerationUADataType)) {
123
+ // istanbul ignore next
124
+ if (doDebug) {
125
+ debugLog("destUADataType.", destUADataType.browseName.toString(), destUADataType.nodeId.toString());
126
+ debugLog("enumerationUADataType.", enumerationUADataType.browseName.toString(), enumerationUADataType.nodeId.toString());
127
+ }
128
+ return true;
129
+ }
130
+ // The value supplied for the attribute is not of the same type as the value.
131
+ const variantUADataType = _dataType_toUADataType(addressSpace, variantDataType);
132
+ (0, node_opcua_assert_1.assert)(variantUADataType instanceof ua_data_type_impl_1.UADataTypeImpl);
133
+ const dest_isSubTypeOf_variant = variantUADataType.isSubtypeOf(builtInUADataType);
134
+ /* istanbul ignore next */
135
+ if (doDebug) {
136
+ if (dest_isSubTypeOf_variant) {
137
+ /* istanbul ignore next*/
138
+ debugLog(chalk.green(" ---------- Type match !!! "), " on ", nodeId.toString());
139
+ }
140
+ else {
141
+ /* istanbul ignore next*/
142
+ debugLog(chalk.red(" ---------- Type mismatch "), " on ", nodeId.toString());
143
+ }
144
+ debugLog(chalk.cyan(" Variable data Type is = "), destUADataType.browseName.toString());
145
+ debugLog(chalk.cyan(" which matches basic Type = "), builtInUADataType.browseName.toString());
146
+ debugLog(chalk.yellow(" Actual dataType = "), variantUADataType.browseName.toString());
147
+ }
148
+ return dest_isSubTypeOf_variant;
149
+ }
150
+ function default_func(dataValue1, callback1) {
151
+ return _default_writable_timestamped_set_func.call(this, dataValue1, callback1);
152
+ }
153
+ /**
154
+ * A OPCUA Variable Node
155
+ *
156
+ * @class UAVariable
157
+ * @constructor
158
+ * @extends BaseNode
159
+ * The AccessLevel Attribute is used to indicate how the Value of a Variable can be accessed (read/write) and if it
160
+ * contains current and/or historic data. The AccessLevel does not take any user access rights into account,
161
+ * i.e. although the Variable is writable this may be restricted to a certain user / user group.
162
+ * The AccessLevel is an 8-bit unsigned integer with the structure defined in the following table:
163
+ *
164
+ * Field Bit Description
165
+ * CurrentRead 0 Indicates if the current value is readable
166
+ * (0 means not readable, 1 means readable).
167
+ * CurrentWrite 1 Indicates if the current value is writable
168
+ * (0 means not writable, 1 means writable).
169
+ * HistoryRead 2 Indicates if the history of the value is readable
170
+ * (0 means not readable, 1 means readable).
171
+ * HistoryWrite 3 Indicates if the history of the value is writable (0 means not writable, 1 means writable).
172
+ * SemanticChange 4 Indicates if the Variable used as Property generates SemanticChangeEvents (see 9.31).
173
+ * Reserved 5:7 Reserved for future use. Shall always be zero.
174
+ *
175
+ * The first two bits also indicate if a current value of this Variable is available and the second two bits
176
+ * indicates if the history of the Variable is available via the OPC UA server.
177
+ *
178
+ */
179
+ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
180
+ get typeDefinitionObj() {
181
+ // istanbul ignore next
182
+ if (super.typeDefinitionObj && super.typeDefinitionObj.nodeClass !== node_opcua_data_model_1.NodeClass.VariableType) {
183
+ console.log(super.typeDefinitionObj.toString());
184
+ throw new Error("Invalid type definition node class , expecting a VariableType got " + node_opcua_data_model_1.NodeClass[super.typeDefinitionObj.nodeClass]);
185
+ }
186
+ return super.typeDefinitionObj;
187
+ }
188
+ get typeDefinition() {
189
+ return super.typeDefinition;
190
+ }
191
+ constructor(options) {
192
+ super(options);
193
+ this.nodeClass = node_opcua_data_model_1.NodeClass.Variable;
194
+ (0, node_opcua_variant_1.verifyRankAndDimensions)(options);
195
+ this.valueRank = options.valueRank;
196
+ this.arrayDimensions = options.arrayDimensions;
197
+ this.dataType = this.resolveNodeId(options.dataType); // DataType (NodeId)
198
+ this.accessLevel = adjust_accessLevel(options.accessLevel);
199
+ this.userAccessLevel = adjust_userAccessLevel(options.userAccessLevel, this.accessLevel);
200
+ this.minimumSamplingInterval = adjust_samplingInterval(options.minimumSamplingInterval || 0);
201
+ this.historizing = !!options.historizing; // coerced to boolean"
202
+ this.$dataValue = new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.UncertainInitialValue, value: { dataType: node_opcua_variant_1.DataType.Null } });
203
+ if (options.value) {
204
+ this.bindVariable(options.value);
205
+ }
206
+ this.setMaxListeners(5000);
207
+ this.semantic_version = 0;
208
+ }
209
+ checkAccessLevelPrivate(_context, accessLevel) {
210
+ if (this.userAccessLevel === undefined) {
211
+ return true;
212
+ }
213
+ return (this.userAccessLevel & accessLevel) === accessLevel;
214
+ }
215
+ checkPermissionPrivate(context, permission) {
216
+ if (!context)
217
+ return true;
218
+ (0, node_opcua_assert_1.assert)(context instanceof session_context_1.SessionContext);
219
+ if (context.checkPermission) {
220
+ if (!(context.checkPermission instanceof Function)) {
221
+ errorLog("context checkPermission is not a function");
222
+ return false;
223
+ }
224
+ if (!context.checkPermission(this, permission)) {
225
+ return false;
226
+ }
227
+ }
228
+ return true;
229
+ }
230
+ checkPermissionAndAccessLevelPrivate(context, permission, accessLevel) {
231
+ if (!this.checkPermissionPrivate(context, permission)) {
232
+ return false;
233
+ }
234
+ return this.checkAccessLevelPrivate(context, accessLevel);
235
+ }
236
+ isReadable(context) {
237
+ return (this.accessLevel & node_opcua_data_model_1.AccessLevelFlag.CurrentRead) === node_opcua_data_model_1.AccessLevelFlag.CurrentRead;
238
+ }
239
+ isUserReadable(context) {
240
+ if (!this.isReadable(context)) {
241
+ return false;
242
+ }
243
+ if (!this.checkPermissionPrivate(context, node_opcua_types_1.PermissionType.Read)) {
244
+ return false;
245
+ }
246
+ return this.checkAccessLevelPrivate(context, node_opcua_data_model_1.AccessLevelFlag.CurrentRead);
247
+ }
248
+ isWritable(context) {
249
+ return (this.accessLevel & node_opcua_data_model_1.AccessLevelFlag.CurrentWrite) === node_opcua_data_model_1.AccessLevelFlag.CurrentWrite;
250
+ }
251
+ isUserWritable(context) {
252
+ if (!this.isWritable(context)) {
253
+ return false;
254
+ }
255
+ return this.checkPermissionAndAccessLevelPrivate(context, node_opcua_types_1.PermissionType.Write, node_opcua_data_model_1.AccessLevelFlag.CurrentWrite);
256
+ }
257
+ canUserReadHistory(context) {
258
+ return this.checkPermissionAndAccessLevelPrivate(context, node_opcua_types_1.PermissionType.ReadHistory, node_opcua_data_model_1.AccessLevelFlag.HistoryRead);
259
+ }
260
+ canUserWriteHistorizingAttribute(context) {
261
+ if (context && !context.checkPermission(this, node_opcua_types_1.PermissionType.WriteHistorizing)) {
262
+ return false;
263
+ }
264
+ return true;
265
+ }
266
+ canUserInsertHistory(context) {
267
+ return this.checkPermissionAndAccessLevelPrivate(context, node_opcua_types_1.PermissionType.InsertHistory, node_opcua_data_model_1.AccessLevelFlag.HistoryWrite);
268
+ }
269
+ canUserModifyHistory(context) {
270
+ return this.checkPermissionAndAccessLevelPrivate(context, node_opcua_types_1.PermissionType.ModifyHistory, node_opcua_data_model_1.AccessLevelFlag.HistoryWrite);
271
+ }
272
+ canUserDeleteHistory(context) {
273
+ return this.checkPermissionAndAccessLevelPrivate(context, node_opcua_types_1.PermissionType.DeleteHistory, node_opcua_data_model_1.AccessLevelFlag.HistoryWrite);
274
+ }
275
+ /**
276
+ *
277
+ *
278
+ * from OPC.UA.Spec 1.02 part 4
279
+ * 5.10.2.4 StatusCodes
280
+ * Table 51 defines values for the operation level statusCode contained in the DataValue structure of
281
+ * each values element. Common StatusCodes are defined in Table 166.
282
+ *
283
+ * Table 51 Read Operation Level Result Codes
284
+ *
285
+ * | Symbolic Id | Description
286
+ * |-----------------------------|---------------------------------------------------------------------------------------------|
287
+ * |BadNodeIdInvalid | The syntax of the node id is not valid.|
288
+ * |BadNodeIdUnknown |The node id refers to a node that does not exist in the server address space.|
289
+ * |BadAttributeIdInvalid | BadAttributeIdInvalid The attribute is not supported for the specified node.|
290
+ * |BadIndexRangeInvalid | The syntax of the index range parameter is invalid.|
291
+ * |BadIndexRangeNoData | No data exists within the range of indexes specified.|
292
+ * |BadDataEncodingInvalid | The data encoding is invalid.|
293
+ * | | This result is used if no dataEncoding can be applied because an Attribute other|
294
+ * | | than Value was requested or the DataType of the Value Attribute is not a subtype|
295
+ * | | of the Structure DataType.|
296
+ * |BadDataEncodingUnsupported | The server does not support the requested data encoding for the node. |
297
+ * | | This result is used if a dataEncoding can be applied but the passed data encoding |
298
+ * | | is not known to the Server. |
299
+ * |BadNotReadable | The access level does not allow reading or subscribing to the Node.|
300
+ * |BadUserAccessDenied | User does not have permission to perform the requested operation. (table 165)|
301
+ */
302
+ readValue(context, indexRange, dataEncoding) {
303
+ if (!context) {
304
+ context = session_context_1.SessionContext.defaultContext;
305
+ }
306
+ if (context.isAccessRestricted(this)) {
307
+ return new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.BadSecurityModeInsufficient });
308
+ }
309
+ if (!this.isReadable(context)) {
310
+ return new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.BadNotReadable });
311
+ }
312
+ if (!this.checkPermissionPrivate(context, node_opcua_types_1.PermissionType.Read)) {
313
+ return new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.BadUserAccessDenied });
314
+ }
315
+ if (!this.isUserReadable(context)) {
316
+ return new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.BadNotReadable });
317
+ }
318
+ if (!(0, node_opcua_data_model_1.isValidDataEncoding)(dataEncoding)) {
319
+ return new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.BadDataEncodingInvalid });
320
+ }
321
+ if (this._timestamped_get_func) {
322
+ if (this._timestamped_get_func.length === 0) {
323
+ const dataValueOrPromise = this._timestamped_get_func();
324
+ if (!Object.prototype.hasOwnProperty.call(dataValueOrPromise, "then")) {
325
+ if (dataValueOrPromise !== this.$dataValue) {
326
+ // TO DO : is this necessary ? this may interfere with current use of $dataValue
327
+ this.$dataValue = dataValueOrPromise;
328
+ this.verifyVariantCompatibility(this.$dataValue.value);
329
+ }
330
+ }
331
+ else {
332
+ errorLog("Unsupported: _timestamped_get_func returns a Promise !");
333
+ }
334
+ }
335
+ }
336
+ let dataValue = this.$dataValue;
337
+ if (dataValue.statusCode.isGoodish()) {
338
+ // note : extractRange will clone the dataValue
339
+ dataValue = (0, node_opcua_data_value_1.extractRange)(dataValue, indexRange);
340
+ }
341
+ /* istanbul ignore next */
342
+ if (dataValue.statusCode.equals(node_opcua_status_code_1.StatusCodes.BadWaitingForInitialData) ||
343
+ dataValue.statusCode.equals(node_opcua_status_code_1.StatusCodes.UncertainInitialValue)) {
344
+ debugLog(chalk.red(" Warning: UAVariable#readValue ") +
345
+ chalk.cyan(this.browseName.toString()) +
346
+ " (" +
347
+ chalk.yellow(this.nodeId.toString()) +
348
+ ") exists but dataValue has not been defined");
349
+ }
350
+ return dataValue;
351
+ }
352
+ isEnumeration() {
353
+ return this.addressSpacePrivate.isEnumeration(this.dataType);
354
+ }
355
+ /**
356
+ * return true if the DataType is of type Extension object
357
+ * this is not taking into account the valueRank of the variable
358
+ */
359
+ isExtensionObject() {
360
+ // DataType must be one of Structure
361
+ if (this.dataType.isEmpty())
362
+ return false;
363
+ const dataTypeNode = this.addressSpace.findDataType(this.dataType);
364
+ if (!dataTypeNode) {
365
+ throw new Error(" Cannot find DataType " + this.dataType.toString() + " in standard address Space");
366
+ }
367
+ const structureNode = this.addressSpace.findDataType("Structure");
368
+ if (!structureNode) {
369
+ throw new Error(" Cannot find 'Structure' DataType in standard address Space");
370
+ }
371
+ return dataTypeNode.isSubtypeOf(structureNode);
372
+ }
373
+ _getEnumerationInfo() {
374
+ // DataType must be one of Enumeration
375
+ (0, node_opcua_assert_1.assert)(this.isEnumeration(), "Variable is not an enumeration");
376
+ const dataTypeNode = this.addressSpace.findDataType(this.dataType);
377
+ return dataTypeNode._getEnumerationInfo();
378
+ }
379
+ asyncRefresh(...args) {
380
+ if (this.$dataValue.statusCode.isGoodish()) {
381
+ this.verifyVariantCompatibility(this.$dataValue.value);
382
+ }
383
+ const oldestDate = args[0];
384
+ (0, node_opcua_assert_1.assert)(oldestDate instanceof Date);
385
+ const callback = args[1];
386
+ if (!this.refreshFunc) {
387
+ // no refresh func
388
+ const dataValue = this.readValue();
389
+ dataValue.serverTimestamp = oldestDate;
390
+ dataValue.serverPicoseconds = 0;
391
+ if (oldestDate.getTime() <= dataValue.serverTimestamp.getTime()) {
392
+ return callback(null, dataValue);
393
+ }
394
+ else {
395
+ // fake
396
+ return callback(null, dataValue);
397
+ }
398
+ }
399
+ if (this.$dataValue.serverTimestamp && oldestDate.getTime() <= this.$dataValue.serverTimestamp.getTime()) {
400
+ const dataValue = this.readValue().clone();
401
+ dataValue.serverTimestamp = oldestDate;
402
+ dataValue.serverPicoseconds = 0;
403
+ return callback(null, dataValue);
404
+ }
405
+ try {
406
+ this.refreshFunc.call(this, (err, dataValue) => {
407
+ // istanbul ignore next
408
+ if (err || !dataValue) {
409
+ errorLog("-------------- refresh call failed", this.browseName.toString(), this.nodeId.toString(), err === null || err === void 0 ? void 0 : err.message);
410
+ dataValue = { statusCode: node_opcua_status_code_1.StatusCodes.BadNoDataAvailable };
411
+ }
412
+ if (dataValue && dataValue !== this.$dataValue) {
413
+ this._internal_set_dataValue(coerceDataValue(dataValue), null);
414
+ }
415
+ callback(err, this.$dataValue);
416
+ });
417
+ }
418
+ catch (err) {
419
+ errorLog("-------------- refresh call failed 2", this.browseName.toString(), this.nodeId.toString());
420
+ errorLog(err);
421
+ const dataValue = new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.BadInternalError });
422
+ this._internal_set_dataValue(dataValue, null);
423
+ callback(err, this.$dataValue);
424
+ }
425
+ }
426
+ readEnumValue() {
427
+ const value = this.readValue().value.value;
428
+ const enumInfo = this._getEnumerationInfo();
429
+ const enumV = enumInfo.valueIndex[value];
430
+ return { value, name: enumV ? enumV.name : "?????" };
431
+ }
432
+ writeEnumValue(value) {
433
+ const enumInfo = this._getEnumerationInfo();
434
+ if (typeof value === "string") {
435
+ if (!Object.prototype.hasOwnProperty.call(enumInfo.nameIndex, value)) {
436
+ const possibleValues = Object.keys(enumInfo.nameIndex).join(",");
437
+ throw new Error("UAVariable#writeEnumValue: cannot find value " + value + " in [" + possibleValues + "]");
438
+ }
439
+ const valueIndex = enumInfo.nameIndex[value].value;
440
+ value = valueIndex;
441
+ }
442
+ if (isFinite(value)) {
443
+ const possibleValues = Object.keys(enumInfo.nameIndex).join(",");
444
+ if (!enumInfo.valueIndex[value]) {
445
+ throw new Error("UAVariable#writeEnumValue : value out of range " + value + " in [" + possibleValues + "]");
446
+ }
447
+ this.setValueFromSource({
448
+ dataType: node_opcua_variant_1.DataType.Int32,
449
+ value
450
+ });
451
+ }
452
+ else {
453
+ throw new Error("UAVariable#writeEnumValue: value type mismatch");
454
+ }
455
+ }
456
+ readAttribute(context, attributeId, indexRange, dataEncoding) {
457
+ context = context || session_context_1.SessionContext.defaultContext;
458
+ (0, node_opcua_assert_1.assert)(context instanceof session_context_1.SessionContext);
459
+ const options = {};
460
+ if (attributeId !== node_opcua_data_model_1.AttributeIds.Value) {
461
+ if (indexRange && indexRange.isDefined()) {
462
+ options.statusCode = node_opcua_status_code_1.StatusCodes.BadIndexRangeNoData;
463
+ return new node_opcua_data_value_1.DataValue(options);
464
+ }
465
+ if ((0, node_opcua_data_model_1.isDataEncoding)(dataEncoding)) {
466
+ options.statusCode = node_opcua_status_code_1.StatusCodes.BadDataEncodingInvalid;
467
+ return new node_opcua_data_value_1.DataValue(options);
468
+ }
469
+ }
470
+ switch (attributeId) {
471
+ case node_opcua_data_model_1.AttributeIds.Value:
472
+ return this.readValue(context, indexRange, dataEncoding);
473
+ case node_opcua_data_model_1.AttributeIds.DataType:
474
+ return this._readDataType();
475
+ case node_opcua_data_model_1.AttributeIds.ValueRank:
476
+ return this._readValueRank();
477
+ case node_opcua_data_model_1.AttributeIds.ArrayDimensions:
478
+ return this._readArrayDimensions();
479
+ case node_opcua_data_model_1.AttributeIds.AccessLevel:
480
+ return this._readAccessLevel(context);
481
+ case node_opcua_data_model_1.AttributeIds.UserAccessLevel:
482
+ return this._readUserAccessLevel(context);
483
+ case node_opcua_data_model_1.AttributeIds.MinimumSamplingInterval:
484
+ return this._readMinimumSamplingInterval();
485
+ case node_opcua_data_model_1.AttributeIds.Historizing:
486
+ return this._readHistorizing();
487
+ case node_opcua_data_model_1.AttributeIds.AccessLevelEx:
488
+ return this._readAccessLevelEx(context);
489
+ default:
490
+ return base_node_impl_1.BaseNodeImpl.prototype.readAttribute.call(this, context, attributeId);
491
+ }
492
+ }
493
+ getBasicDataType() {
494
+ if (this._basicDataType) {
495
+ return this._basicDataType;
496
+ }
497
+ if (this.dataType.namespace === 0 && this.dataType.value === 0) {
498
+ return node_opcua_variant_1.DataType.Null;
499
+ }
500
+ const addressSpace = this.addressSpace;
501
+ if (!addressSpace) {
502
+ // may be node has been deleted already
503
+ return node_opcua_variant_1.DataType.Null;
504
+ }
505
+ const dataTypeNode = addressSpace.findDataType(this.dataType);
506
+ const basicDataType = dataTypeNode && dataTypeNode.nodeClass === node_opcua_data_model_1.NodeClass.DataType ? dataTypeNode.getBasicDataType() : node_opcua_variant_1.DataType.Null;
507
+ // const basicDataType = addressSpace.findCorrespondingBasicDataType(this.dataType);
508
+ this._basicDataType = basicDataType;
509
+ return basicDataType;
510
+ }
511
+ adjustVariant(variant) {
512
+ return (0, node_opcua_variant_1.adjustVariant)(variant, this.valueRank, this.getBasicDataType());
513
+ }
514
+ verifyVariantCompatibility(variant) {
515
+ try {
516
+ // istanbul ignore next
517
+ if (Object.prototype.hasOwnProperty.call(variant, "value")) {
518
+ if (variant.dataType === null || variant.dataType === undefined) {
519
+ throw new Error("Variant must provide a valid dataType : variant = " +
520
+ variant.toString() +
521
+ " this.dataType= " +
522
+ this.dataType.toString());
523
+ }
524
+ if (variant.dataType === node_opcua_variant_1.DataType.Boolean &&
525
+ (this.dataType.namespace !== 0 || this.dataType.value !== node_opcua_variant_1.DataType.Boolean)) {
526
+ throw new Error("Variant must provide a valid Boolean : variant = " +
527
+ variant.toString() +
528
+ " this.dataType= " +
529
+ this.dataType.toString());
530
+ }
531
+ if (this.dataType.namespace === 0 &&
532
+ this.dataType.value === node_opcua_variant_1.DataType.LocalizedText &&
533
+ variant.dataType !== node_opcua_variant_1.DataType.LocalizedText &&
534
+ variant.dataType !== node_opcua_variant_1.DataType.Null) {
535
+ throw new Error("Variant must provide a valid LocalizedText : variant = " +
536
+ variant.toString() +
537
+ " this.dataType= " +
538
+ this.dataType.toString());
539
+ }
540
+ }
541
+ const basicType = this.getBasicDataType();
542
+ if (basicType === node_opcua_variant_1.DataType.String && variant.dataType === node_opcua_variant_1.DataType.ByteString) {
543
+ return; // this is allowed
544
+ }
545
+ if (basicType === node_opcua_variant_1.DataType.ByteString && variant.dataType === node_opcua_variant_1.DataType.String) {
546
+ return; // this is allowed
547
+ }
548
+ if (basicType !== node_opcua_variant_1.DataType.Null &&
549
+ basicType !== node_opcua_variant_1.DataType.Variant &&
550
+ variant.dataType !== node_opcua_variant_1.DataType.Null &&
551
+ variant.dataType !== basicType) {
552
+ const message = "UAVariable.setValueFromSource " +
553
+ this.browseName.toString() +
554
+ " nodeId:" +
555
+ this.nodeId.toString() +
556
+ " dataType:" +
557
+ this.dataType.toString() +
558
+ ":\n" +
559
+ "the provided variant must have the expected dataType!\n" +
560
+ " - the expected dataType is " +
561
+ chalk.cyan(node_opcua_variant_1.DataType[basicType]) +
562
+ "\n" +
563
+ " - the actual dataType is " +
564
+ chalk.magenta(node_opcua_variant_1.DataType[variant.dataType]) +
565
+ "\n" +
566
+ " - " +
567
+ variant.toString();
568
+ throw new Error(message);
569
+ }
570
+ }
571
+ catch (err) {
572
+ errorLog("UAVariable ", err === null || err === void 0 ? void 0 : err.message, this.browseName.toString(), " nodeId=", this.nodeId.toString());
573
+ errorLog(err.message);
574
+ errorLog(err.stack);
575
+ throw err;
576
+ }
577
+ }
578
+ /**
579
+ * setValueFromSource is used to let the device sets the variable values
580
+ * this method also records the current time as sourceTimestamp and serverTimestamp.
581
+ . *
582
+ * The method will raise an exception if the value is not compatible with the dataType and expected dimension
583
+ *
584
+ * @method setValueFromSource
585
+ * @param variant {Variant}
586
+ * @param [statusCode {StatusCode} = StatusCodes.Good]
587
+ * @param [sourceTimestamp= Now]
588
+ */
589
+ setValueFromSource(variant, statusCode, sourceTimestamp) {
590
+ var _a;
591
+ try {
592
+ statusCode = statusCode || node_opcua_status_code_1.StatusCodes.Good;
593
+ const variant1 = node_opcua_variant_1.Variant.coerce(variant);
594
+ this.verifyVariantCompatibility(variant1);
595
+ const now = (0, node_opcua_date_time_1.coerceClock)(sourceTimestamp, 0);
596
+ const dataValue = new node_opcua_data_value_1.DataValue(null);
597
+ dataValue.serverPicoseconds = now.picoseconds;
598
+ dataValue.serverTimestamp = now.timestamp;
599
+ dataValue.sourcePicoseconds = now.picoseconds;
600
+ dataValue.sourceTimestamp = now.timestamp;
601
+ dataValue.statusCode = statusCode;
602
+ dataValue.value = variant1;
603
+ if (dataValue.value.dataType === node_opcua_variant_1.DataType.ExtensionObject) {
604
+ const valueIsCorrect = this.checkExtensionObjectIsCorrect(dataValue.value.value);
605
+ if (!valueIsCorrect) {
606
+ errorLog("setValueFromSource Invalid value !");
607
+ errorLog(this.toString());
608
+ errorLog(dataValue.toString());
609
+ this.checkExtensionObjectIsCorrect(dataValue.value.value);
610
+ }
611
+ // ----------------------------------
612
+ if (this.$extensionObject || this.$$extensionObjectArray) {
613
+ // we have an extension object already bound to this node
614
+ // the client is asking us to replace the object entierly by a new one
615
+ // const ext = dataValue.value.value;
616
+ this._internal_set_dataValue(dataValue);
617
+ return;
618
+ }
619
+ else {
620
+ this.$dataValue = dataValue;
621
+ }
622
+ }
623
+ else {
624
+ this._internal_set_dataValue(dataValue);
625
+ }
626
+ }
627
+ catch (err) {
628
+ errorLog("UAVariable#setValueFromString Error : ", this.browseName.toString(), this.nodeId.toString());
629
+ errorLog(err.message);
630
+ errorLog((_a = this.parent) === null || _a === void 0 ? void 0 : _a.toString());
631
+ throw err;
632
+ }
633
+ }
634
+ writeValue(context, dataValue, ...args) {
635
+ context = context || session_context_1.SessionContext.defaultContext;
636
+ (0, node_opcua_assert_1.assert)(context instanceof session_context_1.SessionContext);
637
+ if (!dataValue.sourceTimestamp) {
638
+ // source timestamp was not specified by the caller
639
+ // we will set the timestamp ourself with the current clock
640
+ if (context.currentTime) {
641
+ dataValue.sourceTimestamp = context.currentTime.timestamp;
642
+ dataValue.sourcePicoseconds = context.currentTime.picoseconds;
643
+ }
644
+ else {
645
+ const { timestamp, picoseconds } = (0, node_opcua_date_time_1.getCurrentClock)();
646
+ dataValue.sourceTimestamp = timestamp;
647
+ dataValue.sourcePicoseconds = picoseconds;
648
+ }
649
+ }
650
+ if (context.currentTime && !dataValue.serverTimestamp) {
651
+ dataValue.serverTimestamp = context.currentTime.timestamp;
652
+ dataValue.serverPicoseconds = context.currentTime.picoseconds;
653
+ }
654
+ // adjust arguments if optional indexRange Parameter is not given
655
+ let indexRange = null;
656
+ let callback;
657
+ if (args.length === 1) {
658
+ indexRange = new node_opcua_numeric_range_1.NumericRange();
659
+ callback = args[0];
660
+ }
661
+ else if (args.length === 2) {
662
+ indexRange = args[0];
663
+ callback = args[1];
664
+ }
665
+ else {
666
+ throw new Error("Invalid Number of args");
667
+ }
668
+ (0, node_opcua_assert_1.assert)(typeof callback === "function");
669
+ (0, node_opcua_assert_1.assert)(dataValue instanceof node_opcua_data_value_1.DataValue);
670
+ // index range could be string
671
+ indexRange = node_opcua_numeric_range_1.NumericRange.coerce(indexRange);
672
+ // test write permission
673
+ if (!this.isWritable(context)) {
674
+ return callback(null, node_opcua_status_code_1.StatusCodes.BadNotWritable);
675
+ }
676
+ if (!this.checkPermissionPrivate(context, node_opcua_types_1.PermissionType.Write)) {
677
+ return new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.BadUserAccessDenied });
678
+ }
679
+ if (!this.isUserWritable(context)) {
680
+ return callback(null, node_opcua_status_code_1.StatusCodes.BadWriteNotSupported);
681
+ }
682
+ // adjust special case
683
+ const variant = adjustVariant2.call(this, dataValue.value);
684
+ const statusCode = this.checkVariantCompatibility(variant);
685
+ if (statusCode.isNot(node_opcua_status_code_1.StatusCodes.Good)) {
686
+ return callback(null, statusCode);
687
+ }
688
+ const write_func = this._timestamped_set_func || default_func;
689
+ if (!write_func) {
690
+ warningLog(" warning " + this.nodeId.toString() + " " + this.browseName.toString() + " has no setter. \n");
691
+ warningLog("Please make sure to bind the variable or to pass a valid value: new Variant({}) during construction time");
692
+ return callback(null, node_opcua_status_code_1.StatusCodes.BadNotWritable);
693
+ }
694
+ (0, node_opcua_assert_1.assert)(write_func);
695
+ write_func.call(this, dataValue, (err, statusCode1) => {
696
+ if (!err) {
697
+ dataValue && this.verifyVariantCompatibility(dataValue.value);
698
+ if (indexRange && !indexRange.isEmpty()) {
699
+ if (!indexRange.isValid()) {
700
+ return callback(null, node_opcua_status_code_1.StatusCodes.BadIndexRangeInvalid);
701
+ }
702
+ const newArrayOrMatrix = dataValue.value.value;
703
+ if (dataValue.value.arrayType === node_opcua_variant_1.VariantArrayType.Array) {
704
+ if (this.$dataValue.value.arrayType !== node_opcua_variant_1.VariantArrayType.Array) {
705
+ return callback(null, node_opcua_status_code_1.StatusCodes.BadTypeMismatch);
706
+ }
707
+ // check that destination data is also an array
708
+ (0, node_opcua_assert_1.assert)(check_valid_array(this.$dataValue.value.dataType, this.$dataValue.value.value));
709
+ const destArr = this.$dataValue.value.value;
710
+ const result = indexRange.set_values(destArr, newArrayOrMatrix);
711
+ if (result.statusCode.isNot(node_opcua_status_code_1.StatusCodes.Good)) {
712
+ return callback(null, result.statusCode);
713
+ }
714
+ dataValue.value.value = result.array;
715
+ // scrap original array so we detect range
716
+ this.$dataValue.value.value = null;
717
+ }
718
+ else if (dataValue.value.arrayType === node_opcua_variant_1.VariantArrayType.Matrix) {
719
+ const dimensions = this.$dataValue.value.dimensions;
720
+ if (this.$dataValue.value.arrayType !== node_opcua_variant_1.VariantArrayType.Matrix || !dimensions) {
721
+ // not a matrix !
722
+ return callback(null, node_opcua_status_code_1.StatusCodes.BadTypeMismatch);
723
+ }
724
+ const matrix = this.$dataValue.value.value;
725
+ const result = indexRange.set_values_matrix({
726
+ matrix,
727
+ dimensions
728
+ }, newArrayOrMatrix);
729
+ if (result.statusCode.isNot(node_opcua_status_code_1.StatusCodes.Good)) {
730
+ return callback(null, result.statusCode);
731
+ }
732
+ dataValue.value.dimensions = this.$dataValue.value.dimensions;
733
+ dataValue.value.value = result.matrix;
734
+ // scrap original array so we detect range
735
+ this.$dataValue.value.value = null;
736
+ }
737
+ else {
738
+ return callback(null, node_opcua_status_code_1.StatusCodes.BadTypeMismatch);
739
+ }
740
+ }
741
+ try {
742
+ this._internal_set_dataValue(dataValue, indexRange);
743
+ }
744
+ catch (err) {
745
+ if (err instanceof Error) {
746
+ warningLog(err.message);
747
+ }
748
+ return callback(null, node_opcua_status_code_1.StatusCodes.BadInternalError);
749
+ }
750
+ }
751
+ callback(err || null, statusCode1);
752
+ });
753
+ }
754
+ writeAttribute(context, writeValueOptions, callback) {
755
+ // istanbul ignore next
756
+ if (!callback) {
757
+ throw new Error("Internal error");
758
+ }
759
+ if (!this.canUserWriteAttribute(context, writeValueOptions.attributeId)) {
760
+ return callback(null, node_opcua_status_code_1.StatusCodes.BadUserAccessDenied);
761
+ }
762
+ const writeValue = writeValueOptions instanceof node_opcua_service_write_1.WriteValue ? writeValueOptions : new node_opcua_service_write_1.WriteValue(writeValueOptions);
763
+ context = context || session_context_1.SessionContext.defaultContext;
764
+ (0, node_opcua_assert_1.assert)(context instanceof session_context_1.SessionContext);
765
+ (0, node_opcua_assert_1.assert)(writeValue instanceof node_opcua_service_write_1.WriteValue);
766
+ (0, node_opcua_assert_1.assert)(writeValue.value instanceof node_opcua_data_value_1.DataValue);
767
+ (0, node_opcua_assert_1.assert)(writeValue.value.value instanceof node_opcua_variant_1.Variant);
768
+ (0, node_opcua_assert_1.assert)(typeof callback === "function");
769
+ // Spec 1.0.2 Part 4 page 58
770
+ // If the SourceTimestamp or the ServerTimestamp is specified, the Server shall
771
+ // use these values.
772
+ // xx _apply_default_timestamps(writeValue.value);
773
+ switch (writeValue.attributeId) {
774
+ case node_opcua_data_model_1.AttributeIds.Value:
775
+ this.writeValue(context, writeValue.value, writeValue.indexRange, callback);
776
+ break;
777
+ case node_opcua_data_model_1.AttributeIds.Historizing:
778
+ if (writeValue.value.value.dataType !== node_opcua_variant_1.DataType.Boolean) {
779
+ return callback(null, node_opcua_status_code_1.StatusCodes.BadTypeMismatch);
780
+ }
781
+ if (!this.checkPermissionPrivate(context, node_opcua_types_1.PermissionType.WriteHistorizing)) {
782
+ return callback(null, node_opcua_status_code_1.StatusCodes.BadUserAccessDenied);
783
+ }
784
+ if (!this.canUserWriteHistorizingAttribute(context)) {
785
+ return callback(null, node_opcua_status_code_1.StatusCodes.BadHistoryOperationUnsupported);
786
+ }
787
+ // if the variable has no historizing in place reject
788
+ if (!this.getChildByName("HA Configuration")) {
789
+ return callback(null, node_opcua_status_code_1.StatusCodes.BadNotSupported);
790
+ }
791
+ // check if user is allowed to do that !
792
+ // TODO
793
+ this.historizing = !!writeValue.value.value.value; // yes ! indeed !
794
+ return callback(null, node_opcua_status_code_1.StatusCodes.Good);
795
+ default:
796
+ super.writeAttribute(context, writeValue, callback);
797
+ break;
798
+ }
799
+ }
800
+ /**
801
+ * @method checkVariantCompatibility
802
+ * note:
803
+ * this method is overridden in address-space-data-access
804
+ * @return {StatusCode}
805
+ */
806
+ checkVariantCompatibility(value) {
807
+ // test dataType
808
+ if (!this._validate_DataType(value.dataType)) {
809
+ return node_opcua_status_code_1.StatusCodes.BadTypeMismatch;
810
+ }
811
+ try {
812
+ this.verifyVariantCompatibility(value);
813
+ }
814
+ catch (err) {
815
+ return node_opcua_status_code_1.StatusCodes.BadTypeMismatch;
816
+ }
817
+ return node_opcua_status_code_1.StatusCodes.Good;
818
+ }
819
+ /**
820
+ * touch the source timestamp of a Variable and cascade up the change
821
+ * to the parent variable if any.
822
+ */
823
+ touchValue(optionalNow) {
824
+ const now = optionalNow || (0, node_opcua_date_time_1.getCurrentClock)();
825
+ (0, ua_variable_impl_ext_obj_1.propagateTouchValueUpward)(this, now);
826
+ }
827
+ /**
828
+ * bind a variable with a get and set functions.
829
+ *
830
+ * properties:
831
+ * - value: a Variant or a status code
832
+ * - sourceTimestamp
833
+ * - sourcePicoseconds
834
+ * @param [options.timestamped_set]
835
+ * @param [options.refreshFunc] the variable asynchronous getter function.
836
+ * @param [overwrite {Boolean} = false] set overwrite to true to overwrite existing binding
837
+ * @return void
838
+ *
839
+ *
840
+ * ### Providing read access to the underlying value
841
+ *
842
+ * #### Variation 1
843
+ *
844
+ * In this variation, the user provides a function that returns a Variant with the current value.
845
+ *
846
+ * The sourceTimestamp will be set automatically.
847
+ *
848
+ * The get function is called synchronously.
849
+ *
850
+ * @example
851
+ *
852
+ *
853
+ * ```javascript
854
+ * ...
855
+ * var options = {
856
+ * get : () => {
857
+ * return new Variant({...});
858
+ * },
859
+ * set : function(variant) {
860
+ * // store the variant somewhere
861
+ * return StatusCodes.Good;
862
+ * }
863
+ * };
864
+ * ...
865
+ * engine.bindVariable(nodeId,options):
866
+ * ...
867
+ * ```
868
+ *
869
+ *
870
+ * #### Variation 2:
871
+ *
872
+ * This variation can be used when the user wants to specify a specific '''sourceTimestamp''' associated
873
+ * with the current value of the UAVariable.
874
+ *
875
+ * The provided ```timestamped_get``` function should return an object with three properties:
876
+ * * value: containing the variant value or a error StatusCode,
877
+ * * sourceTimestamp
878
+ * * sourcePicoseconds
879
+ *
880
+ * ```javascript
881
+ * ...
882
+ * var myDataValue = new DataValue({
883
+ * value: {dataType: DataType.Double , value: 10.0},
884
+ * sourceTimestamp : new Date(),
885
+ * sourcePicoseconds: 0
886
+ * });
887
+ * ...
888
+ * var options = {
889
+ * timestamped_get : () => { return myDataValue; }
890
+ * };
891
+ * ...
892
+ * engine.bindVariable(nodeId,options):
893
+ * ...
894
+ * // record a new value
895
+ * myDataValue.value.value = 5.0;
896
+ * myDataValue.sourceTimestamp = new Date();
897
+ * ...
898
+ * ```
899
+ *
900
+ *
901
+ * #### Variation 3:
902
+ *
903
+ * This variation can be used when the value associated with the variables requires a asynchronous function call to be
904
+ * extracted. In this case, the user should provide an async method ```refreshFunc```.
905
+ *
906
+ *
907
+ * The ```refreshFunc``` shall do whatever is necessary to fetch the most up to date version of the variable value, and
908
+ * call the ```callback``` function when the data is ready.
909
+ *
910
+ *
911
+ * The ```callback``` function follow the standard callback function signature:
912
+ * * the first argument shall be **null** or **Error**, depending of the outcome of the fetch operation,
913
+ * * the second argument shall be a DataValue with the new UAVariable Value, a StatusCode, and time stamps.
914
+ *
915
+ *
916
+ * Optionally, it is possible to pass a sourceTimestamp and a sourcePicoseconds value as a third and fourth arguments
917
+ * of the callback. When sourceTimestamp and sourcePicoseconds are missing, the system will set their default value
918
+ * to the current time..
919
+ *
920
+ *
921
+ * ```javascript
922
+ * ...
923
+ * var options = {
924
+ * refreshFunc : function(callback) {
925
+ * ... do_some_async_stuff_to_get_the_new_variable_value
926
+ * var dataValue = new DataValue({
927
+ * value: new Variant({...}),
928
+ * statusCode: StatusCodes.Good,
929
+ * sourceTimestamp: new Date()
930
+ * });
931
+ * callback(null,dataValue);
932
+ * }
933
+ * };
934
+ * ...
935
+ * variable.bindVariable(nodeId,options):
936
+ * ...
937
+ * ```
938
+ *
939
+ * ### Providing write access to the underlying value
940
+ *
941
+ * #### Variation1 - provide a simple synchronous set function
942
+ *
943
+ *
944
+ * #### Notes
945
+ * to do : explain return StatusCodes.GoodCompletesAsynchronously;
946
+ *
947
+ */
948
+ bindVariable(options, overwrite) {
949
+ if (overwrite) {
950
+ this._timestamped_set_func = null;
951
+ this._timestamped_get_func = null;
952
+ this._get_func = null;
953
+ this._set_func = null;
954
+ this.refreshFunc = undefined;
955
+ this._historyRead = UAVariableImpl.prototype._historyRead;
956
+ }
957
+ options = options || {};
958
+ (0, node_opcua_assert_1.assert)(typeof this._timestamped_set_func !== "function", "UAVariable already bound");
959
+ (0, node_opcua_assert_1.assert)(typeof this._timestamped_get_func !== "function", "UAVariable already bound");
960
+ bind_getter.call(this, options);
961
+ bind_setter.call(this, options);
962
+ const _historyRead = options.historyRead;
963
+ if (_historyRead) {
964
+ (0, node_opcua_assert_1.assert)(typeof this._historyRead !== "function" || this._historyRead === UAVariableImpl.prototype._historyRead);
965
+ (0, node_opcua_assert_1.assert)(typeof _historyRead === "function");
966
+ this._historyRead = _historyRead;
967
+ (0, node_opcua_assert_1.assert)(this._historyRead.length === 6);
968
+ }
969
+ // post conditions
970
+ (0, node_opcua_assert_1.assert)(typeof this._timestamped_set_func === "function");
971
+ (0, node_opcua_assert_1.assert)(this._timestamped_set_func.length === 2, "expecting 2 parameters");
972
+ }
973
+ readValueAsync(context, callback) {
974
+ (0, node_opcua_assert_1.assert)(typeof callback === "function");
975
+ context = context || session_context_1.SessionContext.defaultContext;
976
+ this.__waiting_callbacks = this.__waiting_callbacks || [];
977
+ this.__waiting_callbacks.push(callback);
978
+ const _readValueAsync_in_progress = this.__waiting_callbacks.length >= 2;
979
+ if (_readValueAsync_in_progress) {
980
+ return;
981
+ }
982
+ if (this.isDisposed()) {
983
+ return callback(null, new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.BadNodeIdUnknown }));
984
+ }
985
+ const readImmediate = (innerCallback) => {
986
+ (0, node_opcua_assert_1.assert)(this.$dataValue instanceof node_opcua_data_value_1.DataValue);
987
+ const dataValue = this.readValue();
988
+ innerCallback(null, dataValue);
989
+ };
990
+ let func;
991
+ if (!this.isReadable(context)) {
992
+ func = (innerCallback) => {
993
+ const dataValue = new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.BadNotReadable });
994
+ innerCallback(null, dataValue);
995
+ };
996
+ }
997
+ else if (!this.checkPermissionPrivate(context, node_opcua_types_1.PermissionType.Read)) {
998
+ func = (innerCallback) => {
999
+ const dataValue = new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.BadUserAccessDenied });
1000
+ innerCallback(null, dataValue);
1001
+ };
1002
+ }
1003
+ else if (!this.isUserReadable(context)) {
1004
+ func = (innerCallback) => {
1005
+ const dataValue = new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.BadNotReadable });
1006
+ innerCallback(null, dataValue);
1007
+ };
1008
+ }
1009
+ else {
1010
+ func = typeof this.refreshFunc === "function" ? this.asyncRefresh.bind(this, new Date()) : readImmediate;
1011
+ }
1012
+ const satisfy_callbacks = (err, dataValue) => {
1013
+ // now call all pending callbacks
1014
+ const callbacks = this.__waiting_callbacks || [];
1015
+ this.__waiting_callbacks = [];
1016
+ const n = callbacks.length;
1017
+ for (const callback1 of callbacks) {
1018
+ callback1.call(this, err, dataValue);
1019
+ }
1020
+ };
1021
+ try {
1022
+ func.call(this, satisfy_callbacks);
1023
+ }
1024
+ catch (err) {
1025
+ // istanbul ignore next
1026
+ if (doDebug) {
1027
+ debugLog(chalk.red("func readValueAsync has failed "));
1028
+ if (err instanceof Error) {
1029
+ debugLog(" stack", err.stack);
1030
+ }
1031
+ }
1032
+ satisfy_callbacks(err);
1033
+ }
1034
+ }
1035
+ getWriteMask() {
1036
+ return super.getWriteMask();
1037
+ }
1038
+ getUserWriteMask() {
1039
+ return super.getUserWriteMask();
1040
+ }
1041
+ clone(options, optionalFilter, extraInfo) {
1042
+ options = Object.assign(Object.assign({}, options), {
1043
+ // check this eventNotifier: this.eventNotifier,
1044
+ // check this symbolicName: this.symbolicName,
1045
+ accessLevel: this.accessLevel, arrayDimensions: this.arrayDimensions, dataType: this.dataType, historizing: this.historizing, minimumSamplingInterval: this.minimumSamplingInterval, userAccessLevel: this.userAccessLevel, valueRank: this.valueRank });
1046
+ const newVariable = base_node_private_1._clone.call(this, UAVariableImpl, options, optionalFilter || node_opcua_address_space_base_1.defaultCloneFilter, extraInfo || node_opcua_address_space_base_1.defaultCloneExtraInfo);
1047
+ newVariable.bindVariable();
1048
+ (0, node_opcua_assert_1.assert)(typeof newVariable._timestamped_set_func === "function");
1049
+ (0, node_opcua_assert_1.assert)(newVariable.dataType === this.dataType);
1050
+ newVariable.$dataValue = this.$dataValue.clone();
1051
+ // also bind extension object
1052
+ const v = newVariable.$dataValue.value;
1053
+ if (v.dataType === node_opcua_variant_1.DataType.ExtensionObject && v.value && v.arrayType === node_opcua_variant_1.VariantArrayType.Scalar) {
1054
+ try {
1055
+ newVariable.bindExtensionObject(newVariable.$dataValue.value.value);
1056
+ }
1057
+ catch (err) {
1058
+ errorLog("Errro binding extension objects");
1059
+ errorLog(err.message);
1060
+ errorLog(this.toString());
1061
+ errorLog("---------------------------------------");
1062
+ errorLog(this.$dataValue.toString());
1063
+ errorLog("---------------------------------------");
1064
+ errorLog(newVariable.$dataValue.toString());
1065
+ throw err;
1066
+ }
1067
+ }
1068
+ return newVariable;
1069
+ }
1070
+ getDataTypeNode() {
1071
+ const addressSpace = this.addressSpace;
1072
+ const dt = addressSpace.findNode(this.dataType);
1073
+ // istanbul ignore next
1074
+ if (!dt) {
1075
+ throw new Error("getDataTypeNode: cannot find dataType " + this.dataType.toString());
1076
+ }
1077
+ return dt;
1078
+ }
1079
+ get dataTypeObj() {
1080
+ return this.getDataTypeNode();
1081
+ }
1082
+ checkExtensionObjectIsCorrect(extObj) {
1083
+ if (!extObj) {
1084
+ return true;
1085
+ }
1086
+ const addressSpace = this.addressSpace;
1087
+ const dataType = addressSpace.findDataType(this.dataType);
1088
+ if (!dataType) {
1089
+ // may be we are in the process of loading a xml file and the corresponding dataType
1090
+ // has not yet been loaded !
1091
+ return true;
1092
+ }
1093
+ const Constructor = addressSpace.getExtensionObjectConstructor(this.dataType);
1094
+ if (this.valueRank === -1) {
1095
+ /** Scalar */
1096
+ if (extObj instanceof Array) {
1097
+ return false;
1098
+ }
1099
+ return checkExtensionObjectIsCorrectScalar.call(this, extObj);
1100
+ }
1101
+ else if (this.valueRank >= 1) {
1102
+ /** array */
1103
+ if (!(extObj instanceof Array)) {
1104
+ // let's coerce this scalar into an 1-element array if it is a valid extension object
1105
+ if (checkExtensionObjectIsCorrectScalar.call(this, extObj)) {
1106
+ warningLog(`warning: checkExtensionObjectIsCorrect : expecting a array but got a scalar (value rank of '${this.browseName.toString()}' is 1)\nautomatic conversion from scalar to array with 1 element is taking place.`);
1107
+ extObj = [extObj];
1108
+ }
1109
+ else {
1110
+ return false;
1111
+ }
1112
+ }
1113
+ return checkExtensionObjectIsCorrectArray.call(this, extObj);
1114
+ }
1115
+ else if (this.valueRank === 0) {
1116
+ // Scalar or Array
1117
+ const isCorrectScalar = !Array.isArray(extObj) && checkExtensionObjectIsCorrectScalar.call(this, extObj);
1118
+ const isCorrectArray = Array.isArray(extObj) && checkExtensionObjectIsCorrectArray.call(this, extObj);
1119
+ return isCorrectArray || isCorrectScalar;
1120
+ }
1121
+ else {
1122
+ throw new Error(`checkExtensionObjectIsCorrect: Not Implemented case, please contact sterfive : this.valueRank =${this.valueRank}`);
1123
+ }
1124
+ function checkExtensionObjectIsCorrectScalar(extObj) {
1125
+ // istanbul ignore next
1126
+ if (!(extObj && extObj.constructor)) {
1127
+ errorLog(extObj);
1128
+ throw new Error("expecting an valid extension object");
1129
+ }
1130
+ return extObj.constructor.name === Constructor.name;
1131
+ }
1132
+ function checkExtensionObjectIsCorrectArray(extObjArray) {
1133
+ // istanbul ignore next
1134
+ for (const extObj of extObjArray) {
1135
+ if (!(extObj && extObj.constructor)) {
1136
+ errorLog(extObj);
1137
+ throw new Error("expecting an valid extension object");
1138
+ }
1139
+ }
1140
+ try {
1141
+ for (const e of extObjArray) {
1142
+ if (!e) {
1143
+ continue;
1144
+ }
1145
+ if (e.constructor.name !== Constructor.name) {
1146
+ debugLog("extObj.constructor.name ", e.constructor.name, "expected", Constructor.name);
1147
+ return false;
1148
+ }
1149
+ }
1150
+ return true;
1151
+ }
1152
+ catch (err) {
1153
+ errorLog(err);
1154
+ return false;
1155
+ }
1156
+ }
1157
+ }
1158
+ /**
1159
+ * @private
1160
+ * install UAVariable to exposed th
1161
+ *
1162
+ * precondition:
1163
+ */
1164
+ installExtensionObjectVariables() {
1165
+ (0, ua_variable_impl_ext_obj_1._installExtensionObjectBindingOnProperties)(this, { createMissingProp: true });
1166
+ }
1167
+ /**
1168
+ * @method bindExtensionObject
1169
+ * @return {ExtensionObject}
1170
+ */
1171
+ bindExtensionObjectScalar(optionalExtensionObject, options) {
1172
+ (0, node_opcua_assert_1.assert)(this.valueRank === -1, "expecting an Scalar variable here");
1173
+ return (0, ua_variable_impl_ext_obj_1._bindExtensionObject)(this, optionalExtensionObject, options);
1174
+ }
1175
+ bindExtensionObjectArray(optionalExtensionObject, options) {
1176
+ (0, node_opcua_assert_1.assert)(this.valueRank >= 1, "expecting an Array or a Matrix variable here");
1177
+ return (0, ua_variable_impl_ext_obj_1._bindExtensionObjectArrayOrMatrix)(this, optionalExtensionObject, options);
1178
+ }
1179
+ bindExtensionObject(optionalExtensionObject, options) {
1180
+ // coerce to ExtensionObject[] when this.valueRank === 1
1181
+ if (optionalExtensionObject && this.valueRank === 1 && !Array.isArray(optionalExtensionObject) && optionalExtensionObject instanceof node_opcua_extension_object_1.ExtensionObject) {
1182
+ warningLog("bindExtensionObject: coerce to ExtensionObject[] when valueRank === 1 and value is a scalar extension object");
1183
+ optionalExtensionObject = [optionalExtensionObject];
1184
+ }
1185
+ if (optionalExtensionObject) {
1186
+ if (optionalExtensionObject instanceof Array) {
1187
+ (0, node_opcua_assert_1.assert)(this.valueRank >= 1, "bindExtensionObject: expecting an Array of Matrix variable here");
1188
+ return (0, ua_variable_impl_ext_obj_1._bindExtensionObjectArrayOrMatrix)(this, optionalExtensionObject, options);
1189
+ }
1190
+ else {
1191
+ if (this.valueRank !== -1 && this.valueRank !== 0) {
1192
+ throw new Error("bindExtensionObject: expecting an Scalar variable here but got value rank " + this.valueRank);
1193
+ }
1194
+ return (0, ua_variable_impl_ext_obj_1._bindExtensionObject)(this, optionalExtensionObject, options);
1195
+ }
1196
+ }
1197
+ (0, node_opcua_assert_1.assert)(optionalExtensionObject === undefined);
1198
+ if (this.valueRank === -1) {
1199
+ return (0, ua_variable_impl_ext_obj_1._bindExtensionObject)(this, undefined, options);
1200
+ }
1201
+ else if (this.valueRank === 1) {
1202
+ return (0, ua_variable_impl_ext_obj_1._bindExtensionObjectArrayOrMatrix)(this, undefined, options);
1203
+ }
1204
+ else if (this.valueRank > 1) {
1205
+ return (0, ua_variable_impl_ext_obj_1._bindExtensionObjectArrayOrMatrix)(this, undefined, options);
1206
+ }
1207
+ // unsupported case ...
1208
+ return null;
1209
+ }
1210
+ updateExtensionObjectPartial(partialExtensionObject) {
1211
+ (0, ua_variable_impl_ext_obj_1.setExtensionObjectPartialValue)(this, partialExtensionObject);
1212
+ return this.$extensionObject;
1213
+ }
1214
+ incrementExtensionObjectPartial(path) {
1215
+ const extensionObject = this.readValue().value.value;
1216
+ const partialData = (0, ua_variable_impl_ext_obj_1.extractPartialData)(path, extensionObject);
1217
+ (0, ua_variable_impl_ext_obj_1.incrementElement)(path, partialData);
1218
+ (0, ua_variable_impl_ext_obj_1.setExtensionObjectPartialValue)(this, partialData);
1219
+ }
1220
+ toString() {
1221
+ const options = new base_node_private_1.ToStringBuilder();
1222
+ base_node_private_1.UAVariable_toString.call(this, options);
1223
+ return options.toString();
1224
+ }
1225
+ historyRead(context, historyReadDetails, indexRange, dataEncoding, continuationData, callback) {
1226
+ (0, node_opcua_assert_1.assert)(context instanceof session_context_1.SessionContext);
1227
+ (0, node_opcua_assert_1.assert)(typeof callback === "function");
1228
+ if (typeof this._historyRead !== "function") {
1229
+ return callback(null, new node_opcua_types_1.HistoryReadResult({ statusCode: node_opcua_status_code_1.StatusCodes.BadNotReadable }));
1230
+ }
1231
+ this._historyRead(context, historyReadDetails, indexRange, dataEncoding, continuationData, callback);
1232
+ }
1233
+ _historyReadRaw(context, historyReadRawModifiedDetails, indexRange, dataEncoding, continuationData, callback) {
1234
+ throw new Error("");
1235
+ }
1236
+ _historyReadRawModify(context, historyReadRawModifiedDetails, indexRange, dataEncoding, continuationData, callback) {
1237
+ throw new Error("");
1238
+ }
1239
+ _historyRead(context, historyReadDetails, indexRange, dataEncoding, continuationData, callback) {
1240
+ if (!this.checkPermissionPrivate(context, node_opcua_types_1.PermissionType.ReadHistory)) {
1241
+ const result = new node_opcua_types_1.HistoryReadResult({
1242
+ statusCode: node_opcua_status_code_1.StatusCodes.BadUserAccessDenied
1243
+ });
1244
+ callback(null, result);
1245
+ }
1246
+ if (!this.canUserReadHistory(context)) {
1247
+ const result = new node_opcua_types_1.HistoryReadResult({
1248
+ statusCode: node_opcua_status_code_1.StatusCodes.BadHistoryOperationUnsupported
1249
+ });
1250
+ callback(null, result);
1251
+ }
1252
+ const result = new node_opcua_types_1.HistoryReadResult({
1253
+ statusCode: node_opcua_status_code_1.StatusCodes.BadHistoryOperationUnsupported
1254
+ });
1255
+ callback(null, result);
1256
+ }
1257
+ _historyPush(newDataValue) {
1258
+ throw new Error("");
1259
+ }
1260
+ _historyReadRawAsync(historyReadRawModifiedDetails, maxNumberToExtract, isReversed, reverseDataValue, callback) {
1261
+ throw new Error("");
1262
+ }
1263
+ _historyReadModify(context, historyReadRawModifiedDetails, indexRange, dataEncoding, continuationData, callback) {
1264
+ throw new Error("");
1265
+ }
1266
+ _update_startOfOnlineArchive(newDate) {
1267
+ // please install
1268
+ throw new Error("");
1269
+ }
1270
+ _update_startOfArchive(newDate) {
1271
+ throw new Error("");
1272
+ }
1273
+ _validate_DataType(variantDataType) {
1274
+ return validateDataType(this.addressSpace, this.dataType, variantDataType, this.nodeId, /* allow Nulls */ false);
1275
+ }
1276
+ _internal_set_value(value) {
1277
+ if (value.dataType !== node_opcua_variant_1.DataType.Null) {
1278
+ this.verifyVariantCompatibility(value);
1279
+ }
1280
+ this.$dataValue.value = value;
1281
+ }
1282
+ _internal_set_dataValue(dataValue, indexRange) {
1283
+ (0, node_opcua_assert_1.assert)(dataValue, "expecting a dataValue");
1284
+ (0, node_opcua_assert_1.assert)(dataValue instanceof node_opcua_data_value_1.DataValue, "expecting dataValue to be a DataValue");
1285
+ (0, node_opcua_assert_1.assert)(dataValue !== this.$dataValue, "expecting dataValue to be different from previous DataValue instance");
1286
+ const addressSpace = this.addressSpace;
1287
+ // istanbul ignore next
1288
+ if (!addressSpace) {
1289
+ warningLog("UAVariable#_internal_set_dataValue : no addressSpace ! may be node has already been deleted ?");
1290
+ return;
1291
+ }
1292
+ // istanbul ignore next
1293
+ if (dataValue.value.arrayType === node_opcua_variant_1.VariantArrayType.Matrix) {
1294
+ if (!dataValue.value.dimensions) {
1295
+ throw new Error("missing dimensions: a Matrix Variant needs a dimension");
1296
+ }
1297
+ const nbElements = dataValue.value.dimensions.reduce((acc, x) => acc * x, 1);
1298
+ if (dataValue.value.value.length !== 0 && dataValue.value.value.length !== nbElements) {
1299
+ throw new Error(`Internal Error: matrix dimension doesn't match the number of element in the array : ${dataValue.toString()} "\n expecting ${nbElements} elements but got ${dataValue.value.value.length}`);
1300
+ }
1301
+ }
1302
+ // istanbul ignore next
1303
+ if (dataValue.value.dataType === node_opcua_variant_1.DataType.ExtensionObject) {
1304
+ // istanbul ignore next
1305
+ if (!this.checkExtensionObjectIsCorrect(dataValue.value.value)) {
1306
+ warningLog(dataValue.toString());
1307
+ throw new Error("Invalid Extension Object on nodeId =" + this.nodeId.toString());
1308
+ }
1309
+ }
1310
+ this.verifyVariantCompatibility(dataValue.value);
1311
+ this._inner_replace_dataValue(dataValue, indexRange);
1312
+ }
1313
+ /**
1314
+ * @private
1315
+ */
1316
+ _inner_replace_dataValue(dataValue, indexRange) {
1317
+ (0, node_opcua_assert_1.assert)(this.$dataValue.value instanceof node_opcua_variant_1.Variant);
1318
+ const old_dataValue = this.$dataValue.clone();
1319
+ if (this.$$extensionObjectArray && dataValue.value.arrayType !== node_opcua_variant_1.VariantArrayType.Scalar) {
1320
+ // we have a bounded array or matrix
1321
+ (0, node_opcua_assert_1.assert)(Array.isArray(dataValue.value.value));
1322
+ if (this.$$extensionObjectArray !== this.$dataValue.value.value) {
1323
+ throw new Error("internal error");
1324
+ }
1325
+ this.$$extensionObjectArray = dataValue.value.value;
1326
+ this.$dataValue.value.value = dataValue.value.value;
1327
+ this.$dataValue.statusCode = dataValue.statusCode || node_opcua_status_code_1.StatusCodes.Good;
1328
+ this.$dataValue.serverTimestamp = dataValue.serverTimestamp;
1329
+ this.$dataValue.serverPicoseconds = dataValue.serverPicoseconds;
1330
+ this.$dataValue.sourceTimestamp = dataValue.sourceTimestamp;
1331
+ this.$dataValue.sourcePicoseconds = dataValue.sourcePicoseconds;
1332
+ }
1333
+ else if (this._basicDataType === node_opcua_variant_1.DataType.ExtensionObject && this.valueRank === -1 && this.$set_ExtensionObject && dataValue.value.arrayType === node_opcua_variant_1.VariantArrayType.Scalar) {
1334
+ // the entire extension object is changed.
1335
+ this.$dataValue.statusCode = this.$dataValue.statusCode || node_opcua_status_code_1.StatusCodes.Good;
1336
+ const preciseClock = (0, node_opcua_date_time_1.coerceClock)(this.$dataValue.sourceTimestamp, this.$dataValue.sourcePicoseconds);
1337
+ this.$set_ExtensionObject(dataValue.value.value, preciseClock, new Set());
1338
+ }
1339
+ else {
1340
+ this.$dataValue = dataValue;
1341
+ this.$dataValue.statusCode = this.$dataValue.statusCode || node_opcua_status_code_1.StatusCodes.Good;
1342
+ }
1343
+ // repair missing timestamps
1344
+ const now = new Date();
1345
+ if (!dataValue.serverTimestamp) {
1346
+ this.$dataValue.serverTimestamp = old_dataValue.serverTimestamp || now;
1347
+ this.$dataValue.serverPicoseconds = old_dataValue.serverPicoseconds || 0;
1348
+ }
1349
+ if (!dataValue.sourceTimestamp) {
1350
+ this.$dataValue.sourceTimestamp = old_dataValue.sourceTimestamp || now;
1351
+ this.$dataValue.sourcePicoseconds = old_dataValue.sourcePicoseconds || 0;
1352
+ }
1353
+ if (!(0, node_opcua_data_value_1.sameDataValue)(old_dataValue, dataValue)) {
1354
+ if (this.getBasicDataType() === node_opcua_variant_1.DataType.ExtensionObject) {
1355
+ const preciseClock = (0, node_opcua_date_time_1.coerceClock)(this.$dataValue.sourceTimestamp, this.$dataValue.sourcePicoseconds);
1356
+ const cache = new Set();
1357
+ if (this.$$extensionObjectArray) {
1358
+ this.touchValue(preciseClock);
1359
+ (0, ua_variable_impl_ext_obj_1.propagateTouchValueDownwardArray)(this, preciseClock, cache);
1360
+ }
1361
+ else {
1362
+ this.touchValue(preciseClock);
1363
+ (0, ua_variable_impl_ext_obj_1.propagateTouchValueDownward)(this, preciseClock, cache);
1364
+ }
1365
+ }
1366
+ else {
1367
+ this.emit("value_changed", this.$dataValue.clone(), indexRange);
1368
+ }
1369
+ }
1370
+ }
1371
+ _conditionRefresh(_cache) {
1372
+ apply_condition_refresh_1.apply_condition_refresh.call(this, _cache);
1373
+ }
1374
+ handle_semantic_changed() {
1375
+ this.semantic_version = this.semantic_version + 1;
1376
+ this.emit("semantic_changed");
1377
+ }
1378
+ _readDataType() {
1379
+ (0, node_opcua_assert_1.assert)(this.dataType instanceof node_opcua_nodeid_1.NodeId);
1380
+ const options = {
1381
+ statusCode: node_opcua_status_code_1.StatusCodes.Good,
1382
+ value: {
1383
+ dataType: node_opcua_variant_1.DataType.NodeId,
1384
+ value: this.dataType
1385
+ }
1386
+ };
1387
+ return new node_opcua_data_value_1.DataValue(options);
1388
+ }
1389
+ _readValueRank() {
1390
+ (0, node_opcua_assert_1.assert)(typeof this.valueRank === "number");
1391
+ const options = {
1392
+ statusCode: node_opcua_status_code_1.StatusCodes.Good,
1393
+ value: { dataType: node_opcua_variant_1.DataType.Int32, value: this.valueRank }
1394
+ };
1395
+ return new node_opcua_data_value_1.DataValue(options);
1396
+ }
1397
+ _readArrayDimensions() {
1398
+ (0, node_opcua_assert_1.assert)(Array.isArray(this.arrayDimensions) || this.arrayDimensions === null);
1399
+ (0, node_opcua_assert_1.assert)(!this.arrayDimensions || this.valueRank > 0, "arrayDimension must be null if valueRank <0");
1400
+ const options = {
1401
+ statusCode: node_opcua_status_code_1.StatusCodes.Good,
1402
+ value: { dataType: node_opcua_variant_1.DataType.UInt32, arrayType: node_opcua_variant_1.VariantArrayType.Array, value: this.arrayDimensions }
1403
+ };
1404
+ return new node_opcua_data_value_1.DataValue(options);
1405
+ }
1406
+ _readAccessLevel(context) {
1407
+ (0, node_opcua_assert_1.assert)(context instanceof session_context_1.SessionContext);
1408
+ const options = {
1409
+ statusCode: node_opcua_status_code_1.StatusCodes.Good,
1410
+ value: { dataType: node_opcua_variant_1.DataType.Byte, value: (0, node_opcua_data_model_1.convertAccessLevelFlagToByte)(this.accessLevel) }
1411
+ };
1412
+ return new node_opcua_data_value_1.DataValue(options);
1413
+ }
1414
+ _readAccessLevelEx(context) {
1415
+ (0, node_opcua_assert_1.assert)(context instanceof session_context_1.SessionContext);
1416
+ const options = {
1417
+ statusCode: node_opcua_status_code_1.StatusCodes.Good,
1418
+ // Extra flags are not supported yet. to do:
1419
+ value: { dataType: node_opcua_variant_1.DataType.UInt32, value: (0, node_opcua_data_model_1.convertAccessLevelFlagToByte)(this.accessLevel) }
1420
+ };
1421
+ return new node_opcua_data_value_1.DataValue(options);
1422
+ }
1423
+ _readUserAccessLevel(context) {
1424
+ (0, node_opcua_assert_1.assert)(context instanceof session_context_1.SessionContext);
1425
+ const effectiveUserAccessLevel = _calculateEffectiveUserAccessLevelFromPermission(this, context, this.userAccessLevel);
1426
+ const options = {
1427
+ value: {
1428
+ dataType: node_opcua_variant_1.DataType.Byte,
1429
+ statusCode: node_opcua_status_code_1.StatusCodes.Good,
1430
+ value: (0, node_opcua_data_model_1.convertAccessLevelFlagToByte)(effectiveUserAccessLevel)
1431
+ }
1432
+ };
1433
+ return new node_opcua_data_value_1.DataValue(options);
1434
+ }
1435
+ _readMinimumSamplingInterval() {
1436
+ // expect a Duration => Double
1437
+ const options = {};
1438
+ if (this.minimumSamplingInterval === undefined) {
1439
+ options.statusCode = node_opcua_status_code_1.StatusCodes.BadAttributeIdInvalid;
1440
+ }
1441
+ else {
1442
+ options.value = { dataType: node_opcua_variant_1.DataType.Double, value: this.minimumSamplingInterval };
1443
+ options.statusCode = node_opcua_status_code_1.StatusCodes.Good;
1444
+ }
1445
+ return new node_opcua_data_value_1.DataValue(options);
1446
+ }
1447
+ _readHistorizing() {
1448
+ (0, node_opcua_assert_1.assert)(typeof this.historizing === "boolean");
1449
+ const options = {
1450
+ statusCode: node_opcua_status_code_1.StatusCodes.Good,
1451
+ value: { dataType: node_opcua_variant_1.DataType.Boolean, value: !!this.historizing }
1452
+ };
1453
+ return new node_opcua_data_value_1.DataValue(options);
1454
+ }
1455
+ }
1456
+ exports.UAVariableImpl = UAVariableImpl;
1457
+ // tslint:disable:no-var-requires
1458
+ const thenify = require("thenify");
1459
+ UAVariableImpl.prototype.asyncRefresh = thenify.withCallback(UAVariableImpl.prototype.asyncRefresh);
1460
+ UAVariableImpl.prototype.writeValue = thenify.withCallback(UAVariableImpl.prototype.writeValue);
1461
+ UAVariableImpl.prototype.writeAttribute = thenify.withCallback(UAVariableImpl.prototype.writeAttribute);
1462
+ UAVariableImpl.prototype.historyRead = thenify.withCallback(UAVariableImpl.prototype.historyRead);
1463
+ UAVariableImpl.prototype.readValueAsync = thenify.withCallback(UAVariableImpl.prototype.readValueAsync);
1464
+ function check_valid_array(dataType, array) {
1465
+ if (Array.isArray(array)) {
1466
+ return true;
1467
+ }
1468
+ switch (dataType) {
1469
+ case node_opcua_variant_1.DataType.Double:
1470
+ return array instanceof Float64Array;
1471
+ case node_opcua_variant_1.DataType.Float:
1472
+ return array instanceof Float32Array;
1473
+ case node_opcua_variant_1.DataType.Int32:
1474
+ return array instanceof Int32Array;
1475
+ case node_opcua_variant_1.DataType.Int16:
1476
+ return array instanceof Int16Array;
1477
+ case node_opcua_variant_1.DataType.SByte:
1478
+ return array instanceof Int8Array;
1479
+ case node_opcua_variant_1.DataType.UInt32:
1480
+ return array instanceof Uint32Array;
1481
+ case node_opcua_variant_1.DataType.UInt16:
1482
+ return array instanceof Uint16Array;
1483
+ case node_opcua_variant_1.DataType.Byte:
1484
+ return array instanceof Uint8Array || array instanceof Buffer;
1485
+ }
1486
+ return false;
1487
+ }
1488
+ function _apply_default_timestamps(dataValue) {
1489
+ const now = (0, node_opcua_date_time_1.getCurrentClock)();
1490
+ (0, node_opcua_assert_1.assert)(dataValue instanceof node_opcua_data_value_1.DataValue);
1491
+ if (!dataValue.sourceTimestamp) {
1492
+ dataValue.sourceTimestamp = now.timestamp;
1493
+ dataValue.sourcePicoseconds = now.picoseconds;
1494
+ }
1495
+ if (!dataValue.serverTimestamp) {
1496
+ dataValue.serverTimestamp = now.timestamp;
1497
+ dataValue.serverPicoseconds = now.picoseconds;
1498
+ }
1499
+ }
1500
+ function unsetFlag(flags, mask) {
1501
+ return flags & ~mask;
1502
+ }
1503
+ function setFlag(flags, mask) {
1504
+ return flags | mask;
1505
+ }
1506
+ function _calculateEffectiveUserAccessLevelFromPermission(node, context, userAccessLevel) {
1507
+ function __adjustFlag(permissionType, access, userAccessLevel1) {
1508
+ if ((node.accessLevel & access) === 0 || (userAccessLevel1 & access) === 0) {
1509
+ userAccessLevel1 = unsetFlag(userAccessLevel1, access);
1510
+ }
1511
+ else {
1512
+ if (!context.checkPermission(node, permissionType)) {
1513
+ userAccessLevel1 = unsetFlag(userAccessLevel1, access);
1514
+ }
1515
+ }
1516
+ return userAccessLevel1;
1517
+ }
1518
+ userAccessLevel = node.userAccessLevel === undefined ? node.accessLevel : node.userAccessLevel & node.accessLevel;
1519
+ if (context.checkPermission) {
1520
+ (0, node_opcua_assert_1.assert)(context.checkPermission instanceof Function);
1521
+ userAccessLevel = __adjustFlag(node_opcua_types_1.PermissionType.Read, node_opcua_data_model_1.AccessLevelFlag.CurrentRead, userAccessLevel);
1522
+ userAccessLevel = __adjustFlag(node_opcua_types_1.PermissionType.Write, node_opcua_data_model_1.AccessLevelFlag.CurrentWrite, userAccessLevel);
1523
+ userAccessLevel = __adjustFlag(node_opcua_types_1.PermissionType.Write, node_opcua_data_model_1.AccessLevelFlag.StatusWrite, userAccessLevel);
1524
+ userAccessLevel = __adjustFlag(node_opcua_types_1.PermissionType.Write, node_opcua_data_model_1.AccessLevelFlag.TimestampWrite, userAccessLevel);
1525
+ userAccessLevel = __adjustFlag(node_opcua_types_1.PermissionType.ReadHistory, node_opcua_data_model_1.AccessLevelFlag.HistoryRead, userAccessLevel);
1526
+ userAccessLevel = __adjustFlag(node_opcua_types_1.PermissionType.DeleteHistory, node_opcua_data_model_1.AccessLevelFlag.HistoryWrite, userAccessLevel);
1527
+ return userAccessLevel;
1528
+ }
1529
+ else {
1530
+ return userAccessLevel;
1531
+ }
1532
+ }
1533
+ function adjustVariant2(variant) {
1534
+ // convert Variant( Scalar|ByteString) => Variant(Array|ByteArray)
1535
+ const addressSpace = this.addressSpace;
1536
+ const basicType = this.getBasicDataType();
1537
+ variant = (0, node_opcua_variant_1.adjustVariant)(variant, this.valueRank, basicType);
1538
+ return variant;
1539
+ }
1540
+ function _not_writable_timestamped_set_func(dataValue, callback) {
1541
+ (0, node_opcua_assert_1.assert)(dataValue instanceof node_opcua_data_value_1.DataValue);
1542
+ callback(null, node_opcua_status_code_1.StatusCodes.BadNotWritable, null);
1543
+ }
1544
+ function _default_writable_timestamped_set_func(dataValue, callback) {
1545
+ (0, node_opcua_assert_1.assert)(dataValue instanceof node_opcua_data_value_1.DataValue);
1546
+ callback(null, node_opcua_status_code_1.StatusCodes.Good, dataValue);
1547
+ }
1548
+ function turn_sync_to_async(f, numberOfArgs) {
1549
+ if (f.length <= numberOfArgs) {
1550
+ return function (data, callback) {
1551
+ const r = f.call(this, data);
1552
+ setImmediate(() => {
1553
+ return callback(null, r);
1554
+ });
1555
+ };
1556
+ }
1557
+ else {
1558
+ (0, node_opcua_assert_1.assert)(f.length === numberOfArgs + 1);
1559
+ return f;
1560
+ }
1561
+ }
1562
+ const _default_minimumSamplingInterval = 1000;
1563
+ function coerceDataValue(dataValue) {
1564
+ if (dataValue instanceof node_opcua_data_value_1.DataValue) {
1565
+ return dataValue;
1566
+ }
1567
+ return new node_opcua_data_value_1.DataValue(dataValue);
1568
+ }
1569
+ // variation #3 :
1570
+ function _Variable_bind_with_async_refresh(options) {
1571
+ /* jshint validthis: true */
1572
+ (0, node_opcua_assert_1.assert)(this instanceof UAVariableImpl);
1573
+ (0, node_opcua_assert_1.assert)(typeof options.refreshFunc === "function");
1574
+ (0, node_opcua_assert_1.assert)(!options.get, "a getter shall not be specified when refreshFunc is set");
1575
+ (0, node_opcua_assert_1.assert)(!options.timestamped_get, "a getter shall not be specified when refreshFunc is set");
1576
+ (0, node_opcua_assert_1.assert)(!this.refreshFunc);
1577
+ this.refreshFunc = options.refreshFunc;
1578
+ // TO DO : REVISIT THIS ASSUMPTION
1579
+ if (false && this.minimumSamplingInterval === 0) {
1580
+ // when a getter /timestamped_getter or async_getter is provided
1581
+ // samplingInterval cannot be 0, as the item value must be scanned to be updated.
1582
+ this.minimumSamplingInterval = _default_minimumSamplingInterval; // MonitoredItem.minimumSamplingInterval;
1583
+ debugLog("adapting minimumSamplingInterval on " + this.browseName.toString() + " to " + this.minimumSamplingInterval);
1584
+ }
1585
+ }
1586
+ // variation 2
1587
+ function _Variable_bind_with_timestamped_get(options) {
1588
+ /* jshint validthis: true */
1589
+ (0, node_opcua_assert_1.assert)(this instanceof UAVariableImpl);
1590
+ (0, node_opcua_assert_1.assert)(typeof options.timestamped_get === "function");
1591
+ (0, node_opcua_assert_1.assert)(!options.get, "should not specify 'get' when 'timestamped_get' exists ");
1592
+ (0, node_opcua_assert_1.assert)(!this._timestamped_get_func);
1593
+ const async_refresh_func = (callback) => {
1594
+ Promise.resolve(this._timestamped_get_func.call(this))
1595
+ .then((dataValue) => callback(null, dataValue))
1596
+ .catch((err) => {
1597
+ errorLog("asyncRefresh error: Variable is ", this.nodeId.toString(), this.browseName.toString());
1598
+ callback(err);
1599
+ });
1600
+ };
1601
+ const pThis = this;
1602
+ if (options.timestamped_get.length === 0) {
1603
+ const timestamped_get = options.timestamped_get;
1604
+ // sync version | Promise version
1605
+ this._timestamped_get_func = timestamped_get;
1606
+ const dataValue_verify = timestamped_get.call(pThis);
1607
+ // dataValue_verify should be a DataValue or a Promise
1608
+ /* istanbul ignore next */
1609
+ if (!(dataValue_verify instanceof node_opcua_data_value_1.DataValue) && typeof dataValue_verify.then !== "function") {
1610
+ errorLog(chalk.red(" Bind variable error: "), " the timestamped_get function must return a DataValue or a Promise<DataValue>" +
1611
+ "\n value_check.constructor.name ", dataValue_verify ? dataValue_verify.constructor.name : "null");
1612
+ throw new Error(" Bind variable error: " + " the timestamped_get function must return a DataValue");
1613
+ }
1614
+ _Variable_bind_with_async_refresh.call(this, { refreshFunc: async_refresh_func });
1615
+ }
1616
+ else if (options.timestamped_get.length === 1) {
1617
+ _Variable_bind_with_async_refresh.call(this, { refreshFunc: options.timestamped_get });
1618
+ }
1619
+ else {
1620
+ errorLog("timestamped_get has a invalid number of argument , should be 0 or 1 ");
1621
+ throw new Error("timestamped_get has a invalid number of argument , should be 0 or 1 ");
1622
+ }
1623
+ }
1624
+ // variation 1
1625
+ function _Variable_bind_with_simple_get(options) {
1626
+ /* jshint validthis: true */
1627
+ (0, node_opcua_assert_1.assert)(this instanceof UAVariableImpl);
1628
+ (0, node_opcua_assert_1.assert)(typeof options.get === "function", "should specify get function");
1629
+ (0, node_opcua_assert_1.assert)(options.get.length === 0, "get function should not have arguments");
1630
+ (0, node_opcua_assert_1.assert)(!options.timestamped_get, "should not specify a timestamped_get function when get is specified");
1631
+ (0, node_opcua_assert_1.assert)(!this._timestamped_get_func);
1632
+ (0, node_opcua_assert_1.assert)(!this._get_func);
1633
+ this._get_func = options.get;
1634
+ const timestamped_get_func_from__Variable_bind_with_simple_get = () => {
1635
+ const value = this._get_func();
1636
+ /* istanbul ignore next */
1637
+ if (!is_Variant_or_StatusCode(value)) {
1638
+ errorLog(chalk.red(" Bind variable error: "), " : the getter must return a Variant or a StatusCode" + "\nvalue_check.constructor.name ", value ? value.constructor.name : "null");
1639
+ throw new Error(" bindVariable : the value getter function returns a invalid result ( expecting a Variant or a StatusCode !!!");
1640
+ }
1641
+ if (is_StatusCode(value)) {
1642
+ return new node_opcua_data_value_1.DataValue({ statusCode: value });
1643
+ }
1644
+ else {
1645
+ if (!this.$dataValue || !this.$dataValue.statusCode.isGoodish() || !(0, node_opcua_variant_1.sameVariant)(this.$dataValue.value, value)) {
1646
+ this._inner_replace_dataValue(new node_opcua_data_value_1.DataValue({ value }));
1647
+ }
1648
+ return this.$dataValue;
1649
+ }
1650
+ };
1651
+ _Variable_bind_with_timestamped_get.call(this, {
1652
+ get: undefined,
1653
+ timestamped_get: timestamped_get_func_from__Variable_bind_with_simple_get
1654
+ });
1655
+ }
1656
+ function _Variable_bind_with_simple_set(options) {
1657
+ (0, node_opcua_assert_1.assert)(this instanceof UAVariableImpl);
1658
+ (0, node_opcua_assert_1.assert)(typeof options.set === "function", "should specify set function");
1659
+ (0, node_opcua_assert_1.assert)(!options.timestamped_set, "should not specify a timestamped_set function");
1660
+ (0, node_opcua_assert_1.assert)(!this._timestamped_set_func);
1661
+ (0, node_opcua_assert_1.assert)(!this._set_func);
1662
+ this._set_func = turn_sync_to_async(options.set, 1);
1663
+ (0, node_opcua_assert_1.assert)(this._set_func.length === 2, " set function must have 2 arguments ( variant, callback)");
1664
+ this._timestamped_set_func = (timestamped_value, callback) => {
1665
+ (0, node_opcua_assert_1.assert)(timestamped_value instanceof node_opcua_data_value_1.DataValue);
1666
+ this._set_func(timestamped_value.value, (err, statusCode) => {
1667
+ // istanbul ignore next
1668
+ if (!err && !statusCode) {
1669
+ errorLog(chalk.red("UAVariable Binding Error _set_func must return a StatusCode, check the bindVariable parameters"));
1670
+ errorLog(chalk.yellow("StatusCode.Good is assumed"));
1671
+ return callback(err, node_opcua_status_code_1.StatusCodes.Good, timestamped_value);
1672
+ }
1673
+ callback(err, statusCode, timestamped_value);
1674
+ });
1675
+ };
1676
+ }
1677
+ function _Variable_bind_with_timestamped_set(options) {
1678
+ (0, node_opcua_assert_1.assert)(options.timestamped_set.length === 2 || options.timestamped_set.length === 1, "timestamped_set must have 2 parameters timestamped_set: function(dataValue,callback){} or one paramater timestamped_set: function(dataValue): Promise<StatusCode>{}");
1679
+ (0, node_opcua_assert_1.assert)(!options.set, "should not specify set when timestamped_set_func exists ");
1680
+ this._timestamped_set_func = (0, multiform_func_1.convertToCallbackFunction1)(options.timestamped_set);
1681
+ }
1682
+ function bind_setter(options) {
1683
+ if (typeof options.set === "function") {
1684
+ // variation 1
1685
+ _Variable_bind_with_simple_set.call(this, options);
1686
+ }
1687
+ else if (typeof options.timestamped_set === "function") {
1688
+ // variation 2
1689
+ (0, node_opcua_assert_1.assert)(typeof options.timestamped_get === "function", "timestamped_set must be used with timestamped_get ");
1690
+ _Variable_bind_with_timestamped_set.call(this, {
1691
+ set: undefined,
1692
+ timestamped_set: options.timestamped_set
1693
+ });
1694
+ }
1695
+ else if (typeof options.timestamped_get === "function") {
1696
+ // timestamped_get is specified but timestamped_set is not
1697
+ // => Value is read-only
1698
+ _Variable_bind_with_timestamped_set.call(this, {
1699
+ set: undefined,
1700
+ timestamped_set: _not_writable_timestamped_set_func
1701
+ });
1702
+ }
1703
+ else {
1704
+ _Variable_bind_with_timestamped_set.call(this, {
1705
+ set: undefined,
1706
+ timestamped_set: _default_writable_timestamped_set_func
1707
+ });
1708
+ }
1709
+ }
1710
+ function bind_getter(options) {
1711
+ if (typeof options.get === "function") {
1712
+ // variation 1
1713
+ _Variable_bind_with_simple_get.call(this, options);
1714
+ }
1715
+ else if (typeof options.timestamped_get === "function") {
1716
+ // variation 2
1717
+ _Variable_bind_with_timestamped_get.call(this, {
1718
+ get: undefined,
1719
+ timestamped_get: options.timestamped_get
1720
+ });
1721
+ }
1722
+ else if (typeof options.refreshFunc === "function") {
1723
+ // variation 3
1724
+ _Variable_bind_with_async_refresh.call(this, options);
1725
+ }
1726
+ else {
1727
+ (0, node_opcua_assert_1.assert)(!Object.prototype.hasOwnProperty.call(options, "set"), "getter is missing : a getter must be provided if a setter is provided");
1728
+ // xx bind_variant.call(this,options);
1729
+ if (options.dataType !== undefined) {
1730
+ // if (options.dataType !== DataType.ExtensionObject) {
1731
+ this.setValueFromSource(options);
1732
+ // }
1733
+ }
1734
+ }
1735
+ }
1736
+ class UAVariableImplT extends UAVariableImpl {
1737
+ }
1738
+ exports.UAVariableImplT = UAVariableImplT;
1739
1739
  //# sourceMappingURL=ua_variable_impl.js.map