@mp-consulting/homebridge-daikin-cloud 1.3.6 → 1.3.7

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 (287) hide show
  1. package/LICENSE +39 -1
  2. package/README.md +3 -1
  3. package/dist/src/accessories/air-conditioning-accessory.d.ts +2 -2
  4. package/dist/src/accessories/air-conditioning-accessory.d.ts.map +1 -1
  5. package/dist/src/accessories/air-conditioning-accessory.js.map +1 -1
  6. package/dist/src/accessories/altherma-accessory.d.ts +2 -2
  7. package/dist/src/accessories/altherma-accessory.d.ts.map +1 -1
  8. package/dist/src/accessories/altherma-accessory.js.map +1 -1
  9. package/dist/src/accessories/base-accessory.d.ts +5 -5
  10. package/dist/src/accessories/base-accessory.d.ts.map +1 -1
  11. package/dist/src/accessories/base-accessory.js +7 -4
  12. package/dist/src/accessories/base-accessory.js.map +1 -1
  13. package/dist/src/api/daikin-api.d.ts +25 -25
  14. package/dist/src/api/daikin-api.d.ts.map +1 -1
  15. package/dist/src/api/daikin-api.js +41 -31
  16. package/dist/src/api/daikin-api.js.map +1 -1
  17. package/dist/src/api/daikin-cloud.repository.d.ts.map +1 -1
  18. package/dist/src/api/daikin-cloud.repository.js.map +1 -1
  19. package/dist/src/api/daikin-controller.d.ts +41 -42
  20. package/dist/src/api/daikin-controller.d.ts.map +1 -1
  21. package/dist/src/api/daikin-controller.js +39 -39
  22. package/dist/src/api/daikin-controller.js.map +1 -1
  23. package/dist/src/api/daikin-device.d.ts +33 -31
  24. package/dist/src/api/daikin-device.d.ts.map +1 -1
  25. package/dist/src/api/daikin-device.js +40 -29
  26. package/dist/src/api/daikin-device.js.map +1 -1
  27. package/dist/src/api/daikin-mobile-oauth.d.ts +16 -16
  28. package/dist/src/api/daikin-mobile-oauth.d.ts.map +1 -1
  29. package/dist/src/api/daikin-mobile-oauth.js +32 -22
  30. package/dist/src/api/daikin-mobile-oauth.js.map +1 -1
  31. package/dist/src/api/daikin-oauth.d.ts +29 -29
  32. package/dist/src/api/daikin-oauth.d.ts.map +1 -1
  33. package/dist/src/api/daikin-oauth.js +45 -35
  34. package/dist/src/api/daikin-oauth.js.map +1 -1
  35. package/dist/src/api/daikin-schemas.d.ts +4 -4
  36. package/dist/src/api/daikin-schemas.js +3 -3
  37. package/dist/src/api/daikin-schemas.js.map +1 -1
  38. package/dist/src/api/daikin-types.js.map +1 -1
  39. package/dist/src/api/daikin-websocket.d.ts +31 -32
  40. package/dist/src/api/daikin-websocket.d.ts.map +1 -1
  41. package/dist/src/api/daikin-websocket.js +30 -30
  42. package/dist/src/api/daikin-websocket.js.map +1 -1
  43. package/dist/src/api/index.d.ts +1 -1
  44. package/dist/src/api/index.d.ts.map +1 -1
  45. package/dist/src/api/index.js +2 -1
  46. package/dist/src/api/index.js.map +1 -1
  47. package/dist/src/api/token-storage.d.ts +1 -1
  48. package/dist/src/api/token-storage.d.ts.map +1 -1
  49. package/dist/src/api/token-storage.js +20 -11
  50. package/dist/src/api/token-storage.js.map +1 -1
  51. package/dist/src/config/config-manager.d.ts +33 -33
  52. package/dist/src/config/config-manager.d.ts.map +1 -1
  53. package/dist/src/config/config-manager.js +33 -33
  54. package/dist/src/config/config-manager.js.map +1 -1
  55. package/dist/src/constants/api.constants.js.map +1 -1
  56. package/dist/src/device/accessory-factory.d.ts +10 -10
  57. package/dist/src/device/accessory-factory.d.ts.map +1 -1
  58. package/dist/src/device/accessory-factory.js +6 -6
  59. package/dist/src/device/accessory-factory.js.map +1 -1
  60. package/dist/src/device/capability-detector.d.ts +8 -8
  61. package/dist/src/device/capability-detector.d.ts.map +1 -1
  62. package/dist/src/device/capability-detector.js +6 -6
  63. package/dist/src/device/capability-detector.js.map +1 -1
  64. package/dist/src/device/capability-docs.d.ts +1 -1
  65. package/dist/src/device/capability-docs.d.ts.map +1 -1
  66. package/dist/src/device/capability-docs.js +1 -2
  67. package/dist/src/device/capability-docs.js.map +1 -1
  68. package/dist/src/device/profiles/device-profile.d.ts +1 -1
  69. package/dist/src/device/profiles/device-profile.d.ts.map +1 -1
  70. package/dist/src/device/profiles/device-profile.js +4 -4
  71. package/dist/src/device/profiles/device-profile.js.map +1 -1
  72. package/dist/src/features/base-feature.d.ts +2 -2
  73. package/dist/src/features/base-feature.d.ts.map +1 -1
  74. package/dist/src/features/base-feature.js +2 -3
  75. package/dist/src/features/base-feature.js.map +1 -1
  76. package/dist/src/features/feature-manager.d.ts +8 -8
  77. package/dist/src/features/feature-manager.d.ts.map +1 -1
  78. package/dist/src/features/feature-manager.js +5 -5
  79. package/dist/src/features/feature-manager.js.map +1 -1
  80. package/dist/src/features/modes/dry-operation-mode.feature.d.ts +1 -1
  81. package/dist/src/features/modes/dry-operation-mode.feature.d.ts.map +1 -1
  82. package/dist/src/features/modes/dry-operation-mode.feature.js.map +1 -1
  83. package/dist/src/features/modes/econo-mode.feature.d.ts +1 -1
  84. package/dist/src/features/modes/econo-mode.feature.d.ts.map +1 -1
  85. package/dist/src/features/modes/econo-mode.feature.js.map +1 -1
  86. package/dist/src/features/modes/fan-only-operation-mode.feature.d.ts +1 -1
  87. package/dist/src/features/modes/fan-only-operation-mode.feature.d.ts.map +1 -1
  88. package/dist/src/features/modes/fan-only-operation-mode.feature.js.map +1 -1
  89. package/dist/src/features/modes/indoor-silent-mode.feature.d.ts +1 -1
  90. package/dist/src/features/modes/indoor-silent-mode.feature.d.ts.map +1 -1
  91. package/dist/src/features/modes/indoor-silent-mode.feature.js.map +1 -1
  92. package/dist/src/features/modes/outdoor-silent-mode.feature.d.ts +1 -1
  93. package/dist/src/features/modes/outdoor-silent-mode.feature.d.ts.map +1 -1
  94. package/dist/src/features/modes/outdoor-silent-mode.feature.js.map +1 -1
  95. package/dist/src/features/modes/powerful-mode.feature.d.ts +1 -1
  96. package/dist/src/features/modes/powerful-mode.feature.d.ts.map +1 -1
  97. package/dist/src/features/modes/powerful-mode.feature.js.map +1 -1
  98. package/dist/src/features/modes/streamer-mode.feature.d.ts +1 -1
  99. package/dist/src/features/modes/streamer-mode.feature.d.ts.map +1 -1
  100. package/dist/src/features/modes/streamer-mode.feature.js.map +1 -1
  101. package/dist/src/index.d.ts +1 -1
  102. package/dist/src/index.d.ts.map +1 -1
  103. package/dist/src/index.js.map +1 -1
  104. package/dist/src/platform.d.ts +6 -5
  105. package/dist/src/platform.d.ts.map +1 -1
  106. package/dist/src/platform.js +2 -2
  107. package/dist/src/platform.js.map +1 -1
  108. package/dist/src/services/climate-control.service.d.ts +8 -2
  109. package/dist/src/services/climate-control.service.d.ts.map +1 -1
  110. package/dist/src/services/climate-control.service.js +53 -59
  111. package/dist/src/services/climate-control.service.js.map +1 -1
  112. package/dist/src/services/hot-water-tank.service.d.ts +6 -2
  113. package/dist/src/services/hot-water-tank.service.d.ts.map +1 -1
  114. package/dist/src/services/hot-water-tank.service.js +31 -34
  115. package/dist/src/services/hot-water-tank.service.js.map +1 -1
  116. package/dist/src/types/daikin-enums.js +12 -12
  117. package/dist/src/types/daikin-enums.js.map +1 -1
  118. package/dist/src/types/device-capabilities.d.ts +1 -1
  119. package/dist/src/types/device-capabilities.d.ts.map +1 -1
  120. package/dist/src/utils/log-context.d.ts +23 -23
  121. package/dist/src/utils/log-context.d.ts.map +1 -1
  122. package/dist/src/utils/log-context.js +28 -28
  123. package/dist/src/utils/log-context.js.map +1 -1
  124. package/dist/src/utils/strings.d.ts.map +1 -1
  125. package/dist/src/utils/strings.js.map +1 -1
  126. package/dist/src/utils/update-mapper.d.ts +16 -16
  127. package/dist/src/utils/update-mapper.d.ts.map +1 -1
  128. package/dist/src/utils/update-mapper.js +14 -14
  129. package/dist/src/utils/update-mapper.js.map +1 -1
  130. package/homebridge-ui/public/script.js +956 -897
  131. package/homebridge-ui/server.js +739 -695
  132. package/package.json +27 -24
  133. package/.claude/settings.json +0 -3
  134. package/.claude/settings.local.json +0 -24
  135. package/CHANGELOG.md +0 -114
  136. package/CLAUDE.md +0 -269
  137. package/config.md +0 -2
  138. package/docs/ARCHITECTURE.md +0 -645
  139. package/docs/IMPLEMENTATION_GUIDE.md +0 -899
  140. package/docs/IMPROVEMENTS_SUMMARY.md +0 -415
  141. package/docs/NEXT_STEPS.md +0 -368
  142. package/docs/Screenshot 2024-07-04 at 18.41.28.png +0 -0
  143. package/docs/TROUBLESHOOTING.md +0 -475
  144. package/docs/api-response-for-BRP069A8x.json +0 -520
  145. package/docs/api-response-for-BRP069C4x-2.json +0 -881
  146. package/docs/api-response-for-BRP069C4x.json +0 -916
  147. package/docs/api-response-for-altherma.json +0 -759
  148. package/docs/api-response-for-altherma2.json +0 -2735
  149. package/docs/api-response-with-multiple-devices-incl-heatpump.json +0 -2544
  150. package/docs/cr-insance-altherma-id-0.json +0 -834
  151. package/docs/mock-air-to-air-dx23.json +0 -759
  152. package/docs/mock-air-to-air-dx4.json +0 -1134
  153. package/docs/mock-airpurifier-with-humidifier.json +0 -732
  154. package/docs/mock-airpurifier.json +0 -450
  155. package/docs/mock-altherma-air-to-water-lan.json +0 -845
  156. package/docs/mock-altherma-air-to-water-wlan.json +0 -845
  157. package/docs/mock-d2cnd-gas-boiler.json +0 -649
  158. package/docs/setpointmode-vs-controlmode-vs-setpoints-vs-sensorydata.txt +0 -6
  159. package/images/fan-speed.jpeg +0 -0
  160. package/images/homekit-controls.jpeg +0 -0
  161. package/images/homekit-settings.jpeg +0 -0
  162. package/images/swing-mode.png +0 -0
  163. package/jest.config.ts +0 -21
  164. package/test/fixtures/altherma-crSense-2.ts +0 -834
  165. package/test/fixtures/altherma-fraction.ts +0 -718
  166. package/test/fixtures/altherma-heat-pump-2.ts +0 -479
  167. package/test/fixtures/altherma-heat-pump.ts +0 -757
  168. package/test/fixtures/altherma-miladcerkic-off.ts +0 -524
  169. package/test/fixtures/altherma-miladcerkic.ts +0 -524
  170. package/test/fixtures/altherma-v1ckoeln.ts +0 -644
  171. package/test/fixtures/altherma-with-embedded-id-zero.ts +0 -834
  172. package/test/fixtures/dx23-airco-2.ts +0 -343
  173. package/test/fixtures/dx23-airco.ts +0 -518
  174. package/test/fixtures/dx4-airco.ts +0 -914
  175. package/test/fixtures/unknown-jan.ts +0 -488
  176. package/test/fixtures/unknown-kitchen-guests.ts +0 -488
  177. package/test/hbConfig/.daikin-mobile-tokenset +0 -8
  178. package/test/hbConfig/.uix-dashboard.json +0 -1
  179. package/test/hbConfig/.uix-secrets +0 -1
  180. package/test/hbConfig/accessories/.cachedAccessories.bak +0 -1
  181. package/test/hbConfig/accessories/cachedAccessories +0 -1
  182. package/test/hbConfig/accessories/uiAccessoriesLayout.json +0 -1
  183. package/test/hbConfig/auth.json +0 -10
  184. package/test/hbConfig/backups/config-backups/config.json.1767953686461 +0 -25
  185. package/test/hbConfig/backups/config-backups/config.json.1767953695236 +0 -29
  186. package/test/hbConfig/backups/config-backups/config.json.1767953814763 +0 -29
  187. package/test/hbConfig/backups/config-backups/config.json.1767953823101 +0 -29
  188. package/test/hbConfig/backups/config-backups/config.json.1767954822835 +0 -29
  189. package/test/hbConfig/backups/config-backups/config.json.1767954859218 +0 -29
  190. package/test/hbConfig/backups/config-backups/config.json.1767960145503 +0 -33
  191. package/test/hbConfig/backups/config-backups/config.json.1767960168068 +0 -44
  192. package/test/hbConfig/backups/config-backups/config.json.1767960170333 +0 -46
  193. package/test/hbConfig/backups/config-backups/config.json.1767960172731 +0 -44
  194. package/test/hbConfig/backups/config-backups/config.json.1767960179323 +0 -44
  195. package/test/hbConfig/backups/config-backups/config.json.1767960182114 +0 -44
  196. package/test/hbConfig/backups/config-backups/config.json.1767960189302 +0 -44
  197. package/test/hbConfig/backups/config-backups/config.json.1767960195194 +0 -44
  198. package/test/hbConfig/backups/config-backups/config.json.1767960197301 +0 -44
  199. package/test/hbConfig/backups/config-backups/config.json.1767960199151 +0 -44
  200. package/test/hbConfig/backups/config-backups/config.json.1767960199667 +0 -44
  201. package/test/hbConfig/backups/config-backups/config.json.1767960329839 +0 -44
  202. package/test/hbConfig/backups/config-backups/config.json.1767960334503 +0 -44
  203. package/test/hbConfig/backups/config-backups/config.json.1767960336208 +0 -44
  204. package/test/hbConfig/backups/config-backups/config.json.1767960338537 +0 -44
  205. package/test/hbConfig/backups/config-backups/config.json.1767963223953 +0 -44
  206. package/test/hbConfig/backups/config-backups/config.json.1767963241753 +0 -44
  207. package/test/hbConfig/backups/config-backups/config.json.1767963252785 +0 -44
  208. package/test/hbConfig/backups/config-backups/config.json.1767963463944 +0 -44
  209. package/test/hbConfig/backups/config-backups/config.json.1767963834475 +0 -44
  210. package/test/hbConfig/backups/config-backups/config.json.1767963838474 +0 -44
  211. package/test/hbConfig/backups/config-backups/config.json.1767963843066 +0 -44
  212. package/test/hbConfig/backups/config-backups/config.json.1767965217715 +0 -44
  213. package/test/hbConfig/backups/config-backups/config.json.1767965419624 +0 -25
  214. package/test/hbConfig/backups/config-backups/config.json.1767965870934 +0 -32
  215. package/test/hbConfig/backups/config-backups/config.json.1767977675045 +0 -32
  216. package/test/hbConfig/backups/config-backups/config.json.1767977677222 +0 -33
  217. package/test/hbConfig/backups/config-backups/config.json.1767977710226 +0 -33
  218. package/test/hbConfig/backups/config-backups/config.json.1767977741397 +0 -33
  219. package/test/hbConfig/backups/config-backups/config.json.1767977977093 +0 -35
  220. package/test/hbConfig/backups/config-backups/config.json.1767977981773 +0 -35
  221. package/test/hbConfig/backups/config-backups/config.json.1767977986514 +0 -35
  222. package/test/hbConfig/backups/config-backups/config.json.1767977991174 +0 -35
  223. package/test/hbConfig/backups/config-backups/config.json.1767979424487 +0 -35
  224. package/test/hbConfig/backups/config-backups/config.json.1767979424987 +0 -35
  225. package/test/hbConfig/backups/config-backups/config.json.1767979432646 +0 -47
  226. package/test/hbConfig/backups/config-backups/config.json.1767979433150 +0 -47
  227. package/test/hbConfig/backups/config-backups/config.json.1767979436933 +0 -47
  228. package/test/hbConfig/backups/config-backups/config.json.1767979437438 +0 -47
  229. package/test/hbConfig/backups/config-backups/config.json.1767979441676 +0 -47
  230. package/test/hbConfig/backups/config-backups/config.json.1767979442180 +0 -47
  231. package/test/hbConfig/backups/config-backups/config.json.1767979466735 +0 -47
  232. package/test/hbConfig/backups/config-backups/config.json.1767979903636 +0 -47
  233. package/test/hbConfig/backups/config-backups/config.json.1767979904135 +0 -47
  234. package/test/hbConfig/backups/config-backups/config.json.1767979906606 +0 -47
  235. package/test/hbConfig/backups/config-backups/config.json.1767979907108 +0 -47
  236. package/test/hbConfig/backups/config-backups/config.json.1767988702341 +0 -47
  237. package/test/hbConfig/backups/config-backups/config.json.1767988702837 +0 -47
  238. package/test/hbConfig/backups/config-backups/config.json.1767988713159 +0 -47
  239. package/test/hbConfig/backups/config-backups/config.json.1767988713664 +0 -47
  240. package/test/hbConfig/backups/config-backups/config.json.1767988918139 +0 -47
  241. package/test/hbConfig/backups/config-backups/config.json.1767988918639 +0 -47
  242. package/test/hbConfig/backups/config-backups/config.json.1767988921120 +0 -47
  243. package/test/hbConfig/backups/config-backups/config.json.1767988921624 +0 -47
  244. package/test/hbConfig/backups/config-backups/config.json.1767988930307 +0 -47
  245. package/test/hbConfig/backups/config-backups/config.json.1767988935070 +0 -47
  246. package/test/hbConfig/backups/config-backups/config.json.1767988935574 +0 -47
  247. package/test/hbConfig/backups/config-backups/config.json.1767989710262 +0 -47
  248. package/test/hbConfig/backups/config-backups/config.json.1767989710760 +0 -47
  249. package/test/hbConfig/backups/config-backups/config.json.1767989729668 +0 -47
  250. package/test/hbConfig/backups/config-backups/config.json.1767990295225 +0 -47
  251. package/test/hbConfig/backups/config-backups/config.json.1767990479921 +0 -47
  252. package/test/hbConfig/backups/config-backups/config.json.1767990481702 +0 -49
  253. package/test/hbConfig/backups/instance-backups/homebridge-backup-1E4A432551BA.1768010187391.tar.gz +0 -0
  254. package/test/hbConfig/backups/instance-backups/homebridge-backup-1E4A432551BA.1768096587387.tar.gz +0 -0
  255. package/test/hbConfig/backups/instance-backups/homebridge-backup-1E4A432551BA.1768182987404.tar.gz +0 -0
  256. package/test/hbConfig/config.json +0 -47
  257. package/test/hbConfig/daikin-cloud-certs/server.crt +0 -22
  258. package/test/hbConfig/daikin-cloud-certs/server.key +0 -28
  259. package/test/hbConfig/persist/AccessoryInfo.1E4A432551BA.json +0 -1
  260. package/test/hbConfig/persist/IdentifierCache.1E4A432551BA.json +0 -1
  261. package/test/hbConfig/tmp/daikin_request/api.onecta.daikineurope.com_01-09-2026-23-29-52/request_14758 +0 -1
  262. package/test/hbConfig/tmp/daikin_request/api.onecta.daikineurope.com_01-09-2026-23-29-52/request_14759 +0 -1
  263. package/test/hbConfig/tmp/daikin_request/api.onecta.daikineurope.com_01-09-2026-23-29-52/request_14760 +0 -1
  264. package/test/hbConfig/tmp/daikin_request/api.onecta.daikineurope.com_01-09-2026-23-29-52/request_14761 +0 -1
  265. package/test/hbConfig/tmp/daikin_request/api.onecta.daikineurope.com_01-09-2026-23-29-52/request_14762 +0 -1
  266. package/test/hbConfig/tmp/daikin_request/api.onecta.daikineurope.com_01-09-2026-23-29-52/request_14764 +0 -1
  267. package/test/helpers/test-isolation.ts +0 -228
  268. package/test/integration/air-conditioning.test.ts +0 -396
  269. package/test/integration/altherma.test.ts +0 -279
  270. package/test/integration/platform.test.ts +0 -118
  271. package/test/mobile-tokens.json +0 -8
  272. package/test/mocks/index.ts +0 -27
  273. package/test/test-gigya-auth.js +0 -443
  274. package/test/test-mobile-oauth.js +0 -175
  275. package/test/test-websocket-mobile.js +0 -123
  276. package/test/test-websocket.js +0 -116
  277. package/test/unit/api/__snapshots__/daikinCloud.test.ts.snap +0 -1320
  278. package/test/unit/api/daikin-api.test.ts +0 -442
  279. package/test/unit/api/daikin-cloud-repository.test.ts +0 -107
  280. package/test/unit/api/daikin-oauth.test.ts +0 -214
  281. package/test/unit/api/daikinCloud.test.ts +0 -12
  282. package/test/unit/api/token-storage.test.ts +0 -90
  283. package/test/unit/config/config-manager.test.ts +0 -271
  284. package/test/unit/device/daikin-device.test.ts +0 -73
  285. package/test/unit/services/hot-water-tank.service.test.ts +0 -123
  286. package/test/unit/utils/log-context.test.ts +0 -271
  287. package/test/unit/utils/update-mapper.test.ts +0 -404
