@zwave-js/cc 13.10.1 → 14.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (293) hide show
  1. package/build/cc/AlarmSensorCC.d.ts +31 -20
  2. package/build/cc/AlarmSensorCC.d.ts.map +1 -1
  3. package/build/cc/AlarmSensorCC.js +106 -87
  4. package/build/cc/AlarmSensorCC.js.map +1 -1
  5. package/build/cc/AssociationCC.d.ts +38 -32
  6. package/build/cc/AssociationCC.d.ts.map +1 -1
  7. package/build/cc/AssociationCC.js +193 -176
  8. package/build/cc/AssociationCC.js.map +1 -1
  9. package/build/cc/AssociationGroupInfoCC.d.ts +42 -36
  10. package/build/cc/AssociationGroupInfoCC.d.ts.map +1 -1
  11. package/build/cc/AssociationGroupInfoCC.js +218 -200
  12. package/build/cc/AssociationGroupInfoCC.js.map +1 -1
  13. package/build/cc/BarrierOperatorCC.d.ts +41 -24
  14. package/build/cc/BarrierOperatorCC.d.ts.map +1 -1
  15. package/build/cc/BarrierOperatorCC.js +143 -109
  16. package/build/cc/BarrierOperatorCC.js.map +1 -1
  17. package/build/cc/BasicCC.d.ts +22 -23
  18. package/build/cc/BasicCC.d.ts.map +1 -1
  19. package/build/cc/BasicCC.js +83 -77
  20. package/build/cc/BasicCC.js.map +1 -1
  21. package/build/cc/BatteryCC.d.ts +22 -14
  22. package/build/cc/BatteryCC.d.ts.map +1 -1
  23. package/build/cc/BatteryCC.js +116 -87
  24. package/build/cc/BatteryCC.js.map +1 -1
  25. package/build/cc/BinarySensorCC.d.ts +22 -19
  26. package/build/cc/BinarySensorCC.d.ts.map +1 -1
  27. package/build/cc/BinarySensorCC.js +103 -93
  28. package/build/cc/BinarySensorCC.js.map +1 -1
  29. package/build/cc/BinarySwitchCC.d.ts +20 -20
  30. package/build/cc/BinarySwitchCC.d.ts.map +1 -1
  31. package/build/cc/BinarySwitchCC.js +71 -59
  32. package/build/cc/BinarySwitchCC.js.map +1 -1
  33. package/build/cc/CRC16CC.d.ts +9 -9
  34. package/build/cc/CRC16CC.d.ts.map +1 -1
  35. package/build/cc/CRC16CC.js +36 -36
  36. package/build/cc/CRC16CC.js.map +1 -1
  37. package/build/cc/CentralSceneCC.d.ts +34 -16
  38. package/build/cc/CentralSceneCC.d.ts.map +1 -1
  39. package/build/cc/CentralSceneCC.js +116 -79
  40. package/build/cc/CentralSceneCC.js.map +1 -1
  41. package/build/cc/ClimateControlScheduleCC.d.ts +38 -21
  42. package/build/cc/ClimateControlScheduleCC.d.ts.map +1 -1
  43. package/build/cc/ClimateControlScheduleCC.js +113 -81
  44. package/build/cc/ClimateControlScheduleCC.js.map +1 -1
  45. package/build/cc/ClockCC.d.ts +18 -11
  46. package/build/cc/ClockCC.d.ts.map +1 -1
  47. package/build/cc/ClockCC.js +57 -43
  48. package/build/cc/ClockCC.js.map +1 -1
  49. package/build/cc/ColorSwitchCC.d.ts +37 -33
  50. package/build/cc/ColorSwitchCC.d.ts.map +1 -1
  51. package/build/cc/ColorSwitchCC.js +216 -189
  52. package/build/cc/ColorSwitchCC.js.map +1 -1
  53. package/build/cc/ConfigurationCC.d.ts +89 -74
  54. package/build/cc/ConfigurationCC.d.ts.map +1 -1
  55. package/build/cc/ConfigurationCC.js +541 -485
  56. package/build/cc/ConfigurationCC.js.map +1 -1
  57. package/build/cc/DeviceResetLocallyCC.d.ts +3 -3
  58. package/build/cc/DeviceResetLocallyCC.d.ts.map +1 -1
  59. package/build/cc/DeviceResetLocallyCC.js +14 -14
  60. package/build/cc/DeviceResetLocallyCC.js.map +1 -1
  61. package/build/cc/DoorLockCC.d.ts +66 -27
  62. package/build/cc/DoorLockCC.d.ts.map +1 -1
  63. package/build/cc/DoorLockCC.js +288 -197
  64. package/build/cc/DoorLockCC.js.map +1 -1
  65. package/build/cc/DoorLockLoggingCC.d.ts +23 -13
  66. package/build/cc/DoorLockLoggingCC.d.ts.map +1 -1
  67. package/build/cc/DoorLockLoggingCC.js +81 -63
  68. package/build/cc/DoorLockLoggingCC.js.map +1 -1
  69. package/build/cc/EnergyProductionCC.d.ts +16 -14
  70. package/build/cc/EnergyProductionCC.d.ts.map +1 -1
  71. package/build/cc/EnergyProductionCC.js +58 -52
  72. package/build/cc/EnergyProductionCC.js.map +1 -1
  73. package/build/cc/EntryControlCC.d.ts +44 -18
  74. package/build/cc/EntryControlCC.d.ts.map +1 -1
  75. package/build/cc/EntryControlCC.js +163 -112
  76. package/build/cc/EntryControlCC.js.map +1 -1
  77. package/build/cc/FirmwareUpdateMetaDataCC.d.ts +69 -34
  78. package/build/cc/FirmwareUpdateMetaDataCC.d.ts.map +1 -1
  79. package/build/cc/FirmwareUpdateMetaDataCC.js +311 -245
  80. package/build/cc/FirmwareUpdateMetaDataCC.js.map +1 -1
  81. package/build/cc/HumidityControlModeCC.d.ts +24 -16
  82. package/build/cc/HumidityControlModeCC.d.ts.map +1 -1
  83. package/build/cc/HumidityControlModeCC.js +80 -65
  84. package/build/cc/HumidityControlModeCC.js.map +1 -1
  85. package/build/cc/HumidityControlOperatingStateCC.d.ts +11 -7
  86. package/build/cc/HumidityControlOperatingStateCC.d.ts.map +1 -1
  87. package/build/cc/HumidityControlOperatingStateCC.js +31 -22
  88. package/build/cc/HumidityControlOperatingStateCC.js.map +1 -1
  89. package/build/cc/HumidityControlSetpointCC.d.ts +68 -49
  90. package/build/cc/HumidityControlSetpointCC.d.ts.map +1 -1
  91. package/build/cc/HumidityControlSetpointCC.js +203 -181
  92. package/build/cc/HumidityControlSetpointCC.js.map +1 -1
  93. package/build/cc/InclusionControllerCC.d.ts +13 -11
  94. package/build/cc/InclusionControllerCC.d.ts.map +1 -1
  95. package/build/cc/InclusionControllerCC.js +49 -42
  96. package/build/cc/InclusionControllerCC.js.map +1 -1
  97. package/build/cc/IndicatorCC.d.ts +46 -39
  98. package/build/cc/IndicatorCC.d.ts.map +1 -1
  99. package/build/cc/IndicatorCC.js +298 -277
  100. package/build/cc/IndicatorCC.js.map +1 -1
  101. package/build/cc/IrrigationCC.d.ts +127 -57
  102. package/build/cc/IrrigationCC.d.ts.map +1 -1
  103. package/build/cc/IrrigationCC.js +496 -352
  104. package/build/cc/IrrigationCC.js.map +1 -1
  105. package/build/cc/LanguageCC.d.ts +17 -11
  106. package/build/cc/LanguageCC.d.ts.map +1 -1
  107. package/build/cc/LanguageCC.js +54 -44
  108. package/build/cc/LanguageCC.js.map +1 -1
  109. package/build/cc/LockCC.d.ts +16 -11
  110. package/build/cc/LockCC.d.ts.map +1 -1
  111. package/build/cc/LockCC.js +48 -38
  112. package/build/cc/LockCC.js.map +1 -1
  113. package/build/cc/ManufacturerProprietaryCC.d.ts +12 -11
  114. package/build/cc/ManufacturerProprietaryCC.d.ts.map +1 -1
  115. package/build/cc/ManufacturerProprietaryCC.js +45 -50
  116. package/build/cc/ManufacturerProprietaryCC.js.map +1 -1
  117. package/build/cc/ManufacturerSpecificCC.d.ts +20 -13
  118. package/build/cc/ManufacturerSpecificCC.d.ts.map +1 -1
  119. package/build/cc/ManufacturerSpecificCC.js +79 -63
  120. package/build/cc/ManufacturerSpecificCC.js.map +1 -1
  121. package/build/cc/MeterCC.d.ts +30 -26
  122. package/build/cc/MeterCC.d.ts.map +1 -1
  123. package/build/cc/MeterCC.js +236 -204
  124. package/build/cc/MeterCC.js.map +1 -1
  125. package/build/cc/MultiChannelAssociationCC.d.ts +31 -26
  126. package/build/cc/MultiChannelAssociationCC.d.ts.map +1 -1
  127. package/build/cc/MultiChannelAssociationCC.js +177 -168
  128. package/build/cc/MultiChannelAssociationCC.js.map +1 -1
  129. package/build/cc/MultiChannelCC.d.ts +70 -49
  130. package/build/cc/MultiChannelCC.d.ts.map +1 -1
  131. package/build/cc/MultiChannelCC.js +377 -318
  132. package/build/cc/MultiChannelCC.js.map +1 -1
  133. package/build/cc/MultiCommandCC.d.ts +9 -9
  134. package/build/cc/MultiCommandCC.d.ts.map +1 -1
  135. package/build/cc/MultiCommandCC.js +35 -36
  136. package/build/cc/MultiCommandCC.js.map +1 -1
  137. package/build/cc/MultilevelSensorCC.d.ts +38 -33
  138. package/build/cc/MultilevelSensorCC.d.ts.map +1 -1
  139. package/build/cc/MultilevelSensorCC.js +172 -152
  140. package/build/cc/MultilevelSensorCC.js.map +1 -1
  141. package/build/cc/MultilevelSwitchCC.d.ts +29 -25
  142. package/build/cc/MultilevelSwitchCC.d.ts.map +1 -1
  143. package/build/cc/MultilevelSwitchCC.js +147 -127
  144. package/build/cc/MultilevelSwitchCC.js.map +1 -1
  145. package/build/cc/NoOperationCC.d.ts +0 -8
  146. package/build/cc/NoOperationCC.d.ts.map +1 -1
  147. package/build/cc/NoOperationCC.js +2 -11
  148. package/build/cc/NoOperationCC.js.map +1 -1
  149. package/build/cc/NodeNamingCC.d.ts +27 -17
  150. package/build/cc/NodeNamingCC.d.ts.map +1 -1
  151. package/build/cc/NodeNamingCC.js +86 -69
  152. package/build/cc/NodeNamingCC.js.map +1 -1
  153. package/build/cc/NotificationCC.d.ts +46 -43
  154. package/build/cc/NotificationCC.d.ts.map +1 -1
  155. package/build/cc/NotificationCC.js +317 -303
  156. package/build/cc/NotificationCC.js.map +1 -1
  157. package/build/cc/PowerlevelCC.d.ts +22 -18
  158. package/build/cc/PowerlevelCC.d.ts.map +1 -1
  159. package/build/cc/PowerlevelCC.js +125 -95
  160. package/build/cc/PowerlevelCC.js.map +1 -1
  161. package/build/cc/ProtectionCC.d.ts +49 -26
  162. package/build/cc/ProtectionCC.d.ts.map +1 -1
  163. package/build/cc/ProtectionCC.js +172 -126
  164. package/build/cc/ProtectionCC.js.map +1 -1
  165. package/build/cc/SceneActivationCC.d.ts +8 -7
  166. package/build/cc/SceneActivationCC.d.ts.map +1 -1
  167. package/build/cc/SceneActivationCC.js +28 -23
  168. package/build/cc/SceneActivationCC.js.map +1 -1
  169. package/build/cc/SceneActuatorConfigurationCC.d.ts +23 -15
  170. package/build/cc/SceneActuatorConfigurationCC.d.ts.map +1 -1
  171. package/build/cc/SceneActuatorConfigurationCC.js +79 -62
  172. package/build/cc/SceneActuatorConfigurationCC.js.map +1 -1
  173. package/build/cc/SceneControllerConfigurationCC.d.ts +25 -17
  174. package/build/cc/SceneControllerConfigurationCC.d.ts.map +1 -1
  175. package/build/cc/SceneControllerConfigurationCC.js +92 -78
  176. package/build/cc/SceneControllerConfigurationCC.js.map +1 -1
  177. package/build/cc/ScheduleEntryLockCC.d.ts +86 -72
  178. package/build/cc/ScheduleEntryLockCC.d.ts.map +1 -1
  179. package/build/cc/ScheduleEntryLockCC.js +607 -455
  180. package/build/cc/ScheduleEntryLockCC.js.map +1 -1
  181. package/build/cc/Security2CC.d.ts +78 -87
  182. package/build/cc/Security2CC.d.ts.map +1 -1
  183. package/build/cc/Security2CC.js +798 -765
  184. package/build/cc/Security2CC.js.map +1 -1
  185. package/build/cc/SecurityCC.d.ts +47 -42
  186. package/build/cc/SecurityCC.d.ts.map +1 -1
  187. package/build/cc/SecurityCC.js +240 -218
  188. package/build/cc/SecurityCC.js.map +1 -1
  189. package/build/cc/SoundSwitchCC.d.ts +36 -29
  190. package/build/cc/SoundSwitchCC.d.ts.map +1 -1
  191. package/build/cc/SoundSwitchCC.js +180 -157
  192. package/build/cc/SoundSwitchCC.js.map +1 -1
  193. package/build/cc/SupervisionCC.d.ts +17 -14
  194. package/build/cc/SupervisionCC.d.ts.map +1 -1
  195. package/build/cc/SupervisionCC.js +86 -66
  196. package/build/cc/SupervisionCC.js.map +1 -1
  197. package/build/cc/ThermostatFanModeCC.d.ts +25 -15
  198. package/build/cc/ThermostatFanModeCC.d.ts.map +1 -1
  199. package/build/cc/ThermostatFanModeCC.js +79 -60
  200. package/build/cc/ThermostatFanModeCC.js.map +1 -1
  201. package/build/cc/ThermostatFanStateCC.d.ts +11 -7
  202. package/build/cc/ThermostatFanStateCC.d.ts.map +1 -1
  203. package/build/cc/ThermostatFanStateCC.js +31 -22
  204. package/build/cc/ThermostatFanStateCC.js.map +1 -1
  205. package/build/cc/ThermostatModeCC.d.ts +24 -21
  206. package/build/cc/ThermostatModeCC.d.ts.map +1 -1
  207. package/build/cc/ThermostatModeCC.js +106 -90
  208. package/build/cc/ThermostatModeCC.js.map +1 -1
  209. package/build/cc/ThermostatOperatingStateCC.d.ts +11 -7
  210. package/build/cc/ThermostatOperatingStateCC.d.ts.map +1 -1
  211. package/build/cc/ThermostatOperatingStateCC.js +31 -22
  212. package/build/cc/ThermostatOperatingStateCC.js.map +1 -1
  213. package/build/cc/ThermostatSetbackCC.d.ts +14 -13
  214. package/build/cc/ThermostatSetbackCC.d.ts.map +1 -1
  215. package/build/cc/ThermostatSetbackCC.js +64 -57
  216. package/build/cc/ThermostatSetbackCC.js.map +1 -1
  217. package/build/cc/ThermostatSetpointCC.d.ts +38 -57
  218. package/build/cc/ThermostatSetpointCC.d.ts.map +1 -1
  219. package/build/cc/ThermostatSetpointCC.js +200 -264
  220. package/build/cc/ThermostatSetpointCC.js.map +1 -1
  221. package/build/cc/TimeCC.d.ts +24 -20
  222. package/build/cc/TimeCC.d.ts.map +1 -1
  223. package/build/cc/TimeCC.js +119 -108
  224. package/build/cc/TimeCC.js.map +1 -1
  225. package/build/cc/TimeParametersCC.d.ts +18 -14
  226. package/build/cc/TimeParametersCC.d.ts.map +1 -1
  227. package/build/cc/TimeParametersCC.js +77 -69
  228. package/build/cc/TimeParametersCC.js.map +1 -1
  229. package/build/cc/TransportServiceCC.d.ts +29 -32
  230. package/build/cc/TransportServiceCC.d.ts.map +1 -1
  231. package/build/cc/TransportServiceCC.js +159 -161
  232. package/build/cc/TransportServiceCC.js.map +1 -1
  233. package/build/cc/UserCodeCC.d.ts +83 -66
  234. package/build/cc/UserCodeCC.d.ts.map +1 -1
  235. package/build/cc/UserCodeCC.js +449 -402
  236. package/build/cc/UserCodeCC.js.map +1 -1
  237. package/build/cc/VersionCC.d.ts +36 -20
  238. package/build/cc/VersionCC.d.ts.map +1 -1
  239. package/build/cc/VersionCC.js +190 -149
  240. package/build/cc/VersionCC.js.map +1 -1
  241. package/build/cc/WakeUpCC.d.ts +27 -13
  242. package/build/cc/WakeUpCC.d.ts.map +1 -1
  243. package/build/cc/WakeUpCC.js +105 -77
  244. package/build/cc/WakeUpCC.js.map +1 -1
  245. package/build/cc/WindowCoveringCC.d.ts +39 -27
  246. package/build/cc/WindowCoveringCC.d.ts.map +1 -1
  247. package/build/cc/WindowCoveringCC.js +169 -137
  248. package/build/cc/WindowCoveringCC.js.map +1 -1
  249. package/build/cc/ZWavePlusCC.d.ts +8 -7
  250. package/build/cc/ZWavePlusCC.d.ts.map +1 -1
  251. package/build/cc/ZWavePlusCC.js +44 -37
  252. package/build/cc/ZWavePlusCC.js.map +1 -1
  253. package/build/cc/ZWaveProtocolCC.d.ts +111 -84
  254. package/build/cc/ZWaveProtocolCC.d.ts.map +1 -1
  255. package/build/cc/ZWaveProtocolCC.js +583 -508
  256. package/build/cc/ZWaveProtocolCC.js.map +1 -1
  257. package/build/cc/index.d.ts +37 -34
  258. package/build/cc/index.d.ts.map +1 -1
  259. package/build/cc/index.js +6 -7
  260. package/build/cc/index.js.map +1 -1
  261. package/build/cc/manufacturerProprietary/FibaroCC.d.ts +29 -24
  262. package/build/cc/manufacturerProprietary/FibaroCC.d.ts.map +1 -1
  263. package/build/cc/manufacturerProprietary/FibaroCC.js +109 -112
  264. package/build/cc/manufacturerProprietary/FibaroCC.js.map +1 -1
  265. package/build/index.d.ts +0 -1
  266. package/build/index.d.ts.map +1 -1
  267. package/build/index.js +0 -1
  268. package/build/index.js.map +1 -1
  269. package/build/lib/API.d.ts +21 -18
  270. package/build/lib/API.d.ts.map +1 -1
  271. package/build/lib/API.js +25 -49
  272. package/build/lib/API.js.map +1 -1
  273. package/build/lib/CommandClass.d.ts +51 -89
  274. package/build/lib/CommandClass.d.ts.map +1 -1
  275. package/build/lib/CommandClass.js +177 -249
  276. package/build/lib/CommandClass.js.map +1 -1
  277. package/build/lib/EncapsulatingCommandClass.d.ts +1 -15
  278. package/build/lib/EncapsulatingCommandClass.d.ts.map +1 -1
  279. package/build/lib/EncapsulatingCommandClass.js.map +1 -1
  280. package/build/lib/ICommandClassContainer.d.ts +1 -8
  281. package/build/lib/ICommandClassContainer.d.ts.map +1 -1
  282. package/build/lib/ICommandClassContainer.js +0 -8
  283. package/build/lib/ICommandClassContainer.js.map +1 -1
  284. package/build/lib/Values.d.ts +3 -3
  285. package/build/lib/Values.d.ts.map +1 -1
  286. package/build/lib/_Types.d.ts.map +1 -1
  287. package/build/lib/_Types.js +1 -0
  288. package/build/lib/_Types.js.map +1 -1
  289. package/build/lib/utils.d.ts +14 -13
  290. package/build/lib/utils.d.ts.map +1 -1
  291. package/build/lib/utils.js +94 -92
  292. package/build/lib/utils.js.map +1 -1
  293. package/package.json +4 -5