@@ -1,123 +0,0 @@
1
- import {HotWaterTankService} from '../../../src/services';
2
- import {DaikinCloudDevice, DaikinApi} from '../../../src/api';
3
- import {MockPlatformConfig} from '../../mocks';
4
- import {DaikinCloudAccessoryContext, DaikinCloudPlatform} from '../../../src/platform';
5
- import {PlatformAccessory} from 'homebridge/lib/platformAccessory';
6
- import {Characteristic, uuid} from 'hap-nodejs';
7
- import {althermaHeatPump} from '../../fixtures/altherma-heat-pump';
8
-
9
- import {HomebridgeAPI} from 'homebridge/lib/api.js';
10
- import {Logger} from 'homebridge/lib/logger.js';
11
-
12
- // Helper to get management point data from the device
13
- const getManagementPoint = (device: DaikinCloudDevice, embeddedId: string): any => {
14
- return (device as any).rawData.managementPoints.find((mp: any) => mp.embeddedId === embeddedId);
15
- };
16
-
17
- // Use fake timers to prevent tests from hanging due to setInterval/setTimeout in platform
18
- beforeEach(() => {
19
- jest.useFakeTimers();
20
- });
21
-
22
- afterEach(() => {
23
- jest.clearAllTimers();
24
- jest.useRealTimers();
25
- });
26
-
27
- describe('HotWaterTankService', () => {
28
- let accessory: PlatformAccessory<DaikinCloudAccessoryContext>;
29
- let service: HotWaterTankService;
30
-
31
- const EMBEDDED_ID = 'domesticHotWaterTank';
32
-
33
- beforeEach(() => {
34
- const mockApi = {} as DaikinApi;
35
- accessory = new PlatformAccessory<DaikinCloudAccessoryContext>('ACCESSORY_NAME', uuid.generate('ACCESSORY_UUID'));
36
- // Use a deep copy of the fixture to isolate test mutations
37
- accessory.context['device'] = new DaikinCloudDevice(JSON.parse(JSON.stringify(althermaHeatPump)) as any, mockApi);
38
- accessory.context.device.getLastUpdated = jest.fn().mockReturnValue(new Date(1987, 0, 19, 0, 0, 0, 0));
39
-
40
- const platform = new DaikinCloudPlatform(new Logger(), new MockPlatformConfig(true), new HomebridgeAPI());
41
-
42
- service = new HotWaterTankService(platform, accessory, EMBEDDED_ID);
43
- });
44
-
45
- it('should get the current heating cooling state', async () => {
46
- expect(await service.handleHotWaterTankCurrentHeatingCoolingStateGet()).toBe(Characteristic.CurrentHeatingCoolingState.HEAT);
47
-
48
- getManagementPoint(accessory.context.device, EMBEDDED_ID)['onOffMode'] = { value: 'off' };
49
-
50
- expect(await service.handleHotWaterTankTargetHeatingCoolingStateGet()).toBe(Characteristic.CurrentHeatingCoolingState.OFF);
51
- });
52
-
53
- it('should get the current temperature', async () => {
54
- expect(await service.handleHotWaterTankCurrentTemperatureGet()).toBe(48);
55
- });
56
-
57
- it('should get the target heating cooling temperature', async () => {
58
- expect(await service.handleHotWaterTankHeatingTargetTemperatureGet()).toBe(48);
59
- });
60
-
61
- it('should get the target heating cooling state', async () => {
62
- expect(await service.handleHotWaterTankTargetHeatingCoolingStateGet()).toBe(Characteristic.TargetHeatingCoolingState.HEAT);
63
-
64
- getManagementPoint(accessory.context.device, EMBEDDED_ID)['operationMode'] = {
65
- 'settable': true,
66
- 'values': [
67
- 'auto',
68
- 'dry',
69
- 'cooling',
70
- 'heating',
71
- 'fanOnly',
72
- ],
73
- 'value': 'cooling',
74
- };
75
- expect(await service.handleHotWaterTankTargetHeatingCoolingStateGet()).toBe(Characteristic.TargetHeatingCoolingState.COOL);
76
-
77
- getManagementPoint(accessory.context.device, EMBEDDED_ID)['operationMode'] = {
78
- 'settable': true,
79
- 'values': [
80
- 'auto',
81
- 'dry',
82
- 'cooling',
83
- 'heating',
84
- 'fanOnly',
85
- ],
86
- 'value': 'auto',
87
- };
88
- expect(await service.handleHotWaterTankTargetHeatingCoolingStateGet()).toBe(Characteristic.TargetHeatingCoolingState.AUTO);
89
-
90
- getManagementPoint(accessory.context.device, EMBEDDED_ID)['operationMode'] = {
91
- 'settable': true,
92
- 'values': [
93
- 'auto',
94
- 'dry',
95
- 'cooling',
96
- 'heating',
97
- 'fanOnly',
98
- ],
99
- 'value': 'fanOnly',
100
- };
101
- expect(await service.handleHotWaterTankTargetHeatingCoolingStateGet()).toBe(Characteristic.TargetHeatingCoolingState.AUTO);
102
-
103
- getManagementPoint(accessory.context.device, EMBEDDED_ID)['operationMode'] = {
104
- 'settable': true,
105
- 'values': [
106
- 'auto',
107
- 'dry',
108
- 'cooling',
109
- 'heating',
110
- 'fanOnly',
111
- ],
112
- 'value': 'dry',
113
- };
114
- expect(await service.handleHotWaterTankTargetHeatingCoolingStateGet()).toBe(Characteristic.TargetHeatingCoolingState.AUTO);
115
-
116
- getManagementPoint(accessory.context.device, EMBEDDED_ID)['onOffMode'] = { value: 'off' };
117
- expect(await service.handleHotWaterTankTargetHeatingCoolingStateGet()).toBe(Characteristic.TargetHeatingCoolingState.OFF);
118
- });
119
-
120
- it('should get the powerful mode', async () => {
121
- expect(await service.handlePowerfulModeGet()).toBe(false);
122
- });
123
- });
@@ -1,271 +0,0 @@
1
- /**
2
- * StructuredLogger Tests
3
- */
4
-
5
- import {
6
- StructuredLogger,
7
- LogLevel,
8
- LogCategory,
9
- createLogger,
10
- createCategoryLogger,
11
- createDeviceLogger,
12
- } from '../../../src/utils/log-context';
13
- import {Logger} from 'homebridge';
14
-
15
- describe('StructuredLogger', () => {
16
- let mockLogger: Logger;
17
- let logger: StructuredLogger;
18
-
19
- beforeEach(() => {
20
- mockLogger = {
21
- debug: jest.fn(),
22
- info: jest.fn(),
23
- warn: jest.fn(),
24
- error: jest.fn(),
25
- log: jest.fn(),
26
- } as unknown as Logger;
27
-
28
- logger = new StructuredLogger(mockLogger);
29
- });
30
-
31
- describe('basic logging', () => {
32
- it('should log debug messages', () => {
33
- logger.debug('Debug message');
34
- expect(mockLogger.debug).toHaveBeenCalledWith('Debug message');
35
- });
36
-
37
- it('should log info messages', () => {
38
- logger.info('Info message');
39
- expect(mockLogger.info).toHaveBeenCalledWith('Info message');
40
- });
41
-
42
- it('should log warn messages', () => {
43
- logger.warn('Warning message');
44
- expect(mockLogger.warn).toHaveBeenCalledWith('Warning message');
45
- });
46
-
47
- it('should log error messages', () => {
48
- logger.error('Error message');
49
- expect(mockLogger.error).toHaveBeenCalledWith('Error message');
50
- });
51
- });
52
-
53
- describe('context formatting', () => {
54
- it('should include category in log message', () => {
55
- logger.log(LogLevel.INFO, 'Test', {category: LogCategory.API});
56
- expect(mockLogger.info).toHaveBeenCalledWith('[API] Test');
57
- });
58
-
59
- it('should include device name in log message', () => {
60
- logger.log(LogLevel.INFO, 'Test', {deviceName: 'Living Room'});
61
- expect(mockLogger.info).toHaveBeenCalledWith('[Living Room] Test');
62
- });
63
-
64
- it('should include device ID when no name', () => {
65
- logger.log(LogLevel.INFO, 'Test', {deviceId: 'device123'});
66
- expect(mockLogger.info).toHaveBeenCalledWith('[Device:device123] Test');
67
- });
68
-
69
- it('should include operation in log message', () => {
70
- logger.log(LogLevel.INFO, 'Test', {operation: 'update'});
71
- expect(mockLogger.info).toHaveBeenCalledWith('(update) Test');
72
- });
73
-
74
- it('should include embedded ID', () => {
75
- logger.log(LogLevel.INFO, 'Test', {embeddedId: 'climateControl'});
76
- expect(mockLogger.info).toHaveBeenCalledWith('[climateControl] Test');
77
- });
78
-
79
- it('should include feature name', () => {
80
- logger.log(LogLevel.INFO, 'Test', {feature: 'PowerfulMode'});
81
- expect(mockLogger.info).toHaveBeenCalledWith('[Feature:PowerfulMode] Test');
82
- });
83
-
84
- it('should combine multiple context fields', () => {
85
- logger.log(LogLevel.INFO, 'Test', {
86
- category: LogCategory.DEVICE,
87
- deviceName: 'Kitchen',
88
- operation: 'setState',
89
- });
90
- expect(mockLogger.info).toHaveBeenCalledWith('[Device] [Kitchen] (setState) Test');
91
- });
92
-
93
- it('should append metadata as JSON', () => {
94
- logger.log(LogLevel.INFO, 'Test', {
95
- metadata: {temp: 25, mode: 'cool'},
96
- });
97
-
98
- const logCall = (mockLogger.info as jest.Mock).mock.calls[0][0];
99
- expect(logCall).toContain('{"temp":25,"mode":"cool"}');
100
- });
101
- });
102
-
103
- describe('default context', () => {
104
- it('should merge default context with call context', () => {
105
- const loggerWithDefaults = new StructuredLogger(mockLogger, {
106
- category: LogCategory.PLATFORM,
107
- });
108
-
109
- loggerWithDefaults.log(LogLevel.INFO, 'Test', {deviceId: 'device123'});
110
-
111
- const logCall = (mockLogger.info as jest.Mock).mock.calls[0][0];
112
- expect(logCall).toContain('[Platform]');
113
- expect(logCall).toContain('[Device:device123]');
114
- });
115
-
116
- it('should override default context with call context', () => {
117
- const loggerWithDefaults = new StructuredLogger(mockLogger, {
118
- category: LogCategory.PLATFORM,
119
- });
120
-
121
- loggerWithDefaults.log(LogLevel.INFO, 'Test', {
122
- category: LogCategory.API,
123
- });
124
-
125
- const logCall = (mockLogger.info as jest.Mock).mock.calls[0][0];
126
- expect(logCall).toContain('[API]');
127
- expect(logCall).not.toContain('[Platform]');
128
- });
129
-
130
- it('should merge metadata objects', () => {
131
- const loggerWithDefaults = new StructuredLogger(mockLogger, {
132
- metadata: {defaultKey: 'defaultValue'},
133
- });
134
-
135
- loggerWithDefaults.log(LogLevel.INFO, 'Test', {
136
- metadata: {callKey: 'callValue'},
137
- });
138
-
139
- const logCall = (mockLogger.info as jest.Mock).mock.calls[0][0];
140
- expect(logCall).toContain('defaultKey');
141
- expect(logCall).toContain('callKey');
142
- });
143
- });
144
-
145
- describe('child logger', () => {
146
- it('should create child logger with additional context', () => {
147
- const child = logger.child({category: LogCategory.DEVICE});
148
- child.info('Test message');
149
-
150
- const logCall = (mockLogger.info as jest.Mock).mock.calls[0][0];
151
- expect(logCall).toContain('[Device]');
152
- });
153
-
154
- it('should inherit parent context', () => {
155
- const parent = new StructuredLogger(mockLogger, {
156
- category: LogCategory.PLATFORM,
157
- });
158
-
159
- const child = parent.child({deviceName: 'Kitchen'});
160
- child.info('Test');
161
-
162
- const logCall = (mockLogger.info as jest.Mock).mock.calls[0][0];
163
- expect(logCall).toContain('[Platform]');
164
- expect(logCall).toContain('[Kitchen]');
165
- });
166
- });
167
-
168
- describe('log history', () => {
169
- it('should record log entries in history', () => {
170
- logger.info('Message 1');
171
- logger.warn('Message 2');
172
- logger.error('Message 3');
173
-
174
- const history = logger.getHistory();
175
- expect(history).toHaveLength(3);
176
- });
177
-
178
- it('should return limited history', () => {
179
- for (let i = 0; i < 10; i++) {
180
- logger.info(`Message ${i}`);
181
- }
182
-
183
- const history = logger.getHistory(5);
184
- expect(history).toHaveLength(5);
185
- });
186
-
187
- it('should include context in history entries', () => {
188
- logger.info('Test', {category: LogCategory.API, deviceId: 'device123'});
189
-
190
- const history = logger.getHistory();
191
- expect(history[0].message).toBe('Test');
192
- expect(history[0].context?.category).toBe(LogCategory.API);
193
- expect(history[0].context?.deviceId).toBe('device123');
194
- });
195
-
196
- it('should include timestamp in history entries', () => {
197
- const before = new Date();
198
- logger.info('Test');
199
- const after = new Date();
200
-
201
- const history = logger.getHistory();
202
- expect(history[0].timestamp.getTime()).toBeGreaterThanOrEqual(before.getTime());
203
- expect(history[0].timestamp.getTime()).toBeLessThanOrEqual(after.getTime());
204
- });
205
-
206
- it('should clear history', () => {
207
- logger.info('Message 1');
208
- logger.info('Message 2');
209
- expect(logger.getHistory()).toHaveLength(2);
210
-
211
- logger.clearHistory();
212
- expect(logger.getHistory()).toHaveLength(0);
213
- });
214
- });
215
-
216
- describe('helper functions', () => {
217
- it('createLogger should create StructuredLogger', () => {
218
- const newLogger = createLogger(mockLogger);
219
- expect(newLogger).toBeInstanceOf(StructuredLogger);
220
- });
221
-
222
- it('createLogger should accept default context', () => {
223
- const newLogger = createLogger(mockLogger, {category: LogCategory.API});
224
- newLogger.info('Test');
225
-
226
- const logCall = (mockLogger.info as jest.Mock).mock.calls[0][0];
227
- expect(logCall).toContain('[API]');
228
- });
229
-
230
- it('createCategoryLogger should create logger with category', () => {
231
- const newLogger = createCategoryLogger(mockLogger, LogCategory.WEBSOCKET);
232
- newLogger.info('Test');
233
-
234
- const logCall = (mockLogger.info as jest.Mock).mock.calls[0][0];
235
- expect(logCall).toContain('[WebSocket]');
236
- });
237
-
238
- it('createDeviceLogger should create logger with device context', () => {
239
- const newLogger = createDeviceLogger(mockLogger, 'device123', 'Kitchen AC');
240
- newLogger.info('Test');
241
-
242
- const logCall = (mockLogger.info as jest.Mock).mock.calls[0][0];
243
- expect(logCall).toContain('[Device]');
244
- expect(logCall).toContain('[Kitchen AC]');
245
- });
246
- });
247
-
248
- describe('edge cases', () => {
249
- it('should handle empty message', () => {
250
- logger.info('');
251
- expect(mockLogger.info).toHaveBeenCalled();
252
- });
253
-
254
- it('should handle undefined context', () => {
255
- logger.info('Test', undefined);
256
- expect(mockLogger.info).toHaveBeenCalledWith('Test');
257
- });
258
-
259
- it('should handle empty metadata', () => {
260
- logger.info('Test', {metadata: {}});
261
-
262
- const logCall = (mockLogger.info as jest.Mock).mock.calls[0][0];
263
- expect(logCall).toBe('Test');
264
- });
265
-
266
- it('should handle special characters in messages', () => {
267
- logger.info('Test [brackets] (parens) {braces}');
268
- expect(mockLogger.info).toHaveBeenCalled();
269
- });
270
- });
271
- });