@@ -19,10 +19,10 @@ const AssociationGroupInfoCC_1 = require("../cc/AssociationGroupInfoCC");
19
19
  const MultiChannelAssociationCC_1 = require("../cc/MultiChannelAssociationCC");
20
20
  const API_1 = require("./API");
21
21
  const _Types_1 = require("./_Types");
22
- function getAssociations(applHost, endpoint) {
22
+ function getAssociations(ctx, endpoint) {
23
23
  const ret = new Map();
24
24
  if (endpoint.supportsCC(safe_1.CommandClasses.Association)) {
25
- const destinations = AssociationCC_1.AssociationCC.getAllDestinationsCached(applHost, endpoint);
25
+ const destinations = AssociationCC_1.AssociationCC.getAllDestinationsCached(ctx, endpoint);
26
26
  for (const [groupId, assocs] of destinations) {
27
27
  ret.set(groupId, assocs);
28
28
  }
@@ -32,7 +32,7 @@ function getAssociations(applHost, endpoint) {
32
32
  }
33
33
  // Merge the "normal" destinations with multi channel destinations
34
34
  if (endpoint.supportsCC(safe_1.CommandClasses["Multi Channel Association"])) {
35
- const destinations = MultiChannelAssociationCC_1.MultiChannelAssociationCC.getAllDestinationsCached(applHost, endpoint);
35
+ const destinations = MultiChannelAssociationCC_1.MultiChannelAssociationCC.getAllDestinationsCached(ctx, endpoint);
36
36
  for (const [groupId, assocs] of destinations) {
37
37
  if (ret.has(groupId)) {
38
38
  const normalAssociations = ret.get(groupId);
@@ -50,7 +50,7 @@ function getAssociations(applHost, endpoint) {
50
50
  }
51
51
  return ret;
52
52
  }
53
- function getAllAssociations(applHost, node) {
53
+ function getAllAssociations(ctx, node) {
54
54
  const ret = new safe_2.ObjectKeyMap();
55
55
  for (const endpoint of node.getAllEndpoints()) {
56
56
  const address = {
@@ -58,15 +58,15 @@ function getAllAssociations(applHost, node) {
58
58
  endpoint: endpoint.index,
59
59
  };
60
60
  if (endpoint.supportsCC(safe_1.CommandClasses.Association)) {
61
- ret.set(address, getAssociations(applHost, endpoint));
61
+ ret.set(address, getAssociations(ctx, endpoint));
62
62
  }
63
63
  }
64
64
  return ret;
65
65
  }
66
- function checkAssociation(applHost, endpoint, group, destination) {
66
+ function checkAssociation(ctx, endpoint, group, destination) {
67
67
  // Check that the target endpoint exists except when adding an association to the controller
68
- const targetNode = applHost.nodes.getOrThrow(destination.nodeId);
69
- const targetEndpoint = destination.nodeId === applHost.ownNodeId
68
+ const targetNode = ctx.getNodeOrThrow(destination.nodeId);
69
+ const targetEndpoint = destination.nodeId === ctx.ownNodeId
70
70
  ? targetNode
71
71
  : targetNode.getEndpointOrThrow(destination.endpoint ?? 0);
72
72
  if (!endpoint.supportsCC(safe_1.CommandClasses.Association)
@@ -79,12 +79,12 @@ function checkAssociation(applHost, endpoint, group, destination) {
79
79
  }
80
80
  else if ((0, safe_1.isLongRangeNodeId)(endpoint.nodeId)) {
81
81
  // Except the lifeline back to the host
82
- if (group !== 1 || destination.nodeId !== applHost.ownNodeId) {
82
+ if (group !== 1 || destination.nodeId !== ctx.ownNodeId) {
83
83
  return _Types_1.AssociationCheckResult.Forbidden_SourceIsLongRange;
84
84
  }
85
85
  }
86
86
  // The following checks don't apply to Lifeline associations
87
- if (destination.nodeId === applHost.ownNodeId) {
87
+ if (destination.nodeId === ctx.ownNodeId) {
88
88
  return _Types_1.AssociationCheckResult.OK;
89
89
  }
90
90
  // Disallow self-associations
@@ -97,7 +97,7 @@ function checkAssociation(applHost, endpoint, group, destination) {
97
97
  // For Association version 3 / MCA version 4:
98
98
  // A controlling node MUST NOT associate Node A to a Node B destination
99
99
  // if Node A was not granted Node B’s highest Security Class.
100
- const sourceNode = endpoint.getNodeUnsafe();
100
+ const sourceNode = ctx.getNode(endpoint.nodeId);
101
101
  let securityClassMustMatch;
102
102
  if (destination.endpoint == undefined) {
103
103
  // "normal" association
@@ -136,7 +136,7 @@ function checkAssociation(applHost, endpoint, group, destination) {
136
136
  if (!endpoint.supportsCC(safe_1.CommandClasses["Association Group Information"])) {
137
137
  return _Types_1.AssociationCheckResult.OK;
138
138
  }
139
- const groupCommandList = AssociationGroupInfoCC_1.AssociationGroupInfoCC.getIssuedCommandsCached(applHost, endpoint, group);
139
+ const groupCommandList = AssociationGroupInfoCC_1.AssociationGroupInfoCC.getIssuedCommandsCached(ctx, endpoint, group);
140
140
  if (!groupCommandList || !groupCommandList.size) {
141
141
  // We don't know which CCs this group controls, just allow it
142
142
  return _Types_1.AssociationCheckResult.OK;
@@ -156,7 +156,7 @@ function checkAssociation(applHost, endpoint, group, destination) {
156
156
  return _Types_1.AssociationCheckResult.Forbidden_NoSupportedCCs;
157
157
  }
158
158
  }
159
- function getAssociationGroups(applHost, endpoint) {
159
+ function getAssociationGroups(ctx, endpoint) {
160
160
  // Check whether we have multi channel support or not
161
161
  let assocInstance;
162
162
  let mcInstance;
@@ -169,11 +169,12 @@ function getAssociationGroups(applHost, endpoint) {
169
169
  if (endpoint.supportsCC(safe_1.CommandClasses["Multi Channel Association"])) {
170
170
  mcInstance = MultiChannelAssociationCC_1.MultiChannelAssociationCC;
171
171
  }
172
- const assocGroupCount = assocInstance.getGroupCountCached(applHost, endpoint) ?? 0;
173
- const mcGroupCount = mcInstance?.getGroupCountCached(applHost, endpoint)
172
+ const assocGroupCount = assocInstance.getGroupCountCached(ctx, endpoint)
173
+ ?? 0;
174
+ const mcGroupCount = mcInstance?.getGroupCountCached(ctx, endpoint)
174
175
  ?? 0;
175
176
  const groupCount = Math.max(assocGroupCount, mcGroupCount);
176
- const deviceConfig = applHost.getDeviceConfig?.(endpoint.nodeId);
177
+ const deviceConfig = ctx.getDeviceConfig?.(endpoint.nodeId);
177
178
  const ret = new Map();
178
179
  if (endpoint.supportsCC(safe_1.CommandClasses["Association Group Information"])) {
179
180
  // We can read all information we need from the AGI CC
@@ -184,19 +185,19 @@ function getAssociationGroups(applHost, endpoint) {
184
185
  ret.set(group, {
185
186
  maxNodes: (multiChannel
186
187
  ? mcInstance
187
- : assocInstance).getMaxNodesCached(applHost, endpoint, group) || 1,
188
+ : assocInstance).getMaxNodesCached(ctx, endpoint, group) || 1,
188
189
  // AGI implies Z-Wave+ where group 1 is the lifeline
189
190
  isLifeline: group === 1,
190
191
  label:
191
192
  // prefer the configured label if we have one
192
193
  assocConfig?.label
193
194
  // the ones reported by AGI are sometimes pretty bad
194
- ?? agiInstance.getGroupNameCached(applHost, endpoint, group)
195
+ ?? agiInstance.getGroupNameCached(ctx, endpoint, group)
195
196
  // but still better than "unnamed"
196
197
  ?? `Unnamed group ${group}`,
197
198
  multiChannel,
198
- profile: agiInstance.getGroupProfileCached(applHost, endpoint, group),
199
- issuedCommands: agiInstance.getIssuedCommandsCached(applHost, endpoint, group),
199
+ profile: agiInstance.getGroupProfileCached(ctx, endpoint, group),
200
+ issuedCommands: agiInstance.getIssuedCommandsCached(ctx, endpoint, group),
200
201
  });
201
202
  }
202
203
  }
@@ -208,7 +209,7 @@ function getAssociationGroups(applHost, endpoint) {
208
209
  ret.set(group, {
209
210
  maxNodes: (multiChannel
210
211
  ? mcInstance
211
- : assocInstance).getMaxNodesCached(applHost, endpoint, group)
212
+ : assocInstance).getMaxNodesCached(ctx, endpoint, group)
212
213
  || assocConfig?.maxNodes
213
214
  || 1,
214
215
  isLifeline: assocConfig?.isLifeline ?? group === 1,
@@ -219,16 +220,16 @@ function getAssociationGroups(applHost, endpoint) {
219
220
  }
220
221
  return ret;
221
222
  }
222
- function getAllAssociationGroups(applHost, node) {
223
+ function getAllAssociationGroups(ctx, node) {
223
224
  const ret = new Map();
224
225
  for (const endpoint of node.getAllEndpoints()) {
225
226
  if (endpoint.supportsCC(safe_1.CommandClasses.Association)) {
226
- ret.set(endpoint.index, getAssociationGroups(applHost, endpoint));
227
+ ret.set(endpoint.index, getAssociationGroups(ctx, endpoint));
227
228
  }
228
229
  }
229
230
  return ret;
230
231
  }
231
- async function addAssociations(applHost, endpoint, group, destinations) {
232
+ async function addAssociations(ctx, endpoint, group, destinations) {
232
233
  const nodeAndEndpointString = `${endpoint.nodeId}${endpoint.index > 0 ? `, endpoint ${endpoint.index}` : ""}`;
233
234
  // Check whether we should add any associations the device does not have support for
234
235
  let assocInstance;
@@ -259,14 +260,15 @@ async function addAssociations(applHost, endpoint, group, destinations) {
259
260
  checkResult: _Types_1.AssociationCheckResult.Forbidden_SelfAssociation,
260
261
  })));
261
262
  }
262
- const assocGroupCount = assocInstance?.getGroupCountCached(applHost, endpoint) ?? 0;
263
- const mcGroupCount = mcInstance?.getGroupCountCached(applHost, endpoint)
263
+ const assocGroupCount = assocInstance?.getGroupCountCached(ctx, endpoint)
264
+ ?? 0;
265
+ const mcGroupCount = mcInstance?.getGroupCountCached(ctx, endpoint)
264
266
  ?? 0;
265
267
  const groupCount = Math.max(assocGroupCount, mcGroupCount);
266
268
  if (group > groupCount) {
267
269
  throw new safe_1.ZWaveError(`Group ${group} does not exist on node ${nodeAndEndpointString}`, safe_1.ZWaveErrorCodes.AssociationCC_InvalidGroup);
268
270
  }
269
- const deviceConfig = applHost.getDeviceConfig?.(endpoint.nodeId);
271
+ const deviceConfig = ctx.getDeviceConfig?.(endpoint.nodeId);
270
272
  const groupIsMultiChannel = !!mcInstance
271
273
  && group <= mcGroupCount
272
274
  && deviceConfig?.associations?.get(group)?.multiChannel !== false;
@@ -274,7 +276,7 @@ async function addAssociations(applHost, endpoint, group, destinations) {
274
276
  // Check that all associations are allowed
275
277
  const disallowedAssociations = destinations.map((a) => ({
276
278
  ...a,
277
- checkResult: checkAssociation(applHost, endpoint, group, a),
279
+ checkResult: checkAssociation(ctx, endpoint, group, a),
278
280
  })).filter(({ checkResult }) => checkResult !== _Types_1.AssociationCheckResult.OK);
279
281
  if (disallowedAssociations.length) {
280
282
  let message = `The following associations are not allowed:`;
@@ -284,7 +286,7 @@ async function addAssociations(applHost, endpoint, group, destinations) {
284
286
  throw new safe_1.ZWaveError(message, safe_1.ZWaveErrorCodes.AssociationCC_NotAllowed, disallowedAssociations);
285
287
  }
286
288
  // And add them
287
- const api = API_1.CCAPI.create(safe_1.CommandClasses["Multi Channel Association"], applHost, endpoint);
289
+ const api = API_1.CCAPI.create(safe_1.CommandClasses["Multi Channel Association"], ctx, endpoint);
288
290
  await api.addDestinations({
289
291
  groupId: group,
290
292
  nodeIds: nodeAssociations,
@@ -301,7 +303,7 @@ async function addAssociations(applHost, endpoint, group, destinations) {
301
303
  // Check that all associations are allowed
302
304
  const disallowedAssociations = destinations.map((a) => ({
303
305
  ...a,
304
- checkResult: checkAssociation(applHost, endpoint, group, a),
306
+ checkResult: checkAssociation(ctx, endpoint, group, a),
305
307
  })).filter(({ checkResult }) => checkResult !== _Types_1.AssociationCheckResult.OK);
306
308
  if (disallowedAssociations.length) {
307
309
  let message = `The associations to the following nodes are not allowed`;
@@ -310,13 +312,13 @@ async function addAssociations(applHost, endpoint, group, destinations) {
310
312
  .join("");
311
313
  throw new safe_1.ZWaveError(message, safe_1.ZWaveErrorCodes.AssociationCC_NotAllowed, disallowedAssociations);
312
314
  }
313
- const api = API_1.CCAPI.create(safe_1.CommandClasses.Association, applHost, endpoint);
315
+ const api = API_1.CCAPI.create(safe_1.CommandClasses.Association, ctx, endpoint);
314
316
  await api.addNodeIds(group, ...destinations.map((a) => a.nodeId));
315
317
  // Refresh the association list
316
318
  await api.getGroup(group);
317
319
  }
318
320
  }
319
- async function removeAssociations(applHost, endpoint, group, destinations) {
321
+ async function removeAssociations(ctx, endpoint, group, destinations) {
320
322
  const nodeAndEndpointString = `${endpoint.nodeId}${endpoint.index > 0 ? `, endpoint ${endpoint.index}` : ""}`;
321
323
  // Split associations into conventional and endpoint associations
322
324
  const nodeAssociations = (0, arrays_1.distinct)(destinations
@@ -334,7 +336,7 @@ async function removeAssociations(applHost, endpoint, group, destinations) {
334
336
  // and the node supports multi channel associations
335
337
  if (endpoint.supportsCC(safe_1.CommandClasses["Multi Channel Association"])) {
336
338
  mcInstance = MultiChannelAssociationCC_1.MultiChannelAssociationCC;
337
- if (group <= mcInstance.getGroupCountCached(applHost, endpoint)) {
339
+ if (group <= mcInstance.getGroupCountCached(ctx, endpoint)) {
338
340
  groupExistsAsMultiChannel = true;
339
341
  }
340
342
  }
@@ -345,7 +347,7 @@ async function removeAssociations(applHost, endpoint, group, destinations) {
345
347
  // or as a multi channel association
346
348
  if (endpoint.supportsCC(safe_1.CommandClasses.Association)) {
347
349
  assocInstance = AssociationCC_1.AssociationCC;
348
- if (group <= assocInstance.getGroupCountCached(applHost, endpoint)) {
350
+ if (group <= assocInstance.getGroupCountCached(ctx, endpoint)) {
349
351
  groupExistsAsNodeAssociation = true;
350
352
  }
351
353
  }
@@ -364,7 +366,7 @@ async function removeAssociations(applHost, endpoint, group, destinations) {
364
366
  if (assocInstance
365
367
  && nodeAssociations.length > 0
366
368
  && groupExistsAsNodeAssociation) {
367
- const api = API_1.CCAPI.create(safe_1.CommandClasses.Association, applHost, endpoint);
369
+ const api = API_1.CCAPI.create(safe_1.CommandClasses.Association, ctx, endpoint);
368
370
  await api.removeNodeIds({
369
371
  groupId: group,
370
372
  nodeIds: nodeAssociations,
@@ -373,7 +375,7 @@ async function removeAssociations(applHost, endpoint, group, destinations) {
373
375
  await api.getGroup(group);
374
376
  }
375
377
  if (mcInstance && groupExistsAsMultiChannel) {
376
- const api = API_1.CCAPI.create(safe_1.CommandClasses["Multi Channel Association"], applHost, endpoint);
378
+ const api = API_1.CCAPI.create(safe_1.CommandClasses["Multi Channel Association"], ctx, endpoint);
377
379
  await api.removeDestinations({
378
380
  groupId: group,
379
381
  nodeIds: nodeAssociations,
@@ -383,11 +385,10 @@ async function removeAssociations(applHost, endpoint, group, destinations) {
383
385
  await api.getGroup(group);
384
386
  }
385
387
  }
386
- function getLifelineGroupIds(applHost, endpoint) {
388
+ function getLifelineGroupIds(ctx, endpoint) {
387
389
  // For now only support this for the root endpoint - i.e. node
388
390
  if (endpoint.index > 0)
389
391
  return [];
390
- const node = endpoint;
391
392
  // Some nodes define multiple lifeline groups, so we need to assign us to
392
393
  // all of them
393
394
  const lifelineGroups = [];
@@ -397,7 +398,7 @@ function getLifelineGroupIds(applHost, endpoint) {
397
398
  }
398
399
  // We have a device config file that tells us which (additional) association to assign
399
400
  let associations;
400
- const deviceConfig = applHost.getDeviceConfig?.(node.id);
401
+ const deviceConfig = ctx.getDeviceConfig?.(endpoint.nodeId);
401
402
  if (endpoint.index === 0) {
402
403
  // The root endpoint's associations may be configured separately or as part of "endpoints"
403
404
  associations = deviceConfig?.associations
@@ -414,31 +415,31 @@ function getLifelineGroupIds(applHost, endpoint) {
414
415
  }
415
416
  return (0, arrays_1.distinct)(lifelineGroups).sort();
416
417
  }
417
- async function configureLifelineAssociations(applHost, endpoint) {
418
+ async function configureLifelineAssociations(ctx, endpoint) {
418
419
  // Assign the controller to all lifeline groups
419
- const ownNodeId = applHost.ownNodeId;
420
- const node = endpoint.getNodeUnsafe();
421
- const valueDB = applHost.getValueDB(node.id);
422
- const deviceConfig = applHost.getDeviceConfig?.(node.id);
420
+ const ownNodeId = ctx.ownNodeId;
421
+ const node = ctx.getNodeOrThrow(endpoint.nodeId);
422
+ const valueDB = ctx.getValueDB(node.id);
423
+ const deviceConfig = ctx.getDeviceConfig?.(node.id);
423
424
  // We check if a node supports Multi Channel CC before creating Multi Channel Lifeline Associations (#1109)
424
425
  const nodeSupportsMultiChannel = node.supportsCC(safe_1.CommandClasses["Multi Channel"]);
425
426
  let assocInstance;
426
- const assocAPI = API_1.CCAPI.create(safe_1.CommandClasses.Association, applHost, endpoint);
427
+ const assocAPI = API_1.CCAPI.create(safe_1.CommandClasses.Association, ctx, endpoint);
427
428
  if (endpoint.supportsCC(safe_1.CommandClasses.Association)) {
428
429
  assocInstance = AssociationCC_1.AssociationCC;
429
430
  }
430
431
  let mcInstance;
431
432
  let mcGroupCount = 0;
432
- const mcAPI = API_1.CCAPI.create(safe_1.CommandClasses["Multi Channel Association"], applHost, endpoint);
433
+ const mcAPI = API_1.CCAPI.create(safe_1.CommandClasses["Multi Channel Association"], ctx, endpoint);
433
434
  if (endpoint.supportsCC(safe_1.CommandClasses["Multi Channel Association"])) {
434
435
  mcInstance = MultiChannelAssociationCC_1.MultiChannelAssociationCC;
435
- mcGroupCount = mcInstance.getGroupCountCached(applHost, endpoint) ?? 0;
436
+ mcGroupCount = mcInstance.getGroupCountCached(ctx, endpoint) ?? 0;
436
437
  }
437
- const lifelineGroups = getLifelineGroupIds(applHost, node);
438
+ const lifelineGroups = getLifelineGroupIds(ctx, node);
438
439
  if (lifelineGroups.length === 0) {
439
440
  // We can look for the General Lifeline AGI profile as a last resort
440
441
  if (endpoint.supportsCC(safe_1.CommandClasses["Association Group Information"])) {
441
- const agiAPI = API_1.CCAPI.create(safe_1.CommandClasses["Association Group Information"], applHost, endpoint);
442
+ const agiAPI = API_1.CCAPI.create(safe_1.CommandClasses["Association Group Information"], ctx, endpoint);
442
443
  // The lifeline MUST be group 1
443
444
  const lifeline = await agiAPI
444
445
  .getGroupInfo(1, true)
@@ -450,7 +451,7 @@ async function configureLifelineAssociations(applHost, endpoint) {
450
451
  }
451
452
  }
452
453
  if (lifelineGroups.length === 0) {
453
- applHost.controllerLog.logNode(node.id, {
454
+ ctx.logNode(node.id, {
454
455
  endpoint: endpoint.index,
455
456
  message: "No information about Lifeline associations, cannot assign ourselves!",
456
457
  level: "warn",
@@ -459,7 +460,7 @@ async function configureLifelineAssociations(applHost, endpoint) {
459
460
  valueDB.setValue(AssociationCC_1.AssociationCCValues.hasLifeline.endpoint(endpoint.index), false);
460
461
  return;
461
462
  }
462
- applHost.controllerLog.logNode(node.id, {
463
+ ctx.logNode(node.id, {
463
464
  endpoint: endpoint.index,
464
465
  message: `Checking/assigning lifeline groups: ${lifelineGroups.join(", ")}
465
466
  supports classic associations: ${!!assocInstance}
@@ -489,7 +490,7 @@ supports multi channel associations: ${!!mcInstance}`,
489
490
  }
490
491
  }
491
492
  }
492
- applHost.controllerLog.logNode(node.id, {
493
+ ctx.logNode(node.id, {
493
494
  endpoint: endpoint.index,
494
495
  message: `Configuring lifeline group #${group}:
495
496
  group supports multi channel: ${groupSupportsMultiChannelAssociation}
@@ -502,10 +503,10 @@ must use endpoint association: ${mustUseMultiChannelAssociation}`,
502
503
  if (groupSupportsMultiChannelAssociation && mcInstance) {
503
504
  if (
504
505
  // Only consider a group if it doesn't share its associations with the root endpoint
505
- mcInstance.getMaxNodesCached(applHost, endpoint, group)
506
+ mcInstance.getMaxNodesCached(ctx, endpoint, group)
506
507
  > 0
507
508
  && !!mcInstance
508
- .getAllDestinationsCached(applHost, endpoint)
509
+ .getAllDestinationsCached(ctx, endpoint)
509
510
  .get(group)
510
511
  ?.some((addr) => addr.nodeId === ownNodeId
511
512
  && addr.endpoint == undefined)) {
@@ -515,10 +516,10 @@ must use endpoint association: ${mustUseMultiChannelAssociation}`,
515
516
  if (assocInstance) {
516
517
  if (
517
518
  // Only consider a group if it doesn't share its associations with the root endpoint
518
- assocInstance.getMaxNodesCached(applHost, endpoint, group)
519
+ assocInstance.getMaxNodesCached(ctx, endpoint, group)
519
520
  > 0
520
521
  && !!assocInstance
521
- .getAllDestinationsCached(applHost, endpoint)
522
+ .getAllDestinationsCached(ctx, endpoint)
522
523
  .get(group)
523
524
  ?.some((addr) => addr.nodeId === ownNodeId)) {
524
525
  return true;
@@ -530,10 +531,10 @@ must use endpoint association: ${mustUseMultiChannelAssociation}`,
530
531
  if (mcInstance) {
531
532
  if (
532
533
  // Only consider a group if it doesn't share its associations with the root endpoint
533
- mcInstance.getMaxNodesCached(applHost, endpoint, group)
534
+ mcInstance.getMaxNodesCached(ctx, endpoint, group)
534
535
  > 0
535
536
  && mcInstance
536
- .getAllDestinationsCached(applHost, endpoint)
537
+ .getAllDestinationsCached(ctx, endpoint)
537
538
  .get(group)
538
539
  ?.some((addr) => addr.nodeId === ownNodeId
539
540
  && addr.endpoint === 0)) {
@@ -545,7 +546,7 @@ must use endpoint association: ${mustUseMultiChannelAssociation}`,
545
546
  // If the node was used with other controller software, there might be
546
547
  // invalid lifeline associations which cause reporting problems
547
548
  const invalidEndpointAssociations = mcInstance
548
- ?.getAllDestinationsCached(applHost, endpoint)
549
+ ?.getAllDestinationsCached(ctx, endpoint)
549
550
  .get(group)
550
551
  ?.filter((addr) => addr.nodeId === ownNodeId
551
552
  && addr.endpoint != undefined
@@ -554,7 +555,7 @@ must use endpoint association: ${mustUseMultiChannelAssociation}`,
554
555
  if (invalidEndpointAssociations.length > 0
555
556
  && mcAPI.isSupported()
556
557
  && groupSupportsMultiChannelAssociation) {
557
- applHost.controllerLog.logNode(node.id, {
558
+ ctx.logNode(node.id, {
558
559
  endpoint: endpoint.index,
559
560
  message: `Found invalid lifeline associations in group #${group}, removing them...`,
560
561
  direction: "outbound",
@@ -582,7 +583,7 @@ must use endpoint association: ${mustUseMultiChannelAssociation}`,
582
583
  if (isAssignedAsNodeAssociation(endpoint)) {
583
584
  // We already have the correct association
584
585
  hasLifeline = true;
585
- applHost.controllerLog.logNode(node.id, {
586
+ ctx.logNode(node.id, {
586
587
  endpoint: endpoint.index,
587
588
  message: `Lifeline group #${group} is already assigned with a node association`,
588
589
  direction: "none",
@@ -590,10 +591,10 @@ must use endpoint association: ${mustUseMultiChannelAssociation}`,
590
591
  }
591
592
  else if (assocAPI.isSupported()
592
593
  // Some endpoint groups don't support having any destinations because they are shared with the root
593
- && assocInstance.getMaxNodesCached(applHost, endpoint, group)
594
+ && assocInstance.getMaxNodesCached(ctx, endpoint, group)
594
595
  > 0) {
595
596
  // We can use a node association, but first remove any possible endpoint associations
596
- applHost.controllerLog.logNode(node.id, {
597
+ ctx.logNode(node.id, {
597
598
  endpoint: endpoint.index,
598
599
  message: `Assigning lifeline group #${group} with a node association via Association CC...`,
599
600
  direction: "outbound",
@@ -612,14 +613,14 @@ must use endpoint association: ${mustUseMultiChannelAssociation}`,
612
613
  const groupReport = await assocAPI.getGroup(group);
613
614
  hasLifeline = !!groupReport?.nodeIds.includes(ownNodeId);
614
615
  if (hasLifeline) {
615
- applHost.controllerLog.logNode(node.id, {
616
+ ctx.logNode(node.id, {
616
617
  endpoint: endpoint.index,
617
618
  message: `Lifeline group #${group} was assigned with a node association via Association CC`,
618
619
  direction: "none",
619
620
  });
620
621
  }
621
622
  else {
622
- applHost.controllerLog.logNode(node.id, {
623
+ ctx.logNode(node.id, {
623
624
  endpoint: endpoint.index,
624
625
  message: `Assigning lifeline group #${group} with a node association via Association CC did not work`,
625
626
  direction: "none",
@@ -629,9 +630,9 @@ must use endpoint association: ${mustUseMultiChannelAssociation}`,
629
630
  // Second try: Node association using the Multi Channel Association CC
630
631
  if (!hasLifeline
631
632
  && mcAPI.isSupported()
632
- && mcInstance.getMaxNodesCached(applHost, endpoint, group) > 0) {
633
+ && mcInstance.getMaxNodesCached(ctx, endpoint, group) > 0) {
633
634
  // We can use a node association, but first remove any possible endpoint associations
634
- applHost.controllerLog.logNode(node.id, {
635
+ ctx.logNode(node.id, {
635
636
  endpoint: endpoint.index,
636
637
  message: `Assigning lifeline group #${group} with a node association via Multi Channel Association CC...`,
637
638
  direction: "outbound",
@@ -650,14 +651,14 @@ must use endpoint association: ${mustUseMultiChannelAssociation}`,
650
651
  const groupReport = await mcAPI.getGroup(group);
651
652
  hasLifeline = !!groupReport?.nodeIds.includes(ownNodeId);
652
653
  if (hasLifeline) {
653
- applHost.controllerLog.logNode(node.id, {
654
+ ctx.logNode(node.id, {
654
655
  endpoint: endpoint.index,
655
656
  message: `Lifeline group #${group} was assigned with a node association via Multi Channel Association CC`,
656
657
  direction: "none",
657
658
  });
658
659
  }
659
660
  else {
660
- applHost.controllerLog.logNode(node.id, {
661
+ ctx.logNode(node.id, {
661
662
  endpoint: endpoint.index,
662
663
  message: `Assigning lifeline group #${group} with a node association via Multi Channel Association CC did not work`,
663
664
  direction: "none",
@@ -671,7 +672,7 @@ must use endpoint association: ${mustUseMultiChannelAssociation}`,
671
672
  if (isAssignedAsEndpointAssociation(endpoint)) {
672
673
  // We already have the correct association
673
674
  hasLifeline = true;
674
- applHost.controllerLog.logNode(node.id, {
675
+ ctx.logNode(node.id, {
675
676
  endpoint: endpoint.index,
676
677
  message: `Lifeline group #${group} is already assigned with an endpoint association`,
677
678
  direction: "none",
@@ -679,9 +680,9 @@ must use endpoint association: ${mustUseMultiChannelAssociation}`,
679
680
  }
680
681
  else if (mcAPI.isSupported()
681
682
  && mcAPI.version >= 3
682
- && mcInstance.getMaxNodesCached(applHost, endpoint, group) > 0) {
683
+ && mcInstance.getMaxNodesCached(ctx, endpoint, group) > 0) {
683
684
  // We can use a multi channel association, but first remove any possible node associations
684
- applHost.controllerLog.logNode(node.id, {
685
+ ctx.logNode(node.id, {
685
686
  endpoint: endpoint.index,
686
687
  message: `Assigning lifeline group #${group} with a multi channel association...`,
687
688
  direction: "outbound",
@@ -710,14 +711,14 @@ must use endpoint association: ${mustUseMultiChannelAssociation}`,
710
711
  const groupReport = await mcAPI.getGroup(group);
711
712
  hasLifeline = !!groupReport?.endpoints.some((a) => a.nodeId === ownNodeId && a.endpoint === 0);
712
713
  if (hasLifeline) {
713
- applHost.controllerLog.logNode(node.id, {
714
+ ctx.logNode(node.id, {
714
715
  endpoint: endpoint.index,
715
716
  message: `Lifeline group #${group} was assigned with a multi channel association`,
716
717
  direction: "none",
717
718
  });
718
719
  }
719
720
  else {
720
- applHost.controllerLog.logNode(node.id, {
721
+ ctx.logNode(node.id, {
721
722
  endpoint: endpoint.index,
722
723
  message: `Assigning lifeline group #${group} with a multi channel association did not work`,
723
724
  direction: "none",
@@ -737,7 +738,7 @@ must use endpoint association: ${mustUseMultiChannelAssociation}`,
737
738
  ?.getAssociationConfigForEndpoint(0, group);
738
739
  const rootMustUseNodeAssociation = !nodeSupportsMultiChannel
739
740
  || rootAssocConfig?.multiChannel === false;
740
- applHost.controllerLog.logNode(node.id, {
741
+ ctx.logNode(node.id, {
741
742
  endpoint: endpoint.index,
742
743
  message: `Checking root device for fallback assignment of lifeline group #${group}:
743
744
  root supports multi channel: ${nodeSupportsMultiChannel}
@@ -748,17 +749,17 @@ must use node association: ${rootMustUseNodeAssociation}`,
748
749
  if (isAssignedAsEndpointAssociation(node)) {
749
750
  // We already have the correct association
750
751
  hasLifeline = true;
751
- applHost.controllerLog.logNode(node.id, {
752
+ ctx.logNode(node.id, {
752
753
  endpoint: endpoint.index,
753
754
  message: `Lifeline group #${group} is already assigned with a multi channel association on the root device`,
754
755
  direction: "none",
755
756
  });
756
757
  }
757
758
  else {
758
- const rootMCAPI = API_1.CCAPI.create(safe_1.CommandClasses["Multi Channel Association"], applHost, node);
759
- const rootAssocAPI = API_1.CCAPI.create(safe_1.CommandClasses.Association, applHost, node);
759
+ const rootMCAPI = API_1.CCAPI.create(safe_1.CommandClasses["Multi Channel Association"], ctx, node);
760
+ const rootAssocAPI = API_1.CCAPI.create(safe_1.CommandClasses.Association, ctx, node);
760
761
  if (rootMCAPI.isSupported()) {
761
- applHost.controllerLog.logNode(node.id, {
762
+ ctx.logNode(node.id, {
762
763
  endpoint: endpoint.index,
763
764
  message: `Assigning lifeline group #${group} with a multi channel association on the root device...`,
764
765
  direction: "outbound",
@@ -792,7 +793,7 @@ must use node association: ${rootMustUseNodeAssociation}`,
792
793
  }
793
794
  }
794
795
  if (!hasLifeline) {
795
- applHost.controllerLog.logNode(node.id, {
796
+ ctx.logNode(node.id, {
796
797
  endpoint: endpoint.index,
797
798
  message: `All attempts to assign lifeline group #${group} failed, skipping...`,
798
799
  direction: "none",
@@ -803,31 +804,32 @@ must use node association: ${rootMustUseNodeAssociation}`,
803
804
  // Remember that we did the association assignment
804
805
  valueDB.setValue(AssociationCC_1.AssociationCCValues.hasLifeline.endpoint(endpoint.index), true);
805
806
  }
806
- async function assignLifelineIssueingCommand(applHost, endpoint, ccId, ccCommand) {
807
- const node = endpoint.getNodeUnsafe();
807
+ async function assignLifelineIssueingCommand(ctx, endpoint, ccId, ccCommand) {
808
+ const node = ctx.getNodeOrThrow(endpoint.nodeId);
808
809
  if (node.supportsCC(safe_1.CommandClasses["Association Group Information"])
809
810
  && (node.supportsCC(safe_1.CommandClasses.Association)
810
811
  || node.supportsCC(safe_1.CommandClasses["Multi Channel Association"]))) {
811
812
  const groupsIssueingNotifications = AssociationGroupInfoCC_1.AssociationGroupInfoCC
812
- .findGroupsForIssuedCommand(applHost, node, ccId, ccCommand);
813
+ .findGroupsForIssuedCommand(ctx, node, ccId, ccCommand);
813
814
  if (groupsIssueingNotifications.length > 0) {
814
815
  // We always grab the first group - usually it should be the lifeline
815
816
  const groupId = groupsIssueingNotifications[0];
816
- const existingAssociations = getAssociations(applHost, node).get(groupId) ?? [];
817
- if (!existingAssociations.some((a) => a.nodeId === applHost.ownNodeId)) {
818
- applHost.controllerLog.logNode(node.id, {
817
+ const existingAssociations = getAssociations(ctx, node).get(groupId)
818
+ ?? [];
819
+ if (!existingAssociations.some((a) => a.nodeId === ctx.ownNodeId)) {
820
+ ctx.logNode(node.id, {
819
821
  endpoint: endpoint.index,
820
822
  message: `Configuring associations to receive ${(0, safe_1.getCCName)(ccId)} commands...`,
821
823
  direction: "outbound",
822
824
  });
823
- await addAssociations(applHost, node, groupId, [
824
- { nodeId: applHost.ownNodeId },
825
+ await addAssociations(ctx, node, groupId, [
826
+ { nodeId: ctx.ownNodeId },
825
827
  ]);
826
828
  }
827
829
  }
828
830
  }
829
831
  }
830
- function doesAnyLifelineSendActuatorOrSensorReports(applHost, node) {
832
+ function doesAnyLifelineSendActuatorOrSensorReports(ctx, node) {
831
833
  // No association support means no unsolicited reports
832
834
  if (!node.supportsCC(safe_1.CommandClasses.Association)
833
835
  && !node.supportsCC(safe_1.CommandClasses["Multi Channel Association"])) {
@@ -838,14 +840,14 @@ function doesAnyLifelineSendActuatorOrSensorReports(applHost, node) {
838
840
  return safe_1.NOT_KNOWN;
839
841
  }
840
842
  // Lifeline group IDs include the ones we added via a config file, so they may not be considered true lifelines
841
- const lifelineGroupIds = getLifelineGroupIds(applHost, node);
843
+ const lifelineGroupIds = getLifelineGroupIds(ctx, node);
842
844
  // If any potential lifeline group has the "General: Lifeline" profile, the node MUST send unsolicited reports that way
843
- if (lifelineGroupIds.some((id) => AssociationGroupInfoCC_1.AssociationGroupInfoCC.getGroupProfileCached(applHost, node, id) === _Types_1.AssociationGroupInfoProfile["General: Lifeline"])) {
845
+ if (lifelineGroupIds.some((id) => AssociationGroupInfoCC_1.AssociationGroupInfoCC.getGroupProfileCached(ctx, node, id) === _Types_1.AssociationGroupInfoProfile["General: Lifeline"])) {
844
846
  return true;
845
847
  }
846
848
  // Otherwise check if any of the groups sends any actuator or sensor commands. We'll assume that those are reports
847
849
  for (const groupId of lifelineGroupIds) {
848
- const issuedCommands = AssociationGroupInfoCC_1.AssociationGroupInfoCC.getIssuedCommandsCached(applHost, node, groupId);
850
+ const issuedCommands = AssociationGroupInfoCC_1.AssociationGroupInfoCC.getIssuedCommandsCached(ctx, node, groupId);
849
851
  if (!issuedCommands)
850
852
  continue;
851
853
  const commands = [...issuedCommands.keys()